testcontainers 9.7.0 → 9.8.0
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 +3 -3
- 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
package/dist/package.json
CHANGED
|
@@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.getDockerClientConfig = void 0;
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
|
-
const logger_1 = require("
|
|
17
|
+
const logger_1 = require("../../logger");
|
|
18
18
|
const os_1 = require("os");
|
|
19
19
|
const fs_1 = require("fs");
|
|
20
20
|
const promises_1 = require("fs/promises");
|
|
@@ -30,20 +30,24 @@ function loadFromFile() {
|
|
|
30
30
|
const file = path_1.default.resolve((0, os_1.homedir)(), ".testcontainers.properties");
|
|
31
31
|
const dockerClientConfig = {};
|
|
32
32
|
if ((0, fs_1.existsSync)(file)) {
|
|
33
|
-
logger_1.log.debug(`
|
|
33
|
+
logger_1.log.debug(`Loading ".testcontainers.properties" file...`);
|
|
34
34
|
const string = yield (0, promises_1.readFile)(file, { encoding: "utf-8" });
|
|
35
35
|
const properties = (0, properties_reader_1.default)("").read(string);
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
dockerClientConfig.
|
|
36
|
+
const tcHost = properties.get("tc.host");
|
|
37
|
+
if (tcHost !== null) {
|
|
38
|
+
dockerClientConfig.tcHost = tcHost;
|
|
39
39
|
}
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
dockerClientConfig.
|
|
40
|
+
const dockerHost = properties.get("docker.host");
|
|
41
|
+
if (dockerHost !== null) {
|
|
42
|
+
dockerClientConfig.dockerHost = dockerHost;
|
|
43
43
|
}
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
dockerClientConfig.
|
|
44
|
+
const dockerTlsVerify = properties.get("docker.tls.verify");
|
|
45
|
+
if (dockerTlsVerify !== null) {
|
|
46
|
+
dockerClientConfig.dockerTlsVerify = `${dockerTlsVerify}`;
|
|
47
|
+
}
|
|
48
|
+
const dockerCertPath = properties.get("docker.cert.path");
|
|
49
|
+
if (dockerCertPath !== null) {
|
|
50
|
+
dockerClientConfig.dockerCertPath = dockerCertPath;
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
return dockerClientConfig;
|
|
@@ -63,6 +67,9 @@ function loadFromEnv(env) {
|
|
|
63
67
|
return dockerClientConfig;
|
|
64
68
|
}
|
|
65
69
|
function logDockerClientConfig(config) {
|
|
70
|
+
if (!logger_1.log.enabled()) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
66
73
|
const configurations = Object.entries(config)
|
|
67
74
|
.filter(([, value]) => value !== undefined)
|
|
68
75
|
.map(([key, value]) => `${key}: "${value}"`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import Dockerode from "dockerode";
|
|
3
|
+
import { HostIps } from "../lookup-host-ips";
|
|
4
|
+
import { SystemInfo } from "../../system-info";
|
|
5
|
+
import { ContainerRuntime } from "../types";
|
|
6
|
+
export type DockerClient = DockerClientStrategyResult & {
|
|
7
|
+
host: string;
|
|
8
|
+
containerRuntime: ContainerRuntime;
|
|
9
|
+
hostIps: HostIps;
|
|
10
|
+
info: SystemInfo;
|
|
11
|
+
};
|
|
12
|
+
export type DockerClientStrategyResult = {
|
|
13
|
+
uri: string;
|
|
14
|
+
dockerode: Dockerode;
|
|
15
|
+
composeEnvironment: NodeJS.ProcessEnv;
|
|
16
|
+
allowUserOverrides: boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare function getDockerClient(): Promise<DockerClient>;
|
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getDockerClient = void 0;
|
|
13
|
+
const logger_1 = require("../../logger");
|
|
14
|
+
const lookup_host_ips_1 = require("../lookup-host-ips");
|
|
15
|
+
const system_info_1 = require("../../system-info");
|
|
16
|
+
const rootless_unix_socket_strategy_1 = require("./strategy/rootless-unix-socket-strategy");
|
|
17
|
+
const stream_utils_1 = require("../../stream-utils");
|
|
18
|
+
const stream_1 = require("stream");
|
|
19
|
+
const resolve_host_1 = require("../resolve-host");
|
|
20
|
+
const configuration_strategy_1 = require("./strategy/configuration-strategy");
|
|
21
|
+
const unix_socket_strategy_1 = require("./strategy/unix-socket-strategy");
|
|
22
|
+
const npipe_socket_strategy_1 = require("./strategy/npipe-socket-strategy");
|
|
23
|
+
const testcontainers_host_strategy_1 = require("./strategy/testcontainers-host-strategy");
|
|
24
|
+
let dockerClient;
|
|
25
|
+
function getDockerClient() {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
if (dockerClient) {
|
|
28
|
+
return dockerClient;
|
|
29
|
+
}
|
|
30
|
+
const strategies = [
|
|
31
|
+
new testcontainers_host_strategy_1.TestcontainersHostStrategy(),
|
|
32
|
+
new configuration_strategy_1.ConfigurationStrategy(),
|
|
33
|
+
new unix_socket_strategy_1.UnixSocketStrategy(),
|
|
34
|
+
new rootless_unix_socket_strategy_1.RootlessUnixSocketStrategy(),
|
|
35
|
+
new npipe_socket_strategy_1.NpipeSocketStrategy(),
|
|
36
|
+
];
|
|
37
|
+
for (const strategy of strategies) {
|
|
38
|
+
if (strategy.init) {
|
|
39
|
+
yield strategy.init();
|
|
40
|
+
}
|
|
41
|
+
if (strategy.isApplicable()) {
|
|
42
|
+
logger_1.log.debug(`Found Docker client strategy "${strategy.getName()}"`);
|
|
43
|
+
const { uri, dockerode, composeEnvironment, allowUserOverrides } = yield strategy.getDockerClient();
|
|
44
|
+
logger_1.log.debug(`Testing Docker client strategy "${uri}"...`);
|
|
45
|
+
if (yield isDockerDaemonReachable(dockerode)) {
|
|
46
|
+
const info = yield (0, system_info_1.getSystemInfo)(dockerode);
|
|
47
|
+
const containerRuntime = uri.includes("podman.sock") ? "podman" : "docker";
|
|
48
|
+
const host = yield (0, resolve_host_1.resolveHost)(dockerode, containerRuntime, info.dockerInfo.indexServerAddress, uri, allowUserOverrides);
|
|
49
|
+
const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
|
|
50
|
+
dockerClient = {
|
|
51
|
+
uri,
|
|
52
|
+
containerRuntime,
|
|
53
|
+
host,
|
|
54
|
+
hostIps,
|
|
55
|
+
dockerode,
|
|
56
|
+
info,
|
|
57
|
+
composeEnvironment,
|
|
58
|
+
allowUserOverrides,
|
|
59
|
+
};
|
|
60
|
+
logDockerClient(strategy.getName(), dockerClient);
|
|
61
|
+
return dockerClient;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
logger_1.log.warn(`Docker client strategy "${strategy.getName()}" is not working`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
throw new Error("No Docker client strategy found");
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.getDockerClient = getDockerClient;
|
|
72
|
+
function isDockerDaemonReachable(dockerode) {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
try {
|
|
75
|
+
const response = yield dockerode.ping();
|
|
76
|
+
return (yield (0, stream_utils_1.streamToString)(stream_1.Readable.from(response))) === "OK";
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
logger_1.log.warn(`Docker daemon is not reachable: ${err}`);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function logDockerClient(strategyName, { host, hostIps }) {
|
|
85
|
+
if (!logger_1.log.enabled()) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const formattedHostIps = hostIps.map((hostIp) => hostIp.address).join(", ");
|
|
89
|
+
logger_1.log.info(`Using Docker client strategy "${strategyName}", Docker host "${host}" (${formattedHostIps})`);
|
|
90
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DockerClientStrategyResult } from "../docker-client";
|
|
2
|
+
import { DockerClientStrategy } from "./docker-client-strategy";
|
|
3
|
+
export declare class ConfigurationStrategy implements DockerClientStrategy {
|
|
4
|
+
private dockerHost;
|
|
5
|
+
private dockerTlsVerify;
|
|
6
|
+
private dockerCertPath;
|
|
7
|
+
init(): Promise<void>;
|
|
8
|
+
getDockerClient(): Promise<DockerClientStrategyResult>;
|
|
9
|
+
isApplicable(): boolean;
|
|
10
|
+
getName(): string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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.ConfigurationStrategy = void 0;
|
|
16
|
+
const docker_client_config_1 = require("../docker-client-config");
|
|
17
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
18
|
+
const session_id_1 = require("../../session-id");
|
|
19
|
+
const url_1 = require("url");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
class ConfigurationStrategy {
|
|
23
|
+
init() {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const { dockerHost, dockerTlsVerify, dockerCertPath } = yield (0, docker_client_config_1.getDockerClientConfig)();
|
|
26
|
+
if (dockerHost) {
|
|
27
|
+
this.dockerHost = dockerHost;
|
|
28
|
+
}
|
|
29
|
+
this.dockerTlsVerify = dockerTlsVerify;
|
|
30
|
+
this.dockerCertPath = dockerCertPath;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
getDockerClient() {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
const dockerOptions = { headers: { "x-tc-sid": session_id_1.sessionId } };
|
|
36
|
+
const { pathname, hostname, port } = new url_1.URL(this.dockerHost);
|
|
37
|
+
if (hostname !== "") {
|
|
38
|
+
dockerOptions.host = hostname;
|
|
39
|
+
dockerOptions.port = port;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
dockerOptions.socketPath = pathname;
|
|
43
|
+
}
|
|
44
|
+
if (this.dockerTlsVerify === "1" && this.dockerCertPath !== undefined) {
|
|
45
|
+
dockerOptions.ca = yield fs_1.promises.readFile(path_1.default.resolve(this.dockerCertPath, "ca.pem"));
|
|
46
|
+
dockerOptions.cert = yield fs_1.promises.readFile(path_1.default.resolve(this.dockerCertPath, "cert.pem"));
|
|
47
|
+
dockerOptions.key = yield fs_1.promises.readFile(path_1.default.resolve(this.dockerCertPath, "key.pem"));
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
uri: this.dockerHost,
|
|
51
|
+
dockerode: new dockerode_1.default(dockerOptions),
|
|
52
|
+
composeEnvironment: {
|
|
53
|
+
DOCKER_HOST: this.dockerHost,
|
|
54
|
+
DOCKER_TLS_VERIFY: this.dockerTlsVerify,
|
|
55
|
+
DOCKER_CERT_PATH: this.dockerCertPath,
|
|
56
|
+
},
|
|
57
|
+
allowUserOverrides: true,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
isApplicable() {
|
|
62
|
+
return this.dockerHost !== undefined;
|
|
63
|
+
}
|
|
64
|
+
getName() {
|
|
65
|
+
return "ConfigurationStrategy";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.ConfigurationStrategy = ConfigurationStrategy;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DockerClientStrategyResult } from "../docker-client";
|
|
2
|
+
import { DockerClientStrategy } from "./docker-client-strategy";
|
|
3
|
+
export declare class NpipeSocketStrategy implements DockerClientStrategy {
|
|
4
|
+
getDockerClient(): Promise<DockerClientStrategyResult>;
|
|
5
|
+
isApplicable(): boolean;
|
|
6
|
+
getName(): string;
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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.NpipeSocketStrategy = void 0;
|
|
16
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
17
|
+
class NpipeSocketStrategy {
|
|
18
|
+
getDockerClient() {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
return {
|
|
21
|
+
uri: "npipe:////./pipe/docker_engine",
|
|
22
|
+
dockerode: new dockerode_1.default({ socketPath: "//./pipe/docker_engine" }),
|
|
23
|
+
composeEnvironment: {},
|
|
24
|
+
allowUserOverrides: true,
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
isApplicable() {
|
|
29
|
+
return process.platform === "win32";
|
|
30
|
+
}
|
|
31
|
+
getName() {
|
|
32
|
+
return "NpipeSocketStrategy";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.NpipeSocketStrategy = NpipeSocketStrategy;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
2
|
+
import { DockerClientStrategyResult } from "../docker-client";
|
|
3
|
+
import { DockerClientStrategy } from "./docker-client-strategy";
|
|
3
4
|
export declare class RootlessUnixSocketStrategy implements DockerClientStrategy {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly env;
|
|
@@ -11,7 +12,7 @@ export declare class RootlessUnixSocketStrategy implements DockerClientStrategy
|
|
|
11
12
|
private getSocketPathFromHomeRunDir;
|
|
12
13
|
private getSocketPathFromHomeDesktopDir;
|
|
13
14
|
private getSocketPathFromRunDir;
|
|
14
|
-
getDockerClient(): Promise<
|
|
15
|
+
getDockerClient(): Promise<DockerClientStrategyResult>;
|
|
15
16
|
isApplicable(): boolean;
|
|
16
17
|
getName(): string;
|
|
17
18
|
}
|
|
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.RootlessUnixSocketStrategy = void 0;
|
|
16
|
-
const type_guards_1 = require("
|
|
16
|
+
const type_guards_1 = require("../../../type-guards");
|
|
17
17
|
const fs_1 = require("fs");
|
|
18
18
|
const path_1 = __importDefault(require("path"));
|
|
19
19
|
const os_1 = __importDefault(require("os"));
|
|
@@ -64,6 +64,7 @@ class RootlessUnixSocketStrategy {
|
|
|
64
64
|
uri: `unix://${this.socketPath}`,
|
|
65
65
|
dockerode: new dockerode_1.default({ socketPath: this.socketPath }),
|
|
66
66
|
composeEnvironment: {},
|
|
67
|
+
allowUserOverrides: true,
|
|
67
68
|
};
|
|
68
69
|
});
|
|
69
70
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DockerClientStrategyResult } from "../docker-client";
|
|
2
|
+
import { DockerClientStrategy } from "./docker-client-strategy";
|
|
3
|
+
export declare class TestcontainersHostStrategy implements DockerClientStrategy {
|
|
4
|
+
private host;
|
|
5
|
+
init(): Promise<void>;
|
|
6
|
+
getDockerClient(): Promise<DockerClientStrategyResult>;
|
|
7
|
+
isApplicable(): boolean;
|
|
8
|
+
getName(): string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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.TestcontainersHostStrategy = void 0;
|
|
16
|
+
const docker_client_config_1 = require("../docker-client-config");
|
|
17
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
18
|
+
const session_id_1 = require("../../session-id");
|
|
19
|
+
const url_1 = require("url");
|
|
20
|
+
class TestcontainersHostStrategy {
|
|
21
|
+
init() {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const { tcHost } = yield (0, docker_client_config_1.getDockerClientConfig)();
|
|
24
|
+
if (tcHost) {
|
|
25
|
+
this.host = tcHost;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
getDockerClient() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const dockerOptions = { headers: { "x-tc-sid": session_id_1.sessionId } };
|
|
32
|
+
const { hostname, port } = new url_1.URL(this.host);
|
|
33
|
+
dockerOptions.host = hostname;
|
|
34
|
+
dockerOptions.port = port;
|
|
35
|
+
return {
|
|
36
|
+
uri: this.host,
|
|
37
|
+
dockerode: new dockerode_1.default(dockerOptions),
|
|
38
|
+
composeEnvironment: {
|
|
39
|
+
DOCKER_HOST: this.host,
|
|
40
|
+
},
|
|
41
|
+
allowUserOverrides: false,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
isApplicable() {
|
|
46
|
+
return this.host !== undefined;
|
|
47
|
+
}
|
|
48
|
+
getName() {
|
|
49
|
+
return "TestcontainersHostStrategy";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.TestcontainersHostStrategy = TestcontainersHostStrategy;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DockerClientStrategyResult } from "../docker-client";
|
|
2
|
+
import { DockerClientStrategy } from "./docker-client-strategy";
|
|
3
|
+
export declare class UnixSocketStrategy implements DockerClientStrategy {
|
|
4
|
+
getDockerClient(): Promise<DockerClientStrategyResult>;
|
|
5
|
+
isApplicable(): boolean;
|
|
6
|
+
getName(): string;
|
|
7
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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.UnixSocketStrategy = void 0;
|
|
16
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
17
|
+
const fs_1 = require("fs");
|
|
18
|
+
class UnixSocketStrategy {
|
|
19
|
+
getDockerClient() {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
return {
|
|
22
|
+
uri: "unix:///var/run/docker.sock",
|
|
23
|
+
dockerode: new dockerode_1.default({ socketPath: "/var/run/docker.sock" }),
|
|
24
|
+
composeEnvironment: {},
|
|
25
|
+
allowUserOverrides: true,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
isApplicable() {
|
|
30
|
+
return (process.platform === "linux" || process.platform === "darwin") && (0, fs_1.existsSync)("/var/run/docker.sock");
|
|
31
|
+
}
|
|
32
|
+
getName() {
|
|
33
|
+
return "UnixSocketStrategy";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.UnixSocketStrategy = UnixSocketStrategy;
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.containerLogs = void 0;
|
|
13
13
|
const logger_1 = require("../../../logger");
|
|
14
14
|
const demux_stream_1 = require("../demux-stream");
|
|
15
|
-
const docker_client_1 = require("../../docker-client");
|
|
15
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
16
16
|
const containerLogs = (container, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
try {
|
|
18
18
|
const stream = (yield container.logs({
|
|
@@ -22,7 +22,7 @@ const containerLogs = (container, options = {}) => __awaiter(void 0, void 0, voi
|
|
|
22
22
|
since: options.since ? options.since.getTime() / 1000 : 0,
|
|
23
23
|
}));
|
|
24
24
|
stream.socket.unref();
|
|
25
|
-
return (0, demux_stream_1.demuxStream)((yield (0, docker_client_1.
|
|
25
|
+
return (0, demux_stream_1.demuxStream)((yield (0, docker_client_1.getDockerClient)()).dockerode, stream);
|
|
26
26
|
}
|
|
27
27
|
catch (err) {
|
|
28
28
|
logger_1.log.error(`Failed to get container logs: ${err}`);
|
|
@@ -11,14 +11,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.createContainer = 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 port_1 = require("../../../port");
|
|
16
16
|
const create_labels_1 = require("../create-labels");
|
|
17
17
|
const createContainer = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
18
|
var _a, _b;
|
|
19
19
|
try {
|
|
20
20
|
logger_1.log.info(`Creating container for image "${options.imageName}"...`);
|
|
21
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
21
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
22
22
|
const container = yield dockerode.createContainer({
|
|
23
23
|
name: options.name,
|
|
24
24
|
User: options.user,
|
|
@@ -74,7 +74,7 @@ const getPortBindings = (exposedPorts) => {
|
|
|
74
74
|
dockerodePortBindings[exposedPort.container] = [{ HostPort: exposedPort.host.toString() }];
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
|
-
dockerodePortBindings[exposedPort] = [{ HostPort: "" }];
|
|
77
|
+
dockerodePortBindings[exposedPort] = [{ HostPort: "0" }];
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
return dockerodePortBindings;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ExecResult } from "../../types";
|
|
1
|
+
import { ContainerRuntime, ExecResult } from "../../types";
|
|
2
2
|
import Dockerode from "dockerode";
|
|
3
|
-
|
|
4
|
-
export declare const execContainer: (dockerode: Dockerode, provider: Provider, container: Dockerode.Container, command: string[], shouldLog?: boolean) => Promise<ExecResult>;
|
|
3
|
+
export declare const execContainer: (dockerode: Dockerode, containerRuntime: ContainerRuntime, container: Dockerode.Container, command: string[], shouldLog?: boolean) => Promise<ExecResult>;
|
|
@@ -16,7 +16,7 @@ exports.execContainer = void 0;
|
|
|
16
16
|
const logger_1 = require("../../../logger");
|
|
17
17
|
const byline_1 = __importDefault(require("byline"));
|
|
18
18
|
const demux_stream_1 = require("../demux-stream");
|
|
19
|
-
const execContainer = (dockerode,
|
|
19
|
+
const execContainer = (dockerode, containerRuntime, container, command, shouldLog = true) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
20
|
const chunks = [];
|
|
21
21
|
try {
|
|
22
22
|
const exec = yield container.exec({
|
|
@@ -24,7 +24,7 @@ const execContainer = (dockerode, provider, container, command, shouldLog = true
|
|
|
24
24
|
AttachStdout: true,
|
|
25
25
|
AttachStderr: true,
|
|
26
26
|
});
|
|
27
|
-
const stream = yield startExec(dockerode,
|
|
27
|
+
const stream = yield startExec(dockerode, containerRuntime, exec, container);
|
|
28
28
|
stream.on("data", (chunk) => chunks.push(chunk));
|
|
29
29
|
if (shouldLog && logger_1.execLog.enabled()) {
|
|
30
30
|
(0, byline_1.default)(stream).on("data", (line) => logger_1.execLog.trace(line, { containerId: container.id }));
|
|
@@ -41,10 +41,10 @@ const execContainer = (dockerode, provider, container, command, shouldLog = true
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
exports.execContainer = execContainer;
|
|
44
|
-
const startExec = (dockerode,
|
|
44
|
+
const startExec = (dockerode, containerRuntime, exec, container) => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
45
|
try {
|
|
46
46
|
const stream = yield exec.start({ stdin: true, Detach: false, Tty: true });
|
|
47
|
-
if (
|
|
47
|
+
if (containerRuntime === "podman") {
|
|
48
48
|
return (0, demux_stream_1.demuxStream)(dockerode, stream);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
@@ -10,12 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.getContainerByHash = exports.getContainerById = void 0;
|
|
13
|
-
const docker_client_1 = require("../../docker-client");
|
|
13
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
14
14
|
const logger_1 = require("../../../logger");
|
|
15
15
|
const labels_1 = require("../../../labels");
|
|
16
16
|
const getContainerById = (id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
try {
|
|
18
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
18
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
19
19
|
return dockerode.getContainer(id);
|
|
20
20
|
}
|
|
21
21
|
catch (err) {
|
|
@@ -26,7 +26,7 @@ const getContainerById = (id) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
26
26
|
exports.getContainerById = getContainerById;
|
|
27
27
|
const getContainerByHash = (hash) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
28
|
try {
|
|
29
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
29
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
30
30
|
const containers = yield dockerode.listContainers({
|
|
31
31
|
limit: 1,
|
|
32
32
|
filters: {
|
|
@@ -10,11 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.listContainers = void 0;
|
|
13
|
-
const docker_client_1 = require("../../docker-client");
|
|
13
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
14
14
|
const logger_1 = require("../../../logger");
|
|
15
15
|
const listContainers = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
16
|
try {
|
|
17
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
17
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
18
18
|
return yield dockerode.listContainers();
|
|
19
19
|
}
|
|
20
20
|
catch (err) {
|
|
@@ -16,7 +16,7 @@ exports.buildImage = void 0;
|
|
|
16
16
|
const logger_1 = require("../../../logger");
|
|
17
17
|
const tar_fs_1 = __importDefault(require("tar-fs"));
|
|
18
18
|
const byline_1 = __importDefault(require("byline"));
|
|
19
|
-
const docker_client_1 = require("../../docker-client");
|
|
19
|
+
const docker_client_1 = require("../../client/docker-client");
|
|
20
20
|
const create_labels_1 = require("../create-labels");
|
|
21
21
|
const path_1 = __importDefault(require("path"));
|
|
22
22
|
const fs_1 = require("fs");
|
|
@@ -36,7 +36,7 @@ const buildImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
});
|
|
39
|
-
const { dockerode } = yield (0, docker_client_1.
|
|
39
|
+
const { dockerode } = yield (0, docker_client_1.getDockerClient)();
|
|
40
40
|
const buildImageOptions = {
|
|
41
41
|
dockerfile: options.dockerfileName,
|
|
42
42
|
nocache: !options.cache,
|
|
@@ -14,10 +14,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.pullImage = void 0;
|
|
16
16
|
const logger_1 = require("../../../logger");
|
|
17
|
-
const pull_stream_parser_1 = require("../../pull-stream-parser");
|
|
18
17
|
const image_exists_1 = require("./image-exists");
|
|
19
18
|
const get_auth_config_1 = require("../../../registry-auth-locator/get-auth-config");
|
|
20
19
|
const async_lock_1 = __importDefault(require("async-lock"));
|
|
20
|
+
const byline_1 = __importDefault(require("byline"));
|
|
21
21
|
const imagePullLock = new async_lock_1.default();
|
|
22
22
|
const pullImage = (dockerode, indexServerAddress, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
23
|
try {
|
|
@@ -30,7 +30,14 @@ const pullImage = (dockerode, indexServerAddress, options) => __awaiter(void 0,
|
|
|
30
30
|
logger_1.log.info(`Pulling image "${options.imageName}"...`);
|
|
31
31
|
const authconfig = yield (0, get_auth_config_1.getAuthConfig)((_a = options.imageName.registry) !== null && _a !== void 0 ? _a : indexServerAddress);
|
|
32
32
|
const stream = yield dockerode.pull(options.imageName.toString(), { authconfig });
|
|
33
|
-
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
(0, byline_1.default)(stream).on("data", (line) => {
|
|
35
|
+
if (logger_1.pullLog.enabled()) {
|
|
36
|
+
logger_1.pullLog.trace(line, { imageName: options.imageName.toString() });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
stream.on("end", resolve);
|
|
40
|
+
});
|
|
34
41
|
}));
|
|
35
42
|
}
|
|
36
43
|
catch (err) {
|