build-strap 4.0.0-dev.46 → 4.0.0-dev.54
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/README.md +3 -34
- package/package.json +23 -19
- package/src/ant.d.ts +19 -0
- package/src/ant.js +12 -36
- package/src/cert.d.ts +12 -0
- package/src/cert.js +87 -148
- package/src/clean.d.ts +4 -0
- package/src/clean.js +5 -13
- package/src/copy.d.ts +7 -0
- package/src/copy.js +48 -74
- package/src/cp.d.ts +17 -0
- package/src/cp.js +81 -165
- package/src/docker.container.d.ts +73 -0
- package/src/docker.container.js +208 -350
- package/src/docker.d.ts +68 -0
- package/src/docker.js +163 -339
- package/src/docker.network.d.ts +42 -0
- package/src/docker.network.js +67 -141
- package/src/docker.volume.d.ts +26 -0
- package/src/docker.volume.js +50 -124
- package/src/dockerCleanup.d.ts +38 -0
- package/src/dockerCleanup.js +62 -136
- package/src/dockerCompose.d.ts +154 -0
- package/src/dockerCompose.js +390 -716
- package/src/fs.d.ts +5 -0
- package/src/fs.js +33 -91
- package/src/git.d.ts +9 -0
- package/src/git.js +19 -29
- package/src/index.d.ts +20 -0
- package/src/index.js +20 -26
- package/src/maps.d.ts +33 -0
- package/src/maps.js +12 -82
- package/src/npm.d.ts +48 -0
- package/src/npm.js +128 -131
- package/src/pkg.d.ts +38 -0
- package/src/pkg.js +27 -74
- package/src/publish.d.ts +27 -0
- package/src/publish.js +51 -138
- package/src/run.d.ts +13 -0
- package/src/run.js +39 -84
- package/src/tgz.d.ts +13 -0
- package/src/tgz.js +54 -88
- package/src/version.d.ts +34 -0
- package/src/version.js +85 -126
- package/src/yarn.d.ts +44 -0
- package/src/yarn.js +147 -115
- package/ant.js +0 -43
- package/ant.js.flow +0 -42
- package/artifactory.js +0 -617
- package/artifactory.js.flow +0 -616
- package/cert.conf +0 -20
- package/cert.js +0 -153
- package/cert.js.flow +0 -152
- package/clean.js +0 -20
- package/clean.js.flow +0 -19
- package/copy.js +0 -80
- package/copy.js.flow +0 -79
- package/cp.js +0 -173
- package/cp.js.flow +0 -172
- package/docker.container.js +0 -390
- package/docker.container.js.flow +0 -389
- package/docker.js +0 -365
- package/docker.js.flow +0 -364
- package/docker.network.js +0 -160
- package/docker.network.js.flow +0 -159
- package/docker.volume.js +0 -136
- package/docker.volume.js.flow +0 -136
- package/dockerCleanup.js +0 -152
- package/dockerCleanup.js.flow +0 -151
- package/dockerCompose.js +0 -766
- package/dockerCompose.js.flow +0 -765
- package/flow.js +0 -21
- package/flow.js.flow +0 -20
- package/fs.js +0 -95
- package/fs.js.flow +0 -96
- package/git.js +0 -35
- package/git.js.flow +0 -34
- package/hg.js +0 -35
- package/hg.js.flow +0 -34
- package/index.js +0 -27
- package/index.js.flow +0 -26
- package/inline-resources.js +0 -158
- package/inline-resources.js.flow +0 -157
- package/maps.js +0 -112
- package/maps.js.flow +0 -111
- package/npm.js +0 -145
- package/npm.js.flow +0 -144
- package/pkg.js +0 -81
- package/pkg.js.flow +0 -80
- package/publish.js +0 -145
- package/publish.js.flow +0 -144
- package/run.js +0 -90
- package/run.js.flow +0 -89
- package/src/artifactory.js +0 -616
- package/src/cert.conf +0 -20
- package/src/flow.js +0 -20
- package/src/hg.js +0 -34
- package/src/inline-resources.js +0 -157
- package/src/test.js +0 -55
- package/test.js +0 -56
- package/test.js.flow +0 -55
- package/tgz.js +0 -102
- package/tgz.js.flow +0 -101
- package/version.js +0 -143
- package/version.js.flow +0 -142
- package/yarn.js +0 -124
- package/yarn.js.flow +0 -123
package/src/docker.container.js
CHANGED
|
@@ -1,345 +1,212 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import bytes from 'bytes';
|
|
3
|
-
import throttle from 'lodash
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import { parseDockerDate } from './docker';
|
|
8
|
-
|
|
9
|
-
type DockerContainerInspectOutput = {
|
|
10
|
-
[string]: any,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type DockerContainer = {|
|
|
14
|
-
command: string,
|
|
15
|
-
created: Date,
|
|
16
|
-
id: string,
|
|
17
|
-
image: string,
|
|
18
|
-
labels: string[],
|
|
19
|
-
mounts: string[],
|
|
20
|
-
name: string,
|
|
21
|
-
names: string[],
|
|
22
|
-
networks: string[],
|
|
23
|
-
ports: Array<{ iface: string, sourcePort: number, destPort: number }>,
|
|
24
|
-
runningFor: string,
|
|
25
|
-
size: string,
|
|
26
|
-
status: string,
|
|
27
|
-
exited: boolean,
|
|
28
|
-
inspect: () => Promise<DockerContainerInspectOutput>,
|
|
29
|
-
exists: () => Promise<boolean>,
|
|
30
|
-
isRunning: () => Promise<boolean>,
|
|
31
|
-
start: () => Promise<void>,
|
|
32
|
-
stop: (ignoreError?: boolean) => Promise<void>,
|
|
33
|
-
kill: (ignoreError?: boolean) => Promise<void>,
|
|
34
|
-
restart: () => Promise<void>,
|
|
35
|
-
rm: (ignoreError?: boolean) => Promise<void>,
|
|
36
|
-
teardown: (verbose?: boolean) => Promise<void>,
|
|
37
|
-
|};
|
|
38
|
-
|
|
39
|
-
type DockerContainerLsOptions = {
|
|
40
|
-
all?: boolean,
|
|
41
|
-
filter?: (container: DockerContainer) => boolean,
|
|
42
|
-
};
|
|
43
|
-
|
|
2
|
+
import { throttle } from 'lodash-es';
|
|
3
|
+
import { spawn } from './cp.js';
|
|
4
|
+
import { parseDockerDate } from './docker.js';
|
|
5
|
+
import { buildLog } from './run.js';
|
|
44
6
|
// calling this function in rapid succession can lead to errors.
|
|
45
7
|
// prefer throttled version
|
|
46
|
-
export async function
|
|
47
|
-
|
|
48
|
-
filter,
|
|
49
|
-
}: DockerContainerLsOptions = {}): Promise<DockerContainer[]> {
|
|
50
|
-
return (
|
|
51
|
-
await spawn(
|
|
52
|
-
'docker',
|
|
53
|
-
[
|
|
8
|
+
export async function unthrottledDockerContainerLs({ all, filter, } = {}) {
|
|
9
|
+
return (await spawn('docker', [
|
|
54
10
|
'container',
|
|
55
11
|
'ls',
|
|
56
12
|
...(all ? ['--all'] : []),
|
|
57
13
|
'--no-trunc',
|
|
58
14
|
'--format',
|
|
59
15
|
'{{json .}}',
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
log(`Killing container: <${this.name}>...`);
|
|
144
|
-
await this.kill(false);
|
|
145
|
-
log(`<${this.name}> container killed.`);
|
|
146
|
-
} catch (e2) {
|
|
147
|
-
log(`Failed to kill <${this.name}> container: ${e2.message}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
} else {
|
|
151
|
-
log(`<${this.name}> container not running, skipping stop.`);
|
|
152
|
-
}
|
|
153
|
-
if (await this.exists()) {
|
|
154
|
-
await this.rm(true);
|
|
155
|
-
} else {
|
|
156
|
-
log(`<${this.name}> container does not exist, skipping rm.`);
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
};
|
|
16
|
+
], { captureOutput: true })).output
|
|
17
|
+
.split('\n')
|
|
18
|
+
.filter((line) => !!line.trim())
|
|
19
|
+
.map((line) => {
|
|
20
|
+
const { Command: command, CreatedAt, ID: id, Image: image, Labels, Mounts, Names, Networks, Ports, RunningFor: runningFor, Size, Status: status, } = JSON.parse(line.trim());
|
|
21
|
+
const names = Names.split(',').map((n) => n.trim());
|
|
22
|
+
const [name] = names;
|
|
23
|
+
return {
|
|
24
|
+
command,
|
|
25
|
+
created: parseDockerDate(CreatedAt),
|
|
26
|
+
async exists() {
|
|
27
|
+
try {
|
|
28
|
+
return !!(await this.inspect());
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
exited: /^Exited/.test(status),
|
|
35
|
+
id,
|
|
36
|
+
image,
|
|
37
|
+
inspect: async () => (await dockerContainerInspect(id))?.[0],
|
|
38
|
+
async isRunning() {
|
|
39
|
+
try {
|
|
40
|
+
return (await this.inspect())?.State?.Running || false;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
kill: async (ignoreError = true) => dockerContainerKill(id, ignoreError),
|
|
47
|
+
labels: Labels.split(',').map((l) => l.trim()),
|
|
48
|
+
mounts: Mounts.split(',').map((m) => m.trim()),
|
|
49
|
+
name,
|
|
50
|
+
names,
|
|
51
|
+
networks: Networks.split(',').map((n) => n.trim()),
|
|
52
|
+
ports: Ports.split(',').map((p) => {
|
|
53
|
+
const [, iface, src, dest] = p.match(/^([^:]+):(\d+)-\\u003e(\d+)/i) || [];
|
|
54
|
+
return {
|
|
55
|
+
dest: parseInt(dest, 10),
|
|
56
|
+
iface,
|
|
57
|
+
src: parseInt(src, 10),
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
restart: async () => dockerContainerRestart(id),
|
|
61
|
+
rm: async (ignoreError = true) => dockerContainerRm(id, ignoreError),
|
|
62
|
+
runningFor,
|
|
63
|
+
size: bytes.parse(Size),
|
|
64
|
+
start: async () => dockerContainerStart(id),
|
|
65
|
+
status,
|
|
66
|
+
stop: async (ignoreError = true) => dockerContainerStop(id, ignoreError),
|
|
67
|
+
async teardown(verbose = true) {
|
|
68
|
+
const log = (msg) => verbose && buildLog(msg);
|
|
69
|
+
if (await this.isRunning()) {
|
|
70
|
+
try {
|
|
71
|
+
log(`Stopping container: <${this.name}>...`);
|
|
72
|
+
await this.stop(false);
|
|
73
|
+
log(`<${this.name}> container stopped.`);
|
|
74
|
+
}
|
|
75
|
+
catch (e1) {
|
|
76
|
+
log(`Failed to stop <${this.name}> container: ${e1.message}`);
|
|
77
|
+
try {
|
|
78
|
+
log(`Killing container: <${this.name}>...`);
|
|
79
|
+
await this.kill(false);
|
|
80
|
+
log(`<${this.name}> container killed.`);
|
|
81
|
+
}
|
|
82
|
+
catch (e2) {
|
|
83
|
+
log(`Failed to kill <${this.name}> container: ${e2.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
log(`<${this.name}> container not running, skipping stop.`);
|
|
89
|
+
}
|
|
90
|
+
if (await this.exists()) {
|
|
91
|
+
await this.rm(true);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
log(`<${this.name}> container does not exist, skipping rm.`);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
160
98
|
})
|
|
161
|
-
|
|
99
|
+
.filter((c) => c.id && (typeof filter === 'function' ? filter(c) : true));
|
|
162
100
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
DockerContainerLsOptions | void,
|
|
166
|
-
) => Promise<DockerContainer[]> = throttle(_dockerContainerLs, 500, {
|
|
167
|
-
trailing: false,
|
|
101
|
+
export const dockerContainerLs = throttle(unthrottledDockerContainerLs, 500, {
|
|
102
|
+
trailing: false,
|
|
168
103
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
search: string,
|
|
172
|
-
options?: DockerContainerLsOptions,
|
|
173
|
-
): Promise<?DockerContainer> {
|
|
174
|
-
return (
|
|
175
|
-
(await dockerContainerLs(options)).find(
|
|
176
|
-
(c) =>
|
|
177
|
-
c.name === search ||
|
|
104
|
+
export async function dockerContainerFind(search, options) {
|
|
105
|
+
return ((await dockerContainerLs(options))?.find((c) => c.name === search ||
|
|
178
106
|
c.id.startsWith(search) ||
|
|
179
|
-
c.names.includes(search)
|
|
180
|
-
) || null
|
|
181
|
-
);
|
|
107
|
+
c.names.includes(search)) || null);
|
|
182
108
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
) {
|
|
188
|
-
const ids = Array.isArray(id) ? id : [id];
|
|
189
|
-
try {
|
|
190
|
-
await spawn('docker', ['container', 'stop', ...ids]);
|
|
191
|
-
} catch (e) {
|
|
192
|
-
if (!ignoreErrors) {
|
|
193
|
-
throw new Error(`Failed to stop container(s): ${e.message}`);
|
|
109
|
+
export async function dockerContainerStop(id, ignoreErrors = true) {
|
|
110
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
111
|
+
try {
|
|
112
|
+
await spawn('docker', ['container', 'stop', ...ids]);
|
|
194
113
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
id: string | string[],
|
|
200
|
-
ignoreErrors: boolean = true,
|
|
201
|
-
) {
|
|
202
|
-
const ids = Array.isArray(id) ? id : [id];
|
|
203
|
-
try {
|
|
204
|
-
await spawn('docker', ['container', 'kill', ...ids]);
|
|
205
|
-
} catch (e) {
|
|
206
|
-
if (!ignoreErrors) {
|
|
207
|
-
throw new Error(`Failed to kill container(s): ${e.message}`);
|
|
114
|
+
catch (e) {
|
|
115
|
+
if (!ignoreErrors) {
|
|
116
|
+
throw new Error(`Failed to stop container(s): ${e.message}`);
|
|
117
|
+
}
|
|
208
118
|
}
|
|
209
|
-
}
|
|
210
119
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (id) {
|
|
120
|
+
export async function dockerContainerKill(id, ignoreErrors = true) {
|
|
121
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
214
122
|
try {
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
123
|
+
await spawn('docker', ['container', 'kill', ...ids]);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
if (!ignoreErrors) {
|
|
127
|
+
throw new Error(`Failed to kill container(s): ${e.message}`);
|
|
128
|
+
}
|
|
218
129
|
}
|
|
219
|
-
}
|
|
220
130
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
} catch (e) {
|
|
230
|
-
if (ignoreErrors) {
|
|
231
|
-
buildLog(
|
|
232
|
-
`Warning (ignored Error): Failed to remove container(s): ${e.message}`,
|
|
233
|
-
);
|
|
234
|
-
} else {
|
|
235
|
-
throw new Error(`Failed to remove container(s): ${e.message}`);
|
|
131
|
+
export async function dockerTryStopContainer(id, name = '') {
|
|
132
|
+
if (id) {
|
|
133
|
+
try {
|
|
134
|
+
await dockerContainerStop(id, false);
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
buildLog(`Failed to stop ${name} container: ${e.message}`);
|
|
138
|
+
}
|
|
236
139
|
}
|
|
237
|
-
}
|
|
238
140
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
141
|
+
export async function dockerContainerRm(id, ignoreErrors = true) {
|
|
142
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
143
|
+
try {
|
|
144
|
+
await spawn('docker', ['container', 'rm', ...ids]);
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (ignoreErrors) {
|
|
148
|
+
buildLog(`Warning (ignored Error): Failed to remove container(s): ${e.message}`);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
throw new Error(`Failed to remove container(s): ${e.message}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export async function dockerContainerRestart(id) {
|
|
156
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
157
|
+
await spawn('docker', ['container', 'restart', ...ids]);
|
|
243
158
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
await spawn('docker', ['container', 'start', ...ids]);
|
|
159
|
+
export async function dockerContainerStart(id) {
|
|
160
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
161
|
+
await spawn('docker', ['container', 'start', ...ids]);
|
|
248
162
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
(
|
|
256
|
-
await spawn(
|
|
257
|
-
'docker',
|
|
258
|
-
['container', 'inspect', '--format', '{{json .}}', ...ids],
|
|
259
|
-
{ captureOutput: true },
|
|
260
|
-
)
|
|
261
|
-
)
|
|
262
|
-
.split('\n')
|
|
263
|
-
.filter((line) => !!line.trim())
|
|
264
|
-
.map((line) => JSON.parse(line.trim())) || []
|
|
265
|
-
);
|
|
163
|
+
export async function unthrottledDockerContainerInspect(id) {
|
|
164
|
+
const ids = Array.isArray(id) ? id : [id];
|
|
165
|
+
return ((await spawn('docker', ['container', 'inspect', '--format', '{{json .}}', ...ids], { captureOutput: true })).output
|
|
166
|
+
.split('\n')
|
|
167
|
+
.filter((line) => !!line.trim())
|
|
168
|
+
.map((line) => JSON.parse(line.trim())) || []);
|
|
266
169
|
}
|
|
267
|
-
export const dockerContainerInspect
|
|
268
|
-
string | string[],
|
|
269
|
-
) => Promise<DockerContainerInspectOutput[]> = throttle(
|
|
270
|
-
_dockerContainerInspect,
|
|
271
|
-
500,
|
|
272
|
-
{
|
|
170
|
+
export const dockerContainerInspect = throttle(unthrottledDockerContainerInspect, 500, {
|
|
273
171
|
trailing: false,
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
waitAttempts?: number,
|
|
282
|
-
waitDuration?: number,
|
|
283
|
-
|};
|
|
284
|
-
|
|
285
|
-
type DockerContainerRunArgs = {|
|
|
286
|
-
...DockerContainerRunDaemonArgs,
|
|
287
|
-
spawnOptions?: ?SpawnOptions,
|
|
288
|
-
|};
|
|
289
|
-
|
|
290
|
-
export async function dockerContainerRun({
|
|
291
|
-
image,
|
|
292
|
-
runArgs = [],
|
|
293
|
-
cmd = [],
|
|
294
|
-
spawnOptions,
|
|
295
|
-
}: DockerContainerRunArgs): Promise<string> {
|
|
296
|
-
return spawn('docker', ['container', 'run', ...runArgs, image, ...cmd], {
|
|
297
|
-
stdio: 'inherit',
|
|
298
|
-
pipeOutput: true,
|
|
299
|
-
...spawnOptions,
|
|
300
|
-
});
|
|
172
|
+
});
|
|
173
|
+
export async function dockerContainerRun({ image, runArgs = [], cmd = [], spawnOptions, }) {
|
|
174
|
+
return (await spawn('docker', ['container', 'run', ...runArgs, image, ...cmd], {
|
|
175
|
+
pipeOutput: true,
|
|
176
|
+
stdio: 'inherit',
|
|
177
|
+
...spawnOptions,
|
|
178
|
+
})).output;
|
|
301
179
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
container = await dockerContainerFind(id);
|
|
330
|
-
attempts += 1;
|
|
331
|
-
}
|
|
332
|
-
/* eslint-enable no-await-in-loop */
|
|
333
|
-
|
|
334
|
-
if (!container) {
|
|
335
|
-
throw new Error(`Failed to find newly created container: ${id}`);
|
|
336
|
-
}
|
|
337
|
-
return container;
|
|
180
|
+
export async function dockerContainerRunDaemon({ image, runArgs = [], cmd = [], waitAttempts = 10, waitDuration = 501, }) {
|
|
181
|
+
const id = (await dockerContainerRun({
|
|
182
|
+
cmd,
|
|
183
|
+
image,
|
|
184
|
+
runArgs: ['-d', ...runArgs],
|
|
185
|
+
spawnOptions: {
|
|
186
|
+
captureOutput: true,
|
|
187
|
+
pipeOutput: false,
|
|
188
|
+
stdio: 'pipe',
|
|
189
|
+
},
|
|
190
|
+
})).trim();
|
|
191
|
+
let container = await dockerContainerFind(id);
|
|
192
|
+
let attempts = 0;
|
|
193
|
+
// containers don't always show up in the list right away
|
|
194
|
+
/* eslint-disable no-await-in-loop */
|
|
195
|
+
while (!container && attempts < waitAttempts) {
|
|
196
|
+
await new Promise((resolve) => {
|
|
197
|
+
setTimeout(resolve, waitDuration);
|
|
198
|
+
});
|
|
199
|
+
container = await dockerContainerFind(id);
|
|
200
|
+
attempts += 1;
|
|
201
|
+
}
|
|
202
|
+
/* eslint-enable no-await-in-loop */
|
|
203
|
+
if (!container) {
|
|
204
|
+
throw new Error(`Failed to find newly created container: ${id}`);
|
|
205
|
+
}
|
|
206
|
+
return container;
|
|
338
207
|
}
|
|
339
|
-
|
|
340
208
|
const indicators = ['.', ':', '*', '+', '-', '=', '%', '$', '@', '^', '&'];
|
|
341
209
|
let curIndicator = 0;
|
|
342
|
-
|
|
343
210
|
/**
|
|
344
211
|
* Waits for the given container to be fully started. Checks that the container is
|
|
345
212
|
* running, and test with the provided testFn every second until it returns true.
|
|
@@ -348,42 +215,33 @@ let curIndicator = 0;
|
|
|
348
215
|
* @param {number} timeoutMs The amount of time to wait between attempts.
|
|
349
216
|
* @param {number} maxAttempts The maximum number of attempts before giving up (rejects promise)
|
|
350
217
|
*/
|
|
351
|
-
export const dockerContainerWaitForStart = async (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
? check(tries + 1)
|
|
381
|
-
: reject(
|
|
382
|
-
new Error(`Timeout waiting for '${name}' container to start.`),
|
|
383
|
-
);
|
|
384
|
-
}, timeoutMs);
|
|
385
|
-
};
|
|
386
|
-
check();
|
|
387
|
-
});
|
|
388
|
-
process.stdout.write('\n');
|
|
218
|
+
export const dockerContainerWaitForStart = async (container, testFn, timeoutMs = 1000, maxAttempts = 1200) => {
|
|
219
|
+
// claim an indicator
|
|
220
|
+
const indicator = indicators[curIndicator] || '.';
|
|
221
|
+
curIndicator = (curIndicator + 1) % indicators.length;
|
|
222
|
+
const { name } = container;
|
|
223
|
+
buildLog(`Waiting for ${name} to fully start... ${indicator}`);
|
|
224
|
+
await new Promise((resolve, reject) => {
|
|
225
|
+
const check = (tries = 0) => {
|
|
226
|
+
process.stdout.write(indicator);
|
|
227
|
+
setTimeout(async () => {
|
|
228
|
+
try {
|
|
229
|
+
if (!(await container.isRunning())) {
|
|
230
|
+
return reject(new Error(`The '${name}' container is no longer running.`));
|
|
231
|
+
}
|
|
232
|
+
if (await testFn(container)) {
|
|
233
|
+
return resolve();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
// ignore
|
|
238
|
+
}
|
|
239
|
+
return tries < maxAttempts
|
|
240
|
+
? check(tries + 1)
|
|
241
|
+
: reject(new Error(`Timeout waiting for '${name}' container to start.`));
|
|
242
|
+
}, timeoutMs);
|
|
243
|
+
};
|
|
244
|
+
check();
|
|
245
|
+
});
|
|
246
|
+
process.stdout.write('\n');
|
|
389
247
|
};
|
package/src/docker.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface DockerConfig {
|
|
2
|
+
name?: string;
|
|
3
|
+
registry?: string;
|
|
4
|
+
repository?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getDockerConfig(): DockerConfig;
|
|
7
|
+
export declare const parseDockerDate: (date: string) => Date;
|
|
8
|
+
export declare function dockerBuild(tags?: string[], buildArgs?: string[], target?: string | null, extraArgs?: string[], repo?: string, dockerFile?: string, workDir?: string): Promise<string>;
|
|
9
|
+
export declare function dockerTag(imageId: string, tags?: string[], repo?: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Apply the standard convention for tagging the docker image for the project,
|
|
12
|
+
* based on the source control branch being built.
|
|
13
|
+
* For releases, applies `latest`, `M.m.p`, `M.m`, `M`
|
|
14
|
+
* For release candidates, applies `latest-rc`
|
|
15
|
+
* For feature branches, applies `latest-feature`
|
|
16
|
+
* For development branch, applies `latest-dev`
|
|
17
|
+
* All other branches, no tag is applies
|
|
18
|
+
* @param {string} imageId id of the docker image to which to apply the tags
|
|
19
|
+
* @param {string} repo optional override of the docker repo url to use (derived from package.json by default)
|
|
20
|
+
*/
|
|
21
|
+
export declare function dockerTagVersion(imageId: string, repo?: string): Promise<void>;
|
|
22
|
+
export interface DockerImage {
|
|
23
|
+
created: Date;
|
|
24
|
+
digest: string;
|
|
25
|
+
id: string;
|
|
26
|
+
repository: string;
|
|
27
|
+
size: number;
|
|
28
|
+
tag: string;
|
|
29
|
+
}
|
|
30
|
+
export declare type DockerImageFilter = (i: DockerImage) => boolean;
|
|
31
|
+
export declare function dockerImages(repo?: null | string, filter?: null | DockerImageFilter): Promise<DockerImage[]>;
|
|
32
|
+
export declare function getDockerId(tag?: string, repo?: null | string): Promise<string>;
|
|
33
|
+
export declare function getUntaggedDockerIds(repo?: string, filter?: null | DockerImageFilter): Promise<string[]>;
|
|
34
|
+
export declare function getDockerTags(id?: null | string, repo?: null | string, fullName?: boolean, filter?: null | DockerImageFilter): Promise<string[]>;
|
|
35
|
+
export declare function getDockerDigest(imageId: string, repo?: string): Promise<string>;
|
|
36
|
+
interface DockerLoginOptions {
|
|
37
|
+
password?: string;
|
|
38
|
+
registry?: string;
|
|
39
|
+
user?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function dockerLogin({ password, registry, user, }?: DockerLoginOptions): Promise<void>;
|
|
42
|
+
export declare function dockerPush(tags?: string[], repo?: string): Promise<void>;
|
|
43
|
+
export interface DockerPullOptions {
|
|
44
|
+
image: string;
|
|
45
|
+
offline?: boolean;
|
|
46
|
+
testUrl?: string | null;
|
|
47
|
+
}
|
|
48
|
+
export declare function dockerPull({ image, offline, testUrl, }: DockerPullOptions): Promise<void>;
|
|
49
|
+
export declare function dockerRmi(images?: string[], ignoreErrors?: boolean): Promise<void>;
|
|
50
|
+
export declare function getDockerRepo(): string;
|
|
51
|
+
export interface PullAndRunContainerOptions extends DockerPullOptions {
|
|
52
|
+
alias?: string | null;
|
|
53
|
+
cmd?: string[];
|
|
54
|
+
network?: string | null;
|
|
55
|
+
runArgs?: string[];
|
|
56
|
+
}
|
|
57
|
+
export declare function dockerPullAndRunContainer(options: PullAndRunContainerOptions): Promise<string>;
|
|
58
|
+
export interface CopyFilePathConfig {
|
|
59
|
+
from: string;
|
|
60
|
+
to: string;
|
|
61
|
+
}
|
|
62
|
+
export interface CopyFilesFromDockerImageConfig {
|
|
63
|
+
filePaths: CopyFilePathConfig[];
|
|
64
|
+
ignoreErrors?: boolean;
|
|
65
|
+
imageId: string;
|
|
66
|
+
}
|
|
67
|
+
export declare function copyFilesFromDockerImage({ filePaths, ignoreErrors, imageId, }: CopyFilesFromDockerImageConfig): Promise<any>;
|
|
68
|
+
export {};
|