dockerapi 0.2.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +54 -0
- data/Gemfile.lock +1 -1
- data/README.md +206 -55
- data/bin/setup +17 -3
- data/lib/docker/api/base.rb +10 -10
- data/lib/docker/api/connection.rb +5 -13
- data/lib/docker/api/container.rb +50 -50
- data/lib/docker/api/error.rb +13 -2
- data/lib/docker/api/exec.rb +39 -0
- data/lib/docker/api/image.rb +38 -40
- data/lib/docker/api/network.rb +45 -0
- data/lib/docker/api/response.rb +25 -0
- data/lib/docker/api/system.rb +25 -3
- data/lib/docker/api/version.rb +1 -1
- data/lib/docker/api/volume.rb +34 -0
- data/lib/dockerapi.rb +7 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 756ada080034328ec7c5e7950d5565e6e7d3612bc92af58d9c8f89558a75f5c5
|
|
4
|
+
data.tar.gz: cba4ac000ef8e9d4374bc36be4e87dd3c2227b2fa59cc062f24ad7a06de11c52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c6c059fa47afc4749dac18c62d61a984c2874b41046c2926d7eb884a7761ea088fef4209deaf71fe5864e5351e8e96a975f29520760ae6559209d323dd4f4b6
|
|
7
|
+
data.tar.gz: 25bad2ed4c92a2b5551d78e3a12833037623e7f26045a829b587d4136c383d7431ae7a3d17bf6b9ca139c4fcc060cbf07f15a61854a4a43f601455613174f943
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,57 @@
|
|
|
1
|
+
# 0.7.0
|
|
2
|
+
|
|
3
|
+
Major changes: Docker::API::Connection is now a regular class intead of a Singleton, allowing multiple connections to be stablished within the same program (replacing the connect_to implementation). To leverage this feature, API-related classes must be initialized and may or may not receive a Docker::API::Connection as parameter, or it'll connect to /var/run/docker.sock by default. For this reason, class methods were replaced with instance methods. Documentation will reflect this changes of implementation.
|
|
4
|
+
|
|
5
|
+
Bug fix: Image push returns a 20X status even when the push is unsucessful. To prevent false positives, it now requires the authentication parameters to be provided, generating a 403 status for invalid credentials or an error if they are absent.
|
|
6
|
+
|
|
7
|
+
# 0.6.0
|
|
8
|
+
|
|
9
|
+
Add connection parameters specifications with connect_to in Docker::API::Connection.
|
|
10
|
+
|
|
11
|
+
Add Docker::API::Exec methods:
|
|
12
|
+
* create
|
|
13
|
+
* start
|
|
14
|
+
* resize
|
|
15
|
+
* inspect
|
|
16
|
+
|
|
17
|
+
# 0.5.0
|
|
18
|
+
|
|
19
|
+
Add Docker::API::System methods:
|
|
20
|
+
* auth
|
|
21
|
+
* ping
|
|
22
|
+
* info
|
|
23
|
+
* version
|
|
24
|
+
* events
|
|
25
|
+
* df
|
|
26
|
+
|
|
27
|
+
Add new response class Docker::API::Response with the following methods:
|
|
28
|
+
* json
|
|
29
|
+
* path
|
|
30
|
+
* success?
|
|
31
|
+
|
|
32
|
+
Error classes output better error messages.
|
|
33
|
+
|
|
34
|
+
# 0.4.0
|
|
35
|
+
|
|
36
|
+
Add Docker::API::Network methods:
|
|
37
|
+
* list
|
|
38
|
+
* inspect
|
|
39
|
+
* create
|
|
40
|
+
* remove
|
|
41
|
+
* prune
|
|
42
|
+
* connect
|
|
43
|
+
* disconnect
|
|
44
|
+
|
|
45
|
+
# 0.3.0
|
|
46
|
+
|
|
47
|
+
Add Docker::API::Volume methods:
|
|
48
|
+
* list
|
|
49
|
+
* inspect
|
|
50
|
+
* create
|
|
51
|
+
* remove
|
|
52
|
+
* prune
|
|
53
|
+
|
|
54
|
+
|
|
1
55
|
# 0.2.0
|
|
2
56
|
|
|
3
57
|
Add Docker::API::Image methods:
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -20,72 +20,76 @@ Or install it yourself as:
|
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
23
|
+
New implementation details as of v0.7.0.
|
|
24
|
+
|
|
23
25
|
### Images
|
|
24
26
|
|
|
25
27
|
```ruby
|
|
28
|
+
# Connect to local image endpoints
|
|
29
|
+
image = Docker::API::Image.new
|
|
30
|
+
|
|
26
31
|
# Pull from a public repository
|
|
27
|
-
|
|
32
|
+
image.create( fromImage: "nginx:latest" )
|
|
28
33
|
|
|
29
34
|
# Pull from a private repository
|
|
30
|
-
|
|
35
|
+
image.create( {fromImage: "private/repo:tag"}, {username: "janedoe", password: "password"} )
|
|
31
36
|
|
|
32
37
|
# Create image from local tar file
|
|
33
|
-
|
|
38
|
+
image.create( fromSrc: "/path/to/file.tar", repo: "repo:tag" )
|
|
34
39
|
|
|
35
40
|
# Create image from remote tar file
|
|
36
|
-
|
|
41
|
+
image.create( fromSrc: "https://url.to/file.tar", repo: "repo:tag" )
|
|
37
42
|
|
|
38
43
|
# List images
|
|
39
|
-
|
|
40
|
-
Docker::API::Image.list( all:true )
|
|
44
|
+
image.list
|
|
41
45
|
|
|
42
46
|
# Inspect image
|
|
43
|
-
|
|
47
|
+
image.inspect("image")
|
|
44
48
|
|
|
45
49
|
# History
|
|
46
|
-
|
|
50
|
+
image.history("image")
|
|
47
51
|
|
|
48
52
|
# Search image
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
image.search(term: "busybox", limit: 2)
|
|
54
|
+
image.search(term: "busybox", filters: {"is-automated": {"true": true}})
|
|
55
|
+
image.search(term: "busybox", filters: {"is-official": {"true": true}})
|
|
52
56
|
|
|
53
57
|
# Tag image
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
image.tag("current:tag", repo: "new:tag") # or
|
|
59
|
+
image.tag("current:tag", repo: "new", tag: "tag")
|
|
56
60
|
|
|
57
61
|
# Push image
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
image.push("repo:tag") # to dockerhub
|
|
63
|
+
image.push("localhost:5000/repo:tag") # to local registry
|
|
64
|
+
image.push("private/repo", {tag: "tag"}, {username: "janedoe", password: "password"} # to private repository
|
|
61
65
|
|
|
62
|
-
# Remove
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
# Remove image
|
|
67
|
+
image.remove("image")
|
|
68
|
+
image.remove("image", force: true)
|
|
65
69
|
|
|
66
70
|
# Remove unsued images (prune)
|
|
67
|
-
|
|
71
|
+
image.prune(filters: {dangling: {"false": true}})
|
|
68
72
|
|
|
69
73
|
# Create image from a container (commit)
|
|
70
|
-
|
|
74
|
+
image.commit(container: container, repo: "my/image", tag: "latest", comment: "Comment from commit", author: "dockerapi", pause: false )
|
|
71
75
|
|
|
72
76
|
# Build image from a local tar file
|
|
73
|
-
|
|
77
|
+
image.build("/path/to/file.tar")
|
|
74
78
|
|
|
75
79
|
# Build image from a remote tar file
|
|
76
|
-
|
|
80
|
+
image.build(nil, remote: "https://url.to/file.tar")
|
|
77
81
|
|
|
78
82
|
# Build image from a remote Dockerfile
|
|
79
|
-
|
|
83
|
+
image.build(nil, remote: "https://url.to/Dockerfile")
|
|
80
84
|
|
|
81
85
|
# Delete builder cache
|
|
82
|
-
|
|
86
|
+
image.delete_cache
|
|
83
87
|
|
|
84
88
|
# Export repo
|
|
85
|
-
|
|
89
|
+
image.export("repo:tag", "~/exported_image.tar")
|
|
86
90
|
|
|
87
91
|
# Import repo
|
|
88
|
-
|
|
92
|
+
image.import("/path/to/file.tar")
|
|
89
93
|
```
|
|
90
94
|
|
|
91
95
|
### Containers
|
|
@@ -94,62 +98,177 @@ Let's test a Nginx container
|
|
|
94
98
|
|
|
95
99
|
```ruby
|
|
96
100
|
# Pull nginx image
|
|
97
|
-
Docker::API::Image.create( fromImage: "nginx:latest" )
|
|
101
|
+
Docker::API::Image.new.create( fromImage: "nginx:latest" )
|
|
102
|
+
|
|
103
|
+
# Connect to local container endpoints
|
|
104
|
+
container = Docker::API::Container.new
|
|
98
105
|
|
|
99
106
|
# Create container
|
|
100
|
-
|
|
107
|
+
container.create( {name: "nginx"}, {Image: "nginx:latest", HostConfig: {PortBindings: {"80/tcp": [ {HostIp: "0.0.0.0", HostPort: "80"} ]}}})
|
|
101
108
|
|
|
102
109
|
# Start container
|
|
103
|
-
|
|
110
|
+
container.start("nginx")
|
|
104
111
|
|
|
105
112
|
# Open localhost or machine IP to check the container running
|
|
106
113
|
|
|
107
114
|
# Restart container
|
|
108
|
-
|
|
115
|
+
container.restart("nginx")
|
|
109
116
|
|
|
110
117
|
# Pause/unpause container
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
container.pause("nginx")
|
|
119
|
+
container.unpause("nginx")
|
|
113
120
|
|
|
114
121
|
# List containers
|
|
115
|
-
|
|
122
|
+
container.list
|
|
116
123
|
|
|
117
124
|
# List containers (including stopped ones)
|
|
118
|
-
|
|
125
|
+
container.list(all: true)
|
|
119
126
|
|
|
120
127
|
# Inspect container
|
|
121
|
-
|
|
128
|
+
container.inspect("nginx")
|
|
122
129
|
|
|
123
130
|
# View container's processes
|
|
124
|
-
|
|
131
|
+
container.top("nginx")
|
|
125
132
|
|
|
126
|
-
#
|
|
127
|
-
|
|
133
|
+
# Using json output
|
|
134
|
+
container.top("nginx").json
|
|
128
135
|
|
|
129
136
|
# View filesystem changes
|
|
130
|
-
|
|
137
|
+
container.changes("nginx")
|
|
131
138
|
|
|
132
139
|
# View filesystem logs
|
|
133
|
-
|
|
134
|
-
|
|
140
|
+
container.logs("nginx", stdout: true)
|
|
141
|
+
container.logs("nginx", stdout: true, follow: true)
|
|
135
142
|
|
|
136
143
|
# View filesystem stats
|
|
137
|
-
|
|
144
|
+
container.stats("nginx", stream: true)
|
|
138
145
|
|
|
139
146
|
# Export container
|
|
140
|
-
|
|
147
|
+
container.export("nginx", "~/exported_container")
|
|
141
148
|
|
|
142
149
|
# Get files from container
|
|
143
|
-
|
|
150
|
+
container.archive("nginx", "~/html.tar", path: "/usr/share/nginx/html/")
|
|
144
151
|
|
|
145
152
|
# Stop container
|
|
146
|
-
|
|
153
|
+
container.stop("nginx")
|
|
147
154
|
|
|
148
155
|
# Remove container
|
|
149
|
-
|
|
156
|
+
container.remove("nginx")
|
|
150
157
|
|
|
151
158
|
# Remove stopped containers (prune)
|
|
152
|
-
|
|
159
|
+
container.prune
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Volumes
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
# Connect to local volume endpoints
|
|
166
|
+
volume = Docker::API::Volume.new
|
|
167
|
+
|
|
168
|
+
# Create volume
|
|
169
|
+
volume.create( Name:"my-volume" )
|
|
170
|
+
|
|
171
|
+
# List volumes
|
|
172
|
+
volume.list
|
|
173
|
+
|
|
174
|
+
# Inspect volume
|
|
175
|
+
volume.inspect("my-volume")
|
|
176
|
+
|
|
177
|
+
# Remove volume
|
|
178
|
+
volume.remove("my-volume")
|
|
179
|
+
|
|
180
|
+
# Remove unused volumes (prune)
|
|
181
|
+
volume.prune
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Network
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
# Connect to local network endpoints
|
|
188
|
+
network = Docker::API::Network.new
|
|
189
|
+
|
|
190
|
+
# List networks
|
|
191
|
+
network.list
|
|
192
|
+
|
|
193
|
+
# Inspect network
|
|
194
|
+
network.inspect("bridge")
|
|
195
|
+
|
|
196
|
+
# Create network
|
|
197
|
+
network.create( Name:"my-network" )
|
|
198
|
+
|
|
199
|
+
# Remove network
|
|
200
|
+
network.remove("my-network")
|
|
201
|
+
|
|
202
|
+
# Remove unused network (prune)
|
|
203
|
+
network.prune
|
|
204
|
+
|
|
205
|
+
# Connect container to a network
|
|
206
|
+
network.connect( "my-network", Container: "my-container" )
|
|
207
|
+
|
|
208
|
+
# Disconnect container to a network
|
|
209
|
+
network.disconnect( "my-network", Container: "my-container" )
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### System
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
# Connect to local system endpoints
|
|
216
|
+
sys = Docker::API::System.new
|
|
217
|
+
|
|
218
|
+
# Ping docker api
|
|
219
|
+
sys.ping
|
|
220
|
+
|
|
221
|
+
# Docker components versions
|
|
222
|
+
sys.version
|
|
223
|
+
|
|
224
|
+
# System info
|
|
225
|
+
sys.info
|
|
226
|
+
|
|
227
|
+
# System events (stream)
|
|
228
|
+
sys.events(until: Time.now.to_i)
|
|
229
|
+
|
|
230
|
+
# Data usage information
|
|
231
|
+
sys.df
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Exec
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
# Connect to local exec endpoints
|
|
238
|
+
exe = Docker::API::Exec.new
|
|
239
|
+
|
|
240
|
+
# Create exec instance, get generated exec ID
|
|
241
|
+
response = exe.create(container, AttachStdout:true, Cmd: ["ls", "-l"])
|
|
242
|
+
id = response.json["Id"]
|
|
243
|
+
|
|
244
|
+
# Execute the command, stream from Stdout is stored in response data
|
|
245
|
+
response = exe.start(id)
|
|
246
|
+
print response.data[:stream]
|
|
247
|
+
|
|
248
|
+
# Inspect exec instance
|
|
249
|
+
exe.inspect(id)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Connection
|
|
253
|
+
|
|
254
|
+
By default Docker::API::Connection will connect to local Docker socket at `/var/run/docker.sock`. See examples below to use a different path or connect to a remote address.
|
|
255
|
+
|
|
256
|
+
```ruby
|
|
257
|
+
# Setting different connections
|
|
258
|
+
local = Docker::API::Connection.new('unix:///', socket: "/path/to/docker.sock")
|
|
259
|
+
remote = Docker::API::Connection.new("http://127.0.0.1:2375") # change the IP address accordingly
|
|
260
|
+
|
|
261
|
+
# Using default /var/run/docker.sock
|
|
262
|
+
image_default = Docker::API::Image.new
|
|
263
|
+
image_default.list
|
|
264
|
+
|
|
265
|
+
# Using custom socket path
|
|
266
|
+
image_custom = Docker::API::Image.new(local)
|
|
267
|
+
image_custom.list
|
|
268
|
+
|
|
269
|
+
# Using remote address
|
|
270
|
+
image_remote = Docker::API::Image.new(remote)
|
|
271
|
+
image_remote.list
|
|
153
272
|
```
|
|
154
273
|
|
|
155
274
|
### Requests
|
|
@@ -158,7 +277,39 @@ Requests should work as described in [Docker API documentation](https://docs.doc
|
|
|
158
277
|
|
|
159
278
|
### Response
|
|
160
279
|
|
|
161
|
-
All requests return a Excon::Response
|
|
280
|
+
All requests return a response class that inherits from Excon::Response. Available attribute readers and methods include: `status`, `data`, `body`, `headers`, `json`, `path`, `success?`.
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
response = Docker::API::Image.new.create(fromImage: "busybox:latest")
|
|
284
|
+
|
|
285
|
+
response
|
|
286
|
+
=> #<Docker::API::Response:0x000055bb390b35c0 ... >
|
|
287
|
+
|
|
288
|
+
response.status
|
|
289
|
+
=> 200
|
|
290
|
+
|
|
291
|
+
response.data
|
|
292
|
+
=> {:body=>"...", :cookies=>[], :host=>nil, :headers=>{ ... }, :path=>"/images/create?fromImage=busybox:latest", :port=>nil, :status=>200, :status_line=>"HTTP/1.1 200 OK\r\n", :reason_phrase=>"OK"}
|
|
293
|
+
|
|
294
|
+
response.headers
|
|
295
|
+
=> {"Api-Version"=>"1.40", "Content-Type"=>"application/json", "Docker-Experimental"=>"false", "Ostype"=>"linux", "Server"=>"Docker/19.03.11 (linux)", "Date"=>"Mon, 29 Jun 2020 16:10:06 GMT"}
|
|
296
|
+
|
|
297
|
+
response.body
|
|
298
|
+
=> "{\"status\":\"Pulling from library/busybox\" ... "
|
|
299
|
+
|
|
300
|
+
response.json
|
|
301
|
+
=> [{:status=>"Pulling from library/busybox", :id=>"latest"}, {:status=>"Pulling fs layer", :progressDetail=>{}, :id=>"76df9210b28c"}, ... , {:status=>"Status: Downloaded newer image for busybox:latest"}]
|
|
302
|
+
|
|
303
|
+
response.path
|
|
304
|
+
=> "/images/create?fromImage=busybox:latest"
|
|
305
|
+
|
|
306
|
+
response.success?
|
|
307
|
+
=> true
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Error handling
|
|
311
|
+
|
|
312
|
+
`Docker::API::InvalidParameter` and `Docker::API::InvalidRequestBody` may be raised when an invalid option is passed as argument (ie: an option not described in Docker API documentation for request query parameters nor request body (json) parameters). Even if no errors were raised, consider validating the status code and/or message of the response to check if the Docker daemon has fulfilled the operation properly.
|
|
162
313
|
|
|
163
314
|
## Development
|
|
164
315
|
|
|
@@ -177,10 +328,10 @@ WIP: Work In Progress
|
|
|
177
328
|
|---|---|---|---|
|
|
178
329
|
| Container | Ok | Ok | NS |
|
|
179
330
|
| Image | Ok | Ok | NS |
|
|
180
|
-
| Volume |
|
|
181
|
-
| Network |
|
|
182
|
-
| System |
|
|
183
|
-
| Exec |
|
|
331
|
+
| Volume | Ok | Ok | NS |
|
|
332
|
+
| Network | Ok | Ok | NS |
|
|
333
|
+
| System | Ok | Ok | NS |
|
|
334
|
+
| Exec | Ok | Ok | NS |
|
|
184
335
|
| Swarm | NS | NS | NS |
|
|
185
336
|
| Node | NS | NS | NS |
|
|
186
337
|
| Service | NS | NS | NS |
|
|
@@ -188,8 +339,8 @@ WIP: Work In Progress
|
|
|
188
339
|
| Secret | NS | NS | NS |
|
|
189
340
|
|
|
190
341
|
Misc:
|
|
191
|
-
* Improve response object
|
|
192
|
-
* Improve error objects
|
|
342
|
+
* ~~Improve response object~~
|
|
343
|
+
* ~~Improve error objects~~
|
|
193
344
|
|
|
194
345
|
## Contributing
|
|
195
346
|
|
data/bin/setup
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
IFS=$'\n\t'
|
|
4
|
-
set -vx
|
|
5
|
-
|
|
6
|
-
bundle install
|
|
4
|
+
#set -vx
|
|
7
5
|
|
|
8
6
|
# Do any other automated setup that you need to do here
|
|
7
|
+
if [ $USER == 'root' ]
|
|
8
|
+
then
|
|
9
|
+
echo "Enabling TCP port 2375 for external connection to Docker"
|
|
10
|
+
echo '{"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]}' > /etc/docker/daemon.json
|
|
11
|
+
mkdir -p /etc/systemd/system/docker.service.d
|
|
12
|
+
echo '[Service]' > /etc/systemd/system/docker.service.d/override.conf
|
|
13
|
+
echo 'ExecStart=' >> /etc/systemd/system/docker.service.d/override.conf
|
|
14
|
+
echo 'ExecStart=/usr/bin/dockerd' >> /etc/systemd/system/docker.service.d/override.conf
|
|
15
|
+
systemctl daemon-reload
|
|
16
|
+
systemctl restart docker.service
|
|
17
|
+
echo "Done!"
|
|
18
|
+
else
|
|
19
|
+
echo "Running bundle install"
|
|
20
|
+
bundle install
|
|
21
|
+
echo "Run this script as root for further configurations"
|
|
22
|
+
fi
|
data/lib/docker/api/base.rb
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
module Docker
|
|
2
2
|
module API
|
|
3
3
|
class Base
|
|
4
|
+
|
|
5
|
+
def initialize connection = nil
|
|
6
|
+
@connection = connection || Docker::API::Connection.new
|
|
7
|
+
end
|
|
4
8
|
|
|
5
9
|
private
|
|
6
10
|
|
|
7
|
-
def
|
|
11
|
+
def base_path
|
|
8
12
|
"/"
|
|
9
13
|
end
|
|
10
14
|
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
15
|
+
def validate error, permitted, params
|
|
16
|
+
unpermitted = params.keys.map(&:to_s) - permitted.map(&:to_s)
|
|
17
|
+
raise error.new(permitted, unpermitted) if unpermitted.size > 0
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
## Converts Ruby Hash into query parameters
|
|
21
21
|
## In general, the format is key=value
|
|
22
22
|
## If value is another Hash, it should keep a json syntax {key:value}
|
|
23
|
-
def
|
|
23
|
+
def hash_to_params h
|
|
24
24
|
p = []
|
|
25
25
|
h.each { |k,v| p.push( v.is_a?(Hash) ? "#{k}=#{v.to_json}" : "#{k}=#{v}") }
|
|
26
26
|
p.join("&").gsub(" ","")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def build_path path, params = {}
|
|
30
30
|
p = path.is_a?(Array) ? ([base_path] << path).join("/") : path
|
|
31
31
|
params.size > 0 ? [p, hash_to_params(params)].join("?") : p
|
|
32
32
|
end
|
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
require "excon"
|
|
2
|
-
require "singleton"
|
|
3
|
-
require "json"
|
|
4
1
|
module Docker
|
|
5
2
|
module API
|
|
6
3
|
class Connection
|
|
7
|
-
include Singleton
|
|
8
|
-
|
|
9
4
|
[:get, :post, :head, :delete, :put].each do | method |
|
|
10
5
|
define_method(method) { | path | self.request(method: method, path: path) }
|
|
11
6
|
end
|
|
12
7
|
|
|
13
|
-
def post(path, body = nil)
|
|
14
|
-
self.request(method: :post, path: path, headers: { "Content-Type" => "application/json" }, body: body.to_json)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
8
|
def request params
|
|
18
|
-
@connection.request(params)
|
|
9
|
+
Docker::API::Response.new(@connection.request(params).data)
|
|
19
10
|
end
|
|
20
11
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
def initialize url = nil, params = nil
|
|
13
|
+
url ||= 'unix:///'
|
|
14
|
+
params ||= url == 'unix:///' ? {socket: '/var/run/docker.sock'} : {}
|
|
15
|
+
@connection = Excon.new(url, params)
|
|
24
16
|
end
|
|
25
17
|
|
|
26
18
|
end
|
data/lib/docker/api/container.rb
CHANGED
|
@@ -5,111 +5,111 @@ module Docker
|
|
|
5
5
|
|
|
6
6
|
class Container < Docker::API::Base
|
|
7
7
|
|
|
8
|
-
def
|
|
8
|
+
def base_path
|
|
9
9
|
"/containers"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def list params = {}
|
|
13
13
|
validate Docker::API::InvalidParameter, [:all, :limit, :size, :filters], params
|
|
14
|
-
connection.get(build_path(["json"], params))
|
|
14
|
+
@connection.get(build_path(["json"], params))
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def
|
|
17
|
+
def inspect name, params = {}
|
|
18
18
|
validate Docker::API::InvalidParameter, [:size], params
|
|
19
|
-
connection.get(build_path([name, "json"], params))
|
|
19
|
+
@connection.get(build_path([name, "json"], params))
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def
|
|
22
|
+
def top name, params = {}
|
|
23
23
|
validate Docker::API::InvalidParameter, [:ps_args], params
|
|
24
|
-
connection.get(build_path([name, "top"], params))
|
|
24
|
+
@connection.get(build_path([name, "top"], params))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
connection.get(build_path([name, "changes"]))
|
|
27
|
+
def changes name
|
|
28
|
+
@connection.get(build_path([name, "changes"]))
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def
|
|
31
|
+
def start name, params = {}
|
|
32
32
|
validate Docker::API::InvalidParameter, [:detachKeys], params
|
|
33
|
-
connection.post(build_path([name, "start"], params))
|
|
33
|
+
@connection.post(build_path([name, "start"], params))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def
|
|
36
|
+
def stop name, params = {}
|
|
37
37
|
validate Docker::API::InvalidParameter, [:t], params
|
|
38
|
-
connection.post(build_path([name, "stop"], params))
|
|
38
|
+
@connection.post(build_path([name, "stop"], params))
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def
|
|
41
|
+
def restart name, params = {}
|
|
42
42
|
validate Docker::API::InvalidParameter, [:t], params
|
|
43
|
-
connection.post(build_path([name, "restart"], params))
|
|
43
|
+
@connection.post(build_path([name, "restart"], params))
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def
|
|
46
|
+
def kill name, params = {}
|
|
47
47
|
validate Docker::API::InvalidParameter, [:signal], params
|
|
48
|
-
connection.post(build_path([name, "kill"], params))
|
|
48
|
+
@connection.post(build_path([name, "kill"], params))
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def wait name, params = {}
|
|
52
52
|
validate Docker::API::InvalidParameter, [:condition], params
|
|
53
|
-
connection.post(build_path([name, "wait"], params))
|
|
53
|
+
@connection.post(build_path([name, "wait"], params))
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def
|
|
56
|
+
def update name, body = {}
|
|
57
57
|
validate Docker::API::InvalidRequestBody, Docker::API::UpdateBody, body
|
|
58
|
-
connection.post
|
|
58
|
+
@connection.request(method: :post, path: build_path([name, "update"]), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def
|
|
61
|
+
def rename name, params = {}
|
|
62
62
|
validate Docker::API::InvalidParameter, [:name], params
|
|
63
|
-
connection.post(build_path([name, "rename"], params))
|
|
63
|
+
@connection.post(build_path([name, "rename"], params))
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def resize name, params = {}
|
|
67
67
|
validate Docker::API::InvalidParameter, [:w, :h], params
|
|
68
|
-
connection.post(build_path([name, "resize"], params))
|
|
68
|
+
@connection.post(build_path([name, "resize"], params))
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def prune params = {}
|
|
72
72
|
validate Docker::API::InvalidParameter, [:filters], params
|
|
73
|
-
connection.post(build_path(["prune"], params))
|
|
73
|
+
@connection.post(build_path(["prune"], params))
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
def
|
|
77
|
-
connection.post(build_path([name, "pause"]))
|
|
76
|
+
def pause name
|
|
77
|
+
@connection.post(build_path([name, "pause"]))
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
def
|
|
81
|
-
connection.post(build_path([name, "unpause"]))
|
|
80
|
+
def unpause name
|
|
81
|
+
@connection.post(build_path([name, "unpause"]))
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def
|
|
84
|
+
def remove name, params = {}
|
|
85
85
|
validate Docker::API::InvalidParameter, [:v, :force, :link], params
|
|
86
|
-
connection.delete(build_path([name]))
|
|
86
|
+
@connection.delete(build_path([name]))
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
def
|
|
89
|
+
def logs name, params = {}
|
|
90
90
|
validate Docker::API::InvalidParameter, [:follow, :stdout, :stderr, :since, :until, :timestamps, :tail], params
|
|
91
91
|
|
|
92
92
|
path = build_path([name, "logs"], params)
|
|
93
93
|
|
|
94
94
|
if params[:follow] == true || params[:follow] == 1
|
|
95
|
-
connection.request(method: :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 })
|
|
96
96
|
else
|
|
97
|
-
connection.get(path)
|
|
97
|
+
@connection.get(path)
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
def
|
|
101
|
+
def attach name, params = {}
|
|
102
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 })
|
|
103
|
+
@connection.request(method: :post, path: build_path([name, "attach"], params) , response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect })
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
def
|
|
106
|
+
def create params = {}, body = {}
|
|
107
107
|
validate Docker::API::InvalidParameter, [:name], params
|
|
108
108
|
validate Docker::API::InvalidRequestBody, Docker::API::CreateBody, body
|
|
109
|
-
connection.post
|
|
109
|
+
@connection.request(method: :post, path: build_path(["create"], params), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def
|
|
112
|
+
def stats name, params = {}
|
|
113
113
|
validate Docker::API::InvalidParameter, [:stream], params
|
|
114
114
|
path = build_path([name, "stats"], params)
|
|
115
115
|
|
|
@@ -117,37 +117,37 @@ module Docker
|
|
|
117
117
|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
|
118
118
|
puts chunk
|
|
119
119
|
end
|
|
120
|
-
connection.request(method: :get, path: path , response_block: streamer)
|
|
120
|
+
@connection.request(method: :get, path: path , response_block: streamer)
|
|
121
121
|
else
|
|
122
|
-
connection.get(path)
|
|
122
|
+
@connection.get(path)
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
-
def
|
|
127
|
-
response =
|
|
126
|
+
def export name, path = "exported_container"
|
|
127
|
+
response = self.inspect(name)
|
|
128
128
|
if response.status == 200
|
|
129
129
|
file = File.open(File.expand_path(path), "wb")
|
|
130
130
|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
|
131
131
|
file.write(chunk)
|
|
132
132
|
end
|
|
133
|
-
response = connection.request(method: :get, path: build_path([name, "export"]) , response_block: streamer)
|
|
133
|
+
response = @connection.request(method: :get, path: build_path([name, "export"]) , response_block: streamer)
|
|
134
134
|
file.close
|
|
135
135
|
end
|
|
136
136
|
response
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
def
|
|
139
|
+
def archive name, file, params = {}
|
|
140
140
|
validate Docker::API::InvalidParameter, [:path, :noOverwriteDirNonDir, :copyUIDGID], params
|
|
141
141
|
|
|
142
142
|
begin # File exists on disk, send it to container
|
|
143
143
|
file = File.open( File.expand_path( file ) , "r")
|
|
144
|
-
response = connection.request(method: :put, path: 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} )
|
|
145
145
|
file.close
|
|
146
146
|
rescue Errno::ENOENT # File doesnt exist, get it from container
|
|
147
|
-
response = connection.head(build_path([name, "archive"], params))
|
|
147
|
+
response = @connection.head(build_path([name, "archive"], params))
|
|
148
148
|
if response.status == 200 # file exists in container
|
|
149
149
|
file = File.open( File.expand_path( file ) , "wb")
|
|
150
|
-
response = connection.request(method: :get, path: 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) })
|
|
151
151
|
file.close
|
|
152
152
|
end
|
|
153
153
|
end
|
data/lib/docker/api/error.rb
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
module Docker
|
|
2
2
|
module API
|
|
3
|
-
class
|
|
4
|
-
|
|
3
|
+
class ValidationError < StandardError
|
|
4
|
+
def initialize permitted, unpermitted
|
|
5
|
+
super("Unpermitted options found: #{unpermitted.to_s}. Permitted are #{permitted.to_s}")
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
class Error < StandardError
|
|
9
|
+
def initialize msg = "Error without specific message"
|
|
10
|
+
super(msg)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class InvalidParameter < Docker::API::ValidationError; end
|
|
15
|
+
class InvalidRequestBody < Docker::API::ValidationError; end
|
|
5
16
|
end
|
|
6
17
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Docker
|
|
2
|
+
module API
|
|
3
|
+
class Exec < Docker::API::Base
|
|
4
|
+
|
|
5
|
+
def base_path
|
|
6
|
+
"/exec"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create name, body = {}
|
|
10
|
+
validate Docker::API::InvalidRequestBody, [:AttachStdin, :AttachStdout, :AttachStderr, :DetachKeys, :Tty, :Env, :Cmd, :Privileged, :User, :WorkingDir], body
|
|
11
|
+
@connection.request(method: :post, path: "/containers/#{name}/exec", headers: {"Content-Type": "application/json"}, body: body.to_json )
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def start name, body = {}
|
|
15
|
+
validate Docker::API::InvalidRequestBody, [:Detach, :Tty], body
|
|
16
|
+
|
|
17
|
+
stream = ""
|
|
18
|
+
response = @connection.request(method: :post,
|
|
19
|
+
path: "/exec/#{name}/start",
|
|
20
|
+
headers: {"Content-Type": "application/json"},
|
|
21
|
+
body: body.to_json,
|
|
22
|
+
response_block: lambda { |chunk, remaining_bytes, total_bytes| stream += chunk.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?') }
|
|
23
|
+
)
|
|
24
|
+
response.data.merge!({stream: stream})
|
|
25
|
+
response
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def resize name, params = {}
|
|
29
|
+
validate Docker::API::InvalidParameter, [:w, :h], params
|
|
30
|
+
@connection.post(build_path([name, "resize"], params))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def inspect name
|
|
34
|
+
@connection.get(build_path([name, "json"]))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/docker/api/image.rb
CHANGED
|
@@ -7,113 +7,111 @@ module Docker
|
|
|
7
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
8
|
class Image < Docker::API::Base
|
|
9
9
|
|
|
10
|
-
def
|
|
10
|
+
def base_path
|
|
11
11
|
"/images"
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
connection.get(build_path([name, "json"]))
|
|
14
|
+
def inspect name
|
|
15
|
+
@connection.get(build_path([name, "json"]))
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
connection.get(build_path([name, "history"]))
|
|
18
|
+
def history name
|
|
19
|
+
@connection.get(build_path([name, "history"]))
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def
|
|
22
|
+
def list params = {}
|
|
23
23
|
validate Docker::API::InvalidParameter, [:all, :filters, :digests], params
|
|
24
|
-
connection.get(build_path(["json"], params))
|
|
24
|
+
@connection.get(build_path(["json"], params))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def
|
|
27
|
+
def search params = {}
|
|
28
28
|
validate Docker::API::InvalidParameter, [:term, :limit, :filters], params
|
|
29
|
-
connection.get(build_path(["search"], params))
|
|
29
|
+
@connection.get(build_path(["search"], params))
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def
|
|
32
|
+
def tag name, params = {}
|
|
33
33
|
validate Docker::API::InvalidParameter, [:repo, :tag], params
|
|
34
|
-
connection.post(build_path([name, "tag"], params))
|
|
34
|
+
@connection.post(build_path([name, "tag"], params))
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def prune params = {}
|
|
38
38
|
validate Docker::API::InvalidParameter, [:filters], params
|
|
39
|
-
connection.post(build_path(["prune"], params))
|
|
39
|
+
@connection.post(build_path(["prune"], params))
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def
|
|
42
|
+
def remove name, params = {}
|
|
43
43
|
validate Docker::API::InvalidParameter, [:force, :noprune], params
|
|
44
|
-
connection.delete(build_path([name], params))
|
|
44
|
+
@connection.delete(build_path([name], params))
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def export name, path = "exported_image"
|
|
48
48
|
file = File.open("/tmp/exported-image", "wb")
|
|
49
49
|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
|
50
50
|
file.write(chunk)
|
|
51
51
|
end
|
|
52
|
-
response = connection.request(method: :get, path: build_path([name, "get"]) , response_block: streamer)
|
|
52
|
+
response = @connection.request(method: :get, path: build_path([name, "get"]) , response_block: streamer)
|
|
53
53
|
file.close
|
|
54
54
|
response.status == 200 ? FileUtils.mv("/tmp/exported-image", File.expand_path(path)) : FileUtils.rm("/tmp/exported-image")
|
|
55
55
|
response
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
def
|
|
58
|
+
def import path, params = {}
|
|
59
59
|
validate Docker::API::InvalidParameter, [:quiet], params
|
|
60
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} )
|
|
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
62
|
file.close
|
|
63
63
|
response
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def push name, params = {}, authentication = {}
|
|
67
67
|
validate Docker::API::InvalidParameter, [:tag], params
|
|
68
68
|
|
|
69
69
|
if authentication.keys.size > 0
|
|
70
|
-
|
|
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 } )
|
|
70
|
+
@connection.request(method: :post, path: build_path([name, "push"], params), headers: { "X-Registry-Auth" => Base64.urlsafe_encode64(authentication.to_json.to_s).chomp } )
|
|
73
71
|
else
|
|
74
|
-
|
|
72
|
+
raise Docker::API::Error.new("Provide authentication parameters to push an image")
|
|
75
73
|
end
|
|
76
74
|
end
|
|
77
75
|
|
|
78
|
-
def
|
|
76
|
+
def commit params = {}, body = {}
|
|
79
77
|
validate Docker::API::InvalidParameter, [:container, :repo, :tag, :comment, :author, :pause, :changes], params
|
|
80
78
|
validate Docker::API::InvalidRequestBody, Docker::API::CommitBody, body
|
|
81
|
-
container = Docker::API::Container.inspect(params[:container])
|
|
79
|
+
container = Docker::API::Container.new.inspect(params[:container])
|
|
82
80
|
return container if [404, 301].include? container.status
|
|
83
81
|
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)
|
|
82
|
+
@connection.request(method: :post, path: build_path("/commit", params), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
85
83
|
end
|
|
86
84
|
|
|
87
|
-
def
|
|
85
|
+
def create params = {}, authentication = {}
|
|
88
86
|
validate Docker::API::InvalidParameter, [:fromImage, :fromSrc, :repo, :tag, :message, :platform], params
|
|
89
87
|
|
|
90
88
|
if authentication.keys.size > 0
|
|
91
|
-
auth = Docker::API::System.auth(authentication)
|
|
89
|
+
auth = Docker::API::System.new.auth(authentication)
|
|
92
90
|
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 } )
|
|
91
|
+
@connection.request(method: :post, path: build_path(["create"], params), headers: { "X-Registry-Auth" => Base64.encode64(authentication.to_json.to_s).chomp } )
|
|
94
92
|
elsif params.has_key? :fromSrc
|
|
95
93
|
if params[:fromSrc].match(/^(http|https)/)
|
|
96
|
-
connection.request(method: :post, path: build_path(["create"], params))
|
|
94
|
+
@connection.request(method: :post, path: build_path(["create"], params))
|
|
97
95
|
else
|
|
98
96
|
file = File.open(File.expand_path(params[:fromSrc]), "r")
|
|
99
97
|
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} )
|
|
98
|
+
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
99
|
file.close
|
|
102
100
|
response
|
|
103
101
|
end
|
|
104
102
|
else
|
|
105
|
-
connection.post(build_path(["create"], params))
|
|
103
|
+
@connection.post(build_path(["create"], params))
|
|
106
104
|
end
|
|
107
105
|
end
|
|
108
106
|
|
|
109
|
-
def
|
|
110
|
-
raise Docker::API::
|
|
107
|
+
def build path, params = {}, authentication = {}
|
|
108
|
+
raise Docker::API::Error.new("Expected path or params[:remote]") unless path || params[:remote]
|
|
111
109
|
validate Docker::API::InvalidParameter, Docker::API::BuildParams, params
|
|
112
110
|
|
|
113
111
|
header = {"Content-type": "application/x-tar"}
|
|
114
112
|
if authentication.keys.size > 0
|
|
115
113
|
authentication.each_key do |server|
|
|
116
|
-
auth = Docker::API::System.auth({username: authentication[server][:username] ,password:authentication[server][:password], serveraddress: server})
|
|
114
|
+
auth = Docker::API::System.new.auth({username: authentication[server][:username] ,password:authentication[server][:password], serveraddress: server})
|
|
117
115
|
return auth unless [200, 204].include? auth.status
|
|
118
116
|
end
|
|
119
117
|
header.merge!({"X-Registry-Config": Base64.urlsafe_encode64(authentication.to_json.to_s).chomp})
|
|
@@ -121,17 +119,17 @@ module Docker
|
|
|
121
119
|
|
|
122
120
|
begin
|
|
123
121
|
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})
|
|
122
|
+
response = @connection.request(method: :post, path: build_path("/build", params), headers: header, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s})
|
|
125
123
|
file.close
|
|
126
124
|
rescue
|
|
127
|
-
response = connection.request(method: :post, path: build_path("/build", params), headers: header)
|
|
125
|
+
response = @connection.request(method: :post, path: build_path("/build", params), headers: header)
|
|
128
126
|
end
|
|
129
127
|
response
|
|
130
128
|
end
|
|
131
129
|
|
|
132
|
-
def
|
|
130
|
+
def delete_cache params = {}
|
|
133
131
|
validate Docker::API::InvalidParameter, [:all, "keep-storage", :filters], params
|
|
134
|
-
connection.post(build_path("/build/prune", params))
|
|
132
|
+
@connection.post(build_path("/build/prune", params))
|
|
135
133
|
end
|
|
136
134
|
|
|
137
135
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Docker
|
|
2
|
+
module API
|
|
3
|
+
class Network < Docker::API::Base
|
|
4
|
+
|
|
5
|
+
def base_path
|
|
6
|
+
"/networks"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def list params = {}
|
|
10
|
+
validate Docker::API::InvalidParameter, [:filters], params
|
|
11
|
+
@connection.get(build_path("/networks", params))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def inspect name, params = {}
|
|
15
|
+
validate Docker::API::InvalidParameter, [:verbose, :scope], params
|
|
16
|
+
@connection.get(build_path([name], params))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create body = {}
|
|
20
|
+
validate Docker::API::InvalidRequestBody, [:Name, :CheckDuplicate, :Driver, :Internal, :Attachable, :Ingress, :IPAM, :EnableIPv6, :Options, :Labels], body
|
|
21
|
+
@connection.request(method: :post, path: build_path(["create"]), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def remove name
|
|
25
|
+
@connection.delete(build_path([name]))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def prune params = {}
|
|
29
|
+
validate Docker::API::InvalidParameter, [:filters], params
|
|
30
|
+
@connection.post(build_path(["prune"], params))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def connect name, body = {}
|
|
34
|
+
validate Docker::API::InvalidRequestBody, [:Container, :EndpointConfig], body
|
|
35
|
+
@connection.request(method: :post, path: build_path([name, "connect"]), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def disconnect name, body = {}
|
|
39
|
+
validate Docker::API::InvalidRequestBody, [:Container, :Force], body
|
|
40
|
+
@connection.request(method: :post, path: build_path([name, "disconnect"]), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Docker
|
|
2
|
+
module API
|
|
3
|
+
class Response < Excon::Response
|
|
4
|
+
attr_reader(:json, :path)
|
|
5
|
+
|
|
6
|
+
def initialize data
|
|
7
|
+
super data
|
|
8
|
+
@json = parse_json @body
|
|
9
|
+
@path = @data[:path]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def success?
|
|
13
|
+
(200..204).include? @status
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def parse_json data
|
|
19
|
+
return nil unless headers["Content-Type"] == "application/json"
|
|
20
|
+
return nil if data == ""
|
|
21
|
+
data.split("\r\n").size > 1 ? data.split("\r\n").map{ |e| eval(e) } : JSON.parse(data)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/docker/api/system.rb
CHANGED
|
@@ -2,11 +2,33 @@ require "json"
|
|
|
2
2
|
module Docker
|
|
3
3
|
module API
|
|
4
4
|
class System < Docker::API::Base
|
|
5
|
-
|
|
6
|
-
def
|
|
5
|
+
|
|
6
|
+
def auth body = {}
|
|
7
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)
|
|
8
|
+
@connection.request(method: :post, path: "/auth", headers: { "Content-Type" => "application/json" }, body: body.to_json)
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
def events params = {}
|
|
12
|
+
validate Docker::API::InvalidParameter, [:since, :until, :filters], params
|
|
13
|
+
@connection.request(method: :get, path: build_path("/events", params), response_block: lambda { |chunk, remaining_bytes, total_bytes| puts chunk.inspect } )
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ping
|
|
17
|
+
@connection.get("/_ping")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def info
|
|
21
|
+
@connection.get("/info")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def version
|
|
25
|
+
@connection.get("/version")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def df
|
|
29
|
+
@connection.get("/system/df")
|
|
30
|
+
end
|
|
31
|
+
|
|
10
32
|
end
|
|
11
33
|
end
|
|
12
34
|
end
|
data/lib/docker/api/version.rb
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Docker
|
|
2
|
+
module API
|
|
3
|
+
class Volume < Docker::API::Base
|
|
4
|
+
def base_path
|
|
5
|
+
"/volumes"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def list params = {}
|
|
9
|
+
validate Docker::API::InvalidParameter, [:filters], params
|
|
10
|
+
@connection.get(build_path("/volumes", params))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create body = {}
|
|
14
|
+
validate Docker::API::InvalidRequestBody, [:Name, :Driver, :DriverOpts, :Labels], body
|
|
15
|
+
@connection.request(method: :post, path: build_path(["create"]), headers: {"Content-Type": "application/json"}, body: body.to_json)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def inspect name
|
|
19
|
+
@connection.get(build_path([name]))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove name, params = {}
|
|
23
|
+
validate Docker::API::InvalidParameter, [:force], params
|
|
24
|
+
@connection.delete(build_path([name]))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def prune params = {}
|
|
28
|
+
validate Docker::API::InvalidParameter, [:filters], params
|
|
29
|
+
@connection.post(build_path(["prune"], params))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/dockerapi.rb
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "excon"
|
|
2
|
+
require "json"
|
|
2
3
|
|
|
4
|
+
require "docker/api/version"
|
|
3
5
|
require "docker/api/error"
|
|
4
6
|
require "docker/api/connection"
|
|
7
|
+
require "docker/api/response"
|
|
5
8
|
require "docker/api/base"
|
|
6
9
|
require "docker/api/container"
|
|
7
10
|
require "docker/api/image"
|
|
11
|
+
require "docker/api/volume"
|
|
12
|
+
require "docker/api/network"
|
|
13
|
+
require "docker/api/exec"
|
|
8
14
|
require "docker/api/system"
|
|
9
15
|
|
|
10
16
|
module Docker
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dockerapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.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-
|
|
11
|
+
date: 2020-07-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: excon
|
|
@@ -47,9 +47,13 @@ files:
|
|
|
47
47
|
- lib/docker/api/connection.rb
|
|
48
48
|
- lib/docker/api/container.rb
|
|
49
49
|
- lib/docker/api/error.rb
|
|
50
|
+
- lib/docker/api/exec.rb
|
|
50
51
|
- lib/docker/api/image.rb
|
|
52
|
+
- lib/docker/api/network.rb
|
|
53
|
+
- lib/docker/api/response.rb
|
|
51
54
|
- lib/docker/api/system.rb
|
|
52
55
|
- lib/docker/api/version.rb
|
|
56
|
+
- lib/docker/api/volume.rb
|
|
53
57
|
- lib/dockerapi.rb
|
|
54
58
|
homepage: https://github.com/nu12/dockerapi
|
|
55
59
|
licenses:
|