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.
Files changed (182) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/src/bound-ports.d.ts +12 -0
  3. package/dist/src/bound-ports.js +50 -0
  4. package/dist/src/clock.d.ts +7 -0
  5. package/dist/src/clock.js +9 -0
  6. package/dist/src/docker/docker-client-config.d.ts +10 -0
  7. package/dist/src/docker/docker-client-config.js +66 -0
  8. package/dist/src/docker/docker-client.d.ts +24 -0
  9. package/dist/src/docker/docker-client.js +198 -0
  10. package/dist/src/docker/functions/container/attach-container.d.ts +3 -0
  11. package/dist/src/docker/functions/container/attach-container.js +25 -0
  12. package/dist/src/docker/functions/container/container-logs.d.ts +6 -0
  13. package/dist/src/docker/functions/container/container-logs.js +32 -0
  14. package/dist/src/docker/functions/container/create-container.d.ts +30 -0
  15. package/dist/src/docker/functions/container/create-container.js +114 -0
  16. package/dist/src/docker/functions/container/exec-container.d.ts +9 -0
  17. package/dist/src/docker/functions/container/exec-container.js +59 -0
  18. package/dist/src/docker/functions/container/get-container.d.ts +3 -0
  19. package/dist/src/docker/functions/container/get-container.js +49 -0
  20. package/dist/src/docker/functions/container/inspect-container.d.ts +19 -0
  21. package/dist/src/docker/functions/container/inspect-container.js +67 -0
  22. package/dist/src/docker/functions/container/list-containers.d.ts +2 -0
  23. package/dist/src/docker/functions/container/list-containers.js +25 -0
  24. package/dist/src/docker/functions/container/put-container-archive.d.ts +9 -0
  25. package/dist/src/docker/functions/container/put-container-archive.js +23 -0
  26. package/dist/src/docker/functions/container/remove-container.d.ts +5 -0
  27. package/dist/src/docker/functions/container/remove-container.js +23 -0
  28. package/dist/src/docker/functions/container/restart-container.d.ts +5 -0
  29. package/dist/src/docker/functions/container/restart-container.js +23 -0
  30. package/dist/src/docker/functions/container/start-container.d.ts +2 -0
  31. package/dist/src/docker/functions/container/start-container.js +23 -0
  32. package/dist/src/docker/functions/container/stop-container.d.ts +5 -0
  33. package/dist/src/docker/functions/container/stop-container.js +29 -0
  34. package/dist/src/docker/functions/create-labels.d.ts +3 -0
  35. package/dist/src/docker/functions/create-labels.js +17 -0
  36. package/dist/src/docker/functions/demux-stream.d.ts +3 -0
  37. package/dist/src/docker/functions/demux-stream.js +32 -0
  38. package/dist/src/docker/functions/get-info.d.ts +11 -0
  39. package/dist/src/docker/functions/get-info.js +38 -0
  40. package/dist/src/docker/functions/image/build-image.d.ts +13 -0
  41. package/dist/src/docker/functions/image/build-image.js +76 -0
  42. package/dist/src/docker/functions/image/image-exists.d.ts +3 -0
  43. package/dist/src/docker/functions/image/image-exists.js +34 -0
  44. package/dist/src/docker/functions/image/list-images.d.ts +3 -0
  45. package/dist/src/docker/functions/image/list-images.js +34 -0
  46. package/dist/src/docker/functions/image/pull-image.d.ts +7 -0
  47. package/dist/src/docker/functions/image/pull-image.js +41 -0
  48. package/dist/src/docker/functions/network/connect-network.d.ts +6 -0
  49. package/dist/src/docker/functions/network/connect-network.js +27 -0
  50. package/dist/src/docker/functions/network/create-network.d.ts +16 -0
  51. package/dist/src/docker/functions/network/create-network.js +38 -0
  52. package/dist/src/docker/functions/network/remove-network.d.ts +1 -0
  53. package/dist/src/docker/functions/network/remove-network.js +30 -0
  54. package/dist/src/docker/functions/run-in-container.d.ts +2 -0
  55. package/dist/src/docker/functions/run-in-container.js +39 -0
  56. package/dist/src/docker/get-remote-docker-unix-socket-path.d.ts +5 -0
  57. package/dist/src/docker/get-remote-docker-unix-socket-path.js +17 -0
  58. package/dist/src/docker/lookup-host-ips.d.ts +5 -0
  59. package/dist/src/docker/lookup-host-ips.js +26 -0
  60. package/dist/src/docker/pull-stream-parser.d.ts +11 -0
  61. package/dist/src/docker/pull-stream-parser.js +63 -0
  62. package/dist/src/docker/rootless-unix-socket-strategy.d.ts +16 -0
  63. package/dist/src/docker/rootless-unix-socket-strategy.js +69 -0
  64. package/dist/src/docker/session-id.d.ts +1 -0
  65. package/dist/src/docker/session-id.js +5 -0
  66. package/dist/src/docker/types.d.ts +79 -0
  67. package/dist/src/docker/types.js +2 -0
  68. package/dist/src/docker-compose/default-docker-compose-options.d.ts +3 -0
  69. package/dist/src/docker-compose/default-docker-compose-options.js +37 -0
  70. package/dist/src/docker-compose/docker-compose-options.d.ts +9 -0
  71. package/dist/src/docker-compose/docker-compose-options.js +2 -0
  72. package/dist/src/docker-compose/functions/container-name-resolver.d.ts +1 -0
  73. package/dist/src/docker-compose/functions/container-name-resolver.js +15 -0
  74. package/dist/src/docker-compose/functions/docker-compose-down.d.ts +3 -0
  75. package/dist/src/docker-compose/functions/docker-compose-down.js +39 -0
  76. package/dist/src/docker-compose/functions/docker-compose-stop.d.ts +2 -0
  77. package/dist/src/docker-compose/functions/docker-compose-stop.js +29 -0
  78. package/dist/src/docker-compose/functions/docker-compose-up.d.ts +2 -0
  79. package/dist/src/docker-compose/functions/docker-compose-up.js +41 -0
  80. package/dist/src/docker-compose-environment/docker-compose-environment.d.ts +25 -0
  81. package/dist/src/docker-compose-environment/docker-compose-environment.js +134 -0
  82. package/dist/src/docker-compose-environment/downed-docker-compose-environment.d.ts +2 -0
  83. package/dist/src/docker-compose-environment/downed-docker-compose-environment.js +6 -0
  84. package/dist/src/docker-compose-environment/started-docker-compose-environment.d.ts +15 -0
  85. package/dist/src/docker-compose-environment/started-docker-compose-environment.js +46 -0
  86. package/dist/src/docker-compose-environment/stopped-docker-compose-environment.d.ts +8 -0
  87. package/dist/src/docker-compose-environment/stopped-docker-compose-environment.js +27 -0
  88. package/dist/src/docker-image-name.d.ts +15 -0
  89. package/dist/src/docker-image-name.js +63 -0
  90. package/dist/src/dockerfile-parser.d.ts +3 -0
  91. package/dist/src/dockerfile-parser.js +39 -0
  92. package/dist/src/generic-container/generic-container-builder.d.ts +18 -0
  93. package/dist/src/generic-container/generic-container-builder.js +98 -0
  94. package/dist/src/generic-container/generic-container.d.ts +77 -0
  95. package/dist/src/generic-container/generic-container.js +312 -0
  96. package/dist/src/generic-container/started-generic-container.d.ts +31 -0
  97. package/dist/src/generic-container/started-generic-container.js +97 -0
  98. package/dist/src/generic-container/stopped-generic-container.d.ts +3 -0
  99. package/dist/src/generic-container/stopped-generic-container.js +6 -0
  100. package/dist/src/hash.d.ts +1 -0
  101. package/dist/src/hash.js +11 -0
  102. package/dist/src/http-wait-strategy.d.ts +27 -0
  103. package/dist/src/http-wait-strategy.js +113 -0
  104. package/dist/src/images.d.ts +2 -0
  105. package/dist/src/images.js +6 -0
  106. package/dist/src/index.d.ts +21 -0
  107. package/dist/src/index.js +54 -0
  108. package/dist/src/labels.d.ts +5 -0
  109. package/dist/src/labels.js +8 -0
  110. package/dist/src/logger.d.ts +36 -0
  111. package/dist/src/logger.js +61 -0
  112. package/dist/src/modules/abstract-started-container.d.ts +21 -0
  113. package/dist/src/modules/abstract-started-container.js +59 -0
  114. package/dist/src/modules/arangodb/arangodb-container.d.ts +19 -0
  115. package/dist/src/modules/arangodb/arangodb-container.js +60 -0
  116. package/dist/src/modules/elasticsearch/elasticsearch-container.d.ts +12 -0
  117. package/dist/src/modules/elasticsearch/elasticsearch-container.js +43 -0
  118. package/dist/src/modules/kafka/kafka-container.d.ts +46 -0
  119. package/dist/src/modules/kafka/kafka-container.js +172 -0
  120. package/dist/src/modules/mongodb/mongodb-container.d.ts +19 -0
  121. package/dist/src/modules/mongodb/mongodb-container.js +85 -0
  122. package/dist/src/modules/mysql/mysql-container.d.ts +29 -0
  123. package/dist/src/modules/mysql/mysql-container.js +102 -0
  124. package/dist/src/modules/nats/nats-container.d.ts +55 -0
  125. package/dist/src/modules/nats/nats-container.js +97 -0
  126. package/dist/src/modules/neo4j/neo4j-container.d.ts +23 -0
  127. package/dist/src/modules/neo4j/neo4j-container.js +82 -0
  128. package/dist/src/modules/postgresql/postgresql-container.d.ts +28 -0
  129. package/dist/src/modules/postgresql/postgresql-container.js +87 -0
  130. package/dist/src/network.d.ts +17 -0
  131. package/dist/src/network.js +54 -0
  132. package/dist/src/port-check.d.ts +17 -0
  133. package/dist/src/port-check.js +84 -0
  134. package/dist/src/port-forwarder.d.ts +17 -0
  135. package/dist/src/port-forwarder.js +81 -0
  136. package/dist/src/port-generator.d.ts +15 -0
  137. package/dist/src/port-generator.js +51 -0
  138. package/dist/src/port.d.ts +10 -0
  139. package/dist/src/port.js +47 -0
  140. package/dist/src/pull-policy.d.ts +9 -0
  141. package/dist/src/pull-policy.js +15 -0
  142. package/dist/src/reaper.d.ts +14 -0
  143. package/dist/src/reaper.js +141 -0
  144. package/dist/src/registry-auth-locator/auths.d.ts +8 -0
  145. package/dist/src/registry-auth-locator/auths.js +56 -0
  146. package/dist/src/registry-auth-locator/cred-helpers.d.ts +6 -0
  147. package/dist/src/registry-auth-locator/cred-helpers.js +15 -0
  148. package/dist/src/registry-auth-locator/credential-provider.d.ts +10 -0
  149. package/dist/src/registry-auth-locator/credential-provider.js +83 -0
  150. package/dist/src/registry-auth-locator/creds-store.d.ts +6 -0
  151. package/dist/src/registry-auth-locator/creds-store.js +15 -0
  152. package/dist/src/registry-auth-locator/get-auth-config.d.ts +2 -0
  153. package/dist/src/registry-auth-locator/get-auth-config.js +65 -0
  154. package/dist/src/registry-auth-locator/registry-auth-locator.d.ts +6 -0
  155. package/dist/src/registry-auth-locator/registry-auth-locator.js +2 -0
  156. package/dist/src/registry-auth-locator/registry-matches.d.ts +1 -0
  157. package/dist/src/registry-auth-locator/registry-matches.js +5 -0
  158. package/dist/src/registry-auth-locator/types.d.ts +23 -0
  159. package/dist/src/registry-auth-locator/types.js +2 -0
  160. package/dist/src/retry-strategy.d.ts +17 -0
  161. package/dist/src/retry-strategy.js +46 -0
  162. package/dist/src/startup-check-strategy.d.ts +7 -0
  163. package/dist/src/startup-check-strategy.js +30 -0
  164. package/dist/src/stream-utils.d.ts +6 -0
  165. package/dist/src/stream-utils.js +46 -0
  166. package/dist/src/system-info.d.ts +17 -0
  167. package/dist/src/system-info.js +51 -0
  168. package/dist/src/test-container.d.ts +66 -0
  169. package/dist/src/test-container.js +2 -0
  170. package/dist/src/test-containers.d.ts +3 -0
  171. package/dist/src/test-containers.js +22 -0
  172. package/dist/src/type-guards.d.ts +1 -0
  173. package/dist/src/type-guards.js +7 -0
  174. package/dist/src/uuid.d.ts +6 -0
  175. package/dist/src/uuid.js +13 -0
  176. package/dist/src/wait-for-container.d.ts +4 -0
  177. package/dist/src/wait-for-container.js +34 -0
  178. package/dist/src/wait-strategy.d.ts +32 -0
  179. package/dist/src/wait-strategy.js +137 -0
  180. package/dist/src/wait.d.ts +7 -0
  181. package/dist/src/wait.js +17 -0
  182. package/package.json +1 -1
@@ -0,0 +1,141 @@
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.ReaperInstance = void 0;
13
+ const net_1 = require("net");
14
+ const logger_1 = require("./logger");
15
+ const generic_container_1 = require("./generic-container/generic-container");
16
+ const session_id_1 = require("./docker/session-id");
17
+ const images_1 = require("./images");
18
+ const port_1 = require("./port");
19
+ const labels_1 = require("./labels");
20
+ const wait_1 = require("./wait");
21
+ const retry_strategy_1 = require("./retry-strategy");
22
+ const get_remote_docker_unix_socket_path_1 = require("./docker/get-remote-docker-unix-socket-path");
23
+ const docker_client_1 = require("./docker/docker-client");
24
+ class RealReaper {
25
+ constructor(container, socket) {
26
+ this.container = container;
27
+ this.socket = socket;
28
+ }
29
+ addProject(projectName) {
30
+ this.socket.write(`label=com.docker.compose.project=${projectName}\r\n`);
31
+ }
32
+ getContainerId() {
33
+ return this.container.getId();
34
+ }
35
+ stop() {
36
+ this.socket.end();
37
+ }
38
+ }
39
+ class DisabledReaper {
40
+ addProject() {
41
+ // noop
42
+ }
43
+ stop() {
44
+ // noop
45
+ }
46
+ getContainerId() {
47
+ return "";
48
+ }
49
+ }
50
+ class ReaperInstance {
51
+ static getInstance() {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ if (!this.instance) {
54
+ if (this.isEnabled()) {
55
+ this.instance = this.createRealInstance();
56
+ }
57
+ else {
58
+ this.instance = this.createDisabledInstance();
59
+ }
60
+ }
61
+ return this.instance;
62
+ });
63
+ }
64
+ static stopInstance() {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ if (this.instance) {
67
+ const reaper = yield this.instance;
68
+ reaper.stop();
69
+ this.instance = undefined;
70
+ }
71
+ });
72
+ }
73
+ static isEnabled() {
74
+ return process.env.TESTCONTAINERS_RYUK_DISABLED !== "true";
75
+ }
76
+ static isPrivileged() {
77
+ return process.env.TESTCONTAINERS_RYUK_PRIVILEGED === "true";
78
+ }
79
+ static createDisabledInstance() {
80
+ logger_1.log.debug(`Not creating new Reaper for session: ${session_id_1.sessionId}`);
81
+ return Promise.resolve(new DisabledReaper());
82
+ }
83
+ static createRealInstance() {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ const containerPort = process.env["TESTCONTAINERS_RYUK_PORT"]
86
+ ? { container: 8080, host: Number(process.env["TESTCONTAINERS_RYUK_PORT"]) }
87
+ : 8080;
88
+ logger_1.log.debug(`Creating new Reaper for session: ${session_id_1.sessionId}`);
89
+ const container = new generic_container_1.GenericContainer(images_1.REAPER_IMAGE)
90
+ .withName(`testcontainers-ryuk-${session_id_1.sessionId}`)
91
+ .withExposedPorts(containerPort)
92
+ .withBindMounts([
93
+ {
94
+ source: (0, get_remote_docker_unix_socket_path_1.getRemoteDockerUnixSocketPath)((yield (0, docker_client_1.dockerClient)()).uri),
95
+ target: "/var/run/docker.sock",
96
+ },
97
+ ])
98
+ .withWaitStrategy(wait_1.Wait.forLogMessage(/.+ Started!/));
99
+ if (this.isPrivileged()) {
100
+ container.withPrivilegedMode();
101
+ }
102
+ const startedContainer = yield container.start();
103
+ const containerId = startedContainer.getId();
104
+ const host = startedContainer.getHost();
105
+ const port = startedContainer.getMappedPort(8080);
106
+ const retryStrategy = new retry_strategy_1.IntervalRetryStrategy(1000);
107
+ const retryResult = yield retryStrategy.retryUntil((attempt) => {
108
+ return new Promise((resolve) => {
109
+ logger_1.log.debug(`Connecting to Reaper (attempt ${attempt + 1}) ${containerId} on ${host}:${port}`);
110
+ const socket = new net_1.Socket();
111
+ socket
112
+ .unref()
113
+ .on("timeout", () => logger_1.log.error(`Reaper ${containerId} socket timed out`))
114
+ .on("error", (err) => logger_1.log.error(`Reaper ${containerId} socket error: ${err}`))
115
+ .on("close", (hadError) => {
116
+ if (hadError) {
117
+ logger_1.log.error(`Connection to Reaper ${containerId} closed with error`);
118
+ }
119
+ else {
120
+ logger_1.log.warn(`Connection to Reaper ${containerId} closed`);
121
+ }
122
+ resolve(undefined);
123
+ })
124
+ .connect((0, port_1.getContainerPort)(port), host, () => {
125
+ logger_1.log.debug(`Connected to Reaper ${containerId}`);
126
+ socket.write(`label=${labels_1.LABEL_TESTCONTAINERS_SESSION_ID}=${session_id_1.sessionId}\r\n`);
127
+ const reaper = new RealReaper(startedContainer, socket);
128
+ resolve(reaper);
129
+ });
130
+ });
131
+ }, (result) => result !== undefined, () => new Error(`Failed to connect to Reaper ${containerId}`), 4000);
132
+ if (retryResult instanceof RealReaper) {
133
+ return retryResult;
134
+ }
135
+ else {
136
+ throw retryResult;
137
+ }
138
+ });
139
+ }
140
+ }
141
+ exports.ReaperInstance = ReaperInstance;
@@ -0,0 +1,8 @@
1
+ import { DockerConfig } from "./types";
2
+ import { RegistryAuthLocator } from "./registry-auth-locator";
3
+ import { AuthConfig } from "../docker/types";
4
+ export declare class Auths implements RegistryAuthLocator {
5
+ getName(): string;
6
+ getAuthConfig(registry: string, dockerConfig: DockerConfig): Promise<AuthConfig | undefined>;
7
+ private findAuthEntry;
8
+ }
@@ -0,0 +1,56 @@
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.Auths = void 0;
13
+ const registry_matches_1 = require("./registry-matches");
14
+ class Auths {
15
+ getName() {
16
+ return "Auths";
17
+ }
18
+ getAuthConfig(registry, dockerConfig) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const auth = this.findAuthEntry(registry, dockerConfig);
21
+ if (!auth) {
22
+ return undefined;
23
+ }
24
+ const authConfig = { registryAddress: registry };
25
+ if (auth.email) {
26
+ authConfig.email = auth.email;
27
+ }
28
+ if (auth.auth) {
29
+ const decodedAuth = Buffer.from(auth.auth, "base64").toString();
30
+ const [username, password] = decodedAuth.split(":");
31
+ authConfig.username = username;
32
+ authConfig.password = password;
33
+ }
34
+ else {
35
+ if (auth.username) {
36
+ authConfig.username = auth.username;
37
+ }
38
+ if (auth.password) {
39
+ authConfig.password = auth.password;
40
+ }
41
+ }
42
+ return authConfig;
43
+ });
44
+ }
45
+ findAuthEntry(registry, dockerConfig) {
46
+ var _a;
47
+ const authEntries = (_a = dockerConfig.auths) !== null && _a !== void 0 ? _a : {};
48
+ for (const key in authEntries) {
49
+ if ((0, registry_matches_1.registryMatches)(key, registry)) {
50
+ return authEntries[key];
51
+ }
52
+ }
53
+ return undefined;
54
+ }
55
+ }
56
+ exports.Auths = Auths;
@@ -0,0 +1,6 @@
1
+ import { CredentialProvider } from "./credential-provider";
2
+ import { DockerConfig } from "./types";
3
+ export declare class CredHelpers extends CredentialProvider {
4
+ getName(): string;
5
+ getCredentialProviderName(registry: string, dockerConfig: DockerConfig): string | undefined;
6
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CredHelpers = void 0;
4
+ const credential_provider_1 = require("./credential-provider");
5
+ class CredHelpers extends credential_provider_1.CredentialProvider {
6
+ getName() {
7
+ return "CredHelpers";
8
+ }
9
+ getCredentialProviderName(registry, dockerConfig) {
10
+ if (dockerConfig.credHelpers !== undefined && dockerConfig.credHelpers[registry] !== undefined) {
11
+ return dockerConfig.credHelpers[registry];
12
+ }
13
+ }
14
+ }
15
+ exports.CredHelpers = CredHelpers;
@@ -0,0 +1,10 @@
1
+ import { DockerConfig } from "./types";
2
+ import { RegistryAuthLocator } from "./registry-auth-locator";
3
+ import { AuthConfig } from "../docker/types";
4
+ export declare abstract class CredentialProvider implements RegistryAuthLocator {
5
+ abstract getName(): string;
6
+ abstract getCredentialProviderName(registry: string, dockerConfig: DockerConfig): string | undefined;
7
+ getAuthConfig(registry: string, dockerConfig: DockerConfig): Promise<AuthConfig | undefined>;
8
+ private listCredentials;
9
+ private runCredentialProvider;
10
+ }
@@ -0,0 +1,83 @@
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.CredentialProvider = void 0;
13
+ const logger_1 = require("../logger");
14
+ const child_process_1 = require("child_process");
15
+ const registry_matches_1 = require("./registry-matches");
16
+ class CredentialProvider {
17
+ getAuthConfig(registry, dockerConfig) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const credentialProviderName = this.getCredentialProviderName(registry, dockerConfig);
20
+ if (!credentialProviderName) {
21
+ return undefined;
22
+ }
23
+ const programName = `docker-credential-${credentialProviderName}`;
24
+ logger_1.log.debug(`Executing Docker credential provider: ${programName}`);
25
+ const credentials = yield this.listCredentials(programName);
26
+ if (!Object.keys(credentials).some((aRegistry) => (0, registry_matches_1.registryMatches)(aRegistry, registry))) {
27
+ logger_1.log.debug(`No credential found for registry: "${registry}"`);
28
+ return undefined;
29
+ }
30
+ const response = yield this.runCredentialProvider(registry, programName);
31
+ const authConfig = {
32
+ username: response.Username,
33
+ password: response.Secret,
34
+ registryAddress: response.ServerURL,
35
+ };
36
+ logger_1.log.debug(`Docker credential provider found auth config for ${registry}`);
37
+ return authConfig;
38
+ });
39
+ }
40
+ listCredentials(providerName) {
41
+ return new Promise((resolve, reject) => {
42
+ (0, child_process_1.exec)(`${providerName} list`, (err, stdout) => {
43
+ if (err) {
44
+ logger_1.log.error(`An error occurred listing credentials: ${err}`);
45
+ return reject(new Error("An error occurred listing credentials"));
46
+ }
47
+ try {
48
+ const response = JSON.parse(stdout);
49
+ return resolve(response);
50
+ }
51
+ catch (e) {
52
+ logger_1.log.error(`Unexpected response from Docker credential provider LIST command: "${stdout}"`);
53
+ return reject(new Error("Unexpected response from Docker credential provider LIST command"));
54
+ }
55
+ });
56
+ });
57
+ }
58
+ runCredentialProvider(registry, providerName) {
59
+ return new Promise((resolve, reject) => {
60
+ const sink = (0, child_process_1.spawn)(providerName, ["get"]);
61
+ const chunks = [];
62
+ sink.stdout.on("data", (chunk) => chunks.push(chunk));
63
+ sink.on("close", (code) => {
64
+ if (code !== 0) {
65
+ logger_1.log.error(`An error occurred getting a credential: ${code}`);
66
+ return reject(new Error("An error occurred getting a credential"));
67
+ }
68
+ const response = chunks.join("");
69
+ try {
70
+ const parsedResponse = JSON.parse(response);
71
+ return resolve(parsedResponse);
72
+ }
73
+ catch (e) {
74
+ logger_1.log.error(`Unexpected response from Docker credential provider GET command: "${response}"`);
75
+ return reject(new Error("Unexpected response from Docker credential provider GET command"));
76
+ }
77
+ });
78
+ sink.stdin.write(`${registry}\n`);
79
+ sink.stdin.end();
80
+ });
81
+ }
82
+ }
83
+ exports.CredentialProvider = CredentialProvider;
@@ -0,0 +1,6 @@
1
+ import { CredentialProvider } from "./credential-provider";
2
+ import { DockerConfig } from "./types";
3
+ export declare class CredsStore extends CredentialProvider {
4
+ getName(): string;
5
+ getCredentialProviderName(registry: string, dockerConfig: DockerConfig): string | undefined;
6
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CredsStore = void 0;
4
+ const credential_provider_1 = require("./credential-provider");
5
+ class CredsStore extends credential_provider_1.CredentialProvider {
6
+ getName() {
7
+ return "CredsStore";
8
+ }
9
+ getCredentialProviderName(registry, dockerConfig) {
10
+ if (dockerConfig.credsStore !== undefined && dockerConfig.credsStore.length > 0) {
11
+ return dockerConfig.credsStore;
12
+ }
13
+ }
14
+ }
15
+ exports.CredsStore = CredsStore;
@@ -0,0 +1,2 @@
1
+ import { AuthConfig } from "../docker/types";
2
+ export declare const getAuthConfig: (registry: string) => Promise<AuthConfig | undefined>;
@@ -0,0 +1,65 @@
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.getAuthConfig = void 0;
16
+ const path_1 = __importDefault(require("path"));
17
+ const os_1 = __importDefault(require("os"));
18
+ const fs_1 = require("fs");
19
+ const promises_1 = require("fs/promises");
20
+ const cred_helpers_1 = require("./cred-helpers");
21
+ const creds_store_1 = require("./creds-store");
22
+ const auths_1 = require("./auths");
23
+ const logger_1 = require("../logger");
24
+ const dockerConfigLocation = process.env.DOCKER_CONFIG || `${os_1.default.homedir()}/.docker`;
25
+ const dockerConfigFile = path_1.default.resolve(dockerConfigLocation, "config.json");
26
+ const readDockerConfig = () => __awaiter(void 0, void 0, void 0, function* () {
27
+ if (process.env.DOCKER_AUTH_CONFIG) {
28
+ return parseDockerConfig(process.env.DOCKER_AUTH_CONFIG);
29
+ }
30
+ else if ((0, fs_1.existsSync)(dockerConfigFile)) {
31
+ return parseDockerConfig((yield (0, promises_1.readFile)(dockerConfigFile)).toString());
32
+ }
33
+ else {
34
+ return Promise.resolve({});
35
+ }
36
+ });
37
+ function parseDockerConfig(dockerConfig) {
38
+ const object = JSON.parse(dockerConfig);
39
+ return {
40
+ credsStore: object.credsStore,
41
+ credHelpers: object.credHelpers,
42
+ auths: object.auths,
43
+ };
44
+ }
45
+ const dockerConfig = readDockerConfig();
46
+ const registryAuthLocators = [new cred_helpers_1.CredHelpers(), new creds_store_1.CredsStore(), new auths_1.Auths()];
47
+ const authsCache = new Map();
48
+ const getAuthConfig = (registry) => __awaiter(void 0, void 0, void 0, function* () {
49
+ if (authsCache.has(registry)) {
50
+ logger_1.log.debug(`Re-using cached auth for registry ${registry}`);
51
+ return authsCache.get(registry);
52
+ }
53
+ for (const registryAuthLocator of registryAuthLocators) {
54
+ const authConfig = yield registryAuthLocator.getAuthConfig(registry, yield dockerConfig);
55
+ if (authConfig) {
56
+ logger_1.log.debug(`Found applicable registry auth locator for registry "${registry}": ${registryAuthLocator.getName()}`);
57
+ authsCache.set(registry, authConfig);
58
+ return authConfig;
59
+ }
60
+ }
61
+ logger_1.log.debug(`No registry auth locator found for registry: "${registry}"`);
62
+ authsCache.set(registry, undefined);
63
+ return undefined;
64
+ });
65
+ exports.getAuthConfig = getAuthConfig;
@@ -0,0 +1,6 @@
1
+ import { DockerConfig } from "./types";
2
+ import { AuthConfig } from "../docker/types";
3
+ export interface RegistryAuthLocator {
4
+ getName(): string;
5
+ getAuthConfig(registry: string, dockerConfig: DockerConfig): Promise<AuthConfig | undefined>;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare const registryMatches: (authConfigRegistry: string, requestedRegistry: string) => boolean;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registryMatches = void 0;
4
+ const registryMatches = (authConfigRegistry, requestedRegistry) => authConfigRegistry == requestedRegistry || authConfigRegistry.endsWith("://" + requestedRegistry);
5
+ exports.registryMatches = registryMatches;
@@ -0,0 +1,23 @@
1
+ export type CredentialProviderGetResponse = {
2
+ ServerURL: string;
3
+ Username: string;
4
+ Secret: string;
5
+ };
6
+ export type CredentialProviderListResponse = {
7
+ [registry: string]: string;
8
+ };
9
+ export type Auth = {
10
+ auth?: string;
11
+ email?: string;
12
+ username?: string;
13
+ password?: string;
14
+ };
15
+ export type DockerConfig = {
16
+ credHelpers?: {
17
+ [registry: string]: string;
18
+ };
19
+ credsStore?: string;
20
+ auths?: {
21
+ [registry: string]: Auth;
22
+ };
23
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import { Clock, Time } from "./clock";
2
+ export interface RetryStrategy<T, U> {
3
+ retryUntil(fn: () => Promise<T>, predicate: (result: T) => boolean | Promise<boolean>, onTimeout: () => U, timeout: number): Promise<T | U>;
4
+ }
5
+ declare abstract class AbstractRetryStrategy<T, U> implements RetryStrategy<T, U> {
6
+ protected readonly clock: Clock;
7
+ protected constructor(clock?: Clock);
8
+ abstract retryUntil(fn: () => Promise<T>, predicate: (result: T) => boolean | Promise<boolean>, onTimeout: () => U, timeout: number): Promise<T | U>;
9
+ protected hasTimedOut(timeout: number, startTime: Time): boolean;
10
+ protected wait(duration: number): Promise<void>;
11
+ }
12
+ export declare class IntervalRetryStrategy<T, U> extends AbstractRetryStrategy<T, U> {
13
+ private readonly interval;
14
+ constructor(interval: number);
15
+ retryUntil(fn: (attempt: number) => Promise<T>, predicate: (result: T) => boolean | Promise<boolean>, onTimeout: () => U, timeout: number): Promise<T | U>;
16
+ }
17
+ export {};
@@ -0,0 +1,46 @@
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.IntervalRetryStrategy = void 0;
13
+ const clock_1 = require("./clock");
14
+ class AbstractRetryStrategy {
15
+ constructor(clock = new clock_1.SystemClock()) {
16
+ this.clock = clock;
17
+ }
18
+ hasTimedOut(timeout, startTime) {
19
+ return this.clock.getTime() - startTime > timeout;
20
+ }
21
+ wait(duration) {
22
+ return new Promise((resolve) => setTimeout(resolve, duration));
23
+ }
24
+ }
25
+ class IntervalRetryStrategy extends AbstractRetryStrategy {
26
+ constructor(interval) {
27
+ super();
28
+ this.interval = interval;
29
+ }
30
+ retryUntil(fn, predicate, onTimeout, timeout) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const startTime = this.clock.getTime();
33
+ let attemptNumber = 0;
34
+ let result = yield fn(attemptNumber++);
35
+ while (!(yield predicate(result))) {
36
+ if (this.hasTimedOut(timeout, startTime)) {
37
+ return onTimeout();
38
+ }
39
+ yield this.wait(this.interval);
40
+ result = yield fn(attemptNumber++);
41
+ }
42
+ return result;
43
+ });
44
+ }
45
+ }
46
+ exports.IntervalRetryStrategy = IntervalRetryStrategy;
@@ -0,0 +1,7 @@
1
+ import { AbstractWaitStrategy } from "./wait-strategy";
2
+ import Dockerode from "dockerode";
3
+ export type StartupStatus = "PENDING" | "SUCCESS" | "FAIL";
4
+ export declare abstract class StartupCheckStrategy extends AbstractWaitStrategy {
5
+ abstract checkStartupState(dockerClient: Dockerode, containerId: string): Promise<StartupStatus>;
6
+ waitUntilReady(container: Dockerode.Container): Promise<void>;
7
+ }
@@ -0,0 +1,30 @@
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.StartupCheckStrategy = void 0;
13
+ const wait_strategy_1 = require("./wait-strategy");
14
+ const retry_strategy_1 = require("./retry-strategy");
15
+ const docker_client_1 = require("./docker/docker-client");
16
+ class StartupCheckStrategy extends wait_strategy_1.AbstractWaitStrategy {
17
+ waitUntilReady(container) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const { dockerode } = yield (0, docker_client_1.dockerClient)();
20
+ const startupStatus = yield new retry_strategy_1.IntervalRetryStrategy(1000).retryUntil(() => __awaiter(this, void 0, void 0, function* () { return yield this.checkStartupState(dockerode, container.id); }), (startupStatus) => startupStatus === "SUCCESS" || startupStatus === "FAIL", () => new Error(`Container not accessible after ${this.startupTimeout}ms for ${container.id}`), this.startupTimeout);
21
+ if (startupStatus instanceof Error) {
22
+ throw startupStatus;
23
+ }
24
+ else if (startupStatus === "FAIL") {
25
+ throw new Error(`Container failed to start for ${container.id}`);
26
+ }
27
+ });
28
+ }
29
+ }
30
+ exports.StartupCheckStrategy = StartupCheckStrategy;
@@ -0,0 +1,6 @@
1
+ import { Readable } from "stream";
2
+ type Options = {
3
+ trim: boolean;
4
+ };
5
+ export declare const streamToString: (stream: Readable, options?: Options) => Promise<string>;
6
+ export {};
@@ -0,0 +1,46 @@
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 __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.streamToString = void 0;
20
+ const streamToString = (stream, options = { trim: false }) => { var _a, stream_1, stream_1_1; return __awaiter(void 0, void 0, void 0, function* () {
21
+ var _b, e_1, _c, _d;
22
+ const chunks = [];
23
+ try {
24
+ for (_a = true, stream_1 = __asyncValues(stream); stream_1_1 = yield stream_1.next(), _b = stream_1_1.done, !_b;) {
25
+ _d = stream_1_1.value;
26
+ _a = false;
27
+ try {
28
+ const chunk = _d;
29
+ chunks.push(Buffer.from(chunk));
30
+ }
31
+ finally {
32
+ _a = true;
33
+ }
34
+ }
35
+ }
36
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
37
+ finally {
38
+ try {
39
+ if (!_a && !_b && (_c = stream_1.return)) yield _c.call(stream_1);
40
+ }
41
+ finally { if (e_1) throw e_1.error; }
42
+ }
43
+ const str = Buffer.concat(chunks).toString("utf-8");
44
+ return options.trim ? str.trim() : str;
45
+ }); };
46
+ exports.streamToString = streamToString;
@@ -0,0 +1,17 @@
1
+ import { DockerInfo } from "./docker/functions/get-info";
2
+ import Dockerode from "dockerode";
3
+ export type SystemInfo = {
4
+ nodeInfo: NodeInfo;
5
+ dockerInfo: DockerInfo;
6
+ dockerComposeInfo?: DockerComposeInfo;
7
+ };
8
+ export declare const getSystemInfo: (dockerode: Dockerode) => Promise<SystemInfo>;
9
+ type NodeInfo = {
10
+ version: string;
11
+ architecture: string;
12
+ platform: string;
13
+ };
14
+ export type DockerComposeInfo = {
15
+ version: string;
16
+ };
17
+ export {};