def build_cdroms(self, build_bin=True, build_sources=False, cdrom_size=None): self.repo_images = [] elog = ASCIIDocLog(self.validationpath, True) env = None sysrootstr = "" if os.path.exists(self.sysrootpath): sysrootstr = "(including sysroot packages)" env = BuildEnv(self.xml, self.log, self.sysrootpath, build_sources=build_sources, clean=False) else: env = BuildEnv(self.xml, self.log, self.chrootpath, build_sources=build_sources, clean=False) # ensure the /etc/apt/sources.list is created according to # buil_sources, # build_bin flag, ensure to reopen it with # the new 'sources.list' with env: env.seed_etc() self.drop_rpcaptcache(env=env) with env: init_codename = self.xml.get_initvm_codename() if build_bin: elog.h1("Binary CD %s" % sysrootstr) self.repo_images += mk_binary_cdrom(env.rfs, self.arch, self.codename, init_codename, self.xml, self.builddir, self.log, cdrom_size=cdrom_size) if build_sources: elog.h1("Source CD %s" % sysrootstr) try: self.repo_images += mk_source_cdrom(env.rfs, self.arch, self.codename, init_codename, self.builddir, self.log, cdrom_size=cdrom_size, xml=self.xml) except SystemError as e: # e.g. no deb-src urls specified elog.printo(str(e))
def build_cdroms(self, build_bin=True, build_sources=False, cdrom_size=None): self.repo_images = [] env = None sysrootstr = "" if os.path.exists(self.sysrootpath): sysrootstr = "(including sysroot packages)" env = BuildEnv(self.xml, self.sysrootpath, build_sources=build_sources, clean=False) else: env = BuildEnv(self.xml, self.chrootpath, build_sources=build_sources, clean=False) # ensure the /etc/apt/sources.list is created according to # buil_sources, # build_bin flag, ensure to reopen it with # the new 'sources.list' with env: env.seed_etc() self.drop_rpcaptcache(env=env) with env: init_codename = self.xml.get_initvm_codename() if build_bin: validation.info("Binary CD %s", sysrootstr) self.repo_images += mk_binary_cdrom(env.rfs, self.arch, self.codename, init_codename, self.xml, self.builddir) if build_sources: if not cdrom_size and self.xml.has("src-cdrom/size"): cdrom_size = size_to_int(self.xml.text("src-cdrom/size")) validation.info("Source CD %s", sysrootstr) try: self.repo_images += mk_source_cdrom(env.rfs, self.arch, self.codename, init_codename, self.builddir, cdrom_size=cdrom_size, xml=self.xml) except SystemError as e: # e.g. no deb-src urls specified validation.error(str(e))
def build_cdroms(self, build_bin=True, build_sources=False, cdrom_size=None, tgt_pkg_lst=None): # pylint: disable=too-many-branches # pylint: disable=too-many-locals self.repo_images = [] env = None sysrootstr = "" if os.path.exists(self.sysrootpath): sysrootstr = "(including sysroot packages)" env = BuildEnv(self.xml, self.sysrootpath, build_sources=build_sources, clean=False) else: env = BuildEnv(self.xml, self.chrootpath, build_sources=build_sources, clean=False) # ensure the /etc/apt/sources.list is created according to # buil_sources, # build_bin flag, ensure to reopen it with # the new 'sources.list' with env: env.seed_etc() self.drop_rpcaptcache(env=env) with env: init_codename = self.xml.get_initvm_codename() if build_bin: validation.info("Binary CD %s", sysrootstr) self.repo_images += mk_binary_cdrom(env.rfs, self.arch, self.codename, init_codename, self.xml, self.builddir) if build_sources: if not cdrom_size and self.xml.has("src-cdrom/size"): cdrom_size = size_to_int(self.xml.text("src-cdrom/size")) validation.info("Source CD %s", sysrootstr) # Target component cache = self.get_rpcaptcache(env=self.buildenv) tgt_lst = cache.get_corresponding_source_packages( pkg_lst=tgt_pkg_lst) components = {"target": (self.targetfs, cache, tgt_lst)} # Main component main_lst = [] if self.xml is not None: tmp_lst = [] for pkg_node in self.xml.node("debootstrappkgs"): pkg = XMLPackage(pkg_node, self.arch) tmp_lst.append(pkg.name) main_lst = cache.get_corresponding_source_packages( pkg_lst=tmp_lst) components["main"] = (env.rfs, cache, main_lst) # Added component other_components = [(env, "added")] # Let's build a list of (build_env, name) for the # other RFS if they exist host_sysroot_path = os.path.join(self.sdkpath, "sysroots", "host") for path, name in [(self.chrootpath, "chroot"), (host_sysroot_path, "sysroot-host")]: if os.path.exists(path) and env.path != path: tmp_env = BuildEnv(self.xml, path) with tmp_env: tmp_env.seed_etc() other_components.append((tmp_env, name)) # Now let's generate the correct (rfs, cache, pkg_lst) # components using the full installed packages for build_env, name in other_components: cache = self.get_rpcaptcache(env=build_env) src_lst = cache.get_corresponding_source_packages() components[name] = (build_env.rfs, cache, src_lst) try: # Using kwargs here allows us to avoid making # special case for when self.xml is None kwargs = {"cdrom_size": cdrom_size, "xml": self.xml} if self.xml is not None: kwargs["mirror"] = self.xml.get_primary_mirror( env.rfs.fname("cdrom")) self.repo_images += mk_source_cdrom( components, self.codename, init_codename, self.builddir, **kwargs) except SystemError as e: # e.g. no deb-src urls specified validation.error(str(e))
def run_command(argv): # pylint disable=too-many-statements oparser = OptionParser(usage="usage: %prog mkcdrom [options] <builddir>") oparser.add_option("--skip-validation", action="store_true", dest="skip_validation", default=False, help="Skip xml schema validation") oparser.add_option("--buildtype", dest="buildtype", help="Override the buildtype") oparser.add_option("--arch", dest="arch", help="Override the architecture") oparser.add_option("--codename", dest="codename", help="Override the codename") oparser.add_option("--init_codename", dest="init_codename", help="Override the initvm codename") oparser.add_option("--rfs-only", action="store_true", dest="rfs_only", default=False, help="builddir points to RFS") oparser.add_option("--log", dest="log", help="Log to filename") oparser.add_option("--binary", action="store_true", dest="binary", default=False, help="build binary cdrom") oparser.add_option("--source", action="store_true", dest="source", default=False, help="build source cdrom") oparser.add_option("--cdrom-size", action="store", dest="cdrom_size", default=CDROM_SIZE, help="Source ISO CD size in bytes") (opt, args) = oparser.parse_args(argv) if len(args) != 1: print("wrong number of arguments", file=sys.stderr) oparser.print_help() sys.exit(20) with elbe_logging({"files": opt.log}): if not opt.rfs_only: try: project = ElbeProject(args[0], override_buildtype=opt.buildtype, skip_validate=opt.skip_validation) except ValidationError: logging.exception("XML validation failed. Bailing out") sys.exit(20) builddir = project.builddir rfs = project.buildenv.rfs xml = project.xml arch = xml.text("project/arch", key="arch") codename = xml.text("project/suite") init_codename = xml.get_initvm_codename() else: builddir = os.path.abspath(os.path.curdir) rfs = ChRootFilesystem(args[0]) arch = opt.arch codename = opt.codename init_codename = opt.init_codename xml = None generated_files = [] if opt.source: with rfs: cache = get_rpcaptcache(rfs, arch) components = { "main": (rfs, cache, cache.get_corresponding_source_packages()) } generated_files += mk_source_cdrom(components, codename, init_codename, builddir, opt.cdrom_size) if opt.binary: with rfs: generated_files += mk_binary_cdrom(rfs, arch, codename, init_codename, xml, builddir) logging.info("Image Build finished.") logging.info("Files generated:\n%s", "\n".join([str(f) for f in generated_files]))
def build(self, skip_debootstrap=False, build_bin=False, build_sources=False, cdrom_size=None, debug=False, skip_pkglist=False): # Write the log header self.write_log_header() # Create the build environment, if it does not exist yet if not self.buildenv: self.log.do('mkdir -p "%s"' % self.chrootpath) self.buildenv = BuildEnv(self.xml, self.log, self.chrootpath, build_sources=build_sources) skip_pkglist = False # Install packages if not skip_pkglist: self.install_packages() try: self.buildenv.rfs.dump_elbeversion(self.xml) except IOError: self.log.printo("dump elbeversion failed") # Extract target FS. We always create a new instance here with # clean=true, because we want a pristine directory. self.targetfs = TargetFs(self.targetpath, self.log, self.buildenv.xml, clean=True) os.chdir(self.buildenv.rfs.fname('')) extract_target(self.buildenv.rfs, self.xml, self.targetfs, self.log, self.get_rpcaptcache()) # Package validation and package list if not skip_pkglist: validationpath = os.path.join(self.builddir, "validation.txt") pkgs = self.xml.xml.node("/target/pkg-list") if self.xml.has("fullpkgs"): check_full_pkgs(pkgs, self.xml.xml.node("/fullpkgs"), validationpath, self.get_rpcaptcache()) else: check_full_pkgs(pkgs, None, validationpath, self.get_rpcaptcache()) dump_fullpkgs(self.xml, self.buildenv.rfs, self.get_rpcaptcache()) self.xml.dump_elbe_version() self.targetfs.write_fstab(self.xml) # Dump ELBE version try: self.targetfs.dump_elbeversion(self.xml) except MemoryError: self.log.printo("dump elbeversion failed") # install packages for buildenv if not skip_pkglist: self.install_packages(buildenv=True) # Write source.xml try: sourcexmlpath = os.path.join(self.builddir, "source.xml") self.xml.xml.write(sourcexmlpath) except MemoryError: self.log.printo("write source.xml failed (archive to huge?)") # Elbe report reportpath = os.path.join(self.builddir, "elbe-report.txt") elbe_report(self.xml, self.buildenv, self.get_rpcaptcache(), reportpath, self.targetfs) # Licenses f = open(os.path.join(self.builddir, "licence.txt"), "w+") self.buildenv.rfs.write_licenses(f, self.log) f.close() # Read arch and codename from xml arch = self.xml.text("project/arch", key="arch") codename = self.xml.text("project/suite") # Use some handwaving to determine grub version # jessie and wheezy grubs are 2.0 but differ in behaviour # # We might also want support for legacy grub if self.get_rpcaptcache().is_installed('grub-pc'): if codename == "jessie": grub_version = 202 else: grub_version = 199 elif self.get_rpcaptcache().is_installed('grub-legacy'): self.log.printo( "package grub-legacy is installed, this is obsolete, skipping grub" ) grub_version = 0 else: self.log.printo("package grub-pc is not installed, skipping grub") # version 0 == skip_grub grub_version = 0 self.targetfs.part_target(self.builddir, grub_version) # Build cdrom images self.repo_images = [] with self.buildenv: init_codename = self.xml.get_initvm_codename() if build_bin: self.repo_images += mk_binary_cdrom(self.buildenv.rfs, arch, codename, init_codename, self.xml, self.builddir, self.log, cdrom_size=cdrom_size) if build_sources: try: self.repo_images += mk_source_cdrom(self.buildenv.rfs, arch, codename, init_codename, self.builddir, self.log, cdrom_size=cdrom_size) except SystemError as e: # e.g. no deb-src urls specified self.log.printo(str(e)) if self.postbuild_file: self.log.h2("postbuild script:") self.log.do(self.postbuild_file + ' "%s %s %s"' % (self.builddir, self.xml.text("project/version"), self.xml.text("project/name")), allow_fail=True) os.system('cat "%s"' % os.path.join(self.builddir, "validation.txt"))
def run_command(argv): # pylint disable=too-many-statements oparser = OptionParser(usage="usage: %prog mkcdrom [options] <builddir>") oparser.add_option("--skip-validation", action="store_true", dest="skip_validation", default=False, help="Skip xml schema validation") oparser.add_option("--buildtype", dest="buildtype", help="Override the buildtype") oparser.add_option("--arch", dest="arch", help="Override the architecture") oparser.add_option("--codename", dest="codename", help="Override the codename") oparser.add_option("--init_codename", dest="init_codename", help="Override the initvm codename") oparser.add_option("--rfs-only", action="store_true", dest="rfs_only", default=False, help="builddir points to RFS") oparser.add_option("--log", dest="log", help="Log to filename") oparser.add_option("--binary", action="store_true", dest="binary", default=False, help="build binary cdrom") oparser.add_option("--source", action="store_true", dest="source", default=False, help="build source cdrom") oparser.add_option("--cdrom-size", action="store", dest="cdrom_size", default=CDROM_SIZE, help="ISO CD size in MB") (opt, args) = oparser.parse_args(argv) if len(args) != 1: print("wrong number of arguments", file=sys.stderr) oparser.print_help() sys.exit(20) if not opt.rfs_only: try: project = ElbeProject(args[0], logpath=opt.log, override_buildtype=opt.buildtype, skip_validate=opt.skip_validation) except ValidationError as e: print(str(e), file=sys.stderr) print("xml validation failed. Bailing out", file=sys.stderr) sys.exit(20) builddir = project.builddir rfs = project.buildenv.rfs xml = project.xml arch = xml.text("project/arch", key="arch") codename = xml.text("project/suite") log = project.log init_codename = xml.get_initvm_codename() else: builddir = os.path.abspath(os.path.curdir) rfs = ChRootFilesystem(args[0]) arch = opt.arch codename = opt.codename init_codename = opt.init_codename xml = None if opt.log: log = ASCIIDocLog(opt.log) else: log = StdoutLog() generated_files = [] if opt.source: with rfs: generated_files += mk_source_cdrom(rfs, arch, codename, init_codename, builddir, log, opt.cdrom_size) if opt.binary: with rfs: generated_files += mk_binary_cdrom(rfs, arch, codename, init_codename, xml, builddir, log, opt.cdrom_size) print("") print("Image Build finished !") print("") print("Files generated:") for f in generated_files: print(" %s" % f)
def run_command( argv ): oparser = OptionParser(usage="usage: %prog mkcdrom [options] <builddir>") oparser.add_option( "--skip-validation", action="store_true", dest="skip_validation", default=False, help="Skip xml schema validation" ) oparser.add_option( "--buildtype", dest="buildtype", help="Override the buildtype" ) oparser.add_option( "--arch", dest="arch", help="Override the architecture" ) oparser.add_option( "--codename", dest="codename", help="Override the codename" ) oparser.add_option( "--init_codename", dest="init_codename", help="Override the initvm codename" ) oparser.add_option( "--rfs-only", action="store_true", dest="rfs_only", default=False, help="builddir points to RFS" ) oparser.add_option( "--log", dest="log", help="Log to filename" ) oparser.add_option( "--binary", action="store_true", dest="binary", default=False, help="build binary cdrom" ) oparser.add_option( "--source", action="store_true", dest="source", default=False, help="build source cdrom" ) oparser.add_option( "--cdrom-size", action="store", dest="cdrom_size", default=CDROM_SIZE, help="ISO CD size in MB" ) (opt,args) = oparser.parse_args(argv) if len(args) != 1: print ("wrong number of arguments", file=sys.stderr) oparser.print_help() sys.exit(20) if not opt.rfs_only: try: project = ElbeProject( args[0], logpath=opt.log, override_buildtype=opt.buildtype, skip_validate=opt.skip_validation ) except ValidationError as e: print (str (e), file=sys.stderr) print ("xml validation failed. Bailing out", file=sys.stderr) sys.exit(20) builddir = project.builddir rfs = project.buildenv.rfs xml = project.xml arch = xml.text("project/arch", key="arch" ) codename = xml.text("project/suite" ) log = project.log init_codename = xml.get_initvm_codename () else: builddir = os.path.abspath( os.path.curdir ) rfs = ChRootFilesystem( args[0] ) arch = opt.arch codename = opt.codename init_codename = opt.init_codename xml = None if opt.log: log = ASCIIDocLog( opt.log ) else: log = StdoutLog() generated_files = [] if opt.source: with rfs: generated_files += mk_source_cdrom( rfs, arch, codename, init_codename, builddir, log, opt.cdrom_size ) if opt.binary: with rfs: generated_files += mk_binary_cdrom( rfs, arch, codename, init_codename, xml, builddir, log, opt.cdrom_size ) print ("") print ("Image Build finished !") print ("") print ("Files generated:") for f in generated_files: print (" %s"%f)
def build (self, skip_debootstrap = False, build_bin = False, build_sources = False, cdrom_size = None, debug = False, skip_pkglist = False): # Write the log header self.write_log_header() # Create the build environment, if it does not exist yet if not self.buildenv: self.log.do( 'mkdir -p "%s"' % self.chrootpath ) self.buildenv = BuildEnv( self.xml, self.log, self.chrootpath, build_sources = build_sources ) skip_pkglist = False # Install packages if not skip_pkglist: self.install_packages() try: self.buildenv.rfs.dump_elbeversion (self.xml) except IOError: self.log.printo ("dump elbeversion failed") # Extract target FS. We always create a new instance here with # clean=true, because we want a pristine directory. self.targetfs = TargetFs( self.targetpath, self.log, self.buildenv.xml, clean=True ) os.chdir( self.buildenv.rfs.fname( '' ) ) extract_target( self.buildenv.rfs, self.xml, self.targetfs, self.log, self.get_rpcaptcache() ) # Package validation and package list if not skip_pkglist: validationpath = os.path.join( self.builddir, "validation.txt" ) pkgs = self.xml.xml.node( "/target/pkg-list" ) if self.xml.has( "fullpkgs" ): check_full_pkgs( pkgs, self.xml.xml.node( "/fullpkgs" ), validationpath, self.get_rpcaptcache() ) else: check_full_pkgs( pkgs, None, validationpath, self.get_rpcaptcache() ) dump_fullpkgs( self.xml, self.buildenv.rfs, self.get_rpcaptcache() ) self.xml.dump_elbe_version () self.targetfs.write_fstab (self.xml ) # Dump ELBE version try: self.targetfs.dump_elbeversion( self.xml ) except MemoryError: self.log.printo( "dump elbeversion failed" ) # install packages for buildenv if not skip_pkglist: self.install_packages(buildenv=True) # Write source.xml try: sourcexmlpath = os.path.join( self.builddir, "source.xml" ) self.xml.xml.write( sourcexmlpath ) except MemoryError: self.log.printo( "write source.xml failed (archive to huge?)" ) # Elbe report reportpath = os.path.join( self.builddir, "elbe-report.txt" ) elbe_report( self.xml, self.buildenv, self.get_rpcaptcache(), reportpath, self.targetfs ) # Licenses f = open( os.path.join( self.builddir, "licence.txt" ), "w+" ) self.buildenv.rfs.write_licenses(f, self.log) f.close() # Read arch and codename from xml arch = self.xml.text( "project/arch", key="arch" ) codename = self.xml.text( "project/suite" ) # Use some handwaving to determine grub version # jessie and wheezy grubs are 2.0 but differ in behaviour # # We might also want support for legacy grub if self.get_rpcaptcache().is_installed( 'grub-pc' ): if codename == "jessie": grub_version = 202 else: grub_version = 199 elif self.get_rpcaptcache().is_installed( 'grub-legacy' ): self.log.printo( "package grub-legacy is installed, this is obsolete, skipping grub" ) grub_version = 0 else: self.log.printo( "package grub-pc is not installed, skipping grub" ) # version 0 == skip_grub grub_version = 0 self.targetfs.part_target( self.builddir, grub_version ) # Build cdrom images self.repo_images = [] with self.buildenv: init_codename = self.xml.get_initvm_codename() if build_bin: self.repo_images += mk_binary_cdrom( self.buildenv.rfs, arch, codename, init_codename, self.xml, self.builddir, self.log, cdrom_size=cdrom_size ) if build_sources: try: self.repo_images += mk_source_cdrom( self.buildenv.rfs, arch, codename, init_codename, self.builddir, self.log, cdrom_size=cdrom_size ) except SystemError as e: # e.g. no deb-src urls specified self.log.printo( str (e) ) if self.postbuild_file: self.log.h2 ("postbuild script:") self.log.do (self.postbuild_file + ' "%s %s %s"' % ( self.builddir, self.xml.text ("project/version"), self.xml.text ("project/name")), allow_fail=True) os.system( 'cat "%s"' % os.path.join( self.builddir, "validation.txt" ) )
def build(self, skip_debootstrap=False, build_bin=False, build_sources=False, cdrom_size=None, debug=False, skip_pkglist=False, skip_pbuild=False): # Write the log header self.write_log_header() # Validate Apt Sources m = ValidationMode.NO_CHECK if build_bin: m = ValidationMode.CHECK_BINARIES if build_sources: m = ValidationMode.CHECK_ALL self.xml.validate_apt_sources(m, self.arch) if (self.xml.has('target/pbuilder') and not skip_pbuild): if not os.path.exists(os.path.join(self.builddir, "pbuilder")): self.create_pbuilder() for p in self.xml.node('target/pbuilder'): self.pbuild(p) # the package might be needed by a following pbuild, so update # the project repo that it can be installed in as # build-dependency self.repo.finalize() # To avoid update cache errors, the project repo needs to have # Release and Packages files, even if it's empty. So don't do this # in the if case above! self.repo.finalize() # Create the build environment, if it does not a valid one # self.buildenv might be set when we come here. # However, if its not a full_buildenv, we specify clean here, # so it gets rebuilt properly. if not self.has_full_buildenv(): self.log.do('mkdir -p "%s"' % self.chrootpath) self.buildenv = BuildEnv(self.xml, self.log, self.chrootpath, build_sources=build_sources, clean=True) skip_pkglist = False # Import keyring self.buildenv.import_keys() self.log.printo("Keys imported") # Install packages if not skip_pkglist: self.install_packages() try: self.buildenv.rfs.dump_elbeversion(self.xml) except IOError: self.log.printo("dump elbeversion failed") # Extract target FS. We always create a new instance here with # clean=true, because we want a pristine directory. self.targetfs = TargetFs(self.targetpath, self.log, self.buildenv.xml, clean=True) os.chdir(self.buildenv.rfs.fname('')) extract_target(self.buildenv.rfs, self.xml, self.targetfs, self.log, self.get_rpcaptcache()) # Package validation and package list if not skip_pkglist: validationpath = os.path.join(self.builddir, "validation.txt") pkgs = self.xml.xml.node("/target/pkg-list") if self.xml.has("fullpkgs"): check_full_pkgs(pkgs, self.xml.xml.node("/fullpkgs"), validationpath, self.get_rpcaptcache()) else: check_full_pkgs(pkgs, None, validationpath, self.get_rpcaptcache()) dump_fullpkgs(self.xml, self.buildenv.rfs, self.get_rpcaptcache()) self.xml.dump_elbe_version() self.targetfs.write_fstab(self.xml) # Dump ELBE version try: self.targetfs.dump_elbeversion(self.xml) except MemoryError: self.log.printo("dump elbeversion failed") # install packages for buildenv if not skip_pkglist: self.install_packages(buildenv=True) # Write source.xml try: sourcexmlpath = os.path.join(self.builddir, "source.xml") self.xml.xml.write(sourcexmlpath) except MemoryError: self.log.printo("write source.xml failed (archive to huge?)") # Elbe report reportpath = os.path.join(self.builddir, "elbe-report.txt") elbe_report(self.xml, self.buildenv, self.get_rpcaptcache(), reportpath, self.targetfs) # Licenses f = io.open(os.path.join(self.builddir, "licence.txt"), "w+", encoding='utf-8') self.buildenv.rfs.write_licenses( f, self.log, os.path.join(self.builddir, "licence.xml")) f.close() # Use some handwaving to determine grub version # jessie and wheezy grubs are 2.0 but differ in behaviour # # We might also want support for legacy grub if self.get_rpcaptcache().is_installed('grub-pc'): if self.codename == "wheezy": grub_version = 199 else: grub_version = 202 elif self.get_rpcaptcache().is_installed('grub-legacy'): self.log.printo( "package grub-legacy is installed, this is obsolete, skipping grub" ) grub_version = 0 else: self.log.printo("package grub-pc is not installed, skipping grub") # version 0 == skip_grub grub_version = 0 self.targetfs.part_target(self.builddir, grub_version) # Build cdrom images self.repo_images = [] with self.buildenv: init_codename = self.xml.get_initvm_codename() if build_bin: self.repo_images += mk_binary_cdrom(self.buildenv.rfs, self.arch, self.codename, init_codename, self.xml, self.builddir, self.log, cdrom_size=cdrom_size) if build_sources: try: self.repo_images += mk_source_cdrom(self.buildenv.rfs, self.arch, self.codename, init_codename, self.builddir, self.log, cdrom_size=cdrom_size, xml=self.xml) except SystemError as e: # e.g. no deb-src urls specified self.log.printo(str(e)) if self.postbuild_file: self.log.h2("postbuild script:") self.log.do(self.postbuild_file + ' "%s %s %s"' % (self.builddir, self.xml.text("project/version"), self.xml.text("project/name")), allow_fail=True) os.system('cat "%s"' % os.path.join(self.builddir, "validation.txt"))