@milaboratories/pl-deployments 1.1.5 → 1.1.6
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 +7 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +365 -348
- package/dist/index.mjs.map +1 -1
- package/dist/ssh/pl.d.ts +1 -0
- package/dist/ssh/pl.d.ts.map +1 -1
- package/dist/ssh/ssh.d.ts +4 -1
- package/dist/ssh/ssh.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/ssh/pl.ts +8 -2
- package/src/ssh/ssh.ts +23 -1
package/dist/index.mjs
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
var G = Object.defineProperty;
|
|
2
|
-
var Z = (s,
|
|
3
|
-
var w = (s,
|
|
2
|
+
var Z = (s, t, r) => t in s ? G(s, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : s[t] = r;
|
|
3
|
+
var w = (s, t, r) => Z(s, typeof t != "symbol" ? t + "" : t, r);
|
|
4
4
|
import { spawn as V } from "node:child_process";
|
|
5
|
-
import { sleep as C, fileExists as m, assertNever as T, notEmpty as
|
|
5
|
+
import { sleep as C, fileExists as m, assertNever as T, notEmpty as p, RetryablePromise as Y } from "@milaboratories/ts-helpers";
|
|
6
6
|
import E from "node:fs";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
7
|
+
import f, { readFile as Q } from "node:fs/promises";
|
|
8
|
+
import d from "upath";
|
|
9
9
|
import { request as X } from "undici";
|
|
10
|
-
import { Readable as
|
|
11
|
-
import { text as
|
|
12
|
-
import * as
|
|
13
|
-
import
|
|
10
|
+
import { Readable as rr, Writable as tr } from "node:stream";
|
|
11
|
+
import { text as er } from "node:stream/consumers";
|
|
12
|
+
import * as ir from "tar";
|
|
13
|
+
import or from "decompress";
|
|
14
14
|
import k from "node:os";
|
|
15
|
-
import
|
|
15
|
+
import sr, { Client as S } from "ssh2";
|
|
16
16
|
import B from "node:net";
|
|
17
|
-
import
|
|
17
|
+
import nr from "node:dns";
|
|
18
18
|
import { randomBytes as F } from "node:crypto";
|
|
19
|
-
import { generateSshPlConfigs as
|
|
20
|
-
function
|
|
19
|
+
import { generateSshPlConfigs as ar, getFreePort as y } from "@milaboratories/pl-config";
|
|
20
|
+
function cr(s, t) {
|
|
21
21
|
return s.info(`Running:
|
|
22
|
-
cmd: ${JSON.stringify([
|
|
23
|
-
wd: ${
|
|
22
|
+
cmd: ${JSON.stringify([t.cmd, ...t.args])}
|
|
23
|
+
wd: ${t.opts.cwd}`), s.info(" spawning child process"), V(t.cmd, t.args, t.opts);
|
|
24
24
|
}
|
|
25
25
|
async function D(s) {
|
|
26
26
|
try {
|
|
@@ -32,13 +32,13 @@ async function D(s) {
|
|
|
32
32
|
function _(s) {
|
|
33
33
|
return process.kill(s, "SIGINT");
|
|
34
34
|
}
|
|
35
|
-
async function j(s,
|
|
35
|
+
async function j(s, t) {
|
|
36
36
|
let e = 0;
|
|
37
37
|
for (; await D(s); )
|
|
38
|
-
if (await C(100), e += 100, e >
|
|
39
|
-
throw new Error(`The process did not stopped after ${
|
|
38
|
+
if (await C(100), e += 100, e > t)
|
|
39
|
+
throw new Error(`The process did not stopped after ${t} ms.`);
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const lr = ["linux", "macos", "windows"];
|
|
42
42
|
function I(s) {
|
|
43
43
|
switch (s.toLowerCase()) {
|
|
44
44
|
case "darwin":
|
|
@@ -49,11 +49,11 @@ function I(s) {
|
|
|
49
49
|
return "windows";
|
|
50
50
|
default:
|
|
51
51
|
throw new Error(
|
|
52
|
-
`operating system '${s}' is not currently supported by Platforma ecosystem. The list of OSes supported: ` + JSON.stringify(
|
|
52
|
+
`operating system '${s}' is not currently supported by Platforma ecosystem. The list of OSes supported: ` + JSON.stringify(lr)
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
const
|
|
56
|
+
const hr = ["amd64", "arm64"];
|
|
57
57
|
function P(s) {
|
|
58
58
|
switch (s) {
|
|
59
59
|
case "aarch64":
|
|
@@ -65,20 +65,20 @@ function P(s) {
|
|
|
65
65
|
return "amd64";
|
|
66
66
|
default:
|
|
67
67
|
throw new Error(
|
|
68
|
-
`processor architecture '${s}' is not currently supported by Platforma ecosystem. The list of architectures supported: ` + JSON.stringify(
|
|
68
|
+
`processor architecture '${s}' is not currently supported by Platforma ecosystem. The list of architectures supported: ` + JSON.stringify(hr)
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
async function
|
|
73
|
-
const n =
|
|
72
|
+
async function dr(s, t, r, e, i, o) {
|
|
73
|
+
const n = wr(r, e, t, P(i), I(o)), { archiveUrl: c, archivePath: a } = n;
|
|
74
74
|
return await H(s, c, a), n;
|
|
75
75
|
}
|
|
76
|
-
async function
|
|
77
|
-
const o =
|
|
78
|
-
return await H(s, n, c), await
|
|
76
|
+
async function ur(s, t, r, e, i) {
|
|
77
|
+
const o = fr(r, t, P(e), I(i)), { archiveUrl: n, archivePath: c, archiveType: a, targetFolder: l, binaryPath: h } = o;
|
|
78
|
+
return await H(s, n, c), await mr(s, c, a, l), o;
|
|
79
79
|
}
|
|
80
|
-
function
|
|
81
|
-
const o = `${
|
|
80
|
+
function wr(s, t, r, e, i) {
|
|
81
|
+
const o = `${t}-${e}`, n = M[i], c = `${o}.${n}`, a = `https://cdn.platforma.bio/software/${s}/${i}/${c}`, l = d.join(r, c), h = d.join(r, o);
|
|
82
82
|
return {
|
|
83
83
|
archiveUrl: a,
|
|
84
84
|
archivePath: l,
|
|
@@ -87,8 +87,8 @@ function wt(s, r, t, e, i) {
|
|
|
87
87
|
baseName: o
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
const i = `pl-${s}-${
|
|
90
|
+
function fr(s, t, r, e) {
|
|
91
|
+
const i = `pl-${s}-${r}`, o = M[e], n = `${i}.${o}`, c = `https://cdn.platforma.bio/software/pl/${e}/${n}`, a = d.join(t, n), l = d.join(t, i), h = d.join(i, "binaries", gr[e]);
|
|
92
92
|
return {
|
|
93
93
|
archiveUrl: c,
|
|
94
94
|
archivePath: a,
|
|
@@ -98,62 +98,62 @@ function pt(s, r, t, e) {
|
|
|
98
98
|
baseName: i
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
async function H(s,
|
|
101
|
+
async function H(s, t, r) {
|
|
102
102
|
const e = {};
|
|
103
|
-
e.dstArchive =
|
|
103
|
+
e.dstArchive = r;
|
|
104
104
|
try {
|
|
105
|
-
if (e.fileExisted = await m(
|
|
106
|
-
return s.info(`Platforma Backend archive download skipped: '${
|
|
107
|
-
await
|
|
108
|
-
URL: ${
|
|
109
|
-
Save to: ${
|
|
110
|
-
const { body: i, statusCode: o } = await X(
|
|
105
|
+
if (e.fileExisted = await m(r), e.fileExisted)
|
|
106
|
+
return s.info(`Platforma Backend archive download skipped: '${r}' already exists`), e;
|
|
107
|
+
await f.mkdir(d.dirname(r), { recursive: !0 }), e.dirnameCreated = !0, s.info(`Downloading archive:
|
|
108
|
+
URL: ${t}
|
|
109
|
+
Save to: ${r}`);
|
|
110
|
+
const { body: i, statusCode: o } = await X(t);
|
|
111
111
|
if (e.statusCode = o, o != 200) {
|
|
112
|
-
const n = await
|
|
112
|
+
const n = await er(i);
|
|
113
113
|
throw e.errorMsg = `failed to download archive: ${o}, response: ${n.slice(0, 1e3)}`, s.error(e.errorMsg), new Error(e.errorMsg);
|
|
114
114
|
}
|
|
115
|
-
return e.tmpPath =
|
|
115
|
+
return e.tmpPath = r + ".tmp", await rr.toWeb(i).pipeTo(tr.toWeb(E.createWriteStream(e.tmpPath))), e.wroteTmp = !0, e.tmpExisted = await m(e.tmpPath), await f.rename(e.tmpPath, r), e.renamed = !0, e.newExisted = await m(r), e;
|
|
116
116
|
} catch (i) {
|
|
117
117
|
const o = `downloadArchive: error ${JSON.stringify(i)} occurred, state: ${JSON.stringify(e)}`;
|
|
118
118
|
throw s.error(o), new Error(o);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
const
|
|
122
|
-
async function
|
|
123
|
-
if (s.info("extracting archive..."), s.info(` archive path: '${
|
|
124
|
-
const o = `Platforma Backend binary archive not found at '${
|
|
121
|
+
const pr = ".ok";
|
|
122
|
+
async function mr(s, t, r, e) {
|
|
123
|
+
if (s.info("extracting archive..."), s.info(` archive path: '${t}'`), s.info(` target dir: '${e}'`), !await m(t)) {
|
|
124
|
+
const o = `Platforma Backend binary archive not found at '${t}'`;
|
|
125
125
|
throw s.error(o), new Error(o);
|
|
126
126
|
}
|
|
127
|
-
const i =
|
|
127
|
+
const i = d.join(e, pr);
|
|
128
128
|
if (await m(i)) {
|
|
129
129
|
s.info(`Platforma Backend binaries unpack skipped: '${e}' exists`);
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
-
switch (await m(e) && (s.info(`Removing previous incompletely unpacked folder: '${e}'`), await
|
|
132
|
+
switch (await m(e) && (s.info(`Removing previous incompletely unpacked folder: '${e}'`), await f.rm(e, { recursive: !0 })), s.info(` creating target dir '${e}'`), await f.mkdir(e, { recursive: !0 }), s.info(
|
|
133
133
|
`Unpacking Platforma Backend archive:
|
|
134
|
-
Archive: ${
|
|
134
|
+
Archive: ${t}
|
|
135
135
|
Target dir: ${e}`
|
|
136
|
-
),
|
|
136
|
+
), r) {
|
|
137
137
|
case "tgz":
|
|
138
|
-
await
|
|
139
|
-
file:
|
|
138
|
+
await ir.x({
|
|
139
|
+
file: t,
|
|
140
140
|
cwd: e,
|
|
141
141
|
gzip: !0
|
|
142
142
|
});
|
|
143
143
|
break;
|
|
144
144
|
case "zip":
|
|
145
|
-
await
|
|
145
|
+
await or(t, e);
|
|
146
146
|
break;
|
|
147
147
|
default:
|
|
148
|
-
T(
|
|
148
|
+
T(r);
|
|
149
149
|
}
|
|
150
|
-
await
|
|
150
|
+
await f.writeFile(i, "ok"), s.info(" ... unpack done.");
|
|
151
151
|
}
|
|
152
152
|
const M = {
|
|
153
153
|
linux: "tgz",
|
|
154
154
|
macos: "tgz",
|
|
155
155
|
windows: "zip"
|
|
156
|
-
},
|
|
156
|
+
}, gr = {
|
|
157
157
|
linux: "platforma",
|
|
158
158
|
macos: "platforma",
|
|
159
159
|
windows: "platforma.exe"
|
|
@@ -161,81 +161,81 @@ const M = {
|
|
|
161
161
|
function b() {
|
|
162
162
|
return "1.18.3";
|
|
163
163
|
}
|
|
164
|
-
function
|
|
164
|
+
function yr() {
|
|
165
165
|
return { type: "Download", version: b() };
|
|
166
166
|
}
|
|
167
|
-
async function $
|
|
168
|
-
switch (
|
|
167
|
+
async function $r(s, t, r) {
|
|
168
|
+
switch (r.type) {
|
|
169
169
|
case "Download":
|
|
170
|
-
return (await
|
|
170
|
+
return (await ur(s, t, r.version, k.arch(), k.platform())).binaryPath;
|
|
171
171
|
case "Local":
|
|
172
|
-
return
|
|
172
|
+
return r.path;
|
|
173
173
|
default:
|
|
174
|
-
T(
|
|
174
|
+
T(r);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
function J(s) {
|
|
178
|
-
return
|
|
178
|
+
return d.join(s, "pl_pid");
|
|
179
179
|
}
|
|
180
|
-
async function
|
|
180
|
+
async function Pr(s) {
|
|
181
181
|
if (!await m(s))
|
|
182
182
|
return;
|
|
183
|
-
const
|
|
184
|
-
return Number(
|
|
183
|
+
const t = await f.readFile(s);
|
|
184
|
+
return Number(t.toString());
|
|
185
185
|
}
|
|
186
|
-
async function
|
|
187
|
-
await
|
|
186
|
+
async function vr(s, t) {
|
|
187
|
+
await f.writeFile(s, JSON.stringify(t));
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function Sr() {
|
|
190
190
|
return {};
|
|
191
191
|
}
|
|
192
|
-
function
|
|
193
|
-
return s[
|
|
192
|
+
function Cr(s, t, r) {
|
|
193
|
+
return s[t] = r, r;
|
|
194
194
|
}
|
|
195
|
-
async function A(s,
|
|
196
|
-
const
|
|
195
|
+
async function A(s, t) {
|
|
196
|
+
const r = Sr();
|
|
197
197
|
try {
|
|
198
|
-
return await
|
|
198
|
+
return await t((i, o) => Cr(r, i, o), r);
|
|
199
199
|
} catch (e) {
|
|
200
|
-
throw s.error(`error ${e} while doing traced operation, state: ${JSON.stringify(
|
|
200
|
+
throw s.error(`error ${e} while doing traced operation, state: ${JSON.stringify(r)}`), e;
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
-
const
|
|
204
|
-
class
|
|
205
|
-
constructor(
|
|
203
|
+
const Er = "config-local.yaml";
|
|
204
|
+
class Fr {
|
|
205
|
+
constructor(t, r, e, i, o, n, c, a) {
|
|
206
206
|
w(this, "instance");
|
|
207
207
|
w(this, "pid");
|
|
208
208
|
w(this, "nRuns", 0);
|
|
209
209
|
w(this, "lastRunHistory", {});
|
|
210
210
|
w(this, "wasStopped", !1);
|
|
211
|
-
this.logger =
|
|
211
|
+
this.logger = t, this.workingDir = r, this.startOptions = e, this.initialStartHistory = i, this.onClose = o, this.onError = n, this.onCloseAndError = c, this.onCloseAndErrorNoStop = a;
|
|
212
212
|
}
|
|
213
213
|
async start() {
|
|
214
|
-
await A(this.logger, async (
|
|
214
|
+
await A(this.logger, async (t, r) => {
|
|
215
215
|
this.wasStopped = !1;
|
|
216
|
-
const e =
|
|
216
|
+
const e = cr(this.logger, this.startOptions);
|
|
217
217
|
e.on("error", (o) => {
|
|
218
218
|
this.logger.error(
|
|
219
219
|
`error '${o}', while running platforma, started opts: ${JSON.stringify(this.debugInfo())}`
|
|
220
220
|
), this.onError !== void 0 && this.onError(this), this.onCloseAndError !== void 0 && this.onCloseAndError(this), this.onCloseAndErrorNoStop !== void 0 && !this.wasStopped && this.onCloseAndErrorNoStop(this);
|
|
221
221
|
}), e.on("close", () => {
|
|
222
222
|
this.logger.warn(`platforma was closed, started opts: ${JSON.stringify(this.debugInfo())}`), this.onClose !== void 0 && this.onClose(this), this.onCloseAndError !== void 0 && this.onCloseAndError(this), this.onCloseAndErrorNoStop !== void 0 && !this.wasStopped && this.onCloseAndErrorNoStop(this);
|
|
223
|
-
}),
|
|
224
|
-
const i =
|
|
225
|
-
|
|
223
|
+
}), t("started", !0);
|
|
224
|
+
const i = t("pidFile", J(this.workingDir));
|
|
225
|
+
t("pid", p(e.pid)), t("pidWritten", await vr(i, p(e.pid))), this.nRuns++, this.instance = e, this.pid = e.pid, this.lastRunHistory = r;
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
stop() {
|
|
229
|
-
this.wasStopped = !0, _(
|
|
229
|
+
this.wasStopped = !0, _(p(this.pid));
|
|
230
230
|
}
|
|
231
231
|
async waitStopped() {
|
|
232
|
-
await j(
|
|
232
|
+
await j(p(this.pid), 15e3);
|
|
233
233
|
}
|
|
234
234
|
stopped() {
|
|
235
235
|
return this.wasStopped;
|
|
236
236
|
}
|
|
237
237
|
async isAlive() {
|
|
238
|
-
return await D(
|
|
238
|
+
return await D(p(this.pid));
|
|
239
239
|
}
|
|
240
240
|
debugInfo() {
|
|
241
241
|
return {
|
|
@@ -248,21 +248,21 @@ class Ft {
|
|
|
248
248
|
};
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
-
async function
|
|
252
|
-
const
|
|
253
|
-
plBinary:
|
|
251
|
+
async function it(s, t) {
|
|
252
|
+
const r = {
|
|
253
|
+
plBinary: yr(),
|
|
254
254
|
spawnOptions: {},
|
|
255
255
|
closeOld: !0,
|
|
256
|
-
...
|
|
256
|
+
...t
|
|
257
257
|
};
|
|
258
258
|
return await A(s, async (e, i) => {
|
|
259
|
-
e("startOptions", { ...
|
|
260
|
-
const o =
|
|
261
|
-
|
|
262
|
-
const n =
|
|
263
|
-
s.info(`writing configuration '${n}'...`), await
|
|
264
|
-
const c = await $
|
|
265
|
-
cmd: e("binaryPath",
|
|
259
|
+
e("startOptions", { ...r, config: "too wordy" });
|
|
260
|
+
const o = d.resolve(r.workingDir);
|
|
261
|
+
r.closeOld && e("closeOld", await Dr(s, o));
|
|
262
|
+
const n = d.join(o, Er);
|
|
263
|
+
s.info(`writing configuration '${n}'...`), await f.writeFile(n, r.config);
|
|
264
|
+
const c = await $r(s, d.join(o, "binaries"), r.plBinary), l = {
|
|
265
|
+
cmd: e("binaryPath", d.join("binaries", c)),
|
|
266
266
|
args: ["-config", n],
|
|
267
267
|
opts: {
|
|
268
268
|
env: { ...process.env },
|
|
@@ -270,7 +270,7 @@ async function ir(s, r) {
|
|
|
270
270
|
stdio: ["pipe", "ignore", "inherit"],
|
|
271
271
|
windowsHide: !0,
|
|
272
272
|
// hide a terminal on Windows
|
|
273
|
-
...
|
|
273
|
+
...r.spawnOptions
|
|
274
274
|
}
|
|
275
275
|
};
|
|
276
276
|
e("processOpts", {
|
|
@@ -278,76 +278,80 @@ async function ir(s, r) {
|
|
|
278
278
|
args: l.args,
|
|
279
279
|
cwd: l.opts.cwd
|
|
280
280
|
});
|
|
281
|
-
const h = new
|
|
281
|
+
const h = new Fr(
|
|
282
282
|
s,
|
|
283
|
-
|
|
283
|
+
r.workingDir,
|
|
284
284
|
l,
|
|
285
285
|
i,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
286
|
+
r.onClose,
|
|
287
|
+
r.onError,
|
|
288
|
+
r.onCloseAndError,
|
|
289
|
+
r.onCloseAndErrorNoStop
|
|
290
290
|
);
|
|
291
291
|
return await h.start(), h;
|
|
292
292
|
});
|
|
293
293
|
}
|
|
294
|
-
async function
|
|
295
|
-
return await A(s, async (
|
|
296
|
-
const i =
|
|
297
|
-
return o !== void 0 && n && (
|
|
294
|
+
async function Dr(s, t) {
|
|
295
|
+
return await A(s, async (r, e) => {
|
|
296
|
+
const i = r("pidFilePath", J(t)), o = r("pid", await Pr(i)), n = r("wasAlive", await D(o));
|
|
297
|
+
return o !== void 0 && n && (r("stopped", _(o)), r("waitStopped", await j(o, 1e4))), e;
|
|
298
298
|
});
|
|
299
299
|
}
|
|
300
|
-
const
|
|
300
|
+
const br = {
|
|
301
301
|
keepaliveInterval: 6e4,
|
|
302
302
|
keepaliveCountMax: 10
|
|
303
303
|
};
|
|
304
304
|
class x {
|
|
305
|
-
constructor(
|
|
305
|
+
constructor(t, r) {
|
|
306
306
|
w(this, "config");
|
|
307
307
|
w(this, "homeDir");
|
|
308
|
-
this
|
|
308
|
+
w(this, "forwardedServers", []);
|
|
309
|
+
this.logger = t, this.client = r;
|
|
309
310
|
}
|
|
310
311
|
/**
|
|
311
312
|
* Initializes the SshClient and establishes a connection using the provided configuration.
|
|
312
313
|
* @param config - The connection configuration object for the SSH client.
|
|
313
314
|
* @returns A new instance of SshClient with an active connection.
|
|
314
315
|
*/
|
|
315
|
-
static async init(
|
|
316
|
+
static async init(t, r) {
|
|
316
317
|
const e = {
|
|
317
|
-
...
|
|
318
|
-
...
|
|
319
|
-
}, i = new x(
|
|
318
|
+
...br,
|
|
319
|
+
...r
|
|
320
|
+
}, i = new x(t, new S());
|
|
320
321
|
return await i.connect(e), i;
|
|
321
322
|
}
|
|
323
|
+
getForwardedServers() {
|
|
324
|
+
return this.forwardedServers;
|
|
325
|
+
}
|
|
322
326
|
getFullHostName() {
|
|
323
|
-
var
|
|
324
|
-
return `${(
|
|
327
|
+
var t, r;
|
|
328
|
+
return `${(t = this.config) == null ? void 0 : t.host}:${(r = this.config) == null ? void 0 : r.port}`;
|
|
325
329
|
}
|
|
326
330
|
getUserName() {
|
|
327
|
-
var
|
|
328
|
-
return (
|
|
331
|
+
var t;
|
|
332
|
+
return (t = this.config) == null ? void 0 : t.username;
|
|
329
333
|
}
|
|
330
334
|
/**
|
|
331
335
|
* Connects to the SSH server using the specified configuration.
|
|
332
336
|
* @param config - The connection configuration object for the SSH client.
|
|
333
337
|
* @returns A promise that resolves when the connection is established or rejects on error.
|
|
334
338
|
*/
|
|
335
|
-
async connect(
|
|
336
|
-
return this.config =
|
|
339
|
+
async connect(t) {
|
|
340
|
+
return this.config = t, await Ar(this.client, t);
|
|
337
341
|
}
|
|
338
342
|
/**
|
|
339
343
|
* Executes a command on the SSH server.
|
|
340
344
|
* @param command - The command to execute on the remote server.
|
|
341
345
|
* @returns A promise resolving with the command's stdout and stderr outputs.
|
|
342
346
|
*/
|
|
343
|
-
async exec(
|
|
344
|
-
return new Promise((
|
|
345
|
-
this.client.exec(
|
|
347
|
+
async exec(t) {
|
|
348
|
+
return new Promise((r, e) => {
|
|
349
|
+
this.client.exec(t, (i, o) => {
|
|
346
350
|
if (i)
|
|
347
|
-
return e(`ssh.exec: ${
|
|
351
|
+
return e(`ssh.exec: ${t}, error occurred: ${i}`);
|
|
348
352
|
let n = "", c = "";
|
|
349
353
|
o.on("close", (a) => {
|
|
350
|
-
a === 0 ?
|
|
354
|
+
a === 0 ? r({ stdout: n, stderr: c }) : e(new Error(`Command ${t} exited with code ${a}`));
|
|
351
355
|
}).on("data", (a) => {
|
|
352
356
|
n += a.toString();
|
|
353
357
|
}).stderr.on("data", (a) => {
|
|
@@ -362,7 +366,7 @@ class x {
|
|
|
362
366
|
* @param port - The port number to connect to on the server.
|
|
363
367
|
* @returns 'publickey' | 'password'[] A promise resolving with a list of supported authentication methods.
|
|
364
368
|
*/
|
|
365
|
-
static async getAuthTypes(
|
|
369
|
+
static async getAuthTypes(t, r) {
|
|
366
370
|
return new Promise((e) => {
|
|
367
371
|
let i = "";
|
|
368
372
|
const o = new S();
|
|
@@ -373,8 +377,8 @@ class x {
|
|
|
373
377
|
}), o.on("error", () => {
|
|
374
378
|
o.end(), e(["publickey", "password"]);
|
|
375
379
|
}), o.connect({
|
|
376
|
-
host:
|
|
377
|
-
port:
|
|
380
|
+
host: t,
|
|
381
|
+
port: r,
|
|
378
382
|
username: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
379
383
|
debug: (n) => {
|
|
380
384
|
i += `${n}
|
|
@@ -388,9 +392,9 @@ class x {
|
|
|
388
392
|
* @param log - The debug log output containing authentication information.
|
|
389
393
|
* @returns An array of extracted authentication methods.
|
|
390
394
|
*/
|
|
391
|
-
static extractAuthMethods(
|
|
392
|
-
const
|
|
393
|
-
return
|
|
395
|
+
static extractAuthMethods(t) {
|
|
396
|
+
const r = t.match(/Inbound: Received USERAUTH_FAILURE \((.+)\)/);
|
|
397
|
+
return r && r[1] ? r[1].split(",").map((e) => e.trim()) : [];
|
|
394
398
|
}
|
|
395
399
|
/**
|
|
396
400
|
* Sets up port forwarding between a remote port on the SSH server and a local port.
|
|
@@ -399,9 +403,9 @@ class x {
|
|
|
399
403
|
* @param config - Optional connection configuration for the SSH client.
|
|
400
404
|
* @returns { server: net.Server } A promise resolving with the created server instance.
|
|
401
405
|
*/
|
|
402
|
-
async forwardPort(
|
|
403
|
-
const e = `ssh.forward:${
|
|
404
|
-
|
|
406
|
+
async forwardPort(t, r) {
|
|
407
|
+
const e = `ssh.forward:${t.localPort}:${t.remotePort}.id_${F(1).toString("hex")}`;
|
|
408
|
+
r = r ?? this.config;
|
|
405
409
|
const i = new Y((o) => new Promise((n, c) => {
|
|
406
410
|
const a = new S();
|
|
407
411
|
a.on("ready", () => {
|
|
@@ -410,7 +414,7 @@ class x {
|
|
|
410
414
|
this.logger.info(`${e}.client.error: ${l}`), o.reset(), c(l);
|
|
411
415
|
}), a.on("close", () => {
|
|
412
416
|
this.logger.info(`${e}.client.closed`), o.reset();
|
|
413
|
-
}), a.connect(
|
|
417
|
+
}), a.connect(r);
|
|
414
418
|
}));
|
|
415
419
|
return await i.ensure(), new Promise((o, n) => {
|
|
416
420
|
const c = B.createServer({ pauseOnConnect: !0 }, async (a) => {
|
|
@@ -422,39 +426,49 @@ class x {
|
|
|
422
426
|
this.logger.info(`${l}.persistentClient.catch: ${g}`), a.end();
|
|
423
427
|
return;
|
|
424
428
|
}
|
|
425
|
-
let
|
|
429
|
+
let u;
|
|
426
430
|
try {
|
|
427
|
-
|
|
431
|
+
u = await xr(this.logger, h, "127.0.0.1", 0, "127.0.0.1", t.remotePort);
|
|
428
432
|
} catch (g) {
|
|
429
433
|
this.logger.error(`${l}.forwardOut.err: ${g}`), a.end();
|
|
430
434
|
return;
|
|
431
435
|
}
|
|
432
|
-
a.pipe(
|
|
433
|
-
this.logger.error(`${l}.stream.error: ${g}`), a.end(),
|
|
434
|
-
}),
|
|
435
|
-
a.end(),
|
|
436
|
+
a.pipe(u), u.pipe(a), a.resume(), u.on("error", (g) => {
|
|
437
|
+
this.logger.error(`${l}.stream.error: ${g}`), a.end(), u.end();
|
|
438
|
+
}), u.on("close", () => {
|
|
439
|
+
a.end(), u.end();
|
|
436
440
|
}), a.on("close", () => {
|
|
437
|
-
this.logger.info(`${l}.localSocket: closed`), a.end(),
|
|
441
|
+
this.logger.info(`${l}.localSocket: closed`), a.end(), u.end();
|
|
438
442
|
});
|
|
439
443
|
});
|
|
440
|
-
c.listen(
|
|
441
|
-
this.logger.info(`${e}.server: started listening`), o({ server: c });
|
|
444
|
+
c.listen(t.localPort, "127.0.0.1", () => {
|
|
445
|
+
this.logger.info(`${e}.server: started listening`), this.forwardedServers.push(c), o({ server: c });
|
|
442
446
|
}), c.on("error", (a) => {
|
|
443
447
|
c.close(), n(new Error(`${e}.server: error: ${JSON.stringify(a)}`));
|
|
444
448
|
}), c.on("close", () => {
|
|
445
|
-
this.logger.info(`${e}.server: closed ${JSON.stringify(
|
|
449
|
+
this.logger.info(`${e}.server: closed ${JSON.stringify(t)}`), this.forwardedServers = this.forwardedServers.filter((a) => a !== c);
|
|
446
450
|
});
|
|
447
451
|
});
|
|
448
452
|
}
|
|
453
|
+
closeForwardedPorts() {
|
|
454
|
+
this.logger.info("[SSH] Closing all forwarded ports..."), this.forwardedServers.forEach((t) => {
|
|
455
|
+
const r = t.address();
|
|
456
|
+
if (r && typeof r != "string") {
|
|
457
|
+
const e = r;
|
|
458
|
+
this.logger.info(`[SSH] Closing port forward for server ${e.address}:${e.port}`);
|
|
459
|
+
}
|
|
460
|
+
t.close();
|
|
461
|
+
}), this.forwardedServers = [];
|
|
462
|
+
}
|
|
449
463
|
/**
|
|
450
464
|
* Checks if a specified host is available by performing a DNS lookup.
|
|
451
465
|
* @param hostname - The hostname or IP address to check.
|
|
452
466
|
* @returns A promise resolving with `true` if the host is reachable, otherwise `false`.
|
|
453
467
|
*/
|
|
454
|
-
static async checkHostAvailability(
|
|
455
|
-
return new Promise((
|
|
456
|
-
|
|
457
|
-
|
|
468
|
+
static async checkHostAvailability(t) {
|
|
469
|
+
return new Promise((r) => {
|
|
470
|
+
nr.lookup(t, (e) => {
|
|
471
|
+
r(!e);
|
|
458
472
|
});
|
|
459
473
|
});
|
|
460
474
|
}
|
|
@@ -463,10 +477,10 @@ class x {
|
|
|
463
477
|
* @param privateKey - The private key content to check.
|
|
464
478
|
* @returns A promise resolving with `true` if a passphrase is required, otherwise `false`.
|
|
465
479
|
*/
|
|
466
|
-
static async isPassphraseRequiredForKey(
|
|
467
|
-
return new Promise((
|
|
480
|
+
static async isPassphraseRequiredForKey(t) {
|
|
481
|
+
return new Promise((r, e) => {
|
|
468
482
|
try {
|
|
469
|
-
return
|
|
483
|
+
return sr.utils.parseKey(t) instanceof Error && r(!0), r(!1);
|
|
470
484
|
} catch (i) {
|
|
471
485
|
console.log("Error parsing privateKey"), e(new Error(`ssh.isPassphraseRequiredForKey: err ${i}`));
|
|
472
486
|
}
|
|
@@ -479,12 +493,12 @@ class x {
|
|
|
479
493
|
* @param remotePath - The remote file path on the server.
|
|
480
494
|
* @returns A promise resolving with `true` if the file was successfully uploaded.
|
|
481
495
|
*/
|
|
482
|
-
async uploadFile(
|
|
496
|
+
async uploadFile(t, r) {
|
|
483
497
|
return await this.withSftp(async (e) => new Promise((i, o) => {
|
|
484
|
-
e.fastPut(
|
|
498
|
+
e.fastPut(t, r, (n) => {
|
|
485
499
|
if (n) {
|
|
486
500
|
const c = new Error(
|
|
487
|
-
`ssh.uploadFile: err: ${n}, localPath: ${
|
|
501
|
+
`ssh.uploadFile: err: ${n}, localPath: ${t}, remotePath: ${r}`
|
|
488
502
|
);
|
|
489
503
|
return o(c);
|
|
490
504
|
}
|
|
@@ -492,17 +506,17 @@ class x {
|
|
|
492
506
|
});
|
|
493
507
|
}));
|
|
494
508
|
}
|
|
495
|
-
delay(
|
|
496
|
-
return new Promise((
|
|
497
|
-
setTimeout(() =>
|
|
509
|
+
delay(t) {
|
|
510
|
+
return new Promise((r, e) => {
|
|
511
|
+
setTimeout(() => r(), t);
|
|
498
512
|
});
|
|
499
513
|
}
|
|
500
|
-
async withSftp(
|
|
501
|
-
return new Promise((
|
|
514
|
+
async withSftp(t) {
|
|
515
|
+
return new Promise((r, e) => {
|
|
502
516
|
this.client.sftp((i, o) => {
|
|
503
517
|
if (i)
|
|
504
518
|
return e(new Error(`ssh.withSftp: sftp err: ${i}`));
|
|
505
|
-
|
|
519
|
+
t(o).then(r).catch((n) => {
|
|
506
520
|
e(new Error(`ssh.withSftp.callback: err ${n}`));
|
|
507
521
|
}).finally(() => {
|
|
508
522
|
o == null || o.end();
|
|
@@ -510,20 +524,20 @@ class x {
|
|
|
510
524
|
});
|
|
511
525
|
});
|
|
512
526
|
}
|
|
513
|
-
async writeFileOnTheServer(
|
|
514
|
-
return this.withSftp(async (i) => this.writeFile(i,
|
|
527
|
+
async writeFileOnTheServer(t, r, e = 432) {
|
|
528
|
+
return this.withSftp(async (i) => this.writeFile(i, t, r, e));
|
|
515
529
|
}
|
|
516
|
-
async getForderStructure(
|
|
530
|
+
async getForderStructure(t, r, e = { files: [], directories: [] }) {
|
|
517
531
|
return new Promise((i, o) => {
|
|
518
|
-
|
|
532
|
+
t.readdir(r, async (n, c) => {
|
|
519
533
|
if (n)
|
|
520
534
|
return o(n);
|
|
521
535
|
for (const a of c) {
|
|
522
|
-
const l = `${
|
|
536
|
+
const l = `${r}/${a.filename}`;
|
|
523
537
|
if (a.attrs.isDirectory()) {
|
|
524
538
|
e.directories.push(l);
|
|
525
539
|
try {
|
|
526
|
-
await this.getForderStructure(
|
|
540
|
+
await this.getForderStructure(t, l, e);
|
|
527
541
|
} catch (h) {
|
|
528
542
|
return o(h);
|
|
529
543
|
}
|
|
@@ -534,60 +548,60 @@ class x {
|
|
|
534
548
|
});
|
|
535
549
|
});
|
|
536
550
|
}
|
|
537
|
-
rmdir(
|
|
551
|
+
rmdir(t, r) {
|
|
538
552
|
return new Promise((e, i) => {
|
|
539
|
-
|
|
553
|
+
t.rmdir(r, (o) => o ? i(o) : e(!0));
|
|
540
554
|
});
|
|
541
555
|
}
|
|
542
|
-
unlink(
|
|
556
|
+
unlink(t, r) {
|
|
543
557
|
return new Promise((e, i) => {
|
|
544
|
-
|
|
558
|
+
t.unlink(r, (o) => o ? i(o) : e(!0));
|
|
545
559
|
});
|
|
546
560
|
}
|
|
547
|
-
async deleteFolder(
|
|
548
|
-
return this.withSftp(async (
|
|
561
|
+
async deleteFolder(t) {
|
|
562
|
+
return this.withSftp(async (r) => {
|
|
549
563
|
try {
|
|
550
|
-
const e = await this.getForderStructure(
|
|
564
|
+
const e = await this.getForderStructure(r, t);
|
|
551
565
|
this.logger.info("ssh.deleteFolder list of files and directories"), this.logger.info(`ssh.deleteFolder list of files: ${e.files}`), this.logger.info(`ssh.deleteFolder list of directories: ${e.directories}`);
|
|
552
566
|
for (const i of e.files)
|
|
553
|
-
this.logger.info(`ssh.deleteFolder unlink file ${i}`), await this.unlink(
|
|
567
|
+
this.logger.info(`ssh.deleteFolder unlink file ${i}`), await this.unlink(r, i);
|
|
554
568
|
e.directories.sort((i, o) => o.length - i.length);
|
|
555
569
|
for (const i of e.directories)
|
|
556
|
-
this.logger.info(`ssh.deleteFolder rmdir ${i}`), await this.rmdir(
|
|
557
|
-
return await this.rmdir(
|
|
570
|
+
this.logger.info(`ssh.deleteFolder rmdir ${i}`), await this.rmdir(r, i);
|
|
571
|
+
return await this.rmdir(r, t), !0;
|
|
558
572
|
} catch (e) {
|
|
559
573
|
this.logger.error(e);
|
|
560
574
|
const i = e instanceof Error ? e.message : "";
|
|
561
|
-
throw new Error(`ssh.deleteFolder: path: ${
|
|
575
|
+
throw new Error(`ssh.deleteFolder: path: ${t}, message: ${i}`);
|
|
562
576
|
}
|
|
563
577
|
});
|
|
564
578
|
}
|
|
565
|
-
async readFile(
|
|
566
|
-
return this.withSftp(async (
|
|
567
|
-
|
|
579
|
+
async readFile(t) {
|
|
580
|
+
return this.withSftp(async (r) => new Promise((e, i) => {
|
|
581
|
+
r.readFile(t, (o, n) => {
|
|
568
582
|
if (o)
|
|
569
583
|
return i(new Error(`ssh.readFile: err occurred ${o}`));
|
|
570
584
|
e(n.toString());
|
|
571
585
|
});
|
|
572
586
|
}));
|
|
573
587
|
}
|
|
574
|
-
async chmod(
|
|
588
|
+
async chmod(t, r) {
|
|
575
589
|
return this.withSftp(async (e) => new Promise((i, o) => {
|
|
576
|
-
e.chmod(
|
|
590
|
+
e.chmod(t, r, (n) => n ? o(new Error(`ssh.chmod: ${n}, path: ${t}, mode: ${r}`)) : i(void 0));
|
|
577
591
|
}));
|
|
578
592
|
}
|
|
579
|
-
async checkFileExists(
|
|
580
|
-
return this.withSftp(async (
|
|
581
|
-
|
|
593
|
+
async checkFileExists(t) {
|
|
594
|
+
return this.withSftp(async (r) => new Promise((e, i) => {
|
|
595
|
+
r.stat(t, (o, n) => {
|
|
582
596
|
if (o)
|
|
583
597
|
return o.code === 2 ? e(!1) : i(new Error(`ssh.checkFileExists: err ${o}`));
|
|
584
598
|
e(n.isFile());
|
|
585
599
|
});
|
|
586
600
|
}));
|
|
587
601
|
}
|
|
588
|
-
async checkPathExists(
|
|
589
|
-
return this.withSftp(async (
|
|
590
|
-
|
|
602
|
+
async checkPathExists(t) {
|
|
603
|
+
return this.withSftp(async (r) => new Promise((e, i) => {
|
|
604
|
+
r.stat(t, (o, n) => {
|
|
591
605
|
if (o)
|
|
592
606
|
return o.code === 2 ? e({ exists: !1, isFile: !1, isDirectory: !1 }) : i(new Error(`ssh.checkPathExists: ${o}`));
|
|
593
607
|
e({
|
|
@@ -598,19 +612,19 @@ class x {
|
|
|
598
612
|
});
|
|
599
613
|
}));
|
|
600
614
|
}
|
|
601
|
-
async writeFile(
|
|
615
|
+
async writeFile(t, r, e, i = 432) {
|
|
602
616
|
return new Promise((o, n) => {
|
|
603
|
-
|
|
617
|
+
t.writeFile(r, e, { mode: i }, (c) => {
|
|
604
618
|
if (c)
|
|
605
|
-
return n(new Error(`ssh.writeFile: err ${c}, remotePath: ${
|
|
619
|
+
return n(new Error(`ssh.writeFile: err ${c}, remotePath: ${r}`));
|
|
606
620
|
o(!0);
|
|
607
621
|
});
|
|
608
622
|
});
|
|
609
623
|
}
|
|
610
|
-
uploadFileUsingExistingSftp(
|
|
624
|
+
uploadFileUsingExistingSftp(t, r, e, i = 432) {
|
|
611
625
|
return new Promise((o, n) => {
|
|
612
|
-
Q(
|
|
613
|
-
this.writeFile(
|
|
626
|
+
Q(r).then(async (c) => {
|
|
627
|
+
this.writeFile(t, e, c, i).then(() => {
|
|
614
628
|
o(void 0);
|
|
615
629
|
}).catch((a) => {
|
|
616
630
|
const l = `uploadFileUsingExistingSftp: error ${a} occurred`;
|
|
@@ -619,16 +633,16 @@ class x {
|
|
|
619
633
|
});
|
|
620
634
|
});
|
|
621
635
|
}
|
|
622
|
-
async __uploadDirectory(
|
|
636
|
+
async __uploadDirectory(t, r, e, i = 432) {
|
|
623
637
|
return new Promise((o, n) => {
|
|
624
|
-
E.readdir(
|
|
638
|
+
E.readdir(r, async (c, a) => {
|
|
625
639
|
if (c)
|
|
626
|
-
return n(new Error(`ssh.__uploadDir: err ${c}, localDir: ${
|
|
640
|
+
return n(new Error(`ssh.__uploadDir: err ${c}, localDir: ${r}, remoteDir: ${e}`));
|
|
627
641
|
try {
|
|
628
|
-
await this.__createRemoteDirectory(
|
|
642
|
+
await this.__createRemoteDirectory(t, e);
|
|
629
643
|
for (const l of a) {
|
|
630
|
-
const h =
|
|
631
|
-
E.lstatSync(h).isDirectory() ? await this.__uploadDirectory(
|
|
644
|
+
const h = d.join(r, l), u = `${e}/${l}`;
|
|
645
|
+
E.lstatSync(h).isDirectory() ? await this.__uploadDirectory(t, h, u, i) : await this.uploadFileUsingExistingSftp(t, h, u, i);
|
|
632
646
|
}
|
|
633
647
|
o();
|
|
634
648
|
} catch (l) {
|
|
@@ -644,10 +658,10 @@ class x {
|
|
|
644
658
|
* @param remoteDir - The path to the remote directory on the server.
|
|
645
659
|
* @returns A promise that resolves when the directory and its contents are uploaded.
|
|
646
660
|
*/
|
|
647
|
-
async uploadDirectory(
|
|
661
|
+
async uploadDirectory(t, r, e = 432) {
|
|
648
662
|
return new Promise((i, o) => {
|
|
649
663
|
this.withSftp(async (n) => {
|
|
650
|
-
await this.__uploadDirectory(n,
|
|
664
|
+
await this.__uploadDirectory(n, t, r, e), i();
|
|
651
665
|
});
|
|
652
666
|
});
|
|
653
667
|
}
|
|
@@ -657,17 +671,17 @@ class x {
|
|
|
657
671
|
* @param remotePath - The path to the remote directory.
|
|
658
672
|
* @returns A promise that resolves when the directory is created.
|
|
659
673
|
*/
|
|
660
|
-
__createRemoteDirectory(
|
|
674
|
+
__createRemoteDirectory(t, r) {
|
|
661
675
|
return new Promise((e, i) => {
|
|
662
|
-
const o =
|
|
676
|
+
const o = r.split("/");
|
|
663
677
|
let n = "";
|
|
664
678
|
const c = (a) => {
|
|
665
679
|
if (a >= o.length)
|
|
666
680
|
return e();
|
|
667
|
-
n += `${o[a]}/`,
|
|
668
|
-
l ?
|
|
681
|
+
n += `${o[a]}/`, t.stat(n, (l) => {
|
|
682
|
+
l ? t.mkdir(n, (h) => {
|
|
669
683
|
if (h)
|
|
670
|
-
return i(new Error(`ssh.__createRemDir: err ${h}, remotePath: ${
|
|
684
|
+
return i(new Error(`ssh.__createRemDir: err ${h}, remotePath: ${r}`));
|
|
671
685
|
c(a + 1);
|
|
672
686
|
}) : c(a + 1);
|
|
673
687
|
});
|
|
@@ -681,9 +695,9 @@ class x {
|
|
|
681
695
|
* @param remotePath - The path to the remote directory.
|
|
682
696
|
* @returns A promise that resolves when the directory is created.
|
|
683
697
|
*/
|
|
684
|
-
createRemoteDirectory(
|
|
698
|
+
createRemoteDirectory(t, r = 493) {
|
|
685
699
|
return this.withSftp(async (e) => {
|
|
686
|
-
const i =
|
|
700
|
+
const i = t.split("/");
|
|
687
701
|
let o = "";
|
|
688
702
|
for (const n of i) {
|
|
689
703
|
o += `${n}/`;
|
|
@@ -691,9 +705,9 @@ class x {
|
|
|
691
705
|
await new Promise((c, a) => {
|
|
692
706
|
e.stat(o, (l) => {
|
|
693
707
|
if (!l) return c();
|
|
694
|
-
e.mkdir(o, { mode:
|
|
708
|
+
e.mkdir(o, { mode: r }, (h) => {
|
|
695
709
|
if (h)
|
|
696
|
-
return a(new Error(`ssh.createRemoteDir: err ${h}, remotePath: ${
|
|
710
|
+
return a(new Error(`ssh.createRemoteDir: err ${h}, remotePath: ${t}`));
|
|
697
711
|
c();
|
|
698
712
|
});
|
|
699
713
|
});
|
|
@@ -710,86 +724,86 @@ class x {
|
|
|
710
724
|
* @param localPath - The local file path to save the file.
|
|
711
725
|
* @returns A promise resolving with `true` if the file was successfully downloaded.
|
|
712
726
|
*/
|
|
713
|
-
async downloadFile(
|
|
727
|
+
async downloadFile(t, r) {
|
|
714
728
|
return this.withSftp(async (e) => new Promise((i, o) => {
|
|
715
|
-
e.fastGet(
|
|
729
|
+
e.fastGet(t, r, (n) => {
|
|
716
730
|
if (n)
|
|
717
|
-
return o(new Error(`ssh.downloadFile: err ${n}, remotePath: ${
|
|
731
|
+
return o(new Error(`ssh.downloadFile: err ${n}, remotePath: ${t}, localPath: ${r}`));
|
|
718
732
|
i(!0);
|
|
719
733
|
});
|
|
720
734
|
}));
|
|
721
735
|
}
|
|
722
736
|
/**
|
|
723
|
-
* Closes the SSH client connection.
|
|
737
|
+
* Closes the SSH client connection and forwarded ports.
|
|
724
738
|
*/
|
|
725
739
|
close() {
|
|
726
|
-
this.client.end();
|
|
740
|
+
this.closeForwardedPorts(), this.client.end();
|
|
727
741
|
}
|
|
728
742
|
}
|
|
729
|
-
async function
|
|
743
|
+
async function Ar(s, t, r, e) {
|
|
730
744
|
return new Promise((i, o) => {
|
|
731
745
|
s.on("ready", () => {
|
|
732
746
|
i(s);
|
|
733
747
|
}), s.on("error", (n) => {
|
|
734
748
|
o(new Error(`ssh.connect: error occurred: ${n}`));
|
|
735
749
|
}), s.on("close", () => {
|
|
736
|
-
}), s.connect(
|
|
750
|
+
}), s.connect(t);
|
|
737
751
|
});
|
|
738
752
|
}
|
|
739
|
-
async function
|
|
753
|
+
async function xr(s, t, r, e, i, o) {
|
|
740
754
|
return new Promise((n, c) => {
|
|
741
|
-
|
|
755
|
+
t.forwardOut(r, e, i, o, (a, l) => a ? (s.error(`forwardOut.error: ${a}`), c(a)) : n(l));
|
|
742
756
|
});
|
|
743
757
|
}
|
|
744
|
-
const
|
|
758
|
+
const Or = "minio-2024-12-18T13-15-44Z", kr = "supervisord-0.7.3", Rr = "supervisord_0.7.3_Linux_64-bit";
|
|
745
759
|
function $(s) {
|
|
746
|
-
return
|
|
760
|
+
return d.join(s, "platforma_ssh");
|
|
747
761
|
}
|
|
748
762
|
function v(s) {
|
|
749
|
-
return
|
|
763
|
+
return d.join(s, "platforma_ssh", "binaries");
|
|
750
764
|
}
|
|
751
|
-
function
|
|
752
|
-
return
|
|
765
|
+
function Nr(s, t) {
|
|
766
|
+
return d.join(v(s), `pl-${b()}-${P(t)}`);
|
|
753
767
|
}
|
|
754
|
-
function L(s,
|
|
755
|
-
return
|
|
768
|
+
function L(s, t) {
|
|
769
|
+
return d.join(Nr(s, t), "binaries");
|
|
756
770
|
}
|
|
757
|
-
function R(s,
|
|
758
|
-
return
|
|
771
|
+
function R(s, t) {
|
|
772
|
+
return d.join(L(s, t), "platforma");
|
|
759
773
|
}
|
|
760
|
-
function
|
|
761
|
-
return
|
|
774
|
+
function Ur(s, t) {
|
|
775
|
+
return d.join(L(s, t), "free-port");
|
|
762
776
|
}
|
|
763
|
-
function z(s,
|
|
764
|
-
return
|
|
777
|
+
function z(s, t) {
|
|
778
|
+
return d.join(v(s), `minio-2024-12-18T13-15-44Z-${P(t)}`);
|
|
765
779
|
}
|
|
766
|
-
function
|
|
767
|
-
return
|
|
780
|
+
function Tr(s, t) {
|
|
781
|
+
return d.join(z(s, t), "minio");
|
|
768
782
|
}
|
|
769
|
-
function
|
|
770
|
-
return
|
|
783
|
+
function Br(s, t) {
|
|
784
|
+
return d.join(v(s), `supervisord-0.7.3-${P(t)}`, Rr);
|
|
771
785
|
}
|
|
772
|
-
function W(s,
|
|
773
|
-
return
|
|
786
|
+
function W(s, t) {
|
|
787
|
+
return d.join(Br(s, t), "supervisord");
|
|
774
788
|
}
|
|
775
789
|
function K(s) {
|
|
776
|
-
return
|
|
790
|
+
return d.join($(s), "supervisor.conf");
|
|
777
791
|
}
|
|
778
792
|
function N(s) {
|
|
779
|
-
return
|
|
793
|
+
return d.join($(s), "connection.txt");
|
|
780
794
|
}
|
|
781
|
-
async function
|
|
782
|
-
const e = await O(s,
|
|
795
|
+
async function _r(s, t, r) {
|
|
796
|
+
const e = await O(s, t, r, "--daemon");
|
|
783
797
|
if (e.stderr)
|
|
784
798
|
throw new Error(`Can not run ssh Platforma ${e.stderr}`);
|
|
785
799
|
}
|
|
786
|
-
async function
|
|
787
|
-
const e = await O(s,
|
|
800
|
+
async function jr(s, t, r) {
|
|
801
|
+
const e = await O(s, t, r, "ctl shutdown");
|
|
788
802
|
if (e.stderr)
|
|
789
803
|
throw new Error(`Can not stop ssh Platforma ${e.stderr}`);
|
|
790
804
|
}
|
|
791
|
-
async function
|
|
792
|
-
const i = await O(
|
|
805
|
+
async function Ir(s, t, r, e) {
|
|
806
|
+
const i = await O(t, r, e, "ctl status");
|
|
793
807
|
if (i.stderr)
|
|
794
808
|
return s.info(`supervisord ctl status: stderr occurred: ${i.stderr}, stdout: ${i.stdout}`), !1;
|
|
795
809
|
const o = {
|
|
@@ -798,8 +812,8 @@ async function It(s, r, t, e) {
|
|
|
798
812
|
};
|
|
799
813
|
return o.platforma && o.minio ? !0 : (o.minio || s.warn("Minio is not running on the server"), o.platforma || s.warn("Platforma is not running on the server"), !1);
|
|
800
814
|
}
|
|
801
|
-
function
|
|
802
|
-
const c = Object.entries(
|
|
815
|
+
function Hr(s, t, r, e, i, o, n) {
|
|
816
|
+
const c = Object.entries(t).map(([h, u]) => `${h}="${u}"`).join(","), a = F(16).toString("hex"), l = r;
|
|
803
817
|
return `
|
|
804
818
|
[supervisord]
|
|
805
819
|
logfile=${e}/supervisord.log
|
|
@@ -831,21 +845,21 @@ directory=${e}
|
|
|
831
845
|
autorestart=true
|
|
832
846
|
`;
|
|
833
847
|
}
|
|
834
|
-
async function O(s,
|
|
835
|
-
const i = W(
|
|
848
|
+
async function O(s, t, r, e) {
|
|
849
|
+
const i = W(t, r), o = K(t), n = `${i} --configuration ${o} ${e}`;
|
|
836
850
|
return await s.exec(n);
|
|
837
851
|
}
|
|
838
|
-
function U(s,
|
|
852
|
+
function U(s, t) {
|
|
839
853
|
return ((i) => i.replace(/\x1B\[[0-9;]*m/g, ""))(s).split(`
|
|
840
854
|
`).some((i) => {
|
|
841
855
|
const [o, n] = i.trim().split(/\s{2,}/);
|
|
842
|
-
return o ===
|
|
856
|
+
return o === t && n === "Running";
|
|
843
857
|
});
|
|
844
858
|
}
|
|
845
859
|
class q {
|
|
846
|
-
constructor(
|
|
860
|
+
constructor(t, r, e) {
|
|
847
861
|
w(this, "initState", {});
|
|
848
|
-
this.logger =
|
|
862
|
+
this.logger = t, this.sshClient = r, this.username = e;
|
|
849
863
|
}
|
|
850
864
|
info() {
|
|
851
865
|
return {
|
|
@@ -853,141 +867,144 @@ class q {
|
|
|
853
867
|
initState: this.initState
|
|
854
868
|
};
|
|
855
869
|
}
|
|
856
|
-
static async init(
|
|
870
|
+
static async init(t, r) {
|
|
857
871
|
try {
|
|
858
|
-
const e = await x.init(
|
|
859
|
-
return new q(
|
|
872
|
+
const e = await x.init(t, r);
|
|
873
|
+
return new q(t, e, p(r.username));
|
|
860
874
|
} catch (e) {
|
|
861
|
-
throw
|
|
875
|
+
throw t.error(`Connection error in SshClient.init: ${e}`), e;
|
|
862
876
|
}
|
|
863
877
|
}
|
|
878
|
+
cleanUp() {
|
|
879
|
+
this.sshClient.close();
|
|
880
|
+
}
|
|
864
881
|
async isAlive() {
|
|
865
|
-
const
|
|
882
|
+
const t = await this.getArch(), r = await this.getUserHomeDirectory();
|
|
866
883
|
try {
|
|
867
|
-
return await
|
|
884
|
+
return await Ir(this.logger, this.sshClient, r, t.arch);
|
|
868
885
|
} catch {
|
|
869
886
|
return !1;
|
|
870
887
|
}
|
|
871
888
|
}
|
|
872
889
|
async start() {
|
|
873
|
-
const
|
|
890
|
+
const t = await this.getArch(), r = await this.getUserHomeDirectory();
|
|
874
891
|
try {
|
|
875
|
-
return await
|
|
892
|
+
return await _r(this.sshClient, r, t.arch), await this.checkIsAliveWithInterval();
|
|
876
893
|
} catch (e) {
|
|
877
894
|
const i = `ssh.start: error occurred ${e}`;
|
|
878
895
|
throw this.logger.error(i), new Error(i);
|
|
879
896
|
}
|
|
880
897
|
}
|
|
881
898
|
async stop() {
|
|
882
|
-
const
|
|
899
|
+
const t = await this.getArch(), r = await this.getUserHomeDirectory();
|
|
883
900
|
try {
|
|
884
|
-
return await
|
|
901
|
+
return await jr(this.sshClient, r, t.arch), await this.checkIsAliveWithInterval(void 0, void 0, !1);
|
|
885
902
|
} catch (e) {
|
|
886
903
|
const i = `ssh.stop: error occurred ${e}`;
|
|
887
904
|
throw this.logger.error(i), new Error(i);
|
|
888
905
|
}
|
|
889
906
|
}
|
|
890
907
|
async reset() {
|
|
891
|
-
const
|
|
892
|
-
return this.logger.info("pl.reset: Stop Platforma on the server"), await this.stop(), this.logger.info(`pl.reset: Deleting Platforma workDir ${
|
|
908
|
+
const t = await this.getUserHomeDirectory();
|
|
909
|
+
return this.logger.info("pl.reset: Stop Platforma on the server"), await this.stop(), this.logger.info(`pl.reset: Deleting Platforma workDir ${t} on the server`), await this.sshClient.deleteFolder($(t)), this.cleanUp(), !0;
|
|
893
910
|
}
|
|
894
|
-
async platformaInit(
|
|
895
|
-
const
|
|
911
|
+
async platformaInit(t) {
|
|
912
|
+
const r = { localWorkdir: t };
|
|
896
913
|
try {
|
|
897
|
-
if (
|
|
898
|
-
if (
|
|
914
|
+
if (r.arch = await this.getArch(), r.remoteHome = await this.getUserHomeDirectory(), r.isAlive = await this.isAlive(), r.isAlive) {
|
|
915
|
+
if (r.userCredentials = await this.getUserCredentials(r.remoteHome), !r.userCredentials)
|
|
899
916
|
throw new Error("SshPl.platformaInit: platforma is alive but userCredentials are not found");
|
|
900
|
-
return
|
|
917
|
+
return r.userCredentials;
|
|
901
918
|
}
|
|
902
919
|
const e = await this.downloadBinariesAndUploadToTheServer(
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
920
|
+
t,
|
|
921
|
+
r.remoteHome,
|
|
922
|
+
r.arch
|
|
906
923
|
);
|
|
907
|
-
if (
|
|
924
|
+
if (r.binPaths = { ...e, history: void 0 }, r.downloadedBinaries = e.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)
|
|
908
925
|
throw new Error("SshPl.platformaInit: remote ports are not defined");
|
|
909
|
-
const i = await
|
|
926
|
+
const i = await ar({
|
|
910
927
|
logger: this.logger,
|
|
911
|
-
workingDir: $(
|
|
928
|
+
workingDir: $(r.remoteHome),
|
|
912
929
|
portsMode: {
|
|
913
930
|
type: "customWithMinio",
|
|
914
931
|
ports: {
|
|
915
|
-
debug:
|
|
916
|
-
grpc:
|
|
917
|
-
minio:
|
|
918
|
-
minioConsole:
|
|
919
|
-
monitoring:
|
|
920
|
-
grpcLocal:
|
|
921
|
-
minioLocal:
|
|
932
|
+
debug: r.ports.debug.remote,
|
|
933
|
+
grpc: r.ports.grpc.remote,
|
|
934
|
+
minio: r.ports.minioPort.remote,
|
|
935
|
+
minioConsole: r.ports.minioConsolePort.remote,
|
|
936
|
+
monitoring: r.ports.monitoring.remote,
|
|
937
|
+
grpcLocal: r.ports.grpc.local,
|
|
938
|
+
minioLocal: r.ports.minioPort.local
|
|
922
939
|
}
|
|
923
940
|
},
|
|
924
941
|
licenseMode: {
|
|
925
942
|
type: "env"
|
|
926
943
|
}
|
|
927
944
|
});
|
|
928
|
-
|
|
945
|
+
r.generatedConfig = { ...i, filesToCreate: { skipped: "it is too wordy" } };
|
|
929
946
|
for (const [c, a] of Object.entries(i.filesToCreate))
|
|
930
947
|
await this.sshClient.writeFileOnTheServer(c, a), this.logger.info(`Created file ${c}`);
|
|
931
948
|
for (const c of i.dirsToCreate)
|
|
932
949
|
await this.sshClient.createRemoteDirectory(c), this.logger.info(`Created directory ${c}`);
|
|
933
|
-
const o =
|
|
950
|
+
const o = Hr(
|
|
934
951
|
i.minioConfig.storageDir,
|
|
935
952
|
i.minioConfig.envs,
|
|
936
|
-
await this.getFreePortForPlatformaOnServer(
|
|
953
|
+
await this.getFreePortForPlatformaOnServer(r.remoteHome, r.arch),
|
|
937
954
|
i.workingDir,
|
|
938
955
|
i.plConfig.configPath,
|
|
939
|
-
|
|
940
|
-
|
|
956
|
+
r.binPaths.minioRelPath,
|
|
957
|
+
r.binPaths.downloadedPl
|
|
941
958
|
);
|
|
942
|
-
if (!await this.sshClient.writeFileOnTheServer(K(
|
|
943
|
-
throw new Error(`Can not write supervisord config on the server ${$(
|
|
944
|
-
return
|
|
959
|
+
if (!await this.sshClient.writeFileOnTheServer(K(r.remoteHome), o))
|
|
960
|
+
throw new Error(`Can not write supervisord config on the server ${$(r.remoteHome)}`);
|
|
961
|
+
return r.connectionInfo = {
|
|
945
962
|
plUser: i.plUser,
|
|
946
963
|
plPassword: i.plPassword,
|
|
947
|
-
ports:
|
|
964
|
+
ports: r.ports
|
|
948
965
|
}, await this.sshClient.writeFileOnTheServer(
|
|
949
|
-
N(
|
|
950
|
-
JSON.stringify(
|
|
951
|
-
), await this.start(),
|
|
966
|
+
N(r.remoteHome),
|
|
967
|
+
JSON.stringify(r.connectionInfo, void 0, 2)
|
|
968
|
+
), await this.start(), r.started = !0, this.initState = r, {
|
|
952
969
|
plUser: i.plUser,
|
|
953
970
|
plPassword: i.plPassword,
|
|
954
|
-
ports:
|
|
971
|
+
ports: r.ports
|
|
955
972
|
};
|
|
956
973
|
} catch (e) {
|
|
957
|
-
const i = `SshPl.platformaInit: error occurred: ${e}, state: ${JSON.stringify(
|
|
974
|
+
const i = `SshPl.platformaInit: error occurred: ${e}, state: ${JSON.stringify(r)}`;
|
|
958
975
|
throw this.logger.error(i), new Error(i);
|
|
959
976
|
}
|
|
960
977
|
}
|
|
961
|
-
async downloadBinariesAndUploadToTheServer(
|
|
978
|
+
async downloadBinariesAndUploadToTheServer(t, r, e) {
|
|
962
979
|
const i = [];
|
|
963
980
|
try {
|
|
964
981
|
const o = await this.downloadAndUntar(
|
|
965
|
-
r,
|
|
966
982
|
t,
|
|
983
|
+
r,
|
|
967
984
|
e,
|
|
968
985
|
"pl",
|
|
969
986
|
`pl-${b()}`
|
|
970
987
|
);
|
|
971
988
|
i.push(o);
|
|
972
989
|
const n = await this.downloadAndUntar(
|
|
973
|
-
r,
|
|
974
990
|
t,
|
|
991
|
+
r,
|
|
975
992
|
e,
|
|
976
993
|
"supervisord",
|
|
977
|
-
|
|
994
|
+
kr
|
|
978
995
|
);
|
|
979
996
|
i.push(n);
|
|
980
|
-
const c =
|
|
981
|
-
r,
|
|
997
|
+
const c = Tr(r, e.arch), a = await this.downloadAndUntar(
|
|
982
998
|
t,
|
|
999
|
+
r,
|
|
983
1000
|
e,
|
|
984
1001
|
"minio",
|
|
985
|
-
|
|
1002
|
+
Or
|
|
986
1003
|
);
|
|
987
1004
|
return i.push(a), await this.sshClient.chmod(c, 488), {
|
|
988
1005
|
history: i,
|
|
989
1006
|
minioRelPath: c,
|
|
990
|
-
downloadedPl: R(
|
|
1007
|
+
downloadedPl: R(r, e.arch)
|
|
991
1008
|
};
|
|
992
1009
|
} catch (o) {
|
|
993
1010
|
const n = `SshPl.downloadBinariesAndUploadToServer: error ${o} occurred, state: ${JSON.stringify(i)}`;
|
|
@@ -998,27 +1015,27 @@ class q {
|
|
|
998
1015
|
* because Windows doesn't support symlinks
|
|
999
1016
|
* that are found in linux pl binaries tgz archive.
|
|
1000
1017
|
* For this reason, we extract all to the remote server. */
|
|
1001
|
-
async downloadAndUntar(
|
|
1018
|
+
async downloadAndUntar(t, r, e, i, o) {
|
|
1002
1019
|
const n = {};
|
|
1003
|
-
n.binBasePath = v(
|
|
1020
|
+
n.binBasePath = v(r), await this.sshClient.createRemoteDirectory(n.binBasePath), n.binBasePathCreated = !0;
|
|
1004
1021
|
let c = null;
|
|
1005
1022
|
const a = 5;
|
|
1006
1023
|
for (let h = 1; h <= a; h++)
|
|
1007
1024
|
try {
|
|
1008
|
-
c = await
|
|
1025
|
+
c = await dr(
|
|
1009
1026
|
this.logger,
|
|
1010
|
-
|
|
1027
|
+
t,
|
|
1011
1028
|
i,
|
|
1012
1029
|
o,
|
|
1013
1030
|
e.arch,
|
|
1014
1031
|
e.platform
|
|
1015
1032
|
);
|
|
1016
1033
|
break;
|
|
1017
|
-
} catch (
|
|
1034
|
+
} catch (u) {
|
|
1018
1035
|
if (await C(300), h == a)
|
|
1019
|
-
throw new Error(`downloadAndUntar: ${a} attempts, last error: ${
|
|
1036
|
+
throw new Error(`downloadAndUntar: ${a} attempts, last error: ${u}`);
|
|
1020
1037
|
}
|
|
1021
|
-
n.downloadResult =
|
|
1038
|
+
n.downloadResult = p(c), n.localArchivePath = d.resolve(n.downloadResult.archivePath), n.remoteDir = d.join(n.binBasePath, n.downloadResult.baseName), n.remoteArchivePath = n.remoteDir + ".tgz", await this.sshClient.createRemoteDirectory(n.remoteDir), await this.sshClient.uploadFile(n.localArchivePath, n.remoteArchivePath);
|
|
1022
1039
|
const l = await this.sshClient.exec(
|
|
1023
1040
|
`tar xvf ${n.remoteArchivePath} --directory=${n.remoteDir}`
|
|
1024
1041
|
);
|
|
@@ -1026,67 +1043,67 @@ class q {
|
|
|
1026
1043
|
throw new Error(`downloadAndUntar: untar: stderr occurred: ${l.stderr}, stdout: ${l.stdout}`);
|
|
1027
1044
|
return n.plUntarDone = !0, n;
|
|
1028
1045
|
}
|
|
1029
|
-
async needDownload(
|
|
1030
|
-
const e = W(
|
|
1046
|
+
async needDownload(t, r) {
|
|
1047
|
+
const e = W(t, r.arch), i = z(t, r.arch), o = R(t, r.arch);
|
|
1031
1048
|
return !await this.sshClient.checkFileExists(o) || !await this.sshClient.checkFileExists(i) || !await this.sshClient.checkFileExists(e);
|
|
1032
1049
|
}
|
|
1033
|
-
async checkIsAliveWithInterval(
|
|
1034
|
-
const i =
|
|
1050
|
+
async checkIsAliveWithInterval(t = 1e3, r = 15, e = !0) {
|
|
1051
|
+
const i = r * t;
|
|
1035
1052
|
let o = 0, n = await this.isAlive();
|
|
1036
1053
|
for (; e ? !n : n; ) {
|
|
1037
|
-
if (await C(
|
|
1054
|
+
if (await C(t), o += t, o > i)
|
|
1038
1055
|
throw new Error(`isAliveWithInterval: The process did not ${e ? "started" : "stopped"} after ${i} ms.`);
|
|
1039
1056
|
n = await this.isAlive();
|
|
1040
1057
|
}
|
|
1041
1058
|
}
|
|
1042
|
-
async getUserCredentials(
|
|
1043
|
-
const
|
|
1044
|
-
return JSON.parse(
|
|
1059
|
+
async getUserCredentials(t) {
|
|
1060
|
+
const r = await this.sshClient.readFile(N(t));
|
|
1061
|
+
return JSON.parse(r);
|
|
1045
1062
|
}
|
|
1046
|
-
async fetchPorts(
|
|
1063
|
+
async fetchPorts(t, r) {
|
|
1047
1064
|
return {
|
|
1048
1065
|
grpc: {
|
|
1049
1066
|
local: await y(),
|
|
1050
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1067
|
+
remote: await this.getFreePortForPlatformaOnServer(t, r)
|
|
1051
1068
|
},
|
|
1052
1069
|
monitoring: {
|
|
1053
1070
|
local: await y(),
|
|
1054
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1071
|
+
remote: await this.getFreePortForPlatformaOnServer(t, r)
|
|
1055
1072
|
},
|
|
1056
1073
|
debug: {
|
|
1057
1074
|
local: await y(),
|
|
1058
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1075
|
+
remote: await this.getFreePortForPlatformaOnServer(t, r)
|
|
1059
1076
|
},
|
|
1060
1077
|
minioPort: {
|
|
1061
1078
|
local: await y(),
|
|
1062
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1079
|
+
remote: await this.getFreePortForPlatformaOnServer(t, r)
|
|
1063
1080
|
},
|
|
1064
1081
|
minioConsolePort: {
|
|
1065
1082
|
local: await y(),
|
|
1066
|
-
remote: await this.getFreePortForPlatformaOnServer(
|
|
1083
|
+
remote: await this.getFreePortForPlatformaOnServer(t, r)
|
|
1067
1084
|
}
|
|
1068
1085
|
};
|
|
1069
1086
|
}
|
|
1070
1087
|
async getLocalFreePort() {
|
|
1071
|
-
return new Promise((
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
const e =
|
|
1075
|
-
|
|
1088
|
+
return new Promise((t) => {
|
|
1089
|
+
const r = B.createServer();
|
|
1090
|
+
r.listen(0, () => {
|
|
1091
|
+
const e = r.address().port;
|
|
1092
|
+
r.close((i) => t(e));
|
|
1076
1093
|
});
|
|
1077
1094
|
});
|
|
1078
1095
|
}
|
|
1079
|
-
async getFreePortForPlatformaOnServer(
|
|
1080
|
-
const e =
|
|
1096
|
+
async getFreePortForPlatformaOnServer(t, r) {
|
|
1097
|
+
const e = Ur(t, r.arch), { stdout: i, stderr: o } = await this.sshClient.exec(`${e}`);
|
|
1081
1098
|
if (o)
|
|
1082
1099
|
throw new Error(`getFreePortForPlatformaOnServer: stderr is not empty: ${o}, stdout: ${i}`);
|
|
1083
1100
|
return +i;
|
|
1084
1101
|
}
|
|
1085
1102
|
async getArch() {
|
|
1086
|
-
const { stdout:
|
|
1087
|
-
if (
|
|
1088
|
-
throw new Error(`getArch: stderr is not empty: ${
|
|
1089
|
-
const e =
|
|
1103
|
+
const { stdout: t, stderr: r } = await this.sshClient.exec("uname -s && uname -m");
|
|
1104
|
+
if (r)
|
|
1105
|
+
throw new Error(`getArch: stderr is not empty: ${r}, stdout: ${t}`);
|
|
1106
|
+
const e = t.split(`
|
|
1090
1107
|
`);
|
|
1091
1108
|
return {
|
|
1092
1109
|
platform: e[0],
|
|
@@ -1094,20 +1111,20 @@ class q {
|
|
|
1094
1111
|
};
|
|
1095
1112
|
}
|
|
1096
1113
|
async getUserHomeDirectory() {
|
|
1097
|
-
const { stdout:
|
|
1098
|
-
if (
|
|
1114
|
+
const { stdout: t, stderr: r } = await this.sshClient.exec("echo $HOME");
|
|
1115
|
+
if (r) {
|
|
1099
1116
|
const e = `/home/${this.username}`;
|
|
1100
|
-
return console.warn(`getUserHomeDirectory: stderr is not empty: ${
|
|
1117
|
+
return console.warn(`getUserHomeDirectory: stderr is not empty: ${r}, stdout: ${t}, will get a default home: ${e}`), e;
|
|
1101
1118
|
}
|
|
1102
|
-
return
|
|
1119
|
+
return t.trim();
|
|
1103
1120
|
}
|
|
1104
1121
|
}
|
|
1105
1122
|
export {
|
|
1106
|
-
|
|
1107
|
-
|
|
1123
|
+
Er as LocalConfigYaml,
|
|
1124
|
+
Fr as LocalPl,
|
|
1108
1125
|
x as SshClient,
|
|
1109
1126
|
q as SshPl,
|
|
1110
1127
|
b as getDefaultPlVersion,
|
|
1111
|
-
|
|
1128
|
+
it as localPlatformaInit
|
|
1112
1129
|
};
|
|
1113
1130
|
//# sourceMappingURL=index.mjs.map
|