testcontainers 7.23.2 → 8.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -12
- package/dist/bound-ports.d.ts +3 -0
- package/dist/bound-ports.js +14 -0
- package/dist/docker/docker-client.d.ts +9 -0
- package/dist/docker/docker-client.js +149 -0
- package/dist/docker/functions/container/create-container.d.ts +2 -2
- package/dist/docker/functions/container/create-container.js +11 -10
- package/dist/docker/functions/container/exec-container.js +16 -12
- 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/inspect-container.d.ts +3 -4
- package/dist/docker/functions/container/inspect-container.js +10 -8
- 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/types.d.ts +3 -0
- package/dist/docker-compose/default-docker-compose-options.d.ts +1 -1
- package/dist/docker-compose/docker-compose.d.ts +3 -0
- package/dist/docker-compose/docker-compose.js +10 -0
- package/dist/docker-compose/functions/docker-compose-down.js +1 -1
- package/dist/docker-compose/functions/docker-compose-stop.js +1 -1
- package/dist/docker-compose/functions/docker-compose-up.js +1 -1
- package/dist/docker-compose-environment/docker-compose-environment.d.ts +0 -1
- package/dist/docker-compose-environment/docker-compose-environment.js +6 -14
- package/dist/generic-container/generic-container.d.ts +6 -2
- package/dist/generic-container/generic-container.js +25 -9
- package/dist/log-system-diagnostics.js +2 -21
- package/dist/modules/kafka/kafka-container.d.ts +6 -17
- package/dist/modules/kafka/kafka-container.js +57 -69
- package/dist/port-forwarder.js +2 -2
- package/dist/reaper.d.ts +1 -0
- package/dist/reaper.js +20 -14
- package/dist/test-container.d.ts +2 -1
- package/dist/testcontainers-properties-file.d.ts +1 -0
- package/dist/testcontainers-properties-file.js +31 -0
- package/package.json +4 -2
- 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 -60
|
@@ -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) => {
|
package/dist/docker/types.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export declare type ExtraHost = {
|
|
|
28
28
|
};
|
|
29
29
|
export declare type NetworkMode = string;
|
|
30
30
|
export declare type ContainerName = string;
|
|
31
|
+
export declare type Ports = {
|
|
32
|
+
[internalPort: number]: number;
|
|
33
|
+
};
|
|
31
34
|
export declare type AuthConfig = {
|
|
32
35
|
username: string;
|
|
33
36
|
password: string;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { IDockerComposeOptions } from "docker-compose";
|
|
1
|
+
import { IDockerComposeOptions } from "./docker-compose";
|
|
2
2
|
import { DockerComposeOptions } from "./docker-compose-options";
|
|
3
3
|
export declare const defaultDockerComposeOptions: ({ env, ...options }: DockerComposeOptions) => Partial<IDockerComposeOptions>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.version = exports.stop = exports.down = exports.upAll = exports.upMany = void 0;
|
|
4
|
+
require("../testcontainers-properties-file");
|
|
5
|
+
var docker_compose_1 = require("docker-compose");
|
|
6
|
+
Object.defineProperty(exports, "upMany", { enumerable: true, get: function () { return docker_compose_1.upMany; } });
|
|
7
|
+
Object.defineProperty(exports, "upAll", { enumerable: true, get: function () { return docker_compose_1.upAll; } });
|
|
8
|
+
Object.defineProperty(exports, "down", { enumerable: true, get: function () { return docker_compose_1.down; } });
|
|
9
|
+
Object.defineProperty(exports, "stop", { enumerable: true, get: function () { return docker_compose_1.stop; } });
|
|
10
|
+
Object.defineProperty(exports, "version", { enumerable: true, get: function () { return docker_compose_1.version; } });
|
|
@@ -10,9 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.dockerComposeDown = void 0;
|
|
13
|
-
const docker_compose_1 = require("docker-compose");
|
|
14
13
|
const logger_1 = require("../../logger");
|
|
15
14
|
const default_docker_compose_options_1 = require("../default-docker-compose-options");
|
|
15
|
+
const docker_compose_1 = require("../docker-compose");
|
|
16
16
|
const dockerComposeDown = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
logger_1.log.info(`Downing DockerCompose environment`);
|
|
18
18
|
try {
|
|
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.dockerComposeStop = void 0;
|
|
13
13
|
const logger_1 = require("../../logger");
|
|
14
|
-
const docker_compose_1 = require("docker-compose");
|
|
14
|
+
const docker_compose_1 = require("../docker-compose");
|
|
15
15
|
const default_docker_compose_options_1 = require("../default-docker-compose-options");
|
|
16
16
|
const dockerComposeStop = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
logger_1.log.info(`Stopping DockerCompose environment`);
|
|
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.dockerComposeUp = void 0;
|
|
13
13
|
const logger_1 = require("../../logger");
|
|
14
|
-
const docker_compose_1 = require("docker-compose");
|
|
14
|
+
const docker_compose_1 = require("../docker-compose");
|
|
15
15
|
const default_docker_compose_options_1 = require("../default-docker-compose-options");
|
|
16
16
|
const docker_compose_down_1 = require("./docker-compose-down");
|
|
17
17
|
const dockerComposeUp = (options, services) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -20,7 +20,6 @@ export declare class DockerComposeEnvironment {
|
|
|
20
20
|
withWaitStrategy(containerName: string, waitStrategy: WaitStrategy): this;
|
|
21
21
|
withStartupTimeout(startupTimeout: number): this;
|
|
22
22
|
up(services?: Array<string>): Promise<StartedDockerComposeEnvironment>;
|
|
23
|
-
private getBoundPorts;
|
|
24
23
|
private waitForContainer;
|
|
25
24
|
private getWaitStrategy;
|
|
26
25
|
}
|
|
@@ -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");
|
|
@@ -80,10 +80,7 @@ class DockerComposeEnvironment {
|
|
|
80
80
|
commandOptions.push("--no-recreate");
|
|
81
81
|
}
|
|
82
82
|
const composeOptions = [];
|
|
83
|
-
this.profiles.forEach((profile) =>
|
|
84
|
-
composeOptions.push("--profile");
|
|
85
|
-
composeOptions.push(profile);
|
|
86
|
-
});
|
|
83
|
+
this.profiles.forEach((profile) => composeOptions.push("--profile", profile));
|
|
87
84
|
yield docker_compose_up_1.dockerComposeUp(Object.assign(Object.assign({}, options), { commandOptions, composeOptions, env: this.env }), services);
|
|
88
85
|
const startedContainers = (yield list_containers_1.listContainers()).filter((container) => container.Labels["com.docker.compose.project"] === this.projectName);
|
|
89
86
|
const startedContainerNames = startedContainers.reduce((containerNames, startedContainer) => [
|
|
@@ -92,13 +89,13 @@ class DockerComposeEnvironment {
|
|
|
92
89
|
], []);
|
|
93
90
|
logger_1.log.info(`Started the following containers: ${startedContainerNames.join(", ")}`);
|
|
94
91
|
const startedGenericContainers = (yield Promise.all(startedContainers.map((startedContainer) => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
const container = get_container_1.getContainerById(startedContainer.Id);
|
|
92
|
+
const container = yield get_container_1.getContainerById(startedContainer.Id);
|
|
96
93
|
const containerName = container_name_resolver_1.resolveContainerName(this.projectName, startedContainer.Names[0]);
|
|
97
94
|
(yield container_logs_1.containerLogs(container))
|
|
98
95
|
.on("data", (data) => logger_1.containerLog.trace(`${containerName}: ${data}`))
|
|
99
96
|
.on("err", (data) => logger_1.containerLog.error(`${containerName}: ${data}`));
|
|
100
97
|
const inspectResult = yield inspect_container_1.inspectContainer(container);
|
|
101
|
-
const boundPorts =
|
|
98
|
+
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(inspectResult);
|
|
102
99
|
try {
|
|
103
100
|
logger_1.log.info(`Waiting for container ${containerName} to be ready`);
|
|
104
101
|
yield this.waitForContainer(container, containerName, boundPorts);
|
|
@@ -114,7 +111,7 @@ class DockerComposeEnvironment {
|
|
|
114
111
|
}
|
|
115
112
|
throw err;
|
|
116
113
|
}
|
|
117
|
-
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);
|
|
118
115
|
})))).reduce((map, startedGenericContainer) => {
|
|
119
116
|
const containerName = startedGenericContainer.getName();
|
|
120
117
|
return Object.assign(Object.assign({}, map), { [containerName]: startedGenericContainer });
|
|
@@ -123,14 +120,9 @@ class DockerComposeEnvironment {
|
|
|
123
120
|
return new started_docker_compose_environment_1.StartedDockerComposeEnvironment(startedGenericContainers, Object.assign(Object.assign({}, options), { composeOptions, env: this.env }));
|
|
124
121
|
});
|
|
125
122
|
}
|
|
126
|
-
getBoundPorts(containerInfo) {
|
|
127
|
-
const boundPorts = new bound_ports_1.BoundPorts();
|
|
128
|
-
containerInfo.Ports.filter((port) => port.PublicPort !== undefined).forEach((port) => boundPorts.setBinding(port.PrivatePort, port.PublicPort));
|
|
129
|
-
return boundPorts;
|
|
130
|
-
}
|
|
131
123
|
waitForContainer(container, containerName, boundPorts) {
|
|
132
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
-
const waitStrategy = this.getWaitStrategy(yield
|
|
125
|
+
const waitStrategy = this.getWaitStrategy((yield docker_client_1.dockerClient).host, container, containerName);
|
|
134
126
|
yield waitStrategy.withStartupTimeout(this.startupTimeout).waitUntilReady(container, boundPorts);
|
|
135
127
|
});
|
|
136
128
|
}
|
|
@@ -6,7 +6,8 @@ import { PullPolicy } from "../pull-policy";
|
|
|
6
6
|
import { StartedTestContainer, TestContainer } from "../test-container";
|
|
7
7
|
import { WaitStrategy } from "../wait-strategy";
|
|
8
8
|
import { Readable } from "stream";
|
|
9
|
-
import { BindMode, BindMount, BuildContext, Command, ContainerName, Dir, Env, EnvKey, EnvValue, HealthCheck, NetworkMode, TmpFs } from "../docker/types";
|
|
9
|
+
import { BindMode, BindMount, BuildContext, Command, ContainerName, Dir, Env, EnvKey, EnvValue, ExtraHost, HealthCheck, NetworkMode, TmpFs } from "../docker/types";
|
|
10
|
+
import { InspectResult } from "../docker/functions/container/inspect-container";
|
|
10
11
|
import { GenericContainerBuilder } from "./generic-container-builder";
|
|
11
12
|
export declare class GenericContainer implements TestContainer {
|
|
12
13
|
readonly image: string;
|
|
@@ -31,14 +32,18 @@ export declare class GenericContainer implements TestContainer {
|
|
|
31
32
|
protected tarToCopy?: archiver.Archiver;
|
|
32
33
|
private extraHosts;
|
|
33
34
|
constructor(image: string);
|
|
35
|
+
protected preStart?(): Promise<void>;
|
|
34
36
|
start(): Promise<StartedTestContainer>;
|
|
37
|
+
protected postStart?(container: StartedTestContainer, inspectResult: InspectResult, boundPorts: BoundPorts): Promise<void>;
|
|
35
38
|
withCmd(cmd: Command[]): this;
|
|
36
39
|
withName(name: ContainerName): this;
|
|
37
40
|
withEnv(key: EnvKey, value: EnvValue): this;
|
|
38
41
|
withTmpFs(tmpFs: TmpFs): this;
|
|
39
42
|
withNetworkMode(networkMode: NetworkMode): this;
|
|
40
43
|
withNetworkAliases(...networkAliases: string[]): this;
|
|
44
|
+
withExtraHosts(...extraHosts: ExtraHost[]): this;
|
|
41
45
|
withExposedPorts(...ports: Port[]): this;
|
|
46
|
+
protected addExposedPorts(...ports: Port[]): this;
|
|
42
47
|
withBindMount(source: Dir, target: Dir, bindMode?: BindMode): this;
|
|
43
48
|
withHealthCheck(healthCheck: HealthCheck): this;
|
|
44
49
|
withStartupTimeout(startupTimeout: number): this;
|
|
@@ -51,7 +56,6 @@ export declare class GenericContainer implements TestContainer {
|
|
|
51
56
|
withCopyFileToContainer(sourcePath: string, containerPath: string): this;
|
|
52
57
|
withCopyContentToContainer(content: string | Buffer | Readable, containerPath: string): this;
|
|
53
58
|
protected getTarToCopy(): archiver.Archiver;
|
|
54
|
-
protected preCreate?(boundPorts: BoundPorts): Promise<void>;
|
|
55
59
|
private waitForContainer;
|
|
56
60
|
private getWaitStrategy;
|
|
57
61
|
}
|
|
@@ -14,8 +14,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.GenericContainer = void 0;
|
|
16
16
|
const archiver_1 = __importDefault(require("archiver"));
|
|
17
|
+
const bound_ports_1 = require("../bound-ports");
|
|
17
18
|
const logger_1 = require("../logger");
|
|
18
|
-
const port_binder_1 = require("../port-binder");
|
|
19
19
|
const port_check_1 = require("../port-check");
|
|
20
20
|
const pull_policy_1 = require("../pull-policy");
|
|
21
21
|
const reaper_1 = require("../reaper");
|
|
@@ -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");
|
|
@@ -61,12 +61,11 @@ class GenericContainer {
|
|
|
61
61
|
force: this.pullPolicy.shouldPull(),
|
|
62
62
|
authConfig: yield registry_auth_locator_1.getAuthConfig(this.imageName.registry),
|
|
63
63
|
});
|
|
64
|
-
const boundPorts = yield new port_binder_1.PortBinder().bind(this.ports);
|
|
65
64
|
if (!this.imageName.isReaper()) {
|
|
66
65
|
yield reaper_1.ReaperInstance.getInstance();
|
|
67
66
|
}
|
|
68
|
-
if (this.
|
|
69
|
-
yield this.
|
|
67
|
+
if (this.preStart) {
|
|
68
|
+
yield this.preStart();
|
|
70
69
|
}
|
|
71
70
|
if (!this.imageName.isHelperContainer() && port_forwarder_1.PortForwarderInstance.isRunning()) {
|
|
72
71
|
const portForwarder = yield port_forwarder_1.PortForwarderInstance.getInstance();
|
|
@@ -78,7 +77,7 @@ class GenericContainer {
|
|
|
78
77
|
cmd: this.cmd,
|
|
79
78
|
bindMounts: this.bindMounts,
|
|
80
79
|
tmpFs: this.tmpFs,
|
|
81
|
-
|
|
80
|
+
exposedPorts: this.ports,
|
|
82
81
|
name: this.name,
|
|
83
82
|
networkMode: this.networkAliases.length > 0 ? undefined : this.networkMode,
|
|
84
83
|
healthCheck: this.healthCheck,
|
|
@@ -94,7 +93,11 @@ class GenericContainer {
|
|
|
94
93
|
const portForwarderNetworkId = portForwarder.getNetworkId();
|
|
95
94
|
const excludedNetworks = [portForwarderNetworkId, "none", "host"];
|
|
96
95
|
if (!this.networkMode || !excludedNetworks.includes(this.networkMode)) {
|
|
97
|
-
yield connect_network_1.connectNetwork({
|
|
96
|
+
yield connect_network_1.connectNetwork({
|
|
97
|
+
containerId: container.id,
|
|
98
|
+
networkId: portForwarderNetworkId,
|
|
99
|
+
networkAliases: [],
|
|
100
|
+
});
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
103
|
if (this.networkMode && this.networkAliases.length > 0) {
|
|
@@ -114,8 +117,13 @@ class GenericContainer {
|
|
|
114
117
|
.on("data", (data) => logger_1.containerLog.trace(`${container.id}: ${data.trim()}`))
|
|
115
118
|
.on("err", (data) => logger_1.containerLog.error(`${container.id}: ${data.trim()}`));
|
|
116
119
|
const inspectResult = yield inspect_container_1.inspectContainer(container);
|
|
120
|
+
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(inspectResult).filter(this.ports);
|
|
117
121
|
yield this.waitForContainer(container, boundPorts);
|
|
118
|
-
|
|
122
|
+
const startedContainer = new started_generic_container_1.StartedGenericContainer(container, (yield docker_client_1.dockerClient).host, inspectResult, boundPorts, inspectResult.name);
|
|
123
|
+
if (this.postStart) {
|
|
124
|
+
yield this.postStart(startedContainer, inspectResult, boundPorts);
|
|
125
|
+
}
|
|
126
|
+
return startedContainer;
|
|
119
127
|
});
|
|
120
128
|
}
|
|
121
129
|
withCmd(cmd) {
|
|
@@ -142,10 +150,18 @@ class GenericContainer {
|
|
|
142
150
|
this.networkAliases = networkAliases;
|
|
143
151
|
return this;
|
|
144
152
|
}
|
|
153
|
+
withExtraHosts(...extraHosts) {
|
|
154
|
+
this.extraHosts.push(...extraHosts);
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
145
157
|
withExposedPorts(...ports) {
|
|
146
158
|
this.ports = ports;
|
|
147
159
|
return this;
|
|
148
160
|
}
|
|
161
|
+
addExposedPorts(...ports) {
|
|
162
|
+
this.ports.push(...ports);
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
149
165
|
withBindMount(source, target, bindMode = "rw") {
|
|
150
166
|
this.bindMounts.push({ source, target, bindMode });
|
|
151
167
|
return this;
|
|
@@ -199,7 +215,7 @@ class GenericContainer {
|
|
|
199
215
|
waitForContainer(container, boundPorts) {
|
|
200
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
201
217
|
logger_1.log.debug(`Waiting for container to be ready: ${container.id}`);
|
|
202
|
-
const waitStrategy = this.getWaitStrategy(yield
|
|
218
|
+
const waitStrategy = this.getWaitStrategy((yield docker_client_1.dockerClient).host, container);
|
|
203
219
|
try {
|
|
204
220
|
yield waitStrategy.withStartupTimeout(this.startupTimeout).waitUntilReady(container, boundPorts);
|
|
205
221
|
logger_1.log.info("Container is ready");
|
|
@@ -1,23 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -30,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
30
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
12
|
exports.logSystemDiagnostics = void 0;
|
|
32
13
|
const logger_1 = require("./logger");
|
|
33
|
-
const
|
|
14
|
+
const docker_compose_1 = require("./docker-compose/docker-compose");
|
|
34
15
|
const get_info_1 = require("./docker/functions/get-info");
|
|
35
16
|
const logSystemDiagnostics = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
17
|
const info = {
|
|
@@ -51,7 +32,7 @@ const getNodeInfo = () => {
|
|
|
51
32
|
const getDockerComposeInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
33
|
try {
|
|
53
34
|
return {
|
|
54
|
-
version: (yield
|
|
35
|
+
version: (yield docker_compose_1.version()).data.version,
|
|
55
36
|
};
|
|
56
37
|
}
|
|
57
38
|
catch (err) {
|
|
@@ -1,34 +1,23 @@
|
|
|
1
1
|
import { GenericContainer } from "../../generic-container/generic-container";
|
|
2
2
|
import { BoundPorts } from "../../bound-ports";
|
|
3
|
-
import { StartedNetwork } from "../../network";
|
|
4
3
|
import { Port } from "../../port";
|
|
5
|
-
import { StartedTestContainer
|
|
6
|
-
import { StopOptions } from "../../test-container";
|
|
4
|
+
import { StartedTestContainer } from "../..";
|
|
7
5
|
import { AbstractStartedContainer } from "../abstract-started-container";
|
|
8
6
|
import { Host } from "../../docker/types";
|
|
7
|
+
import { InspectResult } from "../../docker/functions/container/inspect-container";
|
|
9
8
|
export declare const KAFKA_IMAGE = "confluentinc/cp-kafka:5.5.4";
|
|
10
|
-
export declare const ZK_IMAGE = "confluentinc/cp-zookeeper:5.5.4";
|
|
11
9
|
export declare class KafkaContainer extends GenericContainer {
|
|
12
|
-
private readonly zooKeeperImage;
|
|
13
|
-
private readonly host;
|
|
14
10
|
private readonly uuid;
|
|
15
11
|
private readonly portGenerator;
|
|
16
12
|
private isZooKeeperProvided;
|
|
17
13
|
private zooKeeperHost?;
|
|
18
14
|
private zooKeeperPort?;
|
|
19
|
-
|
|
20
|
-
private zooKeeperContainer?;
|
|
21
|
-
constructor(image?: string, host?: Host, zooKeeperImage?: string);
|
|
15
|
+
constructor(image?: string);
|
|
22
16
|
withZooKeeper(host: Host, port: Port): this;
|
|
23
|
-
protected
|
|
17
|
+
protected preStart(): Promise<void>;
|
|
24
18
|
start(): Promise<StartedKafkaContainer>;
|
|
19
|
+
protected postStart(container: StartedTestContainer, inspectResult: InspectResult, boundPorts: BoundPorts): Promise<void>;
|
|
25
20
|
}
|
|
26
21
|
export declare class StartedKafkaContainer extends AbstractStartedContainer {
|
|
27
|
-
|
|
28
|
-
private readonly zooKeeperContainer?;
|
|
29
|
-
private readonly zooKeeperPort?;
|
|
30
|
-
constructor(startedTestContainer: StartedTestContainer, network?: StartedNetwork | undefined, zooKeeperContainer?: StartedTestContainer | undefined, zooKeeperPort?: number | undefined);
|
|
31
|
-
stop(options?: Partial<StopOptions>): Promise<StoppedTestContainer>;
|
|
32
|
-
getZookeeperName(): string | undefined;
|
|
33
|
-
getZookeeperPort(): number | undefined;
|
|
22
|
+
constructor(startedTestContainer: StartedTestContainer);
|
|
34
23
|
}
|
|
@@ -9,26 +9,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.StartedKafkaContainer = exports.KafkaContainer = exports.
|
|
12
|
+
exports.StartedKafkaContainer = exports.KafkaContainer = exports.KAFKA_IMAGE = void 0;
|
|
13
13
|
const generic_container_1 = require("../../generic-container/generic-container");
|
|
14
|
-
const network_1 = require("../../network");
|
|
15
14
|
const uuid_1 = require("../../uuid");
|
|
16
|
-
const logger_1 = require("../../logger");
|
|
17
15
|
const abstract_started_container_1 = require("../abstract-started-container");
|
|
18
16
|
const port_generator_1 = require("../../port-generator");
|
|
19
|
-
const
|
|
17
|
+
const docker_client_1 = require("../../docker/docker-client");
|
|
20
18
|
const KAFKA_PORT = 9093;
|
|
21
19
|
const KAFKA_BROKER_PORT = 9092;
|
|
22
20
|
exports.KAFKA_IMAGE = "confluentinc/cp-kafka:5.5.4";
|
|
23
|
-
exports.ZK_IMAGE = "confluentinc/cp-zookeeper:5.5.4";
|
|
24
21
|
class KafkaContainer extends generic_container_1.GenericContainer {
|
|
25
|
-
constructor(image = exports.KAFKA_IMAGE
|
|
22
|
+
constructor(image = exports.KAFKA_IMAGE) {
|
|
26
23
|
super(image);
|
|
27
|
-
this.zooKeeperImage = zooKeeperImage;
|
|
28
24
|
this.uuid = new uuid_1.RandomUuid();
|
|
29
25
|
this.portGenerator = new port_generator_1.RandomUniquePortGenerator();
|
|
30
26
|
this.isZooKeeperProvided = false;
|
|
31
|
-
this.
|
|
27
|
+
this.withExposedPorts(KAFKA_PORT)
|
|
28
|
+
.withStartupTimeout(180000)
|
|
29
|
+
.withEnv("KAFKA_LISTENERS", `PLAINTEXT://0.0.0.0:${KAFKA_PORT},BROKER://0.0.0.0:${KAFKA_BROKER_PORT}`)
|
|
30
|
+
.withEnv("KAFKA_LISTENER_SECURITY_PROTOCOL_MAP", "BROKER:PLAINTEXT,PLAINTEXT:PLAINTEXT")
|
|
31
|
+
.withEnv("KAFKA_INTER_BROKER_LISTENER_NAME", "BROKER")
|
|
32
|
+
.withEnv("KAFKA_BROKER_ID", "1")
|
|
33
|
+
.withEnv("KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR", "1")
|
|
34
|
+
.withEnv("KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS", "1")
|
|
35
|
+
.withEnv("KAFKA_TRANSACTION_STATE_LOG_MIN_ISR", "1")
|
|
36
|
+
.withEnv("KAFKA_LOG_FLUSH_INTERVAL_MESSAGES", "9223372036854775807")
|
|
37
|
+
.withEnv("KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS", "0")
|
|
38
|
+
.withEnv("KAFKA_CONFLUENT_SUPPORT_METRICS_ENABLE", "false");
|
|
32
39
|
}
|
|
33
40
|
withZooKeeper(host, port) {
|
|
34
41
|
this.isZooKeeperProvided = true;
|
|
@@ -36,10 +43,27 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
36
43
|
this.zooKeeperPort = port;
|
|
37
44
|
return this;
|
|
38
45
|
}
|
|
39
|
-
|
|
46
|
+
preStart() {
|
|
40
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
-
const
|
|
42
|
-
this.withEnv("KAFKA_ADVERTISED_LISTENERS", `
|
|
48
|
+
const network = this.networkMode && this.networkAliases.length > 0 ? this.networkAliases[0] : "localhost";
|
|
49
|
+
this.withEnv("KAFKA_ADVERTISED_LISTENERS", `BROKER://${network}:${KAFKA_BROKER_PORT}`);
|
|
50
|
+
let command = "#!/bin/bash\n";
|
|
51
|
+
if (this.isZooKeeperProvided) {
|
|
52
|
+
this.withEnv("KAFKA_ZOOKEEPER_CONNECT", `${this.zooKeeperHost}:${this.zooKeeperPort}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
this.zooKeeperHost = this.uuid.nextUuid();
|
|
56
|
+
this.zooKeeperPort = yield this.portGenerator.generatePort();
|
|
57
|
+
this.addExposedPorts(this.zooKeeperPort);
|
|
58
|
+
this.withEnv("KAFKA_ZOOKEEPER_CONNECT", `localhost:${this.zooKeeperPort}`);
|
|
59
|
+
command += "echo 'clientPort=" + this.zooKeeperPort + "' > zookeeper.properties\n";
|
|
60
|
+
command += "echo 'dataDir=/var/lib/zookeeper/data' >> zookeeper.properties\n";
|
|
61
|
+
command += "echo 'dataLogDir=/var/lib/zookeeper/log' >> zookeeper.properties\n";
|
|
62
|
+
command += "zookeeper-server-start zookeeper.properties &\n";
|
|
63
|
+
}
|
|
64
|
+
command += "echo '' > /etc/confluent/docker/ensure \n";
|
|
65
|
+
command += "/etc/confluent/docker/run \n";
|
|
66
|
+
this.withCmd(["sh", "-c", command]);
|
|
43
67
|
});
|
|
44
68
|
}
|
|
45
69
|
start() {
|
|
@@ -47,71 +71,35 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
47
71
|
start: { get: () => super.start }
|
|
48
72
|
});
|
|
49
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
this.network = yield new network_1.Network().start();
|
|
74
|
-
this.withNetworkMode(this.network.getName());
|
|
75
|
-
zookeeperContainer.withNetworkMode(this.network.getName());
|
|
76
|
-
}
|
|
77
|
-
this.zooKeeperContainer = yield zookeeperContainer.start();
|
|
74
|
+
return new StartedKafkaContainer(yield _super.start.call(this));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
postStart(container, inspectResult, boundPorts) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
const brokerAdvertisedListener = `BROKER://${inspectResult.hostname}:${KAFKA_BROKER_PORT}`;
|
|
80
|
+
const bootstrapServers = `PLAINTEXT://${(yield docker_client_1.dockerClient).host}:${boundPorts.getBinding(KAFKA_PORT)}`;
|
|
81
|
+
const { output, exitCode } = yield container.exec([
|
|
82
|
+
"kafka-configs",
|
|
83
|
+
"--alter",
|
|
84
|
+
"--bootstrap-server",
|
|
85
|
+
brokerAdvertisedListener,
|
|
86
|
+
"--entity-type",
|
|
87
|
+
"brokers",
|
|
88
|
+
"--entity-name",
|
|
89
|
+
this.env["KAFKA_BROKER_ID"],
|
|
90
|
+
"--add-config",
|
|
91
|
+
`advertised.listeners=[${bootstrapServers},${brokerAdvertisedListener}]`,
|
|
92
|
+
]);
|
|
93
|
+
if (exitCode !== 0) {
|
|
94
|
+
throw new Error(`Kafka container configuration failed with exit code ${exitCode}: ${output}`);
|
|
78
95
|
}
|
|
79
|
-
return new StartedKafkaContainer(yield _super.start.call(this), this.network, this.zooKeeperContainer, zooKeeperPort);
|
|
80
96
|
});
|
|
81
97
|
}
|
|
82
98
|
}
|
|
83
99
|
exports.KafkaContainer = KafkaContainer;
|
|
84
100
|
class StartedKafkaContainer extends abstract_started_container_1.AbstractStartedContainer {
|
|
85
|
-
constructor(startedTestContainer
|
|
101
|
+
constructor(startedTestContainer) {
|
|
86
102
|
super(startedTestContainer);
|
|
87
|
-
this.network = network;
|
|
88
|
-
this.zooKeeperContainer = zooKeeperContainer;
|
|
89
|
-
this.zooKeeperPort = zooKeeperPort;
|
|
90
|
-
}
|
|
91
|
-
stop(options) {
|
|
92
|
-
const _super = Object.create(null, {
|
|
93
|
-
stop: { get: () => super.stop }
|
|
94
|
-
});
|
|
95
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
-
logger_1.log.debug("Stopping Kafka container");
|
|
97
|
-
const stoppedContainer = yield _super.stop.call(this, options);
|
|
98
|
-
if (this.zooKeeperContainer) {
|
|
99
|
-
logger_1.log.debug("Stopping ZooKeeper container");
|
|
100
|
-
yield this.zooKeeperContainer.stop(options);
|
|
101
|
-
}
|
|
102
|
-
if (this.network) {
|
|
103
|
-
logger_1.log.debug("Stopping Kafka network");
|
|
104
|
-
yield this.network.stop();
|
|
105
|
-
}
|
|
106
|
-
return stoppedContainer;
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
getZookeeperName() {
|
|
110
|
-
var _a;
|
|
111
|
-
return (_a = this.zooKeeperContainer) === null || _a === void 0 ? void 0 : _a.getName();
|
|
112
|
-
}
|
|
113
|
-
getZookeeperPort() {
|
|
114
|
-
return this.zooKeeperPort;
|
|
115
103
|
}
|
|
116
104
|
}
|
|
117
105
|
exports.StartedKafkaContainer = StartedKafkaContainer;
|
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.d.ts
CHANGED