Implement V2 interfaces and remaining V1 interfaces
Also adds some tests to registry tests for V1 stuff. Note: All *registry* tests currently pass, but as verbs are not yet converted, the verb tests in registry_tests.py currently fail.
This commit is contained in:
parent
d67991987b
commit
db60df827d
21 changed files with 588 additions and 338 deletions
|
@ -1,6 +1,7 @@
|
|||
import tarfile
|
||||
|
||||
from collections import namedtuple
|
||||
from namedlist import namedlist
|
||||
|
||||
from util.registry.gzipwrap import GzipWrap
|
||||
|
||||
|
@ -10,6 +11,11 @@ class ManifestJSON(namedtuple('ManifestJSON', ['digest', 'json', 'media_type']))
|
|||
ManifestJSON represents a Manifest of any format.
|
||||
"""
|
||||
|
||||
class RepositoryReference(namedtuple('RepositoryReference', ['id', 'name', 'namespace_name'])):
|
||||
"""
|
||||
RepositoryReference represents a reference to a Repository, without its full metadata.
|
||||
"""
|
||||
|
||||
|
||||
class Repository(namedtuple('Repository', ['id', 'name', 'namespace_name', 'description',
|
||||
'is_public'])):
|
||||
|
@ -24,15 +30,16 @@ class Tag(namedtuple('Tag', ['name', 'repository'])):
|
|||
"""
|
||||
|
||||
|
||||
class BlobUpload(namedtuple('BlobUpload', ['uuid', 'byte_count', 'uncompressed_byte_count',
|
||||
'chunk_count', 'sha_state', 'location_name',
|
||||
'storage_metadata', 'piece_sha_state', 'piece_hashes'])):
|
||||
class BlobUpload(namedlist('BlobUpload', ['uuid', 'byte_count', 'uncompressed_byte_count',
|
||||
'chunk_count', 'sha_state', 'location_name',
|
||||
'storage_metadata', 'piece_sha_state', 'piece_hashes',
|
||||
'repo_namespace_name', 'repo_name'])):
|
||||
"""
|
||||
BlobUpload represents the current state of an Blob being uploaded.
|
||||
"""
|
||||
|
||||
|
||||
class Blob(namedtuple('Blob', ['digest', 'size', 'locations'])):
|
||||
class Blob(namedtuple('Blob', ['uuid', 'digest', 'size', 'locations'])):
|
||||
"""
|
||||
Blob represents an opaque binary blob saved to the storage system.
|
||||
"""
|
||||
|
|
|
@ -121,6 +121,10 @@ class DockerSchema1Manifest(object):
|
|||
def content_type(self):
|
||||
return DOCKER_SCHEMA1_SIGNED_MANIFEST_CONTENT_TYPE
|
||||
|
||||
@property
|
||||
def media_type(self):
|
||||
return DOCKER_SCHEMA1_SIGNED_MANIFEST_CONTENT_TYPE
|
||||
|
||||
@property
|
||||
def signatures(self):
|
||||
return self._signatures
|
||||
|
@ -137,6 +141,10 @@ class DockerSchema1Manifest(object):
|
|||
def tag(self):
|
||||
return self._tag
|
||||
|
||||
@property
|
||||
def json(self):
|
||||
return self._bytes
|
||||
|
||||
@property
|
||||
def bytes(self):
|
||||
return self._bytes
|
||||
|
@ -216,11 +224,12 @@ class DockerSchema1Manifest(object):
|
|||
content, but the checksums don't match, then we need to rewrite the image ID
|
||||
to something new in order to ensure consistency.
|
||||
"""
|
||||
# used to synthesize a new "content addressable" image id
|
||||
digest_history = hashlib.sha256()
|
||||
|
||||
# Used to synthesize a new "content addressable" image id
|
||||
digest_history = hashlib.sha256()
|
||||
has_rewritten_ids = False
|
||||
updated_id_map = {}
|
||||
|
||||
for layer in self.layers:
|
||||
digest_str = str(layer.digest)
|
||||
extracted_v1_metadata = layer.v1_metadata
|
||||
|
@ -247,25 +256,33 @@ class DockerSchema1Manifest(object):
|
|||
# Lookup the parent image for the layer, if any.
|
||||
parent_image_id = None
|
||||
if extracted_v1_metadata.parent_image_id is not None:
|
||||
parent_image_id = images_map.get(extracted_v1_metadata.parent_image_id, None)
|
||||
if parent_image_id is None:
|
||||
parent_image = images_map.get(extracted_v1_metadata.parent_image_id, None)
|
||||
if parent_image is None:
|
||||
raise MalformedSchema1Manifest('parent not found with image ID: %s' %
|
||||
extracted_v1_metadata.parent_image_id)
|
||||
parent_image_id = updated_id_map.get(parent_image.image_id, parent_image.image_id)
|
||||
|
||||
# Synthesize and store the v1 metadata in the db.
|
||||
v1_metadata_json = layer.raw_v1_metadata
|
||||
if has_rewritten_ids:
|
||||
v1_metadata_json = _updated_v1_metadata(v1_metadata_json, updated_id_map)
|
||||
|
||||
yield DockerV1Metadata(
|
||||
updated_image = DockerV1Metadata(
|
||||
namespace_name=self.namespace,
|
||||
repo_name=self.repo_name,
|
||||
image_id=working_image_id,
|
||||
created=extracted_v1_metadata.created,
|
||||
comment=extracted_v1_metadata.comment,
|
||||
command=extracted_v1_metadata.command,
|
||||
compat_json=v1_metadata_json,
|
||||
parent_image_id=parent_image_id,
|
||||
checksum=None, # TODO: Check if we need this.
|
||||
content_checksum=digest_str,
|
||||
)
|
||||
|
||||
images_map[updated_image.image_id] = updated_image
|
||||
yield updated_image
|
||||
|
||||
|
||||
class DockerSchema1ManifestBuilder(object):
|
||||
"""
|
||||
|
|
Reference in a new issue