containerify 3.0.1 → 3.1.1
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 +2 -1
- package/lib/cli.js +2 -4
- package/lib/registry.js +26 -15
- package/lib/types.d.ts +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ This will take the `nginx:alpine` image, and copy the files from `./dist/` into
|
|
|
45
45
|
|
|
46
46
|
1. Create the repository in GitLab
|
|
47
47
|
2. Login using your username and password, [CI-credentials](https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html), or [obtain a token from GitLab](https://docs.gitlab.com/ee/api/container_registry.html#obtain-token-from-gitlab)
|
|
48
|
-
3. Example using CI-credentials `containerify --toToken "Basic $(echo -n
|
|
48
|
+
3. Example using CI-credentials `containerify --toToken "Basic $(echo -n "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" | base64)" --to registry.gitlab.com/<Gitlab organisation>/<repository>:<tag>`
|
|
49
49
|
|
|
50
50
|
### Command line options
|
|
51
51
|
|
|
@@ -80,6 +80,7 @@ Options:
|
|
|
80
80
|
--setTimeStamp <timestamp> Optional: Set a specific ISO 8601 timestamp on all entries (e.g. git commit hash). Default: 1970 in tar files, and current time on manifest/config
|
|
81
81
|
--verbose Verbose logging
|
|
82
82
|
--allowInsecureRegistries Allow insecure registries (with self-signed/untrusted cert)
|
|
83
|
+
--allowNoPushAuth Allow pushing images without authentication/token if the registry allows it
|
|
83
84
|
--customContent <dirs/files> Optional: Skip normal node_modules and applayer and include specified root folder files/directories instead. You can specify as
|
|
84
85
|
local-path:absolute-container-path if you want to place it in a specific location
|
|
85
86
|
--extraContent <dirs/files> Optional: Add specific content. Specify as local-path:absolute-container-path,local-path2:absolute-container-path2 etc
|
package/lib/cli.js
CHANGED
|
@@ -53,6 +53,7 @@ const possibleArgs = {
|
|
|
53
53
|
"--setTimeStamp <timestamp>": "Optional: Set a specific ISO 8601 timestamp on all entries (e.g. git commit hash). Default: 1970 in tar files, and current time on manifest/config",
|
|
54
54
|
"--verbose": "Verbose logging",
|
|
55
55
|
"--allowInsecureRegistries": "Allow insecure registries (with self-signed/untrusted cert)",
|
|
56
|
+
"--allowNoPushAuth": "Allow pushing images without a authentication/token to registries that allow it",
|
|
56
57
|
"--customContent <dirs/files>": "Optional: Skip normal node_modules and applayer and include specified root folder files/directories instead. You can specify as local-path:absolute-container-path if you want to place it in a specific location",
|
|
57
58
|
"--extraContent <dirs/files>": "Optional: Add specific content. Specify as local-path:absolute-container-path,local-path2:absolute-container-path2 etc",
|
|
58
59
|
"--layerOwner <gid:uid>": "Optional: Set specific gid and uid on files in the added layers",
|
|
@@ -196,7 +197,7 @@ exitWithErrorIf(!options.folder, "--folder must be specified");
|
|
|
196
197
|
exitWithErrorIf(!options.fromImage, "--fromImage must be specified");
|
|
197
198
|
exitWithErrorIf(!options.toImage, "--toImage must be specified");
|
|
198
199
|
exitWithErrorIf(!options.toRegistry && !options.toTar && !options.toDocker, "Must specify either --toTar, --toRegistry or --toDocker");
|
|
199
|
-
exitWithErrorIf(!!options.toRegistry && !options.toToken, "A token must be
|
|
200
|
+
exitWithErrorIf(!!options.toRegistry && !options.toToken && !options.allowNoPushAuth, "A token must be provided when uploading images");
|
|
200
201
|
if (options.toRegistry && !options.toRegistry.endsWith("/"))
|
|
201
202
|
options.toRegistry += "/";
|
|
202
203
|
if (options.fromRegistry && !options.fromRegistry.endsWith("/"))
|
|
@@ -250,9 +251,6 @@ function run(options) {
|
|
|
250
251
|
yield tarExporter_1.default.saveToTar(todir, tmpdir, options.toTar, [options.toImage], options);
|
|
251
252
|
}
|
|
252
253
|
if (options.toRegistry) {
|
|
253
|
-
if (!options.token && allowInsecure == types_1.InsecureRegistrySupport.NO) {
|
|
254
|
-
throw new Error("Need auth token to upload to " + options.toRegistry);
|
|
255
|
-
}
|
|
256
254
|
const toRegistry = yield (0, registry_1.createRegistry)(options.toRegistry, options.toImage, allowInsecure, options.toToken, options.optimisticToRegistryCheck);
|
|
257
255
|
yield toRegistry.upload(options.toImage, todir, options.doCrossMount, originalManifest, options.fromImage);
|
|
258
256
|
}
|
package/lib/registry.js
CHANGED
|
@@ -98,11 +98,13 @@ function uploadContent(uploadUrl, file, fileConfig, allowInsecure, auth, content
|
|
|
98
98
|
let url = uploadUrl;
|
|
99
99
|
if (fileConfig.digest)
|
|
100
100
|
url += (url.indexOf("?") == -1 ? "?" : "&") + "digest=" + fileConfig.digest;
|
|
101
|
-
const
|
|
102
|
-
authorization: auth,
|
|
101
|
+
const headers = {
|
|
103
102
|
"content-length": fileConfig.size,
|
|
104
103
|
"content-type": contentType,
|
|
105
|
-
}
|
|
104
|
+
};
|
|
105
|
+
if (auth)
|
|
106
|
+
headers.authorization = auth;
|
|
107
|
+
const options = (0, httpRequest_1.createHttpOptions)("PUT", url, headers);
|
|
106
108
|
logger_1.default.debug(options.method, url);
|
|
107
109
|
const req = (0, httpRequest_1.request)(options, allowInsecure, (res) => {
|
|
108
110
|
var _a;
|
|
@@ -128,19 +130,12 @@ function processToken(registryBaseUrl, allowInsecure, imagePath, token) {
|
|
|
128
130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
129
131
|
const { hostname } = URL.parse(registryBaseUrl);
|
|
130
132
|
const image = (0, utils_1.parseImage)(imagePath);
|
|
131
|
-
if ((hostname === null || hostname === void 0 ? void 0 : hostname.endsWith(".docker.io")) && !token)
|
|
132
|
-
|
|
133
|
-
return `Bearer ${resp.token}`;
|
|
134
|
-
}
|
|
135
|
-
if ((hostname === null || hostname === void 0 ? void 0 : hostname.endsWith(".gitlab.com")) && (token === null || token === void 0 ? void 0 : token.startsWith("Basic"))) {
|
|
136
|
-
if (token === null || token === void 0 ? void 0 : token.includes(":")) {
|
|
137
|
-
token = "Basic " + Buffer.from(token === null || token === void 0 ? void 0 : token.replace("Basic ", "")).toString("base64");
|
|
138
|
-
}
|
|
139
|
-
const resp = yield (0, httpRequest_1.dlJson)(`https://gitlab.com/jwt/auth?service=container_registry&scope=repository:${image.path}:pull,push`, { Authorization: token }, allowInsecure);
|
|
140
|
-
return `Bearer ${resp.token}`;
|
|
141
|
-
}
|
|
133
|
+
if ((hostname === null || hostname === void 0 ? void 0 : hostname.endsWith(".docker.io")) && !token)
|
|
134
|
+
return getDockerToken(image.path, allowInsecure);
|
|
142
135
|
if (!token)
|
|
143
136
|
return ""; //We allow to pull from tokenless registries
|
|
137
|
+
if ((hostname === null || hostname === void 0 ? void 0 : hostname.endsWith(".gitlab.com")) && token.startsWith("Basic "))
|
|
138
|
+
return getGitLabToken(token, image.path, allowInsecure);
|
|
144
139
|
if (token.startsWith("Basic "))
|
|
145
140
|
return token;
|
|
146
141
|
if (token.startsWith("ghp_"))
|
|
@@ -148,6 +143,21 @@ function processToken(registryBaseUrl, allowInsecure, imagePath, token) {
|
|
|
148
143
|
return "Bearer " + token;
|
|
149
144
|
});
|
|
150
145
|
}
|
|
146
|
+
function getDockerToken(imagePath, allowInsecure) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
const resp = yield (0, httpRequest_1.dlJson)(`https://auth.docker.io/token?service=registry.docker.io&scope=repository:${imagePath}:pull`, {}, allowInsecure);
|
|
149
|
+
return `Bearer ${resp.token}`;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function getGitLabToken(token, imagePath, allowInsecure) {
|
|
153
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
+
if (token.includes(":")) {
|
|
155
|
+
token = "Basic " + Buffer.from(token === null || token === void 0 ? void 0 : token.replace("Basic ", "")).toString("base64");
|
|
156
|
+
}
|
|
157
|
+
const resp = yield (0, httpRequest_1.dlJson)(`https://gitlab.com/jwt/auth?service=container_registry&scope=repository:${imagePath}:pull,push`, { Authorization: token }, allowInsecure);
|
|
158
|
+
return `Bearer ${resp.token}`;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
151
161
|
function createRegistry(registryBaseUrl, imagePath, allowInsecure, auth, optimisticToRegistryCheck = false) {
|
|
152
162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
153
163
|
const token = yield processToken(registryBaseUrl, allowInsecure, imagePath, auth);
|
|
@@ -171,7 +181,8 @@ function createRegistry(registryBaseUrl, imagePath, allowInsecure, auth, optimis
|
|
|
171
181
|
const url = `${registryBaseUrl}${image.path}/blobs/uploads/${parameters.size > 0 ? "?" + parameters : ""}`;
|
|
172
182
|
const options = URL.parse(url);
|
|
173
183
|
options.method = "POST";
|
|
174
|
-
|
|
184
|
+
if (token)
|
|
185
|
+
options.headers = { authorization: token };
|
|
175
186
|
(0, httpRequest_1.request)(options, allowInsecure, (res) => {
|
|
176
187
|
logger_1.default.debug("POST", `${url}`, res.statusCode);
|
|
177
188
|
if (res.statusCode == 202) {
|
package/lib/types.d.ts
CHANGED
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "3.
|
|
1
|
+
export declare const VERSION = "3.1.1";
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "containerify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Build node.js docker images without docker",
|
|
5
5
|
"main": "./lib/cli.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,12 +12,16 @@
|
|
|
12
12
|
"check": "npm run lint && npm run typecheck",
|
|
13
13
|
"dev": "tsc --watch",
|
|
14
14
|
"integrationTest": "cd tests/integration/ && ./test.sh",
|
|
15
|
-
"registryTest": "cd tests/localtest/ && ./test.sh"
|
|
15
|
+
"registryTest": "cd tests/localtest/ && ./test.sh && ./test-insecure.sh",
|
|
16
|
+
"allTests": "npm run integrationTest && npm run registryTest"
|
|
16
17
|
},
|
|
17
18
|
"bin": {
|
|
18
19
|
"containerify": "./lib/cli.js"
|
|
19
20
|
},
|
|
20
21
|
"author": "Erlend Oftedal <erlend@oftedal.no>",
|
|
22
|
+
"contributors": [
|
|
23
|
+
"Vegard S. Hagen <vegard@stonegarden.dev>"
|
|
24
|
+
],
|
|
21
25
|
"license": "Apache-2.0",
|
|
22
26
|
"repository": {
|
|
23
27
|
"type": "git",
|