Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
lib/portus: we can now remove image manifests
Browse files Browse the repository at this point in the history
Signed-off-by: Miquel Sabaté <[email protected]>
  • Loading branch information
mssola committed Apr 11, 2016
1 parent a4ce4f4 commit 8573026
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
16 changes: 12 additions & 4 deletions bin/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# These are the available commands:
# - catalog
# - delete <name> <digest>
# - delete <name> <digest> blobs/manifests
# - manifest <name>[:<tag>]
# - ping <hostname:port> [use_ssl]

Expand All @@ -23,11 +23,17 @@
puts catalog.inspect
puts "Size: #{catalog.size}"
when "delete"
if ARGV.length == 2
puts "You have to specify first the name, and then the digest"
if ARGV.length != 4
puts "usage: delete <name> <digest> blobs/manifests"
exit 1
end
pp registry.client.delete(ARGV[1], ARGV[2])

if ARGV[3] != "blobs" && ARGV[3] != "manifests"
puts "Unknown #{ARGV[3]} object. Only available: blobs and manifests."
exit 1
end

pp registry.client.delete(ARGV[1], ARGV[2], ARGV[3])
when "manifest"
if ARGV.length == 1
puts "You have to at least specify the name of the image"
Expand All @@ -39,7 +45,9 @@
else
name, tag = ARGV[1], "latest"
end

puts JSON.pretty_generate(registry.client.manifest(name, tag))
puts "Manifest digest: #{registry.client.manifest(name, tag, true)}"
when "ping"
# No registry was found, trying to ping another one.
if registry.nil?
Expand Down
4 changes: 4 additions & 0 deletions lib/portus/http_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def perform_request(path, method = "get", request_auth_token = true)
uri = URI.join(@base_url, path)
req = Net::HTTP.const_get(method.capitalize).new(uri)

# So we deal with compatibility issues in distribution 2.3 and later.
# See: https://github.com/docker/distribution/blob/master/docs/compatibility.md#content-addressable-storage-cas
req["Accept"] = "application/vnd.docker.distribution.manifest.v2+json"

# This only happens if the auth token has already been set by a previous
# call.
req["Authorization"] = "Bearer #{@token}" if @token
Expand Down
25 changes: 14 additions & 11 deletions lib/portus/registry_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ def reachable?
!res.nil? && res.code.to_i == 401
end

# Retrieves the manifest for the required repository:tag. If everything goes
# well, it will return a parsed response from the registry, otherwise it will
# raise either ManifestNotFoundError or a RuntimeError.
def manifest(repository, tag = "latest")
res = perform_request("#{repository}/manifests/#{tag}")
# Calls the `/:repository/manifests/:tag` endpoint from the registry. With
# the `digest` parameter you can tell this method whether you want the full
# manifest for this tag, or just the digest. It defaults to false, meaning
# that the caller wants the full manifest. It will raise either a
# ManifestNotFoundError or a RuntimeError if something goes wrong.
def manifest(repository, tag = "latest", digest = false)
method = digest ? "head" : "get"
res = perform_request("#{repository}/manifests/#{tag}", method)

if res.code.to_i == 200
JSON.parse(res.body)
digest ? res["Docker-Content-Digest"] : JSON.parse(res.body)
elsif res.code.to_i == 404
handle_error res, repository: repository, tag: tag
else
Expand All @@ -61,11 +65,10 @@ def tags(repository)
paged_response("#{repository}/tags/list", "tags")
end

# Deletes a layer of the specified image. The layer is pointed by the digest
# as given by the manifest of the image itself. Returns true if the request
# was successful, otherwise it raises an exception.
def delete(name, digest)
res = perform_request("#{name}/blobs/#{digest}", "delete")
# Deletes a blob/manifest of the specified image. Returns true if the
# request was successful, otherwise it raises an exception.
def delete(name, digest, object = "blobs")
res = perform_request("#{name}/#{object}/#{digest}", "delete")
if res.code.to_i == 202
true
elsif res.code.to_i == 404 || res.code.to_i == 405
Expand Down

0 comments on commit 8573026

Please sign in to comment.