testcontainers 8.0.0 → 8.1.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/docker/docker-client.d.ts +9 -0
- package/dist/docker/docker-client.js +150 -0
- package/dist/docker/functions/container/create-container.js +3 -2
- package/dist/docker/functions/container/get-container.d.ts +1 -1
- package/dist/docker/functions/container/get-container.js +14 -2
- package/dist/docker/functions/container/list-containers.js +3 -2
- package/dist/docker/functions/demux-stream.d.ts +1 -1
- package/dist/docker/functions/demux-stream.js +14 -4
- package/dist/docker/functions/get-info.js +3 -2
- package/dist/docker/functions/image/build-image.js +3 -2
- package/dist/docker/functions/image/list-images.js +3 -2
- package/dist/docker/functions/image/pull-image.js +3 -2
- package/dist/docker/functions/network/connect-network.js +3 -2
- package/dist/docker/functions/network/create-network.js +3 -2
- package/dist/docker/functions/network/remove-network.js +3 -2
- package/dist/docker/functions/run-in-container.d.ts +2 -1
- package/dist/docker/functions/run-in-container.js +2 -3
- package/dist/docker-compose/docker-compose.d.ts +1 -0
- package/dist/docker-compose/docker-compose.js +1 -2
- package/dist/docker-compose-environment/docker-compose-environment.js +4 -4
- package/dist/generic-container/generic-container.js +3 -3
- package/dist/modules/kafka/kafka-container.js +2 -2
- package/dist/port-forwarder.js +2 -2
- package/dist/reaper.js +2 -2
- package/dist/testcontainers-properties-file.d.ts +1 -1
- package/dist/testcontainers-properties-file.js +20 -24
- package/package.json +1 -1
- package/dist/docker/docker-host.d.ts +0 -1
- package/dist/docker/docker-host.js +0 -8
- package/dist/docker/dockerode.d.ts +0 -2
- package/dist/docker/dockerode.js +0 -10
- package/dist/docker/get-docker-host.d.ts +0 -3
- package/dist/docker/get-docker-host.js +0 -64
|
@@ -0,0 +1,150 @@
|
|
|
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 = __importDefault(require("fs"));
|
|
21
|
+
const run_in_container_1 = require("./functions/run-in-container");
|
|
22
|
+
const log_system_diagnostics_1 = require("../log-system-diagnostics");
|
|
23
|
+
require("../testcontainers-properties-file");
|
|
24
|
+
const getDockerClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const strategies = [
|
|
26
|
+
new ConfigurationStrategy(),
|
|
27
|
+
new UnixSocketStrategy(),
|
|
28
|
+
new NpipeSocketStrategy(),
|
|
29
|
+
];
|
|
30
|
+
for (const strategy of strategies) {
|
|
31
|
+
if (strategy.isApplicable()) {
|
|
32
|
+
logger_1.log.debug(`Found applicable Docker client strategy: ${strategy.getName()}`);
|
|
33
|
+
const dockerConfig = strategy.getDockerConfig();
|
|
34
|
+
const dockerode = new dockerode_1.default(createDockerodeOptions(dockerConfig));
|
|
35
|
+
logger_1.log.debug(`Testing Docker client strategy URI: ${dockerConfig.uri}`);
|
|
36
|
+
if (yield isDockerDaemonReachable(dockerode)) {
|
|
37
|
+
const host = yield resolveHost(dockerode, dockerConfig.uri);
|
|
38
|
+
logger_1.log.info(`Using Docker client strategy: ${strategy.getName()}, Docker host: ${host}`);
|
|
39
|
+
log_system_diagnostics_1.logSystemDiagnostics();
|
|
40
|
+
return { host, dockerode };
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger_1.log.warn(`Docker client strategy ${strategy.getName()} is not reachable`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw new Error("No Docker client strategy found");
|
|
48
|
+
});
|
|
49
|
+
const createDockerodeOptions = (dockerConfig) => {
|
|
50
|
+
const dockerOptions = {};
|
|
51
|
+
if (dockerConfig.isSocket) {
|
|
52
|
+
dockerOptions.socketPath = new url_1.URL(dockerConfig.uri).pathname;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
dockerOptions.host = dockerConfig.uri;
|
|
56
|
+
}
|
|
57
|
+
if (dockerConfig.ssl) {
|
|
58
|
+
dockerOptions.ca = dockerConfig.ssl.ca;
|
|
59
|
+
dockerOptions.cert = dockerConfig.ssl.cert;
|
|
60
|
+
dockerOptions.key = dockerConfig.ssl.key;
|
|
61
|
+
}
|
|
62
|
+
return dockerOptions;
|
|
63
|
+
};
|
|
64
|
+
const isDockerDaemonReachable = (dockerode) => __awaiter(void 0, void 0, void 0, function* () { return (yield dockerode.ping()).toString() === "OK"; });
|
|
65
|
+
class ConfigurationStrategy {
|
|
66
|
+
getDockerConfig() {
|
|
67
|
+
const { DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH } = process.env;
|
|
68
|
+
return {
|
|
69
|
+
uri: DOCKER_HOST,
|
|
70
|
+
isSocket: false,
|
|
71
|
+
ssl: DOCKER_TLS_VERIFY === "1" && DOCKER_CERT_PATH !== undefined
|
|
72
|
+
? {
|
|
73
|
+
ca: path_1.default.resolve(DOCKER_CERT_PATH, "ca.pem"),
|
|
74
|
+
cert: path_1.default.resolve(DOCKER_CERT_PATH, "cert.pem"),
|
|
75
|
+
key: path_1.default.resolve(DOCKER_CERT_PATH, "key.pem"),
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
isApplicable() {
|
|
81
|
+
return process.env.DOCKER_HOST !== undefined;
|
|
82
|
+
}
|
|
83
|
+
getName() {
|
|
84
|
+
return "ConfigurationStrategy";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class UnixSocketStrategy {
|
|
88
|
+
getDockerConfig() {
|
|
89
|
+
return {
|
|
90
|
+
uri: "unix:///var/run/docker.sock",
|
|
91
|
+
isSocket: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
isApplicable() {
|
|
95
|
+
return process.platform === "linux" || process.platform === "darwin";
|
|
96
|
+
}
|
|
97
|
+
getName() {
|
|
98
|
+
return "UnixSocketStrategy";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
class NpipeSocketStrategy {
|
|
102
|
+
getDockerConfig() {
|
|
103
|
+
return {
|
|
104
|
+
uri: "npipe:////./pipe/docker_engine",
|
|
105
|
+
isSocket: true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
isApplicable() {
|
|
109
|
+
return process.platform === "win32";
|
|
110
|
+
}
|
|
111
|
+
getName() {
|
|
112
|
+
return "NpipeSocketStrategy";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const resolveHost = (dockerode, uri) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
+
if (process.env.TESTCONTAINERS_HOST_OVERRIDE !== undefined) {
|
|
117
|
+
return process.env.TESTCONTAINERS_HOST_OVERRIDE;
|
|
118
|
+
}
|
|
119
|
+
const { protocol, hostname } = new url_1.URL(uri);
|
|
120
|
+
switch (protocol) {
|
|
121
|
+
case "http:":
|
|
122
|
+
case "https:":
|
|
123
|
+
case "tcp:":
|
|
124
|
+
return hostname;
|
|
125
|
+
case "unix:":
|
|
126
|
+
case "npipe:": {
|
|
127
|
+
if (isInContainer()) {
|
|
128
|
+
const gateway = yield findGateway(dockerode);
|
|
129
|
+
if (gateway !== undefined) {
|
|
130
|
+
return gateway;
|
|
131
|
+
}
|
|
132
|
+
const defaultGateway = yield findDefaultGateway(dockerode);
|
|
133
|
+
if (defaultGateway !== undefined) {
|
|
134
|
+
return defaultGateway;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return "localhost";
|
|
138
|
+
}
|
|
139
|
+
default:
|
|
140
|
+
throw new Error(`Unsupported protocol: ${protocol}`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
const findGateway = (dockerode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
var _a, _b, _c;
|
|
145
|
+
const inspectResult = yield dockerode.getNetwork("bridge").inspect();
|
|
146
|
+
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;
|
|
147
|
+
});
|
|
148
|
+
const findDefaultGateway = (dockerode) => __awaiter(void 0, void 0, void 0, function* () { return run_in_container_1.runInContainer(dockerode, "alpine:3.5", ["sh", "-c", "ip route|awk '/default/ { print $3 }'"]); });
|
|
149
|
+
const isInContainer = () => fs_1.default.existsSync("/.dockerenv");
|
|
150
|
+
exports.dockerClient = getDockerClient();
|
|
@@ -11,12 +11,13 @@ 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
|
|
14
|
+
const docker_client_1 = require("../../docker-client");
|
|
15
15
|
const create_labels_1 = require("../create-labels");
|
|
16
16
|
const createContainer = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
try {
|
|
18
18
|
logger_1.log.info(`Creating container for image: ${options.imageName}`);
|
|
19
|
-
|
|
19
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
20
|
+
return yield dockerode.createContainer({
|
|
20
21
|
name: options.name,
|
|
21
22
|
User: options.user,
|
|
22
23
|
Image: options.imageName.toString(),
|
|
@@ -1,6 +1,18 @@
|
|
|
1
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
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.getContainerById = void 0;
|
|
4
|
-
const
|
|
5
|
-
const getContainerById = (id) =>
|
|
13
|
+
const docker_client_1 = require("../../docker-client");
|
|
14
|
+
const getContainerById = (id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
16
|
+
return dockerode.getContainer(id);
|
|
17
|
+
});
|
|
6
18
|
exports.getContainerById = getContainerById;
|
|
@@ -10,11 +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.listContainers = void 0;
|
|
13
|
-
const
|
|
13
|
+
const docker_client_1 = require("../../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
|
-
|
|
17
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
18
|
+
return yield dockerode.listContainers();
|
|
18
19
|
}
|
|
19
20
|
catch (err) {
|
|
20
21
|
logger_1.log.error(`Failed to list containers: ${err}`);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Readable } from "stream";
|
|
2
|
-
export declare const demuxStream: (stream: Readable) => Readable
|
|
2
|
+
export declare const demuxStream: (stream: Readable) => Promise<Readable>;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
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
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.demuxStream = void 0;
|
|
4
13
|
const stream_1 = require("stream");
|
|
5
14
|
const logger_1 = require("../../logger");
|
|
6
|
-
const
|
|
7
|
-
const demuxStream = (stream) => {
|
|
15
|
+
const docker_client_1 = require("../docker-client");
|
|
16
|
+
const demuxStream = (stream) => __awaiter(void 0, void 0, void 0, function* () {
|
|
8
17
|
try {
|
|
9
18
|
const demuxedStream = new stream_1.PassThrough({ autoDestroy: true, encoding: "utf-8" });
|
|
10
|
-
|
|
19
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
20
|
+
dockerode.modem.demuxStream(stream, demuxedStream, demuxedStream);
|
|
11
21
|
stream.on("end", () => demuxedStream.end());
|
|
12
22
|
demuxedStream.on("close", () => {
|
|
13
23
|
if (!stream.destroyed) {
|
|
@@ -20,5 +30,5 @@ const demuxStream = (stream) => {
|
|
|
20
30
|
logger_1.log.error(`Failed to demux stream: ${err}`);
|
|
21
31
|
throw err;
|
|
22
32
|
}
|
|
23
|
-
};
|
|
33
|
+
});
|
|
24
34
|
exports.demuxStream = demuxStream;
|
|
@@ -10,9 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.getDockerInfo = void 0;
|
|
13
|
-
const
|
|
13
|
+
const docker_client_1 = require("../docker-client");
|
|
14
14
|
const getDockerInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
-
const
|
|
15
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
16
|
+
const info = yield dockerode.info();
|
|
16
17
|
return {
|
|
17
18
|
serverVersion: info.ServerVersion,
|
|
18
19
|
operatingSystem: info.OperatingSystem,
|
|
@@ -18,14 +18,15 @@ const docker_ignore_1 = require("../../../docker-ignore");
|
|
|
18
18
|
const tar_fs_1 = __importDefault(require("tar-fs"));
|
|
19
19
|
const slash_1 = __importDefault(require("slash"));
|
|
20
20
|
const byline_1 = __importDefault(require("byline"));
|
|
21
|
-
const
|
|
21
|
+
const docker_client_1 = require("../../docker-client");
|
|
22
22
|
const create_labels_1 = require("../create-labels");
|
|
23
23
|
const buildImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
24
|
try {
|
|
25
25
|
logger_1.log.info(`Building image '${options.imageName.toString()}' with context '${options.context}'`);
|
|
26
26
|
const dockerIgnoreFiles = yield docker_ignore_1.findDockerIgnoreFiles(options.context, options.dockerfileName);
|
|
27
27
|
const tarStream = tar_fs_1.default.pack(options.context, { ignore: (name) => dockerIgnoreFiles.has(slash_1.default(name)) });
|
|
28
|
-
|
|
28
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
29
|
+
return new Promise((resolve) => dockerode
|
|
29
30
|
.buildImage(tarStream, {
|
|
30
31
|
dockerfile: options.dockerfileName,
|
|
31
32
|
buildargs: options.buildArgs,
|
|
@@ -11,11 +11,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.listImages = void 0;
|
|
13
13
|
const docker_image_name_1 = require("../../../docker-image-name");
|
|
14
|
-
const
|
|
14
|
+
const docker_client_1 = require("../../docker-client");
|
|
15
15
|
const logger_1 = require("../../../logger");
|
|
16
16
|
const listImages = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
try {
|
|
18
|
-
const
|
|
18
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
19
|
+
const images = yield dockerode.listImages();
|
|
19
20
|
return images.reduce((dockerImageNames, image) => {
|
|
20
21
|
if (isDanglingImage(image)) {
|
|
21
22
|
return dockerImageNames;
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.pullImage = void 0;
|
|
13
13
|
const logger_1 = require("../../../logger");
|
|
14
14
|
const pull_stream_parser_1 = require("../../pull-stream-parser");
|
|
15
|
-
const
|
|
15
|
+
const docker_client_1 = require("../../docker-client");
|
|
16
16
|
const image_exists_1 = require("./image-exists");
|
|
17
17
|
const pullImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
18
|
try {
|
|
@@ -21,7 +21,8 @@ const pullImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
logger_1.log.info(`Pulling image: ${options.imageName}`);
|
|
24
|
-
const
|
|
24
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
25
|
+
const stream = yield dockerode.pull(options.imageName.toString(), { authconfig: options.authConfig });
|
|
25
26
|
yield new pull_stream_parser_1.PullStreamParser(options.imageName, logger_1.log).consume(stream);
|
|
26
27
|
}
|
|
27
28
|
catch (err) {
|
|
@@ -11,11 +11,12 @@ 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
|
|
14
|
+
const docker_client_1 = require("../../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 container ${options.containerId} to network ${options.networkId}`);
|
|
18
|
-
const
|
|
18
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
19
|
+
const network = dockerode.getNetwork(options.networkId);
|
|
19
20
|
yield network.connect({ Container: options.containerId, EndpointConfig: { Aliases: options.networkAliases } });
|
|
20
21
|
}
|
|
21
22
|
catch (err) {
|
|
@@ -11,12 +11,13 @@ 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
|
|
14
|
+
const docker_client_1 = require("../../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
|
|
19
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
20
|
+
const network = yield dockerode.createNetwork({
|
|
20
21
|
Name: options.name,
|
|
21
22
|
CheckDuplicate: options.checkDuplicate,
|
|
22
23
|
Driver: options.driver,
|
|
@@ -11,11 +11,12 @@ 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
|
|
14
|
+
const docker_client_1 = require("../../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
|
|
18
|
+
const { dockerode } = yield docker_client_1.dockerClient;
|
|
19
|
+
const network = dockerode.getNetwork(id);
|
|
19
20
|
const { message } = yield network.remove();
|
|
20
21
|
if (message) {
|
|
21
22
|
logger_1.log.warn(message);
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Command } from "../types";
|
|
2
|
-
|
|
2
|
+
import Dockerode from "dockerode";
|
|
3
|
+
export declare const runInContainer: (dockerode: Dockerode, image: string, command: Command[]) => Promise<string | undefined>;
|
|
@@ -12,17 +12,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.runInContainer = void 0;
|
|
13
13
|
const logger_1 = require("../../logger");
|
|
14
14
|
const docker_image_name_1 = require("../../docker-image-name");
|
|
15
|
-
const dockerode_1 = require("../dockerode");
|
|
16
15
|
const pull_image_1 = require("./image/pull-image");
|
|
17
16
|
const start_container_1 = require("./container/start-container");
|
|
18
17
|
const attach_container_1 = require("./container/attach-container");
|
|
19
18
|
const inspect_container_1 = require("./container/inspect-container");
|
|
20
|
-
const runInContainer = (image, command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
const runInContainer = (dockerode, image, command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
20
|
try {
|
|
22
21
|
const imageName = docker_image_name_1.DockerImageName.fromString(image);
|
|
23
22
|
yield pull_image_1.pullImage({ imageName, force: false });
|
|
24
23
|
logger_1.log.debug(`Creating container: ${image} with command: ${command.join(" ")}`);
|
|
25
|
-
const container = yield
|
|
24
|
+
const container = yield dockerode.createContainer({ Image: image, Cmd: command, HostConfig: { AutoRemove: true } });
|
|
26
25
|
logger_1.log.debug(`Attaching to container: ${container.id}`);
|
|
27
26
|
const stream = yield attach_container_1.attachContainer(container);
|
|
28
27
|
const promise = new Promise((resolve) => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.version = exports.stop = exports.down = exports.upAll = exports.upMany = void 0;
|
|
4
|
-
|
|
5
|
-
testcontainers_properties_file_1.loadTestcontainersPropertiesFile();
|
|
4
|
+
require("../testcontainers-properties-file");
|
|
6
5
|
var docker_compose_1 = require("docker-compose");
|
|
7
6
|
Object.defineProperty(exports, "upMany", { enumerable: true, get: function () { return docker_compose_1.upMany; } });
|
|
8
7
|
Object.defineProperty(exports, "upAll", { enumerable: true, get: function () { return docker_compose_1.upAll; } });
|
|
@@ -20,7 +20,7 @@ const reaper_1 = require("../reaper");
|
|
|
20
20
|
const uuid_1 = require("../uuid");
|
|
21
21
|
const list_containers_1 = require("../docker/functions/container/list-containers");
|
|
22
22
|
const get_container_1 = require("../docker/functions/container/get-container");
|
|
23
|
-
const
|
|
23
|
+
const docker_client_1 = require("../docker/docker-client");
|
|
24
24
|
const inspect_container_1 = require("../docker/functions/container/inspect-container");
|
|
25
25
|
const container_logs_1 = require("../docker/functions/container/container-logs");
|
|
26
26
|
const started_docker_compose_environment_1 = require("./started-docker-compose-environment");
|
|
@@ -89,7 +89,7 @@ class DockerComposeEnvironment {
|
|
|
89
89
|
], []);
|
|
90
90
|
logger_1.log.info(`Started the following containers: ${startedContainerNames.join(", ")}`);
|
|
91
91
|
const startedGenericContainers = (yield Promise.all(startedContainers.map((startedContainer) => __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const container = get_container_1.getContainerById(startedContainer.Id);
|
|
92
|
+
const container = yield get_container_1.getContainerById(startedContainer.Id);
|
|
93
93
|
const containerName = container_name_resolver_1.resolveContainerName(this.projectName, startedContainer.Names[0]);
|
|
94
94
|
(yield container_logs_1.containerLogs(container))
|
|
95
95
|
.on("data", (data) => logger_1.containerLog.trace(`${containerName}: ${data}`))
|
|
@@ -111,7 +111,7 @@ class DockerComposeEnvironment {
|
|
|
111
111
|
}
|
|
112
112
|
throw err;
|
|
113
113
|
}
|
|
114
|
-
return new started_generic_container_1.StartedGenericContainer(container, yield
|
|
114
|
+
return new started_generic_container_1.StartedGenericContainer(container, (yield docker_client_1.dockerClient).host, inspectResult, boundPorts, containerName);
|
|
115
115
|
})))).reduce((map, startedGenericContainer) => {
|
|
116
116
|
const containerName = startedGenericContainer.getName();
|
|
117
117
|
return Object.assign(Object.assign({}, map), { [containerName]: startedGenericContainer });
|
|
@@ -122,7 +122,7 @@ class DockerComposeEnvironment {
|
|
|
122
122
|
}
|
|
123
123
|
waitForContainer(container, containerName, boundPorts) {
|
|
124
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
-
const waitStrategy = this.getWaitStrategy(yield
|
|
125
|
+
const waitStrategy = this.getWaitStrategy((yield docker_client_1.dockerClient).host, container, containerName);
|
|
126
126
|
yield waitStrategy.withStartupTimeout(this.startupTimeout).waitUntilReady(container, boundPorts);
|
|
127
127
|
});
|
|
128
128
|
}
|
|
@@ -26,7 +26,7 @@ const registry_auth_locator_1 = require("../registry-auth-locator");
|
|
|
26
26
|
const pull_image_1 = require("../docker/functions/image/pull-image");
|
|
27
27
|
const create_container_1 = require("../docker/functions/container/create-container");
|
|
28
28
|
const connect_network_1 = require("../docker/functions/network/connect-network");
|
|
29
|
-
const
|
|
29
|
+
const docker_client_1 = require("../docker/docker-client");
|
|
30
30
|
const inspect_container_1 = require("../docker/functions/container/inspect-container");
|
|
31
31
|
const start_container_1 = require("../docker/functions/container/start-container");
|
|
32
32
|
const container_logs_1 = require("../docker/functions/container/container-logs");
|
|
@@ -119,7 +119,7 @@ class GenericContainer {
|
|
|
119
119
|
const inspectResult = yield inspect_container_1.inspectContainer(container);
|
|
120
120
|
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(inspectResult).filter(this.ports);
|
|
121
121
|
yield this.waitForContainer(container, boundPorts);
|
|
122
|
-
const startedContainer = new started_generic_container_1.StartedGenericContainer(container, yield
|
|
122
|
+
const startedContainer = new started_generic_container_1.StartedGenericContainer(container, (yield docker_client_1.dockerClient).host, inspectResult, boundPorts, inspectResult.name);
|
|
123
123
|
if (this.postStart) {
|
|
124
124
|
yield this.postStart(startedContainer, inspectResult, boundPorts);
|
|
125
125
|
}
|
|
@@ -215,7 +215,7 @@ class GenericContainer {
|
|
|
215
215
|
waitForContainer(container, boundPorts) {
|
|
216
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
217
217
|
logger_1.log.debug(`Waiting for container to be ready: ${container.id}`);
|
|
218
|
-
const waitStrategy = this.getWaitStrategy(yield
|
|
218
|
+
const waitStrategy = this.getWaitStrategy((yield docker_client_1.dockerClient).host, container);
|
|
219
219
|
try {
|
|
220
220
|
yield waitStrategy.withStartupTimeout(this.startupTimeout).waitUntilReady(container, boundPorts);
|
|
221
221
|
logger_1.log.info("Container is ready");
|
|
@@ -14,7 +14,7 @@ const generic_container_1 = require("../../generic-container/generic-container")
|
|
|
14
14
|
const uuid_1 = require("../../uuid");
|
|
15
15
|
const abstract_started_container_1 = require("../abstract-started-container");
|
|
16
16
|
const port_generator_1 = require("../../port-generator");
|
|
17
|
-
const
|
|
17
|
+
const docker_client_1 = require("../../docker/docker-client");
|
|
18
18
|
const KAFKA_PORT = 9093;
|
|
19
19
|
const KAFKA_BROKER_PORT = 9092;
|
|
20
20
|
exports.KAFKA_IMAGE = "confluentinc/cp-kafka:5.5.4";
|
|
@@ -77,7 +77,7 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
77
77
|
postStart(container, inspectResult, boundPorts) {
|
|
78
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
79
79
|
const brokerAdvertisedListener = `BROKER://${inspectResult.hostname}:${KAFKA_BROKER_PORT}`;
|
|
80
|
-
const bootstrapServers = `PLAINTEXT://${yield
|
|
80
|
+
const bootstrapServers = `PLAINTEXT://${(yield docker_client_1.dockerClient).host}:${boundPorts.getBinding(KAFKA_PORT)}`;
|
|
81
81
|
const { output, exitCode } = yield container.exec([
|
|
82
82
|
"kafka-configs",
|
|
83
83
|
"--alter",
|
package/dist/port-forwarder.js
CHANGED
|
@@ -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
|
|
18
|
+
const docker_client_1 = require("./docker/docker-client");
|
|
19
19
|
const images_1 = require("./images");
|
|
20
20
|
class PortForwarder {
|
|
21
21
|
constructor(sshConnection, container) {
|
|
@@ -66,7 +66,7 @@ class PortForwarderInstance {
|
|
|
66
66
|
`echo "${username}:$PASSWORD" | chpasswd && /usr/sbin/sshd -D -o PermitRootLogin=yes -o AddressFamily=inet -o GatewayPorts=yes`,
|
|
67
67
|
])
|
|
68
68
|
.start();
|
|
69
|
-
const host = yield
|
|
69
|
+
const host = (yield docker_client_1.dockerClient).host;
|
|
70
70
|
const port = container.getMappedPort(22);
|
|
71
71
|
logger_1.log.debug(`Connecting to Port Forwarder on ${host}:${port}`);
|
|
72
72
|
const connection = yield ssh_remote_port_forward_1.createSshConnection({ host, port, username, password });
|
package/dist/reaper.js
CHANGED
|
@@ -14,7 +14,7 @@ const net_1 = require("net");
|
|
|
14
14
|
const logger_1 = require("./logger");
|
|
15
15
|
const generic_container_1 = require("./generic-container/generic-container");
|
|
16
16
|
const session_id_1 = require("./docker/session-id");
|
|
17
|
-
const
|
|
17
|
+
const docker_client_1 = require("./docker/docker-client");
|
|
18
18
|
const images_1 = require("./images");
|
|
19
19
|
class RealReaper {
|
|
20
20
|
constructor(container, socket) {
|
|
@@ -89,7 +89,7 @@ class ReaperInstance {
|
|
|
89
89
|
}
|
|
90
90
|
const startedContainer = yield container.start();
|
|
91
91
|
const containerId = startedContainer.getId();
|
|
92
|
-
const host = yield
|
|
92
|
+
const host = (yield docker_client_1.dockerClient).host;
|
|
93
93
|
const port = startedContainer.getMappedPort(8080);
|
|
94
94
|
logger_1.log.debug(`Connecting to Reaper ${containerId} on ${host}:${port}`);
|
|
95
95
|
const socket = new net_1.Socket();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
@@ -3,33 +3,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadTestcontainersPropertiesFile = void 0;
|
|
7
6
|
const path_1 = __importDefault(require("path"));
|
|
8
7
|
const logger_1 = require("./logger");
|
|
9
8
|
const os_1 = require("os");
|
|
10
9
|
const fs_1 = require("fs");
|
|
11
10
|
const properties_reader_1 = __importDefault(require("properties-reader"));
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
process.env.DOCKER_HOST = host;
|
|
22
|
-
}
|
|
23
|
-
const tlsVerify = properties.get("docker.tls.verify");
|
|
24
|
-
if (tlsVerify !== null) {
|
|
25
|
-
logger_1.log.debug(`Setting DOCKER_TLS_VERIFY to ${tlsVerify}`);
|
|
26
|
-
process.env.DOCKER_TLS_VERIFY = `${tlsVerify}`;
|
|
27
|
-
}
|
|
28
|
-
const certPath = properties.get("docker.cert.path");
|
|
29
|
-
if (certPath !== null) {
|
|
30
|
-
logger_1.log.debug(`Setting DOCKER_CERT_PATH to ${certPath}`);
|
|
31
|
-
process.env.DOCKER_CERT_PATH = certPath;
|
|
32
|
-
}
|
|
11
|
+
const file = path_1.default.resolve(os_1.homedir(), ".testcontainers.properties");
|
|
12
|
+
if (fs_1.existsSync(file)) {
|
|
13
|
+
logger_1.log.debug("Found .testcontainers.properties file");
|
|
14
|
+
const string = fs_1.readFileSync(file, { encoding: "utf-8" });
|
|
15
|
+
const properties = properties_reader_1.default("").read(string);
|
|
16
|
+
const host = properties.get("docker.host");
|
|
17
|
+
if (host !== null) {
|
|
18
|
+
logger_1.log.debug(`Setting DOCKER_HOST to ${host}`);
|
|
19
|
+
process.env.DOCKER_HOST = host;
|
|
33
20
|
}
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const tlsVerify = properties.get("docker.tls.verify");
|
|
22
|
+
if (tlsVerify !== null) {
|
|
23
|
+
logger_1.log.debug(`Setting DOCKER_TLS_VERIFY to ${tlsVerify}`);
|
|
24
|
+
process.env.DOCKER_TLS_VERIFY = `${tlsVerify}`;
|
|
25
|
+
}
|
|
26
|
+
const certPath = properties.get("docker.cert.path");
|
|
27
|
+
if (certPath !== null) {
|
|
28
|
+
logger_1.log.debug(`Setting DOCKER_CERT_PATH to ${certPath}`);
|
|
29
|
+
process.env.DOCKER_CERT_PATH = certPath;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const dockerHost: Promise<string>;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dockerHost = void 0;
|
|
4
|
-
const log_system_diagnostics_1 = require("../log-system-diagnostics");
|
|
5
|
-
const get_docker_host_1 = require("./get-docker-host");
|
|
6
|
-
const dockerode_1 = require("./dockerode");
|
|
7
|
-
exports.dockerHost = get_docker_host_1.getDockerHost(dockerode_1.dockerode);
|
|
8
|
-
log_system_diagnostics_1.logSystemDiagnostics();
|
package/dist/docker/dockerode.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.dockerode = void 0;
|
|
7
|
-
const dockerode_1 = __importDefault(require("dockerode"));
|
|
8
|
-
const testcontainers_properties_file_1 = require("../testcontainers-properties-file");
|
|
9
|
-
testcontainers_properties_file_1.loadTestcontainersPropertiesFile();
|
|
10
|
-
exports.dockerode = new dockerode_1.default();
|
|
@@ -1,64 +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.getDockerHost = void 0;
|
|
16
|
-
const logger_1 = require("../logger");
|
|
17
|
-
const run_in_container_1 = require("./functions/run-in-container");
|
|
18
|
-
const fs_1 = __importDefault(require("fs"));
|
|
19
|
-
const url_1 = require("url");
|
|
20
|
-
const DEFAULT_HOST = "localhost";
|
|
21
|
-
const getDockerHost = (dockerode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
-
for (const [hostStrategyName, hostStrategy] of Object.entries(hostStrategies(dockerode))) {
|
|
23
|
-
const result = yield hostStrategy();
|
|
24
|
-
if (result) {
|
|
25
|
-
const hostname = result === DEFAULT_HOST ? DEFAULT_HOST : new url_1.URL(result).hostname;
|
|
26
|
-
logger_1.log.info(`Docker host strategy ${hostStrategyName}: ${hostname}`);
|
|
27
|
-
return hostname;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
logger_1.log.info(`Docker host strategy FALLBACK: ${DEFAULT_HOST}`);
|
|
31
|
-
return DEFAULT_HOST;
|
|
32
|
-
});
|
|
33
|
-
exports.getDockerHost = getDockerHost;
|
|
34
|
-
const hostStrategies = (dockerode) => ({
|
|
35
|
-
DOCKER_HOST: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
-
if (process.env.DOCKER_HOST) {
|
|
37
|
-
return process.env.DOCKER_HOST;
|
|
38
|
-
}
|
|
39
|
-
}),
|
|
40
|
-
MODEM: () => __awaiter(void 0, void 0, void 0, function* () { return dockerode.modem.host; }),
|
|
41
|
-
TESTCONTAINERS_HOST_OVERRIDE: () => __awaiter(void 0, void 0, void 0, function* () { return process.env["TESTCONTAINERS_HOST_OVERRIDE"]; }),
|
|
42
|
-
OUTSIDE_CONTAINER: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
-
if (!isInContainer()) {
|
|
44
|
-
return DEFAULT_HOST;
|
|
45
|
-
}
|
|
46
|
-
}),
|
|
47
|
-
INSIDE_CONTAINER_NO_IPAM: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
-
const network = yield dockerode.getNetwork("bridge").inspect();
|
|
49
|
-
if (!network.IPAM || !network.IPAM.Config) {
|
|
50
|
-
return DEFAULT_HOST;
|
|
51
|
-
}
|
|
52
|
-
}),
|
|
53
|
-
INSIDE_CONTAINER_IPAM: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
-
const network = yield dockerode.getNetwork("bridge").inspect();
|
|
55
|
-
if (network.IPAM && network.IPAM.Config) {
|
|
56
|
-
const gateways = network.IPAM.Config.filter((config) => !!config.Gateway);
|
|
57
|
-
if (gateways.length > 0) {
|
|
58
|
-
return gateways[0].Gateway;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}),
|
|
62
|
-
CONTAINER_GATEWAY: () => __awaiter(void 0, void 0, void 0, function* () { return run_in_container_1.runInContainer("alpine:3.5", ["sh", "-c", "ip route|awk '/default/ { print $3 }'"]); }),
|
|
63
|
-
});
|
|
64
|
-
const isInContainer = () => fs_1.default.existsSync("/.dockerenv");
|