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.
62 lines
1.7 KiB
Python
62 lines
1.7 KiB
Python
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)
|