testcontainers 12.1.0 → 12.2.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/build/common/file-lock.js +3 -3
- package/build/common/hash.js +2 -2
- package/build/common/index.d.ts +2 -3
- package/build/common/index.js +2 -4
- package/build/common/retry.d.ts +1 -1
- package/build/common/uuid.js +2 -2
- package/build/container-runtime/auth/auths.d.ts +2 -2
- package/build/container-runtime/auth/cred-helpers.d.ts +1 -1
- package/build/container-runtime/auth/credential-provider.d.ts +2 -2
- package/build/container-runtime/auth/credential-provider.js +3 -3
- package/build/container-runtime/auth/creds-store.d.ts +2 -2
- package/build/container-runtime/auth/creds-store.js +1 -1
- package/build/container-runtime/auth/get-auth-config.d.ts +1 -1
- package/build/container-runtime/auth/get-auth-config.js +7 -7
- package/build/container-runtime/auth/registry-auth-locator.d.ts +1 -1
- package/build/container-runtime/auth/registry-matches.js +1 -1
- package/build/container-runtime/clients/client.d.ts +5 -5
- package/build/container-runtime/clients/compose/compose-client.d.ts +1 -1
- package/build/container-runtime/clients/compose/compose-client.js +1 -3
- package/build/container-runtime/clients/compose/default-compose-options.d.ts +2 -2
- package/build/container-runtime/clients/compose/default-compose-options.js +5 -3
- package/build/container-runtime/clients/compose/types.d.ts +3 -2
- package/build/container-runtime/clients/container/container-client.d.ts +5 -4
- package/build/container-runtime/clients/container/docker-container-client.d.ts +6 -5
- package/build/container-runtime/clients/container/docker-container-client.js +13 -9
- package/build/container-runtime/clients/container/types.d.ts +1 -3
- package/build/container-runtime/clients/image/docker-image-client.d.ts +4 -3
- package/build/container-runtime/clients/image/docker-image-client.js +11 -10
- package/build/container-runtime/clients/image/image-client.d.ts +2 -2
- package/build/container-runtime/clients/network/docker-network-client.d.ts +3 -2
- package/build/container-runtime/clients/network/network-client.d.ts +1 -1
- package/build/container-runtime/image-name.d.ts +2 -1
- package/build/container-runtime/image-name.js +23 -13
- package/build/container-runtime/index.d.ts +1 -1
- package/build/container-runtime/strategies/configuration-strategy.d.ts +2 -2
- package/build/container-runtime/strategies/configuration-strategy.js +7 -7
- package/build/container-runtime/strategies/npipe-socket-strategy.d.ts +2 -2
- package/build/container-runtime/strategies/rootless-unix-socket-strategy.d.ts +2 -2
- package/build/container-runtime/strategies/rootless-unix-socket-strategy.js +9 -9
- package/build/container-runtime/strategies/strategy.d.ts +1 -1
- package/build/container-runtime/strategies/testcontainers-host-strategy.d.ts +2 -2
- package/build/container-runtime/strategies/testcontainers-host-strategy.js +2 -2
- package/build/container-runtime/strategies/types.d.ts +1 -1
- package/build/container-runtime/strategies/unix-socket-strategy.d.ts +2 -2
- package/build/container-runtime/strategies/unix-socket-strategy.js +2 -2
- package/build/container-runtime/strategies/utils/config.js +12 -12
- package/build/container-runtime/utils/attach-container.d.ts +2 -2
- package/build/container-runtime/utils/demux-stream.d.ts +2 -2
- package/build/container-runtime/utils/demux-stream.js +2 -2
- package/build/container-runtime/utils/image-exists.d.ts +2 -2
- package/build/container-runtime/utils/lookup-host-ips.d.ts +1 -1
- package/build/container-runtime/utils/lookup-host-ips.js +4 -4
- package/build/container-runtime/utils/pull-image.d.ts +2 -2
- package/build/container-runtime/utils/remote-container-runtime-socket-path.d.ts +1 -1
- package/build/container-runtime/utils/remote-container-runtime-socket-path.js +2 -2
- package/build/container-runtime/utils/resolve-host.d.ts +2 -2
- package/build/container-runtime/utils/resolve-host.js +4 -4
- package/build/container-runtime/utils/run-in-container.d.ts +1 -1
- package/build/container-runtime/utils/run-in-container.js +2 -1
- package/build/container-runtime/utils/start-container.d.ts +1 -1
- package/build/docker-compose-environment/docker-compose-environment.d.ts +5 -5
- package/build/docker-compose-environment/docker-compose-environment.js +18 -8
- package/build/docker-compose-environment/started-docker-compose-environment.d.ts +2 -2
- package/build/docker-compose-environment/stopped-docker-compose-environment.d.ts +1 -1
- package/build/generic-container/abstract-started-container.d.ts +3 -3
- package/build/generic-container/abstract-stopped-container.d.ts +1 -1
- package/build/generic-container/generic-container-builder.d.ts +3 -3
- package/build/generic-container/generic-container-builder.js +11 -6
- package/build/generic-container/generic-container.d.ts +9 -9
- package/build/generic-container/generic-container.js +22 -8
- package/build/generic-container/inspect-container-util-ports-exposed.d.ts +1 -1
- package/build/generic-container/inspect-container-util-ports-exposed.js +1 -1
- package/build/generic-container/started-generic-container.d.ts +6 -5
- package/build/generic-container/started-generic-container.js +19 -16
- package/build/generic-container/stopped-generic-container.d.ts +2 -2
- package/build/index.d.ts +4 -4
- package/build/index.js +3 -3
- package/build/network/network.d.ts +3 -3
- package/build/port-forwarder/port-forwarder.d.ts +2 -3
- package/build/port-forwarder/port-forwarder.js +25 -19
- package/build/reaper/reaper.d.ts +1 -1
- package/build/reaper/reaper.js +21 -19
- package/build/socat/socat-container.d.ts +0 -2
- package/build/socat/socat-container.js +0 -3
- package/build/test-container.d.ts +6 -6
- package/build/test-containers.js +2 -1
- package/build/types.d.ts +3 -4
- package/build/utils/bound-ports.d.ts +3 -3
- package/build/utils/bound-ports.js +2 -2
- package/build/utils/dockerfile-parser.d.ts +1 -1
- package/build/utils/dockerfile-parser.js +2 -2
- package/build/utils/labels.d.ts +0 -2
- package/build/utils/labels.js +5 -5
- package/build/utils/map-inspect-result.d.ts +2 -2
- package/build/utils/map-inspect-result.js +12 -13
- package/build/utils/pull-policy.d.ts +2 -1
- package/build/utils/pull-policy.js +9 -0
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/build/wait-strategies/composite-wait-strategy.d.ts +3 -3
- package/build/wait-strategies/composite-wait-strategy.js +3 -1
- package/build/wait-strategies/health-check-wait-strategy.d.ts +1 -1
- package/build/wait-strategies/host-port-wait-strategy.d.ts +2 -2
- package/build/wait-strategies/http-wait-strategy.d.ts +2 -2
- package/build/wait-strategies/http-wait-strategy.js +4 -7
- package/build/wait-strategies/log-wait-strategy.d.ts +3 -3
- package/build/wait-strategies/log-wait-strategy.js +1 -1
- package/build/wait-strategies/one-shot-startup-startegy.d.ts +2 -2
- package/build/wait-strategies/shell-wait-strategy.d.ts +1 -1
- package/build/wait-strategies/startup-check-strategy.d.ts +1 -2
- package/build/wait-strategies/startup-check-strategy.js +0 -3
- package/build/wait-strategies/utils/health-check.d.ts +2 -4
- package/build/wait-strategies/utils/health-check.js +4 -6
- package/build/wait-strategies/utils/port-check.d.ts +2 -2
- package/build/wait-strategies/utils/port-check.js +2 -2
- package/build/wait-strategies/utils/undici-response-parser.d.ts +1 -1
- package/build/wait-strategies/utils/undici-response-parser.js +2 -2
- package/build/wait-strategies/utils/wait-strategy-selector.d.ts +4 -4
- package/build/wait-strategies/wait-for-container.d.ts +4 -4
- package/build/wait-strategies/wait-strategy.d.ts +2 -2
- package/build/wait-strategies/wait.d.ts +3 -3
- package/build/wait-strategies/wait.js +1 -0
- package/package.json +3 -4
- package/build/common/streams.d.ts +0 -6
- package/build/common/streams.js +0 -12
|
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.withFileLock = withFileLock;
|
|
7
|
-
const promises_1 = require("fs/promises");
|
|
8
|
-
const
|
|
7
|
+
const promises_1 = require("node:fs/promises");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
|
|
10
10
|
const tmp_1 = __importDefault(require("tmp"));
|
|
11
11
|
const logger_1 = require("./logger");
|
|
@@ -29,7 +29,7 @@ async function withFileLock(fileName, fn) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
async function createEmptyTmpFile(fileName) {
|
|
32
|
-
const file =
|
|
32
|
+
const file = node_path_1.default.resolve(tmp_1.default.tmpdir, fileName);
|
|
33
33
|
await (0, promises_1.writeFile)(file, "");
|
|
34
34
|
return file;
|
|
35
35
|
}
|
package/build/common/hash.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.hash = hash;
|
|
7
|
-
const
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
8
|
function hash(str) {
|
|
9
|
-
return
|
|
9
|
+
return node_crypto_1.default.createHash("sha256").update(str).digest("hex");
|
|
10
10
|
}
|
package/build/common/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export { withFileLock } from "./file-lock";
|
|
2
2
|
export { hash } from "./hash";
|
|
3
|
-
export {
|
|
3
|
+
export { buildLog, composeLog, containerLog, execLog, Logger, log, pullLog } from "./logger";
|
|
4
4
|
export { IntervalRetry, Retry } from "./retry";
|
|
5
|
-
export { streamToString } from "./streams";
|
|
6
5
|
export * from "./time";
|
|
7
6
|
export * from "./type-guards";
|
|
8
|
-
export { RandomUuid,
|
|
7
|
+
export { RandomUuid, randomUuid, Uuid } from "./uuid";
|
package/build/common/index.js
CHANGED
|
@@ -14,23 +14,21 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.randomUuid = exports.RandomUuid = exports.
|
|
17
|
+
exports.randomUuid = exports.RandomUuid = exports.IntervalRetry = exports.pullLog = exports.log = exports.Logger = exports.execLog = exports.containerLog = exports.composeLog = exports.buildLog = exports.hash = exports.withFileLock = void 0;
|
|
18
18
|
var file_lock_1 = require("./file-lock");
|
|
19
19
|
Object.defineProperty(exports, "withFileLock", { enumerable: true, get: function () { return file_lock_1.withFileLock; } });
|
|
20
20
|
var hash_1 = require("./hash");
|
|
21
21
|
Object.defineProperty(exports, "hash", { enumerable: true, get: function () { return hash_1.hash; } });
|
|
22
22
|
var logger_1 = require("./logger");
|
|
23
|
-
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
|
|
24
23
|
Object.defineProperty(exports, "buildLog", { enumerable: true, get: function () { return logger_1.buildLog; } });
|
|
25
24
|
Object.defineProperty(exports, "composeLog", { enumerable: true, get: function () { return logger_1.composeLog; } });
|
|
26
25
|
Object.defineProperty(exports, "containerLog", { enumerable: true, get: function () { return logger_1.containerLog; } });
|
|
27
26
|
Object.defineProperty(exports, "execLog", { enumerable: true, get: function () { return logger_1.execLog; } });
|
|
27
|
+
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
|
|
28
28
|
Object.defineProperty(exports, "log", { enumerable: true, get: function () { return logger_1.log; } });
|
|
29
29
|
Object.defineProperty(exports, "pullLog", { enumerable: true, get: function () { return logger_1.pullLog; } });
|
|
30
30
|
var retry_1 = require("./retry");
|
|
31
31
|
Object.defineProperty(exports, "IntervalRetry", { enumerable: true, get: function () { return retry_1.IntervalRetry; } });
|
|
32
|
-
var streams_1 = require("./streams");
|
|
33
|
-
Object.defineProperty(exports, "streamToString", { enumerable: true, get: function () { return streams_1.streamToString; } });
|
|
34
32
|
__exportStar(require("./time"), exports);
|
|
35
33
|
__exportStar(require("./type-guards"), exports);
|
|
36
34
|
var uuid_1 = require("./uuid");
|
package/build/common/retry.d.ts
CHANGED
package/build/common/uuid.js
CHANGED
|
@@ -4,11 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.randomUuid = exports.RandomUuid = void 0;
|
|
7
|
-
const
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
8
|
const hash_1 = require("./hash");
|
|
9
9
|
class RandomUuid {
|
|
10
10
|
nextUuid() {
|
|
11
|
-
return (0, hash_1.hash)(
|
|
11
|
+
return (0, hash_1.hash)(node_crypto_1.default.randomUUID()).substring(0, 12);
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
exports.RandomUuid = RandomUuid;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RegistryAuthLocator } from "./registry-auth-locator";
|
|
2
|
-
import { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
1
|
+
import type { RegistryAuthLocator } from "./registry-auth-locator";
|
|
2
|
+
import type { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
3
3
|
export declare class Auths implements RegistryAuthLocator {
|
|
4
4
|
getName(): string;
|
|
5
5
|
getAuthConfig(registry: string, dockerConfig: ContainerRuntimeConfig): Promise<AuthConfig | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CredentialProvider } from "./credential-provider";
|
|
2
|
-
import { ContainerRuntimeConfig } from "./types";
|
|
2
|
+
import type { ContainerRuntimeConfig } from "./types";
|
|
3
3
|
export declare class CredHelpers extends CredentialProvider {
|
|
4
4
|
getName(): string;
|
|
5
5
|
getCredentialProviderName(registry: string, dockerConfig: ContainerRuntimeConfig): string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RegistryAuthLocator } from "./registry-auth-locator";
|
|
2
|
-
import { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
1
|
+
import type { RegistryAuthLocator } from "./registry-auth-locator";
|
|
2
|
+
import type { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
3
3
|
export declare abstract class CredentialProvider implements RegistryAuthLocator {
|
|
4
4
|
abstract getName(): string;
|
|
5
5
|
abstract getCredentialProviderName(registry: string, dockerConfig: ContainerRuntimeConfig): string | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CredentialProvider = void 0;
|
|
4
|
-
const
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
5
|
const common_1 = require("../../common");
|
|
6
6
|
class CredentialProvider {
|
|
7
7
|
async getAuthConfig(registry, dockerConfig) {
|
|
@@ -15,7 +15,7 @@ class CredentialProvider {
|
|
|
15
15
|
}
|
|
16
16
|
runCredentialProvider(registry, providerName) {
|
|
17
17
|
return new Promise((resolve, reject) => {
|
|
18
|
-
const sink = (0,
|
|
18
|
+
const sink = (0, node_child_process_1.spawn)(providerName, ["get"]);
|
|
19
19
|
const chunks = [];
|
|
20
20
|
sink.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
21
21
|
sink.on("error", (err) => {
|
|
@@ -35,7 +35,7 @@ class CredentialProvider {
|
|
|
35
35
|
: this.parseUsernamePasswordConfig(registry, credentialProviderResponse);
|
|
36
36
|
return resolve(authConfig);
|
|
37
37
|
}
|
|
38
|
-
catch (
|
|
38
|
+
catch (_e) {
|
|
39
39
|
common_1.log.error(`Unexpected response from Docker credential provider GET command: "${response}"`);
|
|
40
40
|
return reject(new Error("Unexpected response from Docker credential provider GET command"));
|
|
41
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CredentialProvider } from "./credential-provider";
|
|
2
|
-
import { ContainerRuntimeConfig } from "./types";
|
|
2
|
+
import type { ContainerRuntimeConfig } from "./types";
|
|
3
3
|
export declare class CredsStore extends CredentialProvider {
|
|
4
4
|
getName(): string;
|
|
5
|
-
getCredentialProviderName(
|
|
5
|
+
getCredentialProviderName(_registry: string, dockerConfig: ContainerRuntimeConfig): string | undefined;
|
|
6
6
|
}
|
|
@@ -6,7 +6,7 @@ class CredsStore extends credential_provider_1.CredentialProvider {
|
|
|
6
6
|
getName() {
|
|
7
7
|
return "CredsStore";
|
|
8
8
|
}
|
|
9
|
-
getCredentialProviderName(
|
|
9
|
+
getCredentialProviderName(_registry, dockerConfig) {
|
|
10
10
|
if (dockerConfig.credsStore !== undefined && dockerConfig.credsStore.length > 0) {
|
|
11
11
|
return dockerConfig.credsStore;
|
|
12
12
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { AuthConfig } from "./types";
|
|
1
|
+
import type { AuthConfig } from "./types";
|
|
2
2
|
export declare const getAuthConfig: (registry: string) => Promise<AuthConfig | undefined>;
|
|
@@ -4,21 +4,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getAuthConfig = void 0;
|
|
7
|
-
const
|
|
8
|
-
const promises_1 = require("fs/promises");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const promises_1 = require("node:fs/promises");
|
|
9
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const common_1 = require("../../common");
|
|
12
12
|
const auths_1 = require("./auths");
|
|
13
13
|
const cred_helpers_1 = require("./cred-helpers");
|
|
14
14
|
const creds_store_1 = require("./creds-store");
|
|
15
|
-
const dockerConfigLocation = process.env.DOCKER_CONFIG || `${
|
|
16
|
-
const dockerConfigFile =
|
|
15
|
+
const dockerConfigLocation = process.env.DOCKER_CONFIG || `${node_os_1.default.homedir()}/.docker`;
|
|
16
|
+
const dockerConfigFile = node_path_1.default.resolve(dockerConfigLocation, "config.json");
|
|
17
17
|
const readDockerConfig = async () => {
|
|
18
18
|
if (process.env.DOCKER_AUTH_CONFIG) {
|
|
19
19
|
return parseDockerConfig(process.env.DOCKER_AUTH_CONFIG);
|
|
20
20
|
}
|
|
21
|
-
else if ((0,
|
|
21
|
+
else if ((0, node_fs_1.existsSync)(dockerConfigFile)) {
|
|
22
22
|
return parseDockerConfig((await (0, promises_1.readFile)(dockerConfigFile)).toString());
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
1
|
+
import type { AuthConfig, ContainerRuntimeConfig } from "./types";
|
|
2
2
|
export interface RegistryAuthLocator {
|
|
3
3
|
getName(): string;
|
|
4
4
|
getAuthConfig(registry: string, dockerConfig: ContainerRuntimeConfig): Promise<AuthConfig | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registryMatches = void 0;
|
|
4
|
-
const registryMatches = (authConfigRegistry, requestedRegistry) => authConfigRegistry
|
|
4
|
+
const registryMatches = (authConfigRegistry, requestedRegistry) => authConfigRegistry === requestedRegistry || authConfigRegistry.endsWith(`://${requestedRegistry}`);
|
|
5
5
|
exports.registryMatches = registryMatches;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ComposeClient } from "./compose/compose-client";
|
|
2
|
-
import { ContainerClient } from "./container/container-client";
|
|
3
|
-
import { ImageClient } from "./image/image-client";
|
|
4
|
-
import { NetworkClient } from "./network/network-client";
|
|
5
|
-
import { Info } from "./types";
|
|
1
|
+
import { type ComposeClient } from "./compose/compose-client";
|
|
2
|
+
import type { ContainerClient } from "./container/container-client";
|
|
3
|
+
import type { ImageClient } from "./image/image-client";
|
|
4
|
+
import type { NetworkClient } from "./network/network-client";
|
|
5
|
+
import type { Info } from "./types";
|
|
6
6
|
export declare class ContainerRuntimeClient {
|
|
7
7
|
readonly info: Info;
|
|
8
8
|
readonly compose: ComposeClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComposeDownOptions, ComposeOptions } from "./types";
|
|
1
|
+
import type { ComposeDownOptions, ComposeOptions } from "./types";
|
|
2
2
|
export interface ComposeClient {
|
|
3
3
|
up(options: ComposeOptions, services?: Array<string>): Promise<void>;
|
|
4
4
|
pull(options: ComposeOptions, services?: Array<string>): Promise<void>;
|
|
@@ -11,7 +11,7 @@ async function getComposeClient(environment) {
|
|
|
11
11
|
try {
|
|
12
12
|
return new DockerComposeClient(environment);
|
|
13
13
|
}
|
|
14
|
-
catch (
|
|
14
|
+
catch (_err) {
|
|
15
15
|
return new MissingComposeClient();
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -85,7 +85,6 @@ class DockerComposeClient {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
class MissingComposeClient {
|
|
88
|
-
constructor() { }
|
|
89
88
|
up() {
|
|
90
89
|
throw new Error("Compose is not installed");
|
|
91
90
|
}
|
|
@@ -99,7 +98,6 @@ class MissingComposeClient {
|
|
|
99
98
|
throw new Error("Compose is not installed");
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
101
|
async function handleAndRethrow(err, handle) {
|
|
104
102
|
const error = err instanceof Error ? err : new Error(err.err.trim());
|
|
105
103
|
await handle(error);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { IDockerComposeOptions } from "docker-compose";
|
|
2
|
-
import { ComposeOptions } from "./types";
|
|
1
|
+
import type { IDockerComposeOptions } from "docker-compose";
|
|
2
|
+
import type { ComposeOptions } from "./types";
|
|
3
3
|
export declare function defaultComposeOptions(environment: NodeJS.ProcessEnv, options: ComposeOptions): Partial<IDockerComposeOptions>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultComposeOptions = defaultComposeOptions;
|
|
4
|
-
const
|
|
4
|
+
const node_os_1 = require("node:os");
|
|
5
5
|
const common_1 = require("../../../common");
|
|
6
6
|
function defaultComposeOptions(environment, options) {
|
|
7
7
|
const log = options.logger ?? common_1.composeLog;
|
|
@@ -11,9 +11,11 @@ function defaultComposeOptions(environment, options) {
|
|
|
11
11
|
? (chunk) => {
|
|
12
12
|
chunk
|
|
13
13
|
.toString()
|
|
14
|
-
.split(
|
|
14
|
+
.split(node_os_1.EOL)
|
|
15
15
|
.filter(common_1.isNotEmptyString)
|
|
16
|
-
.forEach((line) =>
|
|
16
|
+
.forEach((line) => {
|
|
17
|
+
log.trace(line.trim());
|
|
18
|
+
});
|
|
17
19
|
}
|
|
18
20
|
: undefined,
|
|
19
21
|
cwd: options.filePath,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Logger } from "../../../common";
|
|
1
|
+
import type { Logger } from "../../../common";
|
|
2
2
|
export type ComposeOptions = {
|
|
3
3
|
filePath: string;
|
|
4
4
|
files: string | string[];
|
|
@@ -9,7 +9,7 @@ export type ComposeOptions = {
|
|
|
9
9
|
logger?: Logger;
|
|
10
10
|
executable?: ComposeExecutableOptions;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
type ComposeExecutableOptions = {
|
|
13
13
|
executablePath: string;
|
|
14
14
|
options?: string[] | (string | string[])[];
|
|
15
15
|
standalone?: never;
|
|
@@ -22,3 +22,4 @@ export type ComposeDownOptions = {
|
|
|
22
22
|
timeout: number;
|
|
23
23
|
removeVolumes: boolean;
|
|
24
24
|
};
|
|
25
|
+
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
2
|
+
import type Dockerode from "dockerode";
|
|
3
|
+
import type { Container, ContainerCreateOptions, ContainerInfo, ContainerInspectInfo, ContainerLogsOptions, Network } from "dockerode";
|
|
4
|
+
import type { CopyToContainerOptions } from "../../../types";
|
|
5
|
+
import type { ContainerCommitOptions, ContainerStatus, ExecOptions, ExecResult } from "./types";
|
|
5
6
|
export interface ContainerClient {
|
|
6
7
|
dockerode: Dockerode;
|
|
7
8
|
getById(id: string): Container;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { type Readable } from "node:stream";
|
|
2
|
+
import type Dockerode from "dockerode";
|
|
3
|
+
import type { Container, ContainerCreateOptions, ContainerInfo, ContainerInspectInfo, ContainerLogsOptions, Network } from "dockerode";
|
|
4
|
+
import type { CopyToContainerOptions } from "../../../types";
|
|
5
|
+
import type { ContainerClient } from "./container-client";
|
|
6
|
+
import type { ContainerCommitOptions, ContainerStatus, ExecOptions, ExecResult } from "./types";
|
|
6
7
|
export declare class DockerContainerClient implements ContainerClient {
|
|
7
8
|
readonly dockerode: Dockerode;
|
|
8
9
|
constructor(dockerode: Dockerode);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DockerContainerClient = void 0;
|
|
4
|
-
const
|
|
5
|
-
const promises_1 = require("stream/promises");
|
|
4
|
+
const node_stream_1 = require("node:stream");
|
|
5
|
+
const promises_1 = require("node:stream/promises");
|
|
6
6
|
const common_1 = require("../../../common");
|
|
7
7
|
class DockerContainerClient {
|
|
8
8
|
dockerode;
|
|
@@ -63,11 +63,11 @@ class DockerContainerClient {
|
|
|
63
63
|
async putArchive(container, stream, path, options) {
|
|
64
64
|
try {
|
|
65
65
|
common_1.log.debug(`Putting archive to container...`, { containerId: container.id });
|
|
66
|
-
await
|
|
66
|
+
await container.putArchive(stream, {
|
|
67
67
|
path,
|
|
68
68
|
noOverwriteDirNonDir: options?.noOverwriteDirNonDir,
|
|
69
69
|
copyUIDGID: options?.copyUIDGID,
|
|
70
|
-
})
|
|
70
|
+
});
|
|
71
71
|
common_1.log.debug(`Put archive to container`, { containerId: container.id });
|
|
72
72
|
}
|
|
73
73
|
catch (err) {
|
|
@@ -124,7 +124,6 @@ class DockerContainerClient {
|
|
|
124
124
|
common_1.log.debug(`Stopping container...`, { containerId: container.id });
|
|
125
125
|
await container.stop({ t: (0, common_1.toSeconds)(opts?.timeout ?? 0) });
|
|
126
126
|
common_1.log.debug(`Stopped container`, { containerId: container.id });
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
127
|
}
|
|
129
128
|
catch (err) {
|
|
130
129
|
if (err.statusCode === 304) {
|
|
@@ -155,7 +154,7 @@ class DockerContainerClient {
|
|
|
155
154
|
}
|
|
156
155
|
logs(container, opts) {
|
|
157
156
|
common_1.log.debug(`Fetching container logs...`, { containerId: container.id });
|
|
158
|
-
const proxyStream = new
|
|
157
|
+
const proxyStream = new node_stream_1.PassThrough();
|
|
159
158
|
proxyStream.setEncoding("utf8");
|
|
160
159
|
container
|
|
161
160
|
.logs({
|
|
@@ -169,6 +168,11 @@ class DockerContainerClient {
|
|
|
169
168
|
const actualLogStream = stream;
|
|
170
169
|
actualLogStream.socket?.unref();
|
|
171
170
|
const demuxedStream = await this.demuxStream(container.id, actualLogStream);
|
|
171
|
+
if (proxyStream.destroyed) {
|
|
172
|
+
demuxedStream.destroy();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
proxyStream.once("close", () => demuxedStream.destroy());
|
|
172
176
|
demuxedStream.pipe(proxyStream);
|
|
173
177
|
demuxedStream.on("error", (err) => proxyStream.emit("error", err));
|
|
174
178
|
demuxedStream.on("end", () => proxyStream.end());
|
|
@@ -203,8 +207,8 @@ class DockerContainerClient {
|
|
|
203
207
|
}
|
|
204
208
|
const exec = await container.exec(execOptions);
|
|
205
209
|
const stream = await exec.start({ stdin: true, Detach: false, Tty: false });
|
|
206
|
-
const stdoutStream = new
|
|
207
|
-
const stderrStream = new
|
|
210
|
+
const stdoutStream = new node_stream_1.PassThrough();
|
|
211
|
+
const stderrStream = new node_stream_1.PassThrough();
|
|
208
212
|
this.dockerode.modem.demuxStream(stream, stdoutStream, stderrStream);
|
|
209
213
|
const processStream = (stream, chunks) => {
|
|
210
214
|
stream.on("data", (chunk) => {
|
|
@@ -295,7 +299,7 @@ class DockerContainerClient {
|
|
|
295
299
|
async demuxStream(containerId, stream) {
|
|
296
300
|
try {
|
|
297
301
|
common_1.log.debug(`Demuxing stream...`, { containerId });
|
|
298
|
-
const demuxedStream = new
|
|
302
|
+
const demuxedStream = new node_stream_1.PassThrough({ autoDestroy: true, encoding: "utf-8" });
|
|
299
303
|
this.dockerode.modem.demuxStream(stream, demuxedStream, demuxedStream);
|
|
300
304
|
stream.on("end", () => demuxedStream.end());
|
|
301
305
|
demuxedStream.on("close", () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import Dockerode
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type Dockerode from "dockerode";
|
|
2
|
+
import type { ImageBuildOptions, ImageInspectInfo } from "dockerode";
|
|
3
|
+
import type { ImageName } from "../../image-name";
|
|
4
|
+
import type { ImageClient } from "./image-client";
|
|
4
5
|
export declare class DockerImageClient implements ImageClient {
|
|
5
6
|
protected readonly dockerode: Dockerode;
|
|
6
7
|
protected readonly indexServerAddress: string;
|
|
@@ -4,11 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DockerImageClient = void 0;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_stream_1 = require("node:stream");
|
|
7
10
|
const dockerignore_1 = __importDefault(require("@balena/dockerignore"));
|
|
8
11
|
const async_lock_1 = __importDefault(require("async-lock"));
|
|
9
12
|
const byline_1 = __importDefault(require("byline"));
|
|
10
|
-
const fs_1 = require("fs");
|
|
11
|
-
const path_1 = __importDefault(require("path"));
|
|
12
13
|
const tar_fs_1 = __importDefault(require("tar-fs"));
|
|
13
14
|
const common_1 = require("../../../common");
|
|
14
15
|
const get_auth_config_1 = require("../../auth/get-auth-config");
|
|
@@ -25,7 +26,7 @@ class DockerImageClient {
|
|
|
25
26
|
try {
|
|
26
27
|
common_1.log.debug(`Building image "${opts.t}" with context "${context}"...`);
|
|
27
28
|
const tarPackOptions = await this.createTarPackOptions(context, opts.dockerfile ?? "Dockerfile");
|
|
28
|
-
const tarStream = tar_fs_1.default.pack(context, tarPackOptions);
|
|
29
|
+
const tarStream = node_stream_1.Readable.from(tar_fs_1.default.pack(context, tarPackOptions));
|
|
29
30
|
await new Promise((resolve) => {
|
|
30
31
|
this.dockerode
|
|
31
32
|
.buildImage(tarStream, opts)
|
|
@@ -48,16 +49,16 @@ class DockerImageClient {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
async createTarPackOptions(context, dockerfileName) {
|
|
51
|
-
const dockerIgnoreFilePath =
|
|
52
|
-
if (!(0,
|
|
52
|
+
const dockerIgnoreFilePath = node_path_1.default.join(context, ".dockerignore");
|
|
53
|
+
if (!(0, node_fs_1.existsSync)(dockerIgnoreFilePath)) {
|
|
53
54
|
return {};
|
|
54
55
|
}
|
|
55
|
-
const dockerIgnorePatterns = await
|
|
56
|
+
const dockerIgnorePatterns = await node_fs_1.promises.readFile(dockerIgnoreFilePath, { encoding: "utf-8" });
|
|
56
57
|
const instance = (0, dockerignore_1.default)({ ignorecase: false });
|
|
57
58
|
instance.add(dockerIgnorePatterns);
|
|
58
59
|
const allEntries = await this.listContextEntries(context);
|
|
59
60
|
const includedEntries = instance.filter(allEntries);
|
|
60
|
-
const dockerfilePath = this.normalizePathForDockerIgnore(
|
|
61
|
+
const dockerfilePath = this.normalizePathForDockerIgnore(node_path_1.default.normalize(dockerfileName));
|
|
61
62
|
if (!includedEntries.includes(dockerfilePath)) {
|
|
62
63
|
includedEntries.push(dockerfilePath);
|
|
63
64
|
}
|
|
@@ -71,10 +72,10 @@ class DockerImageClient {
|
|
|
71
72
|
if (directory === undefined) {
|
|
72
73
|
continue;
|
|
73
74
|
}
|
|
74
|
-
const absoluteDirectory = directory.length > 0 ?
|
|
75
|
-
const directoryEntries = await
|
|
75
|
+
const absoluteDirectory = directory.length > 0 ? node_path_1.default.join(context, directory) : context;
|
|
76
|
+
const directoryEntries = await node_fs_1.promises.readdir(absoluteDirectory, { withFileTypes: true });
|
|
76
77
|
for (const directoryEntry of directoryEntries) {
|
|
77
|
-
const relativeEntry = directory.length > 0 ?
|
|
78
|
+
const relativeEntry = directory.length > 0 ? node_path_1.default.join(directory, directoryEntry.name) : directoryEntry.name;
|
|
78
79
|
if (directoryEntry.isDirectory()) {
|
|
79
80
|
directoriesToVisit.push(relativeEntry);
|
|
80
81
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ImageBuildOptions, ImageInspectInfo } from "dockerode";
|
|
2
|
-
import { ImageName } from "../../image-name";
|
|
1
|
+
import type { ImageBuildOptions, ImageInspectInfo } from "dockerode";
|
|
2
|
+
import type { ImageName } from "../../image-name";
|
|
3
3
|
export interface ImageClient {
|
|
4
4
|
build(context: string, opts: ImageBuildOptions): Promise<void>;
|
|
5
5
|
pull(imageName: ImageName, opts?: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import Dockerode
|
|
2
|
-
import {
|
|
1
|
+
import type Dockerode from "dockerode";
|
|
2
|
+
import type { Network, NetworkCreateOptions } from "dockerode";
|
|
3
|
+
import type { NetworkClient } from "./network-client";
|
|
3
4
|
export declare class DockerNetworkClient implements NetworkClient {
|
|
4
5
|
protected readonly dockerode: Dockerode;
|
|
5
6
|
constructor(dockerode: Dockerode);
|
|
@@ -2,9 +2,10 @@ export declare class ImageName {
|
|
|
2
2
|
readonly registry: string | undefined;
|
|
3
3
|
readonly image: string;
|
|
4
4
|
readonly tag: string;
|
|
5
|
+
readonly digest?: string | undefined;
|
|
5
6
|
readonly string: string;
|
|
6
7
|
private static readonly hexRE;
|
|
7
|
-
constructor(registry: string | undefined, image: string, tag: string);
|
|
8
|
+
constructor(registry: string | undefined, image: string, tag: string, digest?: string | undefined);
|
|
8
9
|
equals(other: ImageName): boolean;
|
|
9
10
|
static fromString(string: string): ImageName;
|
|
10
11
|
private static getRegistry;
|
|
@@ -6,12 +6,18 @@ class ImageName {
|
|
|
6
6
|
registry;
|
|
7
7
|
image;
|
|
8
8
|
tag;
|
|
9
|
+
digest;
|
|
9
10
|
string;
|
|
10
11
|
static hexRE = /^[0-9a-f]{64}$/i;
|
|
11
|
-
constructor(registry, image, tag) {
|
|
12
|
+
constructor(registry, image, tag, digest) {
|
|
12
13
|
this.registry = registry;
|
|
13
14
|
this.image = image;
|
|
14
15
|
this.tag = tag;
|
|
16
|
+
this.digest = digest;
|
|
17
|
+
if (!this.digest && this.tag.startsWith("sha256:")) {
|
|
18
|
+
// A digest-only reference (image@sha256:...) keeps the digest as its tag.
|
|
19
|
+
this.digest = this.tag;
|
|
20
|
+
}
|
|
15
21
|
if (!this.registry && process.env.TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX) {
|
|
16
22
|
const prefix = process.env.TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX;
|
|
17
23
|
// Parse the registry. If it's undefined - then the whole prefix is a registry.
|
|
@@ -30,12 +36,13 @@ class ImageName {
|
|
|
30
36
|
}
|
|
31
37
|
common_1.log.info(message);
|
|
32
38
|
}
|
|
39
|
+
const tagAndDigest = this.digest ? `${this.tag}@${this.digest}` : this.tag;
|
|
33
40
|
if (this.registry) {
|
|
34
41
|
if (this.tag.startsWith("sha256:")) {
|
|
35
42
|
this.string = `${this.registry}/${this.image}@${this.tag}`;
|
|
36
43
|
}
|
|
37
44
|
else {
|
|
38
|
-
this.string = `${this.registry}/${this.image}:${
|
|
45
|
+
this.string = `${this.registry}/${this.image}:${tagAndDigest}`;
|
|
39
46
|
}
|
|
40
47
|
}
|
|
41
48
|
else if (this.tag === "latest" && ImageName.hexRE.test(this.image)) {
|
|
@@ -51,30 +58,33 @@ class ImageName {
|
|
|
51
58
|
this.string = `${this.image}@${this.tag}`;
|
|
52
59
|
}
|
|
53
60
|
else {
|
|
54
|
-
this.string = `${this.image}:${
|
|
61
|
+
this.string = `${this.image}:${tagAndDigest}`;
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
equals(other) {
|
|
58
|
-
return this.registry === other.registry &&
|
|
65
|
+
return (this.registry === other.registry &&
|
|
66
|
+
this.image === other.image &&
|
|
67
|
+
this.tag === other.tag &&
|
|
68
|
+
this.digest === other.digest);
|
|
59
69
|
}
|
|
60
70
|
static fromString(string) {
|
|
61
|
-
const registry =
|
|
71
|
+
const registry = ImageName.getRegistry(string);
|
|
62
72
|
const stringWithoutRegistry = registry ? string.split("/").slice(1).join("/") : string;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
const [imageAndTag, digest] = stringWithoutRegistry.split("@");
|
|
74
|
+
if (imageAndTag.includes(":")) {
|
|
75
|
+
const [image, tag] = imageAndTag.split(":");
|
|
76
|
+
return new ImageName(registry, image, tag, digest);
|
|
66
77
|
}
|
|
67
|
-
else if (
|
|
68
|
-
|
|
69
|
-
return new ImageName(registry, image, tag);
|
|
78
|
+
else if (digest) {
|
|
79
|
+
return new ImageName(registry, imageAndTag, digest);
|
|
70
80
|
}
|
|
71
81
|
else {
|
|
72
|
-
return new ImageName(registry,
|
|
82
|
+
return new ImageName(registry, imageAndTag, "latest");
|
|
73
83
|
}
|
|
74
84
|
}
|
|
75
85
|
static getRegistry(string) {
|
|
76
86
|
const parts = string.split("/");
|
|
77
|
-
if (parts.length > 1 &&
|
|
87
|
+
if (parts.length > 1 && ImageName.isRegistry(parts[0])) {
|
|
78
88
|
return parts[0];
|
|
79
89
|
}
|
|
80
90
|
}
|