containerify 2.6.0 → 2.6.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 CHANGED
@@ -21,15 +21,14 @@ containerify --fromImage node:13-slim --folder src/ --toImage myapp:latest --toR
21
21
  ### customContent - Adding compiled code to non-node container
22
22
 
23
23
  If you want to build a non-node container (e.g. add compiled frontend code to an nginx container), you can use `--customContent`. When doing this
24
- the normal `node_modules` etc layers will not be added, and workdir, user and entrypoint will not be overridden (allthough they can be explicitely modified
25
- if needed).
24
+ the normal `node_modules` etc layers will not be added. By default it does _NOT_ modify then entrypoint, user or workdir, so the base image settings are still used when running. You can still override with `--entrypoint` etc. if needed.
26
25
 
27
26
  ```
28
- npm run build
29
- containerify --fromImage nginx:alpine --folder . --toImage frontend:latest --customContent dist:/var/www/html --toRegistry https://registry.example.com/v2/
27
+ npm run build # or some other build command
28
+ containerify --fromImage nginx:alpine --folder . --toImage frontend:latest --customContent dist:/usr/share/nginx/html --toRegistry https://registry.example.com/v2/
30
29
  ```
31
30
 
32
- This will take nginx:alpine and copy the files in `./dist/` into `/var/www/html`.
31
+ This will take the `nginx:alpine` image, and copy the files from `./dist/` into `/usr/share/nginx/html`.
33
32
 
34
33
  ### Command line options
35
34
 
@@ -44,6 +43,7 @@ Options:
44
43
  --fromRegistry <registry url> Optional: URL of registry to pull base image from - Default: https://registry-1.docker.io/v2/
45
44
  --fromToken <token> Optional: Authentication token for from registry
46
45
  --toRegistry <registry url> Optional: URL of registry to push base image to - Default: https://registry-1.docker.io/v2/
46
+ --optimisticToRegistryCheck Optional: Treat redirects as layer existing in remote registry. Potentially unsafe, but could save bandwidth.
47
47
  --toToken <token> Optional: Authentication token for target registry
48
48
  --toTar <path> Optional: Export to tar file
49
49
  --registry <path> Optional: Convenience argument for setting both from and to registry
package/lib/cli.js CHANGED
@@ -32,6 +32,7 @@ const possibleArgs = {
32
32
  "--fromRegistry <registry url>": "Optional: URL of registry to pull base image from - Default: https://registry-1.docker.io/v2/",
33
33
  "--fromToken <token>": "Optional: Authentication token for from registry",
34
34
  "--toRegistry <registry url>": "Optional: URL of registry to push base image to - Default: https://registry-1.docker.io/v2/",
35
+ "--optimisticToRegistryCheck": "Treat redirects as layer existing in remote registry. Potentially unsafe, but can save bandwidth.",
35
36
  "--toToken <token>": "Optional: Authentication token for target registry",
36
37
  "--toTar <path>": "Optional: Export to tar file",
37
38
  "--toDocker": "Optional: Export to local docker registry",
@@ -231,7 +232,7 @@ function run(options) {
231
232
  yield tarExporter_1.default.saveToTar(todir, tmpdir, options.toTar, [options.toImage], options);
232
233
  }
233
234
  if (options.toRegistry) {
234
- const toRegistry = (0, registry_1.createRegistry)(options.toRegistry, (_b = options.toToken) !== null && _b !== void 0 ? _b : "");
235
+ const toRegistry = (0, registry_1.createRegistry)(options.toRegistry, (_b = options.toToken) !== null && _b !== void 0 ? _b : "", options.optimisticToRegistryCheck);
235
236
  yield toRegistry.upload(options.toImage, todir);
236
237
  }
237
238
  logger_1.default.debug("Deleting " + tmpdir + " ...");
package/lib/registry.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Platform } from "./types";
2
- export declare function createRegistry(registryBaseUrl: string, token: string): {
2
+ export declare function createRegistry(registryBaseUrl: string, token: string, optimisticToRegistryCheck?: boolean): {
3
3
  download: (imageStr: string, folder: string, preferredPlatform: Platform, cacheFolder?: string) => Promise<void>;
4
4
  upload: (imageStr: string, folder: string) => Promise<void>;
5
5
  };
package/lib/registry.js CHANGED
@@ -13,15 +13,15 @@ exports.createDockerRegistry = exports.createRegistry = void 0;
13
13
  const https = require("https");
14
14
  const http = require("http");
15
15
  const URL = require("url");
16
+ const fss = require("fs");
16
17
  const fs_1 = require("fs");
17
18
  const path = require("path");
18
19
  const fse = require("fs-extra");
19
- const fss = require("fs");
20
20
  const fileutil = require("./fileutil");
21
21
  const logger_1 = require("./logger");
22
22
  const MIMETypes_1 = require("./MIMETypes");
23
23
  const utils_1 = require("./utils");
24
- const redirectCodes = [307, 303, 302];
24
+ const redirectCodes = [308, 307, 303, 302, 301];
25
25
  function request(options, callback) {
26
26
  return (options.protocol == "https:" ? https : http).request(options, (res) => {
27
27
  callback(res);
@@ -128,18 +128,36 @@ function buildHeaders(accept, auth) {
128
128
  headers.authorization = auth;
129
129
  return headers;
130
130
  }
131
- function headOk(url, headers) {
131
+ function headOk(url, headers, optimisticCheck = false, depth = 0) {
132
+ if (depth >= 5) {
133
+ logger_1.default.info("Followed five redirects, assuming layer does not exist");
134
+ return new Promise((resolve) => resolve(false));
135
+ }
132
136
  return new Promise((resolve, reject) => {
133
137
  logger_1.default.debug(`HEAD ${url}`);
134
138
  const options = URL.parse(url);
135
139
  options.headers = headers;
136
140
  options.method = "HEAD";
137
141
  request(options, (res) => {
142
+ var _a;
138
143
  logger_1.default.debug(`HEAD ${url}`, res.statusCode);
144
+ // Not found
139
145
  if (res.statusCode == 404)
140
146
  return resolve(false);
147
+ // OK
141
148
  if (res.statusCode == 200)
142
149
  return resolve(true);
150
+ // Redirected
151
+ if (redirectCodes.includes((_a = res.statusCode) !== null && _a !== void 0 ? _a : 0) && res.headers.location) {
152
+ if (optimisticCheck)
153
+ return resolve(true);
154
+ return resolve(headOk(res.headers.location, headers, optimisticCheck, ++depth));
155
+ }
156
+ // Unauthorized
157
+ // Possibly related to https://gitlab.com/gitlab-org/gitlab/-/issues/23132
158
+ if (res.statusCode == 401) {
159
+ return resolve(false);
160
+ }
143
161
  reject(toError(res));
144
162
  }).end();
145
163
  });
@@ -175,12 +193,12 @@ function uploadContent(uploadUrl, file, fileConfig, auth) {
175
193
  fss.createReadStream(file).pipe(req);
176
194
  });
177
195
  }
178
- function createRegistry(registryBaseUrl, token) {
196
+ function createRegistry(registryBaseUrl, token, optimisticToRegistryCheck = false) {
179
197
  const auth = token.startsWith("Basic ") ? token : "Bearer " + token;
180
198
  function exists(image, layer) {
181
199
  return __awaiter(this, void 0, void 0, function* () {
182
200
  const url = `${registryBaseUrl}${image.path}/blobs/${layer.digest}`;
183
- return yield headOk(url, buildHeaders(layer.mediaType, auth));
201
+ return yield headOk(url, buildHeaders(layer.mediaType, auth), optimisticToRegistryCheck, 0);
184
202
  });
185
203
  }
186
204
  function uploadLayerContent(uploadUrl, layer, dir) {
package/lib/types.d.ts CHANGED
@@ -61,6 +61,7 @@ export type Options = {
61
61
  fromRegistry?: string;
62
62
  fromToken?: string;
63
63
  toRegistry?: string;
64
+ optimisticToRegistryCheck?: boolean;
64
65
  toToken?: string;
65
66
  toTar?: string;
66
67
  toDocker?: boolean;
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "2.6.0";
1
+ export declare const VERSION = "2.6.1";
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = "2.6.0";
4
+ exports.VERSION = "2.6.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "containerify",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Build node.js docker images without docker",
5
5
  "main": "./lib/cli.js",
6
6
  "scripts": {