Merge pull request #3257 from quay/joseph.schorr/QUAY-1030/interfacing-part-9-2

Finish changing V1 to use new registry data model
This commit is contained in:
Joseph Schorr 2018-09-30 15:59:50 -04:00 committed by GitHub
commit ce19273c54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 606 additions and 683 deletions

View file

@ -3,7 +3,7 @@ import json
from cStringIO import StringIO
from enum import Enum, unique
from digest.checksums import compute_simple
from digest.checksums import compute_simple, compute_tarsum
from test.registry.protocols import (RegistryProtocol, Failures, ProtocolOptions, PushResult,
PullResult)
@ -31,7 +31,7 @@ class V1Protocol(RegistryProtocol):
V1ProtocolSteps.GET_IMAGES: {
Failures.UNAUTHENTICATED: 403,
Failures.UNAUTHORIZED: 403,
Failures.APP_REPOSITORY: 405,
Failures.APP_REPOSITORY: 404,
Failures.ANONYMOUS_NOT_ALLOWED: 401,
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
Failures.NAMESPACE_DISABLED: 400,
@ -93,7 +93,7 @@ class V1Protocol(RegistryProtocol):
# GET /v1/repositories/{namespace}/{repository}/tags
image_ids = self.conduct(session, 'GET', prefix + 'tags', headers=headers).json()
assert len(image_ids.values()) == len(tag_names)
assert len(image_ids.values()) >= len(tag_names)
for tag_name in tag_names:
if tag_name not in image_ids:
@ -165,13 +165,21 @@ class V1Protocol(RegistryProtocol):
expected_status=(200, expected_failure,
V1ProtocolSteps.PUT_IMAGE_JSON))
if response.status_code != 200:
break
return
# PUT /v1/images/{imageID}/checksum (old style)
old_checksum = compute_tarsum(StringIO(image.bytes), json.dumps(image_json_data))
checksum_headers = {'X-Docker-Checksum': old_checksum}
checksum_headers.update(headers)
self.conduct(session, 'PUT', '/v1/images/%s/checksum' % image.id,
headers=checksum_headers)
# PUT /v1/images/{imageID}/layer
self.conduct(session, 'PUT', '/v1/images/%s/layer' % image.id,
data=StringIO(image.bytes), headers=headers)
# PUT /v1/images/{imageID}/checksum
# PUT /v1/images/{imageID}/checksum (new style)
checksum = compute_simple(StringIO(image.bytes), json.dumps(image_json_data))
checksum_headers = {'X-Docker-Checksum-Payload': checksum}
checksum_headers.update(headers)
@ -208,3 +216,12 @@ class V1Protocol(RegistryProtocol):
'/v1/repositories/%s/tags/%s' % (self.repo_name(namespace, repo_name), tag_name),
auth=auth,
expected_status=(200, expected_failure, V1ProtocolSteps.DELETE_TAG))
def tag(self, session, namespace, repo_name, tag_name, image, credentials=None,
expected_failure=None, options=None):
auth = self._auth_for_credentials(credentials)
self.conduct(session, 'PUT',
'/v1/repositories/%s/tags/%s' % (self.repo_name(namespace, repo_name), tag_name),
data='"%s"' % image.id,
auth=auth,
expected_status=(200, expected_failure, V1ProtocolSteps.PUT_TAG))

View file

@ -97,6 +97,11 @@ class RegistryProtocol(object):
the given credentials.
"""
@abstractmethod
def delete(self, session, namespace, repo_name, tag_names, credentials=None,
expected_failure=None, options=None):
""" Deletes some tags. """
def repo_name(self, namespace, repo_name):
if namespace:
return '%s/%s' % (namespace, repo_name)

View file

@ -226,7 +226,7 @@ def test_push_pull_logging(credentials, namespace, expected_performer, pusher, p
credentials = credentials(api_caller, registry_server_executor.on(liveserver))
# Push to the repository with the specified credentials.
pusher.push(liveserver_session, namespace, 'newrepo', 'latest', basic_images,
pusher.push(liveserver_session, namespace, 'newrepo', 'anothertag', basic_images,
credentials=credentials)
# Check the logs for the push.
@ -243,7 +243,7 @@ def test_push_pull_logging(credentials, namespace, expected_performer, pusher, p
assert logs[0]['performer']['name'] == expected_performer
# Pull the repository to verify.
puller.pull(liveserver_session, namespace, 'newrepo', 'latest', basic_images,
puller.pull(liveserver_session, namespace, 'newrepo', 'anothertag', basic_images,
credentials=credentials)
# Check the logs for the pull.
@ -1299,3 +1299,20 @@ def test_push_pull_same_blobs(pusher, puller, liveserver_session, app_reloader):
# Pull the repository to verify.
puller.pull(liveserver_session, 'devtable', 'newrepo', 'latest', images,
credentials=credentials, options=options)
def test_push_tag_existing_image(v1_protocol, puller, basic_images, liveserver_session, app_reloader):
""" Test: Push a new tag on an existing manifest/image. """
credentials = ('devtable', 'password')
# Push a new repository.
result = v1_protocol.push(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images,
credentials=credentials)
# Push the same image/manifest to another tag in the repository.
v1_protocol.tag(liveserver_session, 'devtable', 'newrepo', 'anothertag', basic_images[-1],
credentials=credentials)
# Pull the repository to verify.
puller.pull(liveserver_session, 'devtable', 'newrepo', 'anothertag', basic_images,
credentials=credentials)

View file

@ -793,26 +793,6 @@ class RegistryTestsMixin(object):
# Pull the repository to verify.
self.do_pull('public', 'foo.bar', 'public', 'password')
def test_application_repo(self):
# Create an application repository via the API.
self.conduct_api_login('devtable', 'password')
data = {
'repository': 'someapprepo',
'visibility': 'private',
'repo_kind': 'application',
'description': 'test app repo',
}
self.conduct('POST', '/api/v1/repository', json_data=data, expected_code=201)
# Try to push to the repo, which should fail with a 405.
self.do_push('devtable', 'someapprepo', 'devtable', 'password',
expect_failure=FailureCodes.APP_REPOSITORY)
# Try to pull from the repo, which should fail with a 405.
self.do_pull('devtable', 'someapprepo', 'devtable', 'password',
expect_failure=FailureCodes.APP_REPOSITORY)
def test_middle_layer_different_sha(self):
if self.push_version == 'v1':
# No SHAs to munge in V1.

View file

@ -137,11 +137,11 @@ def build_v1_index_specs():
IndexV1TestSpec(url_for('v1.put_image_layer', image_id=FAKE_IMAGE_ID),
PUBLIC_REPO, 403, 403, 403, 403, 403).set_method('PUT'),
IndexV1TestSpec(url_for('v1.put_image_layer', image_id=FAKE_IMAGE_ID),
PRIVATE_REPO, 403, 403, 403, 403, 404).set_method('PUT'),
PRIVATE_REPO, 403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.put_image_layer', image_id=FAKE_IMAGE_ID),
ORG_REPO, 403, 403, 403, 403, 404).set_method('PUT'),
ORG_REPO, 403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.put_image_layer', image_id=FAKE_IMAGE_ID),
ANOTHER_ORG_REPO, 403, 403, 403, 403, 404).set_method('PUT'),
ANOTHER_ORG_REPO, 403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.put_image_checksum',
image_id=FAKE_IMAGE_ID),
@ -205,11 +205,11 @@ def build_v1_index_specs():
IndexV1TestSpec(url_for('v1.update_images', repository=PUBLIC_REPO),
NO_REPO, 403, 403, 403, 403, 403).set_method('PUT'),
IndexV1TestSpec(url_for('v1.update_images', repository=PRIVATE_REPO),
NO_REPO, 403, 403, 403, 403, 204).set_method('PUT'),
NO_REPO, 403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.update_images', repository=ORG_REPO), NO_REPO,
403, 403, 403, 403, 204).set_method('PUT'),
403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.update_images', repository=ANOTHER_ORG_REPO), NO_REPO,
403, 403, 403, 403, 204).set_method('PUT'),
403, 403, 403, 403, 400).set_method('PUT'),
IndexV1TestSpec(url_for('v1.get_repository_images',
repository=PUBLIC_REPO),