@@ -343,50 +343,53 @@ def _persist_file(self, filename: str, data: bytes) -> None:
343343 def _load_root (self ) -> None :
344344 """Load root metadata.
345345
346- Sequentially load and persist every newer root metadata
347- version available, either locally or on the remote.
346+ Sequentially load newer root metadata versions. First try to load from
347+ local cache and if that does not work, from the remote repository.
348+
349+ If metadata is loaded from remote repository, store it in local cache.
348350 """
349351
350352 # Update the root role
351353 lower_bound = self ._trusted_set .root .version + 1
352354 upper_bound = lower_bound + self .config .max_root_rotations
353355
354- for next_version in range (lower_bound , upper_bound ):
355- # look for next_version in local cache
356- try :
357- root_path = os .path .join (
358- self ._dir , "root_history" , f"{ next_version } .root.json"
359- )
360- with open (root_path , "rb" ) as f :
361- self ._trusted_set .update_root (f .read ())
362- continue
363- except (OSError , exceptions .RepositoryError ) as e :
364- # this root did not exist locally or is invalid
365- logger .debug ("Local root is not valid: %s" , e )
366-
367- # next_version was not found locally, try remote
368- try :
369- data = self ._download_metadata (
370- Root .type ,
371- self .config .root_max_length ,
372- next_version ,
373- )
374- self ._trusted_set .update_root (data )
375- self ._persist_root (next_version , data )
376-
377- except exceptions .DownloadHTTPError as exception :
378- if exception .status_code not in {403 , 404 }:
379- raise
380- # 404/403 means current root is newest available
381- break
382-
383- # Make sure there's a non-versioned root.json
384- linkname = os .path .join (self ._dir , "root.json" )
385- version = self ._trusted_set .root .version
386- current = os .path .join ("root_history" , f"{ version } .root.json" )
387- with contextlib .suppress (FileNotFoundError ):
388- os .remove (linkname )
389- os .symlink (current , linkname )
356+ try :
357+ for next_version in range (lower_bound , upper_bound ):
358+ # look for next_version in local cache
359+ try :
360+ root_path = os .path .join (
361+ self ._dir , "root_history" , f"{ next_version } .root.json"
362+ )
363+ with open (root_path , "rb" ) as f :
364+ self ._trusted_set .update_root (f .read ())
365+ continue
366+ except (OSError , exceptions .RepositoryError ) as e :
367+ # this root did not exist locally or is invalid
368+ logger .debug ("Local root is not valid: %s" , e )
369+
370+ # next_version was not found locally, try remote
371+ try :
372+ data = self ._download_metadata (
373+ Root .type ,
374+ self .config .root_max_length ,
375+ next_version ,
376+ )
377+ self ._trusted_set .update_root (data )
378+ self ._persist_root (next_version , data )
379+
380+ except exceptions .DownloadHTTPError as exception :
381+ if exception .status_code not in {403 , 404 }:
382+ raise
383+ # 404/403 means current root is newest available
384+ break
385+ finally :
386+ # Make sure the non-versioned root.json links to current version
387+ linkname = os .path .join (self ._dir , "root.json" )
388+ version = self ._trusted_set .root .version
389+ current = os .path .join ("root_history" , f"{ version } .root.json" )
390+ with contextlib .suppress (FileNotFoundError ):
391+ os .remove (linkname )
392+ os .symlink (current , linkname )
390393
391394 def _load_timestamp (self ) -> None :
392395 """Load local and remote timestamp metadata."""
0 commit comments