class Centurion::DockerRegistry

Constants

OFFICIAL_URL

Public Class Methods

new(base_uri, registry_user=nil, registry_password=nil) click to toggle source
# File lib/centurion/docker_registry.rb, line 10
def initialize(base_uri, registry_user=nil, registry_password=nil)
  @base_uri = base_uri
  @user = registry_user
  @password = registry_password
end

Public Instance Methods

digest_for_tag(repository, tag) click to toggle source
# File lib/centurion/docker_registry.rb, line 16
def digest_for_tag(repository, tag)
  path = "/v1/repositories/#{repository}/tags/#{tag}"
  uri = uri_for_repository_path(repository, path)
  $stderr.puts "GET: #{uri}"
  options = { headers: { "Content-Type" => "application/json" } }
  if @user
    options[:user] = @user
    options[:password] = @password
  end
  response = Excon.get(
    uri,
    options
  )
  raise response.inspect unless response.status == 200

  # This hack is stupid, and I hate it. But it works around the fact that
  # the Docker Registry will return a base JSON String, which the Ruby parser
  # refuses (possibly correctly) to handle
  JSON.load('[' + response.body + ']').first
end
repository_tags(repository) click to toggle source
# File lib/centurion/docker_registry.rb, line 37
def repository_tags(repository)
  path = "/v1/repositories/#{repository}/tags"
  uri = uri_for_repository_path(repository, path)

  $stderr.puts "GET: #{uri.inspect}"

  # Need to workaround a bug in Docker Hub to now pass port in Host header
  options = { omit_default_port: true }

  if @user
    options[:user] = @user
    options[:password] = @password
  end

  response = Excon.get(uri, options)
  raise response.inspect unless response.status == 200

  tags = JSON.load(response.body)

  # The Docker Registry API[1]  specifies a result in the format
  # { "[tag]" : "[image_id]" }. However, the official Docker registry returns a
  # result like [{ "layer": "[image_id]", "name": "[tag]" }].
  #
  # So, we need to normalize the response to what the Docker Registry API
  # specifies should be returned.
  #
  # [1]: https://docs.docker.com/v1.1/reference/api/registry_api/

  if is_official_registry?(repository)
    tags.each_with_object({}) do |tag, hash|
      hash[tag['name']] = tag['layer']
    end
  else
    tags
  end
end

Private Instance Methods

is_official_registry?(repository) click to toggle source
# File lib/centurion/docker_registry.rb, line 76
def is_official_registry?(repository)
  return @base_uri == OFFICIAL_URL
end
uri_for_repository_path(repository, path) click to toggle source
# File lib/centurion/docker_registry.rb, line 80
def uri_for_repository_path(repository, path)
  if repository.match(/\A([a-z0-9]+[a-z0-9\-\.]+(?::[1-9][0-9]*)?)\/(.*)\z/)
    host = $1
    short_image_name = $2
    "https://#{host}#{path.gsub(repository, short_image_name)}"
  else
    @base_uri + path
  end
end