testcontainers 9.7.0 → 9.8.0-beta.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/dist/package.json +1 -1
- package/dist/src/docker/{docker-client-config.d.ts → client/docker-client-config.d.ts} +1 -0
- package/dist/src/docker/{docker-client-config.js → client/docker-client-config.js} +18 -11
- package/dist/src/docker/client/docker-client.d.ts +18 -0
- package/dist/src/docker/client/docker-client.js +90 -0
- package/dist/src/docker/client/strategy/configuration-strategy.d.ts +11 -0
- package/dist/src/docker/client/strategy/configuration-strategy.js +68 -0
- package/dist/src/docker/client/strategy/docker-client-strategy.d.ts +7 -0
- package/dist/src/docker/client/strategy/docker-client-strategy.js +2 -0
- package/dist/src/docker/client/strategy/npipe-socket-strategy.d.ts +7 -0
- package/dist/src/docker/client/strategy/npipe-socket-strategy.js +35 -0
- package/dist/src/docker/{rootless-unix-socket-strategy.d.ts → client/strategy/rootless-unix-socket-strategy.d.ts} +3 -2
- package/dist/src/docker/{rootless-unix-socket-strategy.js → client/strategy/rootless-unix-socket-strategy.js} +2 -1
- package/dist/src/docker/client/strategy/testcontainers-host-strategy.d.ts +9 -0
- package/dist/src/docker/client/strategy/testcontainers-host-strategy.js +52 -0
- package/dist/src/docker/client/strategy/unix-socket-strategy.d.ts +7 -0
- package/dist/src/docker/client/strategy/unix-socket-strategy.js +36 -0
- package/dist/src/docker/functions/container/container-logs.js +2 -2
- package/dist/src/docker/functions/container/create-container.js +2 -2
- package/dist/src/docker/functions/container/exec-container.d.ts +2 -3
- package/dist/src/docker/functions/container/exec-container.js +4 -4
- package/dist/src/docker/functions/container/get-container.js +3 -3
- package/dist/src/docker/functions/container/list-containers.js +2 -2
- package/dist/src/docker/functions/image/build-image.js +2 -2
- package/dist/src/docker/functions/image/pull-image.js +9 -2
- package/dist/src/docker/functions/network/connect-network.js +2 -2
- package/dist/src/docker/functions/network/create-network.js +2 -2
- package/dist/src/docker/functions/network/remove-network.js +2 -2
- package/dist/src/docker/remote-docker-unix-socket-path.d.ts +6 -0
- package/dist/src/docker/remote-docker-unix-socket-path.js +22 -0
- package/dist/src/docker/resolve-host.d.ts +2 -2
- package/dist/src/docker/resolve-host.js +6 -4
- package/dist/src/docker/types.d.ts +1 -0
- package/dist/src/docker-compose/default-docker-compose-options.js +2 -2
- package/dist/src/docker-compose-environment/docker-compose-environment.js +2 -2
- package/dist/src/generic-container/generic-container-builder.js +3 -3
- package/dist/src/generic-container/generic-container.js +5 -5
- package/dist/src/generic-container/started-generic-container.js +4 -4
- package/dist/src/port-check.d.ts +3 -3
- package/dist/src/port-check.js +3 -3
- package/dist/src/port-forwarder.js +2 -2
- package/dist/src/reaper.js +6 -4
- package/dist/src/wait-strategy/host-port-wait-strategy.js +3 -3
- package/dist/src/wait-strategy/http-wait-strategy.js +2 -2
- package/dist/src/wait-strategy/shell-wait-strategy.js +3 -3
- package/dist/src/wait-strategy/startup-check-strategy.js +2 -2
- package/package.json +1 -1
- package/dist/src/docker/docker-client.d.ts +0 -26
- package/dist/src/docker/docker-client.js +0 -156
- package/dist/src/docker/get-remote-docker-unix-socket-path.d.ts +0 -5
- package/dist/src/docker/get-remote-docker-unix-socket-path.js +0 -17
- package/dist/src/docker/pull-stream-parser.d.ts +0 -10
- package/dist/src/docker/pull-stream-parser.js +0 -24
|
@@ -11,11 +11,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.connectNetwork = void 0;
|
|
13
13
|
const logger_1 = require("../../../logger");
|
|
14
|
-
const docker_client_1 = require("../../docker-client");
|
|
14
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
15
15
|
const connectNetwork = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
16
|
try {
|
|
17
17
|
logger_1.log.info(`Connecting to network "${options.networkId}"...`, { containerId: options.containerId });
|
|
18
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
18
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
19
19
|
const network = dockerode.getNetwork(options.networkId);
|
|
20
20
|
yield network.connect({ Container: options.containerId, EndpointConfig: { Aliases: options.networkAliases } });
|
|
21
21
|
logger_1.log.info(`Connected to network "${options.networkId}"...`, { containerId: options.containerId });
|
|
@@ -11,12 +11,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.createNetwork = void 0;
|
|
13
13
|
const logger_1 = require("../../../logger");
|
|
14
|
-
const docker_client_1 = require("../../docker-client");
|
|
14
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
15
15
|
const create_labels_1 = require("../create-labels");
|
|
16
16
|
const createNetwork = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
try {
|
|
18
18
|
logger_1.log.info(`Creating network "${options.name}"...`);
|
|
19
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
19
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
20
20
|
const network = yield dockerode.createNetwork({
|
|
21
21
|
Name: options.name,
|
|
22
22
|
CheckDuplicate: options.checkDuplicate,
|
|
@@ -11,11 +11,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.removeNetwork = void 0;
|
|
13
13
|
const logger_1 = require("../../../logger");
|
|
14
|
-
const docker_client_1 = require("../../docker-client");
|
|
14
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
15
15
|
const removeNetwork = (id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
16
|
try {
|
|
17
17
|
logger_1.log.info(`Removing network "${id}"...`);
|
|
18
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
18
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
19
19
|
const network = dockerode.getNetwork(id);
|
|
20
20
|
const { message } = yield network.remove();
|
|
21
21
|
if (message) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import { DockerClient } from "./client/docker-client";
|
|
6
|
+
export declare const getRemoteDockerUnixSocketPath: (dockerClient: DockerClient, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv) => string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRemoteDockerUnixSocketPath = void 0;
|
|
4
|
+
const getRemoteDockerUnixSocketPath = (dockerClient, platform = process.platform, env = process.env) => {
|
|
5
|
+
if (dockerClient.allowUserOverrides) {
|
|
6
|
+
if (env["TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"] !== undefined) {
|
|
7
|
+
return env["TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
let socketPath;
|
|
11
|
+
if (dockerClient.info.dockerInfo.operatingSystem === "Docker Desktop") {
|
|
12
|
+
socketPath = "/var/run/docker.sock";
|
|
13
|
+
}
|
|
14
|
+
else if (dockerClient.uri.startsWith("unix://")) {
|
|
15
|
+
socketPath = dockerClient.uri.replace("unix://", "");
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
socketPath = "/var/run/docker.sock";
|
|
19
|
+
}
|
|
20
|
+
return platform === "win32" ? `/${socketPath}` : socketPath;
|
|
21
|
+
};
|
|
22
|
+
exports.getRemoteDockerUnixSocketPath = getRemoteDockerUnixSocketPath;
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
/// <reference types="node" />
|
|
5
5
|
import Dockerode from "dockerode";
|
|
6
|
-
import {
|
|
7
|
-
export declare const resolveHost: (dockerode: Dockerode,
|
|
6
|
+
import { ContainerRuntime } from "./types";
|
|
7
|
+
export declare const resolveHost: (dockerode: Dockerode, containerRuntime: ContainerRuntime, indexServerAddress: string, uri: string, allowUserOverrides: boolean, env?: NodeJS.ProcessEnv) => Promise<string>;
|
|
@@ -14,9 +14,11 @@ const url_1 = require("url");
|
|
|
14
14
|
const logger_1 = require("../logger");
|
|
15
15
|
const run_in_container_1 = require("./functions/run-in-container");
|
|
16
16
|
const fs_1 = require("fs");
|
|
17
|
-
const resolveHost = (dockerode,
|
|
18
|
-
if (
|
|
19
|
-
|
|
17
|
+
const resolveHost = (dockerode, containerRuntime, indexServerAddress, uri, allowUserOverrides, env = process.env) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
if (allowUserOverrides) {
|
|
19
|
+
if (env.TESTCONTAINERS_HOST_OVERRIDE !== undefined) {
|
|
20
|
+
return env.TESTCONTAINERS_HOST_OVERRIDE;
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
const { protocol, hostname } = new url_1.URL(uri);
|
|
22
24
|
switch (protocol) {
|
|
@@ -27,7 +29,7 @@ const resolveHost = (dockerode, provider, indexServerAddress, uri, env = process
|
|
|
27
29
|
case "unix:":
|
|
28
30
|
case "npipe:": {
|
|
29
31
|
if (isInContainer()) {
|
|
30
|
-
const networkName =
|
|
32
|
+
const networkName = containerRuntime === "podman" ? "podman" : "bridge";
|
|
31
33
|
const gateway = yield findGateway(dockerode, networkName);
|
|
32
34
|
if (gateway !== undefined) {
|
|
33
35
|
return gateway;
|
|
@@ -21,14 +21,14 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.defaultDockerComposeOptions = void 0;
|
|
24
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
24
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
25
25
|
const logger_1 = require("../logger");
|
|
26
26
|
const os_1 = require("os");
|
|
27
27
|
const type_guards_1 = require("../type-guards");
|
|
28
28
|
const defaultDockerComposeOptions = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
29
|
var _b;
|
|
30
30
|
var { environment = {} } = _a, options = __rest(_a, ["environment"]);
|
|
31
|
-
const { composeEnvironment } = yield (0, docker_client_1.
|
|
31
|
+
const { composeEnvironment } = yield (0, docker_client_1.getDockerClient)();
|
|
32
32
|
const log = (_b = options.logger) !== null && _b !== void 0 ? _b : logger_1.composeLog;
|
|
33
33
|
return {
|
|
34
34
|
log: false,
|
|
@@ -18,7 +18,7 @@ const reaper_1 = require("../reaper");
|
|
|
18
18
|
const uuid_1 = require("../uuid");
|
|
19
19
|
const list_containers_1 = require("../docker/functions/container/list-containers");
|
|
20
20
|
const get_container_1 = require("../docker/functions/container/get-container");
|
|
21
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
21
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
22
22
|
const inspect_container_1 = require("../docker/functions/container/inspect-container");
|
|
23
23
|
const container_logs_1 = require("../docker/functions/container/container-logs");
|
|
24
24
|
const started_docker_compose_environment_1 = require("./started-docker-compose-environment");
|
|
@@ -108,7 +108,7 @@ class DockerComposeEnvironment {
|
|
|
108
108
|
const startedGenericContainers = (yield Promise.all(startedContainers.map((startedContainer) => __awaiter(this, void 0, void 0, function* () {
|
|
109
109
|
const container = yield (0, get_container_1.getContainerById)(startedContainer.Id);
|
|
110
110
|
const containerName = (0, container_name_resolver_1.resolveContainerName)(this.projectName, startedContainer.Names[0]);
|
|
111
|
-
const { host, hostIps } = yield (0, docker_client_1.
|
|
111
|
+
const { host, hostIps } = yield (0, docker_client_1.getDockerClient)();
|
|
112
112
|
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
113
113
|
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult);
|
|
114
114
|
const waitStrategy = this.waitStrategy[containerName]
|
|
@@ -23,7 +23,7 @@ const dockerfile_parser_1 = require("../dockerfile-parser");
|
|
|
23
23
|
const build_image_1 = require("../docker/functions/image/build-image");
|
|
24
24
|
const get_auth_config_1 = require("../registry-auth-locator/get-auth-config");
|
|
25
25
|
const generic_container_1 = require("./generic-container");
|
|
26
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
26
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
27
27
|
const image_exists_1 = require("../docker/functions/image/image-exists");
|
|
28
28
|
class GenericContainerBuilder {
|
|
29
29
|
constructor(context, dockerfileName, uuid = new uuid_1.RandomUuid()) {
|
|
@@ -54,8 +54,8 @@ class GenericContainerBuilder {
|
|
|
54
54
|
const dockerfile = path_1.default.resolve(this.context, this.dockerfileName);
|
|
55
55
|
logger_1.log.debug(`Preparing to build Dockerfile "${dockerfile}" as image "${imageName}"...`);
|
|
56
56
|
const imageNames = yield (0, dockerfile_parser_1.getDockerfileImages)(dockerfile, this.buildArgs);
|
|
57
|
-
const { dockerode,
|
|
58
|
-
const registryConfig = yield this.getRegistryConfig(indexServerAddress, imageNames);
|
|
57
|
+
const { dockerode, info } = yield (0, docker_client_1.getDockerClient)();
|
|
58
|
+
const registryConfig = yield this.getRegistryConfig(info.dockerInfo.indexServerAddress, imageNames);
|
|
59
59
|
yield (0, build_image_1.buildImage)({
|
|
60
60
|
imageName: imageName,
|
|
61
61
|
context: this.context,
|
|
@@ -24,7 +24,7 @@ const port_forwarder_1 = require("../port-forwarder");
|
|
|
24
24
|
const pull_image_1 = require("../docker/functions/image/pull-image");
|
|
25
25
|
const create_container_1 = require("../docker/functions/container/create-container");
|
|
26
26
|
const connect_network_1 = require("../docker/functions/network/connect-network");
|
|
27
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
27
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
28
28
|
const inspect_container_1 = require("../docker/functions/container/inspect-container");
|
|
29
29
|
const start_container_1 = require("../docker/functions/container/start-container");
|
|
30
30
|
const container_logs_1 = require("../docker/functions/container/container-logs");
|
|
@@ -52,8 +52,8 @@ class GenericContainer {
|
|
|
52
52
|
}
|
|
53
53
|
start() {
|
|
54
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
const { dockerode,
|
|
56
|
-
yield (0, pull_image_1.pullImage)(dockerode, indexServerAddress, {
|
|
55
|
+
const { dockerode, info } = yield (0, docker_client_1.getDockerClient)();
|
|
56
|
+
yield (0, pull_image_1.pullImage)(dockerode, info.dockerInfo.indexServerAddress, {
|
|
57
57
|
imageName: this.opts.imageName,
|
|
58
58
|
force: this.pullPolicy.shouldPull(),
|
|
59
59
|
});
|
|
@@ -102,7 +102,7 @@ class GenericContainer {
|
|
|
102
102
|
}
|
|
103
103
|
reuseContainer(container) {
|
|
104
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
const { host, hostIps } = yield (0, docker_client_1.
|
|
105
|
+
const { host, hostIps } = yield (0, docker_client_1.getDockerClient)();
|
|
106
106
|
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
107
107
|
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.opts.exposedPorts);
|
|
108
108
|
if (this.startupTimeout !== undefined) {
|
|
@@ -154,7 +154,7 @@ class GenericContainer {
|
|
|
154
154
|
}
|
|
155
155
|
yield (0, start_container_1.startContainer)(container);
|
|
156
156
|
logger_1.log.info(`Started container for image "${this.opts.imageName}"`, { containerId: container.id });
|
|
157
|
-
const { host, hostIps } = yield (0, docker_client_1.
|
|
157
|
+
const { host, hostIps } = yield (0, docker_client_1.getDockerClient)();
|
|
158
158
|
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
159
159
|
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.opts.exposedPorts);
|
|
160
160
|
if (this.startupTimeout !== undefined) {
|
|
@@ -23,7 +23,7 @@ const stopped_generic_container_1 = require("./stopped-generic-container");
|
|
|
23
23
|
const stop_container_1 = require("../docker/functions/container/stop-container");
|
|
24
24
|
const restart_container_1 = require("../docker/functions/container/restart-container");
|
|
25
25
|
const wait_for_container_1 = require("../wait-for-container");
|
|
26
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
26
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
27
27
|
const async_lock_1 = __importDefault(require("async-lock"));
|
|
28
28
|
class StartedGenericContainer {
|
|
29
29
|
constructor(container, host, inspectResult, boundPorts, name, waitStrategy) {
|
|
@@ -51,7 +51,7 @@ class StartedGenericContainer {
|
|
|
51
51
|
const resolvedOptions = Object.assign({ timeout: 0 }, options);
|
|
52
52
|
logger_1.log.info(`Restarting container...`, { containerId: this.container.id });
|
|
53
53
|
yield (0, restart_container_1.restartContainer)(this.container, resolvedOptions);
|
|
54
|
-
const { hostIps } = yield (0, docker_client_1.
|
|
54
|
+
const { hostIps } = yield (0, docker_client_1.getDockerClient)();
|
|
55
55
|
this.inspectResult = yield (0, inspect_container_1.inspectContainer)(this.container);
|
|
56
56
|
const startTime = this.inspectResult.state.startedAt;
|
|
57
57
|
if (logger_1.containerLog.enabled()) {
|
|
@@ -109,9 +109,9 @@ class StartedGenericContainer {
|
|
|
109
109
|
}
|
|
110
110
|
exec(command) {
|
|
111
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
const { dockerode,
|
|
112
|
+
const { dockerode, containerRuntime } = yield (0, docker_client_1.getDockerClient)();
|
|
113
113
|
logger_1.log.debug(`Executing command "${command.join(" ")}"...`, { containerId: this.container.id });
|
|
114
|
-
const output = yield (0, exec_container_1.execContainer)(dockerode,
|
|
114
|
+
const output = yield (0, exec_container_1.execContainer)(dockerode, containerRuntime, this.container, command);
|
|
115
115
|
logger_1.log.debug(`Executed command "${command.join(" ")}"...`, { containerId: this.container.id });
|
|
116
116
|
return output;
|
|
117
117
|
});
|
package/dist/src/port-check.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Dockerode from "dockerode";
|
|
2
|
-
import {
|
|
2
|
+
import { ContainerRuntime } from "./docker/types";
|
|
3
3
|
export interface PortCheck {
|
|
4
4
|
isBound(port: number): Promise<boolean>;
|
|
5
5
|
}
|
|
@@ -10,11 +10,11 @@ export declare class HostPortCheck implements PortCheck {
|
|
|
10
10
|
}
|
|
11
11
|
export declare class InternalPortCheck implements PortCheck {
|
|
12
12
|
private readonly dockerode;
|
|
13
|
-
private readonly
|
|
13
|
+
private readonly containerRuntime;
|
|
14
14
|
private readonly container;
|
|
15
15
|
private isDistroless;
|
|
16
16
|
private commandOutputs;
|
|
17
|
-
constructor(dockerode: Dockerode,
|
|
17
|
+
constructor(dockerode: Dockerode, containerRuntime: ContainerRuntime, container: Dockerode.Container);
|
|
18
18
|
isBound(port: number): Promise<boolean>;
|
|
19
19
|
private commandOutputsKey;
|
|
20
20
|
}
|
package/dist/src/port-check.js
CHANGED
|
@@ -39,9 +39,9 @@ class HostPortCheck {
|
|
|
39
39
|
}
|
|
40
40
|
exports.HostPortCheck = HostPortCheck;
|
|
41
41
|
class InternalPortCheck {
|
|
42
|
-
constructor(dockerode,
|
|
42
|
+
constructor(dockerode, containerRuntime, container) {
|
|
43
43
|
this.dockerode = dockerode;
|
|
44
|
-
this.
|
|
44
|
+
this.containerRuntime = containerRuntime;
|
|
45
45
|
this.container = container;
|
|
46
46
|
this.isDistroless = false;
|
|
47
47
|
this.commandOutputs = new Set();
|
|
@@ -54,7 +54,7 @@ class InternalPortCheck {
|
|
|
54
54
|
["/bin/sh", "-c", `nc -vz -w 1 localhost ${port}`],
|
|
55
55
|
["/bin/bash", "-c", `</dev/tcp/localhost/${port}`],
|
|
56
56
|
];
|
|
57
|
-
const commandResults = yield Promise.all(commands.map((command) => (0, exec_container_1.execContainer)(this.dockerode, this.
|
|
57
|
+
const commandResults = yield Promise.all(commands.map((command) => (0, exec_container_1.execContainer)(this.dockerode, this.containerRuntime, this.container, command, false)));
|
|
58
58
|
const isBound = commandResults.some((result) => result.exitCode === 0);
|
|
59
59
|
if (!isBound && logger_1.log.enabled()) {
|
|
60
60
|
const shellExists = commandResults.some((result) => result.exitCode !== 126);
|
|
@@ -15,7 +15,7 @@ const logger_1 = require("./logger");
|
|
|
15
15
|
const generic_container_1 = require("./generic-container/generic-container");
|
|
16
16
|
const uuid_1 = require("./uuid");
|
|
17
17
|
const session_id_1 = require("./docker/session-id");
|
|
18
|
-
const docker_client_1 = require("./docker/docker-client");
|
|
18
|
+
const docker_client_1 = require("./docker/client/docker-client");
|
|
19
19
|
const images_1 = require("./images");
|
|
20
20
|
class PortForwarder {
|
|
21
21
|
constructor(sshConnection, container) {
|
|
@@ -70,7 +70,7 @@ class PortForwarderInstance {
|
|
|
70
70
|
`echo "${username}:$PASSWORD" | chpasswd && /usr/sbin/sshd -D -o PermitRootLogin=yes -o AddressFamily=inet -o GatewayPorts=yes -o AllowAgentForwarding=yes -o AllowTcpForwarding=yes -o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostkeyAlgorithms=+ssh-rsa`,
|
|
71
71
|
])
|
|
72
72
|
.start();
|
|
73
|
-
const host = (yield (0, docker_client_1.
|
|
73
|
+
const host = (yield (0, docker_client_1.getDockerClient)()).host;
|
|
74
74
|
const port = container.getMappedPort(22);
|
|
75
75
|
logger_1.log.debug(`Connecting to Port Forwarder on "${host}:${port}"...`);
|
|
76
76
|
const connection = yield (0, ssh_remote_port_forward_1.createSshConnection)({ host, port, username, password });
|
package/dist/src/reaper.js
CHANGED
|
@@ -19,8 +19,8 @@ const port_1 = require("./port");
|
|
|
19
19
|
const labels_1 = require("./labels");
|
|
20
20
|
const wait_1 = require("./wait-strategy/wait");
|
|
21
21
|
const retry_strategy_1 = require("./retry-strategy");
|
|
22
|
-
const
|
|
23
|
-
const docker_client_1 = require("./docker/docker-client");
|
|
22
|
+
const remote_docker_unix_socket_path_1 = require("./docker/remote-docker-unix-socket-path");
|
|
23
|
+
const docker_client_1 = require("./docker/client/docker-client");
|
|
24
24
|
class RealReaper {
|
|
25
25
|
constructor(container, socket) {
|
|
26
26
|
this.container = container;
|
|
@@ -85,13 +85,15 @@ class ReaperInstance {
|
|
|
85
85
|
const containerPort = process.env["TESTCONTAINERS_RYUK_PORT"]
|
|
86
86
|
? { container: 8080, host: Number(process.env["TESTCONTAINERS_RYUK_PORT"]) }
|
|
87
87
|
: 8080;
|
|
88
|
-
|
|
88
|
+
const dockerClient = yield (0, docker_client_1.getDockerClient)();
|
|
89
|
+
const remoteDockerUnixSocketPath = (0, remote_docker_unix_socket_path_1.getRemoteDockerUnixSocketPath)(dockerClient);
|
|
90
|
+
logger_1.log.debug(`Creating new Reaper for session "${session_id_1.sessionId}" with socket path "${remoteDockerUnixSocketPath}"...`);
|
|
89
91
|
const container = new generic_container_1.GenericContainer(images_1.REAPER_IMAGE)
|
|
90
92
|
.withName(`testcontainers-ryuk-${session_id_1.sessionId}`)
|
|
91
93
|
.withExposedPorts(containerPort)
|
|
92
94
|
.withBindMounts([
|
|
93
95
|
{
|
|
94
|
-
source:
|
|
96
|
+
source: remoteDockerUnixSocketPath,
|
|
95
97
|
target: "/var/run/docker.sock",
|
|
96
98
|
},
|
|
97
99
|
])
|
|
@@ -14,13 +14,13 @@ const port_check_1 = require("../port-check");
|
|
|
14
14
|
const logger_1 = require("../logger");
|
|
15
15
|
const retry_strategy_1 = require("../retry-strategy");
|
|
16
16
|
const wait_strategy_1 = require("./wait-strategy");
|
|
17
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
17
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
18
18
|
class HostPortWaitStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
19
19
|
waitUntilReady(container, boundPorts) {
|
|
20
20
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
-
const { dockerode,
|
|
21
|
+
const { dockerode, containerRuntime, host } = yield (0, docker_client_1.getDockerClient)();
|
|
22
22
|
const hostPortCheck = new port_check_1.HostPortCheck(host);
|
|
23
|
-
const internalPortCheck = new port_check_1.InternalPortCheck(dockerode,
|
|
23
|
+
const internalPortCheck = new port_check_1.InternalPortCheck(dockerode, containerRuntime, container);
|
|
24
24
|
yield Promise.all([
|
|
25
25
|
this.waitForHostPorts(hostPortCheck, container, boundPorts),
|
|
26
26
|
this.waitForInternalPorts(internalPortCheck, container, boundPorts),
|
|
@@ -17,7 +17,7 @@ const wait_strategy_1 = require("./wait-strategy");
|
|
|
17
17
|
const retry_strategy_1 = require("../retry-strategy");
|
|
18
18
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
19
19
|
const https_1 = __importDefault(require("https"));
|
|
20
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
20
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
21
21
|
const logger_1 = require("../logger");
|
|
22
22
|
class HttpWaitStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
23
23
|
constructor(path, port) {
|
|
@@ -71,7 +71,7 @@ class HttpWaitStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
|
71
71
|
waitUntilReady(container, boundPorts) {
|
|
72
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
73
|
logger_1.log.debug(`Waiting for HTTP...`, { containerId: container.id });
|
|
74
|
-
const { host } = yield (0, docker_client_1.
|
|
74
|
+
const { host } = yield (0, docker_client_1.getDockerClient)();
|
|
75
75
|
yield new retry_strategy_1.IntervalRetryStrategy(this.readTimeout).retryUntil(() => __awaiter(this, void 0, void 0, function* () {
|
|
76
76
|
try {
|
|
77
77
|
const url = `${this.protocol}://${host}:${boundPorts.getBinding(this.port)}${this.path}`;
|
|
@@ -14,7 +14,7 @@ const logger_1 = require("../logger");
|
|
|
14
14
|
const wait_strategy_1 = require("./wait-strategy");
|
|
15
15
|
const retry_strategy_1 = require("../retry-strategy");
|
|
16
16
|
const exec_container_1 = require("../docker/functions/container/exec-container");
|
|
17
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
17
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
18
18
|
class ShellWaitStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
19
19
|
constructor(command) {
|
|
20
20
|
super();
|
|
@@ -23,9 +23,9 @@ class ShellWaitStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
|
23
23
|
waitUntilReady(container) {
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
25
|
logger_1.log.debug(`Waiting for successful shell command "${this.command}"...`, { containerId: container.id });
|
|
26
|
-
const { dockerode,
|
|
26
|
+
const { dockerode, containerRuntime } = yield (0, docker_client_1.getDockerClient)();
|
|
27
27
|
yield new retry_strategy_1.IntervalRetryStrategy(100).retryUntil(() => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
const { exitCode } = yield (0, exec_container_1.execContainer)(dockerode,
|
|
28
|
+
const { exitCode } = yield (0, exec_container_1.execContainer)(dockerode, containerRuntime, container, ["/bin/sh", "-c", this.command], false);
|
|
29
29
|
return exitCode;
|
|
30
30
|
}), (exitCode) => exitCode === 0, () => {
|
|
31
31
|
const message = `Shell command "${this.command}" not successful after ${this.startupTimeout}ms`;
|
|
@@ -12,12 +12,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.StartupCheckStrategy = void 0;
|
|
13
13
|
const wait_strategy_1 = require("./wait-strategy");
|
|
14
14
|
const retry_strategy_1 = require("../retry-strategy");
|
|
15
|
-
const docker_client_1 = require("../docker/docker-client");
|
|
15
|
+
const docker_client_1 = require("../docker/client/docker-client");
|
|
16
16
|
const logger_1 = require("../logger");
|
|
17
17
|
class StartupCheckStrategy extends wait_strategy_1.AbstractWaitStrategy {
|
|
18
18
|
waitUntilReady(container) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
20
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
21
21
|
const startupStatus = yield new retry_strategy_1.IntervalRetryStrategy(1000).retryUntil(() => __awaiter(this, void 0, void 0, function* () { return yield this.checkStartupState(dockerode, container.id); }), (startupStatus) => startupStatus === "SUCCESS" || startupStatus === "FAIL", () => {
|
|
22
22
|
const message = `Container not accessible after ${this.startupTimeout}ms`;
|
|
23
23
|
logger_1.log.error(message, { containerId: container.id });
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import Dockerode from "dockerode";
|
|
3
|
-
import { HostIps } from "./lookup-host-ips";
|
|
4
|
-
export type Provider = "docker" | "podman";
|
|
5
|
-
type DockerClient = {
|
|
6
|
-
uri: string;
|
|
7
|
-
provider: Provider;
|
|
8
|
-
host: string;
|
|
9
|
-
hostIps: HostIps;
|
|
10
|
-
dockerode: Dockerode;
|
|
11
|
-
indexServerAddress: string;
|
|
12
|
-
composeEnvironment: NodeJS.ProcessEnv;
|
|
13
|
-
};
|
|
14
|
-
export type DockerClientInit = {
|
|
15
|
-
uri: string;
|
|
16
|
-
dockerode: Dockerode;
|
|
17
|
-
composeEnvironment: NodeJS.ProcessEnv;
|
|
18
|
-
};
|
|
19
|
-
export interface DockerClientStrategy {
|
|
20
|
-
init?(): Promise<void>;
|
|
21
|
-
isApplicable(): boolean;
|
|
22
|
-
getDockerClient(): Promise<DockerClientInit>;
|
|
23
|
-
getName(): string;
|
|
24
|
-
}
|
|
25
|
-
export declare const dockerClient: () => Promise<DockerClient>;
|
|
26
|
-
export {};
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.dockerClient = void 0;
|
|
16
|
-
const dockerode_1 = __importDefault(require("dockerode"));
|
|
17
|
-
const path_1 = __importDefault(require("path"));
|
|
18
|
-
const logger_1 = require("../logger");
|
|
19
|
-
const url_1 = require("url");
|
|
20
|
-
const fs_1 = require("fs");
|
|
21
|
-
const session_id_1 = require("./session-id");
|
|
22
|
-
const lookup_host_ips_1 = require("./lookup-host-ips");
|
|
23
|
-
const system_info_1 = require("../system-info");
|
|
24
|
-
const rootless_unix_socket_strategy_1 = require("./rootless-unix-socket-strategy");
|
|
25
|
-
const stream_utils_1 = require("../stream-utils");
|
|
26
|
-
const stream_1 = require("stream");
|
|
27
|
-
const docker_client_config_1 = require("./docker-client-config");
|
|
28
|
-
const resolve_host_1 = require("./resolve-host");
|
|
29
|
-
const getDockerClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
-
const strategies = [
|
|
31
|
-
new ConfigurationStrategy(),
|
|
32
|
-
new UnixSocketStrategy(),
|
|
33
|
-
new rootless_unix_socket_strategy_1.RootlessUnixSocketStrategy(),
|
|
34
|
-
new NpipeSocketStrategy(),
|
|
35
|
-
];
|
|
36
|
-
for (const strategy of strategies) {
|
|
37
|
-
if (strategy.init) {
|
|
38
|
-
yield strategy.init();
|
|
39
|
-
}
|
|
40
|
-
if (strategy.isApplicable()) {
|
|
41
|
-
logger_1.log.debug(`Found Docker client strategy "${strategy.getName()}"`);
|
|
42
|
-
const { uri, dockerode, composeEnvironment } = yield strategy.getDockerClient();
|
|
43
|
-
logger_1.log.debug(`Testing Docker client strategy "${uri}"...`);
|
|
44
|
-
if (yield isDockerDaemonReachable(dockerode)) {
|
|
45
|
-
const indexServerAddress = (yield (0, system_info_1.getSystemInfo)(dockerode)).dockerInfo.indexServerAddress;
|
|
46
|
-
const provider = uri.includes("podman.sock") ? "podman" : "docker";
|
|
47
|
-
const host = yield (0, resolve_host_1.resolveHost)(dockerode, provider, indexServerAddress, uri);
|
|
48
|
-
const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
|
|
49
|
-
logger_1.log.info(`Using Docker client strategy "${strategy.getName()}", Docker host "${host}" (${hostIps
|
|
50
|
-
.map((hostIp) => hostIp.address)
|
|
51
|
-
.join(", ")})`);
|
|
52
|
-
return { uri, provider, host, hostIps, dockerode, indexServerAddress, composeEnvironment };
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
logger_1.log.warn(`Docker client strategy ${strategy.getName()} is not reachable`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
throw new Error("No Docker client strategy found");
|
|
60
|
-
});
|
|
61
|
-
const isDockerDaemonReachable = (dockerode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
-
try {
|
|
63
|
-
const response = yield dockerode.ping();
|
|
64
|
-
return (yield (0, stream_utils_1.streamToString)(stream_1.Readable.from(response))) === "OK";
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
logger_1.log.warn(`Docker daemon is not reachable: ${err}`);
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
class ConfigurationStrategy {
|
|
72
|
-
init() {
|
|
73
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
this.dockerConfig = yield (0, docker_client_config_1.getDockerClientConfig)();
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
getDockerClient() {
|
|
78
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
-
const { dockerHost, dockerTlsVerify, dockerCertPath } = this.dockerConfig;
|
|
80
|
-
const dockerOptions = { headers: { "x-tc-sid": session_id_1.sessionId } };
|
|
81
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
82
|
-
const { pathname, hostname, port } = new url_1.URL(dockerHost);
|
|
83
|
-
if (hostname !== "") {
|
|
84
|
-
dockerOptions.host = hostname;
|
|
85
|
-
dockerOptions.port = port;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
dockerOptions.socketPath = pathname;
|
|
89
|
-
}
|
|
90
|
-
if (dockerTlsVerify === "1" && dockerCertPath !== undefined) {
|
|
91
|
-
dockerOptions.ca = yield fs_1.promises.readFile(path_1.default.resolve(dockerCertPath, "ca.pem"));
|
|
92
|
-
dockerOptions.cert = yield fs_1.promises.readFile(path_1.default.resolve(dockerCertPath, "cert.pem"));
|
|
93
|
-
dockerOptions.key = yield fs_1.promises.readFile(path_1.default.resolve(dockerCertPath, "key.pem"));
|
|
94
|
-
}
|
|
95
|
-
return {
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
97
|
-
uri: dockerHost,
|
|
98
|
-
dockerode: new dockerode_1.default(dockerOptions),
|
|
99
|
-
composeEnvironment: {
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
101
|
-
DOCKER_HOST: dockerHost,
|
|
102
|
-
DOCKER_TLS_VERIFY: dockerTlsVerify,
|
|
103
|
-
DOCKER_CERT_PATH: dockerCertPath,
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
isApplicable() {
|
|
109
|
-
return this.dockerConfig.dockerHost !== undefined;
|
|
110
|
-
}
|
|
111
|
-
getName() {
|
|
112
|
-
return "ConfigurationStrategy";
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
class UnixSocketStrategy {
|
|
116
|
-
getDockerClient() {
|
|
117
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
return {
|
|
119
|
-
uri: "unix:///var/run/docker.sock",
|
|
120
|
-
dockerode: new dockerode_1.default({ socketPath: "/var/run/docker.sock" }),
|
|
121
|
-
composeEnvironment: {},
|
|
122
|
-
};
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
isApplicable() {
|
|
126
|
-
return (process.platform === "linux" || process.platform === "darwin") && (0, fs_1.existsSync)("/var/run/docker.sock");
|
|
127
|
-
}
|
|
128
|
-
getName() {
|
|
129
|
-
return "UnixSocketStrategy";
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
class NpipeSocketStrategy {
|
|
133
|
-
getDockerClient() {
|
|
134
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
return {
|
|
136
|
-
uri: "npipe:////./pipe/docker_engine",
|
|
137
|
-
dockerode: new dockerode_1.default({ socketPath: "//./pipe/docker_engine" }),
|
|
138
|
-
composeEnvironment: {},
|
|
139
|
-
};
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
isApplicable() {
|
|
143
|
-
return process.platform === "win32";
|
|
144
|
-
}
|
|
145
|
-
getName() {
|
|
146
|
-
return "NpipeSocketStrategy";
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
let _dockerClient;
|
|
150
|
-
const dockerClient = () => {
|
|
151
|
-
if (!_dockerClient) {
|
|
152
|
-
_dockerClient = getDockerClient();
|
|
153
|
-
}
|
|
154
|
-
return _dockerClient;
|
|
155
|
-
};
|
|
156
|
-
exports.dockerClient = dockerClient;
|