summaryrefslogtreecommitdiff
path: root/lib/container_registry/client.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/container_registry/client.rb')
-rw-r--r--lib/container_registry/client.rb59
1 files changed, 57 insertions, 2 deletions
diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb
index 15f40993ea3..92861c567a8 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
@@ -33,7 +36,48 @@ module ContainerRegistry
end
def delete_repository_tag(name, reference)
- faraday.delete("/v2/#{name}/manifests/#{reference}").success?
+ result = faraday.delete("/v2/#{name}/manifests/#{reference}")
+
+ result.success? || result.status == 404
+ 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)
@@ -42,7 +86,18 @@ module ContainerRegistry
end
def delete_blob(name, digest)
- faraday.delete("/v2/#{name}/blobs/#{digest}").success?
+ result = faraday.delete("/v2/#{name}/blobs/#{digest}")
+
+ result.success? || result.status == 404
+ 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