@milaboratories/pl-deployments 2.15.7 → 2.15.9

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 (106) hide show
  1. package/README.md +18 -5
  2. package/dist/common/os_and_arch.cjs +19 -19
  3. package/dist/common/os_and_arch.cjs.map +1 -1
  4. package/dist/common/os_and_arch.js +19 -19
  5. package/dist/common/os_and_arch.js.map +1 -1
  6. package/dist/common/pl_binary.cjs +9 -9
  7. package/dist/common/pl_binary.cjs.map +1 -1
  8. package/dist/common/pl_binary.d.ts +6 -6
  9. package/dist/common/pl_binary.d.ts.map +1 -1
  10. package/dist/common/pl_binary.js +9 -9
  11. package/dist/common/pl_binary.js.map +1 -1
  12. package/dist/common/pl_binary_download.cjs +16 -16
  13. package/dist/common/pl_binary_download.cjs.map +1 -1
  14. package/dist/common/pl_binary_download.d.ts +6 -6
  15. package/dist/common/pl_binary_download.d.ts.map +1 -1
  16. package/dist/common/pl_binary_download.js +16 -16
  17. package/dist/common/pl_binary_download.js.map +1 -1
  18. package/dist/common/pl_version.cjs +1 -1
  19. package/dist/common/pl_version.cjs.map +1 -1
  20. package/dist/common/pl_version.js +1 -1
  21. package/dist/common/pl_version.js.map +1 -1
  22. package/dist/index.d.ts +5 -5
  23. package/dist/local/options.d.ts +4 -4
  24. package/dist/local/pid.cjs +1 -1
  25. package/dist/local/pid.cjs.map +1 -1
  26. package/dist/local/pid.js +1 -1
  27. package/dist/local/pid.js.map +1 -1
  28. package/dist/local/pl.cjs +26 -26
  29. package/dist/local/pl.cjs.map +1 -1
  30. package/dist/local/pl.d.ts +8 -8
  31. package/dist/local/pl.d.ts.map +1 -1
  32. package/dist/local/pl.js +26 -26
  33. package/dist/local/pl.js.map +1 -1
  34. package/dist/local/process.cjs +16 -16
  35. package/dist/local/process.cjs.map +1 -1
  36. package/dist/local/process.d.ts +2 -2
  37. package/dist/local/process.js +16 -16
  38. package/dist/local/process.js.map +1 -1
  39. package/dist/local/trace.cjs.map +1 -1
  40. package/dist/local/trace.d.ts +1 -1
  41. package/dist/local/trace.js.map +1 -1
  42. package/dist/package.json.cjs +2 -1
  43. package/dist/package.json.cjs.map +1 -1
  44. package/dist/package.json.js +2 -1
  45. package/dist/package.json.js.map +1 -1
  46. package/dist/ssh/__tests__/common-utils.d.ts +2 -2
  47. package/dist/ssh/__tests__/common-utils.d.ts.map +1 -1
  48. package/dist/ssh/connection_info.cjs +13 -7
  49. package/dist/ssh/connection_info.cjs.map +1 -1
  50. package/dist/ssh/connection_info.d.ts +1 -1
  51. package/dist/ssh/connection_info.d.ts.map +1 -1
  52. package/dist/ssh/connection_info.js +13 -7
  53. package/dist/ssh/connection_info.js.map +1 -1
  54. package/dist/ssh/pl.cjs +79 -76
  55. package/dist/ssh/pl.cjs.map +1 -1
  56. package/dist/ssh/pl.d.ts +18 -18
  57. package/dist/ssh/pl.d.ts.map +1 -1
  58. package/dist/ssh/pl.js +79 -76
  59. package/dist/ssh/pl.js.map +1 -1
  60. package/dist/ssh/pl_paths.cjs +13 -13
  61. package/dist/ssh/pl_paths.cjs.map +1 -1
  62. package/dist/ssh/pl_paths.d.ts.map +1 -1
  63. package/dist/ssh/pl_paths.js +13 -13
  64. package/dist/ssh/pl_paths.js.map +1 -1
  65. package/dist/ssh/ssh.cjs +43 -40
  66. package/dist/ssh/ssh.cjs.map +1 -1
  67. package/dist/ssh/ssh.d.ts +9 -9
  68. package/dist/ssh/ssh.d.ts.map +1 -1
  69. package/dist/ssh/ssh.js +43 -40
  70. package/dist/ssh/ssh.js.map +1 -1
  71. package/dist/ssh/ssh_errors.cjs +7 -5
  72. package/dist/ssh/ssh_errors.cjs.map +1 -1
  73. package/dist/ssh/ssh_errors.d.ts.map +1 -1
  74. package/dist/ssh/ssh_errors.js +7 -5
  75. package/dist/ssh/ssh_errors.js.map +1 -1
  76. package/dist/ssh/supervisord.cjs +15 -13
  77. package/dist/ssh/supervisord.cjs.map +1 -1
  78. package/dist/ssh/supervisord.d.ts +2 -2
  79. package/dist/ssh/supervisord.d.ts.map +1 -1
  80. package/dist/ssh/supervisord.js +15 -13
  81. package/dist/ssh/supervisord.js.map +1 -1
  82. package/package.json +38 -37
  83. package/src/common/os_and_arch.ts +19 -19
  84. package/src/common/pl_binary.ts +30 -27
  85. package/src/common/pl_binary_download.ts +80 -59
  86. package/src/common/pl_version.ts +2 -2
  87. package/src/index.ts +5 -5
  88. package/src/local/config.test.yaml +19 -19
  89. package/src/local/options.ts +4 -4
  90. package/src/local/pid.ts +4 -4
  91. package/src/local/pl.test.ts +245 -253
  92. package/src/local/pl.ts +45 -50
  93. package/src/local/process.ts +21 -21
  94. package/src/local/trace.ts +1 -1
  95. package/src/ssh/__tests__/common-utils.ts +21 -19
  96. package/src/ssh/__tests__/pl-docker.test.ts +68 -59
  97. package/src/ssh/__tests__/ssh-docker.test.ts +152 -90
  98. package/src/ssh/__tests__/ssh-upload.test.ts +42 -31
  99. package/src/ssh/connection_info.ts +33 -27
  100. package/src/ssh/pl.test.ts +15 -13
  101. package/src/ssh/pl.ts +228 -143
  102. package/src/ssh/pl_paths.ts +22 -18
  103. package/src/ssh/ssh.ts +151 -74
  104. package/src/ssh/ssh_errors.test.ts +39 -39
  105. package/src/ssh/ssh_errors.ts +8 -6
  106. package/src/ssh/supervisord.ts +28 -28
package/src/local/pl.ts CHANGED
@@ -1,27 +1,22 @@
1
- import type { ProcessOptions } from './process';
2
- import {
3
- isProcessAlive,
4
- processStop,
5
- processWaitStopped,
6
- processRun,
7
- } from './process';
8
- import type { PlBinarySource } from '../common/pl_binary';
9
- import { newDefaultPlBinarySource, resolveLocalPlBinaryPath } from '../common/pl_binary';
10
- import type { MiLogger } from '@milaboratories/ts-helpers';
11
- import { notEmpty } from '@milaboratories/ts-helpers';
12
- import type { ChildProcess, SpawnOptions } from 'node:child_process';
13
- import { filePid, readPid, writePid } from './pid';
14
- import type { Trace } from './trace';
15
- import { withTrace } from './trace';
16
- import upath from 'upath';
17
- import fsp from 'node:fs/promises';
18
- import type { Required } from 'utility-types';
19
- import * as os from 'node:os';
20
- import type { ProxySettings } from '@milaboratories/pl-http';
21
- import { defaultHttpDispatcher } from '@milaboratories/pl-http';
22
- import { parseHttpAuth } from '@milaboratories/pl-model-common';
23
-
24
- export const LocalConfigYaml = 'config-local.yaml';
1
+ import type { ProcessOptions } from "./process";
2
+ import { isProcessAlive, processStop, processWaitStopped, processRun } from "./process";
3
+ import type { PlBinarySource } from "../common/pl_binary";
4
+ import { newDefaultPlBinarySource, resolveLocalPlBinaryPath } from "../common/pl_binary";
5
+ import type { MiLogger } from "@milaboratories/ts-helpers";
6
+ import { notEmpty } from "@milaboratories/ts-helpers";
7
+ import type { ChildProcess, SpawnOptions } from "node:child_process";
8
+ import { filePid, readPid, writePid } from "./pid";
9
+ import type { Trace } from "./trace";
10
+ import { withTrace } from "./trace";
11
+ import upath from "upath";
12
+ import fsp from "node:fs/promises";
13
+ import type { Required } from "utility-types";
14
+ import * as os from "node:os";
15
+ import type { ProxySettings } from "@milaboratories/pl-http";
16
+ import { defaultHttpDispatcher } from "@milaboratories/pl-http";
17
+ import { parseHttpAuth } from "@milaboratories/pl-model-common";
18
+
19
+ export const LocalConfigYaml = "config-local.yaml";
25
20
 
26
21
  /**
27
22
  * Represents a local running pl-core,
@@ -50,7 +45,7 @@ export class LocalPl {
50
45
  await withTrace(this.logger, async (trace, t) => {
51
46
  this.wasStopped = false;
52
47
  const instance = processRun(this.logger, this.startOptions);
53
- instance.on('error', (e: any) => {
48
+ instance.on("error", (e: any) => {
54
49
  this.logger.error(
55
50
  `error '${e}', while running platforma, started opts: ${JSON.stringify(this.debugInfo())}`,
56
51
  );
@@ -61,7 +56,7 @@ export class LocalPl {
61
56
  if (this.onCloseAndErrorNoStop !== undefined && !this.wasStopped)
62
57
  void this.onCloseAndErrorNoStop(this);
63
58
  });
64
- instance.on('close', () => {
59
+ instance.on("close", () => {
65
60
  this.logger.warn(`platforma was closed, started opts: ${JSON.stringify(this.debugInfo())}`);
66
61
 
67
62
  // keep in mind there are no awaits here, it will be asynchronous
@@ -71,11 +66,11 @@ export class LocalPl {
71
66
  void this.onCloseAndErrorNoStop(this);
72
67
  });
73
68
 
74
- trace('started', true);
69
+ trace("started", true);
75
70
 
76
- const pidFile = trace('pidFile', filePid(this.workingDir));
77
- trace('pid', notEmpty(instance.pid));
78
- trace('pidWritten', await writePid(pidFile, notEmpty(instance.pid)));
71
+ const pidFile = trace("pidFile", filePid(this.workingDir));
72
+ trace("pid", notEmpty(instance.pid));
73
+ trace("pidWritten", await writePid(pidFile, notEmpty(instance.pid)));
79
74
 
80
75
  this.nRuns++;
81
76
  this.instance = instance;
@@ -143,7 +138,7 @@ export type LocalPlOptions = {
143
138
  readonly onCloseAndErrorNoStop?: (pl: LocalPl) => Promise<void>;
144
139
  };
145
140
 
146
- export type LocalPlOptionsFull = Required<LocalPlOptions, 'plBinary' | 'spawnOptions' | 'closeOld'>;
141
+ export type LocalPlOptionsFull = Required<LocalPlOptions, "plBinary" | "spawnOptions" | "closeOld">;
147
142
 
148
143
  /**
149
144
  * Starts pl-core, if the option was provided downloads a binary, reads license environments etc.
@@ -157,12 +152,12 @@ export async function localPlatformaInit(logger: MiLogger, _ops: LocalPlOptions)
157
152
  const ops = mergeDefaultOps(_ops, numCpu);
158
153
 
159
154
  return await withTrace(logger, async (trace, t) => {
160
- trace('startOptions', { ...ops, config: 'too wordy' });
155
+ trace("startOptions", { ...ops, config: "too wordy" });
161
156
 
162
157
  const workDir = upath.resolve(ops.workingDir);
163
158
 
164
159
  if (ops.closeOld) {
165
- trace('closeOld', await localPlatformaReadPidAndStop(logger, workDir));
160
+ trace("closeOld", await localPlatformaReadPidAndStop(logger, workDir));
166
161
  }
167
162
 
168
163
  const configPath = upath.join(workDir, LocalConfigYaml);
@@ -170,14 +165,14 @@ export async function localPlatformaInit(logger: MiLogger, _ops: LocalPlOptions)
170
165
  logger.info(`writing configuration '${configPath}'...`);
171
166
  await fsp.writeFile(configPath, ops.config);
172
167
 
173
- const plBinPath = upath.join(workDir, 'binaries');
168
+ const plBinPath = upath.join(workDir, "binaries");
174
169
  const baseBinaryPath = await resolveLocalPlBinaryPath({
175
170
  logger,
176
171
  downloadDir: plBinPath,
177
172
  src: ops.plBinary,
178
173
  dispatcher: defaultHttpDispatcher(ops.proxy),
179
174
  });
180
- const binaryPath = trace('binaryPath', upath.join('binaries', baseBinaryPath));
175
+ const binaryPath = trace("binaryPath", upath.join("binaries", baseBinaryPath));
181
176
 
182
177
  const env = { ...process.env };
183
178
 
@@ -185,7 +180,7 @@ export async function localPlatformaInit(logger: MiLogger, _ops: LocalPlOptions)
185
180
  const url = new URL(ops.proxy.url);
186
181
  if (ops.proxy.auth) {
187
182
  const parsed = parseHttpAuth(ops.proxy.auth);
188
- if (parsed.scheme !== 'Basic') {
183
+ if (parsed.scheme !== "Basic") {
189
184
  throw new Error(`\
190
185
  Unsupported auth scheme: ${parsed.scheme}. \
191
186
  Only Basic auth is supported by the backend.`);
@@ -198,7 +193,7 @@ Only Basic auth is supported by the backend.`);
198
193
  }
199
194
 
200
195
  const processOpts = plProcessOps(binaryPath, configPath, ops, workDir, env);
201
- trace('processOpts', {
196
+ trace("processOpts", {
202
197
  cmd: processOpts.cmd,
203
198
  args: processOpts.args,
204
199
  cwd: processOpts.opts.cwd,
@@ -227,18 +222,18 @@ async function localPlatformaReadPidAndStop(
227
222
  workingDir: string,
228
223
  ): Promise<Record<string, any>> {
229
224
  return await withTrace(logger, async (trace, t) => {
230
- const file = trace('pidFilePath', filePid(workingDir));
225
+ const file = trace("pidFilePath", filePid(workingDir));
231
226
 
232
- const oldPid = trace('pid', await readPid(file));
233
- const alive = trace('wasAlive', await isProcessAlive(oldPid));
227
+ const oldPid = trace("pid", await readPid(file));
228
+ const alive = trace("wasAlive", await isProcessAlive(oldPid));
234
229
 
235
230
  if (oldPid !== undefined && alive) {
236
- trace('stopped', processStop(oldPid));
231
+ trace("stopped", processStop(oldPid));
237
232
  try {
238
- trace('waitStopped', await processWaitStopped(oldPid, 15_000)); // larger, that 10s we provide to backend in config.
239
- } catch (_e) {
240
- trace('forceStopped', processStop(oldPid, true));
241
- trace('waitForceStopped', await processWaitStopped(oldPid, 5_000));
233
+ trace("waitStopped", await processWaitStopped(oldPid, 15_000)); // larger, that 10s we provide to backend in config.
234
+ } catch {
235
+ trace("forceStopped", processStop(oldPid, true));
236
+ trace("waitForceStopped", await processWaitStopped(oldPid, 5_000));
242
237
  }
243
238
  }
244
239
 
@@ -269,12 +264,12 @@ export function mergeDefaultOps(ops: LocalPlOptions, numCpu: number): LocalPlOpt
269
264
 
270
265
  if (ops.spawnOptions) {
271
266
  const withoutEnv = { ...ops.spawnOptions };
272
- delete withoutEnv['env'];
267
+ delete withoutEnv["env"];
273
268
  result.spawnOptions = { ...result.spawnOptions, ...withoutEnv };
274
269
  }
275
270
 
276
271
  const withoutSpawnOps = { ...ops };
277
- delete withoutSpawnOps['spawnOptions'];
272
+ delete withoutSpawnOps["spawnOptions"];
278
273
 
279
274
  return { ...result, ...withoutSpawnOps };
280
275
  }
@@ -290,11 +285,11 @@ export function plProcessOps(
290
285
  ): ProcessOptions {
291
286
  const result: ProcessOptions = {
292
287
  cmd: binaryPath,
293
- args: ['--config', configPath],
288
+ args: ["--config", configPath],
294
289
  opts: {
295
290
  env: { ...defaultEnv },
296
291
  cwd: workDir,
297
- stdio: ['pipe', 'ignore', 'inherit'],
292
+ stdio: ["pipe", "ignore", "inherit"],
298
293
  windowsHide: true, // hide a terminal on Windows
299
294
  },
300
295
  };
@@ -304,7 +299,7 @@ export function plProcessOps(
304
299
  }
305
300
 
306
301
  const withoutEnv = { ...ops.spawnOptions };
307
- delete withoutEnv['env'];
302
+ delete withoutEnv["env"];
308
303
  result.opts = { ...result.opts, ...withoutEnv };
309
304
 
310
305
  return result;
@@ -1,8 +1,8 @@
1
- import type { SpawnOptions, ChildProcess } from 'node:child_process';
2
- import { spawn } from 'node:child_process';
3
- import { execSync } from 'node:child_process';
4
- import type { MiLogger } from '@milaboratories/ts-helpers';
5
- import { sleep } from '@milaboratories/ts-helpers';
1
+ import type { SpawnOptions, ChildProcess } from "node:child_process";
2
+ import { spawn } from "node:child_process";
3
+ import { execSync } from "node:child_process";
4
+ import type { MiLogger } from "@milaboratories/ts-helpers";
5
+ import { sleep } from "@milaboratories/ts-helpers";
6
6
 
7
7
  export type ProcessOptions = {
8
8
  cmd: string;
@@ -15,7 +15,7 @@ export function processRun(logger: MiLogger, opts: ProcessOptions): ChildProcess
15
15
  cmd: ${JSON.stringify([opts.cmd, ...opts.args])}
16
16
  wd: ${opts.opts.cwd}`);
17
17
 
18
- logger.info(' spawning child process');
18
+ logger.info(" spawning child process");
19
19
  return spawn(opts.cmd, opts.args, opts.opts);
20
20
  }
21
21
 
@@ -26,47 +26,47 @@ export async function isProcessAlive(pid: number) {
26
26
 
27
27
  // Check we look at 'platforma' to not kill wrong process.
28
28
  const processName = getProcessName(pid);
29
- if (process.platform === 'win32') {
30
- return processName === 'platforma.exe'; // process name does not contain path to the file.
29
+ if (process.platform === "win32") {
30
+ return processName === "platforma.exe"; // process name does not contain path to the file.
31
31
  }
32
32
 
33
33
  // Linux and Mac OS X behave differently (so can different Linux distributions).
34
34
  // Process name can contain original path to the binary file or just its name.
35
- return processName.endsWith('/platforma') || processName === 'platforma';
36
- } catch (_e) {
35
+ return processName.endsWith("/platforma") || processName === "platforma";
36
+ } catch {
37
37
  return false;
38
38
  }
39
39
  }
40
40
 
41
41
  function getProcessName(pid: number): string {
42
42
  try {
43
- if (process.platform === 'win32') {
43
+ if (process.platform === "win32") {
44
44
  // Windows: use tasklist command
45
- const output = execSync(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { encoding: 'utf8' });
46
- const lines = output.trim().split('\n');
47
- if (lines.length > 0 && lines[0].includes(',')) {
48
- const parts = lines[0].split(',');
45
+ const output = execSync(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { encoding: "utf8" });
46
+ const lines = output.trim().split("\n");
47
+ if (lines.length > 0 && lines[0].includes(",")) {
48
+ const parts = lines[0].split(",");
49
49
  if (parts.length >= 1) {
50
50
  // Remove quotes and get the executable name
51
- const exeName = parts[0].replace(/^"|"$/g, '').trim();
51
+ const exeName = parts[0].replace(/^"|"$/g, "").trim();
52
52
  return exeName;
53
53
  }
54
54
  }
55
55
  } else {
56
56
  // Unix-like systems: use ps command
57
- const output = execSync(`ps -p ${pid} -o comm=`, { encoding: 'utf8' });
57
+ const output = execSync(`ps -p ${pid} -o comm=`, { encoding: "utf8" });
58
58
  const processName = output.trim();
59
59
  return processName;
60
60
  }
61
- } catch (_error) {
61
+ } catch {
62
62
  // If we can't get the process name, return empty string
63
- return '';
63
+ return "";
64
64
  }
65
- return '';
65
+ return "";
66
66
  }
67
67
 
68
68
  export function processStop(pid: number, force: boolean = false) {
69
- return process.kill(pid, force ? 'SIGKILL' : 'SIGINT');
69
+ return process.kill(pid, force ? "SIGKILL" : "SIGINT");
70
70
  }
71
71
 
72
72
  export async function processWaitStopped(pid: number, maxMs: number) {
@@ -1,4 +1,4 @@
1
- import type { MiLogger } from '@milaboratories/ts-helpers';
1
+ import type { MiLogger } from "@milaboratories/ts-helpers";
2
2
 
3
3
  /** Records all inputs and outputs of one's choice, so if the error happened
4
4
  * one can check how it was by just printing this structure. */
@@ -1,33 +1,32 @@
1
- import type { StartedTestContainer } from 'testcontainers';
2
- import { GenericContainer } from 'testcontainers';
3
- import { readFileSync, existsSync } from 'node:fs';
4
- import path from 'node:path';
5
- import type { ConnectConfig } from 'ssh2';
6
- import fs from 'node:fs';
1
+ import type { StartedTestContainer } from "testcontainers";
2
+ import { GenericContainer } from "testcontainers";
3
+ import { readFileSync, existsSync } from "node:fs";
4
+ import path from "node:path";
5
+ import type { ConnectConfig } from "ssh2";
6
+ import fs from "node:fs";
7
7
 
8
8
  const SSH_PORT = [22, 3001];
9
9
 
10
- export const testAssetsPath = path.resolve(__dirname, '..', '..', '..', 'test-assets');
10
+ export const testAssetsPath = path.resolve(__dirname, "..", "..", "..", "test-assets");
11
11
 
12
- const publicKeyPath = path.resolve(testAssetsPath, 'public-key.pem');
13
- const privateKeyPath = path.resolve(testAssetsPath, 'private-key.pem');
12
+ const publicKeyPath = path.resolve(testAssetsPath, "public-key.pem");
13
+ const privateKeyPath = path.resolve(testAssetsPath, "private-key.pem");
14
14
  if (!existsSync(publicKeyPath) || !existsSync(privateKeyPath)) {
15
- console.error('SSH keys does not exist, see pl-deployments/README.md and regenerate them');
15
+ console.error("SSH keys does not exist, see pl-deployments/README.md and regenerate them");
16
16
  process.exit(1);
17
17
  }
18
18
 
19
19
  export function readPrivateKey(): string {
20
- return readFileSync(privateKeyPath, { encoding: 'utf-8' });
20
+ return readFileSync(privateKeyPath, { encoding: "utf-8" });
21
21
  }
22
22
 
23
23
  export async function initContainer(name: string): Promise<StartedTestContainer> {
24
24
  const imageName = `pl-ssh-test-container-${name}:1.0.0`;
25
25
  const containerName = `pl-ssh-test-${name}`;
26
26
 
27
- console.log('No worries, creating a new container');
27
+ console.log("No worries, creating a new container");
28
28
 
29
- const container = await GenericContainer
30
- .fromDockerfile(path.resolve(__dirname, '..', '..', '..'))
29
+ const container = await GenericContainer.fromDockerfile(path.resolve(__dirname, "..", "..", ".."))
31
30
  .withCache(true)
32
31
  .build(imageName, { deleteOnExit: false });
33
32
 
@@ -46,7 +45,7 @@ export function getContainerHostAndPort(container: StartedTestContainer) {
46
45
  }
47
46
 
48
47
  function logToFile(message: string) {
49
- const logFileName = 'log.txt';
48
+ const logFileName = "log.txt";
50
49
  const logFilePath = path.join(testAssetsPath, logFileName);
51
50
 
52
51
  const timestamp = new Date().toISOString();
@@ -54,20 +53,23 @@ function logToFile(message: string) {
54
53
 
55
54
  fs.appendFile(logFilePath, logMessage, (err) => {
56
55
  if (err) {
57
- console.error('Error writing to log file:', err);
56
+ console.error("Error writing to log file:", err);
58
57
  }
59
58
  });
60
59
  }
61
60
 
62
- export function getConnectionForSsh(container: StartedTestContainer, debug: boolean = false): ConnectConfig {
61
+ export function getConnectionForSsh(
62
+ container: StartedTestContainer,
63
+ debug: boolean = false,
64
+ ): ConnectConfig {
63
65
  const hostData = getContainerHostAndPort(container);
64
66
  const privateKey = readPrivateKey();
65
67
  const config = {
66
68
  host: hostData.host,
67
69
  port: hostData.port,
68
- username: 'pl-doctor',
70
+ username: "pl-doctor",
69
71
  privateKey: privateKey,
70
- passphrase: 'password',
72
+ passphrase: "password",
71
73
  debug: debug ? logToFile : undefined,
72
74
  };
73
75
  logToFile(JSON.stringify(config, null, 4));