containerify 3.0.0 → 3.0.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/lib/cli.js CHANGED
@@ -235,7 +235,7 @@ function run(options) {
235
235
  const todir = yield (0, fileutil_1.ensureEmptyDir)(path.join(tmpdir, "to"));
236
236
  const allowInsecure = options.allowInsecureRegistries ? types_1.InsecureRegistrySupport.YES : types_1.InsecureRegistrySupport.NO;
237
237
  const fromRegistryUrl = (_a = options.fromRegistry) !== null && _a !== void 0 ? _a : registry_1.DEFAULT_DOCKER_REGISTRY;
238
- const fromRegistry = (0, registry_1.createRegistry)(fromRegistryUrl, yield (0, registry_1.processToken)(fromRegistryUrl, allowInsecure, options.fromImage, options.fromToken), allowInsecure);
238
+ const fromRegistry = yield (0, registry_1.createRegistry)(fromRegistryUrl, options.fromImage, allowInsecure, options.fromToken);
239
239
  const originalManifest = yield fromRegistry.download(options.fromImage, fromdir, (0, utils_1.getPreferredPlatform)(options.platform), options.layerCacheFolder);
240
240
  yield appLayerCreator_1.default.addLayers(tmpdir, fromdir, todir, options);
241
241
  if (options.toDocker) {
@@ -250,7 +250,10 @@ function run(options) {
250
250
  yield tarExporter_1.default.saveToTar(todir, tmpdir, options.toTar, [options.toImage], options);
251
251
  }
252
252
  if (options.toRegistry) {
253
- const toRegistry = (0, registry_1.createRegistry)(options.toRegistry, yield (0, registry_1.processToken)(options.toRegistry, allowInsecure, options.toImage, options.toToken), allowInsecure, options.optimisticToRegistryCheck);
253
+ if (!options.token && allowInsecure == types_1.InsecureRegistrySupport.NO) {
254
+ throw new Error("Need auth token to upload to " + options.toRegistry);
255
+ }
256
+ const toRegistry = yield (0, registry_1.createRegistry)(options.toRegistry, options.toImage, allowInsecure, options.toToken, options.optimisticToRegistryCheck);
254
257
  yield toRegistry.upload(options.toImage, todir, options.doCrossMount, originalManifest, options.fromImage);
255
258
  }
256
259
  logger_1.default.debug("Deleting " + tmpdir + " ...");
package/lib/registry.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { InsecureRegistrySupport, Registry } from "./types";
2
- export declare function processToken(registryBaseUrl: string, allowInsecure: InsecureRegistrySupport, imagePath: string, token?: string): Promise<string>;
3
- export declare function createRegistry(registryBaseUrl: string, auth: string, allowInsecure: InsecureRegistrySupport, optimisticToRegistryCheck?: boolean): Registry;
2
+ export declare function createRegistry(registryBaseUrl: string, imagePath: string, allowInsecure: InsecureRegistrySupport, auth?: string, optimisticToRegistryCheck?: boolean): Promise<Registry>;
4
3
  export declare const DEFAULT_DOCKER_REGISTRY = "https://registry-1.docker.io/v2/";
5
4
  export declare function parseFullImageUrl(imageStr: string): {
6
5
  registry: string;
package/lib/registry.js CHANGED
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.parseFullImageUrl = exports.DEFAULT_DOCKER_REGISTRY = exports.createRegistry = exports.processToken = void 0;
12
+ exports.parseFullImageUrl = exports.DEFAULT_DOCKER_REGISTRY = exports.createRegistry = void 0;
13
13
  const URL = require("url");
14
14
  const fss = require("fs");
15
15
  const fs_1 = require("fs");
@@ -140,7 +140,7 @@ function processToken(registryBaseUrl, allowInsecure, imagePath, token) {
140
140
  return `Bearer ${resp.token}`;
141
141
  }
142
142
  if (!token)
143
- throw new Error("Needs auth token to upload to " + registryBaseUrl);
143
+ return ""; //We allow to pull from tokenless registries
144
144
  if (token.startsWith("Basic "))
145
145
  return token;
146
146
  if (token.startsWith("ghp_"))
@@ -148,181 +148,183 @@ function processToken(registryBaseUrl, allowInsecure, imagePath, token) {
148
148
  return "Bearer " + token;
149
149
  });
150
150
  }
151
- exports.processToken = processToken;
152
- function createRegistry(registryBaseUrl, auth, allowInsecure, optimisticToRegistryCheck = false) {
153
- function exists(image, layer) {
154
- return __awaiter(this, void 0, void 0, function* () {
155
- const url = `${registryBaseUrl}${image.path}/blobs/${layer.digest}`;
156
- return yield checkIfLayerExists(url, (0, httpRequest_1.buildHeaders)(layer.mediaType, auth), allowInsecure, optimisticToRegistryCheck, 0);
157
- });
158
- }
159
- function uploadLayerContent(uploadUrl, layer, dir) {
160
- return __awaiter(this, void 0, void 0, function* () {
161
- logger_1.default.info(layer.digest);
162
- const file = path.join(dir, (0, utils_1.getHash)(layer.digest) + (0, utils_1.getLayerTypeFileEnding)(layer));
163
- yield uploadContent(uploadUrl, file, layer, allowInsecure, auth);
164
- });
165
- }
166
- function getUploadUrl(image, mountParameters = undefined) {
167
- return __awaiter(this, void 0, void 0, function* () {
168
- return new Promise((resolve, reject) => {
169
- const parameters = new URLSearchParams(mountParameters);
170
- const url = `${registryBaseUrl}${image.path}/blobs/uploads/${parameters.size > 0 ? "?" + parameters : ""}`;
171
- const options = URL.parse(url);
172
- options.method = "POST";
173
- options.headers = { authorization: auth };
174
- (0, httpRequest_1.request)(options, allowInsecure, (res) => {
175
- logger_1.default.debug("POST", `${url}`, res.statusCode);
176
- if (res.statusCode == 202) {
177
- const { location } = res.headers;
178
- if (location) {
179
- if (location.startsWith("http")) {
180
- resolve({ uploadUrl: location });
151
+ function createRegistry(registryBaseUrl, imagePath, allowInsecure, auth, optimisticToRegistryCheck = false) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ const token = yield processToken(registryBaseUrl, allowInsecure, imagePath, auth);
154
+ function exists(image, layer) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ const url = `${registryBaseUrl}${image.path}/blobs/${layer.digest}`;
157
+ return yield checkIfLayerExists(url, (0, httpRequest_1.buildHeaders)(layer.mediaType, token), allowInsecure, optimisticToRegistryCheck, 0);
158
+ });
159
+ }
160
+ function uploadLayerContent(uploadUrl, layer, dir) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ logger_1.default.info(layer.digest);
163
+ const file = path.join(dir, (0, utils_1.getHash)(layer.digest) + (0, utils_1.getLayerTypeFileEnding)(layer));
164
+ yield uploadContent(uploadUrl, file, layer, allowInsecure, token);
165
+ });
166
+ }
167
+ function getUploadUrl(image, mountParameters = undefined) {
168
+ return __awaiter(this, void 0, void 0, function* () {
169
+ return new Promise((resolve, reject) => {
170
+ const parameters = new URLSearchParams(mountParameters);
171
+ const url = `${registryBaseUrl}${image.path}/blobs/uploads/${parameters.size > 0 ? "?" + parameters : ""}`;
172
+ const options = URL.parse(url);
173
+ options.method = "POST";
174
+ options.headers = { authorization: auth };
175
+ (0, httpRequest_1.request)(options, allowInsecure, (res) => {
176
+ logger_1.default.debug("POST", `${url}`, res.statusCode);
177
+ if (res.statusCode == 202) {
178
+ const { location } = res.headers;
179
+ if (location) {
180
+ if (location.startsWith("http")) {
181
+ resolve({ uploadUrl: location });
182
+ }
183
+ else {
184
+ const regURL = URL.parse(registryBaseUrl);
185
+ resolve({
186
+ uploadUrl: `${regURL.protocol}//${regURL.hostname}${regURL.port ? ":" + regURL.port : ""}${location}`,
187
+ });
188
+ }
181
189
  }
182
- else {
183
- const regURL = URL.parse(registryBaseUrl);
184
- resolve({
185
- uploadUrl: `${regURL.protocol}//${regURL.hostname}${regURL.port ? ":" + regURL.port : ""}${location}`,
186
- });
190
+ reject("Missing location for 202");
191
+ }
192
+ else if (mountParameters && res.statusCode == 201) {
193
+ const returnedDigest = res.headers["docker-content-digest"];
194
+ if (returnedDigest && returnedDigest != mountParameters.mount) {
195
+ reject(`ERROR: Layer mounted with wrong digest: Expected ${mountParameters.mount} but got ${returnedDigest}`);
187
196
  }
197
+ resolve({ mountSuccess: true });
188
198
  }
189
- reject("Missing location for 202");
190
- }
191
- else if (mountParameters && res.statusCode == 201) {
192
- const returnedDigest = res.headers["docker-content-digest"];
193
- if (returnedDigest && returnedDigest != mountParameters.mount) {
194
- reject(`ERROR: Layer mounted with wrong digest: Expected ${mountParameters.mount} but got ${returnedDigest}`);
199
+ else {
200
+ (0, httpRequest_1.waitForResponseEnd)(res, (data) => {
201
+ reject(`Error getting upload URL from ${url}. Got ${res.statusCode} ${res.statusMessage}:\n${data.toString()}`);
202
+ });
195
203
  }
196
- resolve({ mountSuccess: true });
197
- }
198
- else {
199
- (0, httpRequest_1.waitForResponseEnd)(res, (data) => {
200
- reject(`Error getting upload URL from ${url}. Got ${res.statusCode} ${res.statusMessage}:\n${data.toString()}`);
201
- });
202
- }
203
- }).end();
204
+ }).end();
205
+ });
204
206
  });
205
- });
206
- }
207
- function dlManifest(image, preferredPlatform, allowInsecure) {
208
- return __awaiter(this, void 0, void 0, function* () {
209
- // Accept both manifests and index/manifest lists
210
- const res = yield (0, httpRequest_1.dlJson)(`${registryBaseUrl}${image.path}/manifests/${image.tag}`, (0, httpRequest_1.buildHeaders)(`${MIMETypes_1.OCI.index}, ${MIMETypes_1.OCI.manifest}, ${MIMETypes_1.DockerV2.index}, ${MIMETypes_1.DockerV2.manifest}`, auth), allowInsecure);
211
- // We've received an OCI Index or Docker Manifest List and need to find which manifest we want
212
- if (res.mediaType === MIMETypes_1.OCI.index || res.mediaType === MIMETypes_1.DockerV2.index) {
213
- const availableManifests = res.manifests;
214
- const adequateManifest = pickManifest(availableManifests, preferredPlatform);
215
- return dlManifest(Object.assign(Object.assign({}, image), { tag: adequateManifest.digest }), preferredPlatform, allowInsecure);
207
+ }
208
+ function dlManifest(image, preferredPlatform, allowInsecure) {
209
+ return __awaiter(this, void 0, void 0, function* () {
210
+ // Accept both manifests and index/manifest lists
211
+ const res = yield (0, httpRequest_1.dlJson)(`${registryBaseUrl}${image.path}/manifests/${image.tag}`, (0, httpRequest_1.buildHeaders)(`${MIMETypes_1.OCI.index}, ${MIMETypes_1.OCI.manifest}, ${MIMETypes_1.DockerV2.index}, ${MIMETypes_1.DockerV2.manifest}`, token), allowInsecure);
212
+ // We've received an OCI Index or Docker Manifest List and need to find which manifest we want
213
+ if (res.mediaType === MIMETypes_1.OCI.index || res.mediaType === MIMETypes_1.DockerV2.index) {
214
+ const availableManifests = res.manifests;
215
+ const adequateManifest = pickManifest(availableManifests, preferredPlatform);
216
+ return dlManifest(Object.assign(Object.assign({}, image), { tag: adequateManifest.digest }), preferredPlatform, allowInsecure);
217
+ }
218
+ return res;
219
+ });
220
+ }
221
+ function pickManifest(manifests, preferredPlatform) {
222
+ const matchingArchitectures = new Set();
223
+ const matchingOSes = new Set();
224
+ // Find sets of matching architecture and os
225
+ for (const manifest of manifests) {
226
+ if (manifest.platform.architecture === preferredPlatform.architecture) {
227
+ matchingArchitectures.add(manifest);
228
+ }
229
+ if (manifest.platform.os === preferredPlatform.os) {
230
+ matchingOSes.add(manifest);
231
+ }
216
232
  }
217
- return res;
218
- });
219
- }
220
- function pickManifest(manifests, preferredPlatform) {
221
- const matchingArchitectures = new Set();
222
- const matchingOSes = new Set();
223
- // Find sets of matching architecture and os
224
- for (const manifest of manifests) {
225
- if (manifest.platform.architecture === preferredPlatform.architecture) {
226
- matchingArchitectures.add(manifest);
233
+ // If the intersection of matching architectures and OS is one we've found our optimal match
234
+ const intersection = new Set([...matchingArchitectures].filter((x) => matchingOSes.has(x)));
235
+ if (intersection.size == 1) {
236
+ return intersection.values().next().value;
227
237
  }
228
- if (manifest.platform.os === preferredPlatform.os) {
229
- matchingOSes.add(manifest);
238
+ // If we don't have a perfect match we give a warning and try the first matching architecture
239
+ if (matchingArchitectures.size >= 1) {
240
+ const matchingArch = matchingArchitectures.values().next().value;
241
+ logger_1.default.info(`[WARN] Preferred OS '${preferredPlatform.os}' not available.`);
242
+ logger_1.default.info("[WARN] Using closest available manifest:", JSON.stringify(matchingArch.platform));
243
+ return matchingArch;
230
244
  }
245
+ // If there's no image matching the wanted architecture we bail
246
+ logger_1.default.error(`No image matching requested architecture: '${preferredPlatform.architecture}'`);
247
+ logger_1.default.error("Available platforms:", JSON.stringify(manifests.map((m) => m.platform)));
248
+ throw new Error("No image matching requested architecture");
231
249
  }
232
- // If the intersection of matching architectures and OS is one we've found our optimal match
233
- const intersection = new Set([...matchingArchitectures].filter((x) => matchingOSes.has(x)));
234
- if (intersection.size == 1) {
235
- return intersection.values().next().value;
250
+ function dlConfig(image, config, allowInsecure) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ return yield (0, httpRequest_1.dlJson)(`${registryBaseUrl}${image.path}/blobs/${config.digest}`, (0, httpRequest_1.buildHeaders)("*/*", token), allowInsecure);
253
+ });
236
254
  }
237
- // If we don't have a perfect match we give a warning and try the first matching architecture
238
- if (matchingArchitectures.size >= 1) {
239
- const matchingArch = matchingArchitectures.values().next().value;
240
- logger_1.default.info(`[WARN] Preferred OS '${preferredPlatform.os}' not available.`);
241
- logger_1.default.info("[WARN] Using closest available manifest:", JSON.stringify(matchingArch.platform));
242
- return matchingArch;
255
+ function dlLayer(image, layer, folder, allowInsecure, cacheFolder) {
256
+ return __awaiter(this, void 0, void 0, function* () {
257
+ const file = (0, utils_1.getHash)(layer.digest) + (0, utils_1.getLayerTypeFileEnding)(layer);
258
+ yield dlToFile(`${registryBaseUrl}${image.path}/blobs/${layer.digest}`, path.join(folder, file), (0, httpRequest_1.buildHeaders)(layer.mediaType, token), allowInsecure, cacheFolder);
259
+ return file;
260
+ });
243
261
  }
244
- // If there's no image matching the wanted architecture we bail
245
- logger_1.default.error(`No image matching requested architecture: '${preferredPlatform.architecture}'`);
246
- logger_1.default.error("Available platforms:", JSON.stringify(manifests.map((m) => m.platform)));
247
- throw new Error("No image matching requested architecture");
248
- }
249
- function dlConfig(image, config, allowInsecure) {
250
- return __awaiter(this, void 0, void 0, function* () {
251
- return yield (0, httpRequest_1.dlJson)(`${registryBaseUrl}${image.path}/blobs/${config.digest}`, (0, httpRequest_1.buildHeaders)("*/*", auth), allowInsecure);
252
- });
253
- }
254
- function dlLayer(image, layer, folder, allowInsecure, cacheFolder) {
255
- return __awaiter(this, void 0, void 0, function* () {
256
- const file = (0, utils_1.getHash)(layer.digest) + (0, utils_1.getLayerTypeFileEnding)(layer);
257
- yield dlToFile(`${registryBaseUrl}${image.path}/blobs/${layer.digest}`, path.join(folder, file), (0, httpRequest_1.buildHeaders)(layer.mediaType, auth), allowInsecure, cacheFolder);
258
- return file;
259
- });
260
- }
261
- function upload(imageStr, folder, doCrossMount, originalManifest, originalRepository) {
262
- return __awaiter(this, void 0, void 0, function* () {
263
- const image = (0, utils_1.parseImage)(imageStr);
264
- const manifestFile = path.join(folder, "manifest.json");
265
- const manifest = (yield fse.readJson(manifestFile));
266
- logger_1.default.info("Checking layer status...");
267
- const layerStatus = yield Promise.all(manifest.layers.map((l) => __awaiter(this, void 0, void 0, function* () {
268
- return { layer: l, exists: yield exists(image, l) };
269
- })));
270
- const layersForUpload = layerStatus.filter((l) => !l.exists);
271
- logger_1.default.debug("Needs upload:", layersForUpload.map((l) => l.layer.digest));
272
- logger_1.default.info("Uploading layers...");
273
- yield Promise.all(layersForUpload.map((l) => __awaiter(this, void 0, void 0, function* () {
274
- if (doCrossMount && originalManifest.layers.find((x) => x.digest == l.layer.digest)) {
275
- const mount = yield getUploadUrl(image, { mount: l.layer.digest, from: originalRepository });
276
- if ("mountSuccess" in mount) {
277
- logger_1.default.info(`Cross mounted layer ${l.layer.digest} from '${originalRepository}'`);
278
- return;
262
+ function upload(imageStr, folder, doCrossMount, originalManifest, originalRepository) {
263
+ return __awaiter(this, void 0, void 0, function* () {
264
+ const image = (0, utils_1.parseImage)(imageStr);
265
+ const manifestFile = path.join(folder, "manifest.json");
266
+ const manifest = (yield fse.readJson(manifestFile));
267
+ logger_1.default.info("Checking layer status...");
268
+ const layerStatus = yield Promise.all(manifest.layers.map((l) => __awaiter(this, void 0, void 0, function* () {
269
+ return { layer: l, exists: yield exists(image, l) };
270
+ })));
271
+ const layersForUpload = layerStatus.filter((l) => !l.exists);
272
+ logger_1.default.debug("Needs upload:", layersForUpload.map((l) => l.layer.digest));
273
+ logger_1.default.info("Uploading layers...");
274
+ yield Promise.all(layersForUpload.map((l) => __awaiter(this, void 0, void 0, function* () {
275
+ if (doCrossMount && originalManifest.layers.find((x) => x.digest == l.layer.digest)) {
276
+ const mount = yield getUploadUrl(image, { mount: l.layer.digest, from: originalRepository });
277
+ if ("mountSuccess" in mount) {
278
+ logger_1.default.info(`Cross mounted layer ${l.layer.digest} from '${originalRepository}'`);
279
+ return;
280
+ }
281
+ yield uploadLayerContent(mount.uploadUrl, l.layer, folder);
282
+ }
283
+ else {
284
+ const url = yield getUploadUrl(image);
285
+ if ("mountSuccess" in url)
286
+ throw new Error("Mounting not supported for this upload");
287
+ yield uploadLayerContent(url.uploadUrl, l.layer, folder);
279
288
  }
280
- yield uploadLayerContent(mount.uploadUrl, l.layer, folder);
289
+ })));
290
+ logger_1.default.info("Uploading config...");
291
+ const configUploadUrl = yield getUploadUrl(image);
292
+ if ("mountSuccess" in configUploadUrl)
293
+ throw new Error("Mounting not supported for config upload");
294
+ const configFile = path.join(folder, (0, utils_1.getHash)(manifest.config.digest) + ".json");
295
+ yield uploadContent(configUploadUrl.uploadUrl, configFile, manifest.config, allowInsecure, token);
296
+ logger_1.default.info("Uploading manifest...");
297
+ const manifestSize = yield fileutil.sizeOf(manifestFile);
298
+ yield uploadContent(`${registryBaseUrl}${image.path}/manifests/${image.tag}`, manifestFile, { mediaType: manifest.mediaType, size: manifestSize }, allowInsecure, token, manifest.mediaType);
299
+ });
300
+ }
301
+ function download(imageStr, folder, preferredPlatform, cacheFolder) {
302
+ return __awaiter(this, void 0, void 0, function* () {
303
+ const image = (0, utils_1.parseImage)(imageStr);
304
+ logger_1.default.info("Downloading manifest...");
305
+ const manifest = yield dlManifest(image, preferredPlatform, allowInsecure);
306
+ yield fs_1.promises.writeFile(path.join(folder, "manifest.json"), JSON.stringify(manifest));
307
+ logger_1.default.info("Downloading config...");
308
+ const config = yield dlConfig(image, manifest.config, allowInsecure);
309
+ if (config.architecture != preferredPlatform.architecture) {
310
+ logger_1.default.info(`[WARN] Image architecture (${config.architecture}) does not match preferred architecture (${preferredPlatform.architecture}).`);
281
311
  }
282
- else {
283
- const url = yield getUploadUrl(image);
284
- if ("mountSuccess" in url)
285
- throw new Error("Mounting not supported for this upload");
286
- yield uploadLayerContent(url.uploadUrl, l.layer, folder);
312
+ if (config.os != preferredPlatform.os) {
313
+ logger_1.default.info(`[WARN] Image OS (${config.os}) does not match preferred OS (${preferredPlatform.os}).`);
287
314
  }
288
- })));
289
- logger_1.default.info("Uploading config...");
290
- const configUploadUrl = yield getUploadUrl(image);
291
- if ("mountSuccess" in configUploadUrl)
292
- throw new Error("Mounting not supported for config upload");
293
- const configFile = path.join(folder, (0, utils_1.getHash)(manifest.config.digest) + ".json");
294
- yield uploadContent(configUploadUrl.uploadUrl, configFile, manifest.config, allowInsecure, auth);
295
- logger_1.default.info("Uploading manifest...");
296
- const manifestSize = yield fileutil.sizeOf(manifestFile);
297
- yield uploadContent(`${registryBaseUrl}${image.path}/manifests/${image.tag}`, manifestFile, { mediaType: manifest.mediaType, size: manifestSize }, allowInsecure, auth, manifest.mediaType);
298
- });
299
- }
300
- function download(imageStr, folder, preferredPlatform, cacheFolder) {
301
- return __awaiter(this, void 0, void 0, function* () {
302
- const image = (0, utils_1.parseImage)(imageStr);
303
- logger_1.default.info("Downloading manifest...");
304
- const manifest = yield dlManifest(image, preferredPlatform, allowInsecure);
305
- yield fs_1.promises.writeFile(path.join(folder, "manifest.json"), JSON.stringify(manifest));
306
- logger_1.default.info("Downloading config...");
307
- const config = yield dlConfig(image, manifest.config, allowInsecure);
308
- if (config.architecture != preferredPlatform.architecture) {
309
- logger_1.default.info(`[WARN] Image architecture (${config.architecture}) does not match preferred architecture (${preferredPlatform.architecture}).`);
310
- }
311
- if (config.os != preferredPlatform.os) {
312
- logger_1.default.info(`[WARN] Image OS (${config.os}) does not match preferred OS (${preferredPlatform.os}).`);
313
- }
314
- yield fs_1.promises.writeFile(path.join(folder, "config.json"), JSON.stringify(config));
315
- logger_1.default.info("Downloading layers...");
316
- yield Promise.all(manifest.layers.map((layer) => dlLayer(image, layer, folder, allowInsecure, cacheFolder)));
317
- logger_1.default.info("Image downloaded.");
318
- return manifest;
319
- });
320
- }
321
- return {
322
- download: download,
323
- upload: upload,
324
- registryBaseUrl,
325
- };
315
+ yield fs_1.promises.writeFile(path.join(folder, "config.json"), JSON.stringify(config));
316
+ logger_1.default.info("Downloading layers...");
317
+ yield Promise.all(manifest.layers.map((layer) => dlLayer(image, layer, folder, allowInsecure, cacheFolder)));
318
+ logger_1.default.info("Image downloaded.");
319
+ return manifest;
320
+ });
321
+ }
322
+ return {
323
+ download: download,
324
+ upload: upload,
325
+ registryBaseUrl,
326
+ };
327
+ });
326
328
  }
327
329
  exports.createRegistry = createRegistry;
328
330
  exports.DEFAULT_DOCKER_REGISTRY = "https://registry-1.docker.io/v2/";
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.0.0";
1
+ export declare const VERSION = "3.0.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 = "3.0.0";
4
+ exports.VERSION = "3.0.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "containerify",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Build node.js docker images without docker",
5
5
  "main": "./lib/cli.js",
6
6
  "scripts": {