testcontainers 9.3.0 → 9.5.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 +17 -17
- package/dist/src/docker/docker-client.js +2 -45
- package/dist/src/docker/functions/container/exec-container.d.ts +1 -7
- package/dist/src/docker/functions/container/exec-container.js +4 -4
- package/dist/src/docker/resolve-host.d.ts +6 -0
- package/dist/src/docker/resolve-host.js +60 -0
- package/dist/src/docker/rootless-unix-socket-strategy.d.ts +2 -1
- package/dist/src/docker/rootless-unix-socket-strategy.js +10 -2
- package/dist/src/docker-compose/default-docker-compose-options.js +12 -0
- package/dist/src/docker-compose/functions/docker-compose-pull.d.ts +2 -0
- package/dist/src/docker-compose/functions/docker-compose-pull.js +35 -0
- package/dist/src/docker-compose/functions/docker-compose-up.js +2 -2
- package/dist/src/docker-compose-environment/docker-compose-environment.d.ts +4 -1
- package/dist/src/docker-compose-environment/docker-compose-environment.js +17 -5
- package/dist/src/dockerfile-parser.js +2 -1
- package/dist/src/generic-container/create-container-options.d.ts +3 -0
- package/dist/src/generic-container/create-container-options.js +18 -0
- package/dist/src/generic-container/generic-container.d.ts +17 -26
- package/dist/src/generic-container/generic-container.js +80 -83
- package/dist/src/generic-container/started-generic-container.d.ts +5 -3
- package/dist/src/generic-container/started-generic-container.js +13 -6
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +2 -2
- package/dist/src/modules/abstract-started-container.d.ts +2 -0
- package/dist/src/modules/abstract-started-container.js +10 -1
- package/dist/src/modules/arangodb/arangodb-container.js +1 -1
- package/dist/src/modules/elasticsearch/elasticsearch-container.js +7 -1
- package/dist/src/modules/kafka/kafka-container.d.ts +2 -3
- package/dist/src/modules/kafka/kafka-container.js +8 -8
- package/dist/src/modules/mongodb/mongodb-container.d.ts +1 -1
- package/dist/src/modules/mongodb/mongodb-container.js +2 -2
- package/dist/src/modules/mysql/mysql-container.js +1 -1
- package/dist/src/modules/nats/nats-container.js +4 -2
- package/dist/src/modules/neo4j/neo4j-container.js +1 -1
- package/dist/src/modules/postgresql/postgresql-container.js +2 -2
- package/dist/src/port-check.js +1 -1
- package/dist/src/reaper.js +1 -1
- package/dist/src/test-container.d.ts +1 -1
- package/dist/src/type-guards.d.ts +2 -0
- package/dist/src/type-guards.js +6 -4
- package/dist/src/wait-for-container.d.ts +1 -1
- package/dist/src/wait-strategy/default-wait-strategy.d.ts +3 -0
- package/dist/src/wait-strategy/default-wait-strategy.js +7 -0
- package/dist/src/wait-strategy/health-check-wait-strategy.d.ts +5 -0
- package/dist/src/wait-strategy/health-check-wait-strategy.js +31 -0
- package/dist/src/wait-strategy/host-port-wait-strategy.d.ts +13 -0
- package/dist/src/wait-strategy/host-port-wait-strategy.js +54 -0
- package/dist/src/{http-wait-strategy.d.ts → wait-strategy/http-wait-strategy.d.ts} +1 -1
- package/dist/src/{http-wait-strategy.js → wait-strategy/http-wait-strategy.js} +1 -1
- package/dist/src/wait-strategy/log-wait-strategy.d.ts +10 -0
- package/dist/src/wait-strategy/log-wait-strategy.js +67 -0
- package/dist/src/wait-strategy/shell-wait-strategy.d.ts +7 -0
- package/dist/src/wait-strategy/shell-wait-strategy.js +35 -0
- package/dist/src/{startup-check-strategy.js → wait-strategy/startup-check-strategy.js} +2 -2
- package/dist/src/wait-strategy/wait-strategy.d.ts +11 -0
- package/dist/src/wait-strategy/wait-strategy.js +13 -0
- package/dist/src/{wait.d.ts → wait-strategy/wait.d.ts} +4 -1
- package/dist/src/wait-strategy/wait.js +22 -0
- package/package.json +17 -17
- package/dist/src/wait-strategy.d.ts +0 -32
- package/dist/src/wait-strategy.js +0 -137
- package/dist/src/wait.js +0 -17
- /package/dist/src/{startup-check-strategy.d.ts → wait-strategy/startup-check-strategy.d.ts} +0 -0
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testcontainers",
|
|
3
3
|
"author": "Cristian Greco",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.5.0",
|
|
5
5
|
"main": "dist/src/index",
|
|
6
6
|
"types": "dist/src/index",
|
|
7
7
|
"keywords": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@balena/dockerignore": "^1.0.2",
|
|
40
40
|
"@types/archiver": "^5.3.2",
|
|
41
|
-
"@types/dockerode": "^3.3.
|
|
41
|
+
"@types/dockerode": "^3.3.16",
|
|
42
42
|
"archiver": "^5.3.1",
|
|
43
43
|
"async-lock": "^1.4.0",
|
|
44
44
|
"byline": "^5.0.0",
|
|
@@ -56,33 +56,33 @@
|
|
|
56
56
|
"@types/async-lock": "^1.4.0",
|
|
57
57
|
"@types/byline": "^4.2.33",
|
|
58
58
|
"@types/debug": "4.1.7",
|
|
59
|
-
"@types/jest": "^29.
|
|
60
|
-
"@types/node": "^18.11
|
|
61
|
-
"@types/node-fetch": "^2.6.
|
|
59
|
+
"@types/jest": "^29.5.0",
|
|
60
|
+
"@types/node": "^18.15.11",
|
|
61
|
+
"@types/node-fetch": "^2.6.3",
|
|
62
62
|
"@types/pg": "^8.6.6",
|
|
63
63
|
"@types/properties-reader": "^2.1.1",
|
|
64
64
|
"@types/tar-fs": "^2.0.1",
|
|
65
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
66
|
-
"@typescript-eslint/parser": "^5.
|
|
67
|
-
"arangojs": "^8.
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
|
66
|
+
"@typescript-eslint/parser": "^5.57.0",
|
|
67
|
+
"arangojs": "^8.2.0",
|
|
68
68
|
"cross-env": "^7.0.3",
|
|
69
|
-
"eslint": "^8.
|
|
70
|
-
"eslint-config-prettier": "^8.
|
|
69
|
+
"eslint": "^8.37.0",
|
|
70
|
+
"eslint-config-prettier": "^8.8.0",
|
|
71
71
|
"eslint-plugin-prettier": "^4.2.1",
|
|
72
72
|
"husky": "^8.0.3",
|
|
73
73
|
"jest": "^29.5.0",
|
|
74
74
|
"kafkajs": "^2.2.4",
|
|
75
|
-
"lint-staged": "^13.0
|
|
76
|
-
"mongoose": "^6.
|
|
75
|
+
"lint-staged": "^13.2.0",
|
|
76
|
+
"mongoose": "^6.10.4",
|
|
77
77
|
"mysql2": "^2.3.3",
|
|
78
|
-
"nats": "^2.
|
|
79
|
-
"neo4j-driver": "^5.
|
|
80
|
-
"pg": "^8.
|
|
81
|
-
"prettier": "^2.7
|
|
78
|
+
"nats": "^2.13.1",
|
|
79
|
+
"neo4j-driver": "^5.6.0",
|
|
80
|
+
"pg": "^8.10.0",
|
|
81
|
+
"prettier": "^2.8.7",
|
|
82
82
|
"rimraf": "^3.0.2",
|
|
83
83
|
"ts-jest": "^29.0.5",
|
|
84
84
|
"ts-node": "^10.9.1",
|
|
85
|
-
"typescript": "^4.
|
|
85
|
+
"typescript": "^4.9.5",
|
|
86
86
|
"wait-for-expect": "^3.0.2"
|
|
87
87
|
},
|
|
88
88
|
"lint-staged": {
|
|
@@ -18,7 +18,6 @@ const path_1 = __importDefault(require("path"));
|
|
|
18
18
|
const logger_1 = require("../logger");
|
|
19
19
|
const url_1 = require("url");
|
|
20
20
|
const fs_1 = require("fs");
|
|
21
|
-
const run_in_container_1 = require("./functions/run-in-container");
|
|
22
21
|
const session_id_1 = require("./session-id");
|
|
23
22
|
const lookup_host_ips_1 = require("./lookup-host-ips");
|
|
24
23
|
const system_info_1 = require("../system-info");
|
|
@@ -26,6 +25,7 @@ const rootless_unix_socket_strategy_1 = require("./rootless-unix-socket-strategy
|
|
|
26
25
|
const stream_utils_1 = require("../stream-utils");
|
|
27
26
|
const stream_1 = require("stream");
|
|
28
27
|
const docker_client_config_1 = require("./docker-client-config");
|
|
28
|
+
const resolve_host_1 = require("./resolve-host");
|
|
29
29
|
const getDockerClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
30
|
const strategies = [
|
|
31
31
|
new ConfigurationStrategy(),
|
|
@@ -43,7 +43,7 @@ const getDockerClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
43
43
|
logger_1.log.debug(`Testing Docker client strategy URI: ${uri}`);
|
|
44
44
|
if (yield isDockerDaemonReachable(dockerode)) {
|
|
45
45
|
const indexServerAddress = (yield (0, system_info_1.getSystemInfo)(dockerode)).dockerInfo.indexServerAddress;
|
|
46
|
-
const host = yield resolveHost(dockerode, indexServerAddress, uri);
|
|
46
|
+
const host = yield (0, resolve_host_1.resolveHost)(dockerode, indexServerAddress, uri);
|
|
47
47
|
const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
|
|
48
48
|
logger_1.log.info(`Using Docker client strategy: ${strategy.getName()}, Docker host: ${host} (${hostIps
|
|
49
49
|
.map((hostIp) => hostIp.address)
|
|
@@ -145,49 +145,6 @@ class NpipeSocketStrategy {
|
|
|
145
145
|
return "NpipeSocketStrategy";
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
const resolveHost = (dockerode, indexServerAddress, uri) => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
|
-
if (process.env.TESTCONTAINERS_HOST_OVERRIDE !== undefined) {
|
|
150
|
-
return process.env.TESTCONTAINERS_HOST_OVERRIDE;
|
|
151
|
-
}
|
|
152
|
-
const { protocol, hostname } = new url_1.URL(uri);
|
|
153
|
-
switch (protocol) {
|
|
154
|
-
case "http:":
|
|
155
|
-
case "https:":
|
|
156
|
-
case "tcp:":
|
|
157
|
-
return hostname;
|
|
158
|
-
case "unix:":
|
|
159
|
-
case "npipe:": {
|
|
160
|
-
if (isInContainer()) {
|
|
161
|
-
const gateway = yield findGateway(dockerode);
|
|
162
|
-
if (gateway !== undefined) {
|
|
163
|
-
return gateway;
|
|
164
|
-
}
|
|
165
|
-
const defaultGateway = yield findDefaultGateway(dockerode, indexServerAddress);
|
|
166
|
-
if (defaultGateway !== undefined) {
|
|
167
|
-
return defaultGateway;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return "localhost";
|
|
171
|
-
}
|
|
172
|
-
default:
|
|
173
|
-
throw new Error(`Unsupported protocol: ${protocol}`);
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
const findGateway = (dockerode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
177
|
-
var _a, _b, _c;
|
|
178
|
-
logger_1.log.debug(`Checking gateway for Docker host`);
|
|
179
|
-
const inspectResult = yield dockerode.getNetwork("bridge").inspect();
|
|
180
|
-
return (_c = (_b = (_a = inspectResult === null || inspectResult === void 0 ? void 0 : inspectResult.IPAM) === null || _a === void 0 ? void 0 : _a.Config) === null || _b === void 0 ? void 0 : _b.find((config) => config.Gateway !== undefined)) === null || _c === void 0 ? void 0 : _c.Gateway;
|
|
181
|
-
});
|
|
182
|
-
const findDefaultGateway = (dockerode, indexServerAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
183
|
-
logger_1.log.debug(`Checking default gateway for Docker host`);
|
|
184
|
-
return (0, run_in_container_1.runInContainer)(dockerode, indexServerAddress, "alpine:3.14", [
|
|
185
|
-
"sh",
|
|
186
|
-
"-c",
|
|
187
|
-
"ip route|awk '/default/ { print $3 }'",
|
|
188
|
-
]);
|
|
189
|
-
});
|
|
190
|
-
const isInContainer = () => (0, fs_1.existsSync)("/.dockerenv");
|
|
191
148
|
let _dockerClient;
|
|
192
149
|
const dockerClient = () => {
|
|
193
150
|
if (!_dockerClient) {
|
|
@@ -1,9 +1,3 @@
|
|
|
1
1
|
import { ExecResult } from "../../types";
|
|
2
2
|
import Dockerode from "dockerode";
|
|
3
|
-
|
|
4
|
-
tty: boolean;
|
|
5
|
-
stdin: boolean;
|
|
6
|
-
detach: boolean;
|
|
7
|
-
};
|
|
8
|
-
export declare const execContainer: (container: Dockerode.Container, command: string[], options: ExecContainerOptions, shouldLog?: boolean) => Promise<ExecResult>;
|
|
9
|
-
export {};
|
|
3
|
+
export declare const execContainer: (container: Dockerode.Container, command: string[], shouldLog?: boolean) => Promise<ExecResult>;
|
|
@@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.execContainer = void 0;
|
|
16
16
|
const logger_1 = require("../../../logger");
|
|
17
17
|
const byline_1 = __importDefault(require("byline"));
|
|
18
|
-
const execContainer = (container, command,
|
|
18
|
+
const execContainer = (container, command, shouldLog = true) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
19
|
const chunks = [];
|
|
20
20
|
try {
|
|
21
21
|
const exec = yield container.exec({
|
|
@@ -23,7 +23,7 @@ const execContainer = (container, command, options, shouldLog = true) => __await
|
|
|
23
23
|
AttachStdout: true,
|
|
24
24
|
AttachStderr: true,
|
|
25
25
|
});
|
|
26
|
-
const stream = yield startExec(exec
|
|
26
|
+
const stream = yield startExec(exec);
|
|
27
27
|
stream.on("data", (chunk) => chunks.push(chunk));
|
|
28
28
|
if (shouldLog && logger_1.execLog.enabled()) {
|
|
29
29
|
(0, byline_1.default)(stream).on("data", (line) => logger_1.execLog.trace(`${container.id}: ${line}`));
|
|
@@ -38,9 +38,9 @@ const execContainer = (container, command, options, shouldLog = true) => __await
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
exports.execContainer = execContainer;
|
|
41
|
-
const startExec = (exec
|
|
41
|
+
const startExec = (exec) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
42
|
try {
|
|
43
|
-
const stream = yield exec.start(
|
|
43
|
+
const stream = yield exec.start({ stdin: true, Detach: false, Tty: true });
|
|
44
44
|
stream.setEncoding("utf-8");
|
|
45
45
|
return stream;
|
|
46
46
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import Dockerode from "dockerode";
|
|
6
|
+
export declare const resolveHost: (dockerode: Dockerode, indexServerAddress: string, uri: string, env?: NodeJS.ProcessEnv) => Promise<string>;
|
|
@@ -0,0 +1,60 @@
|
|
|
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.resolveHost = void 0;
|
|
13
|
+
const url_1 = require("url");
|
|
14
|
+
const logger_1 = require("../logger");
|
|
15
|
+
const run_in_container_1 = require("./functions/run-in-container");
|
|
16
|
+
const fs_1 = require("fs");
|
|
17
|
+
const resolveHost = (dockerode, indexServerAddress, uri, env = process.env) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
if (env.TESTCONTAINERS_HOST_OVERRIDE !== undefined) {
|
|
19
|
+
return env.TESTCONTAINERS_HOST_OVERRIDE;
|
|
20
|
+
}
|
|
21
|
+
const { protocol, hostname } = new url_1.URL(uri);
|
|
22
|
+
switch (protocol) {
|
|
23
|
+
case "http:":
|
|
24
|
+
case "https:":
|
|
25
|
+
case "tcp:":
|
|
26
|
+
return hostname;
|
|
27
|
+
case "unix:":
|
|
28
|
+
case "npipe:": {
|
|
29
|
+
if (isInContainer()) {
|
|
30
|
+
const gateway = yield findGateway(dockerode);
|
|
31
|
+
if (gateway !== undefined) {
|
|
32
|
+
return gateway;
|
|
33
|
+
}
|
|
34
|
+
const defaultGateway = yield findDefaultGateway(dockerode, indexServerAddress);
|
|
35
|
+
if (defaultGateway !== undefined) {
|
|
36
|
+
return defaultGateway;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return "localhost";
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
throw new Error(`Unsupported protocol: ${protocol}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
exports.resolveHost = resolveHost;
|
|
46
|
+
const findGateway = (dockerode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
var _a, _b, _c;
|
|
48
|
+
logger_1.log.debug(`Checking gateway for Docker host`);
|
|
49
|
+
const inspectResult = yield dockerode.getNetwork("bridge").inspect();
|
|
50
|
+
return (_c = (_b = (_a = inspectResult === null || inspectResult === void 0 ? void 0 : inspectResult.IPAM) === null || _a === void 0 ? void 0 : _a.Config) === null || _b === void 0 ? void 0 : _b.find((config) => config.Gateway !== undefined)) === null || _c === void 0 ? void 0 : _c.Gateway;
|
|
51
|
+
});
|
|
52
|
+
const findDefaultGateway = (dockerode, indexServerAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
logger_1.log.debug(`Checking default gateway for Docker host`);
|
|
54
|
+
return (0, run_in_container_1.runInContainer)(dockerode, indexServerAddress, "alpine:3.14", [
|
|
55
|
+
"sh",
|
|
56
|
+
"-c",
|
|
57
|
+
"ip route|awk '/default/ { print $3 }'",
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
const isInContainer = () => (0, fs_1.existsSync)("/.dockerenv");
|
|
@@ -8,7 +8,8 @@ export declare class RootlessUnixSocketStrategy implements DockerClientStrategy
|
|
|
8
8
|
constructor(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv);
|
|
9
9
|
init(): Promise<void>;
|
|
10
10
|
private getSocketPathFromEnv;
|
|
11
|
-
private
|
|
11
|
+
private getSocketPathFromHomeRunDir;
|
|
12
|
+
private getSocketPathFromHomeDesktopDir;
|
|
12
13
|
private getSocketPathFromRunDir;
|
|
13
14
|
getDockerClient(): Promise<DockerClientInit>;
|
|
14
15
|
isApplicable(): boolean;
|
|
@@ -29,7 +29,12 @@ class RootlessUnixSocketStrategy {
|
|
|
29
29
|
this.applicable = false;
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
this.socketPath = [
|
|
32
|
+
this.socketPath = [
|
|
33
|
+
this.getSocketPathFromEnv(),
|
|
34
|
+
this.getSocketPathFromHomeRunDir(),
|
|
35
|
+
this.getSocketPathFromHomeDesktopDir(),
|
|
36
|
+
this.getSocketPathFromRunDir(),
|
|
37
|
+
]
|
|
33
38
|
.filter(type_guards_1.isDefined)
|
|
34
39
|
.find((candidateSocketPath) => (0, fs_1.existsSync)(candidateSocketPath));
|
|
35
40
|
this.applicable = this.socketPath !== undefined;
|
|
@@ -44,9 +49,12 @@ class RootlessUnixSocketStrategy {
|
|
|
44
49
|
return undefined;
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
|
-
|
|
52
|
+
getSocketPathFromHomeRunDir() {
|
|
48
53
|
return path_1.default.join(os_1.default.homedir(), ".docker", "run", "docker.sock");
|
|
49
54
|
}
|
|
55
|
+
getSocketPathFromHomeDesktopDir() {
|
|
56
|
+
return path_1.default.join(os_1.default.homedir(), ".docker", "desktop", "docker.sock");
|
|
57
|
+
}
|
|
50
58
|
getSocketPathFromRunDir() {
|
|
51
59
|
return path_1.default.join("/run", "user", `${os_1.default.userInfo().uid}`, "docker.sock");
|
|
52
60
|
}
|
|
@@ -22,11 +22,23 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.defaultDockerComposeOptions = void 0;
|
|
24
24
|
const docker_client_1 = require("../docker/docker-client");
|
|
25
|
+
const logger_1 = require("../logger");
|
|
26
|
+
const os_1 = require("os");
|
|
27
|
+
const type_guards_1 = require("../type-guards");
|
|
25
28
|
const defaultDockerComposeOptions = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
29
|
var { environment = {} } = _a, options = __rest(_a, ["environment"]);
|
|
27
30
|
const { composeEnvironment } = yield (0, docker_client_1.dockerClient)();
|
|
28
31
|
return {
|
|
29
32
|
log: false,
|
|
33
|
+
callback: logger_1.log.enabled()
|
|
34
|
+
? (chunk) => {
|
|
35
|
+
chunk
|
|
36
|
+
.toString()
|
|
37
|
+
.split(os_1.EOL)
|
|
38
|
+
.filter(type_guards_1.isNotEmptyString)
|
|
39
|
+
.forEach((line) => logger_1.log.trace(line.trim()));
|
|
40
|
+
}
|
|
41
|
+
: undefined,
|
|
30
42
|
cwd: options.filePath,
|
|
31
43
|
config: options.files,
|
|
32
44
|
composeOptions: options.composeOptions,
|
|
@@ -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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.dockerComposePull = void 0;
|
|
13
|
+
const logger_1 = require("../../logger");
|
|
14
|
+
const docker_compose_1 = require("docker-compose");
|
|
15
|
+
const default_docker_compose_options_1 = require("../default-docker-compose-options");
|
|
16
|
+
const dockerComposePull = (options, services) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
try {
|
|
18
|
+
if (services) {
|
|
19
|
+
logger_1.log.info(`Pulling DockerCompose environment images for ${services.join(", ")}`);
|
|
20
|
+
yield (0, docker_compose_1.pullMany)(services, yield (0, default_docker_compose_options_1.defaultDockerComposeOptions)(options));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
logger_1.log.info(`Pulling DockerCompose environment images`);
|
|
24
|
+
yield (0, docker_compose_1.pullAll)(yield (0, default_docker_compose_options_1.defaultDockerComposeOptions)(options));
|
|
25
|
+
}
|
|
26
|
+
logger_1.log.info(`Pulled DockerCompose environment`);
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const errorMessage = err.err || err.message || err || "";
|
|
31
|
+
logger_1.log.error(`Failed to pull DockerCompose environment images: ${errorMessage.trim()}`);
|
|
32
|
+
throw new Error(errorMessage);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
exports.dockerComposePull = dockerComposePull;
|
|
@@ -27,8 +27,8 @@ const dockerComposeUp = (options, services) => __awaiter(void 0, void 0, void 0,
|
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
|
30
|
-
const errorMessage = err.err || err.message || err;
|
|
31
|
-
logger_1.log.error(`Failed to up DockerCompose environment: ${errorMessage}`);
|
|
30
|
+
const errorMessage = err.err || err.message || err || "";
|
|
31
|
+
logger_1.log.error(`Failed to up DockerCompose environment: ${errorMessage.trim()}`);
|
|
32
32
|
try {
|
|
33
33
|
yield (0, docker_compose_down_1.dockerComposeDown)(options, { removeVolumes: true, timeout: 0 });
|
|
34
34
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { WaitStrategy } from "../wait-strategy";
|
|
1
|
+
import { WaitStrategy } from "../wait-strategy/wait-strategy";
|
|
2
2
|
import { Uuid } from "../uuid";
|
|
3
3
|
import { Environment } from "../docker/types";
|
|
4
4
|
import { StartedDockerComposeEnvironment } from "./started-docker-compose-environment";
|
|
5
|
+
import { PullPolicy } from "../pull-policy";
|
|
5
6
|
export declare class DockerComposeEnvironment {
|
|
6
7
|
private readonly composeFilePath;
|
|
7
8
|
private readonly composeFiles;
|
|
@@ -11,6 +12,7 @@ export declare class DockerComposeEnvironment {
|
|
|
11
12
|
private environmentFile;
|
|
12
13
|
private profiles;
|
|
13
14
|
private environment;
|
|
15
|
+
private pullPolicy;
|
|
14
16
|
private waitStrategy;
|
|
15
17
|
private startupTimeout;
|
|
16
18
|
constructor(composeFilePath: string, composeFiles: string | string[], uuid?: Uuid);
|
|
@@ -19,6 +21,7 @@ export declare class DockerComposeEnvironment {
|
|
|
19
21
|
withEnvironmentFile(environmentFile: string): this;
|
|
20
22
|
withProfiles(...profiles: string[]): this;
|
|
21
23
|
withNoRecreate(): this;
|
|
24
|
+
withPullPolicy(pullPolicy: PullPolicy): this;
|
|
22
25
|
withWaitStrategy(containerName: string, waitStrategy: WaitStrategy): this;
|
|
23
26
|
withStartupTimeout(startupTimeout: number): this;
|
|
24
27
|
up(services?: Array<string>): Promise<StartedDockerComposeEnvironment>;
|
|
@@ -14,7 +14,6 @@ const bound_ports_1 = require("../bound-ports");
|
|
|
14
14
|
const container_name_resolver_1 = require("../docker-compose/functions/container-name-resolver");
|
|
15
15
|
const started_generic_container_1 = require("../generic-container/started-generic-container");
|
|
16
16
|
const logger_1 = require("../logger");
|
|
17
|
-
const wait_strategy_1 = require("../wait-strategy");
|
|
18
17
|
const reaper_1 = require("../reaper");
|
|
19
18
|
const uuid_1 = require("../uuid");
|
|
20
19
|
const list_containers_1 = require("../docker/functions/container/list-containers");
|
|
@@ -26,6 +25,9 @@ const started_docker_compose_environment_1 = require("./started-docker-compose-e
|
|
|
26
25
|
const docker_compose_down_1 = require("../docker-compose/functions/docker-compose-down");
|
|
27
26
|
const docker_compose_up_1 = require("../docker-compose/functions/docker-compose-up");
|
|
28
27
|
const wait_for_container_1 = require("../wait-for-container");
|
|
28
|
+
const default_wait_strategy_1 = require("../wait-strategy/default-wait-strategy");
|
|
29
|
+
const pull_policy_1 = require("../pull-policy");
|
|
30
|
+
const docker_compose_pull_1 = require("../docker-compose/functions/docker-compose-pull");
|
|
29
31
|
class DockerComposeEnvironment {
|
|
30
32
|
constructor(composeFilePath, composeFiles, uuid = new uuid_1.RandomUuid()) {
|
|
31
33
|
this.build = false;
|
|
@@ -33,6 +35,7 @@ class DockerComposeEnvironment {
|
|
|
33
35
|
this.environmentFile = "";
|
|
34
36
|
this.profiles = [];
|
|
35
37
|
this.environment = {};
|
|
38
|
+
this.pullPolicy = new pull_policy_1.DefaultPullPolicy();
|
|
36
39
|
this.waitStrategy = {};
|
|
37
40
|
this.startupTimeout = 60000;
|
|
38
41
|
this.composeFilePath = composeFilePath;
|
|
@@ -60,6 +63,10 @@ class DockerComposeEnvironment {
|
|
|
60
63
|
this.projectName = "testcontainers-node";
|
|
61
64
|
return this;
|
|
62
65
|
}
|
|
66
|
+
withPullPolicy(pullPolicy) {
|
|
67
|
+
this.pullPolicy = pullPolicy;
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
63
70
|
withWaitStrategy(containerName, waitStrategy) {
|
|
64
71
|
this.waitStrategy[containerName] = waitStrategy;
|
|
65
72
|
return this;
|
|
@@ -89,6 +96,9 @@ class DockerComposeEnvironment {
|
|
|
89
96
|
composeOptions.push("--env-file", this.environmentFile);
|
|
90
97
|
}
|
|
91
98
|
this.profiles.forEach((profile) => composeOptions.push("--profile", profile));
|
|
99
|
+
if (this.pullPolicy.shouldPull()) {
|
|
100
|
+
yield (0, docker_compose_pull_1.dockerComposePull)(options, services);
|
|
101
|
+
}
|
|
92
102
|
yield (0, docker_compose_up_1.dockerComposeUp)(Object.assign(Object.assign({}, options), { commandOptions, composeOptions, environment: this.environment }), services);
|
|
93
103
|
const startedContainers = (yield (0, list_containers_1.listContainers)()).filter((container) => container.Labels["com.docker.compose.project"] === this.projectName);
|
|
94
104
|
const startedContainerNames = startedContainers.reduce((containerNames, startedContainer) => [
|
|
@@ -102,10 +112,12 @@ class DockerComposeEnvironment {
|
|
|
102
112
|
const { host, hostIps } = yield (0, docker_client_1.dockerClient)();
|
|
103
113
|
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
104
114
|
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult);
|
|
105
|
-
const waitStrategy = (this.waitStrategy[containerName] ? this.waitStrategy[containerName] : (0,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
const waitStrategy = (this.waitStrategy[containerName] ? this.waitStrategy[containerName] : (0, default_wait_strategy_1.defaultWaitStrategy)(host, container)).withStartupTimeout(this.startupTimeout);
|
|
116
|
+
if (logger_1.containerLog.enabled()) {
|
|
117
|
+
(yield (0, container_logs_1.containerLogs)(container))
|
|
118
|
+
.on("data", (data) => logger_1.containerLog.trace(`${containerName}: ${data.trim()}`))
|
|
119
|
+
.on("err", (data) => logger_1.containerLog.error(`${containerName}: ${data.trim()}`));
|
|
120
|
+
}
|
|
109
121
|
try {
|
|
110
122
|
logger_1.log.info(`Waiting for container ${containerName} to be ready`);
|
|
111
123
|
yield (0, wait_for_container_1.waitForContainer)(container, waitStrategy, host, boundPorts);
|
|
@@ -14,6 +14,7 @@ const os_1 = require("os");
|
|
|
14
14
|
const fs_1 = require("fs");
|
|
15
15
|
const logger_1 = require("./logger");
|
|
16
16
|
const docker_image_name_1 = require("./docker-image-name");
|
|
17
|
+
const type_guards_1 = require("./type-guards");
|
|
17
18
|
const buildArgRegex = /\${([^{]+)}/g;
|
|
18
19
|
const getDockerfileImages = (dockerfile, buildArgs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
20
|
try {
|
|
@@ -32,7 +33,7 @@ function parseImages(dockerfile) {
|
|
|
32
33
|
return Array.from((yield fs_1.promises.readFile(dockerfile, "utf8"))
|
|
33
34
|
.split(os_1.EOL)
|
|
34
35
|
.filter((line) => line.toUpperCase().startsWith("FROM"))
|
|
35
|
-
.map((line) => line.split(" ").filter(
|
|
36
|
+
.map((line) => line.split(" ").filter(type_guards_1.isNotEmptyString)[1])
|
|
36
37
|
.reduce((prev, next) => prev.add(next), new Set())
|
|
37
38
|
.values());
|
|
38
39
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initCreateContainerOptions = void 0;
|
|
4
|
+
const initCreateContainerOptions = (imageName, autoRemove) => ({
|
|
5
|
+
imageName,
|
|
6
|
+
autoRemove,
|
|
7
|
+
environment: {},
|
|
8
|
+
exposedPorts: [],
|
|
9
|
+
command: [],
|
|
10
|
+
bindMounts: [],
|
|
11
|
+
labels: {},
|
|
12
|
+
tmpFs: {},
|
|
13
|
+
useDefaultLogDriver: false,
|
|
14
|
+
privilegedMode: false,
|
|
15
|
+
reusable: false,
|
|
16
|
+
extraHosts: [],
|
|
17
|
+
});
|
|
18
|
+
exports.initCreateContainerOptions = initCreateContainerOptions;
|
|
@@ -3,47 +3,38 @@ import { BoundPorts } from "../bound-ports";
|
|
|
3
3
|
import { PortWithOptionalBinding } from "../port";
|
|
4
4
|
import { PullPolicy } from "../pull-policy";
|
|
5
5
|
import { StartedTestContainer, TestContainer } from "../test-container";
|
|
6
|
-
import { WaitStrategy } from "../wait-strategy";
|
|
7
|
-
import { BindMount, ContentToCopy, Environment, ExtraHost, FileToCopy, HealthCheck, Labels, TmpFs, Ulimits
|
|
6
|
+
import { WaitStrategy } from "../wait-strategy/wait-strategy";
|
|
7
|
+
import { BindMount, ContentToCopy, Environment, ExtraHost, FileToCopy, HealthCheck, Labels, ResourcesQuota, TmpFs, Ulimits } from "../docker/types";
|
|
8
|
+
import { CreateContainerOptions } from "../docker/functions/container/create-container";
|
|
8
9
|
import { InspectResult } from "../docker/functions/container/inspect-container";
|
|
9
10
|
import { GenericContainerBuilder } from "./generic-container-builder";
|
|
10
11
|
import { StartedNetwork } from "../network";
|
|
11
12
|
export declare class GenericContainer implements TestContainer {
|
|
12
13
|
readonly image: string;
|
|
13
14
|
static fromDockerfile(context: string, dockerfileName?: string): GenericContainerBuilder;
|
|
14
|
-
|
|
15
|
-
protected
|
|
15
|
+
protected opts: CreateContainerOptions;
|
|
16
|
+
protected startupTimeout: number;
|
|
17
|
+
protected waitStrategy?: WaitStrategy;
|
|
18
|
+
protected tarToCopy?: archiver.Archiver;
|
|
16
19
|
protected networkMode?: string;
|
|
17
20
|
protected networkAliases: string[];
|
|
18
|
-
protected ports: PortWithOptionalBinding[];
|
|
19
|
-
protected command: string[];
|
|
20
|
-
protected entrypoint?: string[];
|
|
21
|
-
protected bindMounts: BindMount[];
|
|
22
|
-
protected name?: string;
|
|
23
|
-
protected labels: Labels;
|
|
24
|
-
protected tmpFs: TmpFs;
|
|
25
|
-
protected healthCheck?: HealthCheck;
|
|
26
|
-
protected waitStrategy?: WaitStrategy;
|
|
27
|
-
protected startupTimeout: number;
|
|
28
|
-
protected useDefaultLogDriver: boolean;
|
|
29
|
-
protected privilegedMode: boolean;
|
|
30
|
-
protected workingDir?: string;
|
|
31
|
-
protected ipcMode?: string;
|
|
32
|
-
protected ulimits?: Ulimits;
|
|
33
|
-
protected addedCapabilities?: string[];
|
|
34
|
-
protected droppedCapabilities?: string[];
|
|
35
|
-
protected user?: string;
|
|
36
21
|
protected pullPolicy: PullPolicy;
|
|
37
|
-
protected reuse: boolean;
|
|
38
|
-
protected tarToCopy?: archiver.Archiver;
|
|
39
|
-
protected resourcesQuota?: ResourcesQuota;
|
|
40
|
-
private extraHosts;
|
|
41
22
|
constructor(image: string);
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Since version 9.4.0. Will be removed in version 10.0.0. Use `beforeContainerStarted` instead.
|
|
25
|
+
*/
|
|
42
26
|
protected preStart?(): Promise<void>;
|
|
27
|
+
protected beforeContainerStarted?(): Promise<void>;
|
|
28
|
+
protected containerCreated?(containerId: string): Promise<void>;
|
|
29
|
+
protected containerStarting?(inspectResult: InspectResult, reused: boolean): Promise<void>;
|
|
43
30
|
start(): Promise<StartedTestContainer>;
|
|
44
31
|
private reuseContainer;
|
|
45
32
|
private startContainer;
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Since version 9.4.0. Will be removed in version 10.0.0. Use `containerStarted` instead.
|
|
35
|
+
*/
|
|
46
36
|
protected postStart?(container: StartedTestContainer, inspectResult: InspectResult, boundPorts: BoundPorts): Promise<void>;
|
|
37
|
+
protected containerStarted?(container: StartedTestContainer, inspectResult: InspectResult, reused: boolean): Promise<void>;
|
|
47
38
|
protected get hasExposedPorts(): boolean;
|
|
48
39
|
withCommand(command: string[]): this;
|
|
49
40
|
withEntrypoint(entrypoint: string[]): this;
|