@milaboratories/pl-deployments 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +322 -261
- package/dist/index.mjs.map +1 -1
- package/dist/ssh/pl.d.ts +1 -0
- package/dist/ssh/pl.d.ts.map +1 -1
- package/dist/ssh/ssh.d.ts +10 -0
- package/dist/ssh/ssh.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/ssh/__tests__/ssh-docker.test.ts +19 -0
- package/src/ssh/pl.ts +17 -6
- package/src/ssh/ssh.ts +81 -2
package/dist/index.mjs
CHANGED
|
@@ -5,17 +5,17 @@ import { spawn as G } from "node:child_process";
|
|
|
5
5
|
import { sleep as S, fileExists as f, assertNever as N, notEmpty as p } from "@milaboratories/ts-helpers";
|
|
6
6
|
import E from "node:fs";
|
|
7
7
|
import w, { readFile as Z } from "node:fs/promises";
|
|
8
|
-
import
|
|
8
|
+
import u from "upath";
|
|
9
9
|
import { request as V } from "undici";
|
|
10
10
|
import { Readable as Y, Writable as Q } from "node:stream";
|
|
11
11
|
import { text as X } from "node:stream/consumers";
|
|
12
12
|
import * as tt from "tar";
|
|
13
13
|
import rt from "decompress";
|
|
14
|
-
import
|
|
14
|
+
import k from "node:os";
|
|
15
15
|
import et, { Client as v } from "ssh2";
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import { generateSshPlConfigs as
|
|
16
|
+
import U from "node:net";
|
|
17
|
+
import it from "node:dns";
|
|
18
|
+
import { generateSshPlConfigs as ot, getFreePort as g } from "@milaboratories/pl-config";
|
|
19
19
|
import { randomBytes as nt } from "node:crypto";
|
|
20
20
|
function st(s, r) {
|
|
21
21
|
return s.info(`Running:
|
|
@@ -29,7 +29,7 @@ async function C(s) {
|
|
|
29
29
|
return !1;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function T(s) {
|
|
33
33
|
return process.kill(s, "SIGINT");
|
|
34
34
|
}
|
|
35
35
|
async function B(s, r) {
|
|
@@ -39,7 +39,7 @@ async function B(s, r) {
|
|
|
39
39
|
throw new Error(`The process did not stopped after ${r} ms.`);
|
|
40
40
|
}
|
|
41
41
|
const at = ["linux", "macos", "windows"];
|
|
42
|
-
function
|
|
42
|
+
function H(s) {
|
|
43
43
|
switch (s.toLowerCase()) {
|
|
44
44
|
case "darwin":
|
|
45
45
|
return "macos";
|
|
@@ -54,7 +54,7 @@ function _(s) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
const ct = ["amd64", "arm64"];
|
|
57
|
-
function
|
|
57
|
+
function $(s) {
|
|
58
58
|
switch (s) {
|
|
59
59
|
case "aarch64":
|
|
60
60
|
case "aarch64_be":
|
|
@@ -69,63 +69,63 @@ function g(s) {
|
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
async function lt(s, r, t, e,
|
|
73
|
-
const n = ut(t, e, r,
|
|
74
|
-
return await
|
|
72
|
+
async function lt(s, r, t, e, i, o) {
|
|
73
|
+
const n = ut(t, e, r, $(i), H(o)), { archiveUrl: a, archivePath: c } = n;
|
|
74
|
+
return await _(s, a, c), n;
|
|
75
75
|
}
|
|
76
|
-
async function ht(s, r, t, e,
|
|
77
|
-
const
|
|
78
|
-
return await
|
|
76
|
+
async function ht(s, r, t, e, i) {
|
|
77
|
+
const o = dt(t, r, $(e), H(i)), { archiveUrl: n, archivePath: a, archiveType: c, targetFolder: l, binaryPath: h } = o;
|
|
78
|
+
return await _(s, n, a), await pt(s, a, c, l), o;
|
|
79
79
|
}
|
|
80
|
-
function ut(s, r, t, e,
|
|
81
|
-
const
|
|
80
|
+
function ut(s, r, t, e, i) {
|
|
81
|
+
const o = `${r}-${e}`, n = I[i], a = `${o}.${n}`, c = `https://cdn.platforma.bio/software/${s}/${i}/${a}`, l = u.join(t, a), h = u.join(t, o);
|
|
82
82
|
return {
|
|
83
83
|
archiveUrl: c,
|
|
84
84
|
archivePath: l,
|
|
85
85
|
archiveType: n,
|
|
86
|
-
targetFolder:
|
|
87
|
-
baseName:
|
|
86
|
+
targetFolder: h,
|
|
87
|
+
baseName: o
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
function dt(s, r, t, e) {
|
|
91
|
-
const
|
|
91
|
+
const i = `pl-${s}-${t}`, o = I[e], n = `${i}.${o}`, a = `https://cdn.platforma.bio/software/pl/${e}/${n}`, c = u.join(r, n), l = u.join(r, i), h = u.join(i, "binaries", ft[e]);
|
|
92
92
|
return {
|
|
93
93
|
archiveUrl: a,
|
|
94
94
|
archivePath: c,
|
|
95
|
-
archiveType:
|
|
95
|
+
archiveType: o,
|
|
96
96
|
targetFolder: l,
|
|
97
|
-
binaryPath:
|
|
98
|
-
baseName:
|
|
97
|
+
binaryPath: h,
|
|
98
|
+
baseName: i
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
async function
|
|
101
|
+
async function _(s, r, t) {
|
|
102
102
|
const e = {};
|
|
103
103
|
e.dstArchive = t;
|
|
104
104
|
try {
|
|
105
105
|
if (e.fileExisted = await f(t), e.fileExisted)
|
|
106
106
|
return s.info(`Platforma Backend archive download skipped: '${t}' already exists`), e;
|
|
107
|
-
await w.mkdir(
|
|
107
|
+
await w.mkdir(u.dirname(t), { recursive: !0 }), e.dirnameCreated = !0, s.info(`Downloading archive:
|
|
108
108
|
URL: ${r}
|
|
109
109
|
Save to: ${t}`);
|
|
110
|
-
const { body:
|
|
111
|
-
if (e.statusCode =
|
|
112
|
-
const n = await X(
|
|
113
|
-
throw e.errorMsg = `failed to download archive: ${
|
|
110
|
+
const { body: i, statusCode: o } = await V(r);
|
|
111
|
+
if (e.statusCode = o, o != 200) {
|
|
112
|
+
const n = await X(i);
|
|
113
|
+
throw e.errorMsg = `failed to download archive: ${o}, response: ${n.slice(0, 1e3)}`, s.error(e.errorMsg), new Error(e.errorMsg);
|
|
114
114
|
}
|
|
115
|
-
return e.tmpPath = t + ".tmp", await Y.toWeb(
|
|
116
|
-
} catch (
|
|
117
|
-
const
|
|
118
|
-
throw s.error(
|
|
115
|
+
return e.tmpPath = t + ".tmp", await Y.toWeb(i).pipeTo(Q.toWeb(E.createWriteStream(e.tmpPath))), e.wroteTmp = !0, e.tmpExisted = await f(e.tmpPath), await w.rename(e.tmpPath, t), e.renamed = !0, e.newExisted = await f(t), e;
|
|
116
|
+
} catch (i) {
|
|
117
|
+
const o = `downloadArchive: error ${JSON.stringify(i)} occurred, state: ${JSON.stringify(e)}`;
|
|
118
|
+
throw s.error(o), new Error(o);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
const wt = ".ok";
|
|
122
122
|
async function pt(s, r, t, e) {
|
|
123
123
|
if (s.info("extracting archive..."), s.info(` archive path: '${r}'`), s.info(` target dir: '${e}'`), !await f(r)) {
|
|
124
|
-
const
|
|
125
|
-
throw s.error(
|
|
124
|
+
const o = `Platforma Backend binary archive not found at '${r}'`;
|
|
125
|
+
throw s.error(o), new Error(o);
|
|
126
126
|
}
|
|
127
|
-
const
|
|
128
|
-
if (await f(
|
|
127
|
+
const i = u.join(e, wt);
|
|
128
|
+
if (await f(i)) {
|
|
129
129
|
s.info(`Platforma Backend binaries unpack skipped: '${e}' exists`);
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
@@ -147,7 +147,7 @@ async function pt(s, r, t, e) {
|
|
|
147
147
|
default:
|
|
148
148
|
N(t);
|
|
149
149
|
}
|
|
150
|
-
await w.writeFile(
|
|
150
|
+
await w.writeFile(i, "ok"), s.info(" ... unpack done.");
|
|
151
151
|
}
|
|
152
152
|
const I = {
|
|
153
153
|
linux: "tgz",
|
|
@@ -158,16 +158,16 @@ const I = {
|
|
|
158
158
|
macos: "platforma",
|
|
159
159
|
windows: "platforma.exe"
|
|
160
160
|
};
|
|
161
|
-
function
|
|
161
|
+
function F() {
|
|
162
162
|
return "1.18.3";
|
|
163
163
|
}
|
|
164
164
|
function mt() {
|
|
165
|
-
return { type: "Download", version:
|
|
165
|
+
return { type: "Download", version: F() };
|
|
166
166
|
}
|
|
167
|
-
async function
|
|
167
|
+
async function gt(s, r, t) {
|
|
168
168
|
switch (t.type) {
|
|
169
169
|
case "Download":
|
|
170
|
-
return (await ht(s, r, t.version,
|
|
170
|
+
return (await ht(s, r, t.version, k.arch(), k.platform())).binaryPath;
|
|
171
171
|
case "Local":
|
|
172
172
|
return t.path;
|
|
173
173
|
default:
|
|
@@ -175,9 +175,9 @@ async function yt(s, r, t) {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
function j(s) {
|
|
178
|
-
return
|
|
178
|
+
return u.join(s, "pl_pid");
|
|
179
179
|
}
|
|
180
|
-
async function
|
|
180
|
+
async function yt(s) {
|
|
181
181
|
if (!await f(s))
|
|
182
182
|
return;
|
|
183
183
|
const r = await w.readFile(s);
|
|
@@ -192,41 +192,41 @@ function Pt() {
|
|
|
192
192
|
function vt(s, r, t) {
|
|
193
193
|
return s[r] = t, t;
|
|
194
194
|
}
|
|
195
|
-
async function
|
|
195
|
+
async function b(s, r) {
|
|
196
196
|
const t = Pt();
|
|
197
197
|
try {
|
|
198
|
-
return await r((
|
|
198
|
+
return await r((i, o) => vt(t, i, o), t);
|
|
199
199
|
} catch (e) {
|
|
200
200
|
throw s.error(`error ${e} while doing traced operation, state: ${JSON.stringify(t)}`), e;
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
const St = "config-local.yaml";
|
|
204
204
|
class Et {
|
|
205
|
-
constructor(r, t, e,
|
|
205
|
+
constructor(r, t, e, i, o, n, a, c) {
|
|
206
206
|
d(this, "instance");
|
|
207
207
|
d(this, "pid");
|
|
208
208
|
d(this, "nRuns", 0);
|
|
209
209
|
d(this, "lastRunHistory", {});
|
|
210
210
|
d(this, "wasStopped", !1);
|
|
211
|
-
this.logger = r, this.workingDir = t, this.startOptions = e, this.initialStartHistory =
|
|
211
|
+
this.logger = r, this.workingDir = t, this.startOptions = e, this.initialStartHistory = i, this.onClose = o, this.onError = n, this.onCloseAndError = a, this.onCloseAndErrorNoStop = c;
|
|
212
212
|
}
|
|
213
213
|
async start() {
|
|
214
|
-
await
|
|
214
|
+
await b(this.logger, async (r, t) => {
|
|
215
215
|
this.wasStopped = !1;
|
|
216
216
|
const e = st(this.logger, this.startOptions);
|
|
217
|
-
e.on("error", (
|
|
217
|
+
e.on("error", (o) => {
|
|
218
218
|
this.logger.error(
|
|
219
|
-
`error '${
|
|
219
|
+
`error '${o}', while running platforma, started opts: ${JSON.stringify(this.debugInfo())}`
|
|
220
220
|
), this.onError !== void 0 && this.onError(this), this.onCloseAndError !== void 0 && this.onCloseAndError(this), this.onCloseAndErrorNoStop !== void 0 && !this.wasStopped && this.onCloseAndErrorNoStop(this);
|
|
221
221
|
}), e.on("close", () => {
|
|
222
222
|
this.logger.warn(`platforma was closed, started opts: ${JSON.stringify(this.debugInfo())}`), this.onClose !== void 0 && this.onClose(this), this.onCloseAndError !== void 0 && this.onCloseAndError(this), this.onCloseAndErrorNoStop !== void 0 && !this.wasStopped && this.onCloseAndErrorNoStop(this);
|
|
223
223
|
}), r("started", !0);
|
|
224
|
-
const
|
|
225
|
-
r("pid", p(e.pid)), r("pidWritten", await $t(
|
|
224
|
+
const i = r("pidFile", j(this.workingDir));
|
|
225
|
+
r("pid", p(e.pid)), r("pidWritten", await $t(i, p(e.pid))), this.nRuns++, this.instance = e, this.pid = e.pid, this.lastRunHistory = t;
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
stop() {
|
|
229
|
-
this.wasStopped = !0,
|
|
229
|
+
this.wasStopped = !0, T(p(this.pid));
|
|
230
230
|
}
|
|
231
231
|
async waitStopped() {
|
|
232
232
|
await B(p(this.pid), 15e3);
|
|
@@ -255,18 +255,18 @@ async function Xt(s, r) {
|
|
|
255
255
|
closeOld: !0,
|
|
256
256
|
...r
|
|
257
257
|
};
|
|
258
|
-
return await
|
|
258
|
+
return await b(s, async (e, i) => {
|
|
259
259
|
e("startOptions", { ...t, config: "too wordy" });
|
|
260
|
-
const
|
|
261
|
-
t.closeOld && e("closeOld", await Ct(s,
|
|
262
|
-
const n =
|
|
260
|
+
const o = u.resolve(t.workingDir);
|
|
261
|
+
t.closeOld && e("closeOld", await Ct(s, o));
|
|
262
|
+
const n = u.join(o, St);
|
|
263
263
|
s.info(`writing configuration '${n}'...`), await w.writeFile(n, t.config);
|
|
264
|
-
const a = await
|
|
265
|
-
cmd: e("binaryPath",
|
|
264
|
+
const a = await gt(s, u.join(o, "binaries"), t.plBinary), l = {
|
|
265
|
+
cmd: e("binaryPath", u.join("binaries", a)),
|
|
266
266
|
args: ["-config", n],
|
|
267
267
|
opts: {
|
|
268
268
|
env: { ...process.env },
|
|
269
|
-
cwd:
|
|
269
|
+
cwd: o,
|
|
270
270
|
stdio: ["pipe", "ignore", "inherit"],
|
|
271
271
|
windowsHide: !0,
|
|
272
272
|
// hide a terminal on Windows
|
|
@@ -278,26 +278,26 @@ async function Xt(s, r) {
|
|
|
278
278
|
args: l.args,
|
|
279
279
|
cwd: l.opts.cwd
|
|
280
280
|
});
|
|
281
|
-
const
|
|
281
|
+
const h = new Et(
|
|
282
282
|
s,
|
|
283
283
|
t.workingDir,
|
|
284
284
|
l,
|
|
285
|
-
|
|
285
|
+
i,
|
|
286
286
|
t.onClose,
|
|
287
287
|
t.onError,
|
|
288
288
|
t.onCloseAndError,
|
|
289
289
|
t.onCloseAndErrorNoStop
|
|
290
290
|
);
|
|
291
|
-
return await
|
|
291
|
+
return await h.start(), h;
|
|
292
292
|
});
|
|
293
293
|
}
|
|
294
294
|
async function Ct(s, r) {
|
|
295
|
-
return await
|
|
296
|
-
const
|
|
297
|
-
return
|
|
295
|
+
return await b(s, async (t, e) => {
|
|
296
|
+
const i = t("pidFilePath", j(r)), o = t("pid", await yt(i)), n = t("wasAlive", await C(o));
|
|
297
|
+
return o !== void 0 && n && (t("stopped", T(o)), t("waitStopped", await B(o, 1e4))), e;
|
|
298
298
|
});
|
|
299
299
|
}
|
|
300
|
-
const
|
|
300
|
+
const Ft = {
|
|
301
301
|
keepaliveInterval: 6e4,
|
|
302
302
|
keepaliveCountMax: 10
|
|
303
303
|
};
|
|
@@ -314,10 +314,18 @@ class D {
|
|
|
314
314
|
*/
|
|
315
315
|
static async init(r, t) {
|
|
316
316
|
const e = {
|
|
317
|
-
...
|
|
317
|
+
...Ft,
|
|
318
318
|
...t
|
|
319
|
-
},
|
|
320
|
-
return await
|
|
319
|
+
}, i = new D(r, new v());
|
|
320
|
+
return await i.connect(e), i;
|
|
321
|
+
}
|
|
322
|
+
getFullHostName() {
|
|
323
|
+
var r, t;
|
|
324
|
+
return `${(r = this.config) == null ? void 0 : r.host}:${(t = this.config) == null ? void 0 : t.port}`;
|
|
325
|
+
}
|
|
326
|
+
getUserName() {
|
|
327
|
+
var r;
|
|
328
|
+
return (r = this.config) == null ? void 0 : r.username;
|
|
321
329
|
}
|
|
322
330
|
/**
|
|
323
331
|
* Connects to the SSH server using the specified configuration.
|
|
@@ -328,8 +336,8 @@ class D {
|
|
|
328
336
|
return this.config = r, new Promise((t, e) => {
|
|
329
337
|
this.client.on("ready", () => {
|
|
330
338
|
t(void 0);
|
|
331
|
-
}).on("error", (
|
|
332
|
-
e(new Error(`ssh.connect: error occurred: ${
|
|
339
|
+
}).on("error", (i) => {
|
|
340
|
+
e(new Error(`ssh.connect: error occurred: ${i}`));
|
|
333
341
|
}).on("timeout", () => {
|
|
334
342
|
e(new Error("timeout was occurred while waiting for SSH connection."));
|
|
335
343
|
}).connect(r);
|
|
@@ -342,11 +350,11 @@ class D {
|
|
|
342
350
|
*/
|
|
343
351
|
async exec(r) {
|
|
344
352
|
return new Promise((t, e) => {
|
|
345
|
-
this.client.exec(r, (
|
|
346
|
-
if (
|
|
347
|
-
return e(`ssh.exec: ${r}, error occurred: ${
|
|
353
|
+
this.client.exec(r, (i, o) => {
|
|
354
|
+
if (i)
|
|
355
|
+
return e(`ssh.exec: ${r}, error occurred: ${i}`);
|
|
348
356
|
let n = "", a = "";
|
|
349
|
-
|
|
357
|
+
o.on("close", (c) => {
|
|
350
358
|
c === 0 ? t({ stdout: n, stderr: a }) : e(new Error(`Command ${r} exited with code ${c}`));
|
|
351
359
|
}).on("data", (c) => {
|
|
352
360
|
n += c.toString();
|
|
@@ -364,20 +372,20 @@ class D {
|
|
|
364
372
|
*/
|
|
365
373
|
static async getAuthTypes(r, t) {
|
|
366
374
|
return new Promise((e) => {
|
|
367
|
-
let
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const n = this.extractAuthMethods(
|
|
375
|
+
let i = "";
|
|
376
|
+
const o = new v();
|
|
377
|
+
o.on("ready", () => {
|
|
378
|
+
o.end();
|
|
379
|
+
const n = this.extractAuthMethods(i);
|
|
372
380
|
e(n.length === 0 ? ["publickey", "password"] : n);
|
|
373
|
-
}),
|
|
374
|
-
|
|
375
|
-
}),
|
|
381
|
+
}), o.on("error", () => {
|
|
382
|
+
o.end(), e(["publickey", "password"]);
|
|
383
|
+
}), o.connect({
|
|
376
384
|
host: r,
|
|
377
385
|
port: t,
|
|
378
386
|
username: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
379
387
|
debug: (n) => {
|
|
380
|
-
|
|
388
|
+
i += `${n}
|
|
381
389
|
`;
|
|
382
390
|
}
|
|
383
391
|
});
|
|
@@ -400,16 +408,16 @@ class D {
|
|
|
400
408
|
* @returns { server: net.Server } A promise resolving with the created server instance.
|
|
401
409
|
*/
|
|
402
410
|
async forwardPort(r, t) {
|
|
403
|
-
return t = t ?? this.config, new Promise((e,
|
|
411
|
+
return t = t ?? this.config, new Promise((e, i) => {
|
|
404
412
|
if (!t) {
|
|
405
|
-
|
|
413
|
+
i("No config defined");
|
|
406
414
|
return;
|
|
407
415
|
}
|
|
408
|
-
const
|
|
416
|
+
const o = new v();
|
|
409
417
|
let n;
|
|
410
|
-
|
|
411
|
-
this.logger.info(`[SSH] Connection to ${t.host}. Remote port ${r.remotePort} will be available locally on the ${r.localPort}`), n =
|
|
412
|
-
|
|
418
|
+
o.on("ready", () => {
|
|
419
|
+
this.logger.info(`[SSH] Connection to ${t.host}. Remote port ${r.remotePort} will be available locally on the ${r.localPort}`), n = U.createServer({ pauseOnConnect: !0 }, (a) => {
|
|
420
|
+
o.forwardOut(
|
|
413
421
|
"127.0.0.1",
|
|
414
422
|
0,
|
|
415
423
|
"127.0.0.1",
|
|
@@ -425,15 +433,15 @@ class D {
|
|
|
425
433
|
}), n.listen(r.localPort, "127.0.0.1", () => {
|
|
426
434
|
this.logger.info(`[+] Port local ${r.localPort} available locally for remote port → :${r.remotePort}`), e({ server: n });
|
|
427
435
|
}), n.on("error", (a) => {
|
|
428
|
-
|
|
436
|
+
o.end(), n.close(), i(new Error(`ssh.forwardPort: server error: ${a}`));
|
|
429
437
|
}), n.on("close", () => {
|
|
430
|
-
this.logger.info(`Server closed ${JSON.stringify(r)}`),
|
|
438
|
+
this.logger.info(`Server closed ${JSON.stringify(r)}`), o && (this.logger.info("End SSH connection"), o.end());
|
|
431
439
|
});
|
|
432
|
-
}),
|
|
433
|
-
this.logger.error(`[SSH] SSH connection error, ports: ${JSON.stringify(r)}, err: ${a.message}`), n == null || n.close(),
|
|
434
|
-
}),
|
|
440
|
+
}), o.on("error", (a) => {
|
|
441
|
+
this.logger.error(`[SSH] SSH connection error, ports: ${JSON.stringify(r)}, err: ${a.message}`), n == null || n.close(), i(`ssh.forwardPort: conn.err: ${a}`);
|
|
442
|
+
}), o.on("close", () => {
|
|
435
443
|
this.logger.info(`[SSH] Connection closed, ports: ${JSON.stringify(r)}`);
|
|
436
|
-
}),
|
|
444
|
+
}), o.connect(t);
|
|
437
445
|
});
|
|
438
446
|
}
|
|
439
447
|
/**
|
|
@@ -443,7 +451,7 @@ class D {
|
|
|
443
451
|
*/
|
|
444
452
|
static async checkHostAvailability(r) {
|
|
445
453
|
return new Promise((t) => {
|
|
446
|
-
|
|
454
|
+
it.lookup(r, (e) => {
|
|
447
455
|
t(!e);
|
|
448
456
|
});
|
|
449
457
|
});
|
|
@@ -457,8 +465,8 @@ class D {
|
|
|
457
465
|
return new Promise((t, e) => {
|
|
458
466
|
try {
|
|
459
467
|
return et.utils.parseKey(r) instanceof Error && t(!0), t(!1);
|
|
460
|
-
} catch (
|
|
461
|
-
console.log("Error parsing privateKey"), e(new Error(`ssh.isPassphraseRequiredForKey: err ${
|
|
468
|
+
} catch (i) {
|
|
469
|
+
console.log("Error parsing privateKey"), e(new Error(`ssh.isPassphraseRequiredForKey: err ${i}`));
|
|
462
470
|
}
|
|
463
471
|
});
|
|
464
472
|
}
|
|
@@ -470,15 +478,15 @@ class D {
|
|
|
470
478
|
* @returns A promise resolving with `true` if the file was successfully uploaded.
|
|
471
479
|
*/
|
|
472
480
|
async uploadFile(r, t) {
|
|
473
|
-
return await this.withSftp(async (e) => new Promise((
|
|
481
|
+
return await this.withSftp(async (e) => new Promise((i, o) => {
|
|
474
482
|
e.fastPut(r, t, (n) => {
|
|
475
483
|
if (n) {
|
|
476
484
|
const a = new Error(
|
|
477
485
|
`ssh.uploadFile: err: ${n}, localPath: ${r}, remotePath: ${t}`
|
|
478
486
|
);
|
|
479
|
-
return
|
|
487
|
+
return o(a);
|
|
480
488
|
}
|
|
481
|
-
|
|
489
|
+
i(!0);
|
|
482
490
|
});
|
|
483
491
|
}));
|
|
484
492
|
}
|
|
@@ -489,48 +497,97 @@ class D {
|
|
|
489
497
|
}
|
|
490
498
|
async withSftp(r) {
|
|
491
499
|
return new Promise((t, e) => {
|
|
492
|
-
this.client.sftp((
|
|
493
|
-
if (
|
|
494
|
-
return e(new Error(`ssh.withSftp: sftp err: ${
|
|
495
|
-
r(
|
|
500
|
+
this.client.sftp((i, o) => {
|
|
501
|
+
if (i)
|
|
502
|
+
return e(new Error(`ssh.withSftp: sftp err: ${i}`));
|
|
503
|
+
r(o).then(t).catch((n) => {
|
|
496
504
|
e(new Error(`ssh.withSftp.callback: err ${n}`));
|
|
497
505
|
}).finally(() => {
|
|
498
|
-
|
|
506
|
+
o == null || o.end();
|
|
499
507
|
});
|
|
500
508
|
});
|
|
501
509
|
});
|
|
502
510
|
}
|
|
503
511
|
async writeFileOnTheServer(r, t, e = 432) {
|
|
504
|
-
return this.withSftp(async (
|
|
512
|
+
return this.withSftp(async (i) => this.writeFile(i, r, t, e));
|
|
513
|
+
}
|
|
514
|
+
async getForderStructure(r, t, e = { files: [], directories: [] }) {
|
|
515
|
+
return new Promise((i, o) => {
|
|
516
|
+
r.readdir(t, async (n, a) => {
|
|
517
|
+
if (n)
|
|
518
|
+
return o(n);
|
|
519
|
+
for (const c of a) {
|
|
520
|
+
const l = `${t}/${c.filename}`;
|
|
521
|
+
if (c.attrs.isDirectory()) {
|
|
522
|
+
e.directories.push(l);
|
|
523
|
+
try {
|
|
524
|
+
await this.getForderStructure(r, l, e);
|
|
525
|
+
} catch (h) {
|
|
526
|
+
return o(h);
|
|
527
|
+
}
|
|
528
|
+
} else
|
|
529
|
+
e.files.push(l);
|
|
530
|
+
}
|
|
531
|
+
i(e);
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
rmdir(r, t) {
|
|
536
|
+
return new Promise((e, i) => {
|
|
537
|
+
r.rmdir(t, (o) => o ? i(o) : e(!0));
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
unlink(r, t) {
|
|
541
|
+
return new Promise((e, i) => {
|
|
542
|
+
r.unlink(t, (o) => o ? i(o) : e(!0));
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
async deleteFolder(r) {
|
|
546
|
+
return this.withSftp(async (t) => {
|
|
547
|
+
try {
|
|
548
|
+
const e = await this.getForderStructure(t, r);
|
|
549
|
+
this.logger.info("ssh.deleteFolder list of files and directories"), this.logger.info(`ssh.deleteFolder list of files: ${e.files}`), this.logger.info(`ssh.deleteFolder list of directories: ${e.directories}`);
|
|
550
|
+
for (const i of e.files)
|
|
551
|
+
this.logger.info(`ssh.deleteFolder unlink file ${i}`), await this.unlink(t, i);
|
|
552
|
+
e.directories.sort((i, o) => o.length - i.length);
|
|
553
|
+
for (const i of e.directories)
|
|
554
|
+
this.logger.info(`ssh.deleteFolder rmdir ${i}`), await this.rmdir(t, i);
|
|
555
|
+
return await this.rmdir(t, r), !0;
|
|
556
|
+
} catch (e) {
|
|
557
|
+
this.logger.error(e);
|
|
558
|
+
const i = e instanceof Error ? e.message : "";
|
|
559
|
+
throw new Error(`ssh.deleteFolder: path: ${r}, message: ${i}`);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
505
562
|
}
|
|
506
563
|
async readFile(r) {
|
|
507
|
-
return this.withSftp(async (t) => new Promise((e,
|
|
508
|
-
t.readFile(r, (
|
|
509
|
-
if (
|
|
510
|
-
return
|
|
564
|
+
return this.withSftp(async (t) => new Promise((e, i) => {
|
|
565
|
+
t.readFile(r, (o, n) => {
|
|
566
|
+
if (o)
|
|
567
|
+
return i(new Error(`ssh.readFile: err occurred ${o}`));
|
|
511
568
|
e(n.toString());
|
|
512
569
|
});
|
|
513
570
|
}));
|
|
514
571
|
}
|
|
515
572
|
async chmod(r, t) {
|
|
516
|
-
return this.withSftp(async (e) => new Promise((
|
|
517
|
-
e.chmod(r, t, (n) => n ?
|
|
573
|
+
return this.withSftp(async (e) => new Promise((i, o) => {
|
|
574
|
+
e.chmod(r, t, (n) => n ? o(new Error(`ssh.chmod: ${n}, path: ${r}, mode: ${t}`)) : i(void 0));
|
|
518
575
|
}));
|
|
519
576
|
}
|
|
520
577
|
async checkFileExists(r) {
|
|
521
|
-
return this.withSftp(async (t) => new Promise((e,
|
|
522
|
-
t.stat(r, (
|
|
523
|
-
if (
|
|
524
|
-
return
|
|
578
|
+
return this.withSftp(async (t) => new Promise((e, i) => {
|
|
579
|
+
t.stat(r, (o, n) => {
|
|
580
|
+
if (o)
|
|
581
|
+
return o.code === 2 ? e(!1) : i(new Error(`ssh.checkFileExists: err ${o}`));
|
|
525
582
|
e(n.isFile());
|
|
526
583
|
});
|
|
527
584
|
}));
|
|
528
585
|
}
|
|
529
586
|
async checkPathExists(r) {
|
|
530
|
-
return this.withSftp(async (t) => new Promise((e,
|
|
531
|
-
t.stat(r, (
|
|
532
|
-
if (
|
|
533
|
-
return
|
|
587
|
+
return this.withSftp(async (t) => new Promise((e, i) => {
|
|
588
|
+
t.stat(r, (o, n) => {
|
|
589
|
+
if (o)
|
|
590
|
+
return o.code === 2 ? e({ exists: !1, isFile: !1, isDirectory: !1 }) : i(new Error(`ssh.checkPathExists: ${o}`));
|
|
534
591
|
e({
|
|
535
592
|
exists: !0,
|
|
536
593
|
isFile: n.isFile(),
|
|
@@ -539,20 +596,20 @@ class D {
|
|
|
539
596
|
});
|
|
540
597
|
}));
|
|
541
598
|
}
|
|
542
|
-
async writeFile(r, t, e,
|
|
543
|
-
return new Promise((
|
|
544
|
-
r.writeFile(t, e, { mode:
|
|
599
|
+
async writeFile(r, t, e, i = 432) {
|
|
600
|
+
return new Promise((o, n) => {
|
|
601
|
+
r.writeFile(t, e, { mode: i }, (a) => {
|
|
545
602
|
if (a)
|
|
546
603
|
return n(new Error(`ssh.writeFile: err ${a}, remotePath: ${t}`));
|
|
547
|
-
|
|
604
|
+
o(!0);
|
|
548
605
|
});
|
|
549
606
|
});
|
|
550
607
|
}
|
|
551
|
-
uploadFileUsingExistingSftp(r, t, e,
|
|
552
|
-
return new Promise((
|
|
608
|
+
uploadFileUsingExistingSftp(r, t, e, i = 432) {
|
|
609
|
+
return new Promise((o, n) => {
|
|
553
610
|
Z(t).then(async (a) => {
|
|
554
|
-
this.writeFile(r, e, a,
|
|
555
|
-
|
|
611
|
+
this.writeFile(r, e, a, i).then(() => {
|
|
612
|
+
o(void 0);
|
|
556
613
|
}).catch((c) => {
|
|
557
614
|
const l = `uploadFileUsingExistingSftp: error ${c} occurred`;
|
|
558
615
|
this.logger.error(l), n(new Error(l));
|
|
@@ -560,21 +617,21 @@ class D {
|
|
|
560
617
|
});
|
|
561
618
|
});
|
|
562
619
|
}
|
|
563
|
-
async __uploadDirectory(r, t, e,
|
|
564
|
-
return new Promise((
|
|
620
|
+
async __uploadDirectory(r, t, e, i = 432) {
|
|
621
|
+
return new Promise((o, n) => {
|
|
565
622
|
E.readdir(t, async (a, c) => {
|
|
566
623
|
if (a)
|
|
567
624
|
return n(new Error(`ssh.__uploadDir: err ${a}, localDir: ${t}, remoteDir: ${e}`));
|
|
568
625
|
try {
|
|
569
626
|
await this.__createRemoteDirectory(r, e);
|
|
570
627
|
for (const l of c) {
|
|
571
|
-
const
|
|
572
|
-
E.lstatSync(
|
|
628
|
+
const h = u.join(t, l), m = `${e}/${l}`;
|
|
629
|
+
E.lstatSync(h).isDirectory() ? await this.__uploadDirectory(r, h, m, i) : await this.uploadFileUsingExistingSftp(r, h, m, i);
|
|
573
630
|
}
|
|
574
|
-
|
|
631
|
+
o();
|
|
575
632
|
} catch (l) {
|
|
576
|
-
const
|
|
577
|
-
this.logger.error(
|
|
633
|
+
const h = `ssh.__uploadDir: catched err ${l}`;
|
|
634
|
+
this.logger.error(h), n(new Error(h));
|
|
578
635
|
}
|
|
579
636
|
});
|
|
580
637
|
});
|
|
@@ -586,9 +643,9 @@ class D {
|
|
|
586
643
|
* @returns A promise that resolves when the directory and its contents are uploaded.
|
|
587
644
|
*/
|
|
588
645
|
async uploadDirectory(r, t, e = 432) {
|
|
589
|
-
return new Promise((
|
|
646
|
+
return new Promise((i, o) => {
|
|
590
647
|
this.withSftp(async (n) => {
|
|
591
|
-
await this.__uploadDirectory(n, r, t, e),
|
|
648
|
+
await this.__uploadDirectory(n, r, t, e), i();
|
|
592
649
|
});
|
|
593
650
|
});
|
|
594
651
|
}
|
|
@@ -599,16 +656,16 @@ class D {
|
|
|
599
656
|
* @returns A promise that resolves when the directory is created.
|
|
600
657
|
*/
|
|
601
658
|
__createRemoteDirectory(r, t) {
|
|
602
|
-
return new Promise((e,
|
|
603
|
-
const
|
|
659
|
+
return new Promise((e, i) => {
|
|
660
|
+
const o = t.split("/");
|
|
604
661
|
let n = "";
|
|
605
662
|
const a = (c) => {
|
|
606
|
-
if (c >=
|
|
663
|
+
if (c >= o.length)
|
|
607
664
|
return e();
|
|
608
|
-
n += `${
|
|
609
|
-
l ? r.mkdir(n, (
|
|
610
|
-
if (
|
|
611
|
-
return
|
|
665
|
+
n += `${o[c]}/`, r.stat(n, (l) => {
|
|
666
|
+
l ? r.mkdir(n, (h) => {
|
|
667
|
+
if (h)
|
|
668
|
+
return i(new Error(`ssh.__createRemDir: err ${h}, remotePath: ${t}`));
|
|
612
669
|
a(c + 1);
|
|
613
670
|
}) : a(c + 1);
|
|
614
671
|
});
|
|
@@ -624,23 +681,23 @@ class D {
|
|
|
624
681
|
*/
|
|
625
682
|
createRemoteDirectory(r, t = 493) {
|
|
626
683
|
return this.withSftp(async (e) => {
|
|
627
|
-
const
|
|
628
|
-
let
|
|
629
|
-
for (const n of
|
|
630
|
-
|
|
684
|
+
const i = r.split("/");
|
|
685
|
+
let o = "";
|
|
686
|
+
for (const n of i) {
|
|
687
|
+
o += `${n}/`;
|
|
631
688
|
try {
|
|
632
689
|
await new Promise((a, c) => {
|
|
633
|
-
e.stat(
|
|
690
|
+
e.stat(o, (l) => {
|
|
634
691
|
if (!l) return a();
|
|
635
|
-
e.mkdir(
|
|
636
|
-
if (
|
|
637
|
-
return c(new Error(`ssh.createRemoteDir: err ${
|
|
692
|
+
e.mkdir(o, { mode: t }, (h) => {
|
|
693
|
+
if (h)
|
|
694
|
+
return c(new Error(`ssh.createRemoteDir: err ${h}, remotePath: ${r}`));
|
|
638
695
|
a();
|
|
639
696
|
});
|
|
640
697
|
});
|
|
641
698
|
});
|
|
642
699
|
} catch (a) {
|
|
643
|
-
throw console.error(`Failed to create directory: ${
|
|
700
|
+
throw console.error(`Failed to create directory: ${o}`, a), a;
|
|
644
701
|
}
|
|
645
702
|
}
|
|
646
703
|
});
|
|
@@ -652,11 +709,11 @@ class D {
|
|
|
652
709
|
* @returns A promise resolving with `true` if the file was successfully downloaded.
|
|
653
710
|
*/
|
|
654
711
|
async downloadFile(r, t) {
|
|
655
|
-
return this.withSftp(async (e) => new Promise((
|
|
712
|
+
return this.withSftp(async (e) => new Promise((i, o) => {
|
|
656
713
|
e.fastGet(r, t, (n) => {
|
|
657
714
|
if (n)
|
|
658
|
-
return
|
|
659
|
-
|
|
715
|
+
return o(new Error(`ssh.downloadFile: err ${n}, remotePath: ${r}, localPath: ${t}`));
|
|
716
|
+
i(!0);
|
|
660
717
|
});
|
|
661
718
|
}));
|
|
662
719
|
}
|
|
@@ -667,65 +724,65 @@ class D {
|
|
|
667
724
|
this.client.end();
|
|
668
725
|
}
|
|
669
726
|
}
|
|
670
|
-
const
|
|
671
|
-
function
|
|
672
|
-
return
|
|
727
|
+
const bt = "minio-2024-12-18T13-15-44Z", Dt = "supervisord-0.7.3", At = "supervisord_0.7.3_Linux_64-bit";
|
|
728
|
+
function y(s) {
|
|
729
|
+
return u.join(s, "platforma_ssh");
|
|
673
730
|
}
|
|
674
731
|
function P(s) {
|
|
675
|
-
return
|
|
732
|
+
return u.join(s, "platforma_ssh", "binaries");
|
|
676
733
|
}
|
|
677
|
-
function
|
|
678
|
-
return
|
|
734
|
+
function kt(s, r) {
|
|
735
|
+
return u.join(P(s), `pl-${F()}-${$(r)}`);
|
|
679
736
|
}
|
|
680
737
|
function J(s, r) {
|
|
681
|
-
return
|
|
738
|
+
return u.join(kt(s, r), "binaries");
|
|
682
739
|
}
|
|
683
|
-
function
|
|
684
|
-
return
|
|
740
|
+
function x(s, r) {
|
|
741
|
+
return u.join(J(s, r), "platforma");
|
|
685
742
|
}
|
|
686
|
-
function
|
|
687
|
-
return
|
|
743
|
+
function xt(s, r) {
|
|
744
|
+
return u.join(J(s, r), "free-port");
|
|
688
745
|
}
|
|
689
746
|
function M(s, r) {
|
|
690
|
-
return
|
|
747
|
+
return u.join(P(s), `minio-2024-12-18T13-15-44Z-${$(r)}`);
|
|
691
748
|
}
|
|
692
|
-
function
|
|
693
|
-
return
|
|
749
|
+
function Ot(s, r) {
|
|
750
|
+
return u.join(M(s, r), "minio");
|
|
694
751
|
}
|
|
695
752
|
function Rt(s, r) {
|
|
696
|
-
return
|
|
753
|
+
return u.join(P(s), `supervisord-0.7.3-${$(r)}`, At);
|
|
697
754
|
}
|
|
698
755
|
function L(s, r) {
|
|
699
|
-
return
|
|
756
|
+
return u.join(Rt(s, r), "supervisord");
|
|
700
757
|
}
|
|
701
758
|
function z(s) {
|
|
702
|
-
return
|
|
759
|
+
return u.join(y(s), "supervisor.conf");
|
|
703
760
|
}
|
|
704
|
-
function
|
|
705
|
-
return
|
|
761
|
+
function O(s) {
|
|
762
|
+
return u.join(y(s), "connection.txt");
|
|
706
763
|
}
|
|
707
764
|
async function Nt(s, r, t) {
|
|
708
|
-
const e = await
|
|
765
|
+
const e = await A(s, r, t, "--daemon");
|
|
709
766
|
if (e.stderr)
|
|
710
767
|
throw new Error(`Can not run ssh Platforma ${e.stderr}`);
|
|
711
768
|
}
|
|
712
|
-
async function
|
|
713
|
-
const e = await
|
|
769
|
+
async function Ut(s, r, t) {
|
|
770
|
+
const e = await A(s, r, t, "ctl shutdown");
|
|
714
771
|
if (e.stderr)
|
|
715
772
|
throw new Error(`Can not stop ssh Platforma ${e.stderr}`);
|
|
716
773
|
}
|
|
717
|
-
async function
|
|
718
|
-
const
|
|
719
|
-
if (
|
|
720
|
-
return s.info(`supervisord ctl status: stderr occurred: ${
|
|
721
|
-
const
|
|
722
|
-
platforma: R(
|
|
723
|
-
minio: R(
|
|
774
|
+
async function Tt(s, r, t, e) {
|
|
775
|
+
const i = await A(r, t, e, "ctl status");
|
|
776
|
+
if (i.stderr)
|
|
777
|
+
return s.info(`supervisord ctl status: stderr occurred: ${i.stderr}, stdout: ${i.stdout}`), !1;
|
|
778
|
+
const o = {
|
|
779
|
+
platforma: R(i.stdout, "platforma"),
|
|
780
|
+
minio: R(i.stdout, "minio")
|
|
724
781
|
};
|
|
725
|
-
return
|
|
782
|
+
return o.platforma && o.minio ? !0 : (o.minio || s.warn("Minio is not running on the server"), o.platforma || s.warn("Platforma is not running on the server"), !1);
|
|
726
783
|
}
|
|
727
|
-
function Bt(s, r, t, e,
|
|
728
|
-
const a = Object.entries(r).map(([
|
|
784
|
+
function Bt(s, r, t, e, i, o, n) {
|
|
785
|
+
const a = Object.entries(r).map(([h, m]) => `${h}="${m}"`).join(","), c = nt(16).toString("hex"), l = t;
|
|
729
786
|
return `
|
|
730
787
|
[supervisord]
|
|
731
788
|
logfile=${e}/supervisord.log
|
|
@@ -745,27 +802,27 @@ password=${c}
|
|
|
745
802
|
[program:platforma]
|
|
746
803
|
autostart=true
|
|
747
804
|
depends_on=minio
|
|
748
|
-
command=${n} --config ${
|
|
805
|
+
command=${n} --config ${i}
|
|
749
806
|
directory=${e}
|
|
750
807
|
autorestart=true
|
|
751
808
|
|
|
752
809
|
[program:minio]
|
|
753
810
|
autostart=true
|
|
754
811
|
environment=${a}
|
|
755
|
-
command=${
|
|
812
|
+
command=${o} server ${s}
|
|
756
813
|
directory=${e}
|
|
757
814
|
autorestart=true
|
|
758
815
|
`;
|
|
759
816
|
}
|
|
760
|
-
async function
|
|
761
|
-
const
|
|
817
|
+
async function A(s, r, t, e) {
|
|
818
|
+
const i = L(r, t), o = z(r), n = `${i} --configuration ${o} ${e}`;
|
|
762
819
|
return await s.exec(n);
|
|
763
820
|
}
|
|
764
821
|
function R(s, r) {
|
|
765
|
-
return ((
|
|
766
|
-
`).some((
|
|
767
|
-
const [
|
|
768
|
-
return
|
|
822
|
+
return ((i) => i.replace(/\x1B\[[0-9;]*m/g, ""))(s).split(`
|
|
823
|
+
`).some((i) => {
|
|
824
|
+
const [o, n] = i.trim().split(/\s{2,}/);
|
|
825
|
+
return o === r && n === "Running";
|
|
769
826
|
});
|
|
770
827
|
}
|
|
771
828
|
class W {
|
|
@@ -790,7 +847,7 @@ class W {
|
|
|
790
847
|
async isAlive() {
|
|
791
848
|
const r = await this.getArch(), t = await this.getUserHomeDirectory();
|
|
792
849
|
try {
|
|
793
|
-
return await
|
|
850
|
+
return await Tt(this.logger, this.sshClient, t, r.arch);
|
|
794
851
|
} catch {
|
|
795
852
|
return !1;
|
|
796
853
|
}
|
|
@@ -800,19 +857,23 @@ class W {
|
|
|
800
857
|
try {
|
|
801
858
|
return await Nt(this.sshClient, t, r.arch), await this.checkIsAliveWithInterval();
|
|
802
859
|
} catch (e) {
|
|
803
|
-
const
|
|
804
|
-
throw this.logger.error(
|
|
860
|
+
const i = `ssh.start: error occurred ${e}`;
|
|
861
|
+
throw this.logger.error(i), new Error(i);
|
|
805
862
|
}
|
|
806
863
|
}
|
|
807
864
|
async stop() {
|
|
808
865
|
const r = await this.getArch(), t = await this.getUserHomeDirectory();
|
|
809
866
|
try {
|
|
810
|
-
return await
|
|
867
|
+
return await Ut(this.sshClient, t, r.arch), await this.checkIsAliveWithInterval(void 0, void 0, !1);
|
|
811
868
|
} catch (e) {
|
|
812
|
-
const
|
|
813
|
-
throw this.logger.error(
|
|
869
|
+
const i = `ssh.stop: error occurred ${e}`;
|
|
870
|
+
throw this.logger.error(i), new Error(i);
|
|
814
871
|
}
|
|
815
872
|
}
|
|
873
|
+
async reset() {
|
|
874
|
+
const r = await this.getUserHomeDirectory();
|
|
875
|
+
return this.logger.info("pl.reset: Stop Platforma on the server"), await this.stop(), this.logger.info(`pl.reset: Deleting Platforma workDir ${r} on the server`), await this.sshClient.deleteFolder(y(r)), !0;
|
|
876
|
+
}
|
|
816
877
|
async platformaInit(r) {
|
|
817
878
|
const t = { localWorkdir: r };
|
|
818
879
|
try {
|
|
@@ -828,9 +889,9 @@ class W {
|
|
|
828
889
|
);
|
|
829
890
|
if (t.binPaths = { ...e, history: void 0 }, t.downloadedBinaries = e.history, t.ports = await this.fetchPorts(t.remoteHome, t.arch), !t.ports.debug.remote || !t.ports.grpc.remote || !t.ports.minioPort.remote || !t.ports.minioConsolePort.remote || !t.ports.monitoring.remote)
|
|
830
891
|
throw new Error("SshPl.platformaInit: remote ports are not defined");
|
|
831
|
-
const
|
|
892
|
+
const i = await ot({
|
|
832
893
|
logger: this.logger,
|
|
833
|
-
workingDir:
|
|
894
|
+
workingDir: y(t.remoteHome),
|
|
834
895
|
portsMode: {
|
|
835
896
|
type: "customWithMinio",
|
|
836
897
|
ports: {
|
|
@@ -847,50 +908,50 @@ class W {
|
|
|
847
908
|
type: "env"
|
|
848
909
|
}
|
|
849
910
|
});
|
|
850
|
-
t.generatedConfig = { ...
|
|
851
|
-
for (const [a, c] of Object.entries(
|
|
911
|
+
t.generatedConfig = { ...i, filesToCreate: { skipped: "it is too wordy" } };
|
|
912
|
+
for (const [a, c] of Object.entries(i.filesToCreate))
|
|
852
913
|
await this.sshClient.writeFileOnTheServer(a, c), this.logger.info(`Created file ${a}`);
|
|
853
|
-
for (const a of
|
|
914
|
+
for (const a of i.dirsToCreate)
|
|
854
915
|
await this.sshClient.createRemoteDirectory(a), this.logger.info(`Created directory ${a}`);
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
916
|
+
const o = Bt(
|
|
917
|
+
i.minioConfig.storageDir,
|
|
918
|
+
i.minioConfig.envs,
|
|
858
919
|
await this.getFreePortForPlatformaOnServer(t.remoteHome, t.arch),
|
|
859
|
-
|
|
860
|
-
|
|
920
|
+
i.workingDir,
|
|
921
|
+
i.plConfig.configPath,
|
|
861
922
|
t.binPaths.minioRelPath,
|
|
862
923
|
t.binPaths.downloadedPl
|
|
863
924
|
);
|
|
864
|
-
if (!await this.sshClient.writeFileOnTheServer(z(t.remoteHome),
|
|
865
|
-
throw new Error(`Can not write supervisord config on the server ${
|
|
925
|
+
if (!await this.sshClient.writeFileOnTheServer(z(t.remoteHome), o))
|
|
926
|
+
throw new Error(`Can not write supervisord config on the server ${y(t.remoteHome)}`);
|
|
866
927
|
return t.connectionInfo = {
|
|
867
|
-
plUser:
|
|
868
|
-
plPassword:
|
|
928
|
+
plUser: i.plUser,
|
|
929
|
+
plPassword: i.plPassword,
|
|
869
930
|
ports: t.ports
|
|
870
931
|
}, await this.sshClient.writeFileOnTheServer(
|
|
871
|
-
|
|
932
|
+
O(t.remoteHome),
|
|
872
933
|
JSON.stringify(t.connectionInfo, void 0, 2)
|
|
873
934
|
), await this.start(), t.started = !0, this.initState = t, {
|
|
874
|
-
plUser:
|
|
875
|
-
plPassword:
|
|
935
|
+
plUser: i.plUser,
|
|
936
|
+
plPassword: i.plPassword,
|
|
876
937
|
ports: t.ports
|
|
877
938
|
};
|
|
878
939
|
} catch (e) {
|
|
879
|
-
const
|
|
880
|
-
throw this.logger.error(
|
|
940
|
+
const i = `SshPl.platformaInit: error occurred: ${e}, state: ${JSON.stringify(t)}`;
|
|
941
|
+
throw this.logger.error(i), new Error(i);
|
|
881
942
|
}
|
|
882
943
|
}
|
|
883
944
|
async downloadBinariesAndUploadToTheServer(r, t, e) {
|
|
884
|
-
const
|
|
945
|
+
const i = [];
|
|
885
946
|
try {
|
|
886
|
-
const
|
|
947
|
+
const o = await this.downloadAndUntar(
|
|
887
948
|
r,
|
|
888
949
|
t,
|
|
889
950
|
e,
|
|
890
951
|
"pl",
|
|
891
|
-
`pl-${
|
|
952
|
+
`pl-${F()}`
|
|
892
953
|
);
|
|
893
|
-
|
|
954
|
+
i.push(o);
|
|
894
955
|
const n = await this.downloadAndUntar(
|
|
895
956
|
r,
|
|
896
957
|
t,
|
|
@@ -898,49 +959,49 @@ class W {
|
|
|
898
959
|
"supervisord",
|
|
899
960
|
Dt
|
|
900
961
|
);
|
|
901
|
-
|
|
902
|
-
const a =
|
|
962
|
+
i.push(n);
|
|
963
|
+
const a = Ot(t, e.arch), c = await this.downloadAndUntar(
|
|
903
964
|
r,
|
|
904
965
|
t,
|
|
905
966
|
e,
|
|
906
967
|
"minio",
|
|
907
|
-
|
|
968
|
+
bt
|
|
908
969
|
);
|
|
909
|
-
return
|
|
910
|
-
history:
|
|
970
|
+
return i.push(c), await this.sshClient.chmod(a, 488), {
|
|
971
|
+
history: i,
|
|
911
972
|
minioRelPath: a,
|
|
912
|
-
downloadedPl:
|
|
973
|
+
downloadedPl: x(t, e.arch)
|
|
913
974
|
};
|
|
914
|
-
} catch (
|
|
915
|
-
const n = `SshPl.downloadBinariesAndUploadToServer: error ${
|
|
916
|
-
throw this.logger.error(n),
|
|
975
|
+
} catch (o) {
|
|
976
|
+
const n = `SshPl.downloadBinariesAndUploadToServer: error ${o} occurred, state: ${JSON.stringify(i)}`;
|
|
977
|
+
throw this.logger.error(n), o;
|
|
917
978
|
}
|
|
918
979
|
}
|
|
919
980
|
/** We have to extract pl in the remote server,
|
|
920
981
|
* because Windows doesn't support symlinks
|
|
921
982
|
* that are found in linux pl binaries tgz archive.
|
|
922
983
|
* For this reason, we extract all to the remote server. */
|
|
923
|
-
async downloadAndUntar(r, t, e,
|
|
984
|
+
async downloadAndUntar(r, t, e, i, o) {
|
|
924
985
|
const n = {};
|
|
925
986
|
n.binBasePath = P(t), await this.sshClient.createRemoteDirectory(n.binBasePath), n.binBasePathCreated = !0;
|
|
926
987
|
let a = null;
|
|
927
988
|
const c = 5;
|
|
928
|
-
for (let
|
|
989
|
+
for (let h = 1; h <= c; h++)
|
|
929
990
|
try {
|
|
930
991
|
a = await lt(
|
|
931
992
|
this.logger,
|
|
932
993
|
r,
|
|
933
|
-
o,
|
|
934
994
|
i,
|
|
995
|
+
o,
|
|
935
996
|
e.arch,
|
|
936
997
|
e.platform
|
|
937
998
|
);
|
|
938
999
|
break;
|
|
939
1000
|
} catch (m) {
|
|
940
|
-
if (await S(300),
|
|
1001
|
+
if (await S(300), h == c)
|
|
941
1002
|
throw new Error(`downloadAndUntar: ${c} attempts, last error: ${m}`);
|
|
942
1003
|
}
|
|
943
|
-
n.downloadResult = p(a), n.localArchivePath =
|
|
1004
|
+
n.downloadResult = p(a), n.localArchivePath = u.resolve(n.downloadResult.archivePath), n.remoteDir = u.join(n.binBasePath, n.downloadResult.baseName), n.remoteArchivePath = n.remoteDir + ".tgz", await this.sshClient.createRemoteDirectory(n.remoteDir), await this.sshClient.uploadFile(n.localArchivePath, n.remoteArchivePath);
|
|
944
1005
|
const l = await this.sshClient.exec(
|
|
945
1006
|
`tar xvf ${n.remoteArchivePath} --directory=${n.remoteDir}`
|
|
946
1007
|
);
|
|
@@ -949,60 +1010,60 @@ class W {
|
|
|
949
1010
|
return n.plUntarDone = !0, n;
|
|
950
1011
|
}
|
|
951
1012
|
async needDownload(r, t) {
|
|
952
|
-
const e = L(r, t.arch),
|
|
953
|
-
return !await this.sshClient.checkFileExists(
|
|
1013
|
+
const e = L(r, t.arch), i = M(r, t.arch), o = x(r, t.arch);
|
|
1014
|
+
return !await this.sshClient.checkFileExists(o) || !await this.sshClient.checkFileExists(i) || !await this.sshClient.checkFileExists(e);
|
|
954
1015
|
}
|
|
955
1016
|
async checkIsAliveWithInterval(r = 1e3, t = 15, e = !0) {
|
|
956
|
-
const
|
|
957
|
-
let
|
|
1017
|
+
const i = t * r;
|
|
1018
|
+
let o = 0, n = await this.isAlive();
|
|
958
1019
|
for (; e ? !n : n; ) {
|
|
959
|
-
if (await S(r),
|
|
960
|
-
throw new Error(`isAliveWithInterval: The process did not ${e ? "started" : "stopped"} after ${
|
|
1020
|
+
if (await S(r), o += r, o > i)
|
|
1021
|
+
throw new Error(`isAliveWithInterval: The process did not ${e ? "started" : "stopped"} after ${i} ms.`);
|
|
961
1022
|
n = await this.isAlive();
|
|
962
1023
|
}
|
|
963
1024
|
}
|
|
964
1025
|
async getUserCredentials(r) {
|
|
965
|
-
const t = await this.sshClient.readFile(
|
|
1026
|
+
const t = await this.sshClient.readFile(O(r));
|
|
966
1027
|
return JSON.parse(t);
|
|
967
1028
|
}
|
|
968
1029
|
async fetchPorts(r, t) {
|
|
969
1030
|
return {
|
|
970
1031
|
grpc: {
|
|
971
|
-
local: await
|
|
1032
|
+
local: await g(),
|
|
972
1033
|
remote: await this.getFreePortForPlatformaOnServer(r, t)
|
|
973
1034
|
},
|
|
974
1035
|
monitoring: {
|
|
975
|
-
local: await
|
|
1036
|
+
local: await g(),
|
|
976
1037
|
remote: await this.getFreePortForPlatformaOnServer(r, t)
|
|
977
1038
|
},
|
|
978
1039
|
debug: {
|
|
979
|
-
local: await
|
|
1040
|
+
local: await g(),
|
|
980
1041
|
remote: await this.getFreePortForPlatformaOnServer(r, t)
|
|
981
1042
|
},
|
|
982
1043
|
minioPort: {
|
|
983
|
-
local: await
|
|
1044
|
+
local: await g(),
|
|
984
1045
|
remote: await this.getFreePortForPlatformaOnServer(r, t)
|
|
985
1046
|
},
|
|
986
1047
|
minioConsolePort: {
|
|
987
|
-
local: await
|
|
1048
|
+
local: await g(),
|
|
988
1049
|
remote: await this.getFreePortForPlatformaOnServer(r, t)
|
|
989
1050
|
}
|
|
990
1051
|
};
|
|
991
1052
|
}
|
|
992
1053
|
async getLocalFreePort() {
|
|
993
1054
|
return new Promise((r) => {
|
|
994
|
-
const t =
|
|
1055
|
+
const t = U.createServer();
|
|
995
1056
|
t.listen(0, () => {
|
|
996
1057
|
const e = t.address().port;
|
|
997
|
-
t.close((
|
|
1058
|
+
t.close((i) => r(e));
|
|
998
1059
|
});
|
|
999
1060
|
});
|
|
1000
1061
|
}
|
|
1001
1062
|
async getFreePortForPlatformaOnServer(r, t) {
|
|
1002
|
-
const e =
|
|
1003
|
-
if (
|
|
1004
|
-
throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${
|
|
1005
|
-
return +
|
|
1063
|
+
const e = xt(r, t.arch), { stdout: i, stderr: o } = await this.sshClient.exec(`${e}`);
|
|
1064
|
+
if (o)
|
|
1065
|
+
throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${o}, stdout: ${i}`);
|
|
1066
|
+
return +i;
|
|
1006
1067
|
}
|
|
1007
1068
|
async getArch() {
|
|
1008
1069
|
const { stdout: r, stderr: t } = await this.sshClient.exec("uname -s && uname -m");
|
|
@@ -1029,7 +1090,7 @@ export {
|
|
|
1029
1090
|
Et as LocalPl,
|
|
1030
1091
|
D as SshClient,
|
|
1031
1092
|
W as SshPl,
|
|
1032
|
-
|
|
1093
|
+
F as getDefaultPlVersion,
|
|
1033
1094
|
Xt as localPlatformaInit
|
|
1034
1095
|
};
|
|
1035
1096
|
//# sourceMappingURL=index.mjs.map
|