More changes for registry-v2 in python.
Implement the minimal changes to the local filesystem storage driver and feed them through the distributed storage driver. Create a digest package which contains digest_tools and checksums. Fix the tests to use the new v1 endpoint locations. Fix repository.delete_instance to properly filter the generated queries to avoid most subquery deletes, but still generate them when not explicitly filtered.
This commit is contained in:
parent
acbcc2e206
commit
bea8b9ac53
23 changed files with 397 additions and 179 deletions
62
digest/digest_tools.py
Normal file
62
digest/digest_tools.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
import re
|
||||
import os.path
|
||||
import hashlib
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
Digest = namedtuple('Digest', ['is_tarsum', 'tarsum_version', 'hash_alg', 'hash_bytes'])
|
||||
|
||||
|
||||
DIGEST_PATTERN = r'(tarsum\.(v[\w]+)\+)?([\w]+):([0-9a-f]+)'
|
||||
DIGEST_REGEX = re.compile(DIGEST_PATTERN)
|
||||
|
||||
|
||||
class InvalidDigestException(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def parse_digest(digest):
|
||||
""" Returns the digest parsed out to its components. """
|
||||
match = DIGEST_REGEX.match(digest)
|
||||
if match is None or match.end() != len(digest):
|
||||
raise InvalidDigestException('Not a valid digest: %s', digest)
|
||||
|
||||
is_tarsum = match.group(1) is not None
|
||||
return Digest(is_tarsum, match.group(2), match.group(3), match.group(4))
|
||||
|
||||
|
||||
def content_path(digest):
|
||||
""" Returns a relative path to the parsed digest. """
|
||||
parsed = parse_digest(digest)
|
||||
components = []
|
||||
|
||||
if parsed.is_tarsum:
|
||||
components.extend(['tarsum', parsed.tarsum_version])
|
||||
|
||||
prefix = parsed.hash_bytes[0:2].zfill(2)
|
||||
components.extend([parsed.hash_alg, prefix, parsed.hash_bytes])
|
||||
|
||||
return os.path.join(*components)
|
||||
|
||||
|
||||
def sha256_digest(content):
|
||||
""" Returns a sha256 hash of the content bytes in digest form. """
|
||||
def single_chunk_generator():
|
||||
yield content
|
||||
return sha256_digest_from_generator(single_chunk_generator())
|
||||
|
||||
|
||||
def sha256_digest_from_generator(content_generator):
|
||||
""" Reads all of the data from the iterator and creates a sha256 digest from the content
|
||||
"""
|
||||
digest = hashlib.sha256()
|
||||
for chunk in content_generator:
|
||||
digest.update(chunk)
|
||||
return 'sha256:{0}'.format(digest.hexdigest())
|
||||
|
||||
|
||||
def digests_equal(lhs_digest_string, rhs_digest_string):
|
||||
""" Parse and compare the two digests, returns True if the digests are equal, False otherwise.
|
||||
"""
|
||||
return parse_digest(lhs_digest_string) == parse_digest(rhs_digest_string)
|
Reference in a new issue