Skip to content

Commit

Permalink
RepositorySimulator: add non-consistent snapshot support
Browse files Browse the repository at this point in the history
Extend filename partitioning to support serving non-versioned
metadata and non-prefixed target files.

Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
  • Loading branch information
sechkova committed Nov 8, 2021
1 parent 8ae944c commit 089cfea
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions tests/repository_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def __init__(self):
# target downloads are served from this dict
self.target_files: Dict[str, RepositoryTarget] = {}

# Whether to compute hashes and legth for meta in snapshot/timestamp
# Whether to compute hashes and length for meta in snapshot/timestamp
self.compute_metafile_hashes_length = False

self.dump_dir = None
Expand Down Expand Up @@ -145,6 +145,21 @@ def create_key() -> Tuple[Key, SSlibSigner]:
sslib_key = generate_ed25519_key()
return Key.from_securesystemslib_key(sslib_key), SSlibSigner(sslib_key)

@staticmethod
def _partition_filename(filename: str) -> Tuple[str, Optional[str]]:
"""Partition 'filename' into filename and prefix, if any"""
p1, sep, p2 = filename.partition(".")
# If the separator is not found, returns a 3-tuple containing
# the string itself, followed by two empty strings.
if not sep:
prefix = None
filename = p1
else:
prefix = p1
filename = p2

return filename, prefix

def add_signer(self, role: str, signer: SSlibSigner):
if role not in self.signers:
self.signers[role] = {}
Expand Down Expand Up @@ -185,24 +200,19 @@ def publish_root(self):
logger.debug("Published root v%d", self.root.version)

def fetch(self, url: str) -> Iterator[bytes]:
if not self.root.consistent_snapshot:
raise NotImplementedError("non-consistent snapshot not supported")
path = parse.urlparse(url).path
if path.startswith("/metadata/") and path.endswith(".json"):
ver_and_name = path[len("/metadata/") :][: -len(".json")]
# only consistent_snapshot supported ATM: timestamp is special case
if ver_and_name == "timestamp":
version = None
role = "timestamp"
else:
version, _, role = ver_and_name.partition(".")
role, version = self._partition_filename(ver_and_name)
if version:
version = int(version)

yield self._fetch_metadata(role, version)
elif path.startswith("/targets/"):
# figure out target path and hash prefix
target_path = path[len("/targets/") :]
dir_parts, sep, prefixed_filename = target_path.rpartition("/")
prefix, _, filename = prefixed_filename.partition(".")
filename, prefix = self._partition_filename(prefixed_filename)
target_path = f"{dir_parts}{sep}{filename}"

yield self._fetch_target(target_path, prefix)
Expand Down Expand Up @@ -245,7 +255,7 @@ def _fetch_metadata(
elif role == "targets":
md = self.md_targets
else:
md = self.md_delegates[role]
md = self.md_delegates.get(role)

if md is None:
raise FetcherHTTPError(f"Unknown role {role}", 404)
Expand Down

0 comments on commit 089cfea

Please sign in to comment.