Skip to content

Commit

Permalink
Define an interface for storage access
Browse files Browse the repository at this point in the history
Implement an abstract base class (ABC) which defined an abstract interface
for storage operations, regardless of backend.

The aim is to enable securesystemslib functions to operate as normal on
local filesystems by implementing the interface for local filesystem
operations within securesystemslib, with users of the library able to
provide implementations for use with their storage backend of choice when
this is not a local filesystem, i.e. S3 buckets as used by Warehouse for
the PEP 458 implementation.

For more context see tuf issue #1009:
theupdateframework/python-tuf#1009

Signed-off-by: Joshua Lock <[email protected]>
  • Loading branch information
joshuagl committed Apr 20, 2020
1 parent 12e8041 commit bef7265
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
4 changes: 4 additions & 0 deletions securesystemslib/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
144 changes: 144 additions & 0 deletions securesystemslib/storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"""
<Program Name>
storage.py
<Author>
Joshua Lock <[email protected]>
<Started>
April 9, 2020
<Copyright>
See LICENSE for licensing information.
<Purpose>
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():
"""
<Purpose>
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):
"""
<Purpose>
Retrieve a file from the storage backend.
<Arguments>
filepath:
The full path of the file to be retrieved.
<Exceptions>
securesystemslib.exceptions.StorageError, if the file does not exist or is
no accessible.
<Returns>
A file-like object of the file at 'filepath'.
"""
raise NotImplementedError # pragma: no cover


@abc.abstractmethod
def put(self, fileobj, filepath):
"""
<Purpose>
Store a file-like object in the storage backend.
<Arguments>
fileobj:
The file-like object to be stored.
filepath:
The full path to the location where 'fileobj' will be stored.
<Exceptions>
securesystemslib.exceptions.StorageError, if the file can not be stored.
<Returns>
None
"""
raise NotImplementedError # pragma: no cover


@abc.abstractmethod
def getsize(self, filepath):
"""
<Purpose>
Retrieve the size, in bytes, of the file at 'filepath'.
<Arguments>
filepath:
The full path to the file.
<Exceptions>
securesystemslib.exceptions.StorageError, if the file does not exist or is
not accessible.
<Returns>
The size in bytes of the file at 'filepath'.
"""
raise NotImplementedError # pragma: no cover


@abc.abstractmethod
def create_folder(self, filepath):
"""
<Purpose>
Create a folder at filepath and ensure all intermediate components of the
path exist.
<Arguments>
filepath:
The full path of the folder to be created.
<Exceptions>
securesystemslib.exceptions.StorageError, if the folder can not be
created.
<Returns>
None
"""
raise NotImplementedError # pragma: no cover


@abc.abstractmethod
def list_folder(self, filepath):
"""
<Purpose>
List the contents of the folder at 'filepath'.
<Arguments>
filepath:
The full path of the folder to be listed.
<Exceptions>
securesystemslib.exceptions.StorageError, if the file does not exist or is
not accessible.
<Returns>
A list containing the names of the files in the folder. May be an empty
list.
"""
raise NotImplementedError # pragma: no cover

0 comments on commit bef7265

Please sign in to comment.