presidium 0.15.35 → 0.15.36
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.
- package/Docker.js +29 -0
- package/Docker.test.js +380 -351
- package/package.json +1 -1
package/Docker.js
CHANGED
|
@@ -1136,6 +1136,18 @@ Docker.prototype.updateService = function dockerUpdateService(service, options)
|
|
|
1136
1136
|
})
|
|
1137
1137
|
}
|
|
1138
1138
|
|
|
1139
|
+
/**
|
|
1140
|
+
* @name Docker.prototype.deleteService
|
|
1141
|
+
*
|
|
1142
|
+
* @synopsis
|
|
1143
|
+
* ```coffeescript [specscript]
|
|
1144
|
+
* new Docker().deleteService(id string) -> Promise<HttpResponse>
|
|
1145
|
+
* ```
|
|
1146
|
+
*/
|
|
1147
|
+
Docker.prototype.deleteService = function deleteService(id) {
|
|
1148
|
+
return this.http.delete(`/services/${id}`)
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1139
1151
|
/**
|
|
1140
1152
|
* @name Docker.prototype.listServices
|
|
1141
1153
|
*
|
|
@@ -1189,6 +1201,23 @@ Docker.prototype.getServiceLogs = async function getServiceLogs(serviceId, optio
|
|
|
1189
1201
|
}`)
|
|
1190
1202
|
}
|
|
1191
1203
|
|
|
1204
|
+
/**
|
|
1205
|
+
* @name Docker.prototype.listTasks
|
|
1206
|
+
*
|
|
1207
|
+
* @synopsis
|
|
1208
|
+
* ```coffeescript [specscript]
|
|
1209
|
+
* new Docker().listTasks(options {
|
|
1210
|
+
* service?: string,
|
|
1211
|
+
* node?: string,
|
|
1212
|
+
* }) -> Promise<HttpResponse>
|
|
1213
|
+
* ```
|
|
1214
|
+
*/
|
|
1215
|
+
Docker.prototype.listTasks = async function listTasks(options) {
|
|
1216
|
+
return this.http.get(`/tasks?${
|
|
1217
|
+
querystring.stringify(pick(['service', 'node'])(options))
|
|
1218
|
+
}`)
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1192
1221
|
/**
|
|
1193
1222
|
* @name Docker.prototype.pruneImages
|
|
1194
1223
|
*
|
package/Docker.test.js
CHANGED
|
@@ -15,372 +15,401 @@ const {
|
|
|
15
15
|
curry, __,
|
|
16
16
|
} = rubico
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const test = Test.all([
|
|
19
19
|
Test('Docker - prune', Docker)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
.case(async docker => {
|
|
21
|
+
{
|
|
22
|
+
const response = await docker.pruneContainers()
|
|
23
|
+
assert.equal(response.status, 200)
|
|
24
|
+
}
|
|
25
|
+
{
|
|
26
|
+
const response = await docker.pruneVolumes()
|
|
27
|
+
assert.equal(response.status, 200)
|
|
28
|
+
}
|
|
29
|
+
{
|
|
30
|
+
const response = await docker.pruneImages()
|
|
31
|
+
assert.equal(response.status, 200)
|
|
32
|
+
}
|
|
33
|
+
{
|
|
34
|
+
const response = await docker.pruneNetworks()
|
|
35
|
+
assert.equal(response.status, 200)
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
38
|
|
|
39
39
|
Test('Docker - auth', Docker)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
.case(async docker => {
|
|
41
|
+
const response = await docker.auth({
|
|
42
|
+
username: 'admin',
|
|
43
|
+
password: 'password',
|
|
44
|
+
email: 'hey@example.com',
|
|
45
|
+
serveraddress: 'localhost:5000',
|
|
46
|
+
})
|
|
47
|
+
assert.equal(response.status, 200)
|
|
48
|
+
const body = await pipe([
|
|
49
|
+
reduce((a, b) => a + b, ''),
|
|
50
|
+
JSON.parse,
|
|
51
|
+
])(response.body)
|
|
52
|
+
this.identitytoken = get('IdentityToken')(body)
|
|
53
|
+
assert.equal(this.identitytoken, '')
|
|
54
|
+
}),
|
|
55
55
|
|
|
56
56
|
Test('Docker - image', Docker)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
57
|
+
.case(async function (docker) {
|
|
58
|
+
{
|
|
59
|
+
const response = await docker.buildImage('presidium-test:ayo', pathResolve(__dirname), {
|
|
60
|
+
archive: {
|
|
61
|
+
Dockerfile: `
|
|
62
|
+
FROM node:15-alpine
|
|
63
|
+
WORKDIR /opt
|
|
64
|
+
COPY . .
|
|
65
|
+
EXPOSE 8888`,
|
|
66
|
+
},
|
|
67
|
+
platform: 'linux/x86_64',
|
|
68
|
+
})
|
|
69
|
+
assert.equal(response.status, 200)
|
|
70
|
+
response.body.pipe(process.stdout)
|
|
71
|
+
await new Promise(resolve => {
|
|
72
|
+
response.body.on('end', resolve)
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
{
|
|
76
|
+
const response = await docker.listImages()
|
|
77
|
+
assert.equal(response.status, 200)
|
|
78
|
+
const body = await response.json()
|
|
79
|
+
assert(body.length > 1)
|
|
80
|
+
this.initialBodyLength = body.length
|
|
81
|
+
}
|
|
82
|
+
{
|
|
83
|
+
const response = await docker.tagImage('presidium-test:ayo', {
|
|
84
|
+
tag: 'ayo',
|
|
85
|
+
repo: 'localhost:5000/presidium-test',
|
|
86
|
+
})
|
|
87
|
+
response.body.pipe(process.stdout)
|
|
88
|
+
await new Promise(resolve => {
|
|
89
|
+
response.body.on('end', resolve)
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
{
|
|
93
|
+
const response = await docker.pushImage('presidium-test:ayo', 'localhost:5000', {
|
|
94
|
+
identitytoken: this.identitytoken,
|
|
95
|
+
})
|
|
96
|
+
response.body.pipe(process.stdout)
|
|
97
|
+
await new Promise(resolve => {
|
|
98
|
+
response.body.on('end', resolve)
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
{
|
|
102
|
+
const response = await docker.inspectImage('localhost:5000/presidium-test:ayo')
|
|
103
|
+
assert.equal(response.status, 200)
|
|
104
|
+
}
|
|
105
|
+
{
|
|
106
|
+
const responses = await Promise.all([
|
|
107
|
+
docker.removeImage('presidium-test:ayo'),
|
|
108
|
+
docker.removeImage('localhost:5000/presidium-test:ayo'),
|
|
109
|
+
])
|
|
110
|
+
for (const response of responses) {
|
|
111
|
+
const response = await docker.removeImage('presidium-test:ayo')
|
|
112
|
+
assert(response.status == 200 || response.status == 404)
|
|
114
113
|
}
|
|
115
|
-
}
|
|
114
|
+
}
|
|
115
|
+
}),
|
|
116
116
|
|
|
117
117
|
Test('Docker - container', Docker)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const body = await attachResponse.buffer()
|
|
134
|
-
assert.equal(body.constructor, Buffer)
|
|
135
|
-
assert.strictEqual(body[0], 1) // stdout
|
|
136
|
-
assert.strictEqual(body[1], 0) // empty
|
|
137
|
-
assert.strictEqual(body[2], 0) // empty
|
|
138
|
-
assert.strictEqual(body[3], 0) // empty
|
|
139
|
-
assert.strictEqual(body[4], 0) // SIZE1
|
|
140
|
-
assert.strictEqual(body[5], 0) // SIZE2
|
|
141
|
-
assert.strictEqual(body[6], 0) // SIZE3
|
|
142
|
-
assert.strictEqual(body[7], 5) // SIZE4
|
|
143
|
-
assert.strictEqual(body.slice(8).toString(), 'heyy\n')
|
|
144
|
-
|
|
145
|
-
this.removedContainerId = containerId
|
|
146
|
-
}
|
|
118
|
+
.case(async function (docker) {
|
|
119
|
+
{
|
|
120
|
+
const createResponse = await docker.createContainer({
|
|
121
|
+
name: 'test-alpine-3',
|
|
122
|
+
image: 'node:15-alpine',
|
|
123
|
+
cmd: ['node', '-e', 'console.log(\'heyy\')'],
|
|
124
|
+
rm: true,
|
|
125
|
+
})
|
|
126
|
+
assert(createResponse.ok)
|
|
127
|
+
const containerId = (await createResponse.json()).Id
|
|
128
|
+
const attachResponse = await docker.attachContainer(containerId),
|
|
129
|
+
startResponse = await docker.startContainer(containerId)
|
|
130
|
+
assert(startResponse.ok)
|
|
131
|
+
assert(attachResponse.ok)
|
|
147
132
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
target: '/opt/other-volume',
|
|
160
|
-
readonly: true,
|
|
161
|
-
}],
|
|
162
|
-
memory: 512e6, // bytes
|
|
163
|
-
restart: 'on-failure:5',
|
|
164
|
-
|
|
165
|
-
healthCmd: ['echo', 'ok'],
|
|
166
|
-
healthInterval: 1e9,
|
|
167
|
-
healthTimeout: 30e9,
|
|
168
|
-
healthRetries: 10,
|
|
169
|
-
healthStartPeriod: 5e9,
|
|
170
|
-
|
|
171
|
-
publish: {
|
|
172
|
-
23: 22, // hostPort -> containerPort[/protocol]
|
|
173
|
-
8888: '8000/tcp',
|
|
174
|
-
},
|
|
175
|
-
logDriver: 'json-file',
|
|
176
|
-
logDriverOptions: {
|
|
177
|
-
'max-file': '10',
|
|
178
|
-
'max-size': '100m',
|
|
179
|
-
},
|
|
180
|
-
})
|
|
181
|
-
assert(createResponse.ok)
|
|
182
|
-
const containerId = (await createResponse.json()).Id
|
|
183
|
-
this.containerId = containerId
|
|
184
|
-
const attachResponse = await docker.attachContainer(containerId),
|
|
185
|
-
startResponse = await docker.startContainer(containerId)
|
|
186
|
-
assert(startResponse.ok)
|
|
187
|
-
assert(attachResponse.ok)
|
|
188
|
-
|
|
189
|
-
const body = await attachResponse.buffer()
|
|
190
|
-
assert.equal(body.constructor, Buffer)
|
|
191
|
-
assert.strictEqual(body[0], 1) // stdout
|
|
192
|
-
assert.strictEqual(body[1], 0) // empty
|
|
193
|
-
assert.strictEqual(body[2], 0) // empty
|
|
194
|
-
assert.strictEqual(body[3], 0) // empty
|
|
195
|
-
assert.strictEqual(body[4], 0) // SIZE1
|
|
196
|
-
assert.strictEqual(body[5], 0) // SIZE2
|
|
197
|
-
assert.strictEqual(body[6], 0) // SIZE3
|
|
198
|
-
assert.strictEqual(body[7], 4) // SIZE4
|
|
199
|
-
assert.strictEqual(body.slice(8).toString(), 'hey\n')
|
|
200
|
-
}
|
|
133
|
+
const body = await attachResponse.buffer()
|
|
134
|
+
assert.equal(body.constructor, Buffer)
|
|
135
|
+
assert.strictEqual(body[0], 1) // stdout
|
|
136
|
+
assert.strictEqual(body[1], 0) // empty
|
|
137
|
+
assert.strictEqual(body[2], 0) // empty
|
|
138
|
+
assert.strictEqual(body[3], 0) // empty
|
|
139
|
+
assert.strictEqual(body[4], 0) // SIZE1
|
|
140
|
+
assert.strictEqual(body[5], 0) // SIZE2
|
|
141
|
+
assert.strictEqual(body[6], 0) // SIZE3
|
|
142
|
+
assert.strictEqual(body[7], 5) // SIZE4
|
|
143
|
+
assert.strictEqual(body.slice(8).toString(), 'heyy\n')
|
|
201
144
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
name: 'test-alpine-2',
|
|
205
|
-
image: 'node:15-alpine',
|
|
206
|
-
cmd: ['node', '-e', 'http.createServer((request, response) => response.end(\'hey0\')).listen(2999)'],
|
|
207
|
-
rm: true,
|
|
208
|
-
})
|
|
209
|
-
assert(createResponse.ok)
|
|
210
|
-
const containerId = (await createResponse.json()).Id
|
|
211
|
-
assert((await docker.startContainer(containerId)).ok)
|
|
212
|
-
const execResponse = await docker.execContainer(containerId, ['node', '-e', 'console.log(\'heyyy\')'])
|
|
213
|
-
const body = await execResponse.buffer()
|
|
214
|
-
assert.equal(body.constructor, Buffer)
|
|
215
|
-
assert.strictEqual(body[0], 1) // stdout
|
|
216
|
-
assert.strictEqual(body[1], 0) // empty
|
|
217
|
-
assert.strictEqual(body[2], 0) // empty
|
|
218
|
-
assert.strictEqual(body[3], 0) // empty
|
|
219
|
-
assert.strictEqual(body[4], 0) // SIZE1
|
|
220
|
-
assert.strictEqual(body[5], 0) // SIZE2
|
|
221
|
-
assert.strictEqual(body[6], 0) // SIZE3
|
|
222
|
-
assert.strictEqual(body[7], 6) // SIZE4
|
|
223
|
-
assert.strictEqual(body.slice(8).toString(), 'heyyy\n')
|
|
224
|
-
await docker.stopContainer(containerId, { time: 1 })
|
|
225
|
-
}
|
|
145
|
+
this.removedContainerId = containerId
|
|
146
|
+
}
|
|
226
147
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
'max-file': '10',
|
|
244
|
-
'max-size': '100m',
|
|
245
|
-
},
|
|
246
|
-
})
|
|
247
|
-
assert.deepEqual(body.Config.Healthcheck, {
|
|
248
|
-
Test: ['CMD', 'echo', 'ok'],
|
|
249
|
-
Interval: 1000000000,
|
|
250
|
-
Timeout: 30000000000,
|
|
251
|
-
StartPeriod: 5000000000,
|
|
252
|
-
Retries: 10,
|
|
253
|
-
})
|
|
254
|
-
assert.deepEqual(body.HostConfig.Mounts, [{
|
|
255
|
-
Type: 'volume',
|
|
256
|
-
Source: 'other-volume',
|
|
257
|
-
Target: '/opt/other-volume',
|
|
258
|
-
ReadOnly: true
|
|
259
|
-
}])
|
|
260
|
-
}
|
|
148
|
+
{
|
|
149
|
+
const createResponse = await docker.createContainer({
|
|
150
|
+
name: 'test-alpine-1',
|
|
151
|
+
image: 'node:15-alpine',
|
|
152
|
+
cmd: ['node', '-e', 'console.log(\'hey\')'],
|
|
153
|
+
workdir: '/opt/heyo',
|
|
154
|
+
expose: [22, 8888, '8889/udp'],
|
|
155
|
+
env: { HEY: 'hey' },
|
|
156
|
+
volume: ['/opt/my-volume'],
|
|
157
|
+
mounts: [{
|
|
158
|
+
source: 'other-volume',
|
|
159
|
+
target: '/opt/other-volume',
|
|
160
|
+
readonly: true,
|
|
161
|
+
}],
|
|
162
|
+
memory: 512e6, // bytes
|
|
163
|
+
restart: 'on-failure:5',
|
|
261
164
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
165
|
+
healthCmd: ['echo', 'ok'],
|
|
166
|
+
healthInterval: 1e9,
|
|
167
|
+
healthTimeout: 30e9,
|
|
168
|
+
healthRetries: 10,
|
|
169
|
+
healthStartPeriod: 5e9,
|
|
170
|
+
|
|
171
|
+
publish: {
|
|
172
|
+
23: 22, // hostPort -> containerPort[/protocol]
|
|
173
|
+
8888: '8000/tcp',
|
|
174
|
+
},
|
|
175
|
+
logDriver: 'json-file',
|
|
176
|
+
logDriverOptions: {
|
|
177
|
+
'max-file': '10',
|
|
178
|
+
'max-size': '100m',
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
assert(createResponse.ok)
|
|
182
|
+
const containerId = (await createResponse.json()).Id
|
|
183
|
+
this.containerId = containerId
|
|
184
|
+
const attachResponse = await docker.attachContainer(containerId),
|
|
185
|
+
startResponse = await docker.startContainer(containerId)
|
|
186
|
+
assert(startResponse.ok)
|
|
187
|
+
assert(attachResponse.ok)
|
|
188
|
+
|
|
189
|
+
const body = await attachResponse.buffer()
|
|
190
|
+
assert.equal(body.constructor, Buffer)
|
|
191
|
+
assert.strictEqual(body[0], 1) // stdout
|
|
192
|
+
assert.strictEqual(body[1], 0) // empty
|
|
193
|
+
assert.strictEqual(body[2], 0) // empty
|
|
194
|
+
assert.strictEqual(body[3], 0) // empty
|
|
195
|
+
assert.strictEqual(body[4], 0) // SIZE1
|
|
196
|
+
assert.strictEqual(body[5], 0) // SIZE2
|
|
197
|
+
assert.strictEqual(body[6], 0) // SIZE3
|
|
198
|
+
assert.strictEqual(body[7], 4) // SIZE4
|
|
199
|
+
assert.strictEqual(body.slice(8).toString(), 'hey\n')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
const createResponse = await docker.createContainer({
|
|
204
|
+
name: 'test-alpine-2',
|
|
205
|
+
image: 'node:15-alpine',
|
|
206
|
+
cmd: ['node', '-e', 'http.createServer((request, response) => response.end(\'hey0\')).listen(2999)'],
|
|
207
|
+
rm: true,
|
|
208
|
+
})
|
|
209
|
+
assert(createResponse.ok)
|
|
210
|
+
const containerId = (await createResponse.json()).Id
|
|
211
|
+
assert((await docker.startContainer(containerId)).ok)
|
|
212
|
+
const execResponse = await docker.execContainer(containerId, ['node', '-e', 'console.log(\'heyyy\')'])
|
|
213
|
+
const body = await execResponse.buffer()
|
|
214
|
+
assert.equal(body.constructor, Buffer)
|
|
215
|
+
assert.strictEqual(body[0], 1) // stdout
|
|
216
|
+
assert.strictEqual(body[1], 0) // empty
|
|
217
|
+
assert.strictEqual(body[2], 0) // empty
|
|
218
|
+
assert.strictEqual(body[3], 0) // empty
|
|
219
|
+
assert.strictEqual(body[4], 0) // SIZE1
|
|
220
|
+
assert.strictEqual(body[5], 0) // SIZE2
|
|
221
|
+
assert.strictEqual(body[6], 0) // SIZE3
|
|
222
|
+
assert.strictEqual(body[7], 6) // SIZE4
|
|
223
|
+
assert.strictEqual(body.slice(8).toString(), 'heyyy\n')
|
|
224
|
+
await docker.stopContainer(containerId, { time: 1 })
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
{
|
|
228
|
+
const response = await docker.inspectContainer(this.containerId)
|
|
229
|
+
assert.equal(response.status, 200)
|
|
230
|
+
const body = await response.json()
|
|
231
|
+
assert.equal(body.Config.Image, 'node:15-alpine')
|
|
232
|
+
assert.deepEqual(body.Config.Volumes, { '/opt/my-volume': {} })
|
|
233
|
+
assert.equal(body.Config.WorkingDir, '/opt/heyo')
|
|
234
|
+
assert.deepEqual(body.Config.ExposedPorts, { '22/tcp': {}, '8888/tcp': {}, '8889/udp': {} })
|
|
235
|
+
assert.equal(body.HostConfig.Memory, 512e6)
|
|
236
|
+
assert.deepEqual(body.HostConfig.PortBindings, {
|
|
237
|
+
'22/tcp': [{ HostIp: '', HostPort: '23' }],
|
|
238
|
+
'8000/tcp': [{ HostIp: '', HostPort: '8888' }]
|
|
239
|
+
})
|
|
240
|
+
assert.deepEqual(body.HostConfig.LogConfig, {
|
|
241
|
+
Type: 'json-file',
|
|
242
|
+
Config: {
|
|
243
|
+
'max-file': '10',
|
|
244
|
+
'max-size': '100m',
|
|
245
|
+
},
|
|
246
|
+
})
|
|
247
|
+
assert.deepEqual(body.Config.Healthcheck, {
|
|
248
|
+
Test: ['CMD', 'echo', 'ok'],
|
|
249
|
+
Interval: 1000000000,
|
|
250
|
+
Timeout: 30000000000,
|
|
251
|
+
StartPeriod: 5000000000,
|
|
252
|
+
Retries: 10,
|
|
253
|
+
})
|
|
254
|
+
assert.deepEqual(body.HostConfig.Mounts, [{
|
|
255
|
+
Type: 'volume',
|
|
256
|
+
Source: 'other-volume',
|
|
257
|
+
Target: '/opt/other-volume',
|
|
258
|
+
ReadOnly: true
|
|
259
|
+
}])
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
{
|
|
263
|
+
const containersResponse = await docker.listContainers()
|
|
264
|
+
assert.equal(containersResponse.status, 200)
|
|
265
|
+
const body = await containersResponse.json()
|
|
266
|
+
assert(!body.map(get('Id')).includes(this.removedContainerId))
|
|
267
|
+
}
|
|
268
|
+
}),
|
|
269
269
|
|
|
270
270
|
Test('Docker - swarm and service', Docker)
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
{
|
|
277
|
-
const response = await docker.initSwarm('[::1]:2377')
|
|
278
|
-
assert.equal(response.status, 200)
|
|
279
|
-
}
|
|
280
|
-
{
|
|
281
|
-
const response = await docker.inspectSwarm()
|
|
282
|
-
assert.equal(response.status, 200)
|
|
283
|
-
const body = await response.json()
|
|
284
|
-
assert.equal(typeof body.JoinTokens.Worker, 'string')
|
|
285
|
-
assert.equal(typeof body.JoinTokens.Manager, 'string')
|
|
286
|
-
this.workerJoinToken = body.JoinTokens.Worker
|
|
287
|
-
}
|
|
271
|
+
.case(async function (docker) {
|
|
272
|
+
{ // initial leaveSwarm
|
|
273
|
+
const response = await docker.leaveSwarm({ force: true })
|
|
274
|
+
assert([200, 503].includes(response.status))
|
|
275
|
+
}
|
|
288
276
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
cmd: ['node', '-e', 'http.createServer((request, response) => response.end(\'hey1\')).listen(3000)'],
|
|
294
|
-
workdir: '/opt/heyo',
|
|
295
|
-
env: { HEY: 'hey' },
|
|
296
|
-
mounts: [{
|
|
297
|
-
source: 'other-volume',
|
|
298
|
-
target: '/opt/other-volume',
|
|
299
|
-
readonly: true,
|
|
300
|
-
}],
|
|
301
|
-
memory: 512e6, // bytes
|
|
302
|
-
restart: 'on-failure:5',
|
|
303
|
-
|
|
304
|
-
healthCmd: ['wget', '--no-verbose', '--tries=1', '--spider', 'localhost:3000'],
|
|
305
|
-
healthInterval: 1e9,
|
|
306
|
-
healthTimeout: 30e9,
|
|
307
|
-
healthRetries: 10,
|
|
308
|
-
healthStartPeriod: 5e9,
|
|
309
|
-
|
|
310
|
-
publish: {
|
|
311
|
-
23: 22, // hostPort -> containerPort[/protocol]
|
|
312
|
-
8080: 3000,
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
logDriver: 'json-file',
|
|
316
|
-
logDriverOptions: {
|
|
317
|
-
'max-file': '10',
|
|
318
|
-
'max-size': '100m',
|
|
319
|
-
},
|
|
320
|
-
})
|
|
321
|
-
assert.equal(response.status, 201)
|
|
322
|
-
const body = await response.json()
|
|
323
|
-
this.serviceId = body.ID
|
|
324
|
-
}
|
|
277
|
+
{ // initSwarm
|
|
278
|
+
const response = await docker.initSwarm('[::1]:2377')
|
|
279
|
+
assert.equal(response.status, 200)
|
|
280
|
+
}
|
|
325
281
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
source: 'other-volume',
|
|
335
|
-
target: '/opt/other-volume',
|
|
336
|
-
readonly: true,
|
|
337
|
-
}],
|
|
338
|
-
memory: 512e6, // bytes
|
|
339
|
-
restart: 'on-failure',
|
|
340
|
-
publish: { 8081: 3001 },
|
|
341
|
-
|
|
342
|
-
healthCmd: ['wget', '--no-verbose', '--tries=1', '--spider', 'localhost:3001'],
|
|
343
|
-
})
|
|
344
|
-
assert.equal(response.status, 201)
|
|
345
|
-
}
|
|
346
|
-
{
|
|
347
|
-
const response = await docker.listServices()
|
|
348
|
-
assert.equal(response.status, 200)
|
|
349
|
-
const body = await response.json()
|
|
350
|
-
assert.equal(body.length, 2)
|
|
351
|
-
}
|
|
352
|
-
{
|
|
353
|
-
const response = await docker.inspectService(this.serviceId)
|
|
354
|
-
assert.equal(response.status, 200)
|
|
355
|
-
}
|
|
282
|
+
{ // inspectSwarm
|
|
283
|
+
const response = await docker.inspectSwarm()
|
|
284
|
+
assert.equal(response.status, 200)
|
|
285
|
+
const body = await response.json()
|
|
286
|
+
assert.equal(typeof body.JoinTokens.Worker, 'string')
|
|
287
|
+
assert.equal(typeof body.JoinTokens.Manager, 'string')
|
|
288
|
+
this.workerJoinToken = body.JoinTokens.Worker
|
|
289
|
+
}
|
|
356
290
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
291
|
+
{ // create a service
|
|
292
|
+
const response = await docker.createService('hey1', {
|
|
293
|
+
image: 'node:15-alpine',
|
|
294
|
+
replicas: 2,
|
|
295
|
+
cmd: ['node', '-e', 'http.createServer((request, response) => response.end(\'hey1\')).listen(3000)'],
|
|
296
|
+
workdir: '/opt/heyo',
|
|
297
|
+
env: { HEY: 'hey' },
|
|
298
|
+
mounts: [{
|
|
299
|
+
source: 'other-volume',
|
|
300
|
+
target: '/opt/other-volume',
|
|
301
|
+
readonly: true,
|
|
302
|
+
}],
|
|
303
|
+
memory: 512e6, // bytes
|
|
304
|
+
restart: 'on-failure:5',
|
|
366
305
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
306
|
+
healthCmd: ['wget', '--no-verbose', '--tries=1', '--spider', 'localhost:3000'],
|
|
307
|
+
healthInterval: 1e9,
|
|
308
|
+
healthTimeout: 30e9,
|
|
309
|
+
healthRetries: 10,
|
|
310
|
+
healthStartPeriod: 5e9,
|
|
311
|
+
|
|
312
|
+
publish: {
|
|
313
|
+
// 23: 22, // hostPort -> containerPort[/protocol]
|
|
314
|
+
8080: 3000,
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
logDriver: 'json-file',
|
|
318
|
+
logDriverOptions: {
|
|
319
|
+
'max-file': '10',
|
|
320
|
+
'max-size': '100m',
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
assert.equal(response.status, 201)
|
|
324
|
+
const body = await response.json()
|
|
325
|
+
this.serviceId = body.ID
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
{ // create another service
|
|
329
|
+
const response = await docker.createService('hey2', {
|
|
330
|
+
image: 'node:15-alpine',
|
|
331
|
+
replicas: 2,
|
|
332
|
+
cmd: ['node', '-e', 'http.createServer((request, response) => response.end(\'hey2\')).listen(3001)'],
|
|
333
|
+
workdir: '/opt/heyo',
|
|
334
|
+
env: { HEY: 'hey' },
|
|
335
|
+
mounts: [{
|
|
336
|
+
source: 'other-volume',
|
|
337
|
+
target: '/opt/other-volume',
|
|
338
|
+
readonly: true,
|
|
339
|
+
}],
|
|
340
|
+
memory: 512e6, // bytes
|
|
341
|
+
restart: 'on-failure',
|
|
342
|
+
publish: { 8081: 3001 },
|
|
343
|
+
|
|
344
|
+
healthCmd: ['wget', '--no-verbose', '--tries=1', '--spider', 'localhost:3001'],
|
|
345
|
+
})
|
|
346
|
+
assert.equal(response.status, 201)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
{ // listServices
|
|
350
|
+
const response = await docker.listServices()
|
|
351
|
+
assert.equal(response.status, 200)
|
|
352
|
+
const body = await response.json()
|
|
353
|
+
assert.equal(body.length, 2)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
{ // listTasks
|
|
357
|
+
const response = await docker.listTasks()
|
|
358
|
+
const body = await response.json()
|
|
359
|
+
assert.equal(body.length, 4) // 2 for hey1, 2 for hey2
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
{ // inspectService
|
|
363
|
+
const response = await docker.inspectService(this.serviceId)
|
|
364
|
+
assert.equal(response.status, 200)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
{ // deleteService
|
|
368
|
+
const response = await docker.deleteService(this.serviceId)
|
|
369
|
+
assert.equal(response.status, 200)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
{ // listServices again
|
|
373
|
+
const response = await docker.listServices()
|
|
374
|
+
assert.equal(response.status, 200)
|
|
375
|
+
const body = await response.json()
|
|
376
|
+
assert.equal(body.length, 1)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
{ // leaveSwarm without forcing
|
|
380
|
+
const response = await docker.leaveSwarm()
|
|
381
|
+
assert.equal(response.status, 503)
|
|
382
|
+
assert((await response.json()).message.startsWith('You are attempting to leave'))
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
{ // force leaveSwarm
|
|
386
|
+
const response = await docker.leaveSwarm({ force: true })
|
|
387
|
+
assert.equal(response.status, 200)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
await Promise.all([ // TODO figure out a real test for join. Checking for the 503 is ok but is both slow and not a 200
|
|
391
|
+
docker.joinSwarm('[::1]:2377', this.workerJoinToken, {
|
|
392
|
+
listenAddr: 'hey',
|
|
393
|
+
}).then(async response => {
|
|
394
|
+
console.log('hey1', await response.text())
|
|
395
|
+
// assert.equal(response.status, 503)
|
|
396
|
+
assert.equal(response.status, 400)
|
|
397
|
+
}),
|
|
398
|
+
docker.joinSwarm('[::1]:2377', this.workerJoinToken, {
|
|
399
|
+
advertiseAddr: '[::1]:2377',
|
|
400
|
+
listenAddr: 'hey',
|
|
401
|
+
dataPathAddr: '127.0.0.1',
|
|
402
|
+
}).then(async response => {
|
|
403
|
+
console.log('hey2', await response.text())
|
|
404
|
+
// assert.equal(response.status, 503)
|
|
405
|
+
assert.equal(response.status, 400)
|
|
406
|
+
}),
|
|
407
|
+
])
|
|
408
|
+
}),
|
|
409
|
+
])
|
|
410
|
+
|
|
411
|
+
if (process.argv[1] == __filename) {
|
|
412
|
+
test()
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
module.exports = test
|