Class: DockerRegistry2::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/registry/registry.rb

Instance Method Summary collapse

Constructor Details

#initialize(uri, options = {}) ⇒ Registry

Returns a new instance of Registry.

Parameters:

  • base_uri (#to_s)

    Docker registry base URI

  • options (Hash) (defaults to: {})

    Client options

Options Hash (options):

  • :user (#to_s)

    User name for basic authentication

  • :password (#to_s)

    Password for basic authentication

  • :open_timeout (#to_s)

    Time to wait for a connection with a registry

  • :read_timeout (#to_s)

    Time to wait for data from a registry



12
13
14
15
16
17
18
19
# File 'lib/registry/registry.rb', line 12

def initialize(uri, options = {})
  @uri = URI.parse(uri)
  @base_uri = "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
  @user = options[:user]
  @password = options[:password]
  @open_timeout = options[:open_timeout] || 2
  @read_timeout = options[:read_timeout] || 5
end

Instance Method Details

#_pull_v1(repo, manifest, dir) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/registry/registry.rb', line 130

def _pull_v1(repo, manifest, dir)
  # make sure the directory exists
  FileUtils.mkdir_p dir
  return false unless manifest['schemaVersion'] == 1
  # pull each of the layers
  manifest['fsLayers'].each do |layer|
    # define path of file to save layer in
    layer_file = "#{dir}/#{layer['blobSum']}"
    # skip layer if we already got it
    next if File.file? layer_file
    # download layer
    # puts "getting layer (v1) #{layer['blobSum']}"
    File.open(layer_file, 'w') do |fd|
      doreq('get',
            "/v2/#{repo}/blobs/#{layer['blobSum']}",
            fd)
    end
    # return layer file
    layer_file
  end
end

#_pull_v2(repo, manifest, dir) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/registry/registry.rb', line 109

def _pull_v2(repo, manifest, dir)
  # make sure the directory exists
  FileUtils.mkdir_p dir
  return false unless manifest['schemaVersion'] == 2
  # pull each of the layers
  manifest['layers'].each do |layer|
    # define path of file to save layer in
    layer_file = "#{dir}/#{layer['digest']}"
    # skip layer if we already got it
    next if File.file? layer_file
    # download layer
    # puts "getting layer (v2) #{layer['digest']}"
    File.open(layer_file, 'w') do |fd|
      doreq('get',
            "/v2/#{repo}/blobs/#{layer['digest']}",
            fd)
    end
    layer_file
  end
end

#blob_size(repo, blobSum) ⇒ Object

gets the size of a particular blob, given the repo and the content-addressable hash usually unneeded, since manifest includes it



163
164
165
166
# File 'lib/registry/registry.rb', line 163

def blob_size(repo,blobSum)
  response = dohead "/v2/#{repo}/blobs/#{blobSum}"
  Integer(response.headers[:content_length],10)
end

#copy(repo, tag, newregistry, newrepo, newtag) ⇒ Object



158
159
# File 'lib/registry/registry.rb', line 158

def copy(repo,tag,newregistry,newrepo,newtag)
end

#digest(repo, tag) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/registry/registry.rb', line 80

def digest(repo, tag)
  tag_path = "/v2/#{repo}/manifests/#{tag}"
  dohead(tag_path).headers[:docker_content_digest]
rescue DockerRegistry2::InvalidMethod
  # Pre-2.3.0 registries didn't support manifest HEAD requests
  doget(tag_path).headers[:docker_content_digest]
end

#dodelete(url) ⇒ Object



25
26
27
# File 'lib/registry/registry.rb', line 25

def dodelete(url)
  return doreq "delete", url
end

#doget(url) ⇒ Object



21
22
23
# File 'lib/registry/registry.rb', line 21

def doget(url)
  return doreq "get", url
end

#dohead(url) ⇒ Object



29
30
31
# File 'lib/registry/registry.rb', line 29

def dohead(url)
  return doreq "head", url
end

#manifest(repo, tag) ⇒ Object



75
76
77
78
# File 'lib/registry/registry.rb', line 75

def manifest(repo,tag)
  # first get the manifest
  JSON.parse doget "/v2/#{repo}/manifests/#{tag}"
end

#manifest_sum(manifest) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/registry/registry.rb', line 168

def manifest_sum(manifest)
  size = 0
  manifest["layers"].each { |layer|
    size += layer["size"]
  }
  size
end

#pingObject



33
34
35
# File 'lib/registry/registry.rb', line 33

def ping
  response = doget '/v2/'
end

#pull(repo, tag, dir) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/registry/registry.rb', line 95

def pull(repo, tag, dir)
  # make sure the directory exists
  FileUtils.mkdir_p dir
  # get the manifest
  m = manifest repo, tag
  # puts "pulling #{repo}:#{tag} into #{dir}"
  # manifest can contain multiple manifests one for each API version
  downloaded_layers = []
  downloaded_layers += _pull_v2(repo, m, dir) if m['schemaVersion'] == 2
  downloaded_layers += _pull_v1(repo, m, dir) if m['schemaVersion'] == 1
  # return downloaded_layers
  downloaded_layers
end

#push(manifest, dir) ⇒ Object



152
153
# File 'lib/registry/registry.rb', line 152

def push(manifest,dir)
end

#rmtag(image, tag) ⇒ Object



88
89
90
91
92
93
# File 'lib/registry/registry.rb', line 88

def rmtag(image, tag)
  # TODO: Need full response back. Rewrite other manifests() calls without JSON?
  reference = doget("/v2/#{image}/manifests/#{tag}").headers[:docker_content_digest]

  return dodelete("/v2/#{image}/manifests/#{reference}").code
end

#search(query = '') ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/registry/registry.rb', line 37

def search(query = '')
  response = doget "/v2/_catalog"
  # parse the response
  repos = JSON.parse(response)["repositories"]
  if query.strip.length > 0
    re = Regexp.new query
    repos = repos.find_all {|e| re =~ e }
  end
  return repos
end

#tag(repo, tag, newrepo, newtag) ⇒ Object



155
156
# File 'lib/registry/registry.rb', line 155

def tag(repo,tag,newrepo,newtag)
end

#tags(repo, withHashes = false) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/registry/registry.rb', line 48

def tags(repo,withHashes = false)
  response = doget "/v2/#{repo}/tags/list"
  # parse the response
  resp = JSON.parse response
  # do we include the hashes?
  if withHashes then
    useGet = false
    resp["hashes"] = {}
    resp["tags"].each {|tag|
      if useGet then
        head = doget "/v2/#{repo}/manifests/#{tag}"
      else
        begin
          head = dohead "/v2/#{repo}/manifests/#{tag}"
        rescue DockerRegistry2::InvalidMethod
          # in case we are in a registry pre-2.3.0, which did not support manifest HEAD
          useGet = true
          head = doget "/v2/#{repo}/manifests/#{tag}"
        end
      end
      resp["hashes"][tag] = head.headers[:docker_content_digest]
    }
  end

  return resp
end