def read_config(mandatory_opts): loader = KeyValuePairFileLoader( '/etc/dispatch-conf.conf', None) opts, errors = loader.load() if not opts: print(_('dispatch-conf: Error reading /etc/dispatch-conf.conf; fatal'), file=sys.stderr) sys.exit(1) # Handle quote removal here, since KeyValuePairFileLoader doesn't do that. quotes = "\"'" for k, v in opts.items(): if v[:1] in quotes and v[:1] == v[-1:]: opts[k] = v[1:-1] for key in mandatory_opts: if key not in opts: if key == "merge": opts["merge"] = "sdiff --suppress-common-lines --output='%s' '%s' '%s'" else: print(_('dispatch-conf: Missing option "%s" in /etc/dispatch-conf.conf; fatal') % (key,), file=sys.stderr) if not os.path.exists(opts['archive-dir']): os.mkdir(opts['archive-dir']) # Use restrictive permissions by default, in order to protect # against vulnerabilities (like bug #315603 involving rcs). os.chmod(opts['archive-dir'], 0o700) elif not os.path.isdir(opts['archive-dir']): print(_('dispatch-conf: Config archive dir [%s] must exist; fatal') % (opts['archive-dir'],), file=sys.stderr) sys.exit(1) return opts
def read_config(mandatory_opts): eprefix = portage.settings["EPREFIX"] if portage._not_installed: config_path = os.path.join(portage.PORTAGE_BASE_PATH, "cnf", "dispatch-conf.conf") else: config_path = os.path.join(eprefix or os.sep, "etc/dispatch-conf.conf") loader = KeyValuePairFileLoader(config_path, None) opts, _errors = loader.load() if not opts: print( _("dispatch-conf: Error reading {}; fatal").format(config_path), file=sys.stderr, ) sys.exit(1) # Handle quote removal here, since KeyValuePairFileLoader doesn't do that. quotes = "\"'" for k, v in opts.items(): if v[:1] in quotes and v[:1] == v[-1:]: opts[k] = v[1:-1] for key in mandatory_opts: if key not in opts: if key == "merge": opts[ "merge"] = "sdiff --suppress-common-lines --output='%s' '%s' '%s'" else: print( _('dispatch-conf: Missing option "%s" in /etc/dispatch-conf.conf; fatal' ) % (key, ), file=sys.stderr, ) # archive-dir supports ${EPREFIX} expansion, in order to avoid hardcoding variables = {"EPREFIX": eprefix} opts["archive-dir"] = varexpand(opts["archive-dir"], mydict=variables) if not os.path.exists(opts["archive-dir"]): os.mkdir(opts["archive-dir"]) # Use restrictive permissions by default, in order to protect # against vulnerabilities (like bug #315603 involving rcs). os.chmod(opts["archive-dir"], 0o700) elif not os.path.isdir(opts["archive-dir"]): print( _("dispatch-conf: Config archive dir [%s] must exist; fatal") % (opts["archive-dir"], ), file=sys.stderr, ) sys.exit(1) return opts
def read_config(mandatory_opts): eprefix = portage.settings["EPREFIX"] if portage._not_installed: config_path = os.path.join(portage.PORTAGE_BASE_PATH, "cnf", "dispatch-conf.conf") else: config_path = os.path.join(eprefix or os.sep, "etc/dispatch-conf.conf") loader = KeyValuePairFileLoader(config_path, None) opts, _errors = loader.load() if not opts: print(_('dispatch-conf: Error reading /etc/dispatch-conf.conf; fatal'), file=sys.stderr) sys.exit(1) # Handle quote removal here, since KeyValuePairFileLoader doesn't do that. quotes = "\"'" for k, v in opts.items(): if v[:1] in quotes and v[:1] == v[-1:]: opts[k] = v[1:-1] for key in mandatory_opts: if key not in opts: if key == "merge": opts["merge"] = "sdiff --suppress-common-lines --output='%s' '%s' '%s'" else: print(_('dispatch-conf: Missing option "%s" in /etc/dispatch-conf.conf; fatal') % (key,), file=sys.stderr) # archive-dir supports ${EPREFIX} expansion, in order to avoid hardcoding variables = {"EPREFIX": eprefix} opts['archive-dir'] = varexpand(opts['archive-dir'], mydict=variables) if not os.path.exists(opts['archive-dir']): os.mkdir(opts['archive-dir']) # Use restrictive permissions by default, in order to protect # against vulnerabilities (like bug #315603 involving rcs). os.chmod(opts['archive-dir'], 0o700) elif not os.path.isdir(opts['archive-dir']): print(_('dispatch-conf: Config archive dir [%s] must exist; fatal') % (opts['archive-dir'],), file=sys.stderr) sys.exit(1) return opts
def parse_layout_conf(repo_location, repo_name=None): eapi = read_corresponding_eapi_file(os.path.join(repo_location, REPO_NAME_LOC)) layout_filename = os.path.join(repo_location, "metadata", "layout.conf") layout_file = KeyValuePairFileLoader(layout_filename, None, None) layout_data, layout_errors = layout_file.load() data = {} # None indicates abscence of a masters setting, which later code uses # to trigger a backward compatibility fallback that sets an implicit # master. In order to avoid this fallback behavior, layout.conf can # explicitly set masters to an empty value, which will result in an # empty tuple here instead of None. masters = layout_data.get('masters') if masters is not None: masters = tuple(masters.split()) data['masters'] = masters data['aliases'] = tuple(layout_data.get('aliases', '').split()) data['eapis-banned'] = tuple(layout_data.get('eapis-banned', '').split()) data['eapis-deprecated'] = tuple(layout_data.get('eapis-deprecated', '').split()) data['sign-commit'] = layout_data.get('sign-commits', 'false').lower() \ == 'true' data['sign-manifest'] = layout_data.get('sign-manifests', 'true').lower() \ == 'true' data['thin-manifest'] = layout_data.get('thin-manifests', 'false').lower() \ == 'true' data['repo-name'] = _gen_valid_repo(layout_data.get('repo-name', '')) manifest_policy = layout_data.get('use-manifests', 'strict').lower() data['allow-missing-manifest'] = manifest_policy != 'strict' data['create-manifest'] = manifest_policy != 'false' data['disable-manifest'] = manifest_policy == 'false' # for compatibility w/ PMS, fallback to pms; but also check if the # cache exists or not. cache_formats = layout_data.get('cache-formats', '').lower().split() if not cache_formats: # Auto-detect cache formats, and prefer md5-cache if available. # This behavior was deployed in portage-2.1.11.14, so that the # default egencache format could eventually be changed to md5-dict # in portage-2.1.11.32. WARNING: Versions prior to portage-2.1.11.14 # will NOT recognize md5-dict format unless it is explicitly # listed in layout.conf. cache_formats = [] if os.path.isdir(os.path.join(repo_location, 'metadata', 'md5-cache')): cache_formats.append('md5-dict') if os.path.isdir(os.path.join(repo_location, 'metadata', 'cache')): cache_formats.append('pms') data['cache-formats'] = tuple(cache_formats) manifest_hashes = layout_data.get('manifest-hashes') manifest_required_hashes = layout_data.get('manifest-required-hashes') if manifest_required_hashes is not None and manifest_hashes is None: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' specifies " "'manifest-required-hashes' setting without corresponding " "'manifest-hashes'. Portage will default it to match " "the required set but please add the missing entry " "to: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "layout_filename":layout_filename}), SyntaxWarning) manifest_hashes = manifest_required_hashes if manifest_hashes is not None: # require all the hashes unless specified otherwise if manifest_required_hashes is None: manifest_required_hashes = manifest_hashes manifest_required_hashes = frozenset(manifest_required_hashes.upper().split()) manifest_hashes = frozenset(manifest_hashes.upper().split()) missing_required_hashes = manifest_required_hashes.difference( manifest_hashes) if missing_required_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that does not contain " "the '%(hash)s' hashes which are listed in " "'manifest-required-hashes'. Please fix that file " "if you want to generate valid manifests for this " "repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hash": ' '.join(missing_required_hashes), "layout_filename":layout_filename}), SyntaxWarning) unsupported_hashes = manifest_hashes.difference( get_valid_checksum_keys()) if unsupported_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that contains one " "or more hash types '%(hashes)s' which are not supported by " "this portage version. You will have to upgrade " "portage if you want to generate valid manifests for " "this repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hashes":" ".join(sorted(unsupported_hashes)), "layout_filename":layout_filename}), DeprecationWarning) data['manifest-hashes'] = manifest_hashes data['manifest-required-hashes'] = manifest_required_hashes data['update-changelog'] = layout_data.get('update-changelog', 'false').lower() \ == 'true' raw_formats = layout_data.get('profile-formats') if raw_formats is None: if eapi_allows_directories_on_profile_level_and_repository_level(eapi): raw_formats = ('portage-1',) else: raw_formats = ('portage-1-compat',) else: raw_formats = set(raw_formats.split()) unknown = raw_formats.difference(_valid_profile_formats) if unknown: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has unsupported " "profiles in use ('profile-formats = %(unknown_fmts)s' setting in " "'%(layout_filename)s; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename, unknown_fmts=" ".join(unknown))), DeprecationWarning) raw_formats = tuple(raw_formats.intersection(_valid_profile_formats)) data['profile-formats'] = raw_formats try: eapi = layout_data['profile_eapi_when_unspecified'] except KeyError: pass else: if 'profile-default-eapi' not in raw_formats: warnings.warn((_("Repository named '%(repo_name)s' has " "profile_eapi_when_unspecified setting in " "'%(layout_filename)s', but 'profile-default-eapi' is " "not listed in the profile-formats field. Please " "report this issue to the repository maintainer.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename)), SyntaxWarning) elif not portage.eapi_is_supported(eapi): warnings.warn((_("Repository named '%(repo_name)s' has " "unsupported EAPI '%(eapi)s' setting in " "'%(layout_filename)s'; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', eapi=eapi, layout_filename=layout_filename)), SyntaxWarning) else: data['profile_eapi_when_unspecified'] = eapi return data, layout_errors
def ExtractKernelVersion(base_dir): """ Try to figure out what kernel version we are running @param base_dir: Path to sources (usually /usr/src/linux) @type base_dir: string @rtype: tuple( version[string], error[string]) @return: 1. tuple( version[string], error[string]) Either version or error is populated (but never both) """ lines = [] pathname = os.path.join(base_dir, 'Makefile') try: f = io.open(_unicode_encode(pathname, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['content'], errors='replace') except OSError as details: return (None, str(details)) except IOError as details: return (None, str(details)) try: for i in range(4): lines.append(f.readline()) except OSError as details: return (None, str(details)) except IOError as details: return (None, str(details)) finally: f.close() lines = [l.strip() for l in lines] version = '' #XXX: The following code relies on the ordering of vars within the Makefile for line in lines: # split on the '=' then remove annoying whitespace items = line.split("=") items = [i.strip() for i in items] if items[0] == 'VERSION' or \ items[0] == 'PATCHLEVEL': version += items[1] version += "." elif items[0] == 'SUBLEVEL': version += items[1] elif items[0] == 'EXTRAVERSION' and \ items[-1] != items[0]: version += items[1] # Grab a list of files named localversion* and sort them localversions = os.listdir(base_dir) for x in range(len(localversions) - 1, -1, -1): if localversions[x][:12] != "localversion": del localversions[x] localversions.sort() # Append the contents of each to the version string, stripping ALL whitespace for lv in localversions: version += "".join(" ".join(grabfile(base_dir + "/" + lv)).split()) # Check the .config for a CONFIG_LOCALVERSION and append that too, also stripping whitespace loader = KeyValuePairFileLoader(os.path.join(base_dir, ".config"), None) kernelconfig, loader_errors = loader.load() if loader_errors: for file_path, file_errors in loader_errors.items(): for error_str in file_errors: writemsg_level("%s: %s\n" % (file_path, error_str), level=logging.ERROR, noiselevel=-1) if kernelconfig and "CONFIG_LOCALVERSION" in kernelconfig: version += "".join(shlex_split(kernelconfig["CONFIG_LOCALVERSION"])) return (version, None)
def parse_layout_conf(repo_location, repo_name=None): eapi = read_corresponding_eapi_file( os.path.join(repo_location, REPO_NAME_LOC)) layout_filename = os.path.join(repo_location, "metadata", "layout.conf") layout_file = KeyValuePairFileLoader(layout_filename, None, None) layout_data, layout_errors = layout_file.load() data = {} # None indicates abscence of a masters setting, which later code uses # to trigger a backward compatibility fallback that sets an implicit # master. In order to avoid this fallback behavior, layout.conf can # explicitly set masters to an empty value, which will result in an # empty tuple here instead of None. masters = layout_data.get('masters') if masters is not None: masters = tuple(masters.split()) data['masters'] = masters data['aliases'] = tuple(layout_data.get('aliases', '').split()) data['allow-provide-virtual'] = \ layout_data.get('allow-provide-virtuals', 'false').lower() == 'true' data['eapis-banned'] = tuple(layout_data.get('eapis-banned', '').split()) data['eapis-deprecated'] = tuple( layout_data.get('eapis-deprecated', '').split()) data['sign-commit'] = layout_data.get('sign-commits', 'false').lower() \ == 'true' data['sign-manifest'] = layout_data.get('sign-manifests', 'true').lower() \ == 'true' data['thin-manifest'] = layout_data.get('thin-manifests', 'false').lower() \ == 'true' data['repo-name'] = _gen_valid_repo(layout_data.get('repo-name', '')) manifest_policy = layout_data.get('use-manifests', 'strict').lower() data['allow-missing-manifest'] = manifest_policy != 'strict' data['create-manifest'] = manifest_policy != 'false' data['disable-manifest'] = manifest_policy == 'false' # for compatibility w/ PMS, fallback to pms; but also check if the # cache exists or not. cache_formats = layout_data.get('cache-formats', '').lower().split() if not cache_formats: # Auto-detect cache formats, and prefer md5-cache if available. # This behavior was deployed in portage-2.1.11.14, so that the # default egencache format could eventually be changed to md5-dict # in portage-2.1.11.32. WARNING: Versions prior to portage-2.1.11.14 # will NOT recognize md5-dict format unless it is explicitly # listed in layout.conf. cache_formats = [] if os.path.isdir(os.path.join(repo_location, 'metadata', 'md5-cache')): cache_formats.append('md5-dict') if os.path.isdir(os.path.join(repo_location, 'metadata', 'cache')): cache_formats.append('pms') data['cache-formats'] = tuple(cache_formats) manifest_hashes = layout_data.get('manifest-hashes') if manifest_hashes is not None: manifest_hashes = frozenset(manifest_hashes.upper().split()) if MANIFEST2_REQUIRED_HASH not in manifest_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn( (_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that does not contain " "the '%(hash)s' hash which is required by this " "portage version. You will have to upgrade portage " "if you want to generate valid manifests for this " "repository: %(layout_filename)s") % { "repo_name": repo_name or 'unspecified', "hash": MANIFEST2_REQUIRED_HASH, "layout_filename": layout_filename }), DeprecationWarning) unsupported_hashes = manifest_hashes.difference( MANIFEST2_HASH_FUNCTIONS) if unsupported_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn(( _("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that contains one " "or more hash types '%(hashes)s' which are not supported by " "this portage version. You will have to upgrade " "portage if you want to generate valid manifests for " "this repository: %(layout_filename)s") % { "repo_name": repo_name or 'unspecified', "hashes": " ".join(sorted(unsupported_hashes)), "layout_filename": layout_filename }), DeprecationWarning) data['manifest-hashes'] = manifest_hashes data['update-changelog'] = layout_data.get('update-changelog', 'false').lower() \ == 'true' raw_formats = layout_data.get('profile-formats') if raw_formats is None: if eapi_allows_directories_on_profile_level_and_repository_level(eapi): raw_formats = ('portage-1', ) else: raw_formats = ('portage-1-compat', ) else: raw_formats = set(raw_formats.split()) unknown = raw_formats.difference(_valid_profile_formats) if unknown: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_( "Repository named '%(repo_name)s' has unsupported " "profiles in use ('profile-formats = %(unknown_fmts)s' setting in " "'%(layout_filename)s; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename, unknown_fmts=" ".join(unknown))), DeprecationWarning) raw_formats = tuple(raw_formats.intersection(_valid_profile_formats)) data['profile-formats'] = raw_formats try: eapi = layout_data['profile_eapi_when_unspecified'] except KeyError: pass else: if 'profile-default-eapi' not in raw_formats: warnings.warn( (_("Repository named '%(repo_name)s' has " "profile_eapi_when_unspecified setting in " "'%(layout_filename)s', but 'profile-default-eapi' is " "not listed in the profile-formats field. Please " "report this issue to the repository maintainer.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename)), SyntaxWarning) elif not portage.eapi_is_supported(eapi): warnings.warn( (_("Repository named '%(repo_name)s' has " "unsupported EAPI '%(eapi)s' setting in " "'%(layout_filename)s'; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', eapi=eapi, layout_filename=layout_filename)), SyntaxWarning) else: data['profile_eapi_when_unspecified'] = eapi return data, layout_errors
def parse_layout_conf(repo_location, repo_name=None): eapi = read_corresponding_eapi_file(os.path.join(repo_location, REPO_NAME_LOC)) layout_filename = os.path.join(repo_location, "metadata", "layout.conf") layout_file = KeyValuePairFileLoader(layout_filename, None, None) layout_data, layout_errors = layout_file.load() data = {} # None indicates abscence of a masters setting, which later code uses # to trigger a backward compatibility fallback that sets an implicit # master. In order to avoid this fallback behavior, layout.conf can # explicitly set masters to an empty value, which will result in an # empty tuple here instead of None. masters = layout_data.get('masters') if masters is not None: masters = tuple(masters.split()) data['masters'] = masters data['aliases'] = tuple(layout_data.get('aliases', '').split()) data['allow-provide-virtual'] = \ layout_data.get('allow-provide-virtuals', 'false').lower() == 'true' data['sign-commit'] = layout_data.get('sign-commits', 'false').lower() \ == 'true' data['sign-manifest'] = layout_data.get('sign-manifests', 'true').lower() \ == 'true' data['thin-manifest'] = layout_data.get('thin-manifests', 'false').lower() \ == 'true' manifest_policy = layout_data.get('use-manifests', 'strict').lower() data['allow-missing-manifest'] = manifest_policy != 'strict' data['create-manifest'] = manifest_policy != 'false' data['disable-manifest'] = manifest_policy == 'false' # for compatibility w/ PMS, fallback to pms; but also check if the # cache exists or not. cache_formats = layout_data.get('cache-formats', '').lower().split() if not cache_formats: # Auto-detect cache formats, and prefer md5-cache if available. # After this behavior is deployed in stable portage, the default # egencache format can be changed to md5-dict. cache_formats = [] if os.path.isdir(os.path.join(repo_location, 'metadata', 'md5-cache')): cache_formats.append('md5-dict') if os.path.isdir(os.path.join(repo_location, 'metadata', 'cache')): cache_formats.append('pms') data['cache-formats'] = tuple(cache_formats) manifest_hashes = layout_data.get('manifest-hashes') if manifest_hashes is not None: manifest_hashes = frozenset(manifest_hashes.upper().split()) if MANIFEST2_REQUIRED_HASH not in manifest_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that does not contain " "the '%(hash)s' hash which is required by this " "portage version. You will have to upgrade portage " "if you want to generate valid manifests for this " "repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hash":MANIFEST2_REQUIRED_HASH, "layout_filename":layout_filename}), DeprecationWarning) unsupported_hashes = manifest_hashes.difference( MANIFEST2_HASH_FUNCTIONS) if unsupported_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that contains one " "or more hash types '%(hashes)s' which are not supported by " "this portage version. You will have to upgrade " "portage if you want to generate valid manifests for " "this repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hashes":" ".join(sorted(unsupported_hashes)), "layout_filename":layout_filename}), DeprecationWarning) data['manifest-hashes'] = manifest_hashes data['update-changelog'] = layout_data.get('update-changelog', 'false').lower() \ == 'true' raw_formats = layout_data.get('profile-formats') if raw_formats is None: if eapi_allows_directories_on_profile_level_and_repository_level(eapi): raw_formats = ('portage-1',) else: raw_formats = ('portage-1-compat',) else: raw_formats = set(raw_formats.split()) unknown = raw_formats.difference(_valid_profile_formats) if unknown: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has unsupported " "profiles in use ('profile-formats = %(unknown_fmts)s' setting in " "'%(layout_filename)s; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename, unknown_fmts=" ".join(unknown))), DeprecationWarning) raw_formats = tuple(raw_formats.intersection(_valid_profile_formats)) data['profile-formats'] = raw_formats return data, layout_errors
def parse_layout_conf(repo_location, repo_name=None): eapi = read_corresponding_eapi_file(os.path.join(repo_location, REPO_NAME_LOC)) layout_filename = os.path.join(repo_location, "metadata", "layout.conf") layout_file = KeyValuePairFileLoader(layout_filename, None, None) layout_data, layout_errors = layout_file.load() data = {} # None indicates abscence of a masters setting, which later code uses # to trigger a backward compatibility fallback that sets an implicit # master. In order to avoid this fallback behavior, layout.conf can # explicitly set masters to an empty value, which will result in an # empty tuple here instead of None. masters = layout_data.get("masters") if masters is not None: masters = tuple(masters.split()) data["masters"] = masters data["aliases"] = tuple(layout_data.get("aliases", "").split()) data["allow-provide-virtual"] = layout_data.get("allow-provide-virtuals", "false").lower() == "true" data["eapis-banned"] = tuple(layout_data.get("eapis-banned", "").split()) data["eapis-deprecated"] = tuple(layout_data.get("eapis-deprecated", "").split()) data["sign-commit"] = layout_data.get("sign-commits", "false").lower() == "true" data["sign-manifest"] = layout_data.get("sign-manifests", "true").lower() == "true" data["thin-manifest"] = layout_data.get("thin-manifests", "false").lower() == "true" data["repo-name"] = _gen_valid_repo(layout_data.get("repo-name", "")) manifest_policy = layout_data.get("use-manifests", "strict").lower() data["allow-missing-manifest"] = manifest_policy != "strict" data["create-manifest"] = manifest_policy != "false" data["disable-manifest"] = manifest_policy == "false" # for compatibility w/ PMS, fallback to pms; but also check if the # cache exists or not. cache_formats = layout_data.get("cache-formats", "").lower().split() if not cache_formats: # Auto-detect cache formats, and prefer md5-cache if available. # This behavior was deployed in portage-2.1.11.14, so that the # default egencache format could eventually be changed to md5-dict # in portage-2.1.11.32. WARNING: Versions prior to portage-2.1.11.14 # will NOT recognize md5-dict format unless it is explicitly # listed in layout.conf. cache_formats = [] if os.path.isdir(os.path.join(repo_location, "metadata", "md5-cache")): cache_formats.append("md5-dict") if os.path.isdir(os.path.join(repo_location, "metadata", "cache")): cache_formats.append("pms") data["cache-formats"] = tuple(cache_formats) manifest_hashes = layout_data.get("manifest-hashes") if manifest_hashes is not None: manifest_hashes = frozenset(manifest_hashes.upper().split()) if MANIFEST2_REQUIRED_HASH not in manifest_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn( ( _( "Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that does not contain " "the '%(hash)s' hash which is required by this " "portage version. You will have to upgrade portage " "if you want to generate valid manifests for this " "repository: %(layout_filename)s" ) % { "repo_name": repo_name or "unspecified", "hash": MANIFEST2_REQUIRED_HASH, "layout_filename": layout_filename, } ), DeprecationWarning, ) unsupported_hashes = manifest_hashes.difference(MANIFEST2_HASH_FUNCTIONS) if unsupported_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn( ( _( "Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that contains one " "or more hash types '%(hashes)s' which are not supported by " "this portage version. You will have to upgrade " "portage if you want to generate valid manifests for " "this repository: %(layout_filename)s" ) % { "repo_name": repo_name or "unspecified", "hashes": " ".join(sorted(unsupported_hashes)), "layout_filename": layout_filename, } ), DeprecationWarning, ) data["manifest-hashes"] = manifest_hashes data["update-changelog"] = layout_data.get("update-changelog", "false").lower() == "true" raw_formats = layout_data.get("profile-formats") if raw_formats is None: if eapi_allows_directories_on_profile_level_and_repository_level(eapi): raw_formats = ("portage-1",) else: raw_formats = ("portage-1-compat",) else: raw_formats = set(raw_formats.split()) unknown = raw_formats.difference(_valid_profile_formats) if unknown: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn( ( _( "Repository named '%(repo_name)s' has unsupported " "profiles in use ('profile-formats = %(unknown_fmts)s' setting in " "'%(layout_filename)s; please upgrade portage." ) % dict( repo_name=repo_name or "unspecified", layout_filename=layout_filename, unknown_fmts=" ".join(unknown), ) ), DeprecationWarning, ) raw_formats = tuple(raw_formats.intersection(_valid_profile_formats)) data["profile-formats"] = raw_formats try: eapi = layout_data["profile_eapi_when_unspecified"] except KeyError: pass else: if "profile-default-eapi" not in raw_formats: warnings.warn( ( _( "Repository named '%(repo_name)s' has " "profile_eapi_when_unspecified setting in " "'%(layout_filename)s', but 'profile-default-eapi' is " "not listed in the profile-formats field. Please " "report this issue to the repository maintainer." ) % dict(repo_name=repo_name or "unspecified", layout_filename=layout_filename) ), SyntaxWarning, ) elif not portage.eapi_is_supported(eapi): warnings.warn( ( _( "Repository named '%(repo_name)s' has " "unsupported EAPI '%(eapi)s' setting in " "'%(layout_filename)s'; please upgrade portage." ) % dict(repo_name=repo_name or "unspecified", eapi=eapi, layout_filename=layout_filename) ), SyntaxWarning, ) else: data["profile_eapi_when_unspecified"] = eapi return data, layout_errors
def parse_layout_conf(repo_location, repo_name=None): eapi = read_corresponding_eapi_file(os.path.join(repo_location, REPO_NAME_LOC)) layout_filename = os.path.join(repo_location, "metadata", "layout.conf") layout_file = KeyValuePairFileLoader(layout_filename, None, None) layout_data, layout_errors = layout_file.load() data = {} # None indicates abscence of a masters setting, which later code uses # to trigger a backward compatibility fallback that sets an implicit # master. In order to avoid this fallback behavior, layout.conf can # explicitly set masters to an empty value, which will result in an # empty tuple here instead of None. masters = layout_data.get('masters') if masters is not None: masters = tuple(masters.split()) data['masters'] = masters data['aliases'] = tuple(layout_data.get('aliases', '').split()) data['allow-provide-virtual'] = \ layout_data.get('allow-provide-virtuals', 'false').lower() == 'true' data['sign-commit'] = layout_data.get('sign-commits', 'false').lower() \ == 'true' data['sign-manifest'] = layout_data.get('sign-manifests', 'true').lower() \ == 'true' data['thin-manifest'] = layout_data.get('thin-manifests', 'false').lower() \ == 'true' manifest_policy = layout_data.get('use-manifests', 'strict').lower() data['allow-missing-manifest'] = manifest_policy != 'strict' data['create-manifest'] = manifest_policy != 'false' data['disable-manifest'] = manifest_policy == 'false' # for compatibility w/ PMS, fallback to pms; but also check if the # cache exists or not. cache_formats = layout_data.get('cache-formats', 'pms').lower().split() if 'pms' in cache_formats and not os.path.isdir( os.path.join(repo_location, 'metadata', 'cache')): cache_formats.remove('pms') data['cache-formats'] = tuple(cache_formats) manifest_hashes = layout_data.get('manifest-hashes') if manifest_hashes is not None: manifest_hashes = frozenset(manifest_hashes.upper().split()) if MANIFEST2_REQUIRED_HASH not in manifest_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that does not contain " "the '%(hash)s' hash which is required by this " "portage version. You will have to upgrade portage " "if you want to generate valid manifests for this " "repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hash":MANIFEST2_REQUIRED_HASH, "layout_filename":layout_filename}), DeprecationWarning) unsupported_hashes = manifest_hashes.difference( MANIFEST2_HASH_FUNCTIONS) if unsupported_hashes: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has a " "'manifest-hashes' setting that contains one " "or more hash types '%(hashes)s' which are not supported by " "this portage version. You will have to upgrade " "portage if you want to generate valid manifests for " "this repository: %(layout_filename)s") % {"repo_name": repo_name or 'unspecified', "hashes":" ".join(sorted(unsupported_hashes)), "layout_filename":layout_filename}), DeprecationWarning) data['manifest-hashes'] = manifest_hashes data['update-changelog'] = layout_data.get('update-changelog', 'false').lower() \ == 'true' raw_formats = layout_data.get('profile-formats') if raw_formats is None: if eapi in ('4-python',): raw_formats = ('portage-1',) else: raw_formats = ('portage-1-compat',) else: raw_formats = set(raw_formats.split()) unknown = raw_formats.difference(['pms', 'portage-1']) if unknown: repo_name = _get_repo_name(repo_location, cached=repo_name) warnings.warn((_("Repository named '%(repo_name)s' has unsupported " "profiles in use ('profile-formats = %(unknown_fmts)s' setting in " "'%(layout_filename)s; please upgrade portage.") % dict(repo_name=repo_name or 'unspecified', layout_filename=layout_filename, unknown_fmts=" ".join(unknown))), DeprecationWarning) raw_formats = tuple(raw_formats.intersection(['pms', 'portage-1'])) data['profile-formats'] = raw_formats return data, layout_errors