@docker/actions-toolkit 0.75.0 → 0.77.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.
- package/lib/buildkit/buildkit.d.ts +3 -3
- package/lib/buildkit/buildkit.js +67 -117
- package/lib/buildkit/buildkit.js.map +1 -1
- package/lib/buildkit/config.js +7 -14
- package/lib/buildkit/config.js.map +1 -1
- package/lib/buildkit/git.d.ts +1 -1
- package/lib/buildkit/git.js +8 -12
- package/lib/buildkit/git.js.map +1 -1
- package/lib/buildx/bake.d.ts +4 -4
- package/lib/buildx/bake.js +76 -93
- package/lib/buildx/bake.js.map +1 -1
- package/lib/buildx/build.d.ts +5 -5
- package/lib/buildx/build.js +44 -78
- package/lib/buildx/build.js.map +1 -1
- package/lib/buildx/builder.d.ts +2 -2
- package/lib/buildx/builder.js +42 -91
- package/lib/buildx/builder.js.map +1 -1
- package/lib/buildx/buildx.d.ts +3 -3
- package/lib/buildx/buildx.js +212 -274
- package/lib/buildx/buildx.js.map +1 -1
- package/lib/buildx/history.d.ts +2 -2
- package/lib/buildx/history.js +226 -284
- package/lib/buildx/history.js.map +1 -1
- package/lib/buildx/imagetools.d.ts +5 -5
- package/lib/buildx/imagetools.js +67 -92
- package/lib/buildx/imagetools.js.map +1 -1
- package/lib/buildx/install.d.ts +14 -3
- package/lib/buildx/install.js +239 -276
- package/lib/buildx/install.js.map +1 -1
- package/lib/cache.js +88 -138
- package/lib/cache.js.map +1 -1
- package/lib/compose/compose.js +53 -107
- package/lib/compose/compose.js.map +1 -1
- package/lib/compose/install.d.ts +2 -2
- package/lib/compose/install.js +129 -191
- package/lib/compose/install.js.map +1 -1
- package/lib/context.js +10 -50
- package/lib/context.js.map +1 -1
- package/lib/cosign/cosign.js +55 -106
- package/lib/cosign/cosign.js.map +1 -1
- package/lib/cosign/dockerfile.js +1 -4
- package/lib/cosign/dockerfile.js.map +1 -1
- package/lib/cosign/install.d.ts +6 -3
- package/lib/cosign/install.js +183 -261
- package/lib/cosign/install.js.map +1 -1
- package/lib/docker/assets.js +15 -24
- package/lib/docker/assets.js.map +1 -1
- package/lib/docker/docker.d.ts +1 -1
- package/lib/docker/docker.js +112 -182
- package/lib/docker/docker.js.map +1 -1
- package/lib/docker/install.d.ts +3 -3
- package/lib/docker/install.js +543 -617
- package/lib/docker/install.js.map +1 -1
- package/lib/dockerhub.d.ts +1 -1
- package/lib/dockerhub.js +67 -125
- package/lib/dockerhub.js.map +1 -1
- package/lib/exec.js +9 -59
- package/lib/exec.js.map +1 -1
- package/lib/git.d.ts +2 -1
- package/lib/git.js +144 -220
- package/lib/git.js.map +1 -1
- package/lib/github/artifact.d.ts +19 -0
- package/lib/github/artifact.js +49 -0
- package/lib/github/artifact.js.map +1 -0
- package/lib/{github.d.ts → github/github.d.ts} +4 -8
- package/lib/github/github.js +135 -0
- package/lib/github/github.js.map +1 -0
- package/lib/github/summary.d.ts +20 -0
- package/lib/github/summary.js +166 -0
- package/lib/github/summary.js.map +1 -0
- package/lib/index.js +17 -64
- package/lib/index.js.map +1 -1
- package/lib/oci/oci.d.ts +2 -2
- package/lib/oci/oci.js +52 -104
- package/lib/oci/oci.js.map +1 -1
- package/lib/regclient/install.d.ts +2 -2
- package/lib/regclient/install.js +83 -141
- package/lib/regclient/install.js.map +1 -1
- package/lib/regclient/regctl.d.ts +1 -1
- package/lib/regclient/regctl.js +67 -123
- package/lib/regclient/regctl.js.map +1 -1
- package/lib/sigstore/sigstore.d.ts +5 -3
- package/lib/sigstore/sigstore.js +361 -344
- package/lib/sigstore/sigstore.js.map +1 -1
- package/lib/toolkit.d.ts +16 -16
- package/lib/toolkit.js +49 -37
- package/lib/toolkit.js.map +1 -1
- package/lib/types/buildkit/buildkit.js +1 -4
- package/lib/types/buildkit/buildkit.js.map +1 -1
- package/lib/types/buildkit/client.d.ts +2 -2
- package/lib/types/buildkit/client.js +1 -2
- package/lib/types/buildkit/client.js.map +1 -1
- package/lib/types/buildkit/control.d.ts +4 -4
- package/lib/types/buildkit/control.js +1 -2
- package/lib/types/buildkit/control.js.map +1 -1
- package/lib/types/buildkit/git.js +1 -2
- package/lib/types/buildkit/git.js.map +1 -1
- package/lib/types/buildkit/ops.js +1 -2
- package/lib/types/buildkit/ops.js.map +1 -1
- package/lib/types/buildkit/rpc.js +1 -2
- package/lib/types/buildkit/rpc.js.map +1 -1
- package/lib/types/buildx/bake.js +1 -2
- package/lib/types/buildx/bake.js.map +1 -1
- package/lib/types/buildx/build.js +1 -2
- package/lib/types/buildx/build.js.map +1 -1
- package/lib/types/buildx/builder.js +1 -2
- package/lib/types/buildx/builder.js.map +1 -1
- package/lib/types/buildx/buildx.d.ts +1 -1
- package/lib/types/buildx/buildx.js +1 -2
- package/lib/types/buildx/buildx.js.map +1 -1
- package/lib/types/buildx/history.js +1 -2
- package/lib/types/buildx/history.js.map +1 -1
- package/lib/types/buildx/imagetools.d.ts +3 -3
- package/lib/types/buildx/imagetools.js +1 -2
- package/lib/types/buildx/imagetools.js.map +1 -1
- package/lib/types/compose/compose.d.ts +1 -1
- package/lib/types/compose/compose.js +1 -2
- package/lib/types/compose/compose.js.map +1 -1
- package/lib/types/cosign/cosign.d.ts +1 -1
- package/lib/types/cosign/cosign.js +1 -2
- package/lib/types/cosign/cosign.js.map +1 -1
- package/lib/types/docker/docker.js +1 -2
- package/lib/types/docker/docker.js.map +1 -1
- package/lib/types/docker/mediatype.js +3 -6
- package/lib/types/docker/mediatype.js.map +1 -1
- package/lib/types/dockerhub.js +1 -2
- package/lib/types/dockerhub.js.map +1 -1
- package/lib/types/github/artifact.d.ts +26 -0
- package/lib/types/{git.d.ts → github/artifact.js} +3 -3
- package/lib/types/github/artifact.js.map +1 -0
- package/lib/types/{github.d.ts → github/github.d.ts} +4 -23
- package/lib/types/{git.js → github/github.js} +2 -3
- package/lib/types/github/github.js.map +1 -0
- package/lib/types/github/summary.d.ts +29 -0
- package/lib/types/{github.js → github/summary.js} +3 -4
- package/lib/types/github/summary.js.map +1 -0
- package/lib/types/intoto/intoto.js +2 -5
- package/lib/types/intoto/intoto.js.map +1 -1
- package/lib/types/intoto/slsa_provenance/v0.2/provenance.js +1 -4
- package/lib/types/intoto/slsa_provenance/v0.2/provenance.js.map +1 -1
- package/lib/types/oci/config.d.ts +2 -2
- package/lib/types/oci/config.js +1 -2
- package/lib/types/oci/config.js.map +1 -1
- package/lib/types/oci/descriptor.d.ts +1 -1
- package/lib/types/oci/descriptor.js +3 -6
- package/lib/types/oci/descriptor.js.map +1 -1
- package/lib/types/oci/digest.js +1 -2
- package/lib/types/oci/digest.js.map +1 -1
- package/lib/types/oci/index.d.ts +2 -2
- package/lib/types/oci/index.js +1 -2
- package/lib/types/oci/index.js.map +1 -1
- package/lib/types/oci/layout.js +4 -7
- package/lib/types/oci/layout.js.map +1 -1
- package/lib/types/oci/manifest.d.ts +2 -2
- package/lib/types/oci/manifest.js +1 -2
- package/lib/types/oci/manifest.js.map +1 -1
- package/lib/types/oci/mediatype.js +6 -9
- package/lib/types/oci/mediatype.js.map +1 -1
- package/lib/types/oci/oci.d.ts +4 -4
- package/lib/types/oci/oci.js +1 -2
- package/lib/types/oci/oci.js.map +1 -1
- package/lib/types/oci/versioned.js +1 -2
- package/lib/types/oci/versioned.js.map +1 -1
- package/lib/types/regclient/regclient.d.ts +1 -1
- package/lib/types/regclient/regclient.js +1 -2
- package/lib/types/regclient/regclient.js.map +1 -1
- package/lib/types/sigstore/sigstore.d.ts +11 -2
- package/lib/types/sigstore/sigstore.js +4 -7
- package/lib/types/sigstore/sigstore.js.map +1 -1
- package/lib/types/undock/undock.d.ts +1 -1
- package/lib/types/undock/undock.js +1 -2
- package/lib/types/undock/undock.js.map +1 -1
- package/lib/undock/install.d.ts +2 -2
- package/lib/undock/install.js +93 -151
- package/lib/undock/install.js.map +1 -1
- package/lib/undock/undock.js +88 -141
- package/lib/undock/undock.js.map +1 -1
- package/lib/util.js +36 -89
- package/lib/util.js.map +1 -1
- package/package.json +31 -42
- package/lib/github.js +0 -421
- package/lib/github.js.map +0 -1
- package/lib/types/git.js.map +0 -1
- package/lib/types/github.js.map +0 -1
package/lib/docker/install.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Copyright 2023 actions-toolkit authors
|
|
4
3
|
*
|
|
@@ -14,74 +13,39 @@
|
|
|
14
13
|
* See the License for the specific language governing permissions and
|
|
15
14
|
* limitations under the License.
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})();
|
|
50
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
51
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
52
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
53
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
54
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
55
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
56
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
60
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
61
|
-
};
|
|
62
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
-
exports.Install = void 0;
|
|
64
|
-
const child_process = __importStar(require("child_process"));
|
|
65
|
-
const fs_1 = __importDefault(require("fs"));
|
|
66
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
67
|
-
const os_1 = __importDefault(require("os"));
|
|
68
|
-
const path_1 = __importDefault(require("path"));
|
|
69
|
-
const async_retry_1 = __importDefault(require("async-retry"));
|
|
70
|
-
const handlebars = __importStar(require("handlebars"));
|
|
71
|
-
const core = __importStar(require("@actions/core"));
|
|
72
|
-
const io = __importStar(require("@actions/io"));
|
|
73
|
-
const tc = __importStar(require("@actions/tool-cache"));
|
|
74
|
-
const context_1 = require("../context");
|
|
75
|
-
const docker_1 = require("./docker");
|
|
76
|
-
const exec_1 = require("../exec");
|
|
77
|
-
const github_1 = require("../github");
|
|
78
|
-
const regctl_1 = require("../regclient/regctl");
|
|
79
|
-
const undock_1 = require("../undock/undock");
|
|
80
|
-
const util_1 = require("../util");
|
|
81
|
-
const assets_1 = require("./assets");
|
|
82
|
-
class Install {
|
|
16
|
+
import * as child_process from 'child_process';
|
|
17
|
+
import fs from 'fs';
|
|
18
|
+
import fsp from 'fs/promises';
|
|
19
|
+
import os from 'os';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import retry from 'async-retry';
|
|
22
|
+
import * as handlebars from 'handlebars';
|
|
23
|
+
import * as core from '@actions/core';
|
|
24
|
+
import * as io from '@actions/io';
|
|
25
|
+
import * as tc from '@actions/tool-cache';
|
|
26
|
+
import { Context } from '../context.js';
|
|
27
|
+
import { Docker } from './docker.js';
|
|
28
|
+
import { Exec } from '../exec.js';
|
|
29
|
+
import { GitHub } from '../github/github.js';
|
|
30
|
+
import { Regctl } from '../regclient/regctl.js';
|
|
31
|
+
import { Undock } from '../undock/undock.js';
|
|
32
|
+
import { Util } from '../util.js';
|
|
33
|
+
import { limaYamlData, dockerServiceLogsPs1, setupDockerWinPs1 } from './assets.js';
|
|
34
|
+
export class Install {
|
|
35
|
+
runDir;
|
|
36
|
+
source;
|
|
37
|
+
contextName;
|
|
38
|
+
daemonConfig;
|
|
39
|
+
rootless;
|
|
40
|
+
localTCPPort;
|
|
41
|
+
regctl;
|
|
42
|
+
undock;
|
|
43
|
+
githubToken;
|
|
44
|
+
_version;
|
|
45
|
+
_toolDir;
|
|
46
|
+
gitCommit;
|
|
47
|
+
limaInstanceName = 'docker-actions-toolkit';
|
|
83
48
|
constructor(opts) {
|
|
84
|
-
this.limaInstanceName = 'docker-actions-toolkit';
|
|
85
49
|
this.runDir = opts.runDir;
|
|
86
50
|
this.source = opts.source || {
|
|
87
51
|
type: 'archive',
|
|
@@ -92,462 +56,438 @@ class Install {
|
|
|
92
56
|
this.daemonConfig = opts.daemonConfig;
|
|
93
57
|
this.rootless = opts.rootless || false;
|
|
94
58
|
this.localTCPPort = opts.localTCPPort;
|
|
95
|
-
this.regctl = opts.regctl || new
|
|
96
|
-
this.undock = opts.undock || new
|
|
59
|
+
this.regctl = opts.regctl || new Regctl();
|
|
60
|
+
this.undock = opts.undock || new Undock();
|
|
97
61
|
this.githubToken = opts.githubToken || process.env.GITHUB_TOKEN;
|
|
98
62
|
}
|
|
99
63
|
get toolDir() {
|
|
100
|
-
return this._toolDir ||
|
|
64
|
+
return this._toolDir || Context.tmpDir();
|
|
101
65
|
}
|
|
102
|
-
download() {
|
|
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
|
-
break;
|
|
66
|
+
async download() {
|
|
67
|
+
let extractFolder;
|
|
68
|
+
let cacheKey;
|
|
69
|
+
const platform = os.platform();
|
|
70
|
+
switch (this.source.type) {
|
|
71
|
+
case 'image': {
|
|
72
|
+
this._version = this.source.tag;
|
|
73
|
+
cacheKey = `docker-image`;
|
|
74
|
+
extractFolder = await this.downloadSourceImage(platform);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'archive': {
|
|
78
|
+
const version = this.source.version;
|
|
79
|
+
const channel = this.source.channel;
|
|
80
|
+
cacheKey = `docker-archive-${channel}`;
|
|
81
|
+
this._version = version;
|
|
82
|
+
core.info(`Downloading Docker ${version} from ${this.source.channel} at download.docker.com`);
|
|
83
|
+
extractFolder = await this.downloadSourceArchive('docker', this.source);
|
|
84
|
+
if (this.rootless) {
|
|
85
|
+
core.info(`Downloading Docker rootless extras ${version} from ${this.source.channel} at download.docker.com`);
|
|
86
|
+
const extrasFolder = await this.downloadSourceArchive('docker-rootless-extras', this.source);
|
|
87
|
+
fs.readdirSync(extrasFolder).forEach(file => {
|
|
88
|
+
const src = path.join(extrasFolder, file);
|
|
89
|
+
const dest = path.join(extractFolder, file);
|
|
90
|
+
fs.copyFileSync(src, dest);
|
|
91
|
+
});
|
|
131
92
|
}
|
|
93
|
+
break;
|
|
132
94
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
95
|
+
}
|
|
96
|
+
core.info('Fixing perms');
|
|
97
|
+
fs.readdir(path.join(extractFolder), function (err, files) {
|
|
98
|
+
if (err) {
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
102
|
+
files.forEach(function (file, index) {
|
|
103
|
+
if (!Util.isDirectory(path.join(extractFolder, file))) {
|
|
104
|
+
fs.chmodSync(path.join(extractFolder, file), '0755');
|
|
137
105
|
}
|
|
138
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
139
|
-
files.forEach(function (file, index) {
|
|
140
|
-
if (!util_1.Util.isDirectory(path_1.default.join(extractFolder, file))) {
|
|
141
|
-
fs_1.default.chmodSync(path_1.default.join(extractFolder, file), '0755');
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
106
|
});
|
|
145
|
-
const tooldir = yield tc.cacheDir(extractFolder, cacheKey, this._version.replace(/(0+)([1-9]+)/, '$2'));
|
|
146
|
-
core.addPath(tooldir);
|
|
147
|
-
core.info('Added Docker to PATH');
|
|
148
|
-
this._toolDir = tooldir;
|
|
149
|
-
return tooldir;
|
|
150
107
|
});
|
|
108
|
+
const tooldir = await tc.cacheDir(extractFolder, cacheKey, this._version.replace(/(0+)([1-9]+)/, '$2'));
|
|
109
|
+
core.addPath(tooldir);
|
|
110
|
+
core.info('Added Docker to PATH');
|
|
111
|
+
this._toolDir = tooldir;
|
|
112
|
+
return tooldir;
|
|
151
113
|
}
|
|
152
|
-
downloadSourceImage(platform) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
114
|
+
async downloadSourceImage(platform) {
|
|
115
|
+
const dest = path.join(Context.tmpDir(), 'docker-install-image');
|
|
116
|
+
const cliImage = `dockereng/cli-bin:${this._version}`;
|
|
117
|
+
const engineImage = `moby/moby-bin:${this._version}`;
|
|
118
|
+
core.info(`Downloading Docker CLI from ${cliImage}`);
|
|
119
|
+
await this.undock.run({
|
|
120
|
+
source: cliImage,
|
|
121
|
+
dist: dest
|
|
122
|
+
});
|
|
123
|
+
if (['win32', 'linux'].includes(platform)) {
|
|
124
|
+
core.info(`Downloading Docker engine from ${engineImage}`);
|
|
125
|
+
await this.undock.run({
|
|
126
|
+
source: engineImage,
|
|
161
127
|
dist: dest
|
|
162
128
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
const engineImageConfig = yield this.imageConfig(engineImage, 'linux/arm64');
|
|
177
|
-
core.debug(`docker.Install.downloadSourceImage engineImageConfig: ${JSON.stringify(engineImageConfig)}`);
|
|
178
|
-
this.gitCommit = (_b = (_a = engineImageConfig.config) === null || _a === void 0 ? void 0 : _a.Labels) === null || _b === void 0 ? void 0 : _b['org.opencontainers.image.revision'];
|
|
179
|
-
if (!this.gitCommit) {
|
|
180
|
-
throw new Error(`No git revision can be determined from the image`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
catch (e) {
|
|
184
|
-
core.warning(e);
|
|
185
|
-
this.gitCommit = 'master';
|
|
129
|
+
}
|
|
130
|
+
else if (platform == 'darwin') {
|
|
131
|
+
// On macOS, the docker daemon binary will be downloaded inside the lima VM.
|
|
132
|
+
// However, we will get the exact git revision from the image config
|
|
133
|
+
// to get the matching systemd unit files. There's no macOS image for
|
|
134
|
+
// moby/moby-bin - a linux daemon is run inside lima.
|
|
135
|
+
try {
|
|
136
|
+
const engineImageConfig = await this.imageConfig(engineImage, 'linux/arm64');
|
|
137
|
+
core.debug(`docker.Install.downloadSourceImage engineImageConfig: ${JSON.stringify(engineImageConfig)}`);
|
|
138
|
+
this.gitCommit = engineImageConfig.config?.Labels?.['org.opencontainers.image.revision'];
|
|
139
|
+
if (!this.gitCommit) {
|
|
140
|
+
throw new Error(`No git revision can be determined from the image`);
|
|
186
141
|
}
|
|
187
|
-
core.debug(`docker.Install.downloadSourceImage gitCommit: ${this.gitCommit}`);
|
|
188
142
|
}
|
|
189
|
-
|
|
190
|
-
core.warning(
|
|
143
|
+
catch (e) {
|
|
144
|
+
core.warning(e);
|
|
145
|
+
this.gitCommit = 'master';
|
|
191
146
|
}
|
|
192
|
-
|
|
193
|
-
}
|
|
147
|
+
core.debug(`docker.Install.downloadSourceImage gitCommit: ${this.gitCommit}`);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
core.warning(`Docker engine not supported on ${platform}, only the Docker cli will be available`);
|
|
151
|
+
}
|
|
152
|
+
return dest;
|
|
153
|
+
}
|
|
154
|
+
async downloadSourceArchive(component, src) {
|
|
155
|
+
const release = await Install.getRelease(src.version, this.githubToken);
|
|
156
|
+
this._version = release.tag_name.replace(/^(docker-)?v+/, '');
|
|
157
|
+
core.debug(`docker.Install.downloadSourceArchive version: ${this._version}`);
|
|
158
|
+
const downloadURL = this.downloadURL(component, this._version, src.channel);
|
|
159
|
+
core.info(`Downloading ${downloadURL}`);
|
|
160
|
+
const downloadPath = await tc.downloadTool(downloadURL);
|
|
161
|
+
core.debug(`docker.Install.downloadSourceArchive downloadPath: ${downloadPath}`);
|
|
162
|
+
let extractFolder;
|
|
163
|
+
if (os.platform() == 'win32') {
|
|
164
|
+
extractFolder = await tc.extractZip(downloadPath, extractFolder);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
extractFolder = await tc.extractTar(downloadPath, extractFolder);
|
|
168
|
+
}
|
|
169
|
+
if (Util.isDirectory(path.join(extractFolder, component))) {
|
|
170
|
+
extractFolder = path.join(extractFolder, component);
|
|
171
|
+
}
|
|
172
|
+
core.debug(`docker.Install.downloadSourceArchive extractFolder: ${extractFolder}`);
|
|
173
|
+
return extractFolder;
|
|
194
174
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
175
|
+
async install() {
|
|
176
|
+
if (!this.toolDir) {
|
|
177
|
+
throw new Error('toolDir must be set. Run download first.');
|
|
178
|
+
}
|
|
179
|
+
if (!this.runDir) {
|
|
180
|
+
throw new Error('runDir must be set');
|
|
181
|
+
}
|
|
182
|
+
const platform = os.platform();
|
|
183
|
+
if (this.rootless && platform != 'linux') {
|
|
184
|
+
// TODO: Support on macOS (via lima)
|
|
185
|
+
throw new Error(`rootless is only supported on linux`);
|
|
186
|
+
}
|
|
187
|
+
switch (platform) {
|
|
188
|
+
case 'darwin': {
|
|
189
|
+
return await this.installDarwin();
|
|
207
190
|
}
|
|
208
|
-
|
|
209
|
-
|
|
191
|
+
case 'linux': {
|
|
192
|
+
return await this.installLinux();
|
|
210
193
|
}
|
|
211
|
-
|
|
212
|
-
|
|
194
|
+
case 'win32': {
|
|
195
|
+
return await this.installWindows();
|
|
213
196
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
197
|
+
default: {
|
|
198
|
+
throw new Error(`Unsupported platform: ${os.platform()}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
217
201
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
return yield this.installLinux();
|
|
237
|
-
}
|
|
238
|
-
case 'win32': {
|
|
239
|
-
return yield this.installWindows();
|
|
240
|
-
}
|
|
241
|
-
default: {
|
|
242
|
-
throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
|
|
243
|
-
}
|
|
202
|
+
async installDarwin() {
|
|
203
|
+
if (this.source.type == 'image' && !this.gitCommit) {
|
|
204
|
+
throw new Error('gitCommit must be set. Run download first.');
|
|
205
|
+
}
|
|
206
|
+
const src = this.source;
|
|
207
|
+
const limaDir = path.join(os.homedir(), '.lima', this.limaInstanceName);
|
|
208
|
+
await io.mkdirP(limaDir);
|
|
209
|
+
const dockerHost = `unix://${limaDir}/docker.sock`;
|
|
210
|
+
if (!(await Install.limaInstalled())) {
|
|
211
|
+
await this.brewInstall('lima');
|
|
212
|
+
}
|
|
213
|
+
await core.group('Lima version', async () => {
|
|
214
|
+
await Exec.exec('lima', ['--version']);
|
|
215
|
+
});
|
|
216
|
+
await core.group('Creating lima config', async () => {
|
|
217
|
+
let limaDaemonConfig = {};
|
|
218
|
+
if (this.daemonConfig) {
|
|
219
|
+
limaDaemonConfig = JSON.parse(this.daemonConfig);
|
|
244
220
|
}
|
|
221
|
+
handlebars.registerHelper('stringify', function (obj) {
|
|
222
|
+
return new handlebars.SafeString(JSON.stringify(obj));
|
|
223
|
+
});
|
|
224
|
+
const srcArchive = src;
|
|
225
|
+
const limaCfg = handlebars.compile(limaYamlData)({
|
|
226
|
+
customImages: Install.limaCustomImages(),
|
|
227
|
+
daemonConfig: limaDaemonConfig,
|
|
228
|
+
dockerSock: `${limaDir}/docker.sock`,
|
|
229
|
+
localTCPPort: this.localTCPPort,
|
|
230
|
+
gitCommit: this.gitCommit,
|
|
231
|
+
srcType: src.type,
|
|
232
|
+
srcArchiveVersion: this._version, // Use the resolved version (e.g. latest -> 27.4.0)
|
|
233
|
+
srcArchiveChannel: srcArchive.channel,
|
|
234
|
+
srcImageTag: src.tag
|
|
235
|
+
});
|
|
236
|
+
core.info(`Writing lima config to ${path.join(limaDir, 'lima.yaml')}`);
|
|
237
|
+
fs.writeFileSync(path.join(limaDir, 'lima.yaml'), limaCfg);
|
|
238
|
+
core.info(limaCfg);
|
|
245
239
|
});
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
240
|
+
if (!(await Install.qemuInstalled())) {
|
|
241
|
+
await this.brewInstall('qemu');
|
|
242
|
+
}
|
|
243
|
+
const qemuBin = await Install.qemuBin();
|
|
244
|
+
await core.group('QEMU version', async () => {
|
|
245
|
+
await Exec.exec(qemuBin, ['--version']);
|
|
246
|
+
});
|
|
247
|
+
// lima might already be started on the runner so env var added in download
|
|
248
|
+
// method is not expanded to the running process.
|
|
249
|
+
const envs = Object.assign({}, process.env, {
|
|
250
|
+
PATH: `${this.toolDir}:${process.env.PATH}`
|
|
251
|
+
});
|
|
252
|
+
await core.group('Starting lima instance', async () => {
|
|
253
|
+
const limaStartArgs = ['start', `--name=${this.limaInstanceName}`, `--timeout=${process.env.LIMA_START_TIMEOUT ?? '15m'}`];
|
|
254
|
+
if (process.env.LIMA_START_ARGS) {
|
|
255
|
+
limaStartArgs.push(process.env.LIMA_START_ARGS);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
await Exec.exec(`limactl ${limaStartArgs.join(' ')}`, [], { env: envs });
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
fsp
|
|
262
|
+
.readdir(limaDir)
|
|
263
|
+
.then(files => {
|
|
264
|
+
files
|
|
265
|
+
.filter(f => path.extname(f) === '.log')
|
|
266
|
+
.forEach(f => {
|
|
267
|
+
const logfile = path.join(limaDir, f);
|
|
268
|
+
const logcontent = fs.readFileSync(logfile, { encoding: 'utf8' }).trim();
|
|
269
|
+
if (logcontent.length > 0) {
|
|
270
|
+
core.info(`### ${logfile}:\n${logcontent}`);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
})
|
|
274
|
+
.catch(() => {
|
|
275
|
+
// ignore
|
|
281
276
|
});
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
277
|
+
throw e;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
await core.group('Create Docker context', async () => {
|
|
281
|
+
await Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
|
282
|
+
await Docker.exec(['context', 'use', this.contextName]);
|
|
283
|
+
});
|
|
284
|
+
return dockerHost;
|
|
285
|
+
}
|
|
286
|
+
async installLinux() {
|
|
287
|
+
const dockerHost = `unix://${path.join(this.runDir, 'docker.sock')}`;
|
|
288
|
+
await io.mkdirP(this.runDir);
|
|
289
|
+
const daemonConfigPath = path.join(this.runDir, 'daemon.json');
|
|
290
|
+
await fs.writeFileSync(daemonConfigPath, '{}');
|
|
291
|
+
let daemonConfig = undefined;
|
|
292
|
+
const daemonConfigDefaultPath = '/etc/docker/daemon.json';
|
|
293
|
+
if (fs.existsSync(daemonConfigDefaultPath)) {
|
|
294
|
+
await core.group('Default Docker daemon config found', async () => {
|
|
295
|
+
core.info(JSON.stringify(JSON.parse(fs.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' })), null, 2));
|
|
296
|
+
});
|
|
297
|
+
daemonConfig = JSON.parse(fs.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' }));
|
|
298
|
+
}
|
|
299
|
+
if (this.daemonConfig) {
|
|
300
|
+
daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
|
|
301
|
+
}
|
|
302
|
+
if (daemonConfig) {
|
|
303
|
+
const daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
|
|
304
|
+
await core.group('Writing Docker daemon config', async () => {
|
|
305
|
+
fs.writeFileSync(daemonConfigPath, daemonConfigStr);
|
|
306
|
+
core.info(daemonConfigStr);
|
|
297
307
|
});
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
308
|
+
}
|
|
309
|
+
const envs = Object.assign({}, process.env, {
|
|
310
|
+
PATH: `${this.toolDir}:${process.env.PATH}`,
|
|
311
|
+
XDG_RUNTIME_DIR: (this.rootless && this.runDir) || undefined
|
|
312
|
+
});
|
|
313
|
+
await core.group('Start Docker daemon', async () => {
|
|
314
|
+
const bashPath = await io.which('bash', true);
|
|
315
|
+
let dockerPath = `${this.toolDir}/dockerd`;
|
|
316
|
+
if (this.rootless) {
|
|
317
|
+
dockerPath = `${this.toolDir}/dockerd-rootless.sh`;
|
|
318
|
+
if (fs.existsSync('/proc/sys/kernel/apparmor_restrict_unprivileged_userns')) {
|
|
319
|
+
await Exec.exec('sudo', ['sh', '-c', 'echo 0 > /proc/sys/kernel/apparmor_restrict_unprivileged_userns']);
|
|
303
320
|
}
|
|
321
|
+
}
|
|
322
|
+
let cmd = `${dockerPath} --host="${dockerHost}" --config-file="${daemonConfigPath}" --exec-root="${this.runDir}/execroot" --data-root="${this.runDir}/data" --pidfile="${this.runDir}/docker.pid"`;
|
|
323
|
+
if (this.localTCPPort) {
|
|
324
|
+
cmd += ` --host="tcp://127.0.0.1:${this.localTCPPort}"`;
|
|
325
|
+
}
|
|
326
|
+
core.info(`[command] ${cmd}`); // https://github.com/actions/toolkit/blob/3d652d3133965f63309e4b2e1c8852cdbdcb3833/packages/exec/src/toolrunner.ts#L47
|
|
327
|
+
let sudo = 'sudo';
|
|
328
|
+
if (this.rootless) {
|
|
329
|
+
sudo += ' -u \\#1001';
|
|
330
|
+
}
|
|
331
|
+
const proc = await child_process.spawn(
|
|
332
|
+
// We can't use Exec.exec here because we need to detach the process to
|
|
333
|
+
// avoid killing it when the action finishes running. Even if detached,
|
|
334
|
+
// we also need to run dockerd in a subshell and unref the process so
|
|
335
|
+
// GitHub Action doesn't wait for it to finish.
|
|
336
|
+
`${sudo} env "PATH=$PATH" "XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" ${bashPath} << EOF
|
|
337
|
+
( ${cmd} 2>&1 | tee "${this.runDir}/dockerd.log" ) &
|
|
338
|
+
EOF`, [], {
|
|
339
|
+
env: envs,
|
|
340
|
+
detached: true,
|
|
341
|
+
shell: true,
|
|
342
|
+
stdio: ['ignore', process.stdout, process.stderr]
|
|
343
|
+
});
|
|
344
|
+
proc.unref();
|
|
345
|
+
await Util.sleep(3);
|
|
346
|
+
const retries = 10;
|
|
347
|
+
await retry(async (bail) => {
|
|
304
348
|
try {
|
|
305
|
-
|
|
349
|
+
await Exec.getExecOutput(`docker version`, undefined, {
|
|
350
|
+
silent: true,
|
|
351
|
+
env: Object.assign({}, envs, {
|
|
352
|
+
DOCKER_HOST: dockerHost,
|
|
353
|
+
DOCKER_CONTENT_TRUST: 'false'
|
|
354
|
+
})
|
|
355
|
+
});
|
|
306
356
|
}
|
|
307
357
|
catch (e) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const logcontent = fs_1.default.readFileSync(logfile, { encoding: 'utf8' }).trim();
|
|
316
|
-
if (logcontent.length > 0) {
|
|
317
|
-
core.info(`### ${logfile}:\n${logcontent}`);
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
})
|
|
321
|
-
.catch(() => {
|
|
322
|
-
// ignore
|
|
323
|
-
});
|
|
324
|
-
throw e;
|
|
358
|
+
bail(e);
|
|
359
|
+
}
|
|
360
|
+
}, {
|
|
361
|
+
retries: retries,
|
|
362
|
+
minTimeout: 1000,
|
|
363
|
+
onRetry: (err, i) => {
|
|
364
|
+
core.info(`${err}. Retrying (${i}/${retries})...`);
|
|
325
365
|
}
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
})
|
|
331
|
-
|
|
366
|
+
});
|
|
367
|
+
core.info(`Docker daemon started started successfully`);
|
|
368
|
+
});
|
|
369
|
+
await core.group('Create Docker context', async () => {
|
|
370
|
+
await Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
|
371
|
+
await Docker.exec(['context', 'use', this.contextName]);
|
|
332
372
|
});
|
|
373
|
+
return dockerHost;
|
|
333
374
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const daemonConfigDefaultPath = '/etc/docker/daemon.json';
|
|
342
|
-
if (fs_1.default.existsSync(daemonConfigDefaultPath)) {
|
|
343
|
-
yield core.group('Default Docker daemon config found', () => __awaiter(this, void 0, void 0, function* () {
|
|
344
|
-
core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' })), null, 2));
|
|
345
|
-
}));
|
|
346
|
-
daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigDefaultPath, { encoding: 'utf8' }));
|
|
347
|
-
}
|
|
348
|
-
if (this.daemonConfig) {
|
|
349
|
-
daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
|
|
350
|
-
}
|
|
351
|
-
if (daemonConfig) {
|
|
352
|
-
const daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
|
|
353
|
-
yield core.group('Writing Docker daemon config', () => __awaiter(this, void 0, void 0, function* () {
|
|
354
|
-
fs_1.default.writeFileSync(daemonConfigPath, daemonConfigStr);
|
|
355
|
-
core.info(daemonConfigStr);
|
|
356
|
-
}));
|
|
357
|
-
}
|
|
358
|
-
const envs = Object.assign({}, process.env, {
|
|
359
|
-
PATH: `${this.toolDir}:${process.env.PATH}`,
|
|
360
|
-
XDG_RUNTIME_DIR: (this.rootless && this.runDir) || undefined
|
|
375
|
+
async installWindows() {
|
|
376
|
+
const dockerHostSocket = 'npipe:////./pipe/setup_docker_action';
|
|
377
|
+
let daemonConfig = undefined;
|
|
378
|
+
const daemonConfigPath = path.join(this.runDir, 'daemon.json');
|
|
379
|
+
if (fs.existsSync(daemonConfigPath)) {
|
|
380
|
+
await core.group('Default Docker daemon config found', async () => {
|
|
381
|
+
core.info(JSON.stringify(JSON.parse(fs.readFileSync(daemonConfigPath, { encoding: 'utf8' })), null, 2));
|
|
361
382
|
});
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
env: envs,
|
|
389
|
-
detached: true,
|
|
390
|
-
shell: true,
|
|
391
|
-
stdio: ['ignore', process.stdout, process.stderr]
|
|
392
|
-
});
|
|
393
|
-
proc.unref();
|
|
394
|
-
yield util_1.Util.sleep(3);
|
|
395
|
-
const retries = 10;
|
|
396
|
-
yield (0, async_retry_1.default)((bail) => __awaiter(this, void 0, void 0, function* () {
|
|
397
|
-
try {
|
|
398
|
-
yield exec_1.Exec.getExecOutput(`docker version`, undefined, {
|
|
399
|
-
silent: true,
|
|
400
|
-
env: Object.assign({}, envs, {
|
|
401
|
-
DOCKER_HOST: dockerHost,
|
|
402
|
-
DOCKER_CONTENT_TRUST: 'false'
|
|
403
|
-
})
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
catch (e) {
|
|
407
|
-
bail(e);
|
|
408
|
-
}
|
|
409
|
-
}), {
|
|
410
|
-
retries: retries,
|
|
411
|
-
minTimeout: 1000,
|
|
412
|
-
onRetry: (err, i) => {
|
|
413
|
-
core.info(`${err}. Retrying (${i}/${retries})...`);
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
core.info(`Docker daemon started started successfully`);
|
|
417
|
-
}));
|
|
418
|
-
yield core.group('Create Docker context', () => __awaiter(this, void 0, void 0, function* () {
|
|
419
|
-
yield docker_1.Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHost}`]);
|
|
420
|
-
yield docker_1.Docker.exec(['context', 'use', this.contextName]);
|
|
421
|
-
}));
|
|
422
|
-
return dockerHost;
|
|
383
|
+
daemonConfig = JSON.parse(fs.readFileSync(daemonConfigPath, { encoding: 'utf8' }));
|
|
384
|
+
}
|
|
385
|
+
if (this.daemonConfig) {
|
|
386
|
+
daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
|
|
387
|
+
}
|
|
388
|
+
let daemonConfigStr = '{}';
|
|
389
|
+
if (daemonConfig) {
|
|
390
|
+
daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
|
|
391
|
+
await core.group('Docker daemon config', async () => {
|
|
392
|
+
core.info(daemonConfigStr);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
const params = {
|
|
396
|
+
ToolDir: this.toolDir,
|
|
397
|
+
RunDir: this.runDir,
|
|
398
|
+
DockerHostSocket: dockerHostSocket,
|
|
399
|
+
DaemonConfig: daemonConfigStr
|
|
400
|
+
};
|
|
401
|
+
if (this.localTCPPort) {
|
|
402
|
+
params['DockerHostTCP'] = `tcp://127.0.0.1:${this.localTCPPort}`;
|
|
403
|
+
}
|
|
404
|
+
await core.group('Install Docker daemon service', async () => {
|
|
405
|
+
const setupCmd = await Util.powershellCommand(setupDockerWinPs1(), params);
|
|
406
|
+
await Exec.exec(setupCmd.command, setupCmd.args);
|
|
407
|
+
const logCmd = await Util.powershellCommand(dockerServiceLogsPs1());
|
|
408
|
+
await Exec.exec(logCmd.command, logCmd.args);
|
|
423
409
|
});
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const dockerHostSocket = 'npipe:////./pipe/setup_docker_action';
|
|
428
|
-
let daemonConfig = undefined;
|
|
429
|
-
const daemonConfigPath = path_1.default.join(this.runDir, 'daemon.json');
|
|
430
|
-
if (fs_1.default.existsSync(daemonConfigPath)) {
|
|
431
|
-
yield core.group('Default Docker daemon config found', () => __awaiter(this, void 0, void 0, function* () {
|
|
432
|
-
core.info(JSON.stringify(JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' })), null, 2));
|
|
433
|
-
}));
|
|
434
|
-
daemonConfig = JSON.parse(fs_1.default.readFileSync(daemonConfigPath, { encoding: 'utf8' }));
|
|
435
|
-
}
|
|
436
|
-
if (this.daemonConfig) {
|
|
437
|
-
daemonConfig = Object.assign(daemonConfig || {}, JSON.parse(this.daemonConfig));
|
|
438
|
-
}
|
|
439
|
-
let daemonConfigStr = '{}';
|
|
440
|
-
if (daemonConfig) {
|
|
441
|
-
daemonConfigStr = JSON.stringify(daemonConfig, null, 2);
|
|
442
|
-
yield core.group('Docker daemon config', () => __awaiter(this, void 0, void 0, function* () {
|
|
443
|
-
core.info(daemonConfigStr);
|
|
444
|
-
}));
|
|
445
|
-
}
|
|
446
|
-
const params = {
|
|
447
|
-
ToolDir: this.toolDir,
|
|
448
|
-
RunDir: this.runDir,
|
|
449
|
-
DockerHostSocket: dockerHostSocket,
|
|
450
|
-
DaemonConfig: daemonConfigStr
|
|
451
|
-
};
|
|
452
|
-
if (this.localTCPPort) {
|
|
453
|
-
params['DockerHostTCP'] = `tcp://127.0.0.1:${this.localTCPPort}`;
|
|
454
|
-
}
|
|
455
|
-
yield core.group('Install Docker daemon service', () => __awaiter(this, void 0, void 0, function* () {
|
|
456
|
-
const setupCmd = yield util_1.Util.powershellCommand((0, assets_1.setupDockerWinPs1)(), params);
|
|
457
|
-
yield exec_1.Exec.exec(setupCmd.command, setupCmd.args);
|
|
458
|
-
const logCmd = yield util_1.Util.powershellCommand((0, assets_1.dockerServiceLogsPs1)());
|
|
459
|
-
yield exec_1.Exec.exec(logCmd.command, logCmd.args);
|
|
460
|
-
}));
|
|
461
|
-
yield core.group('Create Docker context', () => __awaiter(this, void 0, void 0, function* () {
|
|
462
|
-
yield docker_1.Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHostSocket}`]);
|
|
463
|
-
yield docker_1.Docker.exec(['context', 'use', this.contextName]);
|
|
464
|
-
}));
|
|
465
|
-
return dockerHostSocket;
|
|
410
|
+
await core.group('Create Docker context', async () => {
|
|
411
|
+
await Docker.exec(['context', 'create', this.contextName, '--docker', `host=${dockerHostSocket}`]);
|
|
412
|
+
await Docker.exec(['context', 'use', this.contextName]);
|
|
466
413
|
});
|
|
414
|
+
return dockerHostSocket;
|
|
467
415
|
}
|
|
468
|
-
tearDown() {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
break;
|
|
477
|
-
}
|
|
478
|
-
case 'linux': {
|
|
479
|
-
yield this.tearDownLinux();
|
|
480
|
-
break;
|
|
481
|
-
}
|
|
482
|
-
case 'win32': {
|
|
483
|
-
yield this.tearDownWindows();
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
default: {
|
|
487
|
-
throw new Error(`Unsupported platform: ${os_1.default.platform()}`);
|
|
488
|
-
}
|
|
416
|
+
async tearDown() {
|
|
417
|
+
if (!this.runDir) {
|
|
418
|
+
throw new Error('runDir must be set');
|
|
419
|
+
}
|
|
420
|
+
switch (os.platform()) {
|
|
421
|
+
case 'darwin': {
|
|
422
|
+
await this.tearDownDarwin();
|
|
423
|
+
break;
|
|
489
424
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
425
|
+
case 'linux': {
|
|
426
|
+
await this.tearDownLinux();
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
case 'win32': {
|
|
430
|
+
await this.tearDownWindows();
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
default: {
|
|
434
|
+
throw new Error(`Unsupported platform: ${os.platform()}`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
await core.group(`Cleaning up toolDir`, async () => {
|
|
438
|
+
if (!this._toolDir) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
fs.rmSync(this._toolDir, { recursive: true, force: true });
|
|
496
442
|
});
|
|
497
443
|
}
|
|
498
|
-
tearDownDarwin() {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
yield exec_1.Exec.exec('sudo', ['rm', '-rf', this.runDir]);
|
|
516
|
-
}));
|
|
444
|
+
async tearDownDarwin() {
|
|
445
|
+
await core.group('Docker daemon logs', async () => {
|
|
446
|
+
await Exec.exec('limactl', ['shell', '--tty=false', this.limaInstanceName, 'sudo', 'journalctl', '-u', 'docker.service', '-l', '--no-pager']).catch(() => {
|
|
447
|
+
core.warning(`Failed to get Docker daemon logs`);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
await core.group('Stopping lima instance', async () => {
|
|
451
|
+
await Exec.exec('limactl', ['stop', '--tty=false', this.limaInstanceName, '--force']);
|
|
452
|
+
});
|
|
453
|
+
await core.group('Removing lima instance', async () => {
|
|
454
|
+
await Exec.exec('limactl', ['delete', '--tty=false', this.limaInstanceName, '--force']);
|
|
455
|
+
});
|
|
456
|
+
await core.group('Removing Docker context', async () => {
|
|
457
|
+
await Docker.exec(['context', 'rm', '-f', this.contextName]);
|
|
458
|
+
});
|
|
459
|
+
await core.group(`Cleaning up runDir`, async () => {
|
|
460
|
+
await Exec.exec('sudo', ['rm', '-rf', this.runDir]);
|
|
517
461
|
});
|
|
518
462
|
}
|
|
519
|
-
tearDownLinux() {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
});
|
|
536
|
-
}));
|
|
463
|
+
async tearDownLinux() {
|
|
464
|
+
await core.group('Docker daemon logs', async () => {
|
|
465
|
+
core.info(fs.readFileSync(path.join(this.runDir, 'dockerd.log'), { encoding: 'utf8' }));
|
|
466
|
+
});
|
|
467
|
+
await core.group('Stopping Docker daemon', async () => {
|
|
468
|
+
await Exec.exec('sudo', ['kill', '-s', 'SIGTERM', fs.readFileSync(path.join(this.runDir, 'docker.pid')).toString().trim()]);
|
|
469
|
+
await Util.sleep(5);
|
|
470
|
+
});
|
|
471
|
+
await core.group('Removing Docker context', async () => {
|
|
472
|
+
await Docker.exec(['context', 'rm', '-f', this.contextName]);
|
|
473
|
+
});
|
|
474
|
+
await core.group(`Cleaning up runDir`, async () => {
|
|
475
|
+
await Exec.exec('sudo', ['rm', '-rf', this.runDir], {
|
|
476
|
+
ignoreReturnCode: true,
|
|
477
|
+
failOnStdErr: false
|
|
478
|
+
});
|
|
537
479
|
});
|
|
538
480
|
}
|
|
539
|
-
tearDownWindows() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
yield exec_1.Exec.exec('powershell', ['-Command', `Stop-Service -Name docker -Force`]);
|
|
550
|
-
}));
|
|
481
|
+
async tearDownWindows() {
|
|
482
|
+
await core.group('Docker daemon logs', async () => {
|
|
483
|
+
const logCmd = await Util.powershellCommand(dockerServiceLogsPs1());
|
|
484
|
+
await Exec.exec(logCmd.command, logCmd.args);
|
|
485
|
+
});
|
|
486
|
+
await core.group('Removing Docker context', async () => {
|
|
487
|
+
await Docker.exec(['context', 'rm', '-f', this.contextName]);
|
|
488
|
+
});
|
|
489
|
+
await core.group('Stopping Docker daemon service', async () => {
|
|
490
|
+
await Exec.exec('powershell', ['-Command', `Stop-Service -Name docker -Force`]);
|
|
551
491
|
});
|
|
552
492
|
}
|
|
553
493
|
downloadURL(component, version, channel) {
|
|
@@ -557,7 +497,7 @@ EOF`, [], {
|
|
|
557
497
|
return `https://download.docker.com/${platformOS}/static/${channel}/${platformArch}/${component}-${version}${ext}`;
|
|
558
498
|
}
|
|
559
499
|
static platformOS() {
|
|
560
|
-
switch (
|
|
500
|
+
switch (os.platform()) {
|
|
561
501
|
case 'darwin': {
|
|
562
502
|
return 'mac';
|
|
563
503
|
}
|
|
@@ -568,12 +508,12 @@ EOF`, [], {
|
|
|
568
508
|
return 'win';
|
|
569
509
|
}
|
|
570
510
|
default: {
|
|
571
|
-
return
|
|
511
|
+
return os.platform();
|
|
572
512
|
}
|
|
573
513
|
}
|
|
574
514
|
}
|
|
575
515
|
static platformArch() {
|
|
576
|
-
switch (
|
|
516
|
+
switch (os.arch()) {
|
|
577
517
|
case 'x64': {
|
|
578
518
|
return 'x86_64';
|
|
579
519
|
}
|
|
@@ -599,70 +539,62 @@ EOF`, [], {
|
|
|
599
539
|
}
|
|
600
540
|
}
|
|
601
541
|
default: {
|
|
602
|
-
return
|
|
542
|
+
return os.arch();
|
|
603
543
|
}
|
|
604
544
|
}
|
|
605
545
|
}
|
|
606
|
-
static limaInstalled() {
|
|
607
|
-
return
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
return false;
|
|
617
|
-
});
|
|
546
|
+
static async limaInstalled() {
|
|
547
|
+
return await io
|
|
548
|
+
.which('lima', true)
|
|
549
|
+
.then(res => {
|
|
550
|
+
core.debug(`docker.Install.limaInstalled ok: ${res}`);
|
|
551
|
+
return true;
|
|
552
|
+
})
|
|
553
|
+
.catch(error => {
|
|
554
|
+
core.debug(`docker.Install.limaInstalled error: ${error}`);
|
|
555
|
+
return false;
|
|
618
556
|
});
|
|
619
557
|
}
|
|
620
|
-
static qemuBin() {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return `qemu-system-x86_64`;
|
|
625
|
-
}
|
|
626
|
-
case 'arm64': {
|
|
627
|
-
return `qemu-system-aarch64`;
|
|
628
|
-
}
|
|
629
|
-
default: {
|
|
630
|
-
return `qemu-system-${os_1.default.arch()}`;
|
|
631
|
-
}
|
|
558
|
+
static async qemuBin() {
|
|
559
|
+
switch (os.arch()) {
|
|
560
|
+
case 'x64': {
|
|
561
|
+
return `qemu-system-x86_64`;
|
|
632
562
|
}
|
|
633
|
-
|
|
563
|
+
case 'arm64': {
|
|
564
|
+
return `qemu-system-aarch64`;
|
|
565
|
+
}
|
|
566
|
+
default: {
|
|
567
|
+
return `qemu-system-${os.arch()}`;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
634
570
|
}
|
|
635
|
-
static qemuInstalled() {
|
|
636
|
-
return
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
return false;
|
|
646
|
-
});
|
|
571
|
+
static async qemuInstalled() {
|
|
572
|
+
return await io
|
|
573
|
+
.which(await Install.qemuBin(), true)
|
|
574
|
+
.then(res => {
|
|
575
|
+
core.debug(`docker.Install.qemuInstalled ok: ${res}`);
|
|
576
|
+
return true;
|
|
577
|
+
})
|
|
578
|
+
.catch(error => {
|
|
579
|
+
core.debug(`docker.Install.qemuInstalled error: ${error}`);
|
|
580
|
+
return false;
|
|
647
581
|
});
|
|
648
582
|
}
|
|
649
|
-
static getRelease(version, githubToken) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
path: '.github/docker-releases.json'
|
|
657
|
-
});
|
|
658
|
-
if (!releases[version]) {
|
|
659
|
-
if (!releases['v' + version]) {
|
|
660
|
-
throw new Error(`Cannot find Docker release ${version} in releases JSON`);
|
|
661
|
-
}
|
|
662
|
-
return releases['v' + version];
|
|
663
|
-
}
|
|
664
|
-
return releases[version];
|
|
583
|
+
static async getRelease(version, githubToken) {
|
|
584
|
+
const github = new GitHub({ token: githubToken });
|
|
585
|
+
const releases = await github.releases('Docker', {
|
|
586
|
+
owner: 'docker',
|
|
587
|
+
repo: 'actions-toolkit',
|
|
588
|
+
ref: 'main',
|
|
589
|
+
path: '.github/docker-releases.json'
|
|
665
590
|
});
|
|
591
|
+
if (!releases[version]) {
|
|
592
|
+
if (!releases['v' + version]) {
|
|
593
|
+
throw new Error(`Cannot find Docker release ${version} in releases JSON`);
|
|
594
|
+
}
|
|
595
|
+
return releases['v' + version];
|
|
596
|
+
}
|
|
597
|
+
return releases[version];
|
|
666
598
|
}
|
|
667
599
|
static limaCustomImages() {
|
|
668
600
|
const res = [];
|
|
@@ -670,7 +602,7 @@ EOF`, [], {
|
|
|
670
602
|
if (!env) {
|
|
671
603
|
return res;
|
|
672
604
|
}
|
|
673
|
-
for (const input of
|
|
605
|
+
for (const input of Util.getList(env, { ignoreComma: true, comment: '#' })) {
|
|
674
606
|
const archIndex = input.indexOf(':');
|
|
675
607
|
const arch = input.substring(0, archIndex).trim();
|
|
676
608
|
const digestIndex = input.indexOf('@');
|
|
@@ -684,91 +616,85 @@ EOF`, [], {
|
|
|
684
616
|
}
|
|
685
617
|
return res;
|
|
686
618
|
}
|
|
687
|
-
imageConfig(image, platform) {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
image: image,
|
|
692
|
-
platform: platform
|
|
693
|
-
});
|
|
694
|
-
const configDigest = (_a = manifest === null || manifest === void 0 ? void 0 : manifest.config) === null || _a === void 0 ? void 0 : _a.digest;
|
|
695
|
-
if (!configDigest) {
|
|
696
|
-
throw new Error(`No config digest found for image ${image}`);
|
|
697
|
-
}
|
|
698
|
-
const blob = yield this.regctl.blobGet({
|
|
699
|
-
repository: image,
|
|
700
|
-
digest: configDigest
|
|
701
|
-
});
|
|
702
|
-
return JSON.parse(blob);
|
|
619
|
+
async imageConfig(image, platform) {
|
|
620
|
+
const manifest = await this.regctl.manifestGet({
|
|
621
|
+
image: image,
|
|
622
|
+
platform: platform
|
|
703
623
|
});
|
|
624
|
+
const configDigest = manifest?.config?.digest;
|
|
625
|
+
if (!configDigest) {
|
|
626
|
+
throw new Error(`No config digest found for image ${image}`);
|
|
627
|
+
}
|
|
628
|
+
const blob = await this.regctl.blobGet({
|
|
629
|
+
repository: image,
|
|
630
|
+
digest: configDigest
|
|
631
|
+
});
|
|
632
|
+
return JSON.parse(blob);
|
|
704
633
|
}
|
|
705
|
-
brewInstall(packageName, revision) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
throw new Error(res.stderr);
|
|
726
|
-
}
|
|
727
|
-
for (const line of res.stdout.trim().split('\n')) {
|
|
728
|
-
if (line.includes(dockerTap)) {
|
|
729
|
-
return true;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
return false;
|
|
733
|
-
});
|
|
734
|
-
if (!hasDockerTap) {
|
|
735
|
-
yield exec_1.Exec.exec('brew', ['tap-new', dockerTap], { env: envs });
|
|
634
|
+
async brewInstall(packageName, revision) {
|
|
635
|
+
// avoid brew to auto update and upgrade unrelated packages.
|
|
636
|
+
const envs = Object.assign({}, process.env, {
|
|
637
|
+
HOMEBREW_NO_AUTO_UPDATE: '1',
|
|
638
|
+
HOMEBREW_NO_INSTALL_UPGRADE: '1',
|
|
639
|
+
HOMEBREW_NO_INSTALL_CLEANUP: '1'
|
|
640
|
+
});
|
|
641
|
+
await core.group(`Installing ${packageName}`, async () => {
|
|
642
|
+
if (!revision) {
|
|
643
|
+
await Exec.exec('brew', ['install', packageName]);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
const dockerTap = 'docker-actions-toolkit/tap';
|
|
647
|
+
const hasDockerTap = await Exec.getExecOutput('brew', ['tap'], {
|
|
648
|
+
ignoreReturnCode: true,
|
|
649
|
+
silent: true,
|
|
650
|
+
env: envs
|
|
651
|
+
}).then(res => {
|
|
652
|
+
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
653
|
+
throw new Error(res.stderr);
|
|
736
654
|
}
|
|
737
|
-
const
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
env: envs
|
|
741
|
-
}).then(res => {
|
|
742
|
-
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
743
|
-
throw new Error(res.stderr);
|
|
655
|
+
for (const line of res.stdout.trim().split('\n')) {
|
|
656
|
+
if (line.includes(dockerTap)) {
|
|
657
|
+
return true;
|
|
744
658
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
659
|
+
}
|
|
660
|
+
return false;
|
|
661
|
+
});
|
|
662
|
+
if (!hasDockerTap) {
|
|
663
|
+
await Exec.exec('brew', ['tap-new', dockerTap], { env: envs });
|
|
664
|
+
}
|
|
665
|
+
const brewRepoTapPath = await Exec.getExecOutput('brew', ['--repo', dockerTap], {
|
|
666
|
+
ignoreReturnCode: true,
|
|
667
|
+
silent: true,
|
|
668
|
+
env: envs
|
|
669
|
+
}).then(res => {
|
|
670
|
+
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
671
|
+
throw new Error(res.stderr);
|
|
672
|
+
}
|
|
673
|
+
return res.stdout.trim();
|
|
674
|
+
});
|
|
675
|
+
const formulaURL = `https://raw.githubusercontent.com/Homebrew/homebrew-core/${revision}/Formula/${packageName.charAt(0)}/${packageName}.rb`;
|
|
676
|
+
await tc.downloadTool(formulaURL, path.join(brewRepoTapPath, 'Formula', `${packageName}.rb`));
|
|
677
|
+
const hasFormulaInstalled = await Exec.getExecOutput('brew', ['ls', '-1'], {
|
|
678
|
+
ignoreReturnCode: true,
|
|
679
|
+
silent: true,
|
|
680
|
+
env: envs
|
|
681
|
+
}).then(res => {
|
|
682
|
+
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
683
|
+
throw new Error(res.stderr);
|
|
684
|
+
}
|
|
685
|
+
for (const line of res.stdout.trim().split('\n')) {
|
|
686
|
+
if (line.trim() == packageName) {
|
|
687
|
+
return true;
|
|
761
688
|
}
|
|
762
|
-
return false;
|
|
763
|
-
});
|
|
764
|
-
if (hasFormulaInstalled) {
|
|
765
|
-
yield exec_1.Exec.exec('brew', ['uninstall', packageName, '--ignore-dependencies'], { env: envs });
|
|
766
689
|
}
|
|
767
|
-
|
|
690
|
+
return false;
|
|
691
|
+
});
|
|
692
|
+
if (hasFormulaInstalled) {
|
|
693
|
+
await Exec.exec('brew', ['uninstall', packageName, '--ignore-dependencies'], { env: envs });
|
|
768
694
|
}
|
|
769
|
-
|
|
695
|
+
await Exec.exec('brew', ['install', `${dockerTap}/${packageName}`], { env: envs });
|
|
696
|
+
}
|
|
770
697
|
});
|
|
771
698
|
}
|
|
772
699
|
}
|
|
773
|
-
exports.Install = Install;
|
|
774
700
|
//# sourceMappingURL=install.js.map
|