docker-remote 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +11 -0
- data/Rakefile +14 -0
- data/docker-remote.gemspec +17 -0
- data/lib/docker/remote.rb +9 -0
- data/lib/docker/remote/client.rb +114 -0
- data/lib/docker/remote/server_auth.rb +20 -0
- data/lib/docker/remote/version.rb +5 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f8dcfda8b4cbf58474274964a653f5049f609333bf88d1b9497205a4bb366e6e
|
4
|
+
data.tar.gz: 9ec104d6e95619a579b0e8e4049d00d6e1eb68c425f7490a83a12477ca812e21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 96faa086fc0223dc3377c77e57042b806f446923156c46bf6627438d64104c06bcadcda9674901a830f209ab68abb09a79335893df8e9428472d292e62dc8c83
|
7
|
+
data.tar.gz: '038eb80f159cc9c1c0a3740923c55a4c351c156b10a1e641aaaf4f3d7ceab790fe03d1ca0001f5b2b150978acf8f3e709654764b1e9ab9e950874d2837b54c59'
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
|
5
|
+
require 'docker/remote'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
task default: :spec
|
10
|
+
|
11
|
+
desc 'Run specs'
|
12
|
+
RSpec::Core::RakeTask.new do |t|
|
13
|
+
t.pattern = './spec/**/*_spec.rb'
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'docker/remote/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'docker-remote'
|
6
|
+
s.version = ::Docker::Remote::VERSION
|
7
|
+
s.authors = ['Cameron Dutro']
|
8
|
+
s.email = ['camertron@gmail.com']
|
9
|
+
s.homepage = 'http://github.com/getkuby/docker-remote'
|
10
|
+
|
11
|
+
s.description = s.summary = 'A Ruby client for communicating with the Docker HTTP API v2.'
|
12
|
+
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
|
15
|
+
s.require_path = 'lib'
|
16
|
+
s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'CHANGELOG.md', 'README.md', 'Rakefile', 'docker-remote.gemspec']
|
17
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Docker
|
4
|
+
module Remote
|
5
|
+
class ClientError < StandardError; end
|
6
|
+
class ServerError < StandardError; end
|
7
|
+
class UnauthorizedError < ClientError; end
|
8
|
+
class NotFoundError < ClientError; end
|
9
|
+
|
10
|
+
class Client
|
11
|
+
attr_reader :registry_url, :repo, :username, :password
|
12
|
+
|
13
|
+
def initialize(registry_url, repo, username = nil, password = nil)
|
14
|
+
@registry_url = registry_url
|
15
|
+
@repo = repo
|
16
|
+
@username = username
|
17
|
+
@password = password
|
18
|
+
end
|
19
|
+
|
20
|
+
def tags
|
21
|
+
request = make_get("/v2/#{repo}/tags/list")
|
22
|
+
response = registry_http.request(request)
|
23
|
+
potentially_raise_error!(response)
|
24
|
+
JSON.parse(response.body)['tags']
|
25
|
+
end
|
26
|
+
|
27
|
+
def manifest_for(reference)
|
28
|
+
request = make_get("/v2/#{repo}/manifests/#{reference}")
|
29
|
+
response = registry_http.request(request)
|
30
|
+
potentially_raise_error!(response)
|
31
|
+
JSON.parse(response.body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def catalog
|
35
|
+
request = make_get("/v2/_catalog")
|
36
|
+
response = registry_http.request(request)
|
37
|
+
potentially_raise_error!(response)
|
38
|
+
JSON.parse(response.body)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def token
|
44
|
+
@token ||= begin
|
45
|
+
uri = URI.parse(server_auth.realm)
|
46
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
47
|
+
http.use_ssl = true if uri.scheme == 'https'
|
48
|
+
|
49
|
+
request = Net::HTTP::Get.new(
|
50
|
+
"#{uri.request_uri}?service=#{server_auth.service}&scope=repository:#{repo}:pull"
|
51
|
+
)
|
52
|
+
|
53
|
+
if username && password
|
54
|
+
request.basic_auth(username, password)
|
55
|
+
end
|
56
|
+
|
57
|
+
response = http.request(request)
|
58
|
+
potentially_raise_error!(response)
|
59
|
+
JSON.parse(response.body)['token']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def server_auth
|
64
|
+
@server_auth ||= begin
|
65
|
+
request = Net::HTTP::Get.new('/v2/')
|
66
|
+
response = registry_http.request(request)
|
67
|
+
auth = response['www-authenticate']
|
68
|
+
|
69
|
+
idx = auth.index(' ')
|
70
|
+
auth_type = auth[0..idx].strip
|
71
|
+
|
72
|
+
params = auth[idx..-1].split(',').each_with_object({}) do |param, ret|
|
73
|
+
key, value = param.split('=')
|
74
|
+
ret[key.strip] = value.strip[1..-2] # remove quotes
|
75
|
+
end
|
76
|
+
|
77
|
+
ServerAuth.new(auth_type, params)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def registry_uri
|
82
|
+
@registry_uri ||= URI.parse(registry_url)
|
83
|
+
end
|
84
|
+
|
85
|
+
def registry_http
|
86
|
+
@registry_http ||= Net::HTTP.new(registry_uri.host, registry_uri.port).tap do |http|
|
87
|
+
http.use_ssl = true if registry_uri.scheme == 'https'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def make_get(path)
|
92
|
+
Net::HTTP::Get.new(path).tap do |request|
|
93
|
+
request['Authorization'] = "Bearer #{token}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def potentially_raise_error!(response)
|
98
|
+
case response.code.to_i
|
99
|
+
when 401
|
100
|
+
raise UnauthorizedError, "401 Unauthorized: #{response.message}"
|
101
|
+
when 404
|
102
|
+
raise NotFoundError, "404 Not Found: #{response.message}"
|
103
|
+
end
|
104
|
+
|
105
|
+
case response.code.to_i / 100
|
106
|
+
when 4
|
107
|
+
raise ClientError, "#{response.code}: #{response.message}"
|
108
|
+
when 5
|
109
|
+
raise ServerError, "#{response.code}: #{response.message}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Docker
|
2
|
+
module Remote
|
3
|
+
class ServerAuth
|
4
|
+
attr_reader :auth_type, :params
|
5
|
+
|
6
|
+
def initialize(auth_type, params)
|
7
|
+
@auth_type = auth_type
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def realm
|
12
|
+
@params['realm']
|
13
|
+
end
|
14
|
+
|
15
|
+
def service
|
16
|
+
@params['service']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docker-remote
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cameron Dutro
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A Ruby client for communicating with the Docker HTTP API v2.
|
14
|
+
email:
|
15
|
+
- camertron@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- CHANGELOG.md
|
21
|
+
- Gemfile
|
22
|
+
- Rakefile
|
23
|
+
- docker-remote.gemspec
|
24
|
+
- lib/docker/remote.rb
|
25
|
+
- lib/docker/remote/client.rb
|
26
|
+
- lib/docker/remote/server_auth.rb
|
27
|
+
- lib/docker/remote/version.rb
|
28
|
+
homepage: http://github.com/getkuby/docker-remote
|
29
|
+
licenses: []
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.0.6
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: A Ruby client for communicating with the Docker HTTP API v2.
|
50
|
+
test_files: []
|