@milaboratories/pl-deployments 1.2.2 → 1.2.3
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 +12 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +269 -242
- package/dist/index.mjs.map +1 -1
- package/dist/ssh/pl.d.ts +3 -1
- package/dist/ssh/pl.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/common/pl_binary_download.ts +1 -1
- package/src/ssh/__tests__/ssh-docker.test.ts +1 -1
- package/src/ssh/pl.test.ts +26 -0
- package/src/ssh/pl.ts +48 -6
- package/src/ssh/ssh.ts +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var w = (s, r, t) =>
|
|
4
|
-
import { spawn as
|
|
5
|
-
import { sleep as
|
|
1
|
+
var Y = Object.defineProperty;
|
|
2
|
+
var Q = (s, r, t) => r in s ? Y(s, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[r] = t;
|
|
3
|
+
var w = (s, r, t) => Q(s, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { spawn as X } from "node:child_process";
|
|
5
|
+
import { sleep as F, fileExists as y, assertNever as H, notEmpty as f, RetryablePromise as tt } from "@milaboratories/ts-helpers";
|
|
6
6
|
import D from "node:fs";
|
|
7
|
-
import m, { readFile as
|
|
7
|
+
import m, { readFile as rt } from "node:fs/promises";
|
|
8
8
|
import d from "upath";
|
|
9
|
-
import { request as
|
|
10
|
-
import { Readable as
|
|
11
|
-
import { text as
|
|
12
|
-
import * as
|
|
13
|
-
import
|
|
9
|
+
import { request as et } from "undici";
|
|
10
|
+
import { Readable as it, Writable as ot } from "node:stream";
|
|
11
|
+
import { text as st } from "node:stream/consumers";
|
|
12
|
+
import * as nt from "tar";
|
|
13
|
+
import at from "decompress";
|
|
14
14
|
import A from "node:os";
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
15
|
+
import ct, { Client as b } from "ssh2";
|
|
16
|
+
import M from "node:net";
|
|
17
|
+
import lt from "node:dns";
|
|
18
18
|
import { randomBytes as x } from "node:crypto";
|
|
19
|
-
import { generateSshPlConfigs as
|
|
19
|
+
import { generateSshPlConfigs as ht, getFreePort as v } from "@milaboratories/pl-config";
|
|
20
20
|
import { z as p } from "zod";
|
|
21
|
-
function
|
|
21
|
+
function dt(s, r) {
|
|
22
22
|
return s.info(`Running:
|
|
23
23
|
cmd: ${JSON.stringify([r.cmd, ...r.args])}
|
|
24
|
-
wd: ${r.opts.cwd}`), s.info(" spawning child process"),
|
|
24
|
+
wd: ${r.opts.cwd}`), s.info(" spawning child process"), X(r.cmd, r.args, r.opts);
|
|
25
25
|
}
|
|
26
|
-
async function
|
|
26
|
+
async function k(s) {
|
|
27
27
|
try {
|
|
28
28
|
return process.kill(s, 0), !0;
|
|
29
29
|
} catch {
|
|
30
30
|
return !1;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function G(s) {
|
|
34
34
|
return process.kill(s, "SIGINT");
|
|
35
35
|
}
|
|
36
|
-
async function
|
|
36
|
+
async function J(s, r) {
|
|
37
37
|
let e = 0;
|
|
38
|
-
for (; await
|
|
39
|
-
if (await
|
|
38
|
+
for (; await k(s); )
|
|
39
|
+
if (await F(100), e += 100, e > r)
|
|
40
40
|
throw new Error(`The process did not stopped after ${r} ms.`);
|
|
41
41
|
}
|
|
42
|
-
const
|
|
43
|
-
function
|
|
42
|
+
const ut = ["linux", "macos", "windows"];
|
|
43
|
+
function O(s) {
|
|
44
44
|
switch (s.toLowerCase()) {
|
|
45
45
|
case "darwin":
|
|
46
46
|
return "macos";
|
|
@@ -50,11 +50,11 @@ function k(s) {
|
|
|
50
50
|
return "windows";
|
|
51
51
|
default:
|
|
52
52
|
throw new Error(
|
|
53
|
-
`operating system '${s}' is not currently supported by Platforma ecosystem. The list of OSes supported: ` + JSON.stringify(
|
|
53
|
+
`operating system '${s}' is not currently supported by Platforma ecosystem. The list of OSes supported: ` + JSON.stringify(ut)
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
const
|
|
57
|
+
const wt = ["amd64", "arm64"];
|
|
58
58
|
function S(s) {
|
|
59
59
|
switch (s) {
|
|
60
60
|
case "aarch64":
|
|
@@ -66,33 +66,33 @@ function S(s) {
|
|
|
66
66
|
return "amd64";
|
|
67
67
|
default:
|
|
68
68
|
throw new Error(
|
|
69
|
-
`processor architecture '${s}' is not currently supported by Platforma ecosystem. The list of architectures supported: ` + JSON.stringify(
|
|
69
|
+
`processor architecture '${s}' is not currently supported by Platforma ecosystem. The list of architectures supported: ` + JSON.stringify(wt)
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
const
|
|
74
|
-
async function
|
|
75
|
-
const n =
|
|
73
|
+
const ft = "https://cdn.platforma.bio/software", pt = "https://cdn-ga.pl-open.science/software";
|
|
74
|
+
async function mt(s, r, t, e, i, o) {
|
|
75
|
+
const n = L(t, e, r, S(i), O(o)), { archiveUrl: a, alternativeArchiveGAUrl: c, archivePath: l } = n;
|
|
76
76
|
try {
|
|
77
|
-
await C(s, c, l), n.wasDownloadedFrom = c;
|
|
78
|
-
} catch {
|
|
79
77
|
await C(s, a, l), n.wasDownloadedFrom = a;
|
|
78
|
+
} catch {
|
|
79
|
+
await C(s, c, l), n.wasDownloadedFrom = c;
|
|
80
80
|
}
|
|
81
81
|
return n;
|
|
82
82
|
}
|
|
83
|
-
async function
|
|
84
|
-
const n =
|
|
83
|
+
async function gt(s, r, t, e, i, o) {
|
|
84
|
+
const n = L(t, e, r, S(i), O(o)), { archiveUrl: a, alternativeArchiveGAUrl: c, archivePath: l, archiveType: h, targetFolder: u, baseName: $ } = n;
|
|
85
85
|
try {
|
|
86
|
-
await C(s, c, l), n.wasDownloadedFrom = c;
|
|
87
|
-
} catch {
|
|
88
86
|
await C(s, a, l), n.wasDownloadedFrom = a;
|
|
87
|
+
} catch {
|
|
88
|
+
await C(s, c, l), n.wasDownloadedFrom = c;
|
|
89
89
|
}
|
|
90
|
-
return await
|
|
90
|
+
return await $t(s, l, h, u), n;
|
|
91
91
|
}
|
|
92
|
-
function
|
|
93
|
-
const o = `${r}-${e}`, n =
|
|
92
|
+
function L(s, r, t, e, i) {
|
|
93
|
+
const o = `${r}-${e}`, n = vt[i], a = `${o}.${n}`, c = `${ft}/${s}/${i}/${a}`, l = `${pt}/${s}/${i}/${a}`, h = d.join(t, a), u = d.join(t, o);
|
|
94
94
|
return {
|
|
95
|
-
archiveUrl:
|
|
95
|
+
archiveUrl: c,
|
|
96
96
|
alternativeArchiveGAUrl: l,
|
|
97
97
|
archivePath: h,
|
|
98
98
|
archiveType: n,
|
|
@@ -109,24 +109,24 @@ async function C(s, r, t) {
|
|
|
109
109
|
await m.mkdir(d.dirname(t), { recursive: !0 }), e.dirnameCreated = !0, s.info(`Downloading archive:
|
|
110
110
|
URL: ${r}
|
|
111
111
|
Save to: ${t}`);
|
|
112
|
-
const { body: i, statusCode: o } = await
|
|
112
|
+
const { body: i, statusCode: o } = await et(r);
|
|
113
113
|
if (e.statusCode = o, o != 200) {
|
|
114
|
-
const n = await
|
|
114
|
+
const n = await st(i);
|
|
115
115
|
throw e.errorMsg = `failed to download archive: ${o}, response: ${n.slice(0, 1e3)}`, s.error(e.errorMsg), new Error(e.errorMsg);
|
|
116
116
|
}
|
|
117
|
-
return e.tmpPath = t + ".tmp", await
|
|
117
|
+
return e.tmpPath = t + ".tmp", await it.toWeb(i).pipeTo(ot.toWeb(D.createWriteStream(e.tmpPath))), e.wroteTmp = !0, e.tmpExisted = await y(e.tmpPath), await m.rename(e.tmpPath, t), e.renamed = !0, e.newExisted = await y(t), e;
|
|
118
118
|
} catch (i) {
|
|
119
|
-
const o = `downloadArchive:
|
|
119
|
+
const o = `downloadArchive: ${JSON.stringify(i)}, state: ${JSON.stringify(e)}`;
|
|
120
120
|
throw s.error(o), new Error(o);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
const
|
|
124
|
-
async function
|
|
123
|
+
const yt = ".ok";
|
|
124
|
+
async function $t(s, r, t, e) {
|
|
125
125
|
if (s.info("extracting archive..."), s.info(` archive path: '${r}'`), s.info(` target dir: '${e}'`), !await y(r)) {
|
|
126
126
|
const o = `Platforma Backend binary archive not found at '${r}'`;
|
|
127
127
|
throw s.error(o), new Error(o);
|
|
128
128
|
}
|
|
129
|
-
const i = d.join(e,
|
|
129
|
+
const i = d.join(e, yt);
|
|
130
130
|
if (await y(i)) {
|
|
131
131
|
s.info(`Platforma Backend binaries unpack skipped: '${e}' exists`);
|
|
132
132
|
return;
|
|
@@ -137,21 +137,21 @@ async function yt(s, r, t, e) {
|
|
|
137
137
|
Target dir: ${e}`
|
|
138
138
|
), t) {
|
|
139
139
|
case "tgz":
|
|
140
|
-
await
|
|
140
|
+
await nt.x({
|
|
141
141
|
file: r,
|
|
142
142
|
cwd: e,
|
|
143
143
|
gzip: !0
|
|
144
144
|
});
|
|
145
145
|
break;
|
|
146
146
|
case "zip":
|
|
147
|
-
await
|
|
147
|
+
await at(r, e);
|
|
148
148
|
break;
|
|
149
149
|
default:
|
|
150
|
-
|
|
150
|
+
H(t);
|
|
151
151
|
}
|
|
152
152
|
await m.writeFile(i, "ok"), s.info(" ... unpack done.");
|
|
153
153
|
}
|
|
154
|
-
const
|
|
154
|
+
const vt = {
|
|
155
155
|
linux: "tgz",
|
|
156
156
|
macos: "tgz",
|
|
157
157
|
windows: "zip"
|
|
@@ -159,65 +159,65 @@ const $t = {
|
|
|
159
159
|
function R() {
|
|
160
160
|
return "1.24.0";
|
|
161
161
|
}
|
|
162
|
-
function
|
|
162
|
+
function Pt() {
|
|
163
163
|
return { type: "Download", version: R() };
|
|
164
164
|
}
|
|
165
|
-
async function
|
|
165
|
+
async function St(s, r, t) {
|
|
166
166
|
switch (t.type) {
|
|
167
167
|
case "Download":
|
|
168
|
-
const e = await
|
|
169
|
-
return d.join(e.baseName, "binaries",
|
|
168
|
+
const e = await gt(s, r, "pl", `pl-${t.version}`, A.arch(), A.platform());
|
|
169
|
+
return d.join(e.baseName, "binaries", Ct[O(A.platform())]);
|
|
170
170
|
case "Local":
|
|
171
171
|
return t.path;
|
|
172
172
|
default:
|
|
173
|
-
|
|
173
|
+
H(t);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
-
const
|
|
176
|
+
const Ct = {
|
|
177
177
|
linux: "platforma",
|
|
178
178
|
macos: "platforma",
|
|
179
179
|
windows: "platforma.exe"
|
|
180
180
|
};
|
|
181
|
-
function
|
|
181
|
+
function V(s) {
|
|
182
182
|
return d.join(s, "pl_pid");
|
|
183
183
|
}
|
|
184
|
-
async function
|
|
184
|
+
async function Et(s) {
|
|
185
185
|
if (!await y(s))
|
|
186
186
|
return;
|
|
187
187
|
const r = await m.readFile(s);
|
|
188
188
|
return Number(r.toString());
|
|
189
189
|
}
|
|
190
|
-
async function
|
|
190
|
+
async function At(s, r) {
|
|
191
191
|
await m.writeFile(s, JSON.stringify(r));
|
|
192
192
|
}
|
|
193
|
-
function
|
|
193
|
+
function bt() {
|
|
194
194
|
return {};
|
|
195
195
|
}
|
|
196
196
|
function Ft(s, r, t) {
|
|
197
197
|
return s[r] = t, t;
|
|
198
198
|
}
|
|
199
199
|
async function N(s, r) {
|
|
200
|
-
const t =
|
|
200
|
+
const t = bt();
|
|
201
201
|
try {
|
|
202
202
|
return await r((i, o) => Ft(t, i, o), t);
|
|
203
203
|
} catch (e) {
|
|
204
204
|
throw s.error(`error ${e} while doing traced operation, state: ${JSON.stringify(t)}`), e;
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
|
-
const
|
|
208
|
-
class
|
|
209
|
-
constructor(r, t, e, i, o, n,
|
|
207
|
+
const Dt = "config-local.yaml";
|
|
208
|
+
class xt {
|
|
209
|
+
constructor(r, t, e, i, o, n, a, c) {
|
|
210
210
|
w(this, "instance");
|
|
211
211
|
w(this, "pid");
|
|
212
212
|
w(this, "nRuns", 0);
|
|
213
213
|
w(this, "lastRunHistory", {});
|
|
214
214
|
w(this, "wasStopped", !1);
|
|
215
|
-
this.logger = r, this.workingDir = t, this.startOptions = e, this.initialStartHistory = i, this.onClose = o, this.onError = n, this.onCloseAndError =
|
|
215
|
+
this.logger = r, this.workingDir = t, this.startOptions = e, this.initialStartHistory = i, this.onClose = o, this.onError = n, this.onCloseAndError = a, this.onCloseAndErrorNoStop = c;
|
|
216
216
|
}
|
|
217
217
|
async start() {
|
|
218
218
|
await N(this.logger, async (r, t) => {
|
|
219
219
|
this.wasStopped = !1;
|
|
220
|
-
const e =
|
|
220
|
+
const e = dt(this.logger, this.startOptions);
|
|
221
221
|
e.on("error", (o) => {
|
|
222
222
|
this.logger.error(
|
|
223
223
|
`error '${o}', while running platforma, started opts: ${JSON.stringify(this.debugInfo())}`
|
|
@@ -225,21 +225,21 @@ class Dt {
|
|
|
225
225
|
}), e.on("close", () => {
|
|
226
226
|
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);
|
|
227
227
|
}), r("started", !0);
|
|
228
|
-
const i = r("pidFile",
|
|
229
|
-
r("pid", f(e.pid)), r("pidWritten", await
|
|
228
|
+
const i = r("pidFile", V(this.workingDir));
|
|
229
|
+
r("pid", f(e.pid)), r("pidWritten", await At(i, f(e.pid))), this.nRuns++, this.instance = e, this.pid = e.pid, this.lastRunHistory = t;
|
|
230
230
|
});
|
|
231
231
|
}
|
|
232
232
|
stop() {
|
|
233
|
-
this.wasStopped = !0,
|
|
233
|
+
this.wasStopped = !0, G(f(this.pid));
|
|
234
234
|
}
|
|
235
235
|
async waitStopped() {
|
|
236
|
-
await
|
|
236
|
+
await J(f(this.pid), 15e3);
|
|
237
237
|
}
|
|
238
238
|
stopped() {
|
|
239
239
|
return this.wasStopped;
|
|
240
240
|
}
|
|
241
241
|
async isAlive() {
|
|
242
|
-
return await
|
|
242
|
+
return await k(f(this.pid));
|
|
243
243
|
}
|
|
244
244
|
debugInfo() {
|
|
245
245
|
return {
|
|
@@ -252,9 +252,9 @@ class Dt {
|
|
|
252
252
|
};
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
|
-
async function
|
|
255
|
+
async function gr(s, r) {
|
|
256
256
|
const t = {
|
|
257
|
-
plBinary:
|
|
257
|
+
plBinary: Pt(),
|
|
258
258
|
spawnOptions: {},
|
|
259
259
|
closeOld: !0,
|
|
260
260
|
...r
|
|
@@ -262,11 +262,11 @@ async function fr(s, r) {
|
|
|
262
262
|
return await N(s, async (e, i) => {
|
|
263
263
|
e("startOptions", { ...t, config: "too wordy" });
|
|
264
264
|
const o = d.resolve(t.workingDir);
|
|
265
|
-
t.closeOld && e("closeOld", await
|
|
266
|
-
const n = d.join(o,
|
|
265
|
+
t.closeOld && e("closeOld", await kt(s, o));
|
|
266
|
+
const n = d.join(o, Dt);
|
|
267
267
|
s.info(`writing configuration '${n}'...`), await m.writeFile(n, t.config);
|
|
268
|
-
const
|
|
269
|
-
cmd: e("binaryPath", d.join("binaries",
|
|
268
|
+
const a = d.join(o, "binaries"), c = await St(s, a, t.plBinary), h = {
|
|
269
|
+
cmd: e("binaryPath", d.join("binaries", c)),
|
|
270
270
|
args: ["--config", n],
|
|
271
271
|
opts: {
|
|
272
272
|
env: { ...process.env },
|
|
@@ -282,7 +282,7 @@ async function fr(s, r) {
|
|
|
282
282
|
args: h.args,
|
|
283
283
|
cwd: h.opts.cwd
|
|
284
284
|
});
|
|
285
|
-
const u = new
|
|
285
|
+
const u = new xt(
|
|
286
286
|
s,
|
|
287
287
|
t.workingDir,
|
|
288
288
|
h,
|
|
@@ -295,10 +295,10 @@ async function fr(s, r) {
|
|
|
295
295
|
return await u.start(), u;
|
|
296
296
|
});
|
|
297
297
|
}
|
|
298
|
-
async function
|
|
298
|
+
async function kt(s, r) {
|
|
299
299
|
return await N(s, async (t, e) => {
|
|
300
|
-
const i = t("pidFilePath",
|
|
301
|
-
return o !== void 0 && n && (t("stopped",
|
|
300
|
+
const i = t("pidFilePath", V(r)), o = t("pid", await Et(i)), n = t("wasAlive", await k(o));
|
|
301
|
+
return o !== void 0 && n && (t("stopped", G(o)), t("waitStopped", await J(o, 1e4))), e;
|
|
302
302
|
});
|
|
303
303
|
}
|
|
304
304
|
const Ot = {
|
|
@@ -321,7 +321,7 @@ class B {
|
|
|
321
321
|
const e = {
|
|
322
322
|
...Ot,
|
|
323
323
|
...t
|
|
324
|
-
}, i = new B(r, new
|
|
324
|
+
}, i = new B(r, new b());
|
|
325
325
|
return await i.connect(e), i;
|
|
326
326
|
}
|
|
327
327
|
getForwardedServers() {
|
|
@@ -341,7 +341,7 @@ class B {
|
|
|
341
341
|
* @returns A promise that resolves when the connection is established or rejects on error.
|
|
342
342
|
*/
|
|
343
343
|
async connect(r) {
|
|
344
|
-
return this.config = r, await
|
|
344
|
+
return this.config = r, await Rt(this.client, r);
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
347
|
* Executes a command on the SSH server.
|
|
@@ -352,14 +352,14 @@ class B {
|
|
|
352
352
|
return new Promise((t, e) => {
|
|
353
353
|
this.client.exec(r, (i, o) => {
|
|
354
354
|
if (i)
|
|
355
|
-
return e(`ssh.exec: ${r}
|
|
356
|
-
let n = "",
|
|
357
|
-
o.on("close", (
|
|
358
|
-
|
|
359
|
-
}).on("data", (
|
|
360
|
-
n +=
|
|
361
|
-
}).stderr.on("data", (
|
|
362
|
-
|
|
355
|
+
return e(`ssh.exec: ${r}: ${i}`);
|
|
356
|
+
let n = "", a = "";
|
|
357
|
+
o.on("close", (c) => {
|
|
358
|
+
c === 0 ? t({ stdout: n, stderr: a }) : e(new Error(`Command ${r} exited with code ${c}, stdout: ${n}, stderr: ${a}`));
|
|
359
|
+
}).on("data", (c) => {
|
|
360
|
+
n += c.toString();
|
|
361
|
+
}).stderr.on("data", (c) => {
|
|
362
|
+
a += c.toString();
|
|
363
363
|
});
|
|
364
364
|
});
|
|
365
365
|
});
|
|
@@ -373,7 +373,7 @@ class B {
|
|
|
373
373
|
static async getAuthTypes(r, t) {
|
|
374
374
|
return new Promise((e) => {
|
|
375
375
|
let i = "";
|
|
376
|
-
const o = new
|
|
376
|
+
const o = new b();
|
|
377
377
|
o.on("ready", () => {
|
|
378
378
|
o.end();
|
|
379
379
|
const n = this.extractAuthMethods(i);
|
|
@@ -410,48 +410,48 @@ class B {
|
|
|
410
410
|
async forwardPort(r, t) {
|
|
411
411
|
const e = `ssh.forward:${r.localPort}:${r.remotePort}.id_${x(1).toString("hex")}`;
|
|
412
412
|
t = t ?? this.config;
|
|
413
|
-
const i = new
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
this.logger.info(`${e}.client.ready`), n(
|
|
417
|
-
}),
|
|
418
|
-
this.logger.info(`${e}.client.error: ${l}`), o.reset(),
|
|
419
|
-
}),
|
|
413
|
+
const i = new tt((o) => new Promise((n, a) => {
|
|
414
|
+
const c = new b();
|
|
415
|
+
c.on("ready", () => {
|
|
416
|
+
this.logger.info(`${e}.client.ready`), n(c);
|
|
417
|
+
}), c.on("error", (l) => {
|
|
418
|
+
this.logger.info(`${e}.client.error: ${l}`), o.reset(), a(l);
|
|
419
|
+
}), c.on("close", () => {
|
|
420
420
|
this.logger.info(`${e}.client.closed`), o.reset();
|
|
421
|
-
}),
|
|
421
|
+
}), c.connect(t);
|
|
422
422
|
}));
|
|
423
423
|
return await i.ensure(), new Promise((o, n) => {
|
|
424
|
-
const
|
|
424
|
+
const a = M.createServer({ pauseOnConnect: !0 }, async (c) => {
|
|
425
425
|
const l = `${e}.sock_${x(1).toString("hex")}`;
|
|
426
426
|
let h;
|
|
427
427
|
try {
|
|
428
428
|
h = await i.ensure();
|
|
429
429
|
} catch ($) {
|
|
430
|
-
this.logger.info(`${l}.persistentClient.catch: ${$}`),
|
|
430
|
+
this.logger.info(`${l}.persistentClient.catch: ${$}`), c.end();
|
|
431
431
|
return;
|
|
432
432
|
}
|
|
433
|
-
h.setNoDelay(!0),
|
|
433
|
+
h.setNoDelay(!0), c.setNoDelay(!0);
|
|
434
434
|
let u;
|
|
435
435
|
try {
|
|
436
|
-
u = await
|
|
436
|
+
u = await Nt(this.logger, h, "127.0.0.1", 0, "127.0.0.1", r.remotePort);
|
|
437
437
|
} catch ($) {
|
|
438
|
-
this.logger.error(`${l}.forwardOut.err: ${$}`),
|
|
438
|
+
this.logger.error(`${l}.forwardOut.err: ${$}`), c.end();
|
|
439
439
|
return;
|
|
440
440
|
}
|
|
441
|
-
|
|
442
|
-
this.logger.error(`${l}.stream.error: ${$}`),
|
|
441
|
+
c.pipe(u), u.pipe(c), c.resume(), u.on("error", ($) => {
|
|
442
|
+
this.logger.error(`${l}.stream.error: ${$}`), c.end(), u.end();
|
|
443
443
|
}), u.on("close", () => {
|
|
444
|
-
|
|
445
|
-
}),
|
|
446
|
-
this.logger.info(`${l}.localSocket: closed`),
|
|
444
|
+
c.end(), u.end();
|
|
445
|
+
}), c.on("close", () => {
|
|
446
|
+
this.logger.info(`${l}.localSocket: closed`), c.end(), u.end();
|
|
447
447
|
});
|
|
448
448
|
});
|
|
449
|
-
|
|
450
|
-
this.logger.info(`${e}.server: started listening`), this.forwardedServers.push(
|
|
451
|
-
}),
|
|
452
|
-
|
|
453
|
-
}),
|
|
454
|
-
this.logger.info(`${e}.server: closed ${JSON.stringify(r)}`), this.forwardedServers = this.forwardedServers.filter((
|
|
449
|
+
a.listen(r.localPort, "127.0.0.1", () => {
|
|
450
|
+
this.logger.info(`${e}.server: started listening`), this.forwardedServers.push(a), o({ server: a });
|
|
451
|
+
}), a.on("error", (c) => {
|
|
452
|
+
a.close(), n(new Error(`${e}.server: error: ${JSON.stringify(c)}`));
|
|
453
|
+
}), a.on("close", () => {
|
|
454
|
+
this.logger.info(`${e}.server: closed ${JSON.stringify(r)}`), this.forwardedServers = this.forwardedServers.filter((c) => c !== a);
|
|
455
455
|
});
|
|
456
456
|
});
|
|
457
457
|
}
|
|
@@ -472,7 +472,7 @@ class B {
|
|
|
472
472
|
*/
|
|
473
473
|
static async checkHostAvailability(r) {
|
|
474
474
|
return new Promise((t) => {
|
|
475
|
-
|
|
475
|
+
lt.lookup(r, (e) => {
|
|
476
476
|
t(!e);
|
|
477
477
|
});
|
|
478
478
|
});
|
|
@@ -485,7 +485,7 @@ class B {
|
|
|
485
485
|
static async isPassphraseRequiredForKey(r) {
|
|
486
486
|
return new Promise((t, e) => {
|
|
487
487
|
try {
|
|
488
|
-
return
|
|
488
|
+
return ct.utils.parseKey(r) instanceof Error && t(!0), t(!1);
|
|
489
489
|
} catch (i) {
|
|
490
490
|
console.log("Error parsing privateKey"), e(new Error(`ssh.isPassphraseRequiredForKey: err ${i}`));
|
|
491
491
|
}
|
|
@@ -502,10 +502,10 @@ class B {
|
|
|
502
502
|
return await this.withSftp(async (e) => new Promise((i, o) => {
|
|
503
503
|
e.fastPut(r, t, (n) => {
|
|
504
504
|
if (n) {
|
|
505
|
-
const
|
|
505
|
+
const a = new Error(
|
|
506
506
|
`ssh.uploadFile: err: ${n}, localPath: ${r}, remotePath: ${t}`
|
|
507
507
|
);
|
|
508
|
-
return o(
|
|
508
|
+
return o(a);
|
|
509
509
|
}
|
|
510
510
|
i(!0);
|
|
511
511
|
});
|
|
@@ -529,12 +529,12 @@ class B {
|
|
|
529
529
|
}
|
|
530
530
|
async getForderStructure(r, t, e = { files: [], directories: [] }) {
|
|
531
531
|
return new Promise((i, o) => {
|
|
532
|
-
r.readdir(t, async (n,
|
|
532
|
+
r.readdir(t, async (n, a) => {
|
|
533
533
|
if (n)
|
|
534
534
|
return o(n);
|
|
535
|
-
for (const
|
|
536
|
-
const l = `${t}/${
|
|
537
|
-
if (
|
|
535
|
+
for (const c of a) {
|
|
536
|
+
const l = `${t}/${c.filename}`;
|
|
537
|
+
if (c.attrs.isDirectory()) {
|
|
538
538
|
e.directories.push(l);
|
|
539
539
|
try {
|
|
540
540
|
await this.getForderStructure(r, l, e);
|
|
@@ -580,7 +580,7 @@ class B {
|
|
|
580
580
|
return this.withSftp(async (t) => new Promise((e, i) => {
|
|
581
581
|
t.readFile(r, (o, n) => {
|
|
582
582
|
if (o)
|
|
583
|
-
return i(new Error(`ssh.readFile:
|
|
583
|
+
return i(new Error(`ssh.readFile: ${o}`));
|
|
584
584
|
e(n.toString());
|
|
585
585
|
});
|
|
586
586
|
}));
|
|
@@ -614,20 +614,20 @@ class B {
|
|
|
614
614
|
}
|
|
615
615
|
async writeFile(r, t, e, i = 432) {
|
|
616
616
|
return new Promise((o, n) => {
|
|
617
|
-
r.writeFile(t, e, { mode: i }, (
|
|
618
|
-
if (
|
|
619
|
-
return n(new Error(`ssh.writeFile: err ${
|
|
617
|
+
r.writeFile(t, e, { mode: i }, (a) => {
|
|
618
|
+
if (a)
|
|
619
|
+
return n(new Error(`ssh.writeFile: err ${a}, remotePath: ${t}`));
|
|
620
620
|
o(!0);
|
|
621
621
|
});
|
|
622
622
|
});
|
|
623
623
|
}
|
|
624
624
|
uploadFileUsingExistingSftp(r, t, e, i = 432) {
|
|
625
625
|
return new Promise((o, n) => {
|
|
626
|
-
|
|
627
|
-
this.writeFile(r, e,
|
|
626
|
+
rt(t).then(async (a) => {
|
|
627
|
+
this.writeFile(r, e, a, i).then(() => {
|
|
628
628
|
o(void 0);
|
|
629
|
-
}).catch((
|
|
630
|
-
const l = `uploadFileUsingExistingSftp:
|
|
629
|
+
}).catch((c) => {
|
|
630
|
+
const l = `uploadFileUsingExistingSftp: ${c}`;
|
|
631
631
|
this.logger.error(l), n(new Error(l));
|
|
632
632
|
});
|
|
633
633
|
});
|
|
@@ -635,12 +635,12 @@ class B {
|
|
|
635
635
|
}
|
|
636
636
|
async __uploadDirectory(r, t, e, i = 432) {
|
|
637
637
|
return new Promise((o, n) => {
|
|
638
|
-
D.readdir(t, async (
|
|
639
|
-
if (
|
|
640
|
-
return n(new Error(`ssh.__uploadDir: err ${
|
|
638
|
+
D.readdir(t, async (a, c) => {
|
|
639
|
+
if (a)
|
|
640
|
+
return n(new Error(`ssh.__uploadDir: err ${a}, localDir: ${t}, remoteDir: ${e}`));
|
|
641
641
|
try {
|
|
642
642
|
await this.__createRemoteDirectory(r, e);
|
|
643
|
-
for (const l of
|
|
643
|
+
for (const l of c) {
|
|
644
644
|
const h = d.join(t, l), u = `${e}/${l}`;
|
|
645
645
|
D.lstatSync(h).isDirectory() ? await this.__uploadDirectory(r, h, u, i) : await this.uploadFileUsingExistingSftp(r, h, u, i);
|
|
646
646
|
}
|
|
@@ -663,8 +663,8 @@ class B {
|
|
|
663
663
|
this.withSftp(async (n) => {
|
|
664
664
|
try {
|
|
665
665
|
await this.__uploadDirectory(n, r, t, e), i();
|
|
666
|
-
} catch (
|
|
667
|
-
o(new Error(`ssh.uploadDirectory: ${
|
|
666
|
+
} catch (a) {
|
|
667
|
+
o(new Error(`ssh.uploadDirectory: ${a}`));
|
|
668
668
|
}
|
|
669
669
|
});
|
|
670
670
|
});
|
|
@@ -679,18 +679,18 @@ class B {
|
|
|
679
679
|
return new Promise((e, i) => {
|
|
680
680
|
const o = t.split("/");
|
|
681
681
|
let n = "";
|
|
682
|
-
const
|
|
683
|
-
if (
|
|
682
|
+
const a = (c) => {
|
|
683
|
+
if (c >= o.length)
|
|
684
684
|
return e();
|
|
685
|
-
n += `${o[
|
|
685
|
+
n += `${o[c]}/`, r.stat(n, (l) => {
|
|
686
686
|
l ? r.mkdir(n, (h) => {
|
|
687
687
|
if (h)
|
|
688
688
|
return i(new Error(`ssh.__createRemDir: err ${h}, remotePath: ${t}`));
|
|
689
|
-
c
|
|
690
|
-
}) : c
|
|
689
|
+
a(c + 1);
|
|
690
|
+
}) : a(c + 1);
|
|
691
691
|
});
|
|
692
692
|
};
|
|
693
|
-
|
|
693
|
+
a(0);
|
|
694
694
|
});
|
|
695
695
|
}
|
|
696
696
|
/**
|
|
@@ -706,18 +706,18 @@ class B {
|
|
|
706
706
|
for (const n of i) {
|
|
707
707
|
o += `${n}/`;
|
|
708
708
|
try {
|
|
709
|
-
await new Promise((
|
|
709
|
+
await new Promise((a, c) => {
|
|
710
710
|
e.stat(o, (l) => {
|
|
711
|
-
if (!l) return
|
|
711
|
+
if (!l) return a();
|
|
712
712
|
e.mkdir(o, { mode: t }, (h) => {
|
|
713
713
|
if (h)
|
|
714
|
-
return
|
|
715
|
-
|
|
714
|
+
return c(new Error(`ssh.createRemoteDir: err ${h}, remotePath: ${r}`));
|
|
715
|
+
a();
|
|
716
716
|
});
|
|
717
717
|
});
|
|
718
718
|
});
|
|
719
|
-
} catch (
|
|
720
|
-
throw console.error(`Failed to create directory: ${o}`,
|
|
719
|
+
} catch (a) {
|
|
720
|
+
throw console.error(`Failed to create directory: ${o}`, a), a;
|
|
721
721
|
}
|
|
722
722
|
}
|
|
723
723
|
});
|
|
@@ -744,87 +744,87 @@ class B {
|
|
|
744
744
|
this.closeForwardedPorts(), this.client.end();
|
|
745
745
|
}
|
|
746
746
|
}
|
|
747
|
-
async function
|
|
747
|
+
async function Rt(s, r, t, e) {
|
|
748
748
|
return new Promise((i, o) => {
|
|
749
749
|
s.on("ready", () => {
|
|
750
750
|
i(s);
|
|
751
751
|
}), s.on("error", (n) => {
|
|
752
|
-
o(new Error(`ssh.connect:
|
|
752
|
+
o(new Error(`ssh.connect: ${n}`));
|
|
753
753
|
}), s.on("close", () => {
|
|
754
754
|
}), s.connect(r), s.setNoDelay(!0);
|
|
755
755
|
});
|
|
756
756
|
}
|
|
757
|
-
async function
|
|
758
|
-
return new Promise((n,
|
|
759
|
-
r.forwardOut(t, e, i, o, (
|
|
757
|
+
async function Nt(s, r, t, e, i, o) {
|
|
758
|
+
return new Promise((n, a) => {
|
|
759
|
+
r.forwardOut(t, e, i, o, (c, l) => c ? (s.error(`forwardOut.error: ${c}`), a(c)) : n(l));
|
|
760
760
|
});
|
|
761
761
|
}
|
|
762
|
-
const
|
|
762
|
+
const Bt = "minio-2024-12-18T13-15-44Z", Ut = "supervisord-0.7.3", Tt = "supervisord_0.7.3_Linux_64-bit";
|
|
763
763
|
function g(s) {
|
|
764
764
|
return d.join(s, ".platforma_ssh");
|
|
765
765
|
}
|
|
766
766
|
function E(s) {
|
|
767
767
|
return d.join(g(s), "binaries");
|
|
768
768
|
}
|
|
769
|
-
function
|
|
769
|
+
function It(s, r) {
|
|
770
770
|
return d.join(E(s), `pl-${R()}-${S(r)}`);
|
|
771
771
|
}
|
|
772
772
|
function W(s, r) {
|
|
773
|
-
return d.join(
|
|
773
|
+
return d.join(It(s, r), "binaries");
|
|
774
774
|
}
|
|
775
775
|
function T(s, r) {
|
|
776
776
|
return d.join(W(s, r), "platforma");
|
|
777
777
|
}
|
|
778
|
-
function
|
|
778
|
+
function _t(s, r) {
|
|
779
779
|
return d.join(W(s, r), "free-port");
|
|
780
780
|
}
|
|
781
781
|
function z(s, r) {
|
|
782
782
|
return d.join(E(s), `minio-2024-12-18T13-15-44Z-${S(r)}`);
|
|
783
783
|
}
|
|
784
|
-
function
|
|
784
|
+
function jt(s, r) {
|
|
785
785
|
return d.join(z(s, r), "minio");
|
|
786
786
|
}
|
|
787
|
-
function
|
|
788
|
-
return d.join(E(s), `supervisord-0.7.3-${S(r)}`,
|
|
787
|
+
function Ht(s, r) {
|
|
788
|
+
return d.join(E(s), `supervisord-0.7.3-${S(r)}`, Tt);
|
|
789
789
|
}
|
|
790
|
-
function
|
|
791
|
-
return d.join(
|
|
790
|
+
function q(s, r) {
|
|
791
|
+
return d.join(Ht(s, r), "supervisord");
|
|
792
792
|
}
|
|
793
|
-
function
|
|
793
|
+
function K(s) {
|
|
794
794
|
return d.join(g(s), "supervisor.conf");
|
|
795
795
|
}
|
|
796
796
|
function I(s) {
|
|
797
797
|
return d.join(g(s), "connection.txt");
|
|
798
798
|
}
|
|
799
|
-
async function
|
|
799
|
+
async function Mt(s, r, t) {
|
|
800
800
|
const e = await U(s, r, t, "--daemon");
|
|
801
801
|
if (e.stderr)
|
|
802
802
|
throw new Error(`Can not run ssh Platforma ${e.stderr}`);
|
|
803
803
|
}
|
|
804
|
-
async function
|
|
804
|
+
async function Gt(s, r, t) {
|
|
805
805
|
const e = await U(s, r, t, "ctl shutdown");
|
|
806
806
|
if (e.stderr)
|
|
807
807
|
throw new Error(`Can not stop ssh Platforma ${e.stderr}`);
|
|
808
808
|
}
|
|
809
|
-
async function
|
|
809
|
+
async function Jt(s, r, t, e) {
|
|
810
810
|
let i;
|
|
811
811
|
try {
|
|
812
812
|
i = await U(r, t, e, "ctl status");
|
|
813
|
-
} catch (
|
|
814
|
-
return { execError: String(
|
|
813
|
+
} catch (c) {
|
|
814
|
+
return { execError: String(c), allAlive: !1 };
|
|
815
815
|
}
|
|
816
816
|
if (i.stderr)
|
|
817
817
|
return s.info(`supervisord ctl status: stderr occurred: ${i.stderr}, stdout: ${i.stdout}`), { rawResult: i, allAlive: !1 };
|
|
818
|
-
const o = _(i.stdout, "platforma"), n = _(i.stdout, "minio"),
|
|
818
|
+
const o = _(i.stdout, "platforma"), n = _(i.stdout, "minio"), a = {
|
|
819
819
|
rawResult: i,
|
|
820
820
|
platforma: o,
|
|
821
821
|
minio: n,
|
|
822
822
|
allAlive: o && n
|
|
823
823
|
};
|
|
824
|
-
return
|
|
824
|
+
return a.allAlive || (a.minio || s.warn("Minio is not running on the server"), a.platforma || s.warn("Platforma is not running on the server")), a;
|
|
825
825
|
}
|
|
826
|
-
function
|
|
827
|
-
const
|
|
826
|
+
function Lt(s, r, t, e, i, o, n) {
|
|
827
|
+
const a = Object.entries(r).map(([h, u]) => `${h}="${u}"`).join(","), c = x(16).toString("hex"), l = t;
|
|
828
828
|
return `
|
|
829
829
|
[supervisord]
|
|
830
830
|
logfile=${e}/supervisord.log
|
|
@@ -834,12 +834,12 @@ pidfile=${e}/supervisord.pid
|
|
|
834
834
|
[inet_http_server]
|
|
835
835
|
port=127.0.0.1:${l}
|
|
836
836
|
username=default-user
|
|
837
|
-
password=${
|
|
837
|
+
password=${c}
|
|
838
838
|
|
|
839
839
|
[supervisorctl]
|
|
840
840
|
serverurl=http://127.0.0.1:${l}
|
|
841
841
|
username=default-user
|
|
842
|
-
password=${
|
|
842
|
+
password=${c}
|
|
843
843
|
|
|
844
844
|
[program:platforma]
|
|
845
845
|
autostart=true
|
|
@@ -850,14 +850,14 @@ autorestart=true
|
|
|
850
850
|
|
|
851
851
|
[program:minio]
|
|
852
852
|
autostart=true
|
|
853
|
-
environment=${
|
|
853
|
+
environment=${a}
|
|
854
854
|
command=${o} server ${s}
|
|
855
855
|
directory=${e}
|
|
856
856
|
autorestart=true
|
|
857
857
|
`;
|
|
858
858
|
}
|
|
859
859
|
async function U(s, r, t, e) {
|
|
860
|
-
const i =
|
|
860
|
+
const i = q(r, t), o = K(r), n = `${i} --configuration ${o} ${e}`;
|
|
861
861
|
return await s.exec(n);
|
|
862
862
|
}
|
|
863
863
|
function _(s, r) {
|
|
@@ -870,7 +870,7 @@ function _(s, r) {
|
|
|
870
870
|
const P = p.object({
|
|
871
871
|
local: p.number(),
|
|
872
872
|
remote: p.number()
|
|
873
|
-
}),
|
|
873
|
+
}), Vt = p.object({
|
|
874
874
|
grpc: P,
|
|
875
875
|
monitoring: P,
|
|
876
876
|
debug: P,
|
|
@@ -879,7 +879,7 @@ const P = p.object({
|
|
|
879
879
|
}), Wt = p.object({
|
|
880
880
|
plUser: p.string(),
|
|
881
881
|
plPassword: p.string(),
|
|
882
|
-
ports:
|
|
882
|
+
ports: Vt,
|
|
883
883
|
// It's false by default because it was added later,
|
|
884
884
|
// and in some deployments there won't be useGlobalAccess flag in the file.
|
|
885
885
|
useGlobalAccess: p.boolean().default(!1),
|
|
@@ -895,13 +895,14 @@ function zt(s, r, t, e, i) {
|
|
|
895
895
|
plVersion: i
|
|
896
896
|
};
|
|
897
897
|
}
|
|
898
|
-
function
|
|
898
|
+
function qt(s) {
|
|
899
899
|
return Wt.parse(JSON.parse(s));
|
|
900
900
|
}
|
|
901
|
-
function
|
|
901
|
+
function Kt(s) {
|
|
902
902
|
return JSON.stringify(s, void 0, 2);
|
|
903
903
|
}
|
|
904
|
-
|
|
904
|
+
const j = 2.28;
|
|
905
|
+
class Z {
|
|
905
906
|
constructor(r, t, e) {
|
|
906
907
|
w(this, "initState", {});
|
|
907
908
|
this.logger = r, this.sshClient = t, this.username = e;
|
|
@@ -915,7 +916,7 @@ class q {
|
|
|
915
916
|
static async init(r, t) {
|
|
916
917
|
try {
|
|
917
918
|
const e = await B.init(r, t);
|
|
918
|
-
return new
|
|
919
|
+
return new Z(r, e, f(t.username));
|
|
919
920
|
} catch (e) {
|
|
920
921
|
throw r.error(`Connection error in SshClient.init: ${e}`), e;
|
|
921
922
|
}
|
|
@@ -926,7 +927,7 @@ class q {
|
|
|
926
927
|
/** Provides an info if the platforma and minio are running along with the debug info. */
|
|
927
928
|
async isAlive() {
|
|
928
929
|
const r = await this.getArch(), t = await this.getUserHomeDirectory();
|
|
929
|
-
return await
|
|
930
|
+
return await Jt(this.logger, this.sshClient, t, r.arch);
|
|
930
931
|
}
|
|
931
932
|
/** Starts all the services on the server.
|
|
932
933
|
* Idempotent semantic: we could call it several times. */
|
|
@@ -934,9 +935,9 @@ class q {
|
|
|
934
935
|
const r = await this.getArch(), t = await this.getUserHomeDirectory();
|
|
935
936
|
try {
|
|
936
937
|
if (!(await this.isAlive()).allAlive)
|
|
937
|
-
return await
|
|
938
|
+
return await Mt(this.sshClient, t, r.arch), await this.checkIsAliveWithInterval();
|
|
938
939
|
} catch (e) {
|
|
939
|
-
const i = `SshPl.start:
|
|
940
|
+
const i = `SshPl.start: ${e}`;
|
|
940
941
|
throw this.logger.error(i), new Error(i);
|
|
941
942
|
}
|
|
942
943
|
}
|
|
@@ -946,9 +947,9 @@ class q {
|
|
|
946
947
|
const r = await this.getArch(), t = await this.getUserHomeDirectory();
|
|
947
948
|
try {
|
|
948
949
|
if ((await this.isAlive()).allAlive)
|
|
949
|
-
return await
|
|
950
|
+
return await Gt(this.sshClient, t, r.arch), await this.checkIsAliveWithInterval(void 0, void 0, !1);
|
|
950
951
|
} catch (e) {
|
|
951
|
-
const i = `PlSsh.stop:
|
|
952
|
+
const i = `PlSsh.stop: ${e}`;
|
|
952
953
|
throw this.logger.error(i), new Error(i);
|
|
953
954
|
}
|
|
954
955
|
}
|
|
@@ -968,26 +969,29 @@ class q {
|
|
|
968
969
|
const t = { localWorkdir: r.localWorkdir };
|
|
969
970
|
try {
|
|
970
971
|
const e = {
|
|
971
|
-
...
|
|
972
|
+
...Zt,
|
|
972
973
|
...r
|
|
973
974
|
};
|
|
974
975
|
if (t.plBinaryOps = e.plBinary, t.arch = await this.getArch(), t.remoteHome = await this.getUserHomeDirectory(), t.alive = await this.isAlive(), t.alive.allAlive) {
|
|
975
976
|
if (t.userCredentials = await this.getUserCredentials(t.remoteHome), !t.userCredentials)
|
|
976
977
|
throw new Error("SshPl.platformaInit: platforma is alive but userCredentials are not found");
|
|
977
|
-
const
|
|
978
|
-
if (t.needRestart = !(
|
|
978
|
+
const l = t.userCredentials.useGlobalAccess == e.useGlobalAccess, h = t.userCredentials.plVersion == e.plBinary.version;
|
|
979
|
+
if (t.needRestart = !(l && h), this.logger.info(`SshPl.platformaInit: need restart? ${t.needRestart}`), !t.needRestart)
|
|
979
980
|
return t.userCredentials;
|
|
980
981
|
await this.stop();
|
|
981
982
|
}
|
|
982
|
-
const i = await this.
|
|
983
|
+
const i = await Yt(this.logger, this.sshClient);
|
|
984
|
+
if (i < j)
|
|
985
|
+
throw new Error(`glibc version ${i} is too old. Version ${j} or higher is required for Platforma.`);
|
|
986
|
+
const o = await this.downloadBinariesAndUploadToTheServer(
|
|
983
987
|
e.localWorkdir,
|
|
984
988
|
e.plBinary,
|
|
985
989
|
t.remoteHome,
|
|
986
990
|
t.arch
|
|
987
991
|
);
|
|
988
|
-
if (t.binPaths = { ...
|
|
992
|
+
if (t.binPaths = { ...o, history: void 0 }, t.downloadedBinaries = o.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)
|
|
989
993
|
throw new Error("SshPl.platformaInit: remote ports are not defined");
|
|
990
|
-
const
|
|
994
|
+
const n = await ht({
|
|
991
995
|
logger: this.logger,
|
|
992
996
|
workingDir: g(t.remoteHome),
|
|
993
997
|
portsMode: {
|
|
@@ -1003,36 +1007,37 @@ class q {
|
|
|
1003
1007
|
}
|
|
1004
1008
|
},
|
|
1005
1009
|
licenseMode: e.license,
|
|
1006
|
-
useGlobalAccess: f(e.useGlobalAccess)
|
|
1010
|
+
useGlobalAccess: f(e.useGlobalAccess),
|
|
1011
|
+
plConfigPostprocessing: e.plConfigPostprocessing
|
|
1007
1012
|
});
|
|
1008
|
-
t.generatedConfig = { ...
|
|
1009
|
-
for (const [
|
|
1010
|
-
await this.sshClient.writeFileOnTheServer(
|
|
1011
|
-
for (const
|
|
1012
|
-
await this.sshClient.ensureRemoteDirCreated(
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1013
|
+
t.generatedConfig = { ...n, filesToCreate: { skipped: "it is too wordy" } };
|
|
1014
|
+
for (const [l, h] of Object.entries(n.filesToCreate))
|
|
1015
|
+
await this.sshClient.writeFileOnTheServer(l, h), this.logger.info(`Created file ${l}`);
|
|
1016
|
+
for (const l of n.dirsToCreate)
|
|
1017
|
+
await this.sshClient.ensureRemoteDirCreated(l), this.logger.info(`Created directory ${l}`);
|
|
1018
|
+
const a = Lt(
|
|
1019
|
+
n.minioConfig.storageDir,
|
|
1020
|
+
n.minioConfig.envs,
|
|
1016
1021
|
await this.getFreePortForPlatformaOnServer(t.remoteHome, t.arch),
|
|
1017
|
-
|
|
1018
|
-
|
|
1022
|
+
n.workingDir,
|
|
1023
|
+
n.plConfig.configPath,
|
|
1019
1024
|
t.binPaths.minioRelPath,
|
|
1020
1025
|
t.binPaths.downloadedPl
|
|
1021
1026
|
);
|
|
1022
|
-
if (!await this.sshClient.writeFileOnTheServer(
|
|
1027
|
+
if (!await this.sshClient.writeFileOnTheServer(K(t.remoteHome), a))
|
|
1023
1028
|
throw new Error(`Can not write supervisord config on the server ${g(t.remoteHome)}`);
|
|
1024
1029
|
return t.connectionInfo = zt(
|
|
1025
|
-
|
|
1026
|
-
|
|
1030
|
+
n.plUser,
|
|
1031
|
+
n.plPassword,
|
|
1027
1032
|
t.ports,
|
|
1028
1033
|
f(e.useGlobalAccess),
|
|
1029
1034
|
e.plBinary.version
|
|
1030
1035
|
), await this.sshClient.writeFileOnTheServer(
|
|
1031
1036
|
I(t.remoteHome),
|
|
1032
|
-
|
|
1037
|
+
Kt(t.connectionInfo)
|
|
1033
1038
|
), await this.start(), t.started = !0, this.initState = t, t.connectionInfo;
|
|
1034
1039
|
} catch (e) {
|
|
1035
|
-
const i = `SshPl.platformaInit:
|
|
1040
|
+
const i = `SshPl.platformaInit: ${e}, state: ${JSON.stringify(t)}`;
|
|
1036
1041
|
throw this.logger.error(i), new Error(i);
|
|
1037
1042
|
}
|
|
1038
1043
|
}
|
|
@@ -1047,29 +1052,29 @@ class q {
|
|
|
1047
1052
|
`pl-${t.version}`
|
|
1048
1053
|
);
|
|
1049
1054
|
o.push(n);
|
|
1050
|
-
const
|
|
1055
|
+
const a = await this.downloadAndUntar(
|
|
1051
1056
|
r,
|
|
1052
1057
|
e,
|
|
1053
1058
|
i,
|
|
1054
1059
|
"supervisord",
|
|
1055
|
-
|
|
1060
|
+
Ut
|
|
1056
1061
|
);
|
|
1057
|
-
o.push(
|
|
1058
|
-
const
|
|
1062
|
+
o.push(a);
|
|
1063
|
+
const c = jt(e, i.arch), l = await this.downloadAndUntar(
|
|
1059
1064
|
r,
|
|
1060
1065
|
e,
|
|
1061
1066
|
i,
|
|
1062
1067
|
"minio",
|
|
1063
|
-
|
|
1068
|
+
Bt
|
|
1064
1069
|
);
|
|
1065
|
-
return o.push(l), await this.sshClient.chmod(
|
|
1070
|
+
return o.push(l), await this.sshClient.chmod(c, 488), {
|
|
1066
1071
|
history: o,
|
|
1067
|
-
minioRelPath:
|
|
1072
|
+
minioRelPath: c,
|
|
1068
1073
|
downloadedPl: T(e, i.arch)
|
|
1069
1074
|
};
|
|
1070
1075
|
} catch (n) {
|
|
1071
|
-
const
|
|
1072
|
-
throw this.logger.error(
|
|
1076
|
+
const a = `SshPl.downloadBinariesAndUploadToServer: ${n}, state: ${JSON.stringify(o)}`;
|
|
1077
|
+
throw this.logger.error(a), n;
|
|
1073
1078
|
}
|
|
1074
1079
|
}
|
|
1075
1080
|
/** We have to extract pl in the remote server,
|
|
@@ -1081,11 +1086,11 @@ class q {
|
|
|
1081
1086
|
async downloadAndUntar(r, t, e, i, o) {
|
|
1082
1087
|
const n = {};
|
|
1083
1088
|
n.binBasePath = E(t), await this.sshClient.ensureRemoteDirCreated(n.binBasePath), n.binBasePathCreated = !0;
|
|
1084
|
-
let
|
|
1085
|
-
const
|
|
1086
|
-
for (let h = 1; h <=
|
|
1089
|
+
let a = null;
|
|
1090
|
+
const c = 5;
|
|
1091
|
+
for (let h = 1; h <= c; h++)
|
|
1087
1092
|
try {
|
|
1088
|
-
|
|
1093
|
+
a = await mt(
|
|
1089
1094
|
this.logger,
|
|
1090
1095
|
r,
|
|
1091
1096
|
i,
|
|
@@ -1095,33 +1100,38 @@ class q {
|
|
|
1095
1100
|
);
|
|
1096
1101
|
break;
|
|
1097
1102
|
} catch (u) {
|
|
1098
|
-
if (await
|
|
1099
|
-
throw new Error(`downloadAndUntar: ${
|
|
1103
|
+
if (await F(300), h == c)
|
|
1104
|
+
throw new Error(`downloadAndUntar: ${c} attempts, last error: ${u}`);
|
|
1100
1105
|
}
|
|
1101
|
-
n.downloadResult = f(
|
|
1106
|
+
n.downloadResult = f(a), n.localArchivePath = d.resolve(n.downloadResult.archivePath), n.remoteDir = d.join(n.binBasePath, n.downloadResult.baseName), n.remoteArchivePath = n.remoteDir + ".tgz", await this.sshClient.ensureRemoteDirCreated(n.remoteDir), await this.sshClient.uploadFile(n.localArchivePath, n.remoteArchivePath), n.uploadDone = !0;
|
|
1107
|
+
try {
|
|
1108
|
+
await this.sshClient.exec("hash tar");
|
|
1109
|
+
} catch {
|
|
1110
|
+
throw new Error("tar is not installed on the server. Please install it before running Platforma.");
|
|
1111
|
+
}
|
|
1102
1112
|
const l = await this.sshClient.exec(
|
|
1103
1113
|
`tar --warning=no-all -xvf ${n.remoteArchivePath} --directory=${n.remoteDir}`
|
|
1104
1114
|
);
|
|
1105
1115
|
if (l.stderr)
|
|
1106
|
-
throw Error(`downloadAndUntar: untar: stderr occurred: ${l.stderr}, stdout: ${l.stdout}`);
|
|
1116
|
+
throw new Error(`downloadAndUntar: untar: stderr occurred: ${l.stderr}, stdout: ${l.stdout}`);
|
|
1107
1117
|
return n.untarDone = !0, n;
|
|
1108
1118
|
}
|
|
1109
1119
|
async needDownload(r, t) {
|
|
1110
|
-
const e =
|
|
1120
|
+
const e = q(r, t.arch), i = z(r, t.arch), o = T(r, t.arch);
|
|
1111
1121
|
return !await this.sshClient.checkFileExists(o) || !await this.sshClient.checkFileExists(i) || !await this.sshClient.checkFileExists(e);
|
|
1112
1122
|
}
|
|
1113
1123
|
async checkIsAliveWithInterval(r = 1e3, t = 15, e = !0) {
|
|
1114
1124
|
const i = t * r;
|
|
1115
1125
|
let o = 0, n = await this.isAlive();
|
|
1116
1126
|
for (; e ? !n.allAlive : n.allAlive; ) {
|
|
1117
|
-
if (await
|
|
1127
|
+
if (await F(r), o += r, o > i)
|
|
1118
1128
|
throw new Error(`isAliveWithInterval: The process did not ${e ? "started" : "stopped"} after ${i} ms. Live status: ${JSON.stringify(n)}`);
|
|
1119
1129
|
n = await this.isAlive();
|
|
1120
1130
|
}
|
|
1121
1131
|
}
|
|
1122
1132
|
async getUserCredentials(r) {
|
|
1123
1133
|
const t = await this.sshClient.readFile(I(r));
|
|
1124
|
-
return
|
|
1134
|
+
return qt(t);
|
|
1125
1135
|
}
|
|
1126
1136
|
async fetchPorts(r, t) {
|
|
1127
1137
|
return {
|
|
@@ -1149,7 +1159,7 @@ class q {
|
|
|
1149
1159
|
}
|
|
1150
1160
|
async getLocalFreePort() {
|
|
1151
1161
|
return new Promise((r) => {
|
|
1152
|
-
const t =
|
|
1162
|
+
const t = M.createServer();
|
|
1153
1163
|
t.listen(0, () => {
|
|
1154
1164
|
const e = t.address().port;
|
|
1155
1165
|
t.close((i) => r(e));
|
|
@@ -1157,7 +1167,7 @@ class q {
|
|
|
1157
1167
|
});
|
|
1158
1168
|
}
|
|
1159
1169
|
async getFreePortForPlatformaOnServer(r, t) {
|
|
1160
|
-
const e =
|
|
1170
|
+
const e = _t(r, t.arch), { stdout: i, stderr: o } = await this.sshClient.exec(`${e}`);
|
|
1161
1171
|
if (o)
|
|
1162
1172
|
throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${o}, stdout: ${i}`);
|
|
1163
1173
|
return +i;
|
|
@@ -1182,25 +1192,42 @@ class q {
|
|
|
1182
1192
|
return r.trim();
|
|
1183
1193
|
}
|
|
1184
1194
|
}
|
|
1185
|
-
const
|
|
1195
|
+
const Zt = {
|
|
1186
1196
|
useGlobalAccess: !1,
|
|
1187
1197
|
plBinary: {
|
|
1188
1198
|
type: "Download",
|
|
1189
1199
|
version: R()
|
|
1190
1200
|
}
|
|
1191
1201
|
};
|
|
1202
|
+
async function Yt(s, r) {
|
|
1203
|
+
try {
|
|
1204
|
+
const { stdout: t, stderr: e } = await r.exec("ldd --version | head -n 1");
|
|
1205
|
+
if (e)
|
|
1206
|
+
throw new Error(`Failed to check glibc version: ${e}`);
|
|
1207
|
+
return Qt(t);
|
|
1208
|
+
} catch (t) {
|
|
1209
|
+
throw s.error(`glibc version check failed: ${t}`), t;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
function Qt(s) {
|
|
1213
|
+
const r = s.match(/\d+\.\d+/);
|
|
1214
|
+
if (!r)
|
|
1215
|
+
throw new Error(`Could not parse glibc version from: ${s}`);
|
|
1216
|
+
return parseFloat(r[0]);
|
|
1217
|
+
}
|
|
1192
1218
|
export {
|
|
1193
1219
|
Wt as ConnectionInfo,
|
|
1194
|
-
|
|
1195
|
-
|
|
1220
|
+
Dt as LocalConfigYaml,
|
|
1221
|
+
xt as LocalPl,
|
|
1196
1222
|
P as PortPair,
|
|
1197
1223
|
B as SshClient,
|
|
1198
|
-
|
|
1199
|
-
|
|
1224
|
+
Z as SshPl,
|
|
1225
|
+
Vt as SshPlPorts,
|
|
1200
1226
|
R as getDefaultPlVersion,
|
|
1201
|
-
|
|
1227
|
+
gr as localPlatformaInit,
|
|
1202
1228
|
zt as newConnectionInfo,
|
|
1203
|
-
|
|
1204
|
-
|
|
1229
|
+
qt as parseConnectionInfo,
|
|
1230
|
+
Qt as parseGlibcVersion,
|
|
1231
|
+
Kt as stringifyConnectionInfo
|
|
1205
1232
|
};
|
|
1206
1233
|
//# sourceMappingURL=index.mjs.map
|