mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Review remainder of updater.py
This commit is contained in:
parent
a0ab601b7f
commit
4bcfead253
1 changed files with 94 additions and 84 deletions
|
|
@ -321,8 +321,9 @@ def refresh(self):
|
|||
def cleanup(self):
|
||||
"""
|
||||
<Purpose>
|
||||
Clean up the updater object's temporary directory (and any
|
||||
sub-directories).
|
||||
Remove the updater object's temporary directory (and any sub-directories)
|
||||
created when the updater object is instantiated to store downloaded
|
||||
targets and metadata.
|
||||
|
||||
<Arguments>
|
||||
None
|
||||
|
|
@ -344,30 +345,29 @@ def cleanup(self):
|
|||
def download_target(self, target_filepath):
|
||||
"""
|
||||
<Purpose>
|
||||
It downloads the target files from the path provided named
|
||||
target_filepath.
|
||||
Everything here is performed in a temporary directory.
|
||||
It identifies the target information for target_filepath by calling
|
||||
target() method of tuf.client.updater. This method also downloads the
|
||||
metadata of the updated targets. By doing this, the client retrieves the
|
||||
target information for the targets they want to update. When client
|
||||
retrieves all the information, the updated_targets() method of
|
||||
tuf.client.updater is called to determine the list of targets which have
|
||||
been changed from those saved locally on disk.
|
||||
tuf.client.upater.download_target() downloads all the targets in the list
|
||||
in the destination directory which is our temporary directory.
|
||||
Download the 'target_filepath' target file. Everything here is performed
|
||||
in a temporary directory. It identifies the target information for
|
||||
'target_filepath' by calling the target() method of 'tuf.client.updater'.
|
||||
This method also downloads the metadata of the updated targets. By doing
|
||||
this, the client retrieves the target information for the targets they
|
||||
want to update. When client retrieves all the information, the
|
||||
updated_targets() method of 'tuf.client.updater' is called to determine
|
||||
the list of targets which have been changed from those saved locally on
|
||||
disk. tuf.client.upater.download_target() downloads all the targets in
|
||||
the list in the destination directory, which is our temporary directory.
|
||||
|
||||
This will only store the file at 'destination_directory' if the downloaded
|
||||
file matches the description of the file in the trusted metadata.
|
||||
This will only store the file in the temporary directory if the
|
||||
downloaded file matches the description of the file in the trusted
|
||||
metadata.
|
||||
|
||||
<Arguments>
|
||||
'target_filepath' is the target's relative path on the remote repository.
|
||||
target_filepath:
|
||||
The target's relative path on the remote repository.
|
||||
|
||||
<Exceptions>
|
||||
tuf.FormatError:
|
||||
If 'target_filepath', 'updated_target' in
|
||||
tuf.client.updater.download_target and arguments of updated_targets are
|
||||
improperly formatted.
|
||||
If 'target_filepath', 'updated_target' in
|
||||
'tuf.client.updater.download_target', is improperly formatted.
|
||||
|
||||
tuf.UnknownTargetError:
|
||||
If 'target_filepath' was not found.
|
||||
|
|
@ -379,20 +379,21 @@ def download_target(self, target_filepath):
|
|||
A target file is saved to the local system.
|
||||
|
||||
<Returns>
|
||||
It returns destination_directory where the target is been stored and
|
||||
filename of the target file been stored in the directory.
|
||||
It returns a (destination directory, filename) tuple where the target is
|
||||
been stored and filename of the target file been stored in the directory.
|
||||
"""
|
||||
|
||||
tuf.formats.RELPATH_SCHEMA.check_match(target_filepath)
|
||||
|
||||
# Download file into a temporary directory shared over runtime
|
||||
destination_directory = self.tempdir
|
||||
|
||||
tuf.formats.RELPATH_SCHEMA.check_match(target_filepath)
|
||||
# A new path is generated by joining the destination directory path that is
|
||||
# our temporary directory path and target file path.
|
||||
# Note: join() discards 'destination_directory' if 'target_filepath'
|
||||
# contains a leading path separator (i.e., is treated as an absolute path).
|
||||
filename = os.path.join(destination_directory,
|
||||
target_filepath.lstrip(os.sep))
|
||||
filename = \
|
||||
os.path.join(destination_directory, target_filepath.lstrip(os.sep))
|
||||
|
||||
# Switch TUF context. Switching context before instantiating updater
|
||||
# because updater depends on some module (tuf.conf) variables.
|
||||
|
|
@ -413,7 +414,8 @@ def download_target(self, target_filepath):
|
|||
# determine which targets have changed from those saved locally on disk.
|
||||
# All the targets that have changed are returned in a list. From this list,
|
||||
# a request to download is made by calling 'download_target()'.
|
||||
updated_targets = self.updater.updated_targets(targets, destination_directory)
|
||||
updated_targets = \
|
||||
self.updater.updated_targets(targets, destination_directory)
|
||||
|
||||
# The download_target() method in tuf.client.updater performs the actual
|
||||
# download of the specified target. The file is saved to the
|
||||
|
|
@ -424,7 +426,7 @@ def download_target(self, target_filepath):
|
|||
return destination_directory, filename
|
||||
|
||||
|
||||
# TODO: decide prudent course of action in case of failure
|
||||
# TODO: decide prudent course of action in case of failure.
|
||||
def get_target_filepath(self, source_url):
|
||||
"""
|
||||
<Purpose>
|
||||
|
|
@ -432,8 +434,8 @@ def get_target_filepath(self, source_url):
|
|||
download when a URL is given.
|
||||
|
||||
<Arguments>
|
||||
source_url is passed while calling the function. This is the url which
|
||||
we want to retrieve. For this url, get_target_filepath() method is called.
|
||||
source_url:
|
||||
The URL of the target we want to retrieve.
|
||||
|
||||
<Exceptions>
|
||||
tuf.URLMatchesNoPatternError:
|
||||
|
|
@ -444,7 +446,8 @@ def get_target_filepath(self, source_url):
|
|||
None
|
||||
|
||||
<Returns>
|
||||
It returns target_filepath. This is the target which TUF should download.
|
||||
If the target filepath is matched, return the filepath, otherwise raise
|
||||
an exception.
|
||||
"""
|
||||
|
||||
parsed_source_url = six.moves.urllib.parse.urlparse(source_url)
|
||||
|
|
@ -487,7 +490,7 @@ def get_target_filepath(self, source_url):
|
|||
return target_filepath
|
||||
|
||||
|
||||
# TODO: distinguish between urllib and urllib2 contracts
|
||||
# TODO: distinguish between urllib and urllib2 contracts.
|
||||
def open(self, url, data=None):
|
||||
"""
|
||||
<Purpose>
|
||||
|
|
@ -496,19 +499,16 @@ def open(self, url, data=None):
|
|||
called when TUF wants to open an already existing updater's 'url'.
|
||||
|
||||
<Arguments>
|
||||
url, the one which is to be opened.
|
||||
url:
|
||||
The one which is to be opened.
|
||||
|
||||
data must be a bytes object specifying additional data to be sent to the
|
||||
server or None, if no such data needed.
|
||||
data:
|
||||
Must be a bytes object specifying additional data to be sent to the
|
||||
server or None, if no such data needed.
|
||||
|
||||
<Exceptions>
|
||||
tuf.FormatError:
|
||||
If 'target_filepath', 'updated_target' in
|
||||
tuf.client.updater.download_target and arguments of updated_targets are
|
||||
improperly formatted.
|
||||
|
||||
tuf.UnknownTargetError:
|
||||
If 'target_filepath' was not found.
|
||||
tuf.FormatError:
|
||||
TODO: validate arguments.
|
||||
|
||||
tuf.NoWorkingMirrorError:
|
||||
If a 'target_filepath' could not be downloaded from any of the mirrors.
|
||||
|
|
@ -523,6 +523,9 @@ def open(self, url, data=None):
|
|||
<Returns>
|
||||
'response' which is a file object with info() and geturl() methods added.
|
||||
"""
|
||||
|
||||
# TODO: validate arguments.
|
||||
|
||||
filename, headers = self.retrieve(url, data=data)
|
||||
|
||||
# TUF should always open files in binary mode and remain transparent to the
|
||||
|
|
@ -549,15 +552,16 @@ def open(self, url, data=None):
|
|||
def retrieve(self, url, filename=None, reporthook=None, data=None):
|
||||
"""
|
||||
<Purpose>
|
||||
retrieve() method first get the target file path by calling
|
||||
get_target_filepath(url) which is in tuf.interposition.updater.Updater
|
||||
and then calls download_target() method for the above file path.
|
||||
Get the target file path by calling self.get_target_filepath(url) and
|
||||
then self.download_target() method for the above file path.
|
||||
|
||||
<Arguments>
|
||||
url, which is to be retrieved.
|
||||
url:
|
||||
The URL of the target file to retrieve.
|
||||
|
||||
filename, if the is given then everywhere the given filename is used.
|
||||
If the filename is none, then temporary file is used.
|
||||
filename:
|
||||
If given, then the given filename is used. If the filename is none,
|
||||
then temporary file is used.
|
||||
|
||||
<Exceptions>
|
||||
tuf.FormatError:
|
||||
|
|
@ -606,28 +610,29 @@ def retrieve(self, url, filename=None, reporthook=None, data=None):
|
|||
self.download_target(target_filepath)
|
||||
|
||||
if filename is None:
|
||||
# If no filename is given, use the temporary file.
|
||||
filename = temporary_filename
|
||||
# If no filename is given, use the temporary file.
|
||||
filename = temporary_filename
|
||||
else:
|
||||
# Otherwise, copy TUF-downloaded file in its own directory
|
||||
# to the location user specified.
|
||||
shutil.copy2(temporary_filename, filename)
|
||||
# Otherwise, copy TUF-downloaded file in its own directory
|
||||
# to the location user specified.
|
||||
shutil.copy2(temporary_filename, filename)
|
||||
|
||||
return filename, headers
|
||||
|
||||
|
||||
# TODO: thread-safety, perhaps with a context manager
|
||||
# TODO: thread-safety, perhaps with a context manager.
|
||||
def switch_context(self):
|
||||
"""
|
||||
<Purpose>
|
||||
There is an updater object for each network location that is interposed.
|
||||
Context switching is required because there are multiple
|
||||
tuf.client.updater objects and each one depends on tuf.conf settings
|
||||
There is an updater object for each network location that is interposed.
|
||||
Context switching is required because there are multiple
|
||||
'tuf.client.updater' objects and each one depends on tuf.conf settings
|
||||
that are shared.
|
||||
|
||||
For this, two settings are required -
|
||||
1. Setting local repository directory
|
||||
2. Setting the local SSL certificate PEM file
|
||||
For this, two settings are required:
|
||||
|
||||
1. Setting local repository directory in 'tuf.conf'.
|
||||
2. Setting the local SSL certificate PEM file.
|
||||
|
||||
<Arguments>
|
||||
None
|
||||
|
|
@ -636,8 +641,9 @@ def switch_context(self):
|
|||
None
|
||||
|
||||
<Side Effects>
|
||||
The given configuration's repository_directory and ssl_certificates are
|
||||
assigned to tuf.conf.repository_directory and tuf.conf.ssl_certificates.
|
||||
The given configuration's 'repository_directory' and ssl_certificates
|
||||
settings are set to 'tuf.conf.repository_directory' and
|
||||
'tuf.conf.ssl_certificates', respectively.
|
||||
|
||||
<Returns>
|
||||
None
|
||||
|
|
@ -654,9 +660,8 @@ def switch_context(self):
|
|||
class UpdaterController(object):
|
||||
"""
|
||||
<Purpose>
|
||||
tuf.interposition.updater.UpdaterController is a controller of the Updaters.
|
||||
Given a configuration, it can build and store an Updater, which can be
|
||||
used later with the help of get() method.
|
||||
A controller of Updater() objects. Given a configuration, it can build and
|
||||
store an Updater, which can be used later with the help of get() method.
|
||||
|
||||
<UpdaterController's Methods>
|
||||
|
||||
|
|
@ -670,34 +675,34 @@ class UpdaterController(object):
|
|||
It checks if the given configuration is valid or not.
|
||||
|
||||
add(configuration):
|
||||
This method adds the updater by adding an object of
|
||||
tuf.interposition.updater.Updater in the __updater map and by adding
|
||||
repository mirror's network location in the empty set initialized when
|
||||
the object of tuf.interposition.updater.UpdaterController is created.
|
||||
This method adds the updater by adding an object of
|
||||
'tuf.interposition.updater.Updater' in the __updater map and by adding
|
||||
repository mirror's network location in the empty set initialized when
|
||||
the object of 'tuf.interposition.updater.UpdaterController' is created.
|
||||
|
||||
get(url):
|
||||
This method is to get the updater if it already exists. It takes the url
|
||||
and parse it. Then it utilizes hostname and port of that url to check if
|
||||
it already exists or not. If the updater exists, then it calls the
|
||||
get_target_filepath() method which returns a target file path to be
|
||||
Get the updater if it already exists. It takes the url and parses it.
|
||||
Then it utilizes hostname and port of that url to check if it already
|
||||
exists or not. If the updater exists, then it calls the
|
||||
get_target_filepath() method which returns a target file path to be
|
||||
downloaded.
|
||||
|
||||
refresh(configuration):
|
||||
To refresh the top-level metadata of the given 'configuration'.
|
||||
It updates the latest copies of the metadata for the top-level roles.
|
||||
Refreshes the top-level metadata of the given 'configuration'. It
|
||||
updates the latest copies of the metadata of the top-level roles.
|
||||
|
||||
remove(configuration):
|
||||
Remove an Updater matching the given Configuration as well as its
|
||||
Remove an Updater matching the given 'configuration' as well as its
|
||||
associated mirrors.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
<Purpose>
|
||||
To initalize a private map of updaters and a private set of repository
|
||||
Initalize a private map of updaters and a private set of repository
|
||||
mirror network locations (hostname:port) once the object of
|
||||
tuf.interposition.updater.UpdaterController is created. This empty map
|
||||
and set is later used to add, get and remove updaters and their mirrors.
|
||||
'tuf.interposition.updater.UpdaterController' is created. This empty map
|
||||
and set is later used to add, get, and remove updaters and their mirrors.
|
||||
|
||||
<Arguments>
|
||||
None
|
||||
|
|
@ -812,8 +817,8 @@ def __check_configuration_on_add(self, configuration):
|
|||
def add(self, configuration):
|
||||
"""
|
||||
<Purpose>
|
||||
Add an Updater based on the given Configuration. Tuf keeps the track of
|
||||
the updaters so that it can be fetched for later use.
|
||||
Add an Updater based on the given 'configuration'. TUF keeps track of the
|
||||
updaters so that it can be fetched for later use.
|
||||
|
||||
<Arguments>
|
||||
'configuration' is an object and on the basis of this configuration, an
|
||||
|
|
@ -837,13 +842,17 @@ def add(self, configuration):
|
|||
None
|
||||
"""
|
||||
|
||||
repository_mirror_network_locations = self.__check_configuration_on_add(configuration)
|
||||
repository_mirror_network_locations = \
|
||||
self.__check_configuration_on_add(configuration)
|
||||
|
||||
# If all is well, build and store an Updater, and remember network locations.
|
||||
# If all is well, build and store an Updater, and remember network
|
||||
# locations.
|
||||
logger.info('Adding updater for interposed ' + repr(configuration))
|
||||
|
||||
# Adding an object of the tuf.interposition.updater.Updater with the given
|
||||
# configuration.
|
||||
self.__updaters[configuration.network_location] = Updater(configuration)
|
||||
|
||||
# Adding the new the repository mirror network locations to the list.
|
||||
self.__repository_mirror_network_locations.update(repository_mirror_network_locations)
|
||||
|
||||
|
|
@ -928,7 +937,8 @@ def get(self, url):
|
|||
downloaded.
|
||||
|
||||
<Arguments>
|
||||
url, for which tuf is trying to get an updater. Assumption that url is a
|
||||
url:
|
||||
URL which TUF is trying to get an updater. Assumption that url is a
|
||||
string.
|
||||
|
||||
<Exceptions>
|
||||
|
|
@ -1000,7 +1010,7 @@ def get(self, url):
|
|||
def remove(self, configuration):
|
||||
"""
|
||||
<Purpose>
|
||||
Remove an Updater matching the given Configuration as well as its
|
||||
Remove an Updater matching the given 'configuration', as well as its
|
||||
associated mirrors.
|
||||
|
||||
<Arguments>
|
||||
|
|
|
|||
Loading…
Reference in a new issue