def push( self, session, namespace, repo_name, tag_names, images, credentials=None, expected_failure=None, options=None, ): auth = self._auth_for_credentials(credentials) tag_names = [tag_names] if isinstance(tag_names, str) else tag_names # Ping! self.ping(session) # PUT /v1/repositories/{namespace}/{repository}/ result = self.conduct( session, "PUT", "/v1/repositories/%s/" % self.repo_name(namespace, repo_name), expected_status=(201, expected_failure, V1ProtocolSteps.PUT_IMAGES), json_data={}, auth=auth, ) if result.status_code != 201: return headers = {} headers[ "Authorization"] = "token " + result.headers["www-authenticate"] for image in images: assert image.urls is None # PUT /v1/images/{imageID}/json image_json_data = {"id": image.id} if image.size is not None: image_json_data["Size"] = image.size if image.parent_id is not None: image_json_data["parent"] = image.parent_id if image.config is not None: image_json_data["config"] = image.config if image.created is not None: image_json_data["created"] = image.created image_json = json.dumps(image_json_data) response = self.conduct( session, "PUT", "/v1/images/%s/json" % image.id, data=image_json, headers=headers, expected_status=(200, expected_failure, V1ProtocolSteps.PUT_IMAGE_JSON), ) if response.status_code != 200: return # PUT /v1/images/{imageID}/checksum (old style) old_checksum = compute_tarsum(BytesIO(image.bytes), image_json) 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=BytesIO(image.bytes), headers=headers, ) # PUT /v1/images/{imageID}/checksum (new style) checksum = compute_simple(BytesIO(image.bytes), image_json) checksum_headers = {"X-Docker-Checksum-Payload": checksum} checksum_headers.update(headers) self.conduct(session, "PUT", "/v1/images/%s/checksum" % image.id, headers=checksum_headers) # PUT /v1/repositories/{namespace}/{repository}/tags/latest for tag_name in tag_names: self.conduct( session, "PUT", "/v1/repositories/%s/tags/%s" % (self.repo_name(namespace, repo_name), tag_name), data='"%s"' % images[-1].id, headers=headers, expected_status=(200, expected_failure, V1ProtocolSteps.PUT_TAG), ) # PUT /v1/repositories/{namespace}/{repository}/images self.conduct( session, "PUT", "/v1/repositories/%s/images" % self.repo_name(namespace, repo_name), expected_status=204, headers=headers, ) return PushResult(manifests=None, headers=headers)
def push(self, session, namespace, repo_name, tag_names, images, credentials=None, expected_failure=None, options=None): auth = self._auth_for_credentials(credentials) tag_names = [tag_names] if isinstance(tag_names, str) else tag_names # Ping! self.ping(session) # PUT /v1/repositories/{namespace}/{repository}/ result = self.conduct(session, 'PUT', '/v1/repositories/%s/' % self.repo_name(namespace, repo_name), expected_status=(201, expected_failure, V1ProtocolSteps.PUT_IMAGES), json_data={}, auth=auth) if result.status_code != 201: return headers = {} headers[ 'Authorization'] = 'token ' + result.headers['www-authenticate'] for image in images: assert image.urls is None # PUT /v1/images/{imageID}/json image_json_data = {'id': image.id} if image.size is not None: image_json_data['Size'] = image.size if image.parent_id is not None: image_json_data['parent'] = image.parent_id if image.config is not None: image_json_data['config'] = image.config if image.created is not None: image_json_data['created'] = image.created image_json = json.dumps(image_json_data) response = self.conduct( session, 'PUT', '/v1/images/%s/json' % image.id, data=image_json, headers=headers, expected_status=(200, expected_failure, V1ProtocolSteps.PUT_IMAGE_JSON)) if response.status_code != 200: return # PUT /v1/images/{imageID}/checksum (old style) old_checksum = compute_tarsum(StringIO(image.bytes), image_json) 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 (new style) checksum = compute_simple(StringIO(image.bytes), image_json) checksum_headers = {'X-Docker-Checksum-Payload': checksum} checksum_headers.update(headers) self.conduct(session, 'PUT', '/v1/images/%s/checksum' % image.id, headers=checksum_headers) # PUT /v1/repositories/{namespace}/{repository}/tags/latest for tag_name in tag_names: self.conduct(session, 'PUT', '/v1/repositories/%s/tags/%s' % (self.repo_name(namespace, repo_name), tag_name), data='"%s"' % images[-1].id, headers=headers, expected_status=(200, expected_failure, V1ProtocolSteps.PUT_TAG)) # PUT /v1/repositories/{namespace}/{repository}/images self.conduct(session, 'PUT', '/v1/repositories/%s/images' % self.repo_name(namespace, repo_name), expected_status=204, headers=headers) return PushResult(manifests=None, headers=headers)