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