summaryrefslogtreecommitdiff
path: root/lib/container_registry
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-19 11:50:12 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-19 11:50:12 +0000
commit6cd5b7dbfaa4ff630ecbbfe351a1faac5fc71a8d (patch)
treed3563b9f60936c18a02185e2e53b424bb1b83539 /lib/container_registry
parentb3e0658cb1fbc7c8e7dd381467c656f2e675ee46 (diff)
downloadgitlab-ce-6cd5b7dbfaa4ff630ecbbfe351a1faac5fc71a8d.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/container_registry')
-rw-r--r--lib/container_registry/client.rb51
-rw-r--r--lib/container_registry/tag.rb9
2 files changed, 59 insertions, 1 deletions
diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb
index 15f40993ea3..2bd8eb65306 100644
--- a/lib/container_registry/client.rb
+++ b/lib/container_registry/client.rb
@@ -2,6 +2,7 @@
require 'faraday'
require 'faraday_middleware'
+require 'digest'
module ContainerRegistry
class Client
@@ -9,6 +10,8 @@ module ContainerRegistry
DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE = 'application/vnd.docker.distribution.manifest.v2+json'
OCI_MANIFEST_V1_TYPE = 'application/vnd.oci.image.manifest.v1+json'
+ CONTAINER_IMAGE_V1_TYPE = 'application/vnd.docker.container.image.v1+json'
+
ACCEPTED_TYPES = [DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE, OCI_MANIFEST_V1_TYPE].freeze
# Taken from: FaradayMiddleware::FollowRedirects
@@ -36,6 +39,45 @@ module ContainerRegistry
faraday.delete("/v2/#{name}/manifests/#{reference}").success?
end
+ def upload_raw_blob(path, blob)
+ digest = "sha256:#{Digest::SHA256.hexdigest(blob)}"
+
+ if upload_blob(path, blob, digest).success?
+ [blob, digest]
+ end
+ end
+
+ def upload_blob(name, content, digest)
+ upload = faraday.post("/v2/#{name}/blobs/uploads/")
+ return unless upload.success?
+
+ location = URI(upload.headers['location'])
+
+ faraday.put("#{location.path}?#{location.query}") do |req|
+ req.params['digest'] = digest
+ req.headers['Content-Type'] = 'application/octet-stream'
+ req.body = content
+ end
+ end
+
+ def generate_empty_manifest(path)
+ image = {
+ config: {}
+ }
+ image, image_digest = upload_raw_blob(path, JSON.pretty_generate(image))
+ return unless image
+
+ {
+ schemaVersion: 2,
+ mediaType: DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE,
+ config: {
+ mediaType: CONTAINER_IMAGE_V1_TYPE,
+ size: image.size,
+ digest: image_digest
+ }
+ }
+ end
+
def blob(name, digest, type = nil)
type ||= 'application/octet-stream'
response_body faraday_blob.get("/v2/#{name}/blobs/#{digest}", nil, 'Accept' => type), allow_redirect: true
@@ -45,6 +87,15 @@ module ContainerRegistry
faraday.delete("/v2/#{name}/blobs/#{digest}").success?
end
+ def put_tag(name, reference, manifest)
+ response = faraday.put("/v2/#{name}/manifests/#{reference}") do |req|
+ req.headers['Content-Type'] = DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE
+ req.body = JSON.pretty_generate(manifest)
+ end
+
+ response.headers['docker-content-digest'] if response.success?
+ end
+
private
def initialize_connection(conn, options)
diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb
index ebea84fa1ca..2cc4c8d8b1c 100644
--- a/lib/container_registry/tag.rb
+++ b/lib/container_registry/tag.rb
@@ -98,6 +98,10 @@ module ContainerRegistry
end
end
+ def put(digests)
+ repository.client.put_tag(repository.path, name, digests)
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def total_size
return unless layers
@@ -106,7 +110,10 @@ module ContainerRegistry
end
# rubocop: enable CodeReuse/ActiveRecord
- def delete
+ # Deletes the image associated with this tag
+ # Note this will delete the image and all tags associated with it.
+ # Consider using DeleteTagsService instead.
+ def unsafe_delete
return unless digest
client.delete_repository_tag(repository.path, digest)