dockerapi 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: