@docker/actions-toolkit 0.21.1 → 0.22.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.
Files changed (48) hide show
  1. package/lib/buildkit/buildkit.js +72 -59
  2. package/lib/buildkit/buildkit.js.map +1 -1
  3. package/lib/buildx/bake.d.ts +4 -1
  4. package/lib/buildx/bake.js +103 -59
  5. package/lib/buildx/bake.js.map +1 -1
  6. package/lib/buildx/{inputs.d.ts → build.d.ts} +12 -9
  7. package/lib/buildx/{inputs.js → build.js} +46 -37
  8. package/lib/buildx/build.js.map +1 -0
  9. package/lib/buildx/builder.d.ts +1 -1
  10. package/lib/buildx/builder.js +50 -34
  11. package/lib/buildx/builder.js.map +1 -1
  12. package/lib/buildx/buildx.d.ts +4 -2
  13. package/lib/buildx/buildx.js +124 -65
  14. package/lib/buildx/buildx.js.map +1 -1
  15. package/lib/buildx/install.js +210 -182
  16. package/lib/buildx/install.js.map +1 -1
  17. package/lib/cache.js +68 -58
  18. package/lib/cache.js.map +1 -1
  19. package/lib/context.js +1 -1
  20. package/lib/context.js.map +1 -1
  21. package/lib/docker/docker.js +94 -72
  22. package/lib/docker/docker.js.map +1 -1
  23. package/lib/docker/install.js +347 -321
  24. package/lib/docker/install.js.map +1 -1
  25. package/lib/dockerhub.js +91 -70
  26. package/lib/dockerhub.js.map +1 -1
  27. package/lib/exec.js +19 -6
  28. package/lib/exec.js.map +1 -1
  29. package/lib/git.js +132 -101
  30. package/lib/git.js.map +1 -1
  31. package/lib/github.d.ts +2 -1
  32. package/lib/github.js +134 -35
  33. package/lib/github.js.map +1 -1
  34. package/lib/index.js +26 -15
  35. package/lib/index.js.map +1 -1
  36. package/lib/toolkit.js +0 -6
  37. package/lib/toolkit.js.map +1 -1
  38. package/lib/types/bake.d.ts +3 -0
  39. package/lib/types/build.d.ts +18 -0
  40. package/lib/types/build.js +18 -0
  41. package/lib/types/build.js.map +1 -0
  42. package/lib/types/buildx.d.ts +15 -0
  43. package/lib/types/github.d.ts +11 -0
  44. package/lib/util.d.ts +1 -0
  45. package/lib/util.js +41 -20
  46. package/lib/util.js.map +1 -1
  47. package/package.json +3 -1
  48. package/lib/buildx/inputs.js.map +0 -1
@@ -37,6 +37,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
37
37
  __setModuleDefault(result, mod);
38
38
  return result;
39
39
  };
40
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
41
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
42
+ return new (P || (P = Promise))(function (resolve, reject) {
43
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
44
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
45
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
46
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
47
+ });
48
+ };
40
49
  var __importDefault = (this && this.__importDefault) || function (mod) {
41
50
  return (mod && mod.__esModule) ? mod : { "default": mod };
42
51
  };
@@ -59,15 +68,8 @@ const exec_1 = require("../exec");
59
68
  const util_1 = require("../util");
60
69
  const assets_1 = require("./assets");
61
70
  class Install {
62
- runDir;
63
- version;
64
- channel;
65
- contextName;
66
- daemonConfig;
67
- _version;
68
- _toolDir;
69
- limaInstanceName = 'docker-actions-toolkit';
70
71
  constructor(opts) {
72
+ this.limaInstanceName = 'docker-actions-toolkit';
71
73
  this.runDir = opts.runDir;
72
74
  this.version = opts.version || 'latest';
73
75
  this.channel = opts.channel || 'stable';
@@ -77,314 +79,332 @@ class Install {
77
79
  get toolDir() {
78
80
  return this._toolDir || context_1.Context.tmpDir();
79
81
  }
80
- async download() {
81
- const release = await Install.getRelease(this.version);
82
- this._version = release.tag_name.replace(/^v+|v+$/g, '');
83
- core.debug(`docker.Install.download version: ${this._version}`);
84
- const downloadURL = this.downloadURL(this._version, this.channel);
85
- core.info(`Downloading ${downloadURL}`);
86
- const downloadPath = await tc.downloadTool(downloadURL);
87
- core.debug(`docker.Install.download downloadPath: ${downloadPath}`);
88
- let extractFolder;
89
- if (os_1.default.platform() == 'win32') {
90
- extractFolder = await tc.extractZip(downloadPath);
91
- }
92
- else {
93
- extractFolder = await tc.extractTar(downloadPath);
94
- }
95
- if (util_1.Util.isDirectory(path_1.default.join(extractFolder, 'docker'))) {
96
- extractFolder = path_1.default.join(extractFolder, 'docker');
97
- }
98
- core.debug(`docker.Install.download extractFolder: ${extractFolder}`);
99
- core.info('Fixing perms');
100
- fs_1.default.readdir(path_1.default.join(extractFolder), function (err, files) {
101
- if (err) {
102
- throw err;
103
- }
104
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
105
- files.forEach(function (file, index) {
106
- fs_1.default.chmodSync(path_1.default.join(extractFolder, file), '0755');
107
- });
108
- });
109
- const tooldir = await tc.cacheDir(extractFolder, `docker-${this.channel}`, this._version.replace(/(0+)([1-9]+)/, '$2'));
110
- core.addPath(tooldir);
111
- core.info('Added Docker to PATH');
112
- this._toolDir = tooldir;
113
- return tooldir;
114
- }
115
- async install() {
116
- if (!this.toolDir) {
117
- throw new Error('toolDir must be set. Run download first.');
118
- }
119
- if (!this.runDir) {
120
- throw new Error('runDir must be set');
121
- }
122
- switch (os_1.default.platform()) {
123
- case 'darwin': {
124
- return await this.installDarwin();
125
- }
126
- case 'linux': {
127
- return await this.installLinux();
128
- }
129
- case 'win32': {
130
- return await this.installWindows();
82
+ download() {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ const release = yield Install.getRelease(this.version);
85
+ this._version = release.tag_name.replace(/^v+|v+$/g, '');
86
+ core.debug(`docker.Install.download version: ${this._version}`);
87
+ const downloadURL = this.downloadURL(this._version, this.channel);
88
+ core.info(`Downloading ${downloadURL}`);
89
+ const downloadPath = yield tc.downloadTool(downloadURL);
90
+ core.debug(`docker.Install.download downloadPath: ${downloadPath}`);
91
+ let extractFolder;
92
+ if (os_1.default.platform() == 'win32') {
93
+ extractFolder = yield tc.extractZip(downloadPath);
131
94
  }
132
- default: {
133
- throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
95
+ else {
96
+ extractFolder = yield tc.extractTar(downloadPath);
134
97
  }
135
- }
136
- }
137
- async installDarwin() {
138
- const limaDir = path_1.default.join(os_1.default.homedir(), '.lima', this.limaInstanceName);
139
- await io.mkdirP(limaDir);
140
- const dockerHost = `unix://${limaDir}/docker.sock`;
141
- // avoid brew to auto update and upgrade unrelated packages.
142
- let envs = Object.assign({}, process.env, {
143
- HOMEBREW_NO_AUTO_UPDATE: '1',
144
- HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: '1'
145
- });
146
- if (!(await Install.limaInstalled())) {
147
- await core.group('Installing lima', async () => {
148
- await exec_1.Exec.exec('brew', ['install', 'lima'], { env: envs });
149
- });
150
- }
151
- await core.group('Lima version', async () => {
152
- await exec_1.Exec.exec('lima', ['--version'], { env: envs });
153
- });
154
- await core.group('Creating lima config', async () => {
155
- let limaDaemonConfig = {};
156
- if (this.daemonConfig) {
157
- limaDaemonConfig = JSON.parse(this.daemonConfig);
98
+ if (util_1.Util.isDirectory(path_1.default.join(extractFolder, 'docker'))) {
99
+ extractFolder = path_1.default.join(extractFolder, 'docker');
158
100
  }
159
- handlebars.registerHelper('stringify', function (obj) {
160
- return new handlebars.SafeString(JSON.stringify(obj));
161
- });
162
- const limaCfg = handlebars.compile(assets_1.limaYamlData)({
163
- customImages: Install.limaCustomImages(),
164
- daemonConfig: limaDaemonConfig,
165
- dockerSock: `${limaDir}/docker.sock`,
166
- dockerBinVersion: this._version,
167
- dockerBinChannel: this.channel
101
+ core.debug(`docker.Install.download extractFolder: ${extractFolder}`);
102
+ core.info('Fixing perms');
103
+ fs_1.default.readdir(path_1.default.join(extractFolder), function (err, files) {
104
+ if (err) {
105
+ throw err;
106
+ }
107
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
108
+ files.forEach(function (file, index) {
109
+ fs_1.default.chmodSync(path_1.default.join(extractFolder, file), '0755');
110
+ });
168
111
  });
169
- core.info(`Writing lima config to ${path_1.default.join(limaDir, 'lima.yaml')}`);
170
- fs_1.default.writeFileSync(path_1.default.join(limaDir, 'lima.yaml'), limaCfg);
171
- core.info(limaCfg);
112
+ const tooldir = yield tc.cacheDir(extractFolder, `docker-${this.channel}`, this._version.replace(/(0+)([1-9]+)/, '$2'));
113
+ core.addPath(tooldir);
114
+ core.info('Added Docker to PATH');
115
+ this._toolDir = tooldir;
116
+ return tooldir;
172
117
  });
173
- const qemuArch = await Install.qemuArch();
174
- await core.group('QEMU version', async () => {
175
- await exec_1.Exec.exec(`qemu-system-${qemuArch} --version`);
176
- });
177
- // lima might already be started on the runner so env var added in download
178
- // method is not expanded to the running process.
179
- envs = Object.assign({}, envs, {
180
- PATH: `${this.toolDir}:${process.env.PATH}`
181
- });
182
- await core.group('Starting lima instance', async () => {
183
- const limaStartArgs = ['start', `--name=${this.limaInstanceName}`];
184
- if (process.env.LIMA_START_ARGS) {
185
- limaStartArgs.push(process.env.LIMA_START_ARGS);
118
+ }
119
+ install() {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ if (!this.toolDir) {
122
+ throw new Error('toolDir must be set. Run download first.');
186
123
  }
187
- try {
188
- await exec_1.Exec.exec(`limactl ${limaStartArgs.join(' ')}`, [], { env: envs });
124
+ if (!this.runDir) {
125
+ throw new Error('runDir must be set');
189
126
  }
190
- catch (e) {
191
- promises_1.default
192
- .readdir(limaDir)
193
- .then(files => {
194
- files
195
- .filter(f => path_1.default.extname(f) === '.log')
196
- .forEach(f => {
197
- const logfile = path_1.default.join(limaDir, f);
198
- const logcontent = fs_1.default.readFileSync(logfile, { encoding: 'utf8' }).trim();
199
- if (logcontent.length > 0) {
200
- core.info(`### ${logfile}:\n${logcontent}`);
201
- }
202
- });
203
- })
204
- .catch(() => {
205
- // ignore
206
- });
207
- throw e;
127
+ switch (os_1.default.platform()) {
128
+ case 'darwin': {
129
+ return yield this.installDarwin();
130
+ }
131
+ case 'linux': {
132
+ return yield this.installLinux();
133
+ }
134
+ case 'win32': {
135
+ return yield this.installWindows();
136
+ }
137
+ default: {
138
+ throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
139
+ }
208
140
  }
209
141
  });
210
- await core.group('Create Docker context', async () => {
211
- await exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
212
- await exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
213
- });
214
- return dockerHost;
215
142
  }
216
- async installLinux() {
217
- const dockerHost = `unix://${path_1.default.join(this.runDir, 'docker.sock')}`;
218
- await io.mkdirP(this.runDir);
219
- const daemonConfigPath = path_1.default.join(this.runDir, 'daemon.json');
220
- await fs_1.default.writeFileSync(daemonConfigPath, '{}');
221
- let daemonConfig = undefined;
222
- const daemonConfigDefaultPath = '/etc/docker/daemon.json';
223
- if (fs_1.default.existsSync(daemonConfigDefaultPath)) {
224
- await core.group('Default Docker daemon config found', async () => {
225
- core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' })), null, 2));
143
+ installDarwin() {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ const limaDir = path_1.default.join(os_1.default.homedir(), '.lima', this.limaInstanceName);
146
+ yield io.mkdirP(limaDir);
147
+ const dockerHost = `unix://${limaDir}/docker.sock`;
148
+ // avoid brew to auto update and upgrade unrelated packages.
149
+ let envs = Object.assign({}, process.env, {
150
+ HOMEBREW_NO_AUTO_UPDATE: '1',
151
+ HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: '1'
226
152
  });
227
- daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' }));
228
- }
229
- if (this.daemonConfig) {
230
- daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
231
- }
232
- if (daemonConfig) {
233
- const daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
234
- await core.group('Writing Docker daemon config', async () => {
235
- fs_1.default.writeFileSync(daemonConfigPath, daemonConfigStr);
236
- core.info(daemonConfigStr);
237
- });
238
- }
239
- await core.group('Start Docker daemon', async () => {
240
- const bashPath = await io.which('bash', true);
241
- const cmd = `${this.toolDir}/dockerd --host="${dockerHost}" --config-file="${daemonConfigPath}" --exec-root="${this.runDir}/execroot" --data-root="${this.runDir}/data" --pidfile="${this.runDir}/docker.pid" --userland-proxy=false`;
242
- core.info(`[command] ${cmd}`); // https://github.com/actions/toolkit/blob/3d652d3133965f63309e4b2e1c8852cdbdcb3833/packages/exec/src/toolrunner.ts#L47
243
- const proc = await child_process.spawn(
244
- // We can't use Exec.exec here because we need to detach the process to
245
- // avoid killing it when the action finishes running. Even if detached,
246
- // we also need to run dockerd in a subshell and unref the process so
247
- // GitHub Action doesn't wait for it to finish.
248
- `sudo -E ${bashPath} << EOF
249
- ( ${cmd} 2>&1 | tee "${this.runDir}/dockerd.log" ) &
250
- EOF`, [], {
251
- detached: true,
252
- shell: true,
253
- stdio: ['ignore', process.stdout, process.stderr]
153
+ if (!(yield Install.limaInstalled())) {
154
+ yield core.group('Installing lima', () => __awaiter(this, void 0, void 0, function* () {
155
+ yield exec_1.Exec.exec('brew', ['install', 'lima'], { env: envs });
156
+ }));
157
+ }
158
+ yield core.group('Lima version', () => __awaiter(this, void 0, void 0, function* () {
159
+ yield exec_1.Exec.exec('lima', ['--version'], { env: envs });
160
+ }));
161
+ yield core.group('Creating lima config', () => __awaiter(this, void 0, void 0, function* () {
162
+ let limaDaemonConfig = {};
163
+ if (this.daemonConfig) {
164
+ limaDaemonConfig = JSON.parse(this.daemonConfig);
165
+ }
166
+ handlebars.registerHelper('stringify', function (obj) {
167
+ return new handlebars.SafeString(JSON.stringify(obj));
168
+ });
169
+ const limaCfg = handlebars.compile(assets_1.limaYamlData)({
170
+ customImages: Install.limaCustomImages(),
171
+ daemonConfig: limaDaemonConfig,
172
+ dockerSock: `${limaDir}/docker.sock`,
173
+ dockerBinVersion: this._version,
174
+ dockerBinChannel: this.channel
175
+ });
176
+ core.info(`Writing lima config to ${path_1.default.join(limaDir, 'lima.yaml')}`);
177
+ fs_1.default.writeFileSync(path_1.default.join(limaDir, 'lima.yaml'), limaCfg);
178
+ core.info(limaCfg);
179
+ }));
180
+ const qemuArch = yield Install.qemuArch();
181
+ yield core.group('QEMU version', () => __awaiter(this, void 0, void 0, function* () {
182
+ yield exec_1.Exec.exec(`qemu-system-${qemuArch} --version`);
183
+ }));
184
+ // lima might already be started on the runner so env var added in download
185
+ // method is not expanded to the running process.
186
+ envs = Object.assign({}, envs, {
187
+ PATH: `${this.toolDir}:${process.env.PATH}`
254
188
  });
255
- proc.unref();
256
- await util_1.Util.sleep(3);
257
- const retries = 10;
258
- await (0, async_retry_1.default)(async (bail) => {
189
+ yield core.group('Starting lima instance', () => __awaiter(this, void 0, void 0, function* () {
190
+ const limaStartArgs = ['start', `--name=${this.limaInstanceName}`];
191
+ if (process.env.LIMA_START_ARGS) {
192
+ limaStartArgs.push(process.env.LIMA_START_ARGS);
193
+ }
259
194
  try {
260
- await exec_1.Exec.getExecOutput(`docker version`, undefined, {
261
- silent: true,
262
- env: Object.assign({}, process.env, {
263
- DOCKER_HOST: dockerHost
264
- })
265
- });
195
+ yield exec_1.Exec.exec(`limactl ${limaStartArgs.join(' ')}`, [], { env: envs });
266
196
  }
267
197
  catch (e) {
268
- bail(e);
269
- }
270
- }, {
271
- retries: retries,
272
- minTimeout: 1000,
273
- onRetry: (err, i) => {
274
- core.info(`${err}. Retrying (${i}/${retries})...`);
198
+ promises_1.default
199
+ .readdir(limaDir)
200
+ .then(files => {
201
+ files
202
+ .filter(f => path_1.default.extname(f) === '.log')
203
+ .forEach(f => {
204
+ const logfile = path_1.default.join(limaDir, f);
205
+ const logcontent = fs_1.default.readFileSync(logfile, { encoding: 'utf8' }).trim();
206
+ if (logcontent.length > 0) {
207
+ core.info(`### ${logfile}:\n${logcontent}`);
208
+ }
209
+ });
210
+ })
211
+ .catch(() => {
212
+ // ignore
213
+ });
214
+ throw e;
275
215
  }
276
- });
277
- core.info(`Docker daemon started started successfully`);
216
+ }));
217
+ yield core.group('Create Docker context', () => __awaiter(this, void 0, void 0, function* () {
218
+ yield exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
219
+ yield exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
220
+ }));
221
+ return dockerHost;
278
222
  });
279
- await core.group('Create Docker context', async () => {
280
- await exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
281
- await exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
282
- });
283
- return dockerHost;
284
223
  }
285
- async installWindows() {
286
- const dockerHost = 'npipe:////./pipe/setup_docker_action';
287
- let daemonConfig = undefined;
288
- const daemonConfigPath = path_1.default.join(this.runDir, 'daemon.json');
289
- if (fs_1.default.existsSync(daemonConfigPath)) {
290
- await core.group('Default Docker daemon config found', async () => {
291
- core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' })), null, 2));
292
- });
293
- daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' }));
294
- }
295
- if (this.daemonConfig) {
296
- daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
297
- }
298
- let daemonConfigStr = '{}';
299
- if (daemonConfig) {
300
- daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
301
- await core.group('Docker daemon config', async () => {
302
- core.info(daemonConfigStr);
303
- });
304
- }
305
- await core.group('Install Docker daemon service', async () => {
306
- const setupCmd = await util_1.Util.powershellCommand((0, assets_1.setupDockerWinPs1)(), {
307
- ToolDir: this.toolDir,
308
- RunDir: this.runDir,
309
- DockerHost: dockerHost,
310
- DaemonConfig: daemonConfigStr
311
- });
312
- await exec_1.Exec.exec(setupCmd.command, setupCmd.args);
313
- const logCmd = await util_1.Util.powershellCommand((0, assets_1.dockerServiceLogsPs1)());
314
- await exec_1.Exec.exec(logCmd.command, logCmd.args);
315
- });
316
- await core.group('Create Docker context', async () => {
317
- await exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
318
- await exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
224
+ installLinux() {
225
+ return __awaiter(this, void 0, void 0, function* () {
226
+ const dockerHost = `unix://${path_1.default.join(this.runDir, 'docker.sock')}`;
227
+ yield io.mkdirP(this.runDir);
228
+ const daemonConfigPath = path_1.default.join(this.runDir, 'daemon.json');
229
+ yield fs_1.default.writeFileSync(daemonConfigPath, '{}');
230
+ let daemonConfig = undefined;
231
+ const daemonConfigDefaultPath = '/etc/docker/daemon.json';
232
+ if (fs_1.default.existsSync(daemonConfigDefaultPath)) {
233
+ yield core.group('Default Docker daemon config found', () => __awaiter(this, void 0, void 0, function* () {
234
+ core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' })), null, 2));
235
+ }));
236
+ daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' }));
237
+ }
238
+ if (this.daemonConfig) {
239
+ daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
240
+ }
241
+ if (daemonConfig) {
242
+ const daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
243
+ yield core.group('Writing Docker daemon config', () => __awaiter(this, void 0, void 0, function* () {
244
+ fs_1.default.writeFileSync(daemonConfigPath, daemonConfigStr);
245
+ core.info(daemonConfigStr);
246
+ }));
247
+ }
248
+ yield core.group('Start Docker daemon', () => __awaiter(this, void 0, void 0, function* () {
249
+ const bashPath = yield io.which('bash', true);
250
+ const cmd = `${this.toolDir}/dockerd --host="${dockerHost}" --config-file="${daemonConfigPath}" --exec-root="${this.runDir}/execroot" --data-root="${this.runDir}/data" --pidfile="${this.runDir}/docker.pid" --userland-proxy=false`;
251
+ core.info(`[command] ${cmd}`); // https://github.com/actions/toolkit/blob/3d652d3133965f63309e4b2e1c8852cdbdcb3833/packages/exec/src/toolrunner.ts#L47
252
+ const proc = yield child_process.spawn(
253
+ // We can't use Exec.exec here because we need to detach the process to
254
+ // avoid killing it when the action finishes running. Even if detached,
255
+ // we also need to run dockerd in a subshell and unref the process so
256
+ // GitHub Action doesn't wait for it to finish.
257
+ `sudo -E ${bashPath} << EOF
258
+ ( ${cmd} 2>&1 | tee "${this.runDir}/dockerd.log" ) &
259
+ EOF`, [], {
260
+ detached: true,
261
+ shell: true,
262
+ stdio: ['ignore', process.stdout, process.stderr]
263
+ });
264
+ proc.unref();
265
+ yield util_1.Util.sleep(3);
266
+ const retries = 10;
267
+ yield (0, async_retry_1.default)((bail) => __awaiter(this, void 0, void 0, function* () {
268
+ try {
269
+ yield exec_1.Exec.getExecOutput(`docker version`, undefined, {
270
+ silent: true,
271
+ env: Object.assign({}, process.env, {
272
+ DOCKER_HOST: dockerHost
273
+ })
274
+ });
275
+ }
276
+ catch (e) {
277
+ bail(e);
278
+ }
279
+ }), {
280
+ retries: retries,
281
+ minTimeout: 1000,
282
+ onRetry: (err, i) => {
283
+ core.info(`${err}. Retrying (${i}/${retries})...`);
284
+ }
285
+ });
286
+ core.info(`Docker daemon started started successfully`);
287
+ }));
288
+ yield core.group('Create Docker context', () => __awaiter(this, void 0, void 0, function* () {
289
+ yield exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
290
+ yield exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
291
+ }));
292
+ return dockerHost;
319
293
  });
320
- return dockerHost;
321
294
  }
322
- async tearDown() {
323
- if (!this.runDir) {
324
- throw new Error('runDir must be set');
325
- }
326
- switch (os_1.default.platform()) {
327
- case 'darwin': {
328
- await this.tearDownDarwin();
329
- break;
295
+ installWindows() {
296
+ return __awaiter(this, void 0, void 0, function* () {
297
+ const dockerHost = 'npipe:////./pipe/setup_docker_action';
298
+ let daemonConfig = undefined;
299
+ const daemonConfigPath = path_1.default.join(this.runDir, 'daemon.json');
300
+ if (fs_1.default.existsSync(daemonConfigPath)) {
301
+ yield core.group('Default Docker daemon config found', () => __awaiter(this, void 0, void 0, function* () {
302
+ core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' })), null, 2));
303
+ }));
304
+ daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' }));
330
305
  }
331
- case 'linux': {
332
- await this.tearDownLinux();
333
- break;
334
- }
335
- case 'win32': {
336
- await this.tearDownWindows();
337
- break;
306
+ if (this.daemonConfig) {
307
+ daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
338
308
  }
339
- default: {
340
- throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
309
+ let daemonConfigStr = '{}';
310
+ if (daemonConfig) {
311
+ daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
312
+ yield core.group('Docker daemon config', () => __awaiter(this, void 0, void 0, function* () {
313
+ core.info(daemonConfigStr);
314
+ }));
341
315
  }
342
- }
343
- }
344
- async tearDownDarwin() {
345
- await core.group('Docker daemon logs', async () => {
346
- await exec_1.Exec.exec('limactl', ['shell', '--tty=false', this.limaInstanceName, 'sudo', 'journalctl', '-u', 'docker.service', '-l', '--no-pager']).catch(() => {
347
- core.warning(`Failed to get Docker daemon logs`);
348
- });
349
- });
350
- await core.group('Stopping lima instance', async () => {
351
- await exec_1.Exec.exec('limactl', ['stop', '--tty=false', this.limaInstanceName, '--force']);
352
- });
353
- await core.group('Removing lima instance', async () => {
354
- await exec_1.Exec.exec('limactl', ['delete', '--tty=false', this.limaInstanceName, '--force']);
355
- });
356
- await core.group('Removing Docker context', async () => {
357
- await exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
358
- });
359
- await core.group(`Cleaning up runDir`, async () => {
360
- await exec_1.Exec.exec('sudo', ['rm', '-rf', this.runDir]);
316
+ yield core.group('Install Docker daemon service', () => __awaiter(this, void 0, void 0, function* () {
317
+ const setupCmd = yield util_1.Util.powershellCommand((0, assets_1.setupDockerWinPs1)(), {
318
+ ToolDir: this.toolDir,
319
+ RunDir: this.runDir,
320
+ DockerHost: dockerHost,
321
+ DaemonConfig: daemonConfigStr
322
+ });
323
+ yield exec_1.Exec.exec(setupCmd.command, setupCmd.args);
324
+ const logCmd = yield util_1.Util.powershellCommand((0, assets_1.dockerServiceLogsPs1)());
325
+ yield exec_1.Exec.exec(logCmd.command, logCmd.args);
326
+ }));
327
+ yield core.group('Create Docker context', () => __awaiter(this, void 0, void 0, function* () {
328
+ yield exec_1.Exec.exec('docker', ['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
329
+ yield exec_1.Exec.exec('docker', ['context', 'use', this.contextName]);
330
+ }));
331
+ return dockerHost;
361
332
  });
362
333
  }
363
- async tearDownLinux() {
364
- await core.group('Docker daemon logs', async () => {
365
- core.info(fs_1.default.readFileSync(path_1.default.join(this.runDir, 'dockerd.log'), { encoding: 'utf8' }));
366
- });
367
- await core.group('Stopping Docker daemon', async () => {
368
- await exec_1.Exec.exec('sudo', ['kill', '-s', 'SIGTERM', fs_1.default.readFileSync(path_1.default.join(this.runDir, 'docker.pid')).toString().trim()]);
369
- await util_1.Util.sleep(5);
370
- });
371
- await core.group('Removing Docker context', async () => {
372
- await exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
334
+ tearDown() {
335
+ return __awaiter(this, void 0, void 0, function* () {
336
+ if (!this.runDir) {
337
+ throw new Error('runDir must be set');
338
+ }
339
+ switch (os_1.default.platform()) {
340
+ case 'darwin': {
341
+ yield this.tearDownDarwin();
342
+ break;
343
+ }
344
+ case 'linux': {
345
+ yield this.tearDownLinux();
346
+ break;
347
+ }
348
+ case 'win32': {
349
+ yield this.tearDownWindows();
350
+ break;
351
+ }
352
+ default: {
353
+ throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
354
+ }
355
+ }
373
356
  });
374
- await core.group(`Cleaning up runDir`, async () => {
375
- await exec_1.Exec.exec('sudo', ['rm', '-rf', this.runDir], {
376
- ignoreReturnCode: true,
377
- failOnStdErr: false
378
- });
357
+ }
358
+ tearDownDarwin() {
359
+ return __awaiter(this, void 0, void 0, function* () {
360
+ yield core.group('Docker daemon logs', () => __awaiter(this, void 0, void 0, function* () {
361
+ yield exec_1.Exec.exec('limactl', ['shell', '--tty=false', this.limaInstanceName, 'sudo', 'journalctl', '-u', 'docker.service', '-l', '--no-pager']).catch(() => {
362
+ core.warning(`Failed to get Docker daemon logs`);
363
+ });
364
+ }));
365
+ yield core.group('Stopping lima instance', () => __awaiter(this, void 0, void 0, function* () {
366
+ yield exec_1.Exec.exec('limactl', ['stop', '--tty=false', this.limaInstanceName, '--force']);
367
+ }));
368
+ yield core.group('Removing lima instance', () => __awaiter(this, void 0, void 0, function* () {
369
+ yield exec_1.Exec.exec('limactl', ['delete', '--tty=false', this.limaInstanceName, '--force']);
370
+ }));
371
+ yield core.group('Removing Docker context', () => __awaiter(this, void 0, void 0, function* () {
372
+ yield exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
373
+ }));
374
+ yield core.group(`Cleaning up runDir`, () => __awaiter(this, void 0, void 0, function* () {
375
+ yield exec_1.Exec.exec('sudo', ['rm', '-rf', this.runDir]);
376
+ }));
379
377
  });
380
378
  }
381
- async tearDownWindows() {
382
- await core.group('Docker daemon logs', async () => {
383
- const logCmd = await util_1.Util.powershellCommand((0, assets_1.dockerServiceLogsPs1)());
384
- await exec_1.Exec.exec(logCmd.command, logCmd.args);
379
+ tearDownLinux() {
380
+ return __awaiter(this, void 0, void 0, function* () {
381
+ yield core.group('Docker daemon logs', () => __awaiter(this, void 0, void 0, function* () {
382
+ core.info(fs_1.default.readFileSync(path_1.default.join(this.runDir, 'dockerd.log'), { encoding: 'utf8' }));
383
+ }));
384
+ yield core.group('Stopping Docker daemon', () => __awaiter(this, void 0, void 0, function* () {
385
+ yield exec_1.Exec.exec('sudo', ['kill', '-s', 'SIGTERM', fs_1.default.readFileSync(path_1.default.join(this.runDir, 'docker.pid')).toString().trim()]);
386
+ yield util_1.Util.sleep(5);
387
+ }));
388
+ yield core.group('Removing Docker context', () => __awaiter(this, void 0, void 0, function* () {
389
+ yield exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
390
+ }));
391
+ yield core.group(`Cleaning up runDir`, () => __awaiter(this, void 0, void 0, function* () {
392
+ yield exec_1.Exec.exec('sudo', ['rm', '-rf', this.runDir], {
393
+ ignoreReturnCode: true,
394
+ failOnStdErr: false
395
+ });
396
+ }));
385
397
  });
386
- await core.group('Removing Docker context', async () => {
387
- await exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
398
+ }
399
+ tearDownWindows() {
400
+ return __awaiter(this, void 0, void 0, function* () {
401
+ yield core.group('Docker daemon logs', () => __awaiter(this, void 0, void 0, function* () {
402
+ const logCmd = yield util_1.Util.powershellCommand((0, assets_1.dockerServiceLogsPs1)());
403
+ yield exec_1.Exec.exec(logCmd.command, logCmd.args);
404
+ }));
405
+ yield core.group('Removing Docker context', () => __awaiter(this, void 0, void 0, function* () {
406
+ yield exec_1.Exec.exec('docker', ['context', 'rm', '-f', this.contextName]);
407
+ }));
388
408
  });
389
409
  }
390
410
  downloadURL(version, channel) {
@@ -440,45 +460,51 @@ EOF`, [], {
440
460
  }
441
461
  }
442
462
  }
443
- static async limaInstalled() {
444
- return await io
445
- .which('lima', true)
446
- .then(res => {
447
- core.debug(`docker.Install.limaAvailable ok: ${res}`);
448
- return true;
449
- })
450
- .catch(error => {
451
- core.debug(`docker.Install.limaAvailable error: ${error}`);
452
- return false;
463
+ static limaInstalled() {
464
+ return __awaiter(this, void 0, void 0, function* () {
465
+ return yield io
466
+ .which('lima', true)
467
+ .then(res => {
468
+ core.debug(`docker.Install.limaAvailable ok: ${res}`);
469
+ return true;
470
+ })
471
+ .catch(error => {
472
+ core.debug(`docker.Install.limaAvailable error: ${error}`);
473
+ return false;
474
+ });
453
475
  });
454
476
  }
455
- static async qemuArch() {
456
- switch (os_1.default.arch()) {
457
- case 'x64': {
458
- return 'x86_64';
477
+ static qemuArch() {
478
+ return __awaiter(this, void 0, void 0, function* () {
479
+ switch (os_1.default.arch()) {
480
+ case 'x64': {
481
+ return 'x86_64';
482
+ }
483
+ case 'arm64': {
484
+ return 'aarch64';
485
+ }
486
+ default: {
487
+ return os_1.default.arch();
488
+ }
459
489
  }
460
- case 'arm64': {
461
- return 'aarch64';
490
+ });
491
+ }
492
+ static getRelease(version) {
493
+ return __awaiter(this, void 0, void 0, function* () {
494
+ const url = `https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/docker-releases.json`;
495
+ const http = new httpm.HttpClient('docker-actions-toolkit');
496
+ const resp = yield http.get(url);
497
+ const body = yield resp.readBody();
498
+ const statusCode = resp.message.statusCode || 500;
499
+ if (statusCode >= 400) {
500
+ throw new Error(`Failed to get Docker release ${version} from ${url} with status code ${statusCode}: ${body}`);
462
501
  }
463
- default: {
464
- return os_1.default.arch();
502
+ const releases = JSON.parse(body);
503
+ if (!releases[version]) {
504
+ throw new Error(`Cannot find Docker release ${version} in ${url}`);
465
505
  }
466
- }
467
- }
468
- static async getRelease(version) {
469
- const url = `https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/docker-releases.json`;
470
- const http = new httpm.HttpClient('docker-actions-toolkit');
471
- const resp = await http.get(url);
472
- const body = await resp.readBody();
473
- const statusCode = resp.message.statusCode || 500;
474
- if (statusCode >= 400) {
475
- throw new Error(`Failed to get Docker release ${version} from ${url} with status code ${statusCode}: ${body}`);
476
- }
477
- const releases = JSON.parse(body);
478
- if (!releases[version]) {
479
- throw new Error(`Cannot find Docker release ${version} in ${url}`);
480
- }
481
- return releases[version];
506
+ return releases[version];
507
+ });
482
508
  }
483
509
  static limaCustomImages() {
484
510
  const res = [];