testcontainers 9.2.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/bound-ports.d.ts +12 -0
- package/dist/src/bound-ports.js +50 -0
- package/dist/src/clock.d.ts +7 -0
- package/dist/src/clock.js +9 -0
- package/dist/src/docker/docker-client-config.d.ts +10 -0
- package/dist/src/docker/docker-client-config.js +66 -0
- package/dist/src/docker/docker-client.d.ts +24 -0
- package/dist/src/docker/docker-client.js +198 -0
- package/dist/src/docker/functions/container/attach-container.d.ts +3 -0
- package/dist/src/docker/functions/container/attach-container.js +25 -0
- package/dist/src/docker/functions/container/container-logs.d.ts +6 -0
- package/dist/src/docker/functions/container/container-logs.js +32 -0
- package/dist/src/docker/functions/container/create-container.d.ts +30 -0
- package/dist/src/docker/functions/container/create-container.js +114 -0
- package/dist/src/docker/functions/container/exec-container.d.ts +9 -0
- package/dist/src/docker/functions/container/exec-container.js +59 -0
- package/dist/src/docker/functions/container/get-container.d.ts +3 -0
- package/dist/src/docker/functions/container/get-container.js +49 -0
- package/dist/src/docker/functions/container/inspect-container.d.ts +19 -0
- package/dist/src/docker/functions/container/inspect-container.js +67 -0
- package/dist/src/docker/functions/container/list-containers.d.ts +2 -0
- package/dist/src/docker/functions/container/list-containers.js +25 -0
- package/dist/src/docker/functions/container/put-container-archive.d.ts +9 -0
- package/dist/src/docker/functions/container/put-container-archive.js +23 -0
- package/dist/src/docker/functions/container/remove-container.d.ts +5 -0
- package/dist/src/docker/functions/container/remove-container.js +23 -0
- package/dist/src/docker/functions/container/restart-container.d.ts +5 -0
- package/dist/src/docker/functions/container/restart-container.js +23 -0
- package/dist/src/docker/functions/container/start-container.d.ts +2 -0
- package/dist/src/docker/functions/container/start-container.js +23 -0
- package/dist/src/docker/functions/container/stop-container.d.ts +5 -0
- package/dist/src/docker/functions/container/stop-container.js +29 -0
- package/dist/src/docker/functions/create-labels.d.ts +3 -0
- package/dist/src/docker/functions/create-labels.js +17 -0
- package/dist/src/docker/functions/demux-stream.d.ts +3 -0
- package/dist/src/docker/functions/demux-stream.js +32 -0
- package/dist/src/docker/functions/get-info.d.ts +11 -0
- package/dist/src/docker/functions/get-info.js +38 -0
- package/dist/src/docker/functions/image/build-image.d.ts +13 -0
- package/dist/src/docker/functions/image/build-image.js +76 -0
- package/dist/src/docker/functions/image/image-exists.d.ts +3 -0
- package/dist/src/docker/functions/image/image-exists.js +34 -0
- package/dist/src/docker/functions/image/list-images.d.ts +3 -0
- package/dist/src/docker/functions/image/list-images.js +34 -0
- package/dist/src/docker/functions/image/pull-image.d.ts +7 -0
- package/dist/src/docker/functions/image/pull-image.js +41 -0
- package/dist/src/docker/functions/network/connect-network.d.ts +6 -0
- package/dist/src/docker/functions/network/connect-network.js +27 -0
- package/dist/src/docker/functions/network/create-network.d.ts +16 -0
- package/dist/src/docker/functions/network/create-network.js +38 -0
- package/dist/src/docker/functions/network/remove-network.d.ts +1 -0
- package/dist/src/docker/functions/network/remove-network.js +30 -0
- package/dist/src/docker/functions/run-in-container.d.ts +2 -0
- package/dist/src/docker/functions/run-in-container.js +39 -0
- package/dist/src/docker/get-remote-docker-unix-socket-path.d.ts +5 -0
- package/dist/src/docker/get-remote-docker-unix-socket-path.js +17 -0
- package/dist/src/docker/lookup-host-ips.d.ts +5 -0
- package/dist/src/docker/lookup-host-ips.js +26 -0
- package/dist/src/docker/pull-stream-parser.d.ts +11 -0
- package/dist/src/docker/pull-stream-parser.js +63 -0
- package/dist/src/docker/rootless-unix-socket-strategy.d.ts +16 -0
- package/dist/src/docker/rootless-unix-socket-strategy.js +69 -0
- package/dist/src/docker/session-id.d.ts +1 -0
- package/dist/src/docker/session-id.js +5 -0
- package/dist/src/docker/types.d.ts +79 -0
- package/dist/src/docker/types.js +2 -0
- package/dist/src/docker-compose/default-docker-compose-options.d.ts +3 -0
- package/dist/src/docker-compose/default-docker-compose-options.js +37 -0
- package/dist/src/docker-compose/docker-compose-options.d.ts +9 -0
- package/dist/src/docker-compose/docker-compose-options.js +2 -0
- package/dist/src/docker-compose/functions/container-name-resolver.d.ts +1 -0
- package/dist/src/docker-compose/functions/container-name-resolver.js +15 -0
- package/dist/src/docker-compose/functions/docker-compose-down.d.ts +3 -0
- package/dist/src/docker-compose/functions/docker-compose-down.js +39 -0
- package/dist/src/docker-compose/functions/docker-compose-stop.d.ts +2 -0
- package/dist/src/docker-compose/functions/docker-compose-stop.js +29 -0
- package/dist/src/docker-compose/functions/docker-compose-up.d.ts +2 -0
- package/dist/src/docker-compose/functions/docker-compose-up.js +41 -0
- package/dist/src/docker-compose-environment/docker-compose-environment.d.ts +25 -0
- package/dist/src/docker-compose-environment/docker-compose-environment.js +134 -0
- package/dist/src/docker-compose-environment/downed-docker-compose-environment.d.ts +2 -0
- package/dist/src/docker-compose-environment/downed-docker-compose-environment.js +6 -0
- package/dist/src/docker-compose-environment/started-docker-compose-environment.d.ts +15 -0
- package/dist/src/docker-compose-environment/started-docker-compose-environment.js +46 -0
- package/dist/src/docker-compose-environment/stopped-docker-compose-environment.d.ts +8 -0
- package/dist/src/docker-compose-environment/stopped-docker-compose-environment.js +27 -0
- package/dist/src/docker-image-name.d.ts +15 -0
- package/dist/src/docker-image-name.js +63 -0
- package/dist/src/dockerfile-parser.d.ts +3 -0
- package/dist/src/dockerfile-parser.js +39 -0
- package/dist/src/generic-container/generic-container-builder.d.ts +18 -0
- package/dist/src/generic-container/generic-container-builder.js +98 -0
- package/dist/src/generic-container/generic-container.d.ts +77 -0
- package/dist/src/generic-container/generic-container.js +312 -0
- package/dist/src/generic-container/started-generic-container.d.ts +31 -0
- package/dist/src/generic-container/started-generic-container.js +97 -0
- package/dist/src/generic-container/stopped-generic-container.d.ts +3 -0
- package/dist/src/generic-container/stopped-generic-container.js +6 -0
- package/dist/src/hash.d.ts +1 -0
- package/dist/src/hash.js +11 -0
- package/dist/src/http-wait-strategy.d.ts +27 -0
- package/dist/src/http-wait-strategy.js +113 -0
- package/dist/src/images.d.ts +2 -0
- package/dist/src/images.js +6 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.js +54 -0
- package/dist/src/labels.d.ts +5 -0
- package/dist/src/labels.js +8 -0
- package/dist/src/logger.d.ts +36 -0
- package/dist/src/logger.js +61 -0
- package/dist/src/modules/abstract-started-container.d.ts +21 -0
- package/dist/src/modules/abstract-started-container.js +59 -0
- package/dist/src/modules/arangodb/arangodb-container.d.ts +19 -0
- package/dist/src/modules/arangodb/arangodb-container.js +60 -0
- package/dist/src/modules/elasticsearch/elasticsearch-container.d.ts +12 -0
- package/dist/src/modules/elasticsearch/elasticsearch-container.js +43 -0
- package/dist/src/modules/kafka/kafka-container.d.ts +46 -0
- package/dist/src/modules/kafka/kafka-container.js +172 -0
- package/dist/src/modules/mongodb/mongodb-container.d.ts +19 -0
- package/dist/src/modules/mongodb/mongodb-container.js +85 -0
- package/dist/src/modules/mysql/mysql-container.d.ts +29 -0
- package/dist/src/modules/mysql/mysql-container.js +102 -0
- package/dist/src/modules/nats/nats-container.d.ts +55 -0
- package/dist/src/modules/nats/nats-container.js +97 -0
- package/dist/src/modules/neo4j/neo4j-container.d.ts +23 -0
- package/dist/src/modules/neo4j/neo4j-container.js +82 -0
- package/dist/src/modules/postgresql/postgresql-container.d.ts +28 -0
- package/dist/src/modules/postgresql/postgresql-container.js +87 -0
- package/dist/src/network.d.ts +17 -0
- package/dist/src/network.js +54 -0
- package/dist/src/port-check.d.ts +17 -0
- package/dist/src/port-check.js +84 -0
- package/dist/src/port-forwarder.d.ts +17 -0
- package/dist/src/port-forwarder.js +81 -0
- package/dist/src/port-generator.d.ts +15 -0
- package/dist/src/port-generator.js +51 -0
- package/dist/src/port.d.ts +10 -0
- package/dist/src/port.js +47 -0
- package/dist/src/pull-policy.d.ts +9 -0
- package/dist/src/pull-policy.js +15 -0
- package/dist/src/reaper.d.ts +14 -0
- package/dist/src/reaper.js +141 -0
- package/dist/src/registry-auth-locator/auths.d.ts +8 -0
- package/dist/src/registry-auth-locator/auths.js +56 -0
- package/dist/src/registry-auth-locator/cred-helpers.d.ts +6 -0
- package/dist/src/registry-auth-locator/cred-helpers.js +15 -0
- package/dist/src/registry-auth-locator/credential-provider.d.ts +10 -0
- package/dist/src/registry-auth-locator/credential-provider.js +83 -0
- package/dist/src/registry-auth-locator/creds-store.d.ts +6 -0
- package/dist/src/registry-auth-locator/creds-store.js +15 -0
- package/dist/src/registry-auth-locator/get-auth-config.d.ts +2 -0
- package/dist/src/registry-auth-locator/get-auth-config.js +65 -0
- package/dist/src/registry-auth-locator/registry-auth-locator.d.ts +6 -0
- package/dist/src/registry-auth-locator/registry-auth-locator.js +2 -0
- package/dist/src/registry-auth-locator/registry-matches.d.ts +1 -0
- package/dist/src/registry-auth-locator/registry-matches.js +5 -0
- package/dist/src/registry-auth-locator/types.d.ts +23 -0
- package/dist/src/registry-auth-locator/types.js +2 -0
- package/dist/src/retry-strategy.d.ts +17 -0
- package/dist/src/retry-strategy.js +46 -0
- package/dist/src/startup-check-strategy.d.ts +7 -0
- package/dist/src/startup-check-strategy.js +30 -0
- package/dist/src/stream-utils.d.ts +6 -0
- package/dist/src/stream-utils.js +46 -0
- package/dist/src/system-info.d.ts +17 -0
- package/dist/src/system-info.js +51 -0
- package/dist/src/test-container.d.ts +66 -0
- package/dist/src/test-container.js +2 -0
- package/dist/src/test-containers.d.ts +3 -0
- package/dist/src/test-containers.js +22 -0
- package/dist/src/type-guards.d.ts +1 -0
- package/dist/src/type-guards.js +7 -0
- package/dist/src/uuid.d.ts +6 -0
- package/dist/src/uuid.js +13 -0
- package/dist/src/wait-for-container.d.ts +4 -0
- package/dist/src/wait-for-container.js +34 -0
- package/dist/src/wait-strategy.d.ts +32 -0
- package/dist/src/wait-strategy.js +137 -0
- package/dist/src/wait.d.ts +7 -0
- package/dist/src/wait.js +17 -0
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { GenericContainer } from "../../generic-container/generic-container";
|
|
2
|
+
import { StartedTestContainer } from "../../test-container";
|
|
3
|
+
import { AbstractStartedContainer } from "../abstract-started-container";
|
|
4
|
+
export declare class PostgreSqlContainer extends GenericContainer {
|
|
5
|
+
private database;
|
|
6
|
+
private username;
|
|
7
|
+
private password;
|
|
8
|
+
constructor(image?: string);
|
|
9
|
+
withDatabase(database: string): this;
|
|
10
|
+
withUsername(username: string): this;
|
|
11
|
+
withPassword(password: string): this;
|
|
12
|
+
start(): Promise<StartedPostgreSqlContainer>;
|
|
13
|
+
}
|
|
14
|
+
export declare class StartedPostgreSqlContainer extends AbstractStartedContainer {
|
|
15
|
+
private readonly database;
|
|
16
|
+
private readonly username;
|
|
17
|
+
private readonly password;
|
|
18
|
+
private readonly port;
|
|
19
|
+
constructor(startedTestContainer: StartedTestContainer, database: string, username: string, password: string);
|
|
20
|
+
getPort(): number;
|
|
21
|
+
getDatabase(): string;
|
|
22
|
+
getUsername(): string;
|
|
23
|
+
getPassword(): string;
|
|
24
|
+
/**
|
|
25
|
+
* @returns A connection URI in the form of `postgres[ql]://[username[:password]@][host[:port],]/database`
|
|
26
|
+
*/
|
|
27
|
+
getConnectionUri(): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
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.StartedPostgreSqlContainer = exports.PostgreSqlContainer = void 0;
|
|
13
|
+
const generic_container_1 = require("../../generic-container/generic-container");
|
|
14
|
+
const abstract_started_container_1 = require("../abstract-started-container");
|
|
15
|
+
const wait_1 = require("../../wait");
|
|
16
|
+
const POSTGRES_PORT = 5432;
|
|
17
|
+
class PostgreSqlContainer extends generic_container_1.GenericContainer {
|
|
18
|
+
constructor(image = "postgres:13.3-alpine") {
|
|
19
|
+
super(image);
|
|
20
|
+
this.database = "test";
|
|
21
|
+
this.username = "test";
|
|
22
|
+
this.password = "test";
|
|
23
|
+
}
|
|
24
|
+
withDatabase(database) {
|
|
25
|
+
this.database = database;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
withUsername(username) {
|
|
29
|
+
this.username = username;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
withPassword(password) {
|
|
33
|
+
this.password = password;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
start() {
|
|
37
|
+
const _super = Object.create(null, {
|
|
38
|
+
start: { get: () => super.start }
|
|
39
|
+
});
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
this.withExposedPorts(...(this.hasExposedPorts ? this.ports : [POSTGRES_PORT]))
|
|
42
|
+
.withEnvironment({
|
|
43
|
+
POSTGRES_DB: this.database,
|
|
44
|
+
POSTGRES_USER: this.username,
|
|
45
|
+
POSTGRES_PASSWORD: this.password,
|
|
46
|
+
})
|
|
47
|
+
.withWaitStrategy(wait_1.Wait.forLogMessage(/.*database system is ready to accept connections.*/, 2))
|
|
48
|
+
.withStartupTimeout(120000);
|
|
49
|
+
return new StartedPostgreSqlContainer(yield _super.start.call(this), this.database, this.username, this.password);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.PostgreSqlContainer = PostgreSqlContainer;
|
|
54
|
+
class StartedPostgreSqlContainer extends abstract_started_container_1.AbstractStartedContainer {
|
|
55
|
+
constructor(startedTestContainer, database, username, password) {
|
|
56
|
+
super(startedTestContainer);
|
|
57
|
+
this.database = database;
|
|
58
|
+
this.username = username;
|
|
59
|
+
this.password = password;
|
|
60
|
+
this.port = startedTestContainer.getMappedPort(5432);
|
|
61
|
+
}
|
|
62
|
+
getPort() {
|
|
63
|
+
return this.port;
|
|
64
|
+
}
|
|
65
|
+
getDatabase() {
|
|
66
|
+
return this.database;
|
|
67
|
+
}
|
|
68
|
+
getUsername() {
|
|
69
|
+
return this.username;
|
|
70
|
+
}
|
|
71
|
+
getPassword() {
|
|
72
|
+
return this.password;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @returns A connection URI in the form of `postgres[ql]://[username[:password]@][host[:port],]/database`
|
|
76
|
+
*/
|
|
77
|
+
getConnectionUri() {
|
|
78
|
+
const url = new URL("", "postgres://");
|
|
79
|
+
url.hostname = this.getHost();
|
|
80
|
+
url.port = this.getPort().toString();
|
|
81
|
+
url.pathname = this.getDatabase();
|
|
82
|
+
url.username = this.getUsername();
|
|
83
|
+
url.password = this.getPassword();
|
|
84
|
+
return url.toString();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.StartedPostgreSqlContainer = StartedPostgreSqlContainer;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Uuid } from "./uuid";
|
|
2
|
+
import { CreateNetworkOptions } from "./docker/functions/network/create-network";
|
|
3
|
+
export declare class Network {
|
|
4
|
+
private readonly createNetworkOptions;
|
|
5
|
+
constructor(createNetworkOptions?: Partial<CreateNetworkOptions>, uuid?: Uuid);
|
|
6
|
+
start(): Promise<StartedNetwork>;
|
|
7
|
+
}
|
|
8
|
+
export declare class StartedNetwork {
|
|
9
|
+
private readonly id;
|
|
10
|
+
private readonly options;
|
|
11
|
+
constructor(id: string, options: CreateNetworkOptions);
|
|
12
|
+
getId(): string;
|
|
13
|
+
getName(): string;
|
|
14
|
+
stop(): Promise<StoppedNetwork>;
|
|
15
|
+
}
|
|
16
|
+
export declare class StoppedNetwork {
|
|
17
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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.StoppedNetwork = exports.StartedNetwork = exports.Network = void 0;
|
|
13
|
+
const uuid_1 = require("./uuid");
|
|
14
|
+
const logger_1 = require("./logger");
|
|
15
|
+
const reaper_1 = require("./reaper");
|
|
16
|
+
const create_network_1 = require("./docker/functions/network/create-network");
|
|
17
|
+
const remove_network_1 = require("./docker/functions/network/remove-network");
|
|
18
|
+
class Network {
|
|
19
|
+
constructor(createNetworkOptions = {}, uuid = new uuid_1.RandomUuid()) {
|
|
20
|
+
this.createNetworkOptions = Object.assign({ name: uuid.nextUuid(), driver: "bridge", checkDuplicate: true, internal: false, attachable: false, ingress: false, enableIPv6: false }, createNetworkOptions);
|
|
21
|
+
}
|
|
22
|
+
start() {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
yield reaper_1.ReaperInstance.getInstance();
|
|
25
|
+
const id = yield (0, create_network_1.createNetwork)(this.createNetworkOptions);
|
|
26
|
+
logger_1.log.info(`Started network with ID: ${id}`);
|
|
27
|
+
return new StartedNetwork(id, this.createNetworkOptions);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.Network = Network;
|
|
32
|
+
class StartedNetwork {
|
|
33
|
+
constructor(id, options) {
|
|
34
|
+
this.id = id;
|
|
35
|
+
this.options = options;
|
|
36
|
+
}
|
|
37
|
+
getId() {
|
|
38
|
+
return this.id;
|
|
39
|
+
}
|
|
40
|
+
getName() {
|
|
41
|
+
return this.options.name;
|
|
42
|
+
}
|
|
43
|
+
stop() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
logger_1.log.info(`Stopping network with ID: ${this.id}`);
|
|
46
|
+
yield (0, remove_network_1.removeNetwork)(this.id);
|
|
47
|
+
return new StoppedNetwork();
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.StartedNetwork = StartedNetwork;
|
|
52
|
+
class StoppedNetwork {
|
|
53
|
+
}
|
|
54
|
+
exports.StoppedNetwork = StoppedNetwork;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Dockerode from "dockerode";
|
|
2
|
+
export interface PortCheck {
|
|
3
|
+
isBound(port: number): Promise<boolean>;
|
|
4
|
+
}
|
|
5
|
+
export declare class HostPortCheck implements PortCheck {
|
|
6
|
+
private readonly host;
|
|
7
|
+
constructor(host: string);
|
|
8
|
+
isBound(port: number): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare class InternalPortCheck implements PortCheck {
|
|
11
|
+
private readonly container;
|
|
12
|
+
private isDistroless;
|
|
13
|
+
private commandOutputs;
|
|
14
|
+
constructor(container: Dockerode.Container);
|
|
15
|
+
isBound(port: number): Promise<boolean>;
|
|
16
|
+
private commandOutputsKey;
|
|
17
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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.InternalPortCheck = exports.HostPortCheck = void 0;
|
|
13
|
+
const net_1 = require("net");
|
|
14
|
+
const exec_container_1 = require("./docker/functions/container/exec-container");
|
|
15
|
+
const logger_1 = require("./logger");
|
|
16
|
+
class HostPortCheck {
|
|
17
|
+
constructor(host) {
|
|
18
|
+
this.host = host;
|
|
19
|
+
}
|
|
20
|
+
isBound(port) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const socket = new net_1.Socket();
|
|
23
|
+
socket
|
|
24
|
+
.setTimeout(1000)
|
|
25
|
+
.on("error", () => {
|
|
26
|
+
socket.destroy();
|
|
27
|
+
resolve(false);
|
|
28
|
+
})
|
|
29
|
+
.on("timeout", () => {
|
|
30
|
+
socket.destroy();
|
|
31
|
+
resolve(false);
|
|
32
|
+
})
|
|
33
|
+
.connect(port, this.host, () => {
|
|
34
|
+
socket.end();
|
|
35
|
+
resolve(true);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.HostPortCheck = HostPortCheck;
|
|
41
|
+
class InternalPortCheck {
|
|
42
|
+
constructor(container) {
|
|
43
|
+
this.container = container;
|
|
44
|
+
this.isDistroless = false;
|
|
45
|
+
this.commandOutputs = new Set();
|
|
46
|
+
}
|
|
47
|
+
isBound(port) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const portHex = port.toString(16).padStart(4, "0");
|
|
50
|
+
const commands = [
|
|
51
|
+
["/bin/sh", "-c", `cat /proc/net/tcp* | awk '{print $2}' | grep -i :${portHex}`],
|
|
52
|
+
["/bin/sh", "-c", `nc -vz -w 1 localhost ${port}`],
|
|
53
|
+
["/bin/bash", "-c", `</dev/tcp/localhost/${port}`],
|
|
54
|
+
];
|
|
55
|
+
const commandResults = yield Promise.all(commands.map((command) => (0, exec_container_1.execContainer)(this.container, command, { stdin: true, detach: false, tty: true }, false)));
|
|
56
|
+
const isBound = commandResults.some((result) => result.exitCode === 0);
|
|
57
|
+
if (!isBound && logger_1.log.enabled()) {
|
|
58
|
+
const shellExists = commandResults.some((result) => result.exitCode !== 126);
|
|
59
|
+
if (!shellExists) {
|
|
60
|
+
if (!this.isDistroless) {
|
|
61
|
+
this.isDistroless = true;
|
|
62
|
+
logger_1.log.error(`The HostPortWaitStrategy will not work on a distroless image, use an alternate wait strategy for container ${this.container.id}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
commandResults
|
|
67
|
+
.map((result) => (Object.assign(Object.assign({}, result), { output: result.output.trim() })))
|
|
68
|
+
.filter((result) => result.exitCode !== 126 && result.output.length > 0)
|
|
69
|
+
.forEach((result) => {
|
|
70
|
+
if (!this.commandOutputs.has(this.commandOutputsKey(result.output))) {
|
|
71
|
+
logger_1.log.trace(`Port check result for container ${this.container.id} exit code ${result.exitCode}: ${result.output}`);
|
|
72
|
+
this.commandOutputs.add(this.commandOutputsKey(result.output));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return isBound;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
commandOutputsKey(output) {
|
|
81
|
+
return `${this.container.id}:${output}`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.InternalPortCheck = InternalPortCheck;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SshConnection } from "ssh-remote-port-forward";
|
|
2
|
+
import { StartedTestContainer } from "./test-container";
|
|
3
|
+
export declare class PortForwarder {
|
|
4
|
+
private readonly sshConnection;
|
|
5
|
+
private readonly container;
|
|
6
|
+
constructor(sshConnection: SshConnection, container: StartedTestContainer);
|
|
7
|
+
exposeHostPort(port: number): Promise<void>;
|
|
8
|
+
getNetworkId(): string;
|
|
9
|
+
getIpAddress(): string;
|
|
10
|
+
private getNetworkName;
|
|
11
|
+
}
|
|
12
|
+
export declare class PortForwarderInstance {
|
|
13
|
+
private static instance;
|
|
14
|
+
static isRunning(): boolean;
|
|
15
|
+
static getInstance(): Promise<PortForwarder>;
|
|
16
|
+
private static createInstance;
|
|
17
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
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.PortForwarderInstance = exports.PortForwarder = void 0;
|
|
13
|
+
const ssh_remote_port_forward_1 = require("ssh-remote-port-forward");
|
|
14
|
+
const logger_1 = require("./logger");
|
|
15
|
+
const generic_container_1 = require("./generic-container/generic-container");
|
|
16
|
+
const uuid_1 = require("./uuid");
|
|
17
|
+
const session_id_1 = require("./docker/session-id");
|
|
18
|
+
const docker_client_1 = require("./docker/docker-client");
|
|
19
|
+
const images_1 = require("./images");
|
|
20
|
+
class PortForwarder {
|
|
21
|
+
constructor(sshConnection, container) {
|
|
22
|
+
this.sshConnection = sshConnection;
|
|
23
|
+
this.container = container;
|
|
24
|
+
}
|
|
25
|
+
exposeHostPort(port) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
logger_1.log.info(`Exposing host port ${port}`);
|
|
28
|
+
yield this.sshConnection.remoteForward("localhost", port);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
getNetworkId() {
|
|
32
|
+
return this.container.getNetworkId(this.getNetworkName());
|
|
33
|
+
}
|
|
34
|
+
getIpAddress() {
|
|
35
|
+
return this.container.getIpAddress(this.getNetworkName());
|
|
36
|
+
}
|
|
37
|
+
getNetworkName() {
|
|
38
|
+
return this.container.getNetworkNames()[0];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.PortForwarder = PortForwarder;
|
|
42
|
+
class PortForwarderInstance {
|
|
43
|
+
static isRunning() {
|
|
44
|
+
return this.instance !== undefined;
|
|
45
|
+
}
|
|
46
|
+
static getInstance() {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
if (!this.instance) {
|
|
49
|
+
this.instance = this.createInstance();
|
|
50
|
+
}
|
|
51
|
+
return this.instance;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
static createInstance() {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
logger_1.log.debug(`Creating new Port Forwarder`);
|
|
57
|
+
const username = "root";
|
|
58
|
+
const password = new uuid_1.RandomUuid().nextUuid();
|
|
59
|
+
const containerPort = process.env["TESTCONTAINERS_SSHD_PORT"]
|
|
60
|
+
? { container: 22, host: Number(process.env["TESTCONTAINERS_SSHD_PORT"]) }
|
|
61
|
+
: 22;
|
|
62
|
+
const container = yield new generic_container_1.GenericContainer(images_1.SSHD_IMAGE)
|
|
63
|
+
.withName(`testcontainers-port-forwarder-${session_id_1.sessionId}`)
|
|
64
|
+
.withExposedPorts(containerPort)
|
|
65
|
+
.withEnvironment({ PASSWORD: password })
|
|
66
|
+
.withCommand([
|
|
67
|
+
"sh",
|
|
68
|
+
"-c",
|
|
69
|
+
`echo "${username}:$PASSWORD" | chpasswd && /usr/sbin/sshd -D -o PermitRootLogin=yes -o AddressFamily=inet -o GatewayPorts=yes -o AllowAgentForwarding=yes -o AllowTcpForwarding=yes -o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostkeyAlgorithms=+ssh-rsa`,
|
|
70
|
+
])
|
|
71
|
+
.start();
|
|
72
|
+
const host = (yield (0, docker_client_1.dockerClient)()).host;
|
|
73
|
+
const port = container.getMappedPort(22);
|
|
74
|
+
logger_1.log.debug(`Connecting to Port Forwarder on ${host}:${port}`);
|
|
75
|
+
const connection = yield (0, ssh_remote_port_forward_1.createSshConnection)({ host, port, username, password });
|
|
76
|
+
connection.unref();
|
|
77
|
+
return new PortForwarder(connection, container);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.PortForwarderInstance = PortForwarderInstance;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PortGenerator {
|
|
2
|
+
generatePort(): Promise<number>;
|
|
3
|
+
}
|
|
4
|
+
export declare class RandomUniquePortGenerator implements PortGenerator {
|
|
5
|
+
private readonly portGenerator;
|
|
6
|
+
private static readonly assignedPorts;
|
|
7
|
+
constructor(portGenerator?: PortGenerator);
|
|
8
|
+
generatePort(): Promise<number>;
|
|
9
|
+
}
|
|
10
|
+
export declare class FixedPortGenerator implements PortGenerator {
|
|
11
|
+
private readonly ports;
|
|
12
|
+
private portIndex;
|
|
13
|
+
constructor(ports: number[]);
|
|
14
|
+
generatePort(): Promise<number>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
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.FixedPortGenerator = exports.RandomUniquePortGenerator = void 0;
|
|
16
|
+
const get_port_1 = __importDefault(require("get-port"));
|
|
17
|
+
class RandomPortGenerator {
|
|
18
|
+
generatePort() {
|
|
19
|
+
return (0, get_port_1.default)({ port: this.randomBetweenInclusive(10000, 65535) });
|
|
20
|
+
}
|
|
21
|
+
randomBetweenInclusive(min, max) {
|
|
22
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
class RandomUniquePortGenerator {
|
|
26
|
+
constructor(portGenerator = new RandomPortGenerator()) {
|
|
27
|
+
this.portGenerator = portGenerator;
|
|
28
|
+
}
|
|
29
|
+
generatePort() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
let port;
|
|
32
|
+
do {
|
|
33
|
+
port = yield this.portGenerator.generatePort();
|
|
34
|
+
} while (RandomUniquePortGenerator.assignedPorts.has(port));
|
|
35
|
+
RandomUniquePortGenerator.assignedPorts.add(port);
|
|
36
|
+
return port;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RandomUniquePortGenerator = RandomUniquePortGenerator;
|
|
41
|
+
RandomUniquePortGenerator.assignedPorts = new Set();
|
|
42
|
+
class FixedPortGenerator {
|
|
43
|
+
constructor(ports) {
|
|
44
|
+
this.ports = ports;
|
|
45
|
+
this.portIndex = 0;
|
|
46
|
+
}
|
|
47
|
+
generatePort() {
|
|
48
|
+
return Promise.resolve(this.ports[this.portIndex++]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.FixedPortGenerator = FixedPortGenerator;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HostIps } from "./docker/lookup-host-ips";
|
|
2
|
+
import { HostPortBindings } from "./docker/types";
|
|
3
|
+
export type PortWithBinding = {
|
|
4
|
+
container: number;
|
|
5
|
+
host: number;
|
|
6
|
+
};
|
|
7
|
+
export type PortWithOptionalBinding = number | PortWithBinding;
|
|
8
|
+
export declare const getContainerPort: (port: PortWithOptionalBinding) => number;
|
|
9
|
+
export declare const hasHostBinding: (port: PortWithOptionalBinding) => port is PortWithBinding;
|
|
10
|
+
export declare const resolveHostPortBinding: (hostIps: HostIps, hostPortBindings: HostPortBindings) => number;
|
package/dist/src/port.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.resolveHostPortBinding = exports.hasHostBinding = exports.getContainerPort = void 0;
|
|
27
|
+
const net = __importStar(require("net"));
|
|
28
|
+
const getContainerPort = (port) => typeof port === "number" ? port : port.container;
|
|
29
|
+
exports.getContainerPort = getContainerPort;
|
|
30
|
+
const hasHostBinding = (port) => {
|
|
31
|
+
return typeof port === "object" && port.host !== undefined;
|
|
32
|
+
};
|
|
33
|
+
exports.hasHostBinding = hasHostBinding;
|
|
34
|
+
const resolveHostPortBinding = (hostIps, hostPortBindings) => {
|
|
35
|
+
if (isDualStackIp(hostPortBindings)) {
|
|
36
|
+
return hostPortBindings[0].hostPort;
|
|
37
|
+
}
|
|
38
|
+
for (const { family } of hostIps) {
|
|
39
|
+
const hostPortBinding = hostPortBindings.find(({ hostIp }) => net.isIP(hostIp) === family);
|
|
40
|
+
if (hostPortBinding !== undefined) {
|
|
41
|
+
return hostPortBinding.hostPort;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
throw new Error("No host port found for host IP");
|
|
45
|
+
};
|
|
46
|
+
exports.resolveHostPortBinding = resolveHostPortBinding;
|
|
47
|
+
const isDualStackIp = (hostPortBindings) => hostPortBindings.length === 1 && hostPortBindings[0].hostIp === "";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AlwaysPullPolicy = exports.DefaultPullPolicy = void 0;
|
|
4
|
+
class DefaultPullPolicy {
|
|
5
|
+
shouldPull() {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.DefaultPullPolicy = DefaultPullPolicy;
|
|
10
|
+
class AlwaysPullPolicy {
|
|
11
|
+
shouldPull() {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.AlwaysPullPolicy = AlwaysPullPolicy;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Reaper {
|
|
2
|
+
addProject(projectName: string): void;
|
|
3
|
+
getContainerId(): string;
|
|
4
|
+
stop(): void;
|
|
5
|
+
}
|
|
6
|
+
export declare class ReaperInstance {
|
|
7
|
+
private static instance?;
|
|
8
|
+
static getInstance(): Promise<Reaper>;
|
|
9
|
+
static stopInstance(): Promise<void>;
|
|
10
|
+
private static isEnabled;
|
|
11
|
+
private static isPrivileged;
|
|
12
|
+
private static createDisabledInstance;
|
|
13
|
+
private static createRealInstance;
|
|
14
|
+
}
|