dockerapi 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39b737a07cdf35864b8be1402ca7d504c59fc854e2092762df7a9f448bb2bf24
4
- data.tar.gz: d71d1894cab1f61a3713f0991d24c272f99373832bff140c962604a8d707621f
3
+ metadata.gz: 12366435331bd8fc215857a65d28b337f9ccb22556d8451e6f213d4fda8a5113
4
+ data.tar.gz: 724f52952a3f24dc664dc1b1b5cc66a75ae920b281de61b36ae74ed5431d7159
5
5
  SHA512:
6
- metadata.gz: 3622c339bae6e7a93738d110a5d6eaa38dda6288abeebda35c4b376cd354b33fa2b1595bf53fc2da04cf8a5e6f8e78a49f7cea10927afdb3fc719f119d94a8fd
7
- data.tar.gz: d40f00a1e7c913a5b005cba33182e2295da22d1631eb0fec23101d45639998391ad89829a03a51b3c197da8f69196c954fb8e70234f90175f2b7bbc410159be1
6
+ metadata.gz: 61ac762e369e72c7b715b2ae3c19cc9046fd25425ef865bbb723a86f79df57716dfa1c1d42720830b10f441150d96def147649921e764180c194e778589071bd
7
+ data.tar.gz: 9d2327454dc893fe4cf9ab5adf06619a69142dea22bad32536886552711f3f6119060f859092af4ab17285d2a740e2aa56b563d32fb367c5a55cc6183c2967dd
@@ -0,0 +1,45 @@
1
+ # 0.2.0
2
+
3
+ Add Docker::API::Image methods:
4
+ * inspect
5
+ * history
6
+ * list
7
+ * search
8
+ * tag
9
+ * prune
10
+ * remove
11
+ * export
12
+ * import
13
+ * push
14
+ * commit
15
+ * create
16
+ * build
17
+ * delete_cache
18
+
19
+ Add Docker::API::System.auth (untested) for basic authentication
20
+
21
+ # 0.1.0
22
+
23
+ Add Docker::API::Container methods:
24
+ * list
25
+ * inspect
26
+ * top
27
+ * changes
28
+ * start
29
+ * stop
30
+ * restart
31
+ * kill
32
+ * wait
33
+ * update
34
+ * rename
35
+ * resize
36
+ * prune
37
+ * pause
38
+ * unpause
39
+ * remove
40
+ * logs
41
+ * attach
42
+ * create
43
+ * stats
44
+ * export
45
+ * archive
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dockerapi (0.1.0)
5
- excon
4
+ dockerapi (0.2.0)
5
+ excon (~> 0.74.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -20,6 +20,76 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
+ ### Images
24
+
25
+ ```ruby
26
+ # Pull from a public repository
27
+ Docker::API::Image.create( fromImage: "nginx:latest" )
28
+
29
+ # Pull from a private repository
30
+ Docker::API::Image.create( {fromImage: "private/repo:tag"}, {username: "janedoe", password: "password"} )
31
+
32
+ # Create image from local tar file
33
+ Docker::API::Image.create( fromSrc: "/path/to/file.tar", repo: "repo:tag" )
34
+
35
+ # Create image from remote tar file
36
+ Docker::API::Image.create( fromSrc: "https://url.to/file.tar", repo: "repo:tag" )
37
+
38
+ # List images
39
+ Docker::API::Image.list
40
+ Docker::API::Image.list( all:true )
41
+
42
+ # Inspect image
43
+ Docker::API::Image.inspect("image")
44
+
45
+ # History
46
+ Docker::API::Image.history("image")
47
+
48
+ # Search image
49
+ Docker::API::Image.search(term: "busybox", limit: 2)
50
+ Docker::API::Image.search(term: "busybox", filters: {"is-automated": {"true": true}})
51
+ Docker::API::Image.search(term: "busybox", filters: {"is-official": {"true": true}})
52
+
53
+ # Tag image
54
+ Docker::API::Image.tag("current:tag", repo: "new:tag") # or
55
+ Docker::API::Image.tag("current:tag", repo: "new", tag: "tag")
56
+
57
+ # Push image
58
+ Docker::API::Image.push("repo:tag") # to dockerhub
59
+ Docker::API::Image.push("localhost:5000/repo:tag") # to local registry
60
+ Docker::API::Image.push("private/repo", {tag: "tag"}, {username: "janedoe", password: "password"} # to private repository
61
+
62
+ # Remove container
63
+ Docker::API::Image.remove("image")
64
+ Docker::API::Image.remove("image", force: true)
65
+
66
+ # Remove unsued images (prune)
67
+ Docker::API::Image.prune(filters: {dangling: {"false": true}})
68
+
69
+ # Create image from a container (commit)
70
+ Docker::API::Image.commit(container: container, repo: "my/image", tag: "latest", comment: "Comment from commit", author: "dockerapi", pause: false )
71
+
72
+ # Build image from a local tar file
73
+ Docker::API::Image.build("/path/to/file.tar")
74
+
75
+ # Build image from a remote tar file
76
+ Docker::API::Image.build(nil, remote: "https://url.to/file.tar")
77
+
78
+ # Build image from a remote Dockerfile
79
+ Docker::API::Image.build(nil, remote: "https://url.to/Dockerfile")
80
+
81
+ # Delete builder cache
82
+ Docker::API::Image.delete_cache
83
+
84
+ # Export repo
85
+ Docker::API::Image.export("repo:tag", "~/exported_image.tar")
86
+
87
+ # Import repo
88
+ Docker::API::Image.import("/path/to/file.tar")
89
+ ```
90
+
91
+ ### Containers
92
+
23
93
  Let's test a Nginx container
24
94
 
25
95
  ```ruby
@@ -84,7 +154,7 @@ Docker::API::Container.prune
84
154
 
85
155
  ### Requests
86
156
 
87
- Requests should work as described in Docker API documentation.
157
+ Requests should work as described in [Docker API documentation](https://docs.docker.com/engine/api/v1.40). Check it out to customize your requests.
88
158
 
89
159
  ### Response
90
160
 
@@ -105,8 +175,8 @@ WIP: Work In Progress
105
175
 
106
176
  | Class | Tests | Implementation | Refactoring |
107
177
  |---|---|---|---|
108
- | Container | WIP | WIP | NS |
109
- | Image | NS | NS | NS |
178
+ | Container | Ok | Ok | NS |
179
+ | Image | Ok | Ok | NS |
110
180
  | Volume | NS | NS | NS |
111
181
  | Network | NS | NS | NS |
112
182
  | System | NS | NS | NS |
@@ -14,16 +14,16 @@ Gem::Specification.new do |spec|
14
14
 
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
16
  spec.metadata["source_code_uri"] = "https://github.com/nu12/dockerapi.git"
17
- #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
17
+ spec.metadata["changelog_uri"] = "https://github.com/nu12/dockerapi/blob/master/CHANGELOG.md"
18
18
 
19
19
  # Specify which files should be added to the gem when it is released.
20
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
21
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|resources)/}) }
23
23
  end
24
24
  spec.bindir = "exe"
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency "excon"
28
+ spec.add_dependency("excon", "~> 0.74.0")
29
29
  end
@@ -0,0 +1,36 @@
1
+ module Docker
2
+ module API
3
+ class Base
4
+
5
+ private
6
+
7
+ def self.base_path
8
+ "/"
9
+ end
10
+
11
+ def self.connection
12
+ Docker::API::Connection.instance
13
+ end
14
+
15
+ def self.validate error, permitted_keys, params
16
+ not_permitted = params.keys.map(&:to_s) - permitted_keys.map(&:to_s)
17
+ raise error if not_permitted.size > 0
18
+ end
19
+
20
+ ## Converts Ruby Hash into query parameters
21
+ ## In general, the format is key=value
22
+ ## If value is another Hash, it should keep a json syntax {key:value}
23
+ def self.hash_to_params h
24
+ p = []
25
+ h.each { |k,v| p.push( v.is_a?(Hash) ? "#{k}=#{v.to_json}" : "#{k}=#{v}") }
26
+ p.join("&").gsub(" ","")
27
+ end
28
+
29
+ def self.build_path path, params = {}
30
+ p = path.is_a?(Array) ? ([base_path] << path).join("/") : path
31
+ params.size > 0 ? [p, hash_to_params(params)].join("?") : p
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -6,30 +6,16 @@ module Docker
6
6
  class Connection
7
7
  include Singleton
8
8
 
9
- attr_reader(:connection)
10
-
11
- def get path
12
- r = @connection.get(path: path)
13
- #p r
14
- r
9
+ [:get, :post, :head, :delete, :put].each do | method |
10
+ define_method(method) { | path | self.request(method: method, path: path) }
15
11
  end
16
12
 
17
13
  def post(path, body = nil)
18
- if body
19
- r = @connection.post(path: path, headers: { "Content-Type" => "application/json" }, body: body.to_json)
20
- else
21
- r = @connection.post(path: path)
22
- end
23
- #p r
24
- r
25
- end
26
-
27
- def head(path)
28
- @connection.head(path: path)
14
+ self.request(method: :post, path: path, headers: { "Content-Type" => "application/json" }, body: body.to_json)
29
15
  end
30
16
 
31
- def delete path
32
- @connection.delete(path: path)
17
+ def request params
18
+ @connection.request(params)
33
19
  end
34
20
 
35
21
  private
@@ -3,121 +3,123 @@ module Docker
3
3
  CreateBody = [:Hostname,:Domainname,:User,:AttachStdin,:AttachStdout,:AttachStderr,:ExposedPorts,:Tty,:OpenStdin,:StdinOnce,:Env,:Cmd,:HealthCheck,:ArgsEscaped,:Image,:Volumes,:WorkingDir,:Entrypoint,:NetworkDisabled,:MacAddress,:OnBuild,:Labels,:StopSignal,:StopTimeout,:Shell,:HostConfig,:NetworkingConfig]
4
4
  UpdateBody = [:CpuShares, :Memory, :CgroupParent, :BlkioWeight, :BlkioWeightDevice, :BlkioWeightReadBps, :BlkioWeightWriteBps, :BlkioWeightReadOps, :BlkioWeightWriteOps, :CpuPeriod, :CpuQuota, :CpuRealtimePeriod, :CpuRealtimeRuntime, :CpusetCpus, :CpusetMems, :Devices, :DeviceCgroupRules, :DeviceRequest, :Kernel, :Memory, :KernelMemoryTCP, :MemoryReservation, :MemorySwap, :MemorySwappiness, :NanoCPUs, :OomKillDisable, :Init, :PidsLimit, :ULimits, :CpuCount, :CpuPercent, :IOMaximumIOps, :IOMaximumBandwidth, :RestartPolicy]
5
5
 
6
- class Container
6
+ class Container < Docker::API::Base
7
7
 
8
- @@base_path = "/containers"
8
+ def self.base_path
9
+ "/containers"
10
+ end
9
11
 
10
12
  def self.list params = {}
11
- self.validate Docker::API::InvalidParameter, [:all, :limit, :size, :filters], params
12
- Docker::API::Connection.instance.get(self.build_path(["json"], params))
13
+ validate Docker::API::InvalidParameter, [:all, :limit, :size, :filters], params
14
+ connection.get(build_path(["json"], params))
13
15
  end
14
16
 
15
17
  def self.inspect name, params = {}
16
- self.validate Docker::API::InvalidParameter, [:size], params
17
- Docker::API::Connection.instance.get(self.build_path([name, "json"], params))
18
+ validate Docker::API::InvalidParameter, [:size], params
19
+ connection.get(build_path([name, "json"], params))
18
20
  end
19
21
 
20
22
  def self.top name, params = {}
21
- self.validate Docker::API::InvalidParameter, [:ps_args], params
22
- Docker::API::Connection.instance.get(self.build_path([name, "top"], params))
23
+ validate Docker::API::InvalidParameter, [:ps_args], params
24
+ connection.get(build_path([name, "top"], params))
23
25
  end
24
26
 
25
27
  def self.changes name
26
- Docker::API::Connection.instance.get(self.build_path([name, "changes"]))
28
+ connection.get(build_path([name, "changes"]))
27
29
  end
28
30
 
29
31
  def self.start name, params = {}
30
- self.validate Docker::API::InvalidParameter, [:detachKeys], params
31
- Docker::API::Connection.instance.post(self.build_path([name, "start"], params))
32
+ validate Docker::API::InvalidParameter, [:detachKeys], params
33
+ connection.post(build_path([name, "start"], params))
32
34
  end
33
35
 
34
36
  def self.stop name, params = {}
35
- self.validate Docker::API::InvalidParameter, [:t], params
36
- Docker::API::Connection.instance.post(self.build_path([name, "stop"], params))
37
+ validate Docker::API::InvalidParameter, [:t], params
38
+ connection.post(build_path([name, "stop"], params))
37
39
  end
38
40
 
39
41
  def self.restart name, params = {}
40
- self.validate Docker::API::InvalidParameter, [:t], params
41
- Docker::API::Connection.instance.post(self.build_path([name, "restart"], params))
42
+ validate Docker::API::InvalidParameter, [:t], params
43
+ connection.post(build_path([name, "restart"], params))
42
44
  end
43
45
 
44
46
  def self.kill name, params = {}
45
- self.validate Docker::API::InvalidParameter, [:signal], params
46
- Docker::API::Connection.instance.post(self.build_path([name, "kill"], params))
47
+ validate Docker::API::InvalidParameter, [:signal], params
48
+ connection.post(build_path([name, "kill"], params))
47
49
  end
48
50
 
49
51
  def self.wait name, params = {}
50
- self.validate Docker::API::InvalidParameter, [:condition], params
51
- Docker::API::Connection.instance.post(self.build_path([name, "wait"], params))
52
+ validate Docker::API::InvalidParameter, [:condition], params
53
+ connection.post(build_path([name, "wait"], params))
52
54
  end
53
55
 
54
56
  def self.update name, body = {}
55
- self.validate Docker::API::InvalidRequestBody, Docker::API::UpdateBody, body
56
- Docker::API::Connection.instance.post(self.build_path([name, "update"]), body)
57
+ validate Docker::API::InvalidRequestBody, Docker::API::UpdateBody, body
58
+ connection.post(build_path([name, "update"]), body)
57
59
  end
58
60
 
59
61
  def self.rename name, params = {}
60
- self.validate Docker::API::InvalidParameter, [:name], params
61
- Docker::API::Connection.instance.post(self.build_path([name, "rename"], params))
62
+ validate Docker::API::InvalidParameter, [:name], params
63
+ connection.post(build_path([name, "rename"], params))
62
64
  end
63
65
 
64
66
  def self.resize name, params = {}
65
- self.validate Docker::API::InvalidParameter, [:w, :h], params
66
- Docker::API::Connection.instance.post(self.build_path([name, "resize"], params))
67
+ validate Docker::API::InvalidParameter, [:w, :h], params
68
+ connection.post(build_path([name, "resize"], params))
67
69
  end
68
70
 
69
71
  def self.prune params = {}
70
- self.validate Docker::API::InvalidParameter, [:filters], params
71
- Docker::API::Connection.instance.post(self.build_path(["prune"], params))
72
+ validate Docker::API::InvalidParameter, [:filters], params
73
+ connection.post(build_path(["prune"], params))
72
74
  end
73
75
 
74
76
  def self.pause name
75
- Docker::API::Connection.instance.post(self.build_path([name, "pause"]))
77
+ connection.post(build_path([name, "pause"]))
76
78
  end
77
79
 
78
80
  def self.unpause name
79
- Docker::API::Connection.instance.post(self.build_path([name, "unpause"]))
81
+ connection.post(build_path([name, "unpause"]))
80
82
  end
81
83
 
82
84
  def self.remove name, params = {}
83
- self.validate Docker::API::InvalidParameter, [:v, :force, :link], params
84
- Docker::API::Connection.instance.delete(self.build_path([name]))
85
+ validate Docker::API::InvalidParameter, [:v, :force, :link], params
86
+ connection.delete(build_path([name]))
85
87
  end
86
88
 
87
89
  def self.logs name, params = {}
88
- self.validate Docker::API::InvalidParameter, [:follow, :stdout, :stderr, :since, :until, :timestamps, :tail], params
90
+ validate Docker::API::InvalidParameter, [:follow, :stdout, :stderr, :since, :until, :timestamps, :tail], params
89
91
 
90
- path = self.build_path([name, "logs"], params)
92
+ path = build_path([name, "logs"], params)
91
93
 
92
94
  if params[:follow] == true || params[:follow] == 1
93
- Docker::API::Connection.instance.connection.get(path: path , response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect })
95
+ connection.request(method: :get, path: path , response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect })
94
96
  else
95
- Docker::API::Connection.instance.get(path)
97
+ connection.get(path)
96
98
  end
97
99
  end
98
100
 
99
101
  def self.attach name, params = {}
100
- self.validate Docker::API::InvalidParameter, [:detachKeys, :logs, :stream, :stdin, :stdout, :stderr], params
101
- Docker::API::Connection.instance.connection.request(method: :post, path: self.build_path([name, "attach"], params) , response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect })
102
+ validate Docker::API::InvalidParameter, [:detachKeys, :logs, :stream, :stdin, :stdout, :stderr], params
103
+ connection.request(method: :post, path: build_path([name, "attach"], params) , response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect })
102
104
  end
103
105
 
104
106
  def self.create params = {}, body = {}
105
- self.validate Docker::API::InvalidParameter, [:name], params
106
- self.validate Docker::API::InvalidRequestBody, Docker::API::CreateBody, body
107
- Docker::API::Connection.instance.post(self.build_path(["create"], params), body)
107
+ validate Docker::API::InvalidParameter, [:name], params
108
+ validate Docker::API::InvalidRequestBody, Docker::API::CreateBody, body
109
+ connection.post(build_path(["create"], params), body)
108
110
  end
109
111
 
110
112
  def self.stats name, params = {}
111
- self.validate Docker::API::InvalidParameter, [:stream], params
112
- path = self.build_path([name, "stats"], params)
113
+ validate Docker::API::InvalidParameter, [:stream], params
114
+ path = build_path([name, "stats"], params)
113
115
 
114
116
  if params[:stream] == true || params[:stream] == 1
115
117
  streamer = lambda do |chunk, remaining_bytes, total_bytes|
116
118
  puts chunk
117
119
  end
118
- Docker::API::Connection.instance.connection.get(path: path , response_block: streamer)
120
+ connection.request(method: :get, path: path , response_block: streamer)
119
121
  else
120
- Docker::API::Connection.instance.get(path)
122
+ connection.get(path)
121
123
  end
122
124
  end
123
125
 
@@ -128,56 +130,30 @@ module Docker
128
130
  streamer = lambda do |chunk, remaining_bytes, total_bytes|
129
131
  file.write(chunk)
130
132
  end
131
- response = Docker::API::Connection.instance.connection.get(path: self.build_path([name, "export"]) , response_block: streamer)
133
+ response = connection.request(method: :get, path: build_path([name, "export"]) , response_block: streamer)
132
134
  file.close
133
135
  end
134
136
  response
135
137
  end
136
138
 
137
139
  def self.archive name, file, params = {}
138
- self.validate Docker::API::InvalidParameter, [:path, :noOverwriteDirNonDir, :copyUIDGID], params
140
+ validate Docker::API::InvalidParameter, [:path, :noOverwriteDirNonDir, :copyUIDGID], params
139
141
 
140
142
  begin # File exists on disk, send it to container
141
143
  file = File.open( File.expand_path( file ) , "r")
142
- response = Docker::API::Connection.instance.connection.put(path: self.build_path([name, "archive"], params) , request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s} )
144
+ response = connection.request(method: :put, path: build_path([name, "archive"], params) , request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s} )
143
145
  file.close
144
146
  rescue Errno::ENOENT # File doesnt exist, get it from container
145
- response = Docker::API::Connection.instance.head(self.build_path([name, "archive"], params))
147
+ response = connection.head(build_path([name, "archive"], params))
146
148
  if response.status == 200 # file exists in container
147
149
  file = File.open( File.expand_path( file ) , "wb")
148
- response = Docker::API::Connection.instance.connection.get(path: self.build_path([name, "archive"], params) , response_block: lambda { |chunk, remaining_bytes, total_bytes| file.write(chunk) })
150
+ response = connection.request(method: :get, path: build_path([name, "archive"], params) , response_block: lambda { |chunk, remaining_bytes, total_bytes| file.write(chunk) })
149
151
  file.close
150
152
  end
151
153
  end
152
154
  response
153
155
  end
154
-
155
- private
156
-
157
- def self.validate error, permitted_keys, params
158
- not_permitted = params.keys - permitted_keys
159
- raise error if not_permitted.size > 0
160
- end
161
-
162
- ## Converts Ruby Hash into query parameters
163
- ## In general, the format is key=value
164
- ## If value is another Hash, it should keep a json syntax {key:value}
165
- def self.hash_to_params h
166
- p = []
167
- h.each do |k,v|
168
- if v.is_a?(Hash)
169
- p << "#{k}=#{v.to_json}"
170
- else
171
- p << "#{k}=#{v}"
172
- end
173
- end
174
- p.join("&").gsub(" ","")
175
- end
176
156
 
177
- def self.build_path path, params = {}
178
- p = ([@@base_path] << path).join("/")
179
- params.size > 0 ? [p, self.hash_to_params(params)].join("?") : p
180
- end
181
157
  end
182
158
  end
183
159
  end
@@ -1,23 +1,139 @@
1
+ require "base64"
2
+ require "json"
3
+ require 'fileutils'
1
4
  module Docker
2
5
  module API
3
- class Image
6
+ CommitBody = [:Hostname, :Domainname, :User, :AttachStdin, :AttachStdout, :AttachStderr, :ExposedPorts, :Tty, :OpenStdin, :StdinOnce, :Env, :Cmd, :HealthCheck, :ArgsEscaped, :Image, :Volumes, :WorkingDir, :Entrypoint, :NetworkDisabled, :MacAddress, :OnBuild, :Labels, :StopSignal, :StopTimeout, :Shell]
7
+ BuildParams = [:dockerfile, :t, :extrahosts, :remote, :q, :nocache, :cachefrom, :pull, :rm, :forcerm, :memory, :memswap, :cpushares, :cpusetcpus, :cpuperiod, :cpuquota, :buildargs, :shmsize, :squash, :labels, :networkmode, :platform, :target, :outputs]
8
+ class Image < Docker::API::Base
4
9
 
5
- @@base_path = "/images"
10
+ def self.base_path
11
+ "/images"
12
+ end
13
+
14
+ def self.inspect name
15
+ connection.get(build_path([name, "json"]))
16
+ end
17
+
18
+ def self.history name
19
+ connection.get(build_path([name, "history"]))
20
+ end
21
+
22
+ def self.list params = {}
23
+ validate Docker::API::InvalidParameter, [:all, :filters, :digests], params
24
+ connection.get(build_path(["json"], params))
25
+ end
26
+
27
+ def self.search params = {}
28
+ validate Docker::API::InvalidParameter, [:term, :limit, :filters], params
29
+ connection.get(build_path(["search"], params))
30
+ end
31
+
32
+ def self.tag name, params = {}
33
+ validate Docker::API::InvalidParameter, [:repo, :tag], params
34
+ connection.post(build_path([name, "tag"], params))
35
+ end
36
+
37
+ def self.prune params = {}
38
+ validate Docker::API::InvalidParameter, [:filters], params
39
+ connection.post(build_path(["prune"], params))
40
+ end
6
41
 
7
- def self.create query_params = {}
8
- Docker::API::Connection.instance.post(self.build_path(["create"], query_params))
42
+ def self.remove name, params = {}
43
+ validate Docker::API::InvalidParameter, [:force, :noprune], params
44
+ connection.delete(build_path([name], params))
9
45
  end
10
46
 
11
- def self.remove name, query_params = {}
12
- Docker::API::Connection.instance.delete(self.build_path([name], query_params))
47
+ def self.export name, path = "exported_image"
48
+ file = File.open("/tmp/exported-image", "wb")
49
+ streamer = lambda do |chunk, remaining_bytes, total_bytes|
50
+ file.write(chunk)
51
+ end
52
+ response = connection.request(method: :get, path: build_path([name, "get"]) , response_block: streamer)
53
+ file.close
54
+ response.status == 200 ? FileUtils.mv("/tmp/exported-image", File.expand_path(path)) : FileUtils.rm("/tmp/exported-image")
55
+ response
13
56
  end
14
57
 
15
- private
58
+ def self.import path, params = {}
59
+ validate Docker::API::InvalidParameter, [:quiet], params
60
+ file = File.open(File.expand_path(path), "r")
61
+ response = connection.request(method: :post, path: build_path(["load"], params) , headers: {"Content-Type" => "application/x-tar"}, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s} )
62
+ file.close
63
+ response
64
+ end
65
+
66
+ def self.push name, params = {}, authentication = {}
67
+ validate Docker::API::InvalidParameter, [:tag], params
68
+
69
+ if authentication.keys.size > 0
70
+ auth = Docker::API::System.auth(authentication)
71
+ return auth unless [200, 204].include? auth.status
72
+ connection.request(method: :post, path: build_path([name, "push"], params), headers: { "X-Registry-Auth" => Base64.encode64(authentication.to_json.to_s).chomp } )
73
+ else
74
+ connection.post(build_path([name, "push"], params))
75
+ end
76
+ end
16
77
 
17
- def self.build_path path, params = {}
18
- p = ([@@base_path] << path).join("/")
19
- params.size > 0 ? [p, params.map {|k,v| "#{k}=#{v}"}.join("&")].join("?") : p
78
+ def self.commit params = {}, body = {}
79
+ validate Docker::API::InvalidParameter, [:container, :repo, :tag, :comment, :author, :pause, :changes], params
80
+ validate Docker::API::InvalidRequestBody, Docker::API::CommitBody, body
81
+ container = Docker::API::Container.inspect(params[:container])
82
+ return container if [404, 301].include? container.status
83
+ body = JSON.parse(container.body)["Config"].merge(body)
84
+ connection.request(method: :post, path: build_path("/commit", params), headers: {"Content-Type": "application/json"}, body: body.to_json)
20
85
  end
86
+
87
+ def self.create params = {}, authentication = {}
88
+ validate Docker::API::InvalidParameter, [:fromImage, :fromSrc, :repo, :tag, :message, :platform], params
89
+
90
+ if authentication.keys.size > 0
91
+ auth = Docker::API::System.auth(authentication)
92
+ return auth unless [200, 204].include? auth.status
93
+ connection.request(method: :post, path: build_path(["create"], params), headers: { "X-Registry-Auth" => Base64.encode64(authentication.to_json.to_s).chomp } )
94
+ elsif params.has_key? :fromSrc
95
+ if params[:fromSrc].match(/^(http|https)/)
96
+ connection.request(method: :post, path: build_path(["create"], params))
97
+ else
98
+ file = File.open(File.expand_path(params[:fromSrc]), "r")
99
+ params[:fromSrc] = "-"
100
+ response = connection.request(method: :post, path: build_path(["create"], params) , headers: {"Content-Type" => "application/x-tar"}, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s} )
101
+ file.close
102
+ response
103
+ end
104
+ else
105
+ connection.post(build_path(["create"], params))
106
+ end
107
+ end
108
+
109
+ def self.build path, params = {}, authentication = {}
110
+ raise Docker::API::InvalidRequestBody unless path || params[:remote]
111
+ validate Docker::API::InvalidParameter, Docker::API::BuildParams, params
112
+
113
+ header = {"Content-type": "application/x-tar"}
114
+ if authentication.keys.size > 0
115
+ authentication.each_key do |server|
116
+ auth = Docker::API::System.auth({username: authentication[server][:username] ,password:authentication[server][:password], serveraddress: server})
117
+ return auth unless [200, 204].include? auth.status
118
+ end
119
+ header.merge!({"X-Registry-Config": Base64.urlsafe_encode64(authentication.to_json.to_s).chomp})
120
+ end
121
+
122
+ begin
123
+ file = File.open( File.expand_path( path ) , "r")
124
+ response = connection.request(method: :post, path: build_path("/build", params), headers: header, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s})
125
+ file.close
126
+ rescue
127
+ response = connection.request(method: :post, path: build_path("/build", params), headers: header)
128
+ end
129
+ response
130
+ end
131
+
132
+ def self.delete_cache params = {}
133
+ validate Docker::API::InvalidParameter, [:all, "keep-storage", :filters], params
134
+ connection.post(build_path("/build/prune", params))
135
+ end
136
+
21
137
  end
22
138
 
23
139
  end
@@ -0,0 +1,12 @@
1
+ require "json"
2
+ module Docker
3
+ module API
4
+ class System < Docker::API::Base
5
+
6
+ def self.auth body = {}
7
+ validate Docker::API::InvalidRequestBody, [:username, :password, :email, :serveraddress, :identitytoken], body
8
+ connection.request(method: :post, path: "/auth", headers: { "Content-Type" => "application/json" }, body: body.to_json)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,6 +1,6 @@
1
1
  module Docker
2
2
  module API
3
- GEM_VERSION = "0.1.0"
3
+ GEM_VERSION = "0.2.0"
4
4
 
5
5
  API_VERSION = "1.40"
6
6
 
@@ -2,8 +2,10 @@ require "docker/api/version"
2
2
 
3
3
  require "docker/api/error"
4
4
  require "docker/api/connection"
5
+ require "docker/api/base"
5
6
  require "docker/api/container"
6
7
  require "docker/api/image"
8
+ require "docker/api/system"
7
9
 
8
10
  module Docker
9
11
  module API
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockerapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alysson A. Costa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-22 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: excon
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.74.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.74.0
27
27
  description: Interact directly with Docker API from Ruby code.
28
28
  email:
29
29
  - alysson.avila.costa@gmail.com
@@ -34,6 +34,7 @@ files:
34
34
  - ".gitignore"
35
35
  - ".rspec"
36
36
  - ".travis.yml"
37
+ - CHANGELOG.md
37
38
  - Gemfile
38
39
  - Gemfile.lock
39
40
  - LICENSE.txt
@@ -42,10 +43,12 @@ files:
42
43
  - bin/console
43
44
  - bin/setup
44
45
  - dockerapi.gemspec
46
+ - lib/docker/api/base.rb
45
47
  - lib/docker/api/connection.rb
46
48
  - lib/docker/api/container.rb
47
49
  - lib/docker/api/error.rb
48
50
  - lib/docker/api/image.rb
51
+ - lib/docker/api/system.rb
49
52
  - lib/docker/api/version.rb
50
53
  - lib/dockerapi.rb
51
54
  homepage: https://github.com/nu12/dockerapi
@@ -54,6 +57,7 @@ licenses:
54
57
  metadata:
55
58
  homepage_uri: https://github.com/nu12/dockerapi
56
59
  source_code_uri: https://github.com/nu12/dockerapi.git
60
+ changelog_uri: https://github.com/nu12/dockerapi/blob/master/CHANGELOG.md
57
61
  post_install_message:
58
62
  rdoc_options: []
59
63
  require_paths: