def ensure_clean_wrkdir(package): """Ensure that a fresh work directory is present for the package to build.""" wrkdir = misc.get_wrkdir(package) if os.path.exists(wrkdir): print("Old workdir found. Deleting... ", end='', flush=True) misc.remove_file_or_dir(wrkdir) print("ok") if package in conf.config['distfiles']: ensure_distfile("compressed", package) ensure_distfile("uncompressed", package) misc.extract_tarball(package) if package in conf.config['extrafiles']: if not os.path.exists(wrkdir): try: os.makedirs(wrkdir) except OSError as e: misc.die("\nFilesystem error: Could not create directory \"" + directory + "\"! Exiting.") if package in conf.config['extrafiles']: ensure_extrafiles_present(package) extradir = globalvars.SUBSTITUTION_MAP['rbuild_extra_dir'] + '/' + package extrafiles = conf.get_config_value('extrafiles', package).split(", ") for f in extrafiles: absolute_path = extradir + '/' + os.path.basename(f) try: shutil.copy(absolute_path, wrkdir) except IOError as e: misc.die("\nFilesystem error: Could not copy \"" + absolute_path + "\" to \"" + wrkdir + "\"! Exiting.")
def assert_conf_section_present(section): """Check if configuration section (section) exists and error out if not.""" misc.verbose_output("Config: Checking for section \"" + section + "\"... ") if section not in config.sections(): misc.die("\nError: Cannot find section \"" + section + "\" in configuration file \"" + CONFNAME + "\"! Exiting.") misc.verbose_output("ok\n")
def get_os_version(): if conf.get_config_value('version', 'osversion') == '' or conf.get_config_value( 'version', 'osversion') == 'auto': if globalvars.OSNAME == 'FreeBSD': osversion = misc.get_cmd_output("uname", "-K") misc.verbose_output("System: Autodetecting OS version... " + osversion + "\n") return osversion elif globalvars.OSNAME == 'DragonFly': major = globalvars.OSRELEASE[:globalvars.OSRELEASE.find(".")] minor = globalvars.OSRELEASE[globalvars.OSRELEASE.find(".") + 1:] if len(major) == 1: maj = major + "00" elif len(major) == 2: maj = major + "0" else: maj = major if len(minor) == 1: mnr = minor + "00" elif len(minor) == 2: mnr = minor + "0" else: mnr = minor osversion = maj + mnr misc.verbose_output("System: Autodetecting OS version... " + osversion + "\n") return osversion else: misc.die("FATAL: INCOMPLETELY SUPPORTED OS! THIS IS A BUG.") else: osversion = conf.get_config_value('version', 'osversion') misc.verbose_output("System: OS version is \"" + osversion + "\" (override via config file)\n") return osversion
def assert_conf_file_present(): """Check if config file is present and error out if not.""" ("Config: Checking if config file exists... ") if not os.path.isfile(globalvars.CONFNAME): misc.die("\nError: Could not read configuration file \"" + globalvars.CONFNAME + "\"! Exiting.") misc.verbose_output("ok\n")
def assert_key_in_conf_section(section, key, not_empty): """Check if key (key) is present in section (section), make sure it's not empty if (not_empty) is true. Error out otherwise.""" misc.verbose_output("Config: Checking for key \"" + key + "\" in " + section + "... ") if not key in config[section]: misc.die("\nConfiguration error: Key \"" + key + "\" missing in section \"" + section + "\"! Exiting.") if not_empty and config[section][key] == '': misc.die("\nConfiguration error: Key \"" + key + "\" exists in section \"" + section + "\" but is not allowed to be empty! Exiting.") misc.verbose_output("ok\n")
def get_config_value(section, key): """Check if section (section) exists in config and key (key) is present there. Then retrieve the value or error out if either is not present.""" if not section in config.sections(): misc.die("Error: Cannot get config values, section \"" + section + "\" does not exist! Exiting.") if not key in config[section]: misc.die("Error: Cannot get config values, no key \"" + key + "\" in section \"" + section + "\"! Exiting.") value = config[section][key] if len(subst.get_substitution_variables(value)) > 0: return (subst.substitute_variables(value)) else: return (value)
def get_os_major(): if conf.get_config_value('version', 'osmajor') == '' or conf.get_config_value( 'version', 'osmajor') == 'auto': if globalvars.OSNAME == 'FreeBSD' or globalvars.OSNAME == 'DragonFly': osmajor = globalvars.OSRELEASE[:globalvars.OSRELEASE.find(".")] misc.verbose_output("System: Autodetecting OS major version... " + osmajor + "\n") return osmajor else: misc.die("FATAL: INCOMPLETELY SUPPORTED OS! THIS IS A BUG.") else: osmajor = conf.get_config_value('version', 'osmajor') misc.verbose_output("System: OS major version is \"" + osmajor + "\" (override via config file)\n") return osmajor
def get_os_arch(): if conf.get_config_value('version', 'osarch') == '' or conf.get_config_value( 'version', 'osarch') == 'auto': if globalvars.OSNAME == 'FreeBSD' or globalvars.OSNAME == 'DragonFly': osarch = misc.get_cmd_output("uname", "-p") misc.verbose_output("System: Autodetecting host architecture... " + osarch + "\n") return osarch else: misc.die("FATAL: INCOMPLETELY SUPPORTED OS! THIS IS A BUG.") else: osarch = conf.get_config_value('version', 'osarch') misc.verbose_output("System: Host architecture is \"" + osarch + "\" (override via config file)\n") return osarch
def get_os_release(): if conf.get_config_value('version', 'osrelease') == '' or conf.get_config_value( 'version', 'osrelease') == 'auto': if globalvars.OSNAME == 'FreeBSD' or globalvars.OSNAME == 'DragonFly': temp = misc.get_cmd_output("uname", "-r") osrelease = temp[:temp.find("-")] misc.verbose_output("System: Autodetecting OS release... " + osrelease + "\n") return osrelease else: misc.die("FATAL: INCOMPLETELY SUPPORTED OS! THIS IS A BUG.") else: osrelease = conf.get_config_value('version', 'osrelease') misc.verbose_output("System: OS release is \"" + osrelease + "\" (override via config file)\n") return osrelease
def build_package(phase, package): """Configure, make or install (phase) a program (package).""" if phase == "configure": activity = "Configuring" env = phase elif phase == "make": activity = "Building" env = phase elif phase == "install": activity = "Installing" env = "make" else: misc.die("\nError: Unknown build phase \"" + phase + "\"! Exiting.") env = misc.prepare_env(env, package) print(activity + " \"" + package + "\"... ", end='', flush=True) wrkdir = misc.get_wrkdir(package) for cmd in conf.get_config_value(phase + "_cmds", package).split(', '): r = misc.do_shell_cmd(cmd, wrkdir, env) if r != 0: misc.die("\nError: " + activity + " failed for package \"" + package + "\"! Exiting.") print("ok")
def get_stdarch(): if conf.get_config_value('version', 'stdarch') == '' or conf.get_config_value( 'version', 'stdarch') == 'auto': if globalvars.OSARCH == "amd64" or globalvars.OSARCH == "x86_64": stdarch = "x86_64" elif globalvars.OSARCH == "i386": stdarch = "x86" elif globalvars.OSARCH == "aarch64" or OSARCH == "arm64": stdarch = "aarch64" else: misc.die("System: Error, unsupported architecture \"" + OSARCH + "\"!") misc.verbose_output( "System: Autodetecting host standard architecture... " + stdarch + "\n") return stdarch else: stdarch = conf.get_config_value('version', 'stdarch') misc.verbose_output("System: Host standard architecture is \"" + stdarch + "\" (override via config file)\n") return stdarch
def assemble_triple(): if conf.get_config_value('version', 'tgt_triple') == '' or conf.get_config_value( 'version', 'tgt_triple') == 'auto': if globalvars.OSNAME == 'FreeBSD': tgt_triple = globalvars.STDARCH + "-raven-" + globalvars.OSNAME.lower( ) + globalvars.OSMAJOR misc.verbose_output("System: Assembling target triple... " + tgt_triple + "\n") return tgt_triple elif globalvars.OSNAME == 'DragonFly': tgt_triple = globalvars.STDARCH + "-raven-" + globalvars.OSNAME.lower( ) + globalvars.OSRELEASE misc.verbose_output("System: Assembling target triple... " + tgt_triple + "\n") return tgt_triple else: misc.die("FATAL: INCOMPLETELY SUPPORTED OS! THIS IS A BUG.") else: tgt_triple = conf.get_config_value('version', 'tgt_triple') misc.verbose_output("System: Target triple is \"" + tgt_triple + "\" (override via config file)\n") return tgt_triple
def ensure_extrafiles_present(package): """Ensure that the extra files for a package are present.""" extradir = globalvars.SUBSTITUTION_MAP['rbuild_extra_dir'] + '/' + package extrafiles = conf.get_config_value('extrafiles', package).split(", ") md5s = None if package + "_md5" in conf.config['extrafiles']: md5s = conf.get_config_value('extrafiles', package + "_md5").split(", ") misc.verbose_output("Extra files: Ensuring directory \"" + extradir + "\" exists... ") if not os.path.isdir(extradir): try: os.makedirs(extradir) except OSError as e: misc.die("\nPatches error: Could not create directory \"" + extradir + "\"! Exiting.") misc.verbose_output("ok\n") i = 0 for f in extrafiles: filename = os.path.basename(f) absolute_path = extradir + '/' + filename if not os.path.isfile(absolute_path): misc.fetch_file(f, extradir, filename) misc.verbose_output("Comparing checksums for extra file " + str(i) + "... ") if md5s == None: misc.verbose_output("skipping (not available)\n") else: if misc.get_file_hash(absolute_path) == md5s[i]: misc.verbose_output("ok (matches)\n") else: misc.verbose_output("Mismatch! Fetching again...\n") misc.remove_file_or_dir(absolute_path) misc.fetch_file(f, extradir, filename) misc.verbose_output("Comparing checksums once more... ") if misc.get_file_hash(absolute_path) == md5s[i]: misc.verbose_output("ok (matches)\n") else: misc.die("Mismatch again! Bailing out...") i = i + 1
def ensure_patchfiles_present(package): """Check if patches required to build the package are present, try to fetch them otherwise.""" patches = conf.get_config_value('patches', package).split(", ") md5s = None if package + "_md5" in conf.config['patches']: md5s = conf.get_config_value('patches', package + "_md5").split(", ") patchdir = globalvars.SUBSTITUTION_MAP['rbuild_patches_dir'] + '/' + package misc.verbose_output("Patches: Ensuring directory \"" + patchdir + "\" exists... ") if not os.path.isdir(patchdir): try: os.makedirs(patchdir) except OSError as e: misc.die("\nPatches error: Could not create directory \"" + patchdir + "\"! Exiting.") misc.verbose_output("ok\n") i = 0 for uri in patches: filename = os.path.basename(uri) absolute_path = patchdir + '/' + filename if not os.path.isfile(absolute_path): misc.fetch_file(uri, patchdir, filename) misc.verbose_output("Comparing checksums for patch " + str(i) + "... ") if md5s == None: misc.verbose_output("skipping (not available)\n") else: if misc.get_file_hash(absolute_path) == md5s[i]: misc.verbose_output("ok (matches)\n") else: misc.verbose_output("Mismatch! Fetching again...\n") misc.remove_file_or_dir(absolute_path) misc.fetch_file(uri, patchdir, filename) misc.verbose_output("Comparing checksums once more... ") if misc.get_file_hash(absolute_path) == md5s[i]: misc.verbose_output("ok (matches)\n") else: misc.die("Mismatch again! Bailing out...") i = i + 1
def ensure_distfile(mode, package): """Ensure that the compressed or uncompressed ("mode") distfile for a package is present.""" if mode == "compressed": distdir = globalvars.SUBSTITUTION_MAP['rbuild_dist_comp_dir'] filename = misc.get_filename('distfiles', package) hashtype = "md5" elif mode == "uncompressed": distdir = globalvars.SUBSTITUTION_MAP['rbuild_dist_uncomp_dir'] filename = os.path.basename(misc.get_tarball_uri(package)) hashtype = "umd5" else: misc.die("Invalid ensure_distfile mode \"" + mode + "\"! Aborting...") absolute_path = distdir + '/' + filename if not os.path.isfile(absolute_path): if mode == "compressed": misc.fetch_file(conf.get_config_value('distfiles', package), distdir, filename) else: misc.decompress_file(globalvars.SUBSTITUTION_MAP['rbuild_dist_comp_dir'], misc.get_filename('distfiles', package), distdir) checksum = misc.get_distfile_checksum(hashtype, package) misc.verbose_output("Checksum for \"" + package + "\": Comparing for " + mode + " distfile... ") if checksum == None: misc.verbose_output("skipping (not available)\n") else: if misc.get_file_hash(absolute_path) == checksum: misc.verbose_output("ok (matches)\n") else: if mode == "compressed": misc.verbose_output("Mismatch! Fetching again...\n") misc.remove_file_or_dir(absolute_path) misc.fetch_file(conf.get_config_value('distfiles', package), globalvars.SUBSTITUTION_MAP['rbuild_dist_comp_dir'], filename) misc.verbose_output("Comparing checksums once more... ") if misc.get_file_hash(absolute_path) == checksum: misc.verbose_output("ok (matches)\n") else: misc.die("Mismatch again! Bailing out...") else: misc.verbose_output("Mismatch! Extracting again...\n") misc.die("Extract again!")
if p in conf.config['make_cmds']: build_package('make', p) build_package('install', p) ########## # Main # ########## conf.assert_conf_file_present() conf.config = configparser.ConfigParser() conf.config.read(globalvars.CONFNAME) conf.assert_config_valid() globalvars.OSNAME = platform.get_osname() if not globalvars.OSNAME in globalvars.OPERATING_SYSTEMS_SUPPORTED: misc.die("Unsupported OS: \"" + globalvars.OSNAME + "\"!") globalvars.OSRELEASE = platform.get_os_release() globalvars.OSVERSION = platform.get_os_version() globalvars.OSMAJOR = platform.get_os_major() globalvars.OSARCH = platform.get_os_arch() globalvars.STDARCH = platform.get_stdarch() globalvars.TGT_TRIPLE = platform.assemble_triple() print("System: Set for " + globalvars.TGT_TRIPLE + ".") subst.populate_substitution_map() misc.assert_external_binaries_available() misc.ensure_fs_hierarchy('rjail') misc.ensure_fs_hierarchy('rbuild') print("Filesystem: Hierarchy is in place.") packages_present, packages_missing = misc.detect_packages() print_info()