diff --git a/securesystemslib/exceptions.py b/securesystemslib/exceptions.py index 7aa636743..e847f2a75 100755 --- a/securesystemslib/exceptions.py +++ b/securesystemslib/exceptions.py @@ -121,3 +121,7 @@ class InvalidConfigurationError(Error): """If a configuration object does not match the expected format.""" pass +class StorageError(Error): + """Indicate an error occured during interaction with an abstracted storage + backend.""" + pass diff --git a/securesystemslib/storage.py b/securesystemslib/storage.py new file mode 100644 index 000000000..1b4c3cbbc --- /dev/null +++ b/securesystemslib/storage.py @@ -0,0 +1,150 @@ +""" + + storage.py + + + Joshua Lock + + + April 9, 2020 + + + See LICENSE for licensing information. + + + Provides an interface for filesystem interactions, StorageBackendInterface. +""" + +from __future__ import absolute_import +from __future__ import unicode_literals + +import abc +import errno +import logging +import os +import shutil + +import securesystemslib.exceptions + +logger = logging.getLogger(__name__) + + + +class StorageBackendInterface(): + """ + + Defines an interface for abstract storage operations which can be implemented + for a variety of storage solutions, such as remote and local filesystems. + """ + + __metaclass__ = abc.ABCMeta + + + @abc.abstractmethod + def get(self, filepath): + """ + + A context manager for 'with' statements that is used for retrieving files + from a storage backend and cleans up the files upon exit. + + with storage_backend.get('/path/to/file') as file_object: + # operations + # file is now closed + + + filepath: + The full path of the file to be retrieved. + + + securesystemslib.exceptions.StorageError, if the file does not exist or is + no accessible. + + + A ContextManager object that emits a file-like object for the file at + 'filepath'. + """ + raise NotImplementedError # pragma: no cover + + + @abc.abstractmethod + def put(self, fileobj, filepath): + """ + + Store a file-like object in the storage backend. + + + fileobj: + The file-like object to be stored. + + filepath: + The full path to the location where 'fileobj' will be stored. + + + securesystemslib.exceptions.StorageError, if the file can not be stored. + + + None + """ + raise NotImplementedError # pragma: no cover + + + @abc.abstractmethod + def getsize(self, filepath): + """ + + Retrieve the size, in bytes, of the file at 'filepath'. + + + filepath: + The full path to the file. + + + securesystemslib.exceptions.StorageError, if the file does not exist or is + not accessible. + + + The size in bytes of the file at 'filepath'. + """ + raise NotImplementedError # pragma: no cover + + + @abc.abstractmethod + def create_folder(self, filepath): + """ + + Create a folder at filepath and ensure all intermediate components of the + path exist. + + + filepath: + The full path of the folder to be created. + + + securesystemslib.exceptions.StorageError, if the folder can not be + created. + + + None + """ + raise NotImplementedError # pragma: no cover + + + @abc.abstractmethod + def list_folder(self, filepath): + """ + + List the contents of the folder at 'filepath'. + + + filepath: + The full path of the folder to be listed. + + + securesystemslib.exceptions.StorageError, if the file does not exist or is + not accessible. + + + A list containing the names of the files in the folder. May be an empty + list. + """ + raise NotImplementedError # pragma: no cover