From 42ec5cc6e6b8d3452184c0aa429c285bbddf0df8 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Fri, 21 Sep 2018 14:12:46 +0900 Subject: source.py: Fix re-instantiation This fixes an issue where the re-instantiated Source used with Source mirroring enabled is not completely initialized. Failing to load the ref from the project.refs file for instance, will result in a crash at `fetch` time. This fixes issue #666 --- buildstream/source.py | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/buildstream/source.py b/buildstream/source.py index f546258e6..af9474904 100644 --- a/buildstream/source.py +++ b/buildstream/source.py @@ -620,12 +620,8 @@ class Source(Plugin): self.fetch() return - context = self._get_context() - source_kind = type(self) for uri in project.get_alias_uris(alias, first_pass=self.__first_pass): - new_source = source_kind(context, project, self.__meta, - alias_override=(alias, uri)) - new_source._preflight() + new_source = self.__clone_for_uri(uri) try: new_source.fetch() # FIXME: Need to consider temporary vs. permanent failures, @@ -878,6 +874,38 @@ class Source(Plugin): # Local Private Methods # ############################################################# + # __clone_for_uri() + # + # Clone the source with an alternative URI setup for the alias + # which this source uses. + # + # This is used for iteration over source mirrors. + # + # Args: + # uri (str): The alternative URI for this source's alias + # + # Returns: + # (Source): A new clone of this Source, with the specified URI + # as the value of the alias this Source has marked as + # primary with either mark_download_url() or + # translate_url(). + # + def __clone_for_uri(self, uri): + project = self._get_project() + context = self._get_context() + alias = self._get_alias() + source_kind = type(self) + + clone = source_kind(context, project, self.__meta, alias_override=(alias, uri)) + + # Do the necessary post instantiation routines here + # + clone._preflight() + clone._load_ref() + clone._update_state() + + return clone + # Tries to call track for every mirror, stopping once it succeeds def __do_track(self): project = self._get_project() @@ -890,15 +918,10 @@ class Source(Plugin): if not mirrors or not alias: return self.track() - context = self._get_context() - source_kind = type(self) - # NOTE: We are assuming here that tracking only requires substituting the # first alias used for uri in reversed(project.get_alias_uris(alias, first_pass=self.__first_pass)): - new_source = source_kind(context, project, self.__meta, - alias_override=(alias, uri)) - new_source._preflight() + new_source = self.__clone_for_uri(uri) try: ref = new_source.track() # FIXME: Need to consider temporary vs. permanent failures, -- cgit v1.2.1