testcontainers 9.10.0 → 9.11.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.
Files changed (43) hide show
  1. package/dist/package.json +18 -16
  2. package/dist/src/docker/client/docker-client-types.d.ts +21 -0
  3. package/dist/src/docker/client/docker-client-types.js +2 -0
  4. package/dist/src/docker/client/docker-client.d.ts +1 -17
  5. package/dist/src/docker/client/docker-client.js +50 -23
  6. package/dist/src/docker/client/strategy/configuration-strategy.d.ts +1 -1
  7. package/dist/src/docker/client/strategy/configuration-strategy.js +2 -4
  8. package/dist/src/docker/client/strategy/docker-client-strategy.d.ts +1 -1
  9. package/dist/src/docker/client/strategy/npipe-socket-strategy.d.ts +1 -1
  10. package/dist/src/docker/client/strategy/npipe-socket-strategy.js +1 -5
  11. package/dist/src/docker/client/strategy/rootless-unix-socket-strategy.d.ts +1 -1
  12. package/dist/src/docker/client/strategy/rootless-unix-socket-strategy.js +1 -2
  13. package/dist/src/docker/client/strategy/testcontainers-host-strategy.d.ts +1 -1
  14. package/dist/src/docker/client/strategy/testcontainers-host-strategy.js +2 -7
  15. package/dist/src/docker/client/strategy/unix-socket-strategy.d.ts +1 -1
  16. package/dist/src/docker/client/strategy/unix-socket-strategy.js +1 -5
  17. package/dist/src/docker/functions/container/create-container.d.ts +1 -1
  18. package/dist/src/docker/functions/container/create-container.js +2 -2
  19. package/dist/src/docker/functions/create-labels.d.ts +1 -2
  20. package/dist/src/docker/functions/create-labels.js +2 -3
  21. package/dist/src/docker/functions/image/build-image.d.ts +2 -1
  22. package/dist/src/docker/functions/image/build-image.js +2 -2
  23. package/dist/src/docker/functions/network/create-network.d.ts +1 -1
  24. package/dist/src/docker/functions/network/create-network.js +2 -2
  25. package/dist/src/docker/remote-docker-unix-socket-path.d.ts +2 -2
  26. package/dist/src/docker/types.d.ts +3 -0
  27. package/dist/src/docker-compose-environment/docker-compose-environment.js +2 -2
  28. package/dist/src/file-lock.d.ts +1 -0
  29. package/dist/src/file-lock.js +47 -0
  30. package/dist/src/generic-container/generic-container-builder.d.ts +4 -1
  31. package/dist/src/generic-container/generic-container-builder.js +4 -5
  32. package/dist/src/generic-container/generic-container.d.ts +8 -4
  33. package/dist/src/generic-container/generic-container.js +75 -72
  34. package/dist/src/index.d.ts +1 -1
  35. package/dist/src/modules/selenium/selenium-container.js +11 -8
  36. package/dist/src/network.js +3 -3
  37. package/dist/src/port-forwarder.js +2 -2
  38. package/dist/src/reaper.d.ts +5 -14
  39. package/dist/src/reaper.js +124 -114
  40. package/dist/src/test-container.d.ts +2 -1
  41. package/package.json +18 -16
  42. package/dist/src/docker/session-id.d.ts +0 -1
  43. package/dist/src/docker/session-id.js +0 -5
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "testcontainers",
3
3
  "author": "Cristian Greco",
4
- "version": "9.10.0",
4
+ "version": "9.11.0",
5
5
  "main": "dist/src/index",
6
6
  "types": "dist/src/index",
7
7
  "keywords": [
@@ -46,46 +46,48 @@
46
46
  "docker-compose": "^0.24.1",
47
47
  "dockerode": "^3.3.5",
48
48
  "get-port": "^5.1.1",
49
- "node-fetch": "^2.6.11",
49
+ "node-fetch": "^2.6.12",
50
+ "proper-lockfile": "^4.1.2",
50
51
  "properties-reader": "^2.2.0",
51
52
  "ssh-remote-port-forward": "^1.0.4",
52
53
  "tar-fs": "^2.1.1",
53
54
  "tmp": "^0.2.1"
54
55
  },
55
56
  "devDependencies": {
56
- "@elastic/elasticsearch": "^7.17.0",
57
+ "@elastic/elasticsearch": "^7.17.11",
57
58
  "@types/async-lock": "^1.4.0",
58
59
  "@types/byline": "^4.2.33",
59
60
  "@types/debug": "4.1.8",
60
- "@types/jest": "^29.5.2",
61
- "@types/node": "^18.16.18",
61
+ "@types/jest": "^29.5.3",
62
+ "@types/node": "^18.16.19",
62
63
  "@types/node-fetch": "^2.6.4",
63
64
  "@types/pg": "^8.10.2",
65
+ "@types/proper-lockfile": "^4.1.2",
64
66
  "@types/properties-reader": "^2.1.1",
65
67
  "@types/selenium-webdriver": "^4.1.15",
66
68
  "@types/tar-fs": "^2.0.1",
67
69
  "@types/tmp": "^0.2.3",
68
- "@typescript-eslint/eslint-plugin": "^5.59.11",
69
- "@typescript-eslint/parser": "^5.59.11",
70
- "arangojs": "^8.3.0",
70
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
71
+ "@typescript-eslint/parser": "^5.62.0",
72
+ "arangojs": "^8.4.0",
71
73
  "cross-env": "^7.0.3",
72
- "eslint": "^8.42.0",
74
+ "eslint": "^8.44.0",
73
75
  "eslint-config-prettier": "^8.8.0",
74
76
  "eslint-plugin-prettier": "^4.2.1",
75
77
  "husky": "^8.0.3",
76
- "jest": "^29.5.0",
78
+ "jest": "^29.6.1",
77
79
  "kafkajs": "^2.2.4",
78
- "lint-staged": "^13.2.2",
79
- "mongoose": "^6.11.2",
80
+ "lint-staged": "^13.2.3",
81
+ "mongoose": "^6.11.3",
80
82
  "mqtt": "^4.3.7",
81
83
  "mysql2": "^2.3.3",
82
- "nats": "^2.14.0",
83
- "neo4j-driver": "^5.9.1",
84
- "pg": "^8.11.0",
84
+ "nats": "^2.15.1",
85
+ "neo4j-driver": "^5.10.0",
86
+ "pg": "^8.11.1",
85
87
  "prettier": "^2.8.8",
86
88
  "rimraf": "^3.0.2",
87
89
  "selenium-webdriver": "^4.10.0",
88
- "ts-jest": "^29.1.0",
90
+ "ts-jest": "^29.1.1",
89
91
  "ts-node": "^10.9.1",
90
92
  "typescript": "^4.9.5",
91
93
  "wait-for-expect": "^3.0.2"
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import Dockerode, { DockerOptions } from "dockerode";
3
+ import { HostIps } from "../lookup-host-ips";
4
+ import { SystemInfo } from "../../system-info";
5
+ import { ContainerRuntime } from "../types";
6
+ export type DockerClient = PartialDockerClient & {
7
+ sessionId: string;
8
+ };
9
+ export type PartialDockerClient = DockerClientStrategyResult & {
10
+ dockerode: Dockerode;
11
+ host: string;
12
+ containerRuntime: ContainerRuntime;
13
+ hostIps: HostIps;
14
+ info: SystemInfo;
15
+ };
16
+ export type DockerClientStrategyResult = {
17
+ uri: string;
18
+ dockerOptions: DockerOptions;
19
+ composeEnvironment: NodeJS.ProcessEnv;
20
+ allowUserOverrides: boolean;
21
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,18 +1,2 @@
1
- /// <reference types="node" />
2
- import Dockerode from "dockerode";
3
- import { HostIps } from "../lookup-host-ips";
4
- import { SystemInfo } from "../../system-info";
5
- import { ContainerRuntime } from "../types";
6
- export type DockerClient = DockerClientStrategyResult & {
7
- host: string;
8
- containerRuntime: ContainerRuntime;
9
- hostIps: HostIps;
10
- info: SystemInfo;
11
- };
12
- export type DockerClientStrategyResult = {
13
- uri: string;
14
- dockerode: Dockerode;
15
- composeEnvironment: NodeJS.ProcessEnv;
16
- allowUserOverrides: boolean;
17
- };
1
+ import { DockerClient } from "./docker-client-types";
18
2
  export declare function getDockerClient(): Promise<DockerClient>;
@@ -8,8 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.getDockerClient = void 0;
16
+ const dockerode_1 = __importDefault(require("dockerode"));
13
17
  const logger_1 = require("../../logger");
14
18
  const lookup_host_ips_1 = require("../lookup-host-ips");
15
19
  const system_info_1 = require("../../system-info");
@@ -21,26 +25,31 @@ const configuration_strategy_1 = require("./strategy/configuration-strategy");
21
25
  const unix_socket_strategy_1 = require("./strategy/unix-socket-strategy");
22
26
  const npipe_socket_strategy_1 = require("./strategy/npipe-socket-strategy");
23
27
  const testcontainers_host_strategy_1 = require("./strategy/testcontainers-host-strategy");
28
+ const uuid_1 = require("../../uuid");
29
+ const file_lock_1 = require("../../file-lock");
30
+ const reaper_1 = require("../../reaper");
24
31
  let dockerClient;
32
+ const strategies = [
33
+ new testcontainers_host_strategy_1.TestcontainersHostStrategy(),
34
+ new configuration_strategy_1.ConfigurationStrategy(),
35
+ new unix_socket_strategy_1.UnixSocketStrategy(),
36
+ new rootless_unix_socket_strategy_1.RootlessUnixSocketStrategy(),
37
+ new npipe_socket_strategy_1.NpipeSocketStrategy(),
38
+ ];
25
39
  function getDockerClient() {
26
40
  return __awaiter(this, void 0, void 0, function* () {
27
41
  if (dockerClient) {
28
42
  return dockerClient;
29
43
  }
30
- const strategies = [
31
- new testcontainers_host_strategy_1.TestcontainersHostStrategy(),
32
- new configuration_strategy_1.ConfigurationStrategy(),
33
- new unix_socket_strategy_1.UnixSocketStrategy(),
34
- new rootless_unix_socket_strategy_1.RootlessUnixSocketStrategy(),
35
- new npipe_socket_strategy_1.NpipeSocketStrategy(),
36
- ];
37
44
  for (const strategy of strategies) {
38
45
  try {
39
- const dockerClient = yield tryToCreateDockerClient(strategy);
40
- if (dockerClient) {
41
- logDockerClient(strategy.getName(), dockerClient);
42
- return dockerClient;
46
+ const initialisedDockerClient = yield initialiseStrategy(strategy);
47
+ if (!initialisedDockerClient) {
48
+ continue;
43
49
  }
50
+ dockerClient = initialisedDockerClient;
51
+ logDockerClient(strategy.getName(), dockerClient);
52
+ return dockerClient;
44
53
  }
45
54
  catch (err) {
46
55
  logger_1.log.warn(`Docker client strategy "${strategy.getName()}" threw: "${err}"`);
@@ -50,30 +59,48 @@ function getDockerClient() {
50
59
  });
51
60
  }
52
61
  exports.getDockerClient = getDockerClient;
62
+ function initialiseStrategy(strategy) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ const partialDockerClient = yield tryToCreateDockerClient(strategy);
65
+ if (!partialDockerClient) {
66
+ return;
67
+ }
68
+ yield (0, file_lock_1.withFileLock)("tc.lock", () => __awaiter(this, void 0, void 0, function* () {
69
+ var _a;
70
+ const dockerode = new dockerode_1.default(partialDockerClient.dockerOptions);
71
+ const containers = yield dockerode.listContainers();
72
+ const reaperContainer = containers.find((container) => container.Labels["org.testcontainers.ryuk"] === "true");
73
+ const sessionId = (_a = reaperContainer === null || reaperContainer === void 0 ? void 0 : reaperContainer.Labels["org.testcontainers.session-id"]) !== null && _a !== void 0 ? _a : new uuid_1.RandomUuid().nextUuid();
74
+ const dockerOptions = Object.assign(Object.assign({}, partialDockerClient.dockerOptions), { headers: Object.assign(Object.assign({}, partialDockerClient.dockerOptions.headers), { "x-tc-sid": sessionId }) });
75
+ dockerClient = Object.assign(Object.assign({}, partialDockerClient), { sessionId,
76
+ dockerOptions, dockerode: new dockerode_1.default(dockerOptions) });
77
+ yield (0, reaper_1.startReaper)(dockerClient, sessionId, reaperContainer);
78
+ yield (0, reaper_1.registerSessionIdForCleanup)(sessionId);
79
+ }));
80
+ return dockerClient;
81
+ });
82
+ }
53
83
  function tryToCreateDockerClient(strategy) {
54
84
  return __awaiter(this, void 0, void 0, function* () {
55
85
  if (strategy.init) {
56
86
  yield strategy.init();
57
87
  }
58
88
  if (strategy.isApplicable()) {
59
- const { uri, dockerode, composeEnvironment, allowUserOverrides } = yield strategy.getDockerClient();
60
- logger_1.log.debug(`Testing Docker client strategy "${strategy.getName()}" with URI "${uri}"...`);
89
+ const dockerClientStrategyResult = yield strategy.getDockerClient();
90
+ logger_1.log.debug(`Testing Docker client strategy "${strategy.getName()}" with URI "${dockerClientStrategyResult.uri}"...`);
91
+ const dockerode = new dockerode_1.default(dockerClientStrategyResult.dockerOptions);
61
92
  if (yield isDockerDaemonReachable(dockerode)) {
62
93
  const info = yield (0, system_info_1.getSystemInfo)(dockerode);
63
- const containerRuntime = uri.includes("podman.sock") ? "podman" : "docker";
64
- const host = yield (0, resolve_host_1.resolveHost)(dockerode, containerRuntime, info.dockerInfo.indexServerAddress, uri, allowUserOverrides);
94
+ const containerRuntime = dockerClientStrategyResult.uri.includes("podman.sock")
95
+ ? "podman"
96
+ : "docker";
97
+ const host = yield (0, resolve_host_1.resolveHost)(dockerode, containerRuntime, info.dockerInfo.indexServerAddress, dockerClientStrategyResult.uri, dockerClientStrategyResult.allowUserOverrides);
65
98
  const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
66
- dockerClient = {
67
- uri,
68
- containerRuntime,
99
+ return Object.assign(Object.assign({}, dockerClientStrategyResult), { containerRuntime,
69
100
  host,
70
101
  hostIps,
71
- dockerode,
72
102
  info,
73
- composeEnvironment,
74
- allowUserOverrides,
75
- };
76
- return dockerClient;
103
+ dockerode });
77
104
  }
78
105
  else {
79
106
  logger_1.log.warn(`Docker client strategy "${strategy.getName()}" does not work`);
@@ -1,4 +1,4 @@
1
- import { DockerClientStrategyResult } from "../docker-client";
1
+ import { DockerClientStrategyResult } from "../docker-client-types";
2
2
  import { DockerClientStrategy } from "./docker-client-strategy";
3
3
  export declare class ConfigurationStrategy implements DockerClientStrategy {
4
4
  private dockerHost;
@@ -14,8 +14,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ConfigurationStrategy = void 0;
16
16
  const docker_client_config_1 = require("../docker-client-config");
17
- const dockerode_1 = __importDefault(require("dockerode"));
18
- const session_id_1 = require("../../session-id");
19
17
  const url_1 = require("url");
20
18
  const fs_1 = require("fs");
21
19
  const path_1 = __importDefault(require("path"));
@@ -32,7 +30,7 @@ class ConfigurationStrategy {
32
30
  }
33
31
  getDockerClient() {
34
32
  return __awaiter(this, void 0, void 0, function* () {
35
- const dockerOptions = { headers: { "x-tc-sid": session_id_1.sessionId } };
33
+ const dockerOptions = {};
36
34
  const { pathname, hostname, port } = new url_1.URL(this.dockerHost);
37
35
  if (hostname !== "") {
38
36
  dockerOptions.host = hostname;
@@ -48,7 +46,7 @@ class ConfigurationStrategy {
48
46
  }
49
47
  return {
50
48
  uri: this.dockerHost,
51
- dockerode: new dockerode_1.default(dockerOptions),
49
+ dockerOptions,
52
50
  composeEnvironment: {
53
51
  DOCKER_HOST: this.dockerHost,
54
52
  DOCKER_TLS_VERIFY: this.dockerTlsVerify,
@@ -1,4 +1,4 @@
1
- import { DockerClientStrategyResult } from "../docker-client";
1
+ import { DockerClientStrategyResult } from "../docker-client-types";
2
2
  export interface DockerClientStrategy {
3
3
  init?(): Promise<void>;
4
4
  isApplicable(): boolean;
@@ -1,4 +1,4 @@
1
- import { DockerClientStrategyResult } from "../docker-client";
1
+ import { DockerClientStrategyResult } from "../docker-client-types";
2
2
  import { DockerClientStrategy } from "./docker-client-strategy";
3
3
  export declare class NpipeSocketStrategy implements DockerClientStrategy {
4
4
  getDockerClient(): Promise<DockerClientStrategyResult>;
@@ -8,18 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.NpipeSocketStrategy = void 0;
16
- const dockerode_1 = __importDefault(require("dockerode"));
17
13
  class NpipeSocketStrategy {
18
14
  getDockerClient() {
19
15
  return __awaiter(this, void 0, void 0, function* () {
20
16
  return {
21
17
  uri: "npipe:////./pipe/docker_engine",
22
- dockerode: new dockerode_1.default({ socketPath: "//./pipe/docker_engine" }),
18
+ dockerOptions: { socketPath: "//./pipe/docker_engine" },
23
19
  composeEnvironment: {},
24
20
  allowUserOverrides: true,
25
21
  };
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { DockerClientStrategyResult } from "../docker-client";
2
+ import { DockerClientStrategyResult } from "../docker-client-types";
3
3
  import { DockerClientStrategy } from "./docker-client-strategy";
4
4
  export declare class RootlessUnixSocketStrategy implements DockerClientStrategy {
5
5
  private readonly platform;
@@ -17,7 +17,6 @@ const type_guards_1 = require("../../../type-guards");
17
17
  const fs_1 = require("fs");
18
18
  const path_1 = __importDefault(require("path"));
19
19
  const os_1 = __importDefault(require("os"));
20
- const dockerode_1 = __importDefault(require("dockerode"));
21
20
  class RootlessUnixSocketStrategy {
22
21
  constructor(platform = process.platform, env = process.env) {
23
22
  this.platform = platform;
@@ -62,7 +61,7 @@ class RootlessUnixSocketStrategy {
62
61
  return __awaiter(this, void 0, void 0, function* () {
63
62
  return {
64
63
  uri: `unix://${this.socketPath}`,
65
- dockerode: new dockerode_1.default({ socketPath: this.socketPath }),
64
+ dockerOptions: { socketPath: this.socketPath },
66
65
  composeEnvironment: {},
67
66
  allowUserOverrides: true,
68
67
  };
@@ -1,4 +1,4 @@
1
- import { DockerClientStrategyResult } from "../docker-client";
1
+ import { DockerClientStrategyResult } from "../docker-client-types";
2
2
  import { DockerClientStrategy } from "./docker-client-strategy";
3
3
  export declare class TestcontainersHostStrategy implements DockerClientStrategy {
4
4
  private host;
@@ -8,14 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.TestcontainersHostStrategy = void 0;
16
13
  const docker_client_config_1 = require("../docker-client-config");
17
- const dockerode_1 = __importDefault(require("dockerode"));
18
- const session_id_1 = require("../../session-id");
19
14
  const url_1 = require("url");
20
15
  class TestcontainersHostStrategy {
21
16
  init() {
@@ -28,13 +23,13 @@ class TestcontainersHostStrategy {
28
23
  }
29
24
  getDockerClient() {
30
25
  return __awaiter(this, void 0, void 0, function* () {
31
- const dockerOptions = { headers: { "x-tc-sid": session_id_1.sessionId } };
26
+ const dockerOptions = {};
32
27
  const { hostname, port } = new url_1.URL(this.host);
33
28
  dockerOptions.host = hostname;
34
29
  dockerOptions.port = port;
35
30
  return {
36
31
  uri: this.host,
37
- dockerode: new dockerode_1.default(dockerOptions),
32
+ dockerOptions,
38
33
  composeEnvironment: {
39
34
  DOCKER_HOST: this.host,
40
35
  },
@@ -1,4 +1,4 @@
1
- import { DockerClientStrategyResult } from "../docker-client";
1
+ import { DockerClientStrategyResult } from "../docker-client-types";
2
2
  import { DockerClientStrategy } from "./docker-client-strategy";
3
3
  export declare class UnixSocketStrategy implements DockerClientStrategy {
4
4
  getDockerClient(): Promise<DockerClientStrategyResult>;
@@ -8,19 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.UnixSocketStrategy = void 0;
16
- const dockerode_1 = __importDefault(require("dockerode"));
17
13
  const fs_1 = require("fs");
18
14
  class UnixSocketStrategy {
19
15
  getDockerClient() {
20
16
  return __awaiter(this, void 0, void 0, function* () {
21
17
  return {
22
18
  uri: "unix:///var/run/docker.sock",
23
- dockerode: new dockerode_1.default({ socketPath: "/var/run/docker.sock" }),
19
+ dockerOptions: { socketPath: "/var/run/docker.sock" },
24
20
  composeEnvironment: {},
25
21
  allowUserOverrides: true,
26
22
  };
@@ -28,4 +28,4 @@ export type CreateContainerOptions = {
28
28
  resourcesQuota?: ResourcesQuota;
29
29
  sharedMemorySize?: number;
30
30
  };
31
- export declare const createContainer: (options: CreateContainerOptions) => Promise<Dockerode.Container>;
31
+ export declare const createContainer: (sessionId: string, options: CreateContainerOptions) => Promise<Dockerode.Container>;
@@ -14,7 +14,7 @@ const logger_1 = require("../../../logger");
14
14
  const docker_client_1 = require("../../client/docker-client");
15
15
  const port_1 = require("../../../port");
16
16
  const create_labels_1 = require("../create-labels");
17
- const createContainer = (options) => __awaiter(void 0, void 0, void 0, function* () {
17
+ const createContainer = (sessionId, options) => __awaiter(void 0, void 0, void 0, function* () {
18
18
  var _a, _b;
19
19
  try {
20
20
  logger_1.log.info(`Creating container for image "${options.imageName}"...`);
@@ -27,7 +27,7 @@ const createContainer = (options) => __awaiter(void 0, void 0, void 0, function*
27
27
  ExposedPorts: getExposedPorts(options.exposedPorts),
28
28
  Cmd: options.command,
29
29
  Entrypoint: options.entrypoint,
30
- Labels: (0, create_labels_1.createLabels)(options.reusable, options.imageName, options.labels),
30
+ Labels: (0, create_labels_1.createLabels)(sessionId, options.reusable, options.labels),
31
31
  Healthcheck: getHealthCheck(options.healthCheck),
32
32
  WorkingDir: options.workingDir,
33
33
  HostConfig: {
@@ -1,3 +1,2 @@
1
- import { DockerImageName } from "../../docker-image-name";
2
1
  import { Labels } from "../types";
3
- export declare const createLabels: (reusable: boolean, dockerImageName?: DockerImageName, extraLabels?: Labels) => Labels;
2
+ export declare const createLabels: (sessionId: string, reusable: boolean, extraLabels?: Labels) => Labels;
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLabels = void 0;
4
- const session_id_1 = require("../session-id");
5
4
  const labels_1 = require("../../labels");
6
5
  const package_json_1 = require("../../../package.json");
7
- const createLabels = (reusable, dockerImageName, extraLabels = {}) => {
6
+ const createLabels = (sessionId, reusable, extraLabels = {}) => {
8
7
  const labels = Object.assign(Object.assign({}, extraLabels), { [labels_1.LABEL_TESTCONTAINERS]: "true", [labels_1.LABEL_TESTCONTAINERS_LANG]: "node", [labels_1.LABEL_TESTCONTAINERS_VERSION]: package_json_1.version });
9
8
  if (!reusable) {
10
- labels[labels_1.LABEL_TESTCONTAINERS_SESSION_ID] = session_id_1.sessionId;
9
+ labels[labels_1.LABEL_TESTCONTAINERS_SESSION_ID] = sessionId;
11
10
  }
12
11
  return labels;
13
12
  };
@@ -9,5 +9,6 @@ export type BuildImageOptions = {
9
9
  pullPolicy: PullPolicy;
10
10
  registryConfig: RegistryConfig;
11
11
  cache: boolean;
12
+ deleteOnExit: boolean;
12
13
  };
13
- export declare const buildImage: (options: BuildImageOptions) => Promise<void>;
14
+ export declare const buildImage: (sessionId: string, options: BuildImageOptions) => Promise<void>;
@@ -21,7 +21,7 @@ const create_labels_1 = require("../create-labels");
21
21
  const path_1 = __importDefault(require("path"));
22
22
  const fs_1 = require("fs");
23
23
  const dockerignore_1 = __importDefault(require("@balena/dockerignore"));
24
- const buildImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
24
+ const buildImage = (sessionId, options) => __awaiter(void 0, void 0, void 0, function* () {
25
25
  try {
26
26
  logger_1.log.info(`Building image "${options.imageName.toString()}" with context "${options.context}"...`);
27
27
  const isDockerIgnored = yield createIsDockerIgnoredFunction(options.context);
@@ -42,7 +42,7 @@ const buildImage = (options) => __awaiter(void 0, void 0, void 0, function* () {
42
42
  nocache: !options.cache,
43
43
  buildargs: options.buildArgs,
44
44
  t: options.imageName.toString(),
45
- labels: (0, create_labels_1.createLabels)(false, options.imageName),
45
+ labels: (0, create_labels_1.createLabels)(sessionId, !options.deleteOnExit),
46
46
  registryconfig: options.registryConfig,
47
47
  pull: options.pullPolicy.shouldPull() ? "true" : undefined,
48
48
  };
@@ -13,4 +13,4 @@ export type CreateNetworkOptions = {
13
13
  [key: string]: string;
14
14
  };
15
15
  };
16
- export declare const createNetwork: (options: CreateNetworkOptions) => Promise<string>;
16
+ export declare const createNetwork: (sessionId: string, options: CreateNetworkOptions) => Promise<string>;
@@ -13,7 +13,7 @@ exports.createNetwork = void 0;
13
13
  const logger_1 = require("../../../logger");
14
14
  const docker_client_1 = require("../../client/docker-client");
15
15
  const create_labels_1 = require("../create-labels");
16
- const createNetwork = (options) => __awaiter(void 0, void 0, void 0, function* () {
16
+ const createNetwork = (sessionId, options) => __awaiter(void 0, void 0, void 0, function* () {
17
17
  try {
18
18
  logger_1.log.info(`Creating network "${options.name}"...`);
19
19
  const { dockerode } = yield (0, docker_client_1.getDockerClient)();
@@ -26,7 +26,7 @@ const createNetwork = (options) => __awaiter(void 0, void 0, void 0, function* (
26
26
  Ingress: options.ingress,
27
27
  EnableIPv6: options.enableIPv6,
28
28
  Options: options.options,
29
- Labels: Object.assign(Object.assign({}, options.labels), (0, create_labels_1.createLabels)(false)),
29
+ Labels: Object.assign(Object.assign({}, options.labels), (0, create_labels_1.createLabels)(sessionId, false)),
30
30
  });
31
31
  logger_1.log.info(`Created network "${options.name}"`);
32
32
  return network.id;
@@ -3,5 +3,5 @@
3
3
  /// <reference types="node" />
4
4
  /// <reference types="node" />
5
5
  /// <reference types="node" />
6
- import { DockerClient } from "./client/docker-client";
7
- export declare const getRemoteDockerUnixSocketPath: (dockerClient: DockerClient, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv) => string;
6
+ import { PartialDockerClient } from "./client/docker-client-types";
7
+ export declare const getRemoteDockerUnixSocketPath: (dockerClient: PartialDockerClient, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv) => string;
@@ -14,11 +14,14 @@ export type BindMount = {
14
14
  export type FileToCopy = {
15
15
  source: string;
16
16
  target: string;
17
+ mode?: number;
17
18
  };
19
+ export type DirectoryToCopy = FileToCopy;
18
20
  export type Content = string | Buffer | Readable;
19
21
  export type ContentToCopy = {
20
22
  content: Content;
21
23
  target: string;
24
+ mode?: number;
22
25
  };
23
26
  export type TmpFs = {
24
27
  [dir in string]: string;
@@ -14,7 +14,6 @@ const bound_ports_1 = require("../bound-ports");
14
14
  const container_name_resolver_1 = require("../docker-compose/functions/container-name-resolver");
15
15
  const started_generic_container_1 = require("../generic-container/started-generic-container");
16
16
  const logger_1 = require("../logger");
17
- const reaper_1 = require("../reaper");
18
17
  const uuid_1 = require("../uuid");
19
18
  const list_containers_1 = require("../docker/functions/container/list-containers");
20
19
  const get_container_1 = require("../docker/functions/container/get-container");
@@ -28,6 +27,7 @@ const wait_for_container_1 = require("../wait-for-container");
28
27
  const pull_policy_1 = require("../pull-policy");
29
28
  const docker_compose_pull_1 = require("../docker-compose/functions/docker-compose-pull");
30
29
  const wait_1 = require("../wait-strategy/wait");
30
+ const reaper_1 = require("../reaper");
31
31
  class DockerComposeEnvironment {
32
32
  constructor(composeFilePath, composeFiles, uuid = new uuid_1.RandomUuid()) {
33
33
  this.build = false;
@@ -77,7 +77,7 @@ class DockerComposeEnvironment {
77
77
  up(services) {
78
78
  return __awaiter(this, void 0, void 0, function* () {
79
79
  logger_1.log.info(`Starting DockerCompose environment "${this.projectName}"...`);
80
- (yield reaper_1.ReaperInstance.getInstance()).addProject(this.projectName);
80
+ yield (0, reaper_1.registerComposeProjectForCleanup)(this.projectName);
81
81
  const options = {
82
82
  filePath: this.composeFilePath,
83
83
  files: this.composeFiles,
@@ -0,0 +1 @@
1
+ export declare function withFileLock<T>(fileName: string, fn: () => T): Promise<T>;
@@ -0,0 +1,47 @@
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.withFileLock = void 0;
16
+ const path_1 = __importDefault(require("path"));
17
+ const tmp_1 = __importDefault(require("tmp"));
18
+ const promises_1 = require("fs/promises");
19
+ const logger_1 = require("./logger");
20
+ const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
21
+ function withFileLock(fileName, fn) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const file = yield createEmptyTmpFile(fileName);
24
+ let releaseLockFn;
25
+ try {
26
+ logger_1.log.debug(`Acquiring lock file "${file}"...`);
27
+ releaseLockFn = yield proper_lockfile_1.default.lock(file, { retries: { forever: true } });
28
+ logger_1.log.debug(`Acquired lock file "${file}"`);
29
+ return yield fn();
30
+ }
31
+ finally {
32
+ if (releaseLockFn) {
33
+ logger_1.log.debug(`Releasing lock file "${file}"...`);
34
+ yield releaseLockFn();
35
+ logger_1.log.debug(`Released lock file "${file}"`);
36
+ }
37
+ }
38
+ });
39
+ }
40
+ exports.withFileLock = withFileLock;
41
+ function createEmptyTmpFile(fileName) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const file = path_1.default.resolve(tmp_1.default.tmpdir, fileName);
44
+ yield (0, promises_1.writeFile)(file, "");
45
+ return file;
46
+ });
47
+ }
@@ -2,6 +2,9 @@ import { BuildArgs } from "../docker/types";
2
2
  import { PullPolicy } from "../pull-policy";
3
3
  import { Uuid } from "../uuid";
4
4
  import { GenericContainer } from "./generic-container";
5
+ export type BuildOptions = {
6
+ deleteOnExit: boolean;
7
+ };
5
8
  export declare class GenericContainerBuilder {
6
9
  private readonly context;
7
10
  private readonly dockerfileName;
@@ -13,6 +16,6 @@ export declare class GenericContainerBuilder {
13
16
  withBuildArgs(buildArgs: BuildArgs): GenericContainerBuilder;
14
17
  withPullPolicy(pullPolicy: PullPolicy): this;
15
18
  withCache(cache: boolean): this;
16
- build(image?: string): Promise<GenericContainer>;
19
+ build(image?: string, options?: BuildOptions): Promise<GenericContainer>;
17
20
  private getRegistryConfig;
18
21
  }