@milaboratories/pl-deployments 2.3.3 → 2.4.1
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 +34 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +683 -585
- package/dist/index.mjs.map +1 -1
- package/dist/ssh/connection_info.d.ts +52 -1
- package/dist/ssh/connection_info.d.ts.map +1 -1
- package/dist/ssh/pl.d.ts +22 -7
- package/dist/ssh/pl.d.ts.map +1 -1
- package/dist/ssh/supervisord.d.ts +4 -2
- package/dist/ssh/supervisord.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ssh/__tests__/pl-docker.test.ts +13 -10
- package/src/ssh/connection_info.ts +8 -0
- package/src/ssh/pl.ts +268 -138
- package/src/ssh/supervisord.ts +47 -8
package/dist/index.mjs
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { spawn as
|
|
5
|
-
import { sleep as
|
|
1
|
+
var Y = Object.defineProperty;
|
|
2
|
+
var Q = (o, t, e) => t in o ? Y(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
|
+
var p = (o, t, e) => Q(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { spawn as tt } from "node:child_process";
|
|
5
|
+
import { sleep as x, fileExists as v, assertNever as j, notEmpty as m, RetryablePromise as et } from "@milaboratories/ts-helpers";
|
|
6
6
|
import O from "node:fs";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { request as
|
|
10
|
-
import { Readable as
|
|
11
|
-
import { text as
|
|
12
|
-
import * as
|
|
13
|
-
import
|
|
14
|
-
import * as
|
|
15
|
-
import
|
|
16
|
-
import
|
|
7
|
+
import y, { readFile as rt } from "node:fs/promises";
|
|
8
|
+
import h from "upath";
|
|
9
|
+
import { request as it } from "undici";
|
|
10
|
+
import { Readable as nt, Writable as ot } from "node:stream";
|
|
11
|
+
import { text as st } from "node:stream/consumers";
|
|
12
|
+
import * as at from "tar";
|
|
13
|
+
import ct from "decompress";
|
|
14
|
+
import * as lt from "node:os";
|
|
15
|
+
import b from "node:os";
|
|
16
|
+
import dt, { Client as D } from "ssh2";
|
|
17
17
|
import G from "node:net";
|
|
18
18
|
import ht from "node:dns";
|
|
19
|
-
import { randomBytes as
|
|
20
|
-
import { generateSshPlConfigs as
|
|
21
|
-
import { z as
|
|
22
|
-
function
|
|
19
|
+
import { randomBytes as F } from "node:crypto";
|
|
20
|
+
import { generateSshPlConfigs as ut, getFreePort as $ } from "@milaboratories/pl-config";
|
|
21
|
+
import { z as w } from "zod";
|
|
22
|
+
function pt(o, t) {
|
|
23
23
|
return o.info(`Running:
|
|
24
|
-
cmd: ${JSON.stringify([
|
|
25
|
-
wd: ${
|
|
24
|
+
cmd: ${JSON.stringify([t.cmd, ...t.args])}
|
|
25
|
+
wd: ${t.opts.cwd}`), o.info(" spawning child process"), tt(t.cmd, t.args, t.opts);
|
|
26
26
|
}
|
|
27
|
-
async function
|
|
27
|
+
async function k(o) {
|
|
28
28
|
try {
|
|
29
29
|
return process.kill(o, 0), !0;
|
|
30
30
|
} catch {
|
|
31
31
|
return !1;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function J(o) {
|
|
35
35
|
return process.kill(o, "SIGINT");
|
|
36
36
|
}
|
|
37
|
-
async function
|
|
38
|
-
let
|
|
39
|
-
for (; await
|
|
40
|
-
if (await
|
|
41
|
-
throw new Error(`The process did not stopped after ${
|
|
37
|
+
async function L(o, t) {
|
|
38
|
+
let r = 0;
|
|
39
|
+
for (; await k(o); )
|
|
40
|
+
if (await x(100), r += 100, r > t)
|
|
41
|
+
throw new Error(`The process did not stopped after ${t} ms.`);
|
|
42
42
|
}
|
|
43
43
|
const wt = ["linux", "macos", "windows"];
|
|
44
|
-
function
|
|
44
|
+
function R(o) {
|
|
45
45
|
switch (o.toLowerCase()) {
|
|
46
46
|
case "darwin":
|
|
47
47
|
return "macos";
|
|
@@ -56,7 +56,7 @@ function k(o) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
const ft = ["amd64", "arm64"];
|
|
59
|
-
function
|
|
59
|
+
function C(o) {
|
|
60
60
|
switch (o) {
|
|
61
61
|
case "aarch64":
|
|
62
62
|
case "aarch64_be":
|
|
@@ -71,176 +71,176 @@ function P(o) {
|
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
const
|
|
75
|
-
async function gt(o, e, r,
|
|
76
|
-
const s =
|
|
74
|
+
const mt = "https://cdn.platforma.bio/software", yt = "https://cdn-ga.pl-open.science/software";
|
|
75
|
+
async function gt(o, t, e, r, i, n) {
|
|
76
|
+
const s = z(e, r, t, C(i), R(n)), { archiveUrl: a, alternativeArchiveGAUrl: c, archivePath: l } = s;
|
|
77
77
|
try {
|
|
78
|
-
await
|
|
78
|
+
await A(o, a, l), s.wasDownloadedFrom = a;
|
|
79
79
|
} catch {
|
|
80
|
-
await
|
|
80
|
+
await A(o, c, l), s.wasDownloadedFrom = c;
|
|
81
81
|
}
|
|
82
82
|
return s;
|
|
83
83
|
}
|
|
84
|
-
async function
|
|
85
|
-
const s =
|
|
84
|
+
async function vt(o, t, e, r, i, n) {
|
|
85
|
+
const s = z(e, r, t, C(i), R(n)), { archiveUrl: a, alternativeArchiveGAUrl: c, archivePath: l, archiveType: d, targetFolder: u } = s;
|
|
86
86
|
try {
|
|
87
|
-
await
|
|
87
|
+
await A(o, a, l), s.wasDownloadedFrom = a;
|
|
88
88
|
} catch {
|
|
89
|
-
await
|
|
89
|
+
await A(o, c, l), s.wasDownloadedFrom = c;
|
|
90
90
|
}
|
|
91
|
-
return await
|
|
91
|
+
return await St(o, l, d, u), s;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
94
|
-
const n = `${
|
|
93
|
+
function z(o, t, e, r, i) {
|
|
94
|
+
const n = `${t}-${r}`, s = Ct[i], a = `${n}.${s}`, c = `${mt}/${o}/${i}/${a}`, l = `${yt}/${o}/${i}/${a}`, d = h.join(e, a), u = h.join(e, n);
|
|
95
95
|
return {
|
|
96
96
|
archiveUrl: c,
|
|
97
97
|
alternativeArchiveGAUrl: l,
|
|
98
|
-
archivePath:
|
|
98
|
+
archivePath: d,
|
|
99
99
|
archiveType: s,
|
|
100
|
-
targetFolder:
|
|
100
|
+
targetFolder: u,
|
|
101
101
|
baseName: n
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
-
async function
|
|
105
|
-
const
|
|
106
|
-
|
|
104
|
+
async function A(o, t, e) {
|
|
105
|
+
const r = {};
|
|
106
|
+
r.dstArchive = e;
|
|
107
107
|
try {
|
|
108
|
-
if (
|
|
109
|
-
return o.info(`Platforma Backend archive download skipped: '${
|
|
110
|
-
await
|
|
111
|
-
URL: ${
|
|
112
|
-
Save to: ${
|
|
113
|
-
const { body: i, statusCode: n } = await
|
|
114
|
-
if (
|
|
115
|
-
const s = await
|
|
116
|
-
throw
|
|
108
|
+
if (r.fileExisted = await v(e), r.fileExisted)
|
|
109
|
+
return o.info(`Platforma Backend archive download skipped: '${e}' already exists`), r;
|
|
110
|
+
await y.mkdir(h.dirname(e), { recursive: !0 }), r.dirnameCreated = !0, o.info(`Downloading archive:
|
|
111
|
+
URL: ${t}
|
|
112
|
+
Save to: ${e}`);
|
|
113
|
+
const { body: i, statusCode: n } = await it(t);
|
|
114
|
+
if (r.statusCode = n, n != 200) {
|
|
115
|
+
const s = await st(i);
|
|
116
|
+
throw r.errorMsg = `failed to download archive: ${n}, response: ${s.slice(0, 1e3)}`, o.error(r.errorMsg), new Error(r.errorMsg);
|
|
117
117
|
}
|
|
118
|
-
return
|
|
118
|
+
return r.tmpPath = e + ".tmp", await nt.toWeb(i).pipeTo(ot.toWeb(O.createWriteStream(r.tmpPath))), r.wroteTmp = !0, r.tmpExisted = await v(r.tmpPath), await y.rename(r.tmpPath, e), r.renamed = !0, r.newExisted = await v(e), r;
|
|
119
119
|
} catch (i) {
|
|
120
|
-
const n = `downloadArchive: ${JSON.stringify(i)}, state: ${JSON.stringify(
|
|
120
|
+
const n = `downloadArchive: ${JSON.stringify(i)}, state: ${JSON.stringify(r)}`;
|
|
121
121
|
throw o.error(n), new Error(n);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
-
const
|
|
125
|
-
async function
|
|
126
|
-
if (o.info("extracting archive..."), o.info(` archive path: '${
|
|
127
|
-
const n = `Platforma Backend binary archive not found at '${
|
|
124
|
+
const $t = ".ok";
|
|
125
|
+
async function St(o, t, e, r) {
|
|
126
|
+
if (o.info("extracting archive..."), o.info(` archive path: '${t}'`), o.info(` target dir: '${r}'`), !await v(t)) {
|
|
127
|
+
const n = `Platforma Backend binary archive not found at '${t}'`;
|
|
128
128
|
throw o.error(n), new Error(n);
|
|
129
129
|
}
|
|
130
|
-
const i =
|
|
130
|
+
const i = h.join(r, $t);
|
|
131
131
|
if (await v(i)) {
|
|
132
|
-
o.info(`Platforma Backend binaries unpack skipped: '${
|
|
132
|
+
o.info(`Platforma Backend binaries unpack skipped: '${r}' exists`);
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
|
-
switch (await v(
|
|
135
|
+
switch (await v(r) && (o.info(`Removing previous incompletely unpacked folder: '${r}'`), await y.rm(r, { recursive: !0 })), o.info(` creating target dir '${r}'`), await y.mkdir(r, { recursive: !0 }), o.info(
|
|
136
136
|
`Unpacking Platforma Backend archive:
|
|
137
|
-
Archive: ${
|
|
138
|
-
Target dir: ${
|
|
139
|
-
),
|
|
137
|
+
Archive: ${t}
|
|
138
|
+
Target dir: ${r}`
|
|
139
|
+
), e) {
|
|
140
140
|
case "tgz":
|
|
141
|
-
await
|
|
142
|
-
file:
|
|
143
|
-
cwd:
|
|
141
|
+
await at.x({
|
|
142
|
+
file: t,
|
|
143
|
+
cwd: r,
|
|
144
144
|
gzip: !0
|
|
145
145
|
});
|
|
146
146
|
break;
|
|
147
147
|
case "zip":
|
|
148
|
-
await
|
|
148
|
+
await ct(t, r);
|
|
149
149
|
break;
|
|
150
150
|
default:
|
|
151
|
-
|
|
151
|
+
j(e);
|
|
152
152
|
}
|
|
153
|
-
await
|
|
153
|
+
await y.writeFile(i, "ok"), o.info(" ... unpack done.");
|
|
154
154
|
}
|
|
155
|
-
const
|
|
155
|
+
const Ct = {
|
|
156
156
|
linux: "tgz",
|
|
157
157
|
macos: "tgz",
|
|
158
158
|
windows: "zip"
|
|
159
159
|
};
|
|
160
|
-
function
|
|
161
|
-
return "1.
|
|
160
|
+
function N() {
|
|
161
|
+
return "1.34.2";
|
|
162
162
|
}
|
|
163
|
-
function
|
|
164
|
-
return { type: "Download", version:
|
|
163
|
+
function Et() {
|
|
164
|
+
return { type: "Download", version: N() };
|
|
165
165
|
}
|
|
166
|
-
async function
|
|
167
|
-
switch (
|
|
166
|
+
async function Ft(o, t, e) {
|
|
167
|
+
switch (e.type) {
|
|
168
168
|
case "Download":
|
|
169
|
-
const
|
|
170
|
-
return
|
|
169
|
+
const r = await vt(o, t, "pl", `pl-${e.version}`, b.arch(), b.platform());
|
|
170
|
+
return h.join(r.baseName, "binaries", At[R(b.platform())]);
|
|
171
171
|
case "Local":
|
|
172
|
-
return
|
|
172
|
+
return e.path;
|
|
173
173
|
default:
|
|
174
|
-
|
|
174
|
+
j(e);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
-
const
|
|
177
|
+
const At = {
|
|
178
178
|
linux: "platforma",
|
|
179
179
|
macos: "platforma",
|
|
180
180
|
windows: "platforma.exe"
|
|
181
181
|
};
|
|
182
|
-
function
|
|
183
|
-
return
|
|
182
|
+
function V(o) {
|
|
183
|
+
return h.join(o, "pl_pid");
|
|
184
184
|
}
|
|
185
|
-
async function
|
|
185
|
+
async function Pt(o) {
|
|
186
186
|
if (!await v(o))
|
|
187
187
|
return;
|
|
188
|
-
const
|
|
189
|
-
return Number(
|
|
188
|
+
const t = await y.readFile(o);
|
|
189
|
+
return Number(t.toString());
|
|
190
190
|
}
|
|
191
|
-
async function bt(o,
|
|
192
|
-
await
|
|
191
|
+
async function bt(o, t) {
|
|
192
|
+
await y.writeFile(o, JSON.stringify(t));
|
|
193
193
|
}
|
|
194
|
-
function
|
|
194
|
+
function Dt() {
|
|
195
195
|
return {};
|
|
196
196
|
}
|
|
197
|
-
function
|
|
198
|
-
return o[
|
|
197
|
+
function xt(o, t, e) {
|
|
198
|
+
return o[t] = e, e;
|
|
199
199
|
}
|
|
200
|
-
async function
|
|
201
|
-
const
|
|
200
|
+
async function U(o, t) {
|
|
201
|
+
const e = Dt();
|
|
202
202
|
try {
|
|
203
|
-
return await
|
|
204
|
-
} catch (
|
|
205
|
-
throw o.error(`error ${
|
|
203
|
+
return await t((i, n) => xt(e, i, n), e);
|
|
204
|
+
} catch (r) {
|
|
205
|
+
throw o.error(`error ${r} while doing traced operation, state: ${JSON.stringify(e)}`), r;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
const
|
|
209
|
-
class
|
|
210
|
-
constructor(e, r,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
this.logger =
|
|
208
|
+
const Ot = "config-local.yaml";
|
|
209
|
+
class kt {
|
|
210
|
+
constructor(t, e, r, i, n, s, a, c) {
|
|
211
|
+
p(this, "instance");
|
|
212
|
+
p(this, "pid");
|
|
213
|
+
p(this, "nRuns", 0);
|
|
214
|
+
p(this, "lastRunHistory", {});
|
|
215
|
+
p(this, "wasStopped", !1);
|
|
216
|
+
this.logger = t, this.workingDir = e, this.startOptions = r, this.initialStartHistory = i, this.onClose = n, this.onError = s, this.onCloseAndError = a, this.onCloseAndErrorNoStop = c;
|
|
217
217
|
}
|
|
218
218
|
async start() {
|
|
219
|
-
await
|
|
219
|
+
await U(this.logger, async (t, e) => {
|
|
220
220
|
this.wasStopped = !1;
|
|
221
|
-
const
|
|
222
|
-
|
|
221
|
+
const r = pt(this.logger, this.startOptions);
|
|
222
|
+
r.on("error", (n) => {
|
|
223
223
|
this.logger.error(
|
|
224
224
|
`error '${n}', while running platforma, started opts: ${JSON.stringify(this.debugInfo())}`
|
|
225
225
|
), this.onError !== void 0 && this.onError(this), this.onCloseAndError !== void 0 && this.onCloseAndError(this), this.onCloseAndErrorNoStop !== void 0 && !this.wasStopped && this.onCloseAndErrorNoStop(this);
|
|
226
|
-
}),
|
|
226
|
+
}), r.on("close", () => {
|
|
227
227
|
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);
|
|
228
|
-
}),
|
|
229
|
-
const i =
|
|
230
|
-
|
|
228
|
+
}), t("started", !0);
|
|
229
|
+
const i = t("pidFile", V(this.workingDir));
|
|
230
|
+
t("pid", m(r.pid)), t("pidWritten", await bt(i, m(r.pid))), this.nRuns++, this.instance = r, this.pid = r.pid, this.lastRunHistory = e;
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
stop() {
|
|
234
|
-
this.wasStopped = !0,
|
|
234
|
+
this.wasStopped = !0, J(m(this.pid));
|
|
235
235
|
}
|
|
236
236
|
async waitStopped() {
|
|
237
|
-
await
|
|
237
|
+
await L(m(this.pid), 15e3);
|
|
238
238
|
}
|
|
239
239
|
stopped() {
|
|
240
240
|
return this.wasStopped;
|
|
241
241
|
}
|
|
242
242
|
async isAlive() {
|
|
243
|
-
return await
|
|
243
|
+
return await k(m(this.pid));
|
|
244
244
|
}
|
|
245
245
|
debugInfo() {
|
|
246
246
|
return {
|
|
@@ -253,72 +253,72 @@ class xt {
|
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
|
-
async function
|
|
257
|
-
const
|
|
258
|
-
return await
|
|
259
|
-
i("startOptions", { ...
|
|
260
|
-
const s =
|
|
261
|
-
|
|
262
|
-
const a =
|
|
263
|
-
o.info(`writing configuration '${a}'...`), await
|
|
264
|
-
const c =
|
|
256
|
+
async function Ce(o, t) {
|
|
257
|
+
const e = Math.max(lt.cpus().length - 2, 1), r = Nt(t, e);
|
|
258
|
+
return await U(o, async (i, n) => {
|
|
259
|
+
i("startOptions", { ...r, config: "too wordy" });
|
|
260
|
+
const s = h.resolve(r.workingDir);
|
|
261
|
+
r.closeOld && i("closeOld", await Rt(o, s));
|
|
262
|
+
const a = h.join(s, Ot);
|
|
263
|
+
o.info(`writing configuration '${a}'...`), await y.writeFile(a, r.config);
|
|
264
|
+
const c = h.join(s, "binaries"), l = await Ft(o, c, r.plBinary), d = i("binaryPath", h.join("binaries", l)), u = Ut(d, a, r, s, process.env);
|
|
265
265
|
i("processOpts", {
|
|
266
|
-
cmd:
|
|
267
|
-
args:
|
|
268
|
-
cwd:
|
|
266
|
+
cmd: u.cmd,
|
|
267
|
+
args: u.args,
|
|
268
|
+
cwd: u.opts.cwd
|
|
269
269
|
});
|
|
270
|
-
const f = new
|
|
270
|
+
const f = new kt(
|
|
271
271
|
o,
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
r.workingDir,
|
|
273
|
+
u,
|
|
274
274
|
n,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
r.onClose,
|
|
276
|
+
r.onError,
|
|
277
|
+
r.onCloseAndError,
|
|
278
|
+
r.onCloseAndErrorNoStop
|
|
279
279
|
);
|
|
280
280
|
return await f.start(), f;
|
|
281
281
|
});
|
|
282
282
|
}
|
|
283
|
-
async function
|
|
284
|
-
return await
|
|
285
|
-
const i =
|
|
286
|
-
return n !== void 0 && s && (
|
|
283
|
+
async function Rt(o, t) {
|
|
284
|
+
return await U(o, async (e, r) => {
|
|
285
|
+
const i = e("pidFilePath", V(t)), n = e("pid", await Pt(i)), s = e("wasAlive", await k(n));
|
|
286
|
+
return n !== void 0 && s && (e("stopped", J(n)), e("waitStopped", await L(n, 1e4))), r;
|
|
287
287
|
});
|
|
288
288
|
}
|
|
289
|
-
function
|
|
289
|
+
function Nt(o, t) {
|
|
290
290
|
var i;
|
|
291
|
-
const
|
|
292
|
-
plBinary:
|
|
291
|
+
const e = {
|
|
292
|
+
plBinary: Et(),
|
|
293
293
|
spawnOptions: {
|
|
294
294
|
env: {
|
|
295
|
-
GOMAXPROCS: String(
|
|
295
|
+
GOMAXPROCS: String(t)
|
|
296
296
|
}
|
|
297
297
|
},
|
|
298
298
|
closeOld: !0
|
|
299
299
|
};
|
|
300
|
-
if ((i = o.spawnOptions) != null && i.env && (
|
|
300
|
+
if ((i = o.spawnOptions) != null && i.env && (e.spawnOptions.env = { ...e.spawnOptions.env, ...o.spawnOptions.env }), o.spawnOptions) {
|
|
301
301
|
const n = { ...o.spawnOptions };
|
|
302
|
-
delete n.env,
|
|
302
|
+
delete n.env, e.spawnOptions = { ...e.spawnOptions, ...n };
|
|
303
303
|
}
|
|
304
|
-
const
|
|
305
|
-
return delete
|
|
304
|
+
const r = { ...o };
|
|
305
|
+
return delete r.spawnOptions, { ...e, ...r };
|
|
306
306
|
}
|
|
307
|
-
function
|
|
307
|
+
function Ut(o, t, e, r, i) {
|
|
308
308
|
var a;
|
|
309
309
|
const n = {
|
|
310
310
|
cmd: o,
|
|
311
|
-
args: ["--config",
|
|
311
|
+
args: ["--config", t],
|
|
312
312
|
opts: {
|
|
313
313
|
env: { ...i },
|
|
314
|
-
cwd:
|
|
314
|
+
cwd: r,
|
|
315
315
|
stdio: ["pipe", "ignore", "inherit"],
|
|
316
316
|
windowsHide: !0
|
|
317
317
|
// hide a terminal on Windows
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
|
-
(a =
|
|
321
|
-
const s = { ...
|
|
320
|
+
(a = e.spawnOptions) != null && a.env && (n.opts.env = { ...n.opts.env, ...e.spawnOptions.env });
|
|
321
|
+
const s = { ...e.spawnOptions };
|
|
322
322
|
return delete s.env, n.opts = { ...n.opts, ...s }, n;
|
|
323
323
|
}
|
|
324
324
|
const Bt = {
|
|
@@ -326,56 +326,56 @@ const Bt = {
|
|
|
326
326
|
keepaliveCountMax: 10
|
|
327
327
|
};
|
|
328
328
|
class B {
|
|
329
|
-
constructor(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
this.logger =
|
|
329
|
+
constructor(t, e) {
|
|
330
|
+
p(this, "config");
|
|
331
|
+
p(this, "homeDir");
|
|
332
|
+
p(this, "forwardedServers", []);
|
|
333
|
+
this.logger = t, this.client = e;
|
|
334
334
|
}
|
|
335
335
|
/**
|
|
336
336
|
* Initializes the SshClient and establishes a connection using the provided configuration.
|
|
337
337
|
* @param config - The connection configuration object for the SSH client.
|
|
338
338
|
* @returns A new instance of SshClient with an active connection.
|
|
339
339
|
*/
|
|
340
|
-
static async init(
|
|
341
|
-
const
|
|
340
|
+
static async init(t, e) {
|
|
341
|
+
const r = {
|
|
342
342
|
...Bt,
|
|
343
|
-
...
|
|
344
|
-
}, i = new B(
|
|
345
|
-
return await i.connect(
|
|
343
|
+
...e
|
|
344
|
+
}, i = new B(t, new D());
|
|
345
|
+
return await i.connect(r), i;
|
|
346
346
|
}
|
|
347
347
|
getForwardedServers() {
|
|
348
348
|
return this.forwardedServers;
|
|
349
349
|
}
|
|
350
350
|
getFullHostName() {
|
|
351
|
-
var
|
|
352
|
-
return `${(
|
|
351
|
+
var t, e;
|
|
352
|
+
return `${(t = this.config) == null ? void 0 : t.host}:${(e = this.config) == null ? void 0 : e.port}`;
|
|
353
353
|
}
|
|
354
354
|
getUserName() {
|
|
355
|
-
var
|
|
356
|
-
return (
|
|
355
|
+
var t;
|
|
356
|
+
return (t = this.config) == null ? void 0 : t.username;
|
|
357
357
|
}
|
|
358
358
|
/**
|
|
359
359
|
* Connects to the SSH server using the specified configuration.
|
|
360
360
|
* @param config - The connection configuration object for the SSH client.
|
|
361
361
|
* @returns A promise that resolves when the connection is established or rejects on error.
|
|
362
362
|
*/
|
|
363
|
-
async connect(
|
|
364
|
-
return this.config =
|
|
363
|
+
async connect(t) {
|
|
364
|
+
return this.config = t, await It(this.client, t);
|
|
365
365
|
}
|
|
366
366
|
/**
|
|
367
367
|
* Executes a command on the SSH server.
|
|
368
368
|
* @param command - The command to execute on the remote server.
|
|
369
369
|
* @returns A promise resolving with the command's stdout and stderr outputs.
|
|
370
370
|
*/
|
|
371
|
-
async exec(
|
|
372
|
-
return new Promise((
|
|
373
|
-
this.client.exec(
|
|
371
|
+
async exec(t) {
|
|
372
|
+
return new Promise((e, r) => {
|
|
373
|
+
this.client.exec(t, (i, n) => {
|
|
374
374
|
if (i)
|
|
375
|
-
return
|
|
375
|
+
return r(new Error(`ssh.exec: ${t}: ${i}`));
|
|
376
376
|
let s = "", a = "";
|
|
377
377
|
n.on("close", (c) => {
|
|
378
|
-
c === 0 ?
|
|
378
|
+
c === 0 ? e({ stdout: s, stderr: a }) : r(new Error(`Command ${t} exited with code ${c}, stdout: ${s}, stderr: ${a}`));
|
|
379
379
|
}).on("data", (c) => {
|
|
380
380
|
s += c.toString();
|
|
381
381
|
}).stderr.on("data", (c) => {
|
|
@@ -390,19 +390,19 @@ class B {
|
|
|
390
390
|
* @param port - The port number to connect to on the server.
|
|
391
391
|
* @returns 'publickey' | 'password'[] A promise resolving with a list of supported authentication methods.
|
|
392
392
|
*/
|
|
393
|
-
static async getAuthTypes(
|
|
394
|
-
return new Promise((
|
|
393
|
+
static async getAuthTypes(t, e) {
|
|
394
|
+
return new Promise((r) => {
|
|
395
395
|
let i = "";
|
|
396
|
-
const n = new
|
|
396
|
+
const n = new D();
|
|
397
397
|
n.on("ready", () => {
|
|
398
398
|
n.end();
|
|
399
399
|
const s = this.extractAuthMethods(i);
|
|
400
|
-
|
|
400
|
+
r(s.length === 0 ? ["publickey", "password"] : s);
|
|
401
401
|
}), n.on("error", () => {
|
|
402
|
-
n.end(),
|
|
402
|
+
n.end(), r(["publickey", "password"]);
|
|
403
403
|
}), n.connect({
|
|
404
|
-
host:
|
|
405
|
-
port:
|
|
404
|
+
host: t,
|
|
405
|
+
port: e,
|
|
406
406
|
username: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
407
407
|
debug: (s) => {
|
|
408
408
|
i += `${s}
|
|
@@ -416,9 +416,9 @@ class B {
|
|
|
416
416
|
* @param log - The debug log output containing authentication information.
|
|
417
417
|
* @returns An array of extracted authentication methods.
|
|
418
418
|
*/
|
|
419
|
-
static extractAuthMethods(
|
|
420
|
-
const
|
|
421
|
-
return
|
|
419
|
+
static extractAuthMethods(t) {
|
|
420
|
+
const e = t.match(/Inbound: Received USERAUTH_FAILURE \((.+)\)/);
|
|
421
|
+
return e && e[1] ? e[1].split(",").map((r) => r.trim()) : [];
|
|
422
422
|
}
|
|
423
423
|
/**
|
|
424
424
|
* Sets up port forwarding between a remote port on the SSH server and a local port.
|
|
@@ -427,62 +427,62 @@ class B {
|
|
|
427
427
|
* @param config - Optional connection configuration for the SSH client.
|
|
428
428
|
* @returns { server: net.Server } A promise resolving with the created server instance.
|
|
429
429
|
*/
|
|
430
|
-
async forwardPort(
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
const i = new
|
|
434
|
-
const c = new
|
|
430
|
+
async forwardPort(t, e) {
|
|
431
|
+
const r = `ssh.forward:${t.localPort}:${t.remotePort}.id_${F(1).toString("hex")}`;
|
|
432
|
+
e = e ?? this.config;
|
|
433
|
+
const i = new et((n) => new Promise((s, a) => {
|
|
434
|
+
const c = new D();
|
|
435
435
|
c.on("ready", () => {
|
|
436
|
-
this.logger.info(`${
|
|
436
|
+
this.logger.info(`${r}.client.ready`), s(c);
|
|
437
437
|
}), c.on("error", (l) => {
|
|
438
|
-
this.logger.info(`${
|
|
438
|
+
this.logger.info(`${r}.client.error: ${l}`), n.reset(), a(l);
|
|
439
439
|
}), c.on("close", () => {
|
|
440
|
-
this.logger.info(`${
|
|
441
|
-
}), c.connect(
|
|
440
|
+
this.logger.info(`${r}.client.closed`), n.reset();
|
|
441
|
+
}), c.connect(e);
|
|
442
442
|
}));
|
|
443
443
|
return await i.ensure(), new Promise((n, s) => {
|
|
444
444
|
const a = G.createServer({ pauseOnConnect: !0 }, async (c) => {
|
|
445
|
-
const l = `${
|
|
446
|
-
let
|
|
445
|
+
const l = `${r}.sock_${F(1).toString("hex")}`;
|
|
446
|
+
let d;
|
|
447
447
|
try {
|
|
448
|
-
|
|
448
|
+
d = await i.ensure();
|
|
449
449
|
} catch (f) {
|
|
450
450
|
this.logger.info(`${l}.persistentClient.catch: ${f}`), c.end();
|
|
451
451
|
return;
|
|
452
452
|
}
|
|
453
|
-
|
|
454
|
-
let
|
|
453
|
+
d.setNoDelay(!0), c.setNoDelay(!0);
|
|
454
|
+
let u;
|
|
455
455
|
try {
|
|
456
|
-
|
|
456
|
+
u = await _t(this.logger, d, "127.0.0.1", 0, "127.0.0.1", t.remotePort);
|
|
457
457
|
} catch (f) {
|
|
458
458
|
this.logger.error(`${l}.forwardOut.err: ${f}`), c.end();
|
|
459
459
|
return;
|
|
460
460
|
}
|
|
461
|
-
c.pipe(
|
|
462
|
-
this.logger.error(`${l}.stream.error: ${f}`), c.end(),
|
|
463
|
-
}),
|
|
464
|
-
c.end(),
|
|
461
|
+
c.pipe(u), u.pipe(c), c.resume(), u.on("error", (f) => {
|
|
462
|
+
this.logger.error(`${l}.stream.error: ${f}`), c.end(), u.end();
|
|
463
|
+
}), u.on("close", () => {
|
|
464
|
+
c.end(), u.end();
|
|
465
465
|
}), c.on("close", () => {
|
|
466
|
-
this.logger.info(`${l}.localSocket: closed`), c.end(),
|
|
466
|
+
this.logger.info(`${l}.localSocket: closed`), c.end(), u.end();
|
|
467
467
|
});
|
|
468
468
|
});
|
|
469
|
-
a.listen(
|
|
470
|
-
this.logger.info(`${
|
|
469
|
+
a.listen(t.localPort, "127.0.0.1", () => {
|
|
470
|
+
this.logger.info(`${r}.server: started listening`), this.forwardedServers.push(a), n({ server: a });
|
|
471
471
|
}), a.on("error", (c) => {
|
|
472
|
-
a.close(), s(new Error(`${
|
|
472
|
+
a.close(), s(new Error(`${r}.server: error: ${JSON.stringify(c)}`));
|
|
473
473
|
}), a.on("close", () => {
|
|
474
|
-
this.logger.info(`${
|
|
474
|
+
this.logger.info(`${r}.server: closed ${JSON.stringify(t)}`), this.forwardedServers = this.forwardedServers.filter((c) => c !== a);
|
|
475
475
|
});
|
|
476
476
|
});
|
|
477
477
|
}
|
|
478
478
|
closeForwardedPorts() {
|
|
479
|
-
this.logger.info("[SSH] Closing all forwarded ports..."), this.forwardedServers.forEach((
|
|
480
|
-
const
|
|
481
|
-
if (
|
|
482
|
-
const
|
|
483
|
-
this.logger.info(`[SSH] Closing port forward for server ${
|
|
479
|
+
this.logger.info("[SSH] Closing all forwarded ports..."), this.forwardedServers.forEach((t) => {
|
|
480
|
+
const e = t.address();
|
|
481
|
+
if (e && typeof e != "string") {
|
|
482
|
+
const r = e;
|
|
483
|
+
this.logger.info(`[SSH] Closing port forward for server ${r.address}:${r.port}`);
|
|
484
484
|
}
|
|
485
|
-
|
|
485
|
+
t.close();
|
|
486
486
|
}), this.forwardedServers = [];
|
|
487
487
|
}
|
|
488
488
|
/**
|
|
@@ -490,10 +490,10 @@ class B {
|
|
|
490
490
|
* @param hostname - The hostname or IP address to check.
|
|
491
491
|
* @returns A promise resolving with `true` if the host is reachable, otherwise `false`.
|
|
492
492
|
*/
|
|
493
|
-
static async checkHostAvailability(
|
|
494
|
-
return new Promise((
|
|
495
|
-
ht.lookup(
|
|
496
|
-
|
|
493
|
+
static async checkHostAvailability(t) {
|
|
494
|
+
return new Promise((e) => {
|
|
495
|
+
ht.lookup(t, (r) => {
|
|
496
|
+
e(!r);
|
|
497
497
|
});
|
|
498
498
|
});
|
|
499
499
|
}
|
|
@@ -502,12 +502,12 @@ class B {
|
|
|
502
502
|
* @param privateKey - The private key content to check.
|
|
503
503
|
* @returns A promise resolving with `true` if a passphrase is required, otherwise `false`.
|
|
504
504
|
*/
|
|
505
|
-
static async isPassphraseRequiredForKey(
|
|
506
|
-
return new Promise((
|
|
505
|
+
static async isPassphraseRequiredForKey(t) {
|
|
506
|
+
return new Promise((e, r) => {
|
|
507
507
|
try {
|
|
508
|
-
return
|
|
508
|
+
return dt.utils.parseKey(t) instanceof Error && e(!0), e(!1);
|
|
509
509
|
} catch (i) {
|
|
510
|
-
console.log("Error parsing privateKey"),
|
|
510
|
+
console.log("Error parsing privateKey"), r(new Error(`ssh.isPassphraseRequiredForKey: err ${i}`));
|
|
511
511
|
}
|
|
512
512
|
});
|
|
513
513
|
}
|
|
@@ -518,12 +518,12 @@ class B {
|
|
|
518
518
|
* @param remotePath - The remote file path on the server.
|
|
519
519
|
* @returns A promise resolving with `true` if the file was successfully uploaded.
|
|
520
520
|
*/
|
|
521
|
-
async uploadFile(
|
|
522
|
-
return await this.withSftp(async (
|
|
523
|
-
|
|
521
|
+
async uploadFile(t, e) {
|
|
522
|
+
return await this.withSftp(async (r) => new Promise((i, n) => {
|
|
523
|
+
r.fastPut(t, e, (s) => {
|
|
524
524
|
if (s) {
|
|
525
525
|
const a = new Error(
|
|
526
|
-
`ssh.uploadFile: err: ${s}, localPath: ${
|
|
526
|
+
`ssh.uploadFile: err: ${s}, localPath: ${t}, remotePath: ${e}`
|
|
527
527
|
);
|
|
528
528
|
return n(a);
|
|
529
529
|
}
|
|
@@ -531,100 +531,100 @@ class B {
|
|
|
531
531
|
});
|
|
532
532
|
}));
|
|
533
533
|
}
|
|
534
|
-
async withSftp(
|
|
535
|
-
return new Promise((
|
|
534
|
+
async withSftp(t) {
|
|
535
|
+
return new Promise((e, r) => {
|
|
536
536
|
this.client.sftp((i, n) => {
|
|
537
537
|
if (i)
|
|
538
|
-
return
|
|
539
|
-
|
|
540
|
-
|
|
538
|
+
return r(new Error(`ssh.withSftp: sftp err: ${i}`));
|
|
539
|
+
t(n).then(e).catch((s) => {
|
|
540
|
+
r(new Error(`ssh.withSftp.callback: err ${s}`));
|
|
541
541
|
}).finally(() => {
|
|
542
542
|
n == null || n.end();
|
|
543
543
|
});
|
|
544
544
|
});
|
|
545
545
|
});
|
|
546
546
|
}
|
|
547
|
-
async writeFileOnTheServer(e, r
|
|
548
|
-
return this.withSftp(async (i) => this.writeFile(i, e, r
|
|
547
|
+
async writeFileOnTheServer(t, e, r = 432) {
|
|
548
|
+
return this.withSftp(async (i) => this.writeFile(i, t, e, r));
|
|
549
549
|
}
|
|
550
|
-
async getForderStructure(e, r
|
|
550
|
+
async getForderStructure(t, e, r = { files: [], directories: [] }) {
|
|
551
551
|
return new Promise((i, n) => {
|
|
552
|
-
|
|
552
|
+
t.readdir(e, async (s, a) => {
|
|
553
553
|
if (s)
|
|
554
554
|
return n(s);
|
|
555
555
|
for (const c of a) {
|
|
556
|
-
const l = `${
|
|
556
|
+
const l = `${e}/${c.filename}`;
|
|
557
557
|
if (c.attrs.isDirectory()) {
|
|
558
|
-
|
|
558
|
+
r.directories.push(l);
|
|
559
559
|
try {
|
|
560
|
-
await this.getForderStructure(
|
|
561
|
-
} catch (
|
|
562
|
-
return n(
|
|
560
|
+
await this.getForderStructure(t, l, r);
|
|
561
|
+
} catch (d) {
|
|
562
|
+
return n(d instanceof Error ? d : new Error(String(d)));
|
|
563
563
|
}
|
|
564
564
|
} else
|
|
565
|
-
|
|
565
|
+
r.files.push(l);
|
|
566
566
|
}
|
|
567
|
-
i(
|
|
567
|
+
i(r);
|
|
568
568
|
});
|
|
569
569
|
});
|
|
570
570
|
}
|
|
571
|
-
rmdir(
|
|
572
|
-
return new Promise((
|
|
573
|
-
|
|
571
|
+
rmdir(t, e) {
|
|
572
|
+
return new Promise((r, i) => {
|
|
573
|
+
t.rmdir(e, (n) => n ? i(n) : r(!0));
|
|
574
574
|
});
|
|
575
575
|
}
|
|
576
|
-
unlink(
|
|
577
|
-
return new Promise((
|
|
578
|
-
|
|
576
|
+
unlink(t, e) {
|
|
577
|
+
return new Promise((r, i) => {
|
|
578
|
+
t.unlink(e, (n) => n ? i(n) : r(!0));
|
|
579
579
|
});
|
|
580
580
|
}
|
|
581
|
-
async deleteFolder(
|
|
582
|
-
return this.withSftp(async (
|
|
581
|
+
async deleteFolder(t) {
|
|
582
|
+
return this.withSftp(async (e) => {
|
|
583
583
|
try {
|
|
584
|
-
const
|
|
585
|
-
this.logger.info("ssh.deleteFolder list of files and directories"), this.logger.info(`ssh.deleteFolder list of files: ${
|
|
586
|
-
for (const i of
|
|
587
|
-
this.logger.info(`ssh.deleteFolder unlink file ${i}`), await this.unlink(
|
|
588
|
-
|
|
589
|
-
for (const i of
|
|
590
|
-
this.logger.info(`ssh.deleteFolder rmdir ${i}`), await this.rmdir(
|
|
591
|
-
return await this.rmdir(
|
|
592
|
-
} catch (
|
|
593
|
-
this.logger.error(
|
|
594
|
-
const i =
|
|
595
|
-
throw new Error(`ssh.deleteFolder: path: ${
|
|
584
|
+
const r = await this.getForderStructure(e, t);
|
|
585
|
+
this.logger.info("ssh.deleteFolder list of files and directories"), this.logger.info(`ssh.deleteFolder list of files: ${r.files}`), this.logger.info(`ssh.deleteFolder list of directories: ${r.directories}`);
|
|
586
|
+
for (const i of r.files)
|
|
587
|
+
this.logger.info(`ssh.deleteFolder unlink file ${i}`), await this.unlink(e, i);
|
|
588
|
+
r.directories.sort((i, n) => n.length - i.length);
|
|
589
|
+
for (const i of r.directories)
|
|
590
|
+
this.logger.info(`ssh.deleteFolder rmdir ${i}`), await this.rmdir(e, i);
|
|
591
|
+
return await this.rmdir(e, t), !0;
|
|
592
|
+
} catch (r) {
|
|
593
|
+
this.logger.error(r);
|
|
594
|
+
const i = r instanceof Error ? r.message : "";
|
|
595
|
+
throw new Error(`ssh.deleteFolder: path: ${t}, message: ${i}`);
|
|
596
596
|
}
|
|
597
597
|
});
|
|
598
598
|
}
|
|
599
|
-
async readFile(
|
|
600
|
-
return this.withSftp(async (
|
|
601
|
-
|
|
599
|
+
async readFile(t) {
|
|
600
|
+
return this.withSftp(async (e) => new Promise((r, i) => {
|
|
601
|
+
e.readFile(t, (n, s) => {
|
|
602
602
|
if (n)
|
|
603
603
|
return i(new Error(`ssh.readFile: ${n}`));
|
|
604
|
-
|
|
604
|
+
r(s.toString());
|
|
605
605
|
});
|
|
606
606
|
}));
|
|
607
607
|
}
|
|
608
|
-
async chmod(
|
|
609
|
-
return this.withSftp(async (
|
|
610
|
-
|
|
608
|
+
async chmod(t, e) {
|
|
609
|
+
return this.withSftp(async (r) => new Promise((i, n) => {
|
|
610
|
+
r.chmod(t, e, (s) => s ? n(new Error(`ssh.chmod: ${s}, path: ${t}, mode: ${e}`)) : i(void 0));
|
|
611
611
|
}));
|
|
612
612
|
}
|
|
613
|
-
async checkFileExists(
|
|
614
|
-
return this.withSftp(async (
|
|
615
|
-
|
|
613
|
+
async checkFileExists(t) {
|
|
614
|
+
return this.withSftp(async (e) => new Promise((r, i) => {
|
|
615
|
+
e.stat(t, (n, s) => {
|
|
616
616
|
if (n)
|
|
617
|
-
return (n == null ? void 0 : n.code) === 2 ?
|
|
618
|
-
|
|
617
|
+
return (n == null ? void 0 : n.code) === 2 ? r(!1) : i(new Error(`ssh.checkFileExists: err ${n}`));
|
|
618
|
+
r(s.isFile());
|
|
619
619
|
});
|
|
620
620
|
}));
|
|
621
621
|
}
|
|
622
|
-
async checkPathExists(
|
|
623
|
-
return this.withSftp(async (
|
|
624
|
-
|
|
622
|
+
async checkPathExists(t) {
|
|
623
|
+
return this.withSftp(async (e) => new Promise((r, i) => {
|
|
624
|
+
e.stat(t, (n, s) => {
|
|
625
625
|
if (n)
|
|
626
|
-
return n.code === 2 ?
|
|
627
|
-
|
|
626
|
+
return n.code === 2 ? r({ exists: !1, isFile: !1, isDirectory: !1 }) : i(new Error(`ssh.checkPathExists: ${n}`));
|
|
627
|
+
r({
|
|
628
628
|
exists: !0,
|
|
629
629
|
isFile: s.isFile(),
|
|
630
630
|
isDirectory: s.isDirectory()
|
|
@@ -632,18 +632,18 @@ class B {
|
|
|
632
632
|
});
|
|
633
633
|
}));
|
|
634
634
|
}
|
|
635
|
-
async writeFile(e, r,
|
|
635
|
+
async writeFile(t, e, r, i = 432) {
|
|
636
636
|
return new Promise((n, s) => {
|
|
637
|
-
|
|
637
|
+
t.writeFile(e, r, { mode: i }, (a) => {
|
|
638
638
|
if (a)
|
|
639
|
-
return s(new Error(`ssh.writeFile: err ${a}, remotePath: ${
|
|
639
|
+
return s(new Error(`ssh.writeFile: err ${a}, remotePath: ${e}`));
|
|
640
640
|
n(!0);
|
|
641
641
|
});
|
|
642
642
|
});
|
|
643
643
|
}
|
|
644
|
-
uploadFileUsingExistingSftp(e, r,
|
|
644
|
+
uploadFileUsingExistingSftp(t, e, r, i = 432) {
|
|
645
645
|
return new Promise((n, s) => {
|
|
646
|
-
rt(
|
|
646
|
+
rt(e).then(async (a) => this.writeFile(t, r, a, i).then(() => {
|
|
647
647
|
n(void 0);
|
|
648
648
|
}).catch((c) => {
|
|
649
649
|
const l = `uploadFileUsingExistingSftp: ${c}`;
|
|
@@ -651,21 +651,21 @@ class B {
|
|
|
651
651
|
}));
|
|
652
652
|
});
|
|
653
653
|
}
|
|
654
|
-
async __uploadDirectory(e, r,
|
|
654
|
+
async __uploadDirectory(t, e, r, i = 432) {
|
|
655
655
|
return new Promise((n, s) => {
|
|
656
|
-
O.readdir(
|
|
656
|
+
O.readdir(e, async (a, c) => {
|
|
657
657
|
if (a)
|
|
658
|
-
return s(new Error(`ssh.__uploadDir: err ${a}, localDir: ${
|
|
658
|
+
return s(new Error(`ssh.__uploadDir: err ${a}, localDir: ${e}, remoteDir: ${r}`));
|
|
659
659
|
try {
|
|
660
|
-
await this.__createRemoteDirectory(
|
|
660
|
+
await this.__createRemoteDirectory(t, r);
|
|
661
661
|
for (const l of c) {
|
|
662
|
-
const
|
|
663
|
-
O.lstatSync(
|
|
662
|
+
const d = h.join(e, l), u = `${r}/${l}`;
|
|
663
|
+
O.lstatSync(d).isDirectory() ? await this.__uploadDirectory(t, d, u, i) : await this.uploadFileUsingExistingSftp(t, d, u, i);
|
|
664
664
|
}
|
|
665
665
|
n();
|
|
666
666
|
} catch (l) {
|
|
667
|
-
const
|
|
668
|
-
this.logger.error(
|
|
667
|
+
const d = `ssh.__uploadDir: catched err ${l}`;
|
|
668
|
+
this.logger.error(d), s(new Error(d));
|
|
669
669
|
}
|
|
670
670
|
});
|
|
671
671
|
});
|
|
@@ -676,11 +676,11 @@ class B {
|
|
|
676
676
|
* @param remoteDir - The path to the remote directory on the server.
|
|
677
677
|
* @returns A promise that resolves when the directory and its contents are uploaded.
|
|
678
678
|
*/
|
|
679
|
-
async uploadDirectory(e, r
|
|
679
|
+
async uploadDirectory(t, e, r = 432) {
|
|
680
680
|
return new Promise((i, n) => {
|
|
681
681
|
this.withSftp(async (s) => {
|
|
682
682
|
try {
|
|
683
|
-
await this.__uploadDirectory(s, e, r
|
|
683
|
+
await this.__uploadDirectory(s, t, e, r), i();
|
|
684
684
|
} catch (a) {
|
|
685
685
|
n(new Error(`ssh.uploadDirectory: ${a}`));
|
|
686
686
|
}
|
|
@@ -693,17 +693,17 @@ class B {
|
|
|
693
693
|
* @param remotePath - The path to the remote directory.
|
|
694
694
|
* @returns A promise that resolves when the directory is created.
|
|
695
695
|
*/
|
|
696
|
-
__createRemoteDirectory(
|
|
697
|
-
return new Promise((
|
|
698
|
-
const n =
|
|
696
|
+
__createRemoteDirectory(t, e) {
|
|
697
|
+
return new Promise((r, i) => {
|
|
698
|
+
const n = e.split("/");
|
|
699
699
|
let s = "";
|
|
700
700
|
const a = (c) => {
|
|
701
701
|
if (c >= n.length)
|
|
702
|
-
return
|
|
703
|
-
s += `${n[c]}/`,
|
|
704
|
-
l ?
|
|
705
|
-
if (
|
|
706
|
-
return i(new Error(`ssh.__createRemDir: err ${
|
|
702
|
+
return r();
|
|
703
|
+
s += `${n[c]}/`, t.stat(s, (l) => {
|
|
704
|
+
l ? t.mkdir(s, (d) => {
|
|
705
|
+
if (d)
|
|
706
|
+
return i(new Error(`ssh.__createRemDir: err ${d}, remotePath: ${e}`));
|
|
707
707
|
a(c + 1);
|
|
708
708
|
}) : a(c + 1);
|
|
709
709
|
});
|
|
@@ -717,19 +717,19 @@ class B {
|
|
|
717
717
|
* @param remotePath - The path to the remote directory.
|
|
718
718
|
* @returns A promise that resolves when the directory is created.
|
|
719
719
|
*/
|
|
720
|
-
ensureRemoteDirCreated(
|
|
721
|
-
return this.withSftp(async (
|
|
722
|
-
const i =
|
|
720
|
+
ensureRemoteDirCreated(t, e = 493) {
|
|
721
|
+
return this.withSftp(async (r) => {
|
|
722
|
+
const i = t.split("/");
|
|
723
723
|
let n = "";
|
|
724
724
|
for (const s of i) {
|
|
725
725
|
n += `${s}/`;
|
|
726
726
|
try {
|
|
727
727
|
await new Promise((a, c) => {
|
|
728
|
-
|
|
728
|
+
r.stat(n, (l) => {
|
|
729
729
|
if (!l) return a();
|
|
730
|
-
|
|
731
|
-
if (
|
|
732
|
-
return c(new Error(`ssh.createRemoteDir: err ${
|
|
730
|
+
r.mkdir(n, { mode: e }, (d) => {
|
|
731
|
+
if (d)
|
|
732
|
+
return c(new Error(`ssh.createRemoteDir: err ${d}, remotePath: ${t}`));
|
|
733
733
|
a();
|
|
734
734
|
});
|
|
735
735
|
});
|
|
@@ -746,11 +746,11 @@ class B {
|
|
|
746
746
|
* @param localPath - The local file path to save the file.
|
|
747
747
|
* @returns A promise resolving with `true` if the file was successfully downloaded.
|
|
748
748
|
*/
|
|
749
|
-
async downloadFile(
|
|
750
|
-
return this.withSftp(async (
|
|
751
|
-
|
|
749
|
+
async downloadFile(t, e) {
|
|
750
|
+
return this.withSftp(async (r) => new Promise((i, n) => {
|
|
751
|
+
r.fastGet(t, e, (s) => {
|
|
752
752
|
if (s)
|
|
753
|
-
return n(new Error(`ssh.downloadFile: err ${s}, remotePath: ${
|
|
753
|
+
return n(new Error(`ssh.downloadFile: err ${s}, remotePath: ${t}, localPath: ${e}`));
|
|
754
754
|
i(!0);
|
|
755
755
|
});
|
|
756
756
|
}));
|
|
@@ -762,93 +762,123 @@ class B {
|
|
|
762
762
|
this.closeForwardedPorts(), this.client.end();
|
|
763
763
|
}
|
|
764
764
|
}
|
|
765
|
-
async function
|
|
765
|
+
async function It(o, t, e, r) {
|
|
766
766
|
return new Promise((i, n) => {
|
|
767
767
|
o.on("ready", () => {
|
|
768
768
|
i(o);
|
|
769
769
|
}), o.on("error", (s) => {
|
|
770
770
|
n(new Error(`ssh.connect: ${s}`));
|
|
771
771
|
}), o.on("close", () => {
|
|
772
|
-
}), o.connect(
|
|
772
|
+
}), o.connect(t), o.setNoDelay(!0);
|
|
773
773
|
});
|
|
774
774
|
}
|
|
775
|
-
async function _t(o, e, r,
|
|
775
|
+
async function _t(o, t, e, r, i, n) {
|
|
776
776
|
return new Promise((s, a) => {
|
|
777
|
-
|
|
777
|
+
t.forwardOut(e, r, i, n, (c, l) => c ? (o.error(`forwardOut.error: ${c}`), a(c)) : s(l));
|
|
778
778
|
});
|
|
779
779
|
}
|
|
780
|
-
const Tt = "minio-2024-12-18T13-15-44Z",
|
|
781
|
-
function
|
|
782
|
-
return
|
|
780
|
+
const Tt = "minio-2024-12-18T13-15-44Z", Mt = "supervisord-0.7.3", Ht = "supervisord_0.7.3_Linux_64-bit";
|
|
781
|
+
function g(o) {
|
|
782
|
+
return h.join(o, ".platforma_ssh");
|
|
783
783
|
}
|
|
784
|
-
function
|
|
785
|
-
return
|
|
784
|
+
function P(o) {
|
|
785
|
+
return h.join(g(o), "binaries");
|
|
786
786
|
}
|
|
787
|
-
function
|
|
788
|
-
return
|
|
787
|
+
function jt(o, t) {
|
|
788
|
+
return h.join(P(o), `pl-${N()}-${C(t)}`);
|
|
789
789
|
}
|
|
790
|
-
function
|
|
791
|
-
return
|
|
790
|
+
function W(o, t) {
|
|
791
|
+
return h.join(jt(o, t), "binaries");
|
|
792
792
|
}
|
|
793
|
-
function _(o,
|
|
794
|
-
return
|
|
793
|
+
function _(o, t) {
|
|
794
|
+
return h.join(W(o, t), "platforma");
|
|
795
795
|
}
|
|
796
|
-
function Gt(o,
|
|
797
|
-
return
|
|
796
|
+
function Gt(o, t) {
|
|
797
|
+
return h.join(W(o, t), "free-port");
|
|
798
798
|
}
|
|
799
|
-
function q(o,
|
|
800
|
-
return
|
|
799
|
+
function q(o, t) {
|
|
800
|
+
return h.join(P(o), `minio-2024-12-18T13-15-44Z-${C(t)}`);
|
|
801
801
|
}
|
|
802
|
-
function
|
|
803
|
-
return
|
|
802
|
+
function Jt(o, t) {
|
|
803
|
+
return h.join(q(o, t), "minio");
|
|
804
804
|
}
|
|
805
|
-
function
|
|
806
|
-
return
|
|
805
|
+
function Lt(o, t) {
|
|
806
|
+
return h.join(P(o), `supervisord-0.7.3-${C(t)}`, Ht);
|
|
807
807
|
}
|
|
808
|
-
function
|
|
809
|
-
return
|
|
808
|
+
function K(o, t) {
|
|
809
|
+
return h.join(Lt(o, t), "supervisord");
|
|
810
810
|
}
|
|
811
|
-
function
|
|
812
|
-
return
|
|
811
|
+
function Z(o) {
|
|
812
|
+
return h.join(g(o), "supervisor.conf");
|
|
813
813
|
}
|
|
814
814
|
function T(o) {
|
|
815
|
-
return
|
|
815
|
+
return h.join(g(o), "connection.txt");
|
|
816
|
+
}
|
|
817
|
+
async function zt(o, t, e) {
|
|
818
|
+
const r = await I(o, t, e, "--daemon");
|
|
819
|
+
if (r.stderr)
|
|
820
|
+
throw new Error(`Can not run ssh Platforma ${r.stderr}`);
|
|
816
821
|
}
|
|
817
|
-
async function
|
|
818
|
-
const
|
|
819
|
-
if (
|
|
820
|
-
throw new Error(`Can not
|
|
822
|
+
async function Vt(o, t, e) {
|
|
823
|
+
const r = await I(o, t, e, "ctl shutdown");
|
|
824
|
+
if (r.stderr)
|
|
825
|
+
throw new Error(`Can not stop ssh Platforma ${r.stderr}`);
|
|
821
826
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
if (t.stderr)
|
|
825
|
-
throw new Error(`Can not stop ssh Platforma ${t.stderr}`);
|
|
827
|
+
function E(o, t) {
|
|
828
|
+
return t ? o.platforma && o.minio : o.platforma;
|
|
826
829
|
}
|
|
827
|
-
|
|
830
|
+
function Wt(o) {
|
|
831
|
+
return o.execError === void 0;
|
|
832
|
+
}
|
|
833
|
+
async function qt(o, t, e, r) {
|
|
828
834
|
let i;
|
|
829
835
|
try {
|
|
830
|
-
i = await
|
|
836
|
+
i = await I(t, e, r, "ctl status");
|
|
831
837
|
} catch (c) {
|
|
832
|
-
return { execError: String(c)
|
|
838
|
+
return { execError: String(c) };
|
|
833
839
|
}
|
|
834
840
|
if (i.stderr)
|
|
835
|
-
return o.info(`supervisord ctl status: stderr occurred: ${i.stderr}, stdout: ${i.stdout}`), { rawResult: i
|
|
836
|
-
const n =
|
|
841
|
+
return o.info(`supervisord ctl status: stderr occurred: ${i.stderr}, stdout: ${i.stdout}`), { rawResult: i };
|
|
842
|
+
const n = M(i.stdout, "platforma"), s = M(i.stdout, "minio"), a = {
|
|
837
843
|
rawResult: i,
|
|
838
844
|
platforma: n,
|
|
839
|
-
minio: s
|
|
840
|
-
allAlive: n && s
|
|
845
|
+
minio: s
|
|
841
846
|
};
|
|
842
|
-
return a.
|
|
847
|
+
return a.minio || o.warn("Minio is not running on the server"), a.platforma || o.warn("Platforma is not running on the server"), a;
|
|
843
848
|
}
|
|
844
|
-
function
|
|
845
|
-
const
|
|
849
|
+
function Kt(o, t, e, r) {
|
|
850
|
+
const i = F(16).toString("hex"), n = o;
|
|
846
851
|
return `
|
|
847
852
|
[supervisord]
|
|
848
853
|
logfile=${t}/supervisord.log
|
|
849
854
|
loglevel=info
|
|
850
855
|
pidfile=${t}/supervisord.pid
|
|
851
856
|
|
|
857
|
+
[inet_http_server]
|
|
858
|
+
port=127.0.0.1:${n}
|
|
859
|
+
username=default-user
|
|
860
|
+
password=${i}
|
|
861
|
+
|
|
862
|
+
[supervisorctl]
|
|
863
|
+
serverurl=http://127.0.0.1:${n}
|
|
864
|
+
username=default-user
|
|
865
|
+
password=${i}
|
|
866
|
+
|
|
867
|
+
[program:platforma]
|
|
868
|
+
autostart=true
|
|
869
|
+
command=${r} --config ${e}
|
|
870
|
+
directory=${t}
|
|
871
|
+
autorestart=true
|
|
872
|
+
`;
|
|
873
|
+
}
|
|
874
|
+
function Zt(o, t, e, r, i, n, s) {
|
|
875
|
+
const a = Object.entries(t).map(([d, u]) => `${d}="${u}"`).join(","), c = F(16).toString("hex"), l = e;
|
|
876
|
+
return `
|
|
877
|
+
[supervisord]
|
|
878
|
+
logfile=${r}/supervisord.log
|
|
879
|
+
loglevel=info
|
|
880
|
+
pidfile=${r}/supervisord.pid
|
|
881
|
+
|
|
852
882
|
[inet_http_server]
|
|
853
883
|
port=127.0.0.1:${l}
|
|
854
884
|
username=default-user
|
|
@@ -863,67 +893,73 @@ password=${c}
|
|
|
863
893
|
autostart=true
|
|
864
894
|
depends_on=minio
|
|
865
895
|
command=${s} --config ${i}
|
|
866
|
-
directory=${
|
|
896
|
+
directory=${r}
|
|
867
897
|
autorestart=true
|
|
868
898
|
|
|
869
899
|
[program:minio]
|
|
870
900
|
autostart=true
|
|
871
901
|
environment=${a}
|
|
872
902
|
command=${n} server ${o}
|
|
873
|
-
directory=${
|
|
903
|
+
directory=${r}
|
|
874
904
|
autorestart=true
|
|
875
905
|
`;
|
|
876
906
|
}
|
|
877
|
-
async function
|
|
878
|
-
const i =
|
|
907
|
+
async function I(o, t, e, r) {
|
|
908
|
+
const i = K(t, e), n = Z(t), s = `${i} --configuration ${n} ${r}`;
|
|
879
909
|
return await o.exec(s);
|
|
880
910
|
}
|
|
881
|
-
function
|
|
911
|
+
function M(o, t) {
|
|
882
912
|
return ((i) => i.replace(/\x1B\[[0-9;]*m/g, ""))(o).split(`
|
|
883
913
|
`).some((i) => {
|
|
884
914
|
const [n, s] = i.trim().split(/\s{2,}/);
|
|
885
|
-
return n ===
|
|
915
|
+
return n === t && s === "Running";
|
|
886
916
|
});
|
|
887
917
|
}
|
|
888
|
-
const S =
|
|
889
|
-
local:
|
|
890
|
-
remote:
|
|
891
|
-
}),
|
|
918
|
+
const S = w.object({
|
|
919
|
+
local: w.number(),
|
|
920
|
+
remote: w.number()
|
|
921
|
+
}), Xt = w.object({
|
|
892
922
|
grpc: S,
|
|
923
|
+
http: S.optional(),
|
|
893
924
|
monitoring: S,
|
|
894
925
|
debug: S,
|
|
926
|
+
/** @deprecated */
|
|
895
927
|
minioPort: S,
|
|
928
|
+
/** @deprecated */
|
|
896
929
|
minioConsolePort: S
|
|
897
|
-
}),
|
|
898
|
-
plUser:
|
|
899
|
-
plPassword:
|
|
900
|
-
ports:
|
|
930
|
+
}), Yt = w.object({
|
|
931
|
+
plUser: w.string(),
|
|
932
|
+
plPassword: w.string(),
|
|
933
|
+
ports: Xt,
|
|
901
934
|
// It's false by default because it was added later,
|
|
902
935
|
// and in some deployments there won't be useGlobalAccess flag in the file.
|
|
903
|
-
useGlobalAccess:
|
|
936
|
+
useGlobalAccess: w.boolean().default(!1),
|
|
904
937
|
// We added the field afterwards, the pl backend was this version.
|
|
905
|
-
plVersion:
|
|
938
|
+
plVersion: w.string().default("1.18.3"),
|
|
939
|
+
// It's true by default because it was added later and previous installation use minio.
|
|
940
|
+
minioIsUsed: w.boolean().default(!0)
|
|
906
941
|
});
|
|
907
|
-
function
|
|
942
|
+
function Qt(o, t, e, r, i, n) {
|
|
908
943
|
return {
|
|
909
944
|
plUser: o,
|
|
910
|
-
plPassword:
|
|
911
|
-
ports:
|
|
912
|
-
useGlobalAccess:
|
|
913
|
-
plVersion: i
|
|
945
|
+
plPassword: t,
|
|
946
|
+
ports: e,
|
|
947
|
+
useGlobalAccess: r,
|
|
948
|
+
plVersion: i,
|
|
949
|
+
minioIsUsed: n
|
|
914
950
|
};
|
|
915
951
|
}
|
|
916
|
-
function
|
|
917
|
-
return
|
|
952
|
+
function te(o) {
|
|
953
|
+
return Yt.parse(JSON.parse(o));
|
|
918
954
|
}
|
|
919
|
-
function
|
|
955
|
+
function ee(o) {
|
|
920
956
|
return JSON.stringify(o, void 0, 2);
|
|
921
957
|
}
|
|
922
|
-
const
|
|
923
|
-
class
|
|
924
|
-
constructor(e, r
|
|
925
|
-
|
|
926
|
-
this.logger =
|
|
958
|
+
const H = 2.28;
|
|
959
|
+
class X {
|
|
960
|
+
constructor(t, e, r) {
|
|
961
|
+
p(this, "initState", { step: "init" });
|
|
962
|
+
this.logger = t, this.sshClient = e, this.username = r;
|
|
927
963
|
}
|
|
928
964
|
info() {
|
|
929
965
|
return {
|
|
@@ -931,12 +967,12 @@ class Z {
|
|
|
931
967
|
initState: this.initState
|
|
932
968
|
};
|
|
933
969
|
}
|
|
934
|
-
static async init(
|
|
970
|
+
static async init(t, e) {
|
|
935
971
|
try {
|
|
936
|
-
const
|
|
937
|
-
return new
|
|
938
|
-
} catch (
|
|
939
|
-
throw
|
|
972
|
+
const r = await B.init(t, e);
|
|
973
|
+
return new X(t, r, m(e.username));
|
|
974
|
+
} catch (r) {
|
|
975
|
+
throw t.error(`Connection error in SshClient.init: ${r}`), r;
|
|
940
976
|
}
|
|
941
977
|
}
|
|
942
978
|
cleanUp() {
|
|
@@ -944,30 +980,34 @@ class Z {
|
|
|
944
980
|
}
|
|
945
981
|
/** Provides an info if the platforma and minio are running along with the debug info. */
|
|
946
982
|
async isAlive() {
|
|
947
|
-
const
|
|
948
|
-
return await
|
|
983
|
+
const t = await this.getArch(), e = await this.getUserHomeDirectory();
|
|
984
|
+
return await qt(this.logger, this.sshClient, e, t.arch);
|
|
949
985
|
}
|
|
950
986
|
/** Starts all the services on the server.
|
|
951
987
|
* Idempotent semantic: we could call it several times. */
|
|
952
|
-
async start() {
|
|
988
|
+
async start(t) {
|
|
953
989
|
const e = await this.getArch(), r = await this.getUserHomeDirectory();
|
|
954
990
|
try {
|
|
955
|
-
if (!(await this.isAlive())
|
|
956
|
-
return await
|
|
957
|
-
} catch (
|
|
958
|
-
const
|
|
959
|
-
throw this.logger.error(
|
|
991
|
+
if (!E(await this.isAlive(), t))
|
|
992
|
+
return await zt(this.sshClient, r, e.arch), await this.checkIsAliveWithInterval(t);
|
|
993
|
+
} catch (i) {
|
|
994
|
+
const n = `SshPl.start: ${i}`;
|
|
995
|
+
throw this.logger.error(n), new Error(n);
|
|
960
996
|
}
|
|
961
997
|
}
|
|
962
998
|
/** Stops all the services on the server.
|
|
963
999
|
* Idempotent semantic: we could call it several times. */
|
|
964
1000
|
async stop() {
|
|
965
|
-
const
|
|
1001
|
+
const t = await this.getArch(), e = await this.getUserHomeDirectory();
|
|
966
1002
|
try {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1003
|
+
const r = await this.isAlive();
|
|
1004
|
+
if (Wt(r)) {
|
|
1005
|
+
await Vt(this.sshClient, e, t.arch);
|
|
1006
|
+
const i = r.minio === !0;
|
|
1007
|
+
return await this.checkIsAliveWithInterval(i, 1e3, 15, !1);
|
|
1008
|
+
}
|
|
1009
|
+
} catch (r) {
|
|
1010
|
+
const i = `PlSsh.stop: ${r}`;
|
|
971
1011
|
throw this.logger.error(i), new Error(i);
|
|
972
1012
|
}
|
|
973
1013
|
}
|
|
@@ -977,125 +1017,179 @@ class Z {
|
|
|
977
1017
|
}
|
|
978
1018
|
/** Stops platforma and deletes its state. */
|
|
979
1019
|
async stopAndClean() {
|
|
980
|
-
const
|
|
981
|
-
this.logger.info("pl.reset: Stop Platforma on the server"), await this.stop(), this.logger.info(`pl.reset: Deleting Platforma workDir ${
|
|
1020
|
+
const t = await this.getUserHomeDirectory();
|
|
1021
|
+
this.logger.info("pl.reset: Stop Platforma on the server"), await this.stop(), this.logger.info(`pl.reset: Deleting Platforma workDir ${g(t)} on the server`), await this.sshClient.deleteFolder(g(t));
|
|
982
1022
|
}
|
|
983
1023
|
/** Downloads binaries and untar them on the server,
|
|
984
1024
|
* generates all the configs, creates necessary dirs,
|
|
985
1025
|
* and finally starts all the services. */
|
|
986
|
-
async platformaInit(
|
|
987
|
-
const
|
|
1026
|
+
async platformaInit(t) {
|
|
1027
|
+
const e = { localWorkdir: t.localWorkdir, step: "init" }, { onProgress: r } = t, i = {
|
|
1028
|
+
...re,
|
|
1029
|
+
...t
|
|
1030
|
+
};
|
|
1031
|
+
e.plBinaryOps = i.plBinary;
|
|
988
1032
|
try {
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
if (r.plBinaryOps = i.plBinary, await (t == null ? void 0 : t("Detecting server architecture...")), r.arch = await this.getArch(), await (t == null ? void 0 : t("Server architecture detected.")), await (t == null ? void 0 : t("Fetching user home directory...")), r.remoteHome = await this.getUserHomeDirectory(), await (t == null ? void 0 : t("User home directory retrieved.")), await (t == null ? void 0 : t("Checking platform status...")), r.alive = await this.isAlive(), r.alive.allAlive && await (t == null ? void 0 : t("All required services are running.")), r.alive.allAlive) {
|
|
994
|
-
if (r.userCredentials = await this.getUserCredentials(r.remoteHome), !r.userCredentials)
|
|
995
|
-
throw new Error("SshPl.platformaInit: platforma is alive but userCredentials are not found");
|
|
996
|
-
const h = r.userCredentials.useGlobalAccess == i.useGlobalAccess, d = r.userCredentials.plVersion == i.plBinary.version;
|
|
997
|
-
if (r.needRestart = !(h && d), this.logger.info(`SshPl.platformaInit: need restart? ${r.needRestart}`), !r.needRestart)
|
|
998
|
-
return await (t == null ? void 0 : t("Server setup completed.")), r.userCredentials;
|
|
999
|
-
await (t == null ? void 0 : t("Stopping services...")), await this.stop();
|
|
1000
|
-
}
|
|
1001
|
-
await (t == null ? void 0 : t("Downloading and uploading required binaries..."));
|
|
1002
|
-
const n = await tr(this.logger, this.sshClient);
|
|
1003
|
-
if (n < j)
|
|
1004
|
-
throw new Error(`glibc version ${n} is too old. Version ${j} or higher is required for Platforma.`);
|
|
1005
|
-
const s = await this.downloadBinariesAndUploadToTheServer(
|
|
1006
|
-
i.localWorkdir,
|
|
1007
|
-
i.plBinary,
|
|
1008
|
-
r.remoteHome,
|
|
1009
|
-
r.arch
|
|
1010
|
-
);
|
|
1011
|
-
if (await (t == null ? void 0 : t("All required binaries have been downloaded and uploaded.")), r.binPaths = { ...s, history: void 0 }, r.downloadedBinaries = s.history, r.ports = await this.fetchPorts(r.remoteHome, r.arch), !r.ports.debug.remote || !r.ports.grpc.remote || !r.ports.minioPort.remote || !r.ports.minioConsolePort.remote || !r.ports.monitoring.remote)
|
|
1012
|
-
throw new Error("SshPl.platformaInit: remote ports are not defined");
|
|
1013
|
-
await (t == null ? void 0 : t("Generating server configuration..."));
|
|
1014
|
-
const a = await dt({
|
|
1015
|
-
logger: this.logger,
|
|
1016
|
-
workingDir: y(r.remoteHome),
|
|
1017
|
-
portsMode: {
|
|
1018
|
-
type: "customWithMinio",
|
|
1019
|
-
ports: {
|
|
1020
|
-
debug: r.ports.debug.remote,
|
|
1021
|
-
grpc: r.ports.grpc.remote,
|
|
1022
|
-
minio: r.ports.minioPort.remote,
|
|
1023
|
-
minioConsole: r.ports.minioConsolePort.remote,
|
|
1024
|
-
monitoring: r.ports.monitoring.remote,
|
|
1025
|
-
grpcLocal: r.ports.grpc.local,
|
|
1026
|
-
minioLocal: r.ports.minioPort.local
|
|
1027
|
-
}
|
|
1028
|
-
},
|
|
1029
|
-
licenseMode: i.license,
|
|
1030
|
-
useGlobalAccess: p(i.useGlobalAccess),
|
|
1031
|
-
plConfigPostprocessing: i.plConfigPostprocessing
|
|
1032
|
-
});
|
|
1033
|
-
r.generatedConfig = { ...a, filesToCreate: { skipped: "it is too wordy" } }, await (t == null ? void 0 : t("Server configuration generated.")), await (t == null ? void 0 : t("Generating folder structure..."));
|
|
1034
|
-
for (const [h, d] of Object.entries(a.filesToCreate))
|
|
1035
|
-
await this.sshClient.writeFileOnTheServer(h, d), this.logger.info(`Created file ${h}`);
|
|
1036
|
-
for (const h of a.dirsToCreate)
|
|
1037
|
-
await this.sshClient.ensureRemoteDirCreated(h), this.logger.info(`Created directory ${h}`);
|
|
1038
|
-
await (t == null ? void 0 : t("Folder structure created.")), await (t == null ? void 0 : t("Writing supervisord configuration..."));
|
|
1039
|
-
const c = qt(
|
|
1040
|
-
a.minioConfig.storageDir,
|
|
1041
|
-
a.minioConfig.envs,
|
|
1042
|
-
await this.getFreePortForPlatformaOnServer(r.remoteHome, r.arch),
|
|
1043
|
-
a.workingDir,
|
|
1044
|
-
a.plConfig.configPath,
|
|
1045
|
-
r.binPaths.minioRelPath,
|
|
1046
|
-
r.binPaths.downloadedPl
|
|
1047
|
-
);
|
|
1048
|
-
if (!await this.sshClient.writeFileOnTheServer(K(r.remoteHome), c))
|
|
1049
|
-
throw new Error(`Can not write supervisord config on the server ${y(r.remoteHome)}`);
|
|
1050
|
-
return await (t == null ? void 0 : t("Supervisord configuration written.")), await (t == null ? void 0 : t("Saving connection information...")), r.connectionInfo = Zt(
|
|
1051
|
-
a.plUser,
|
|
1052
|
-
a.plPassword,
|
|
1053
|
-
r.ports,
|
|
1054
|
-
p(i.useGlobalAccess),
|
|
1055
|
-
i.plBinary.version
|
|
1056
|
-
), await this.sshClient.writeFileOnTheServer(
|
|
1057
|
-
T(r.remoteHome),
|
|
1058
|
-
Yt(r.connectionInfo)
|
|
1059
|
-
), await (t == null ? void 0 : t("Connection information saved.")), await (t == null ? void 0 : t("Starting Platforma on the server...")), await this.start(), r.started = !0, this.initState = r, await (t == null ? void 0 : t("Platforma has been started successfully.")), r.connectionInfo;
|
|
1060
|
-
} catch (i) {
|
|
1061
|
-
const n = `SshPl.platformaInit: ${i}, state: ${JSON.stringify(r)}`;
|
|
1062
|
-
throw this.logger.error(n), new Error(n);
|
|
1033
|
+
return await this.doStepDetectArch(e, r), await this.doStepDetectHome(e, r), await this.doStepReadExistedConfig(e, i, r) ? (await this.doStepStopExistedPlatforma(e, r), await (r == null ? void 0 : r("Installation platforma...")), await this.doStepDownloadBinaries(e, r, i), await this.doStepFetchPorts(e), await this.doStepGenerateNewConfig(e, r, i), await this.doStepCreateFoldersAndSaveFiles(e, r), await this.doStepConfigureSupervisord(e, r), await this.doStepSaveNewConnectionInfo(e, r, i), await this.doStepStartPlatforma(e, r), e.connectionInfo) : (await (r == null ? void 0 : r("Platforma is already running. Skipping initialization.")), e.existedSettings);
|
|
1034
|
+
} catch (n) {
|
|
1035
|
+
const s = `SshPl.platformaInit: ${n}, state: ${JSON.stringify(this.removeSensitiveData(e))}`;
|
|
1036
|
+
throw this.logger.error(s), new Error(s);
|
|
1063
1037
|
}
|
|
1064
1038
|
}
|
|
1065
|
-
async
|
|
1066
|
-
|
|
1039
|
+
async doStepStopExistedPlatforma(t, e) {
|
|
1040
|
+
t.step = "stopExistedPlatforma", E(t.alive, t.shouldUseMinio ?? !1) && (await (e == null ? void 0 : e("Stopping services...")), await this.stop());
|
|
1041
|
+
}
|
|
1042
|
+
removeSensitiveData(t) {
|
|
1043
|
+
const e = { ...t };
|
|
1044
|
+
return e.generatedConfig = { ...e.generatedConfig, filesToCreate: { skipped: "sanitized" } }, e;
|
|
1045
|
+
}
|
|
1046
|
+
async doStepStartPlatforma(t, e) {
|
|
1047
|
+
t.step = "startPlatforma", await (e == null ? void 0 : e("Starting Platforma on the server...")), await this.start(t.shouldUseMinio ?? !1), t.started = !0, this.initState = t, await (e == null ? void 0 : e("Platforma has been started successfully."));
|
|
1048
|
+
}
|
|
1049
|
+
async doStepSaveNewConnectionInfo(t, e, r) {
|
|
1050
|
+
t.step = "saveNewConnectionInfo";
|
|
1051
|
+
const i = t.generatedConfig;
|
|
1052
|
+
await (e == null ? void 0 : e("Saving connection information...")), t.connectionInfo = Qt(
|
|
1053
|
+
i.plUser,
|
|
1054
|
+
i.plPassword,
|
|
1055
|
+
t.ports,
|
|
1056
|
+
m(r.useGlobalAccess),
|
|
1057
|
+
r.plBinary.version,
|
|
1058
|
+
t.shouldUseMinio ?? !1
|
|
1059
|
+
), await this.sshClient.writeFileOnTheServer(
|
|
1060
|
+
T(t.remoteHome),
|
|
1061
|
+
ee(t.connectionInfo)
|
|
1062
|
+
), await (e == null ? void 0 : e("Connection information saved."));
|
|
1063
|
+
}
|
|
1064
|
+
async doStepConfigureSupervisord(t, e) {
|
|
1065
|
+
await (e == null ? void 0 : e("Writing supervisord configuration...")), t.step = "configureSupervisord";
|
|
1066
|
+
const r = t.generatedConfig;
|
|
1067
|
+
let i;
|
|
1068
|
+
if (t.shouldUseMinio ? i = Zt(
|
|
1069
|
+
r.minioConfig.storageDir,
|
|
1070
|
+
r.minioConfig.envs,
|
|
1071
|
+
await this.getFreePortForPlatformaOnServer(t.remoteHome, t.arch),
|
|
1072
|
+
r.workingDir,
|
|
1073
|
+
r.plConfig.configPath,
|
|
1074
|
+
t.binPaths.minioRelPath,
|
|
1075
|
+
t.binPaths.downloadedPl
|
|
1076
|
+
) : i = Kt(
|
|
1077
|
+
await this.getFreePortForPlatformaOnServer(t.remoteHome, t.arch),
|
|
1078
|
+
r.workingDir,
|
|
1079
|
+
r.plConfig.configPath,
|
|
1080
|
+
t.binPaths.downloadedPl
|
|
1081
|
+
), !await this.sshClient.writeFileOnTheServer(Z(t.remoteHome), i))
|
|
1082
|
+
throw new Error(`Can not write supervisord config on the server ${g(t.remoteHome)}`);
|
|
1083
|
+
await (e == null ? void 0 : e("Supervisord configuration written."));
|
|
1084
|
+
}
|
|
1085
|
+
async doStepCreateFoldersAndSaveFiles(t, e) {
|
|
1086
|
+
t.step = "createFoldersAndSaveFiles";
|
|
1087
|
+
const r = t.generatedConfig;
|
|
1088
|
+
await (e == null ? void 0 : e("Generating folder structure..."));
|
|
1089
|
+
for (const [i, n] of Object.entries(r.filesToCreate))
|
|
1090
|
+
await this.sshClient.writeFileOnTheServer(i, n), this.logger.info(`Created file ${i}`);
|
|
1091
|
+
for (const i of r.dirsToCreate)
|
|
1092
|
+
await this.sshClient.ensureRemoteDirCreated(i), this.logger.info(`Created directory ${i}`);
|
|
1093
|
+
await (e == null ? void 0 : e("Folder structure created."));
|
|
1094
|
+
}
|
|
1095
|
+
async doStepGenerateNewConfig(t, e, r) {
|
|
1096
|
+
t.step = "generateNewConfig", await (e == null ? void 0 : e("Generating new config..."));
|
|
1097
|
+
const i = await ut({
|
|
1098
|
+
logger: this.logger,
|
|
1099
|
+
workingDir: g(t.remoteHome),
|
|
1100
|
+
portsMode: {
|
|
1101
|
+
type: "customWithMinio",
|
|
1102
|
+
ports: {
|
|
1103
|
+
debug: t.ports.debug.remote,
|
|
1104
|
+
grpc: t.ports.grpc.remote,
|
|
1105
|
+
http: t.ports.http.remote,
|
|
1106
|
+
minio: t.ports.minioPort.remote,
|
|
1107
|
+
minioConsole: t.ports.minioConsolePort.remote,
|
|
1108
|
+
monitoring: t.ports.monitoring.remote,
|
|
1109
|
+
httpLocal: t.ports.http.local,
|
|
1110
|
+
grpcLocal: t.ports.grpc.local,
|
|
1111
|
+
minioLocal: t.ports.minioPort.local
|
|
1112
|
+
}
|
|
1113
|
+
},
|
|
1114
|
+
licenseMode: r.license,
|
|
1115
|
+
useGlobalAccess: m(r.useGlobalAccess),
|
|
1116
|
+
plConfigPostprocessing: r.plConfigPostprocessing,
|
|
1117
|
+
useMinio: t.shouldUseMinio ?? !1
|
|
1118
|
+
});
|
|
1119
|
+
t.generatedConfig = { ...i }, await (e == null ? void 0 : e("New config generated"));
|
|
1120
|
+
}
|
|
1121
|
+
async doStepFetchPorts(t) {
|
|
1122
|
+
var e;
|
|
1123
|
+
if (t.step = "fetchPorts", 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 || !((e = t.ports.http) != null && e.remote))
|
|
1124
|
+
throw new Error("SshPl.platformaInit: remote ports are not defined");
|
|
1125
|
+
}
|
|
1126
|
+
async doStepDownloadBinaries(t, e, r) {
|
|
1127
|
+
t.step = "downloadBinaries", await (e == null ? void 0 : e("Downloading and uploading required binaries..."));
|
|
1128
|
+
const i = await ie(this.logger, this.sshClient);
|
|
1129
|
+
if (i < H)
|
|
1130
|
+
throw new Error(`glibc version ${i} is too old. Version ${H} or higher is required for Platforma.`);
|
|
1131
|
+
const n = await this.downloadBinariesAndUploadToTheServer(
|
|
1132
|
+
r.localWorkdir,
|
|
1133
|
+
r.plBinary,
|
|
1134
|
+
t.remoteHome,
|
|
1135
|
+
t.arch,
|
|
1136
|
+
t.shouldUseMinio ?? !1
|
|
1137
|
+
);
|
|
1138
|
+
await (e == null ? void 0 : e("All required binaries have been downloaded and uploaded.")), t.binPaths = { ...n, history: void 0 }, t.downloadedBinaries = n.history;
|
|
1139
|
+
}
|
|
1140
|
+
async doStepDetectArch(t, e) {
|
|
1141
|
+
t.step = "detectArch", await (e == null ? void 0 : e("Detecting server architecture...")), t.arch = await this.getArch(), await (e == null ? void 0 : e("Server architecture detected."));
|
|
1142
|
+
}
|
|
1143
|
+
async doStepDetectHome(t, e) {
|
|
1144
|
+
t.step = "detectHome", await (e == null ? void 0 : e("Fetching user home directory...")), t.remoteHome = await this.getUserHomeDirectory(), await (e == null ? void 0 : e("User home directory retrieved."));
|
|
1145
|
+
}
|
|
1146
|
+
async doStepReadExistedConfig(t, e, r) {
|
|
1147
|
+
var s;
|
|
1148
|
+
if (t.step = "checkAlive", await (r == null ? void 0 : r("Checking platform status...")), t.alive = await this.isAlive(), !((s = t.alive) != null && s.platforma))
|
|
1149
|
+
return !0;
|
|
1150
|
+
if (await (r == null ? void 0 : r("All required services are running.")), t.existedSettings = await this.readExistedConfig(t.remoteHome), !t.existedSettings)
|
|
1151
|
+
throw new Error("SshPl.platformaInit: platforma is alive but existed settings are not found");
|
|
1152
|
+
const i = t.existedSettings.useGlobalAccess == e.useGlobalAccess, n = t.existedSettings.plVersion == e.plBinary.version;
|
|
1153
|
+
return t.needRestart = !(i && n), this.logger.info(`SshPl.platformaInit: need restart? ${t.needRestart}`), t.shouldUseMinio = t.existedSettings.minioIsUsed, t.shouldUseMinio ? this.logger.info("SshPl.platformaInit: minio is used") : this.logger.info("SshPl.platformaInit: minio is not used"), t.needRestart ? (await (r == null ? void 0 : r("Stopping services...")), await this.stop(), !0) : (await (r == null ? void 0 : r("Server setup completed.")), !1);
|
|
1154
|
+
}
|
|
1155
|
+
async downloadBinariesAndUploadToTheServer(t, e, r, i, n) {
|
|
1156
|
+
const s = [];
|
|
1067
1157
|
try {
|
|
1068
|
-
const
|
|
1069
|
-
e,
|
|
1158
|
+
const a = await this.downloadAndUntar(
|
|
1070
1159
|
t,
|
|
1160
|
+
r,
|
|
1071
1161
|
i,
|
|
1072
1162
|
"pl",
|
|
1073
|
-
`pl-${
|
|
1163
|
+
`pl-${e.version}`
|
|
1074
1164
|
);
|
|
1075
|
-
|
|
1076
|
-
const
|
|
1077
|
-
e,
|
|
1165
|
+
s.push(a);
|
|
1166
|
+
const c = await this.downloadAndUntar(
|
|
1078
1167
|
t,
|
|
1168
|
+
r,
|
|
1079
1169
|
i,
|
|
1080
1170
|
"supervisord",
|
|
1081
|
-
|
|
1171
|
+
Mt
|
|
1082
1172
|
);
|
|
1083
|
-
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1173
|
+
s.push(c);
|
|
1174
|
+
const l = Jt(r, i.arch);
|
|
1175
|
+
if (n) {
|
|
1176
|
+
const d = await this.downloadAndUntar(
|
|
1177
|
+
t,
|
|
1178
|
+
r,
|
|
1179
|
+
i,
|
|
1180
|
+
"minio",
|
|
1181
|
+
Tt
|
|
1182
|
+
);
|
|
1183
|
+
s.push(d), await this.sshClient.chmod(l, 488);
|
|
1184
|
+
}
|
|
1185
|
+
return {
|
|
1186
|
+
history: s,
|
|
1187
|
+
minioRelPath: n ? l : void 0,
|
|
1188
|
+
downloadedPl: _(r, i.arch)
|
|
1095
1189
|
};
|
|
1096
|
-
} catch (
|
|
1097
|
-
const
|
|
1098
|
-
throw this.logger.error(
|
|
1190
|
+
} catch (a) {
|
|
1191
|
+
const c = `SshPl.downloadBinariesAndUploadToServer: ${a}, state: ${JSON.stringify(s)}`;
|
|
1192
|
+
throw this.logger.error(c), a;
|
|
1099
1193
|
}
|
|
1100
1194
|
}
|
|
1101
1195
|
/** We have to extract pl in the remote server,
|
|
@@ -1104,27 +1198,27 @@ class Z {
|
|
|
1104
1198
|
* For this reason, we extract all to the remote server.
|
|
1105
1199
|
* It requires `tar` to be installed on the server
|
|
1106
1200
|
* (it's not installed for Rocky Linux for example). */
|
|
1107
|
-
async downloadAndUntar(e, r,
|
|
1201
|
+
async downloadAndUntar(t, e, r, i, n) {
|
|
1108
1202
|
const s = {};
|
|
1109
|
-
s.binBasePath =
|
|
1203
|
+
s.binBasePath = P(e), await this.sshClient.ensureRemoteDirCreated(s.binBasePath), s.binBasePathCreated = !0;
|
|
1110
1204
|
let a = null;
|
|
1111
1205
|
const c = 5;
|
|
1112
|
-
for (let
|
|
1206
|
+
for (let d = 1; d <= c; d++)
|
|
1113
1207
|
try {
|
|
1114
1208
|
a = await gt(
|
|
1115
1209
|
this.logger,
|
|
1116
|
-
|
|
1210
|
+
t,
|
|
1117
1211
|
i,
|
|
1118
1212
|
n,
|
|
1119
|
-
|
|
1120
|
-
|
|
1213
|
+
r.arch,
|
|
1214
|
+
r.platform
|
|
1121
1215
|
);
|
|
1122
1216
|
break;
|
|
1123
|
-
} catch (
|
|
1124
|
-
if (await
|
|
1125
|
-
throw new Error(`downloadAndUntar: ${c} attempts, last error: ${
|
|
1217
|
+
} catch (u) {
|
|
1218
|
+
if (await x(300), d == c)
|
|
1219
|
+
throw new Error(`downloadAndUntar: ${c} attempts, last error: ${u}`);
|
|
1126
1220
|
}
|
|
1127
|
-
s.downloadResult =
|
|
1221
|
+
s.downloadResult = m(a), s.localArchivePath = h.resolve(s.downloadResult.archivePath), s.remoteDir = h.join(s.binBasePath, s.downloadResult.baseName), s.remoteArchivePath = s.remoteDir + ".tgz", await this.sshClient.ensureRemoteDirCreated(s.remoteDir), await this.sshClient.uploadFile(s.localArchivePath, s.remoteArchivePath), s.uploadDone = !0;
|
|
1128
1222
|
try {
|
|
1129
1223
|
await this.sshClient.exec("hash tar");
|
|
1130
1224
|
} catch {
|
|
@@ -1137,120 +1231,124 @@ class Z {
|
|
|
1137
1231
|
throw new Error(`downloadAndUntar: untar: stderr occurred: ${l.stderr}, stdout: ${l.stdout}`);
|
|
1138
1232
|
return s.untarDone = !0, s;
|
|
1139
1233
|
}
|
|
1140
|
-
async needDownload(
|
|
1141
|
-
const
|
|
1142
|
-
return !await this.sshClient.checkFileExists(n) || !await this.sshClient.checkFileExists(i) || !await this.sshClient.checkFileExists(
|
|
1143
|
-
}
|
|
1144
|
-
async checkIsAliveWithInterval(e = 1e3, r = 15,
|
|
1145
|
-
const
|
|
1146
|
-
let
|
|
1147
|
-
for (;
|
|
1148
|
-
if (await
|
|
1149
|
-
throw new Error(`isAliveWithInterval: The process did not ${
|
|
1150
|
-
|
|
1234
|
+
async needDownload(t, e) {
|
|
1235
|
+
const r = K(t, e.arch), i = q(t, e.arch), n = _(t, e.arch);
|
|
1236
|
+
return !await this.sshClient.checkFileExists(n) || !await this.sshClient.checkFileExists(i) || !await this.sshClient.checkFileExists(r);
|
|
1237
|
+
}
|
|
1238
|
+
async checkIsAliveWithInterval(t, e = 1e3, r = 15, i = !0) {
|
|
1239
|
+
const n = r * e;
|
|
1240
|
+
let s = 0, a = await this.isAlive();
|
|
1241
|
+
for (; i ? !E(a, t) : E(a, t); ) {
|
|
1242
|
+
if (await x(e), s += e, s > n)
|
|
1243
|
+
throw new Error(`isAliveWithInterval: The process did not ${i ? "started" : "stopped"} after ${n} ms. Live status: ${JSON.stringify(a)}`);
|
|
1244
|
+
a = await this.isAlive();
|
|
1151
1245
|
}
|
|
1152
1246
|
}
|
|
1153
|
-
async
|
|
1154
|
-
const
|
|
1155
|
-
return
|
|
1247
|
+
async readExistedConfig(t) {
|
|
1248
|
+
const e = await this.sshClient.readFile(T(t));
|
|
1249
|
+
return te(e);
|
|
1156
1250
|
}
|
|
1157
|
-
async fetchPorts(
|
|
1251
|
+
async fetchPorts(t, e) {
|
|
1158
1252
|
return {
|
|
1159
1253
|
grpc: {
|
|
1160
1254
|
local: await $(),
|
|
1161
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1255
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1162
1256
|
},
|
|
1163
1257
|
monitoring: {
|
|
1164
1258
|
local: await $(),
|
|
1165
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1259
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1166
1260
|
},
|
|
1167
1261
|
debug: {
|
|
1168
1262
|
local: await $(),
|
|
1169
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1263
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1264
|
+
},
|
|
1265
|
+
http: {
|
|
1266
|
+
local: await $(),
|
|
1267
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1170
1268
|
},
|
|
1171
1269
|
minioPort: {
|
|
1172
1270
|
local: await $(),
|
|
1173
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1271
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1174
1272
|
},
|
|
1175
1273
|
minioConsolePort: {
|
|
1176
1274
|
local: await $(),
|
|
1177
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1275
|
+
remote: await this.getFreePortForPlatformaOnServer(t, e)
|
|
1178
1276
|
}
|
|
1179
1277
|
};
|
|
1180
1278
|
}
|
|
1181
1279
|
async getLocalFreePort() {
|
|
1182
|
-
return new Promise((
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1280
|
+
return new Promise((t) => {
|
|
1281
|
+
const e = G.createServer();
|
|
1282
|
+
e.listen(0, () => {
|
|
1283
|
+
const r = e.address().port;
|
|
1284
|
+
e.close((i) => t(r));
|
|
1187
1285
|
});
|
|
1188
1286
|
});
|
|
1189
1287
|
}
|
|
1190
|
-
async getFreePortForPlatformaOnServer(
|
|
1191
|
-
const
|
|
1288
|
+
async getFreePortForPlatformaOnServer(t, e) {
|
|
1289
|
+
const r = Gt(t, e.arch), { stdout: i, stderr: n } = await this.sshClient.exec(`${r}`);
|
|
1192
1290
|
if (n)
|
|
1193
1291
|
throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${n}, stdout: ${i}`);
|
|
1194
1292
|
return +i;
|
|
1195
1293
|
}
|
|
1196
1294
|
async getArch() {
|
|
1197
|
-
const { stdout:
|
|
1198
|
-
if (
|
|
1199
|
-
throw new Error(`getArch: stderr is not empty: ${
|
|
1200
|
-
const
|
|
1295
|
+
const { stdout: t, stderr: e } = await this.sshClient.exec("uname -s && uname -m");
|
|
1296
|
+
if (e)
|
|
1297
|
+
throw new Error(`getArch: stderr is not empty: ${e}, stdout: ${t}`);
|
|
1298
|
+
const r = t.split(`
|
|
1201
1299
|
`);
|
|
1202
1300
|
return {
|
|
1203
|
-
platform:
|
|
1204
|
-
arch:
|
|
1301
|
+
platform: r[0],
|
|
1302
|
+
arch: r[1]
|
|
1205
1303
|
};
|
|
1206
1304
|
}
|
|
1207
1305
|
async getUserHomeDirectory() {
|
|
1208
|
-
const { stdout:
|
|
1209
|
-
if (
|
|
1210
|
-
const
|
|
1211
|
-
return console.warn(`getUserHomeDirectory: stderr is not empty: ${
|
|
1306
|
+
const { stdout: t, stderr: e } = await this.sshClient.exec("echo $HOME");
|
|
1307
|
+
if (e) {
|
|
1308
|
+
const r = `/home/${this.username}`;
|
|
1309
|
+
return console.warn(`getUserHomeDirectory: stderr is not empty: ${e}, stdout: ${t}, will get a default home: ${r}`), r;
|
|
1212
1310
|
}
|
|
1213
|
-
return
|
|
1311
|
+
return t.trim();
|
|
1214
1312
|
}
|
|
1215
1313
|
}
|
|
1216
|
-
const
|
|
1314
|
+
const re = {
|
|
1217
1315
|
useGlobalAccess: !1,
|
|
1218
1316
|
plBinary: {
|
|
1219
1317
|
type: "Download",
|
|
1220
|
-
version:
|
|
1318
|
+
version: N()
|
|
1221
1319
|
}
|
|
1222
1320
|
};
|
|
1223
|
-
async function
|
|
1321
|
+
async function ie(o, t) {
|
|
1224
1322
|
try {
|
|
1225
|
-
const { stdout:
|
|
1226
|
-
if (
|
|
1227
|
-
throw new Error(`Failed to check glibc version: ${
|
|
1228
|
-
return
|
|
1229
|
-
} catch (
|
|
1230
|
-
throw o.error(`glibc version check failed: ${
|
|
1323
|
+
const { stdout: e, stderr: r } = await t.exec("ldd --version | head -n 1");
|
|
1324
|
+
if (r)
|
|
1325
|
+
throw new Error(`Failed to check glibc version: ${r}`);
|
|
1326
|
+
return ne(e);
|
|
1327
|
+
} catch (e) {
|
|
1328
|
+
throw o.error(`glibc version check failed: ${e}`), e;
|
|
1231
1329
|
}
|
|
1232
1330
|
}
|
|
1233
|
-
function
|
|
1234
|
-
const
|
|
1235
|
-
if (!
|
|
1331
|
+
function ne(o) {
|
|
1332
|
+
const t = o.match(/\d+\.\d+/);
|
|
1333
|
+
if (!t)
|
|
1236
1334
|
throw new Error(`Could not parse glibc version from: ${o}`);
|
|
1237
|
-
return parseFloat(
|
|
1335
|
+
return parseFloat(t[0]);
|
|
1238
1336
|
}
|
|
1239
1337
|
export {
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1338
|
+
Yt as ConnectionInfo,
|
|
1339
|
+
Ot as LocalConfigYaml,
|
|
1340
|
+
kt as LocalPl,
|
|
1243
1341
|
S as PortPair,
|
|
1244
1342
|
B as SshClient,
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1343
|
+
X as SshPl,
|
|
1344
|
+
Xt as SshPlPorts,
|
|
1345
|
+
N as getDefaultPlVersion,
|
|
1346
|
+
Ce as localPlatformaInit,
|
|
1347
|
+
Nt as mergeDefaultOps,
|
|
1348
|
+
Qt as newConnectionInfo,
|
|
1349
|
+
te as parseConnectionInfo,
|
|
1350
|
+
ne as parseGlibcVersion,
|
|
1351
|
+
Ut as plProcessOps,
|
|
1352
|
+
ee as stringifyConnectionInfo
|
|
1255
1353
|
};
|
|
1256
1354
|
//# sourceMappingURL=index.mjs.map
|