Example #1
0
 def _check_var_directory(self, varname, var):
     if not isdir_raise_eaccess(var):
         writemsg(
             _("!!! Error: %s='%s' is not a directory. "
               "Please correct this.\n") % (varname, var),
             noiselevel=-1,
         )
         raise DirectoryNotFound(var)
Example #2
0
	def _check_locations(self):
		"""Check if repositories location are correct and show a warning message if not"""
		for (name, r) in self.prepos.items():
			if name != 'DEFAULT':
				if r.location is None:
					writemsg(_("!!! Location not set for repository %s\n") % name, noiselevel=-1)
				else:
					if not isdir_raise_eaccess(r.location) and not portage._sync_mode:
						self.prepos_order.remove(name)
						writemsg(_("!!! Invalid Repository Location"
							" (not a dir): '%s'\n") % r.location, noiselevel=-1)
Example #3
0
	def _check_locations(self):
		"""Check if repositories location are correct and show a warning message if not"""
		for (name, r) in self.prepos.items():
			if name != 'DEFAULT':
				if r.location is None:
					writemsg(_("!!! Location not set for repository %s\n") % name, noiselevel=-1)
				else:
					if not isdir_raise_eaccess(r.location) and not portage._sync_mode:
						self.prepos_order.remove(name)
						writemsg(_("!!! Invalid Repository Location"
							" (not a dir): '%s'\n") % r.location, noiselevel=-1)
Example #4
0
	def set_port_dirs(self, portdir, portdir_overlay):
		self.portdir = portdir
		self.portdir_overlay = portdir_overlay
		if self.portdir_overlay is None:
			self.portdir_overlay = ""

		self.overlay_profiles = []
		for ov in shlex_split(self.portdir_overlay):
			ov = normalize_path(ov)
			profiles_dir = os.path.join(ov, "profiles")
			if isdir_raise_eaccess(profiles_dir):
				self.overlay_profiles.append(profiles_dir)

		self.profile_locations = [os.path.join(portdir, "profiles")] + self.overlay_profiles
		self.profile_and_user_locations = self.profile_locations[:]
		if self._user_config:
			self.profile_and_user_locations.append(self.abs_user_config)

		self.profile_locations = tuple(self.profile_locations)
		self.profile_and_user_locations = tuple(self.profile_and_user_locations)
Example #5
0
	def set_port_dirs(self, portdir, portdir_overlay):
		self.portdir = portdir
		self.portdir_overlay = portdir_overlay
		if self.portdir_overlay is None:
			self.portdir_overlay = ""

		self.overlay_profiles = []
		for ov in shlex_split(self.portdir_overlay):
			ov = normalize_path(ov)
			profiles_dir = os.path.join(ov, "profiles")
			if isdir_raise_eaccess(profiles_dir):
				self.overlay_profiles.append(profiles_dir)

		self.profile_locations = [os.path.join(portdir, "profiles")] + self.overlay_profiles
		self.profile_and_user_locations = self.profile_locations[:]
		if self._user_config:
			self.profile_and_user_locations.append(self.abs_user_config)

		self.profile_locations = tuple(self.profile_locations)
		self.profile_and_user_locations = tuple(self.profile_and_user_locations)
Example #6
0
	def __init__(self, paths, settings):
		"""Load config from files in paths"""

		prepos = {}
		location_map = {}
		treemap = {}
		ignored_map = {}
		default_opts = {
			"EPREFIX" : settings["EPREFIX"],
			"EROOT" : settings["EROOT"],
			"PORTAGE_CONFIGROOT" : settings["PORTAGE_CONFIGROOT"],
			"ROOT" : settings["ROOT"],
		}

		if "PORTAGE_REPOSITORIES" in settings:
			portdir = ""
			portdir_overlay = ""
			# deprecated portdir_sync
			portdir_sync = ""
		else:
			portdir = settings.get("PORTDIR", "")
			portdir_overlay = settings.get("PORTDIR_OVERLAY", "")
			# deprecated portdir_sync
			portdir_sync = settings.get("SYNC", "")

		default_opts['sync-rsync-extra-opts'] = \
			settings.get("PORTAGE_RSYNC_EXTRA_OPTS", "")

		try:
			self._parse(paths, prepos, settings.local_config, default_opts)
		except ConfigParserError as e:
			writemsg(
				_("!!! Error while reading repo config file: %s\n") % e,
				noiselevel=-1)
			# The configparser state is unreliable (prone to quirky
			# exceptions) after it has thrown an error, so use empty
			# config and try to fall back to PORTDIR{,_OVERLAY}.
			prepos.clear()
			prepos['DEFAULT'] = RepoConfig('DEFAULT',
				{}, local_config=settings.local_config)
			location_map.clear()
			treemap.clear()

		default_portdir = os.path.join(os.sep,
			settings['EPREFIX'].lstrip(os.sep), 'usr', 'portage')

		# If PORTDIR_OVERLAY contains a repo with the same repo_name as
		# PORTDIR, then PORTDIR is overridden.
		portdir = self._add_repositories(portdir, portdir_overlay, prepos,
			ignored_map, settings.local_config,
			default_portdir)
		if portdir and portdir.strip():
			portdir = os.path.realpath(portdir)

		ignored_repos = tuple((repo_name, tuple(paths)) \
			for repo_name, paths in ignored_map.items())

		self.missing_repo_names = frozenset(repo.location
			for repo in prepos.values()
			if repo.location is not None and repo.missing_repo_name)

		# Do this before expanding aliases, so that location_map and
		# treemap consistently map unaliased names whenever available.
		for repo_name, repo in list(prepos.items()):
			if repo.location is None:
				if repo_name != 'DEFAULT':
					# Skip this warning for repoman (bug #474578).
					if settings.local_config and paths:
						writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf is missing location attribute") %
							repo.name, level=logging.ERROR, noiselevel=-1)
					del prepos[repo_name]
					continue
			else:
				if not portage._sync_mode:
					if not isdir_raise_eaccess(repo.location):
						writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf has location attribute set "
							"to nonexistent directory: '%s'") %
							(repo_name, repo.location), level=logging.ERROR, noiselevel=-1)

						# Ignore missing directory for 'gentoo' so that
						# first sync with emerge-webrsync is possible.
						if repo.name != 'gentoo':
							del prepos[repo_name]
							continue

					# After removing support for PORTDIR_OVERLAY, the following check can be:
					# if repo.missing_repo_name:
					if repo.missing_repo_name and repo.name != repo_name:
						writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf refers to repository "
							"without repository name set in '%s'") %
							(repo_name, os.path.join(repo.location, REPO_NAME_LOC)), level=logging.ERROR, noiselevel=-1)
						del prepos[repo_name]
						continue

					if repo.name != repo_name:
						writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf has name different "
							"from repository name '%s' set inside repository") %
							(repo_name, repo.name), level=logging.ERROR, noiselevel=-1)
						del prepos[repo_name]
						continue

				location_map[repo.location] = repo_name
				treemap[repo_name] = repo.location

		# Add alias mappings, but never replace unaliased mappings.
		for repo_name, repo in list(prepos.items()):
			names = set()
			names.add(repo_name)
			if repo.aliases:
				aliases = stack_lists([repo.aliases], incremental=True)
				names.update(aliases)

			for name in names:
				if name in prepos and prepos[name].location is not None:
					if name == repo_name:
						# unaliased names already handled earlier
						continue
					writemsg_level(_("!!! Repository name or alias '%s', " + \
						"defined for repository '%s', overrides " + \
						"existing alias or repository.\n") % (name, repo_name), level=logging.WARNING, noiselevel=-1)
					# Never replace an unaliased mapping with
					# an aliased mapping.
					continue
				prepos[name] = repo
				if repo.location is not None:
					if repo.location not in location_map:
						# Never replace an unaliased mapping with
						# an aliased mapping.
						location_map[repo.location] = name
					treemap[name] = repo.location

		main_repo = prepos['DEFAULT'].main_repo
		if main_repo is None or main_repo not in prepos:
			#setting main_repo if it was not set in repos.conf
			main_repo = location_map.get(portdir)
			if main_repo is not None:
				prepos['DEFAULT'].main_repo = main_repo
			else:
				prepos['DEFAULT'].main_repo = None
				if portdir and not portage._sync_mode:
					writemsg(_("!!! main-repo not set in DEFAULT and PORTDIR is empty.\n"), noiselevel=-1)

		if main_repo is not None and prepos[main_repo].priority is None:
			# This happens if main-repo has been set in repos.conf.
			prepos[main_repo].priority = -1000

		# DEPRECATED Backward compatible SYNC support for old mirrorselect.
		# Feb. 2, 2015.  Version 2.2.16
		if portdir_sync and main_repo is not None:
			writemsg(_("!!! SYNC setting found in make.conf.\n    "
				"This setting is Deprecated and no longer used.  "
				"Please ensure your 'sync-type' and 'sync-uri' are set correctly"
				" in /etc/portage/repos.conf/gentoo.conf\n"),
				noiselevel=-1)


		# Include repo.name in sort key, for predictable sorting
		# even when priorities are equal.
		prepos_order = sorted(prepos.items(),
			key=lambda r:(r[1].priority or 0, r[1].name))

		# filter duplicates from aliases, by only including
		# items where repo.name == key
		prepos_order = [repo.name for (key, repo) in prepos_order
			if repo.name == key and key != 'DEFAULT' and
			repo.location is not None]

		self.prepos = prepos
		self.prepos_order = prepos_order
		self.ignored_repos = ignored_repos
		self.location_map = location_map
		self.treemap = treemap
		self._prepos_changed = True
		self._repo_location_list = []

		#The 'masters' key currently contains repo names. Replace them with the matching RepoConfig.
		for repo_name, repo in prepos.items():
			if repo_name == "DEFAULT":
				continue
			if repo.masters is None:
				if self.mainRepo() and repo_name != self.mainRepo().name:
					repo.masters = self.mainRepo(),
				else:
					repo.masters = ()
			else:
				if repo.masters and isinstance(repo.masters[0], RepoConfig):
					# This one has already been processed
					# because it has an alias.
					continue
				master_repos = []
				for master_name in repo.masters:
					if master_name not in prepos:
						layout_filename = os.path.join(repo.location,
							"metadata", "layout.conf")
						writemsg_level(_("Unavailable repository '%s' " \
							"referenced by masters entry in '%s'\n") % \
							(master_name, layout_filename),
							level=logging.ERROR, noiselevel=-1)
					else:
						master_repos.append(prepos[master_name])
				repo.masters = tuple(master_repos)

		#The 'eclass_overrides' key currently contains repo names. Replace them with the matching repo paths.
		for repo_name, repo in prepos.items():
			if repo_name == "DEFAULT":
				continue

			eclass_locations = []
			eclass_locations.extend(master_repo.location for master_repo in repo.masters)
			# Only append the current repo to eclass_locations if it's not
			# there already. This allows masters to have more control over
			# eclass override order, which may be useful for scenarios in
			# which there is a plan to migrate eclasses to a master repo.
			if repo.location not in eclass_locations:
				eclass_locations.append(repo.location)

			if repo.eclass_overrides:
				for other_repo_name in repo.eclass_overrides:
					if other_repo_name in self.treemap:
						eclass_locations.append(self.get_location_for_name(other_repo_name))
					else:
						writemsg_level(_("Unavailable repository '%s' " \
							"referenced by eclass-overrides entry for " \
							"'%s'\n") % (other_repo_name, repo_name), \
							level=logging.ERROR, noiselevel=-1)
			repo.eclass_locations = tuple(eclass_locations)

		eclass_dbs = {}
		for repo_name, repo in prepos.items():
			if repo_name == "DEFAULT":
				continue

			eclass_db = None
			for eclass_location in repo.eclass_locations:
				tree_db = eclass_dbs.get(eclass_location)
				if tree_db is None:
					tree_db = eclass_cache.cache(eclass_location)
					eclass_dbs[eclass_location] = tree_db
				if eclass_db is None:
					eclass_db = tree_db.copy()
				else:
					eclass_db.append(tree_db)
			repo.eclass_db = eclass_db

		for repo_name, repo in prepos.items():
			if repo_name == "DEFAULT":
				continue

			if repo._masters_orig is None and self.mainRepo() and \
				repo.name != self.mainRepo().name and not portage._sync_mode:
				# TODO: Delete masters code in pym/portage/tests/resolver/ResolverPlayground.py when deleting this warning.
				writemsg_level("!!! %s\n" % _("Repository '%s' is missing masters attribute in '%s'") %
					(repo.name, os.path.join(repo.location, "metadata", "layout.conf")) +
					"!!! %s\n" % _("Set 'masters = %s' in this file for future compatibility") %
					self.mainRepo().name, level=logging.WARNING, noiselevel=-1)

		self._prepos_changed = True
		self._repo_location_list = []

		self._check_locations()
Example #7
0
	def _add_repositories(portdir, portdir_overlay, prepos,
		ignored_map, local_config, default_portdir):
		"""Add overlays in PORTDIR_OVERLAY as repositories"""
		overlays = []
		portdir_orig = None
		if portdir:
			portdir = normalize_path(portdir)
			portdir_orig = portdir
			overlays.append(portdir)
		try:
			port_ov = [normalize_path(i) for i in shlex_split(portdir_overlay)]
		except ValueError as e:
			#File "/usr/lib/python3.2/shlex.py", line 168, in read_token
			#	raise ValueError("No closing quotation")
			writemsg(_("!!! Invalid PORTDIR_OVERLAY:"
				" %s: %s\n") % (e, portdir_overlay), noiselevel=-1)
			port_ov = []
		overlays.extend(port_ov)
		default_repo_opts = {}
		if prepos['DEFAULT'].aliases is not None:
			default_repo_opts['aliases'] = \
				' '.join(prepos['DEFAULT'].aliases)
		if prepos['DEFAULT'].eclass_overrides is not None:
			default_repo_opts['eclass-overrides'] = \
				' '.join(prepos['DEFAULT'].eclass_overrides)
		if prepos['DEFAULT'].masters is not None:
			default_repo_opts['masters'] = \
				' '.join(prepos['DEFAULT'].masters)

		if overlays:
			# We need a copy of the original repos.conf data, since we're
			# going to modify the prepos dict and some of the RepoConfig
			# objects that we put in prepos may have to be discarded if
			# they get overridden by a repository with the same name but
			# a different location. This is common with repoman, for example,
			# when temporarily overriding an rsync repo with another copy
			# of the same repo from CVS.
			repos_conf = prepos.copy()
			#overlay priority is negative because we want them to be looked before any other repo
			base_priority = 0
			for ov in overlays:
				# Ignore missing directory for 'gentoo' so that
				# first sync with emerge-webrsync is possible.
				if isdir_raise_eaccess(ov) or \
					(base_priority == 0 and ov is portdir):
					repo_opts = default_repo_opts.copy()
					repo_opts['location'] = ov
					repo = RepoConfig(None, repo_opts, local_config=local_config)
					# repos_conf_opts contains options from repos.conf
					repos_conf_opts = repos_conf.get(repo.name)
					if repos_conf_opts is not None:
						# Selectively copy only the attributes which
						# repos.conf is allowed to override.
						for k in ('aliases', 'auto_sync',
							'clone_depth', 'eclass_overrides',
							'force', 'masters', 'priority', 'strict_misc_digests',
							'sync_depth', 'sync_hooks_only_on_change',
							'sync_openpgp_key_path',
							'sync_openpgp_key_refresh_retry_count',
							'sync_openpgp_key_refresh_retry_delay_max',
							'sync_openpgp_key_refresh_retry_delay_exp_base',
							'sync_openpgp_key_refresh_retry_delay_mult',
							'sync_openpgp_key_refresh_retry_overall_timeout',
							'sync_type', 'sync_umask', 'sync_uri', 'sync_user',
							'module_specific_options'):
							v = getattr(repos_conf_opts, k, None)
							if v is not None:
								setattr(repo, k, v)

					if repo.name in prepos:
						# Silently ignore when PORTDIR overrides the location
						# setting from the default repos.conf (bug #478544).
						old_location = prepos[repo.name].location
						if old_location is not None and \
							old_location != repo.location and \
							not (base_priority == 0 and
							old_location == default_portdir):
							ignored_map.setdefault(repo.name, []).append(old_location)
							if old_location == portdir:
								portdir = repo.location

					if repo.priority is None:
						if base_priority == 0 and ov == portdir_orig:
							# If it's the original PORTDIR setting and it's not
							# in PORTDIR_OVERLAY, then it will be assigned a
							# special priority setting later.
							pass
						else:
							repo.priority = base_priority
							base_priority += 1

					prepos[repo.name] = repo
				else:

					if not portage._sync_mode:
						writemsg(_("!!! Invalid PORTDIR_OVERLAY (not a dir): '%s'\n") % ov, noiselevel=-1)

		return portdir
Example #8
0
    def load_profiles(self, repositories, known_repository_paths):
        known_repository_paths = set(
            os.path.realpath(x) for x in known_repository_paths)

        known_repos = []
        for x in known_repository_paths:
            try:
                repo = repositories.get_repo_for_location(x)
            except KeyError:
                layout_data = parse_layout_conf(x)[0]
            else:
                layout_data = {
                    "profile-formats": repo.profile_formats,
                    "profile_eapi_when_unspecified": repo.eapi
                }
            # force a trailing '/' for ease of doing startswith checks
            known_repos.append((x + '/', layout_data))
        known_repos = tuple(known_repos)

        if self.config_profile_path is None:
            deprecated_profile_path = os.path.join(self.config_root, 'etc',
                                                   'make.profile')
            self.config_profile_path = \
             os.path.join(self.config_root, PROFILE_PATH)
            if isdir_raise_eaccess(self.config_profile_path):
                self.profile_path = self.config_profile_path
                if isdir_raise_eaccess(deprecated_profile_path) and not \
                 os.path.samefile(self.profile_path,
                 deprecated_profile_path):
                    # Don't warn if they refer to the same path, since
                    # that can be used for backward compatibility with
                    # old software.
                    writemsg("!!! %s\n" % _("Found 2 make.profile dirs: "
                                            "using '%s', ignoring '%s'") %
                             (self.profile_path, deprecated_profile_path),
                             noiselevel=-1)
            else:
                self.config_profile_path = deprecated_profile_path
                if isdir_raise_eaccess(self.config_profile_path):
                    self.profile_path = self.config_profile_path
                else:
                    self.profile_path = None
        else:
            # NOTE: repoman may pass in an empty string
            # here, in order to create an empty profile
            # for checking dependencies of packages with
            # empty KEYWORDS.
            self.profile_path = self.config_profile_path

        # The symlink might not exist or might not be a symlink.
        self.profiles = []
        self.profiles_complex = []
        if self.profile_path:
            try:
                self._addProfile(os.path.realpath(self.profile_path),
                                 repositories, known_repos)
            except ParseError as e:
                if not portage._sync_mode:
                    writemsg(_("!!! Unable to parse profile: '%s'\n") %
                             self.profile_path,
                             noiselevel=-1)
                    writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
                self.profiles = []
                self.profiles_complex = []

        if self._user_config and self.profiles:
            custom_prof = os.path.join(self.config_root, CUSTOM_PROFILE_PATH)
            if os.path.exists(custom_prof):
                # For read_corresponding_eapi_file, specify default=None
                # in order to allow things like wildcard atoms when
                # is no explicit EAPI setting.
                self.user_profile_dir = custom_prof
                self.profiles.append(custom_prof)
                self.profiles_complex.append(
                    _profile_node(
                        custom_prof, True, True,
                        ('profile-bashrcs', 'profile-set'),
                        read_corresponding_eapi_file(custom_prof + os.sep,
                                                     default=None), True))
            del custom_prof

        self.profiles = tuple(self.profiles)
        self.profiles_complex = tuple(self.profiles_complex)
Example #9
0
	def load_profiles(self, repositories, known_repository_paths):
		known_repository_paths = set(os.path.realpath(x)
			for x in known_repository_paths)

		known_repos = []
		for x in known_repository_paths:
			try:
				layout_data = {"profile-formats":
					repositories.get_repo_for_location(x).profile_formats}
			except KeyError:
				layout_data = parse_layout_conf(x)[0]
			# force a trailing '/' for ease of doing startswith checks
			known_repos.append((x + '/', layout_data))
		known_repos = tuple(known_repos)

		if self.config_profile_path is None:
			deprecated_profile_path = os.path.join(
				self.config_root, 'etc', 'make.profile')
			self.config_profile_path = \
				os.path.join(self.config_root, PROFILE_PATH)
			if isdir_raise_eaccess(self.config_profile_path):
				self.profile_path = self.config_profile_path
				if isdir_raise_eaccess(deprecated_profile_path) and not \
					os.path.samefile(self.profile_path,
					deprecated_profile_path):
					# Don't warn if they refer to the same path, since
					# that can be used for backward compatibility with
					# old software.
					writemsg("!!! %s\n" %
						_("Found 2 make.profile dirs: "
						"using '%s', ignoring '%s'") %
						(self.profile_path, deprecated_profile_path),
						noiselevel=-1)
			else:
				self.config_profile_path = deprecated_profile_path
				if isdir_raise_eaccess(self.config_profile_path):
					self.profile_path = self.config_profile_path
				else:
					self.profile_path = None
		else:
			# NOTE: repoman may pass in an empty string
			# here, in order to create an empty profile
			# for checking dependencies of packages with
			# empty KEYWORDS.
			self.profile_path = self.config_profile_path


		# The symlink might not exist or might not be a symlink.
		self.profiles = []
		self.profiles_complex = []
		if self.profile_path:
			try:
				self._addProfile(os.path.realpath(self.profile_path),
					repositories, known_repos)
			except ParseError as e:
				if not portage._sync_disabled_warnings:
					writemsg(_("!!! Unable to parse profile: '%s'\n") % self.profile_path, noiselevel=-1)
					writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
				self.profiles = []
				self.profiles_complex = []

		if self._user_config and self.profiles:
			custom_prof = os.path.join(
				self.config_root, CUSTOM_PROFILE_PATH)
			if os.path.exists(custom_prof):
				self.user_profile_dir = custom_prof
				self.profiles.append(custom_prof)
				self.profiles_complex.append(
					_profile_node(custom_prof, True, True))
			del custom_prof

		self.profiles = tuple(self.profiles)
		self.profiles_complex = tuple(self.profiles_complex)
Example #10
0
	def _check_var_directory(self, varname, var):
		if not isdir_raise_eaccess(var):
			writemsg(_("!!! Error: %s='%s' is not a directory. "
				"Please correct this.\n") % (varname, var),
				noiselevel=-1)
			raise DirectoryNotFound(var)
Example #11
0
    def __init__(self, paths, settings):
        """Load config from files in paths"""

        prepos = {}
        location_map = {}
        treemap = {}
        ignored_map = {}
        default_opts = {
            "EPREFIX": settings["EPREFIX"],
            "EROOT": settings["EROOT"],
            "PORTAGE_CONFIGROOT": settings["PORTAGE_CONFIGROOT"],
            "ROOT": settings["ROOT"],
        }

        if "PORTAGE_REPOSITORIES" in settings:
            portdir = ""
            portdir_overlay = ""
            # deprecated portdir_sync
            portdir_sync = ""
        else:
            portdir = settings.get("PORTDIR", "")
            portdir_overlay = settings.get("PORTDIR_OVERLAY", "")
            # deprecated portdir_sync
            portdir_sync = settings.get("SYNC", "")

        default_opts['sync-rsync-extra-opts'] = \
         settings.get("PORTAGE_RSYNC_EXTRA_OPTS", None)

        try:
            self._parse(paths, prepos, settings.local_config, default_opts)
        except ConfigParserError as e:
            writemsg(_("!!! Error while reading repo config file: %s\n") % e,
                     noiselevel=-1)
            # The configparser state is unreliable (prone to quirky
            # exceptions) after it has thrown an error, so use empty
            # config and try to fall back to PORTDIR{,_OVERLAY}.
            prepos.clear()
            prepos['DEFAULT'] = RepoConfig('DEFAULT', {},
                                           local_config=settings.local_config)
            location_map.clear()
            treemap.clear()

        default_portdir = os.path.join(os.sep,
                                       settings['EPREFIX'].lstrip(os.sep),
                                       'usr', 'portage')

        # If PORTDIR_OVERLAY contains a repo with the same repo_name as
        # PORTDIR, then PORTDIR is overridden.
        portdir = self._add_repositories(portdir, portdir_overlay, prepos,
                                         ignored_map, settings.local_config,
                                         default_portdir)
        if portdir and portdir.strip():
            portdir = os.path.realpath(portdir)

        ignored_repos = tuple((repo_name, tuple(paths)) \
         for repo_name, paths in ignored_map.items())

        self.missing_repo_names = frozenset(
            repo.location for repo in prepos.values()
            if repo.location is not None and repo.missing_repo_name)

        # Do this before expanding aliases, so that location_map and
        # treemap consistently map unaliased names whenever available.
        for repo_name, repo in list(prepos.items()):
            if repo.location is None:
                if repo_name != 'DEFAULT':
                    # Skip this warning for repoman (bug #474578).
                    if settings.local_config and paths:
                        writemsg_level("!!! %s\n" % _(
                            "Section '%s' in repos.conf is missing location attribute"
                        ) % repo.name,
                                       level=logging.ERROR,
                                       noiselevel=-1)
                    del prepos[repo_name]
                    continue
            else:
                if not portage._sync_mode:
                    if not isdir_raise_eaccess(repo.location):
                        writemsg_level("!!! %s\n" % _(
                            "Section '%s' in repos.conf has location attribute set "
                            "to nonexistent directory: '%s'") %
                                       (repo_name, repo.location),
                                       level=logging.ERROR,
                                       noiselevel=-1)

                        # Ignore missing directory for 'gentoo' so that
                        # first sync with emerge-webrsync is possible.
                        if repo.name != 'gentoo':
                            del prepos[repo_name]
                            continue

                    # After removing support for PORTDIR_OVERLAY, the following check can be:
                    # if repo.missing_repo_name:
                    if repo.missing_repo_name and repo.name != repo_name:
                        writemsg_level("!!! %s\n" % _(
                            "Section '%s' in repos.conf refers to repository "
                            "without repository name set in '%s'") %
                                       (repo_name,
                                        os.path.join(repo.location,
                                                     REPO_NAME_LOC)),
                                       level=logging.ERROR,
                                       noiselevel=-1)
                        del prepos[repo_name]
                        continue

                    if repo.name != repo_name:
                        writemsg_level("!!! %s\n" % _(
                            "Section '%s' in repos.conf has name different "
                            "from repository name '%s' set inside repository")
                                       % (repo_name, repo.name),
                                       level=logging.ERROR,
                                       noiselevel=-1)
                        del prepos[repo_name]
                        continue

                location_map[repo.location] = repo_name
                treemap[repo_name] = repo.location

        # Add alias mappings, but never replace unaliased mappings.
        for repo_name, repo in list(prepos.items()):
            names = set()
            names.add(repo_name)
            if repo.aliases:
                aliases = stack_lists([repo.aliases], incremental=True)
                names.update(aliases)

            for name in names:
                if name in prepos and prepos[name].location is not None:
                    if name == repo_name:
                        # unaliased names already handled earlier
                        continue
                    writemsg_level(_("!!! Repository name or alias '%s', " + \
                     "defined for repository '%s', overrides " + \
                     "existing alias or repository.\n") % (name, repo_name), level=logging.WARNING, noiselevel=-1)
                    # Never replace an unaliased mapping with
                    # an aliased mapping.
                    continue
                prepos[name] = repo
                if repo.location is not None:
                    if repo.location not in location_map:
                        # Never replace an unaliased mapping with
                        # an aliased mapping.
                        location_map[repo.location] = name
                    treemap[name] = repo.location

        main_repo = prepos['DEFAULT'].main_repo
        if main_repo is None or main_repo not in prepos:
            #setting main_repo if it was not set in repos.conf
            main_repo = location_map.get(portdir)
            if main_repo is not None:
                prepos['DEFAULT'].main_repo = main_repo
            else:
                prepos['DEFAULT'].main_repo = None
                if portdir and not portage._sync_mode:
                    writemsg(_(
                        "!!! main-repo not set in DEFAULT and PORTDIR is empty.\n"
                    ),
                             noiselevel=-1)

        if main_repo is not None and prepos[main_repo].priority is None:
            # This happens if main-repo has been set in repos.conf.
            prepos[main_repo].priority = -1000

        # DEPRECATED Backward compatible SYNC support for old mirrorselect.
        # Feb. 2, 2015.  Version 2.2.16
        if portdir_sync and main_repo is not None:
            writemsg(_(
                "!!! SYNC setting found in make.conf.\n    "
                "This setting is Deprecated and no longer used.  "
                "Please ensure your 'sync-type' and 'sync-uri' are set correctly"
                " in /etc/portage/repos.conf/gentoo.conf\n"),
                     noiselevel=-1)

        # Include repo.name in sort key, for predictable sorting
        # even when priorities are equal.
        prepos_order = sorted(prepos.items(),
                              key=lambda r: (r[1].priority or 0, r[1].name))

        # filter duplicates from aliases, by only including
        # items where repo.name == key
        prepos_order = [
            repo.name for (key, repo) in prepos_order if repo.name == key
            and key != 'DEFAULT' and repo.location is not None
        ]

        self.prepos = prepos
        self.prepos_order = prepos_order
        self.ignored_repos = ignored_repos
        self.location_map = location_map
        self.treemap = treemap
        self._prepos_changed = True
        self._repo_location_list = []

        #The 'masters' key currently contains repo names. Replace them with the matching RepoConfig.
        for repo_name, repo in prepos.items():
            if repo_name == "DEFAULT":
                continue
            if repo.masters is None:
                if self.mainRepo() and repo_name != self.mainRepo().name:
                    repo.masters = self.mainRepo(),
                else:
                    repo.masters = ()
            else:
                if repo.masters and isinstance(repo.masters[0], RepoConfig):
                    # This one has already been processed
                    # because it has an alias.
                    continue
                master_repos = []
                for master_name in repo.masters:
                    if master_name not in prepos:
                        layout_filename = os.path.join(repo.location,
                                                       "metadata",
                                                       "layout.conf")
                        writemsg_level(_("Unavailable repository '%s' " \
                         "referenced by masters entry in '%s'\n") % \
                         (master_name, layout_filename),
                         level=logging.ERROR, noiselevel=-1)
                    else:
                        master_repos.append(prepos[master_name])
                repo.masters = tuple(master_repos)

        #The 'eclass_overrides' key currently contains repo names. Replace them with the matching repo paths.
        for repo_name, repo in prepos.items():
            if repo_name == "DEFAULT":
                continue

            eclass_locations = []
            eclass_locations.extend(master_repo.location
                                    for master_repo in repo.masters)
            # Only append the current repo to eclass_locations if it's not
            # there already. This allows masters to have more control over
            # eclass override order, which may be useful for scenarios in
            # which there is a plan to migrate eclasses to a master repo.
            if repo.location not in eclass_locations:
                eclass_locations.append(repo.location)

            if repo.eclass_overrides:
                for other_repo_name in repo.eclass_overrides:
                    if other_repo_name in self.treemap:
                        eclass_locations.append(
                            self.get_location_for_name(other_repo_name))
                    else:
                        writemsg_level(_("Unavailable repository '%s' " \
                         "referenced by eclass-overrides entry for " \
                         "'%s'\n") % (other_repo_name, repo_name), \
                         level=logging.ERROR, noiselevel=-1)
            repo.eclass_locations = tuple(eclass_locations)

        eclass_dbs = {}
        for repo_name, repo in prepos.items():
            if repo_name == "DEFAULT":
                continue

            eclass_db = None
            for eclass_location in repo.eclass_locations:
                tree_db = eclass_dbs.get(eclass_location)
                if tree_db is None:
                    tree_db = eclass_cache.cache(eclass_location)
                    eclass_dbs[eclass_location] = tree_db
                if eclass_db is None:
                    eclass_db = tree_db.copy()
                else:
                    eclass_db.append(tree_db)
            repo.eclass_db = eclass_db

        for repo_name, repo in prepos.items():
            if repo_name == "DEFAULT":
                continue

            if repo._masters_orig is None and self.mainRepo() and \
             repo.name != self.mainRepo().name and not portage._sync_mode:
                # TODO: Delete masters code in pym/portage/tests/resolver/ResolverPlayground.py when deleting this warning.
                writemsg_level(
                    "!!! %s\n" %
                    _("Repository '%s' is missing masters attribute in '%s'") %
                    (repo.name,
                     os.path.join(repo.location, "metadata", "layout.conf")) +
                    "!!! %s\n" %
                    _("Set 'masters = %s' in this file for future compatibility"
                      ) % self.mainRepo().name,
                    level=logging.WARNING,
                    noiselevel=-1)

        self._prepos_changed = True
        self._repo_location_list = []

        self._check_locations()
Example #12
0
    def _add_repositories(portdir, portdir_overlay, prepos, ignored_map,
                          local_config, default_portdir):
        """Add overlays in PORTDIR_OVERLAY as repositories"""
        overlays = []
        portdir_orig = None
        if portdir:
            portdir = normalize_path(portdir)
            portdir_orig = portdir
            overlays.append(portdir)
        try:
            port_ov = [normalize_path(i) for i in shlex_split(portdir_overlay)]
        except ValueError as e:
            #File "/usr/lib/python3.2/shlex.py", line 168, in read_token
            #	raise ValueError("No closing quotation")
            writemsg(_("!!! Invalid PORTDIR_OVERLAY:"
                       " %s: %s\n") % (e, portdir_overlay),
                     noiselevel=-1)
            port_ov = []
        overlays.extend(port_ov)
        default_repo_opts = {}
        if prepos['DEFAULT'].aliases is not None:
            default_repo_opts['aliases'] = \
             ' '.join(prepos['DEFAULT'].aliases)
        if prepos['DEFAULT'].eclass_overrides is not None:
            default_repo_opts['eclass-overrides'] = \
             ' '.join(prepos['DEFAULT'].eclass_overrides)
        if prepos['DEFAULT'].masters is not None:
            default_repo_opts['masters'] = \
             ' '.join(prepos['DEFAULT'].masters)

        if overlays:
            # We need a copy of the original repos.conf data, since we're
            # going to modify the prepos dict and some of the RepoConfig
            # objects that we put in prepos may have to be discarded if
            # they get overridden by a repository with the same name but
            # a different location. This is common with repoman, for example,
            # when temporarily overriding an rsync repo with another copy
            # of the same repo from CVS.
            repos_conf = prepos.copy()
            #overlay priority is negative because we want them to be looked before any other repo
            base_priority = 0
            for ov in overlays:
                # Ignore missing directory for 'gentoo' so that
                # first sync with emerge-webrsync is possible.
                if isdir_raise_eaccess(ov) or \
                 (base_priority == 0 and ov is portdir):
                    repo_opts = default_repo_opts.copy()
                    repo_opts['location'] = ov
                    repo = RepoConfig(None,
                                      repo_opts,
                                      local_config=local_config)
                    # repos_conf_opts contains options from repos.conf
                    repos_conf_opts = repos_conf.get(repo.name)
                    if repos_conf_opts is not None:
                        # Selectively copy only the attributes which
                        # repos.conf is allowed to override.
                        for k in ('aliases', 'auto_sync', 'eclass_overrides',
                                  'force', 'masters', 'priority', 'sync_depth',
                                  'sync_hooks_only_on_change', 'sync_type',
                                  'sync_umask', 'sync_uri', 'sync_user',
                                  'module_specific_options'):
                            v = getattr(repos_conf_opts, k, None)
                            if v is not None:
                                setattr(repo, k, v)

                    if repo.name in prepos:
                        # Silently ignore when PORTDIR overrides the location
                        # setting from the default repos.conf (bug #478544).
                        old_location = prepos[repo.name].location
                        if old_location is not None and \
                         old_location != repo.location and \
                         not (base_priority == 0 and
                         old_location == default_portdir):
                            ignored_map.setdefault(repo.name,
                                                   []).append(old_location)
                            if old_location == portdir:
                                portdir = repo.location

                    if repo.priority is None:
                        if base_priority == 0 and ov == portdir_orig:
                            # If it's the original PORTDIR setting and it's not
                            # in PORTDIR_OVERLAY, then it will be assigned a
                            # special priority setting later.
                            pass
                        else:
                            repo.priority = base_priority
                            base_priority += 1

                    prepos[repo.name] = repo
                else:

                    if not portage._sync_mode:
                        writemsg(
                            _("!!! Invalid PORTDIR_OVERLAY (not a dir): '%s'\n"
                              ) % ov,
                            noiselevel=-1)

        return portdir