ramm 0.0.23 → 0.0.25
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/ramm.js +60 -52
- package/dist/types/base/base.d.ts +18 -0
- package/dist/types/base/tee.d.ts +3 -0
- package/dist/types/debug.d.ts +1 -1
- package/dist/types/ramm.d.ts +1 -1
- package/package.json +1 -1
package/dist/ramm.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// src/base.ts
|
|
2
|
+
// src/base/base.ts
|
|
3
3
|
var {spawn } = globalThis.Bun;
|
|
4
4
|
|
|
5
5
|
// src/debug.ts
|
|
6
6
|
var debugInternal = (func, command) => {
|
|
7
7
|
console.info(`>>>${func}<<< ${command}`);
|
|
8
8
|
};
|
|
9
|
-
var debugSilentCommand = (command) => {
|
|
10
|
-
debugInternal("\x1B[32mCommand (silent)\x1B[0m", `\x1B[38;5;85m${command}\x1B[0m`);
|
|
11
|
-
};
|
|
12
9
|
var debugCommand = (command) => {
|
|
13
|
-
debugInternal("
|
|
10
|
+
debugInternal(">>>\x1B[32mCommand\x1B[0m<<<", `\x1B[38;5;85m${command}\x1B[0m`);
|
|
11
|
+
};
|
|
12
|
+
var debugApiCall = (command) => {
|
|
13
|
+
debugInternal(">>>\x1B[32mapi command\x1B[0m<<<", `\x1B[38;5;85m${command}\x1B[0m`);
|
|
14
14
|
};
|
|
15
15
|
var debugBlock = (text) => {
|
|
16
16
|
debugInternal("\x1B[34mBlock\x1B[0m", `\x1B[38;5;81m${text}\x1B[0m`);
|
|
@@ -42,13 +42,7 @@ class Context {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// src/base.ts
|
|
46
|
-
var defaultContext = new Context({
|
|
47
|
-
name: "root",
|
|
48
|
-
address: "0.0.0.0",
|
|
49
|
-
userspace: false,
|
|
50
|
-
sudo: false
|
|
51
|
-
});
|
|
45
|
+
// src/base/tee.ts
|
|
52
46
|
var tee = async (read) => {
|
|
53
47
|
const reader = read.getReader();
|
|
54
48
|
let output = "";
|
|
@@ -75,19 +69,15 @@ var teeErr = async (read) => {
|
|
|
75
69
|
process.stderr.write(value);
|
|
76
70
|
}
|
|
77
71
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
output += decoder.decode(value);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
var execCommand = async (command) => {
|
|
72
|
+
|
|
73
|
+
// src/base/base.ts
|
|
74
|
+
var defaultContext = new Context({
|
|
75
|
+
name: "root",
|
|
76
|
+
address: "0.0.0.0",
|
|
77
|
+
userspace: false,
|
|
78
|
+
sudo: false
|
|
79
|
+
});
|
|
80
|
+
var execCommandMayError = async (command) => {
|
|
91
81
|
debugCommand(command);
|
|
92
82
|
const result = spawn(["bash", "-c", command], {
|
|
93
83
|
stdin: "inherit",
|
|
@@ -105,15 +95,14 @@ var execCommand = async (command) => {
|
|
|
105
95
|
spawnResult: result
|
|
106
96
|
};
|
|
107
97
|
};
|
|
108
|
-
var
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
};
|
|
98
|
+
var execCommand = async (command) => {
|
|
99
|
+
const result = await execCommandMayError(command);
|
|
100
|
+
if (result.spawnResult.exitCode !== 0) {
|
|
101
|
+
console.error(">>>Error<<<");
|
|
102
|
+
console.error("command:", command);
|
|
103
|
+
throw new Error(command);
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
117
106
|
};
|
|
118
107
|
var copyFilesBySsh = async (from, to, context) => {
|
|
119
108
|
await execCommand(`rsync -avz ${from} ${context.getAddress()}:${to}`);
|
|
@@ -136,7 +125,7 @@ var {$ } = globalThis.Bun;
|
|
|
136
125
|
var installSystemPackage = async (packageName) => {
|
|
137
126
|
const osName = (await $`cat /etc/os-release | grep ^ID= | cut -d'=' -f2`.text()).trim();
|
|
138
127
|
if (osName === "ubuntu") {
|
|
139
|
-
await
|
|
128
|
+
await execCommandMayError(`apt-get install -y ${packageName}`);
|
|
140
129
|
}
|
|
141
130
|
};
|
|
142
131
|
|
|
@@ -162,7 +151,7 @@ var restartSystemdService = async (name, constext = defaultContext) => {
|
|
|
162
151
|
await execCommand(formatUserspace(constext, `systemctl restart ${name}`));
|
|
163
152
|
};
|
|
164
153
|
var checkSystemdService = async (context, serviceName) => {
|
|
165
|
-
const { spawnResult } = await
|
|
154
|
+
const { spawnResult } = await execCommandMayError(formatUserspace(context, `systemctl is-active ${serviceName}`));
|
|
166
155
|
return spawnResult.exitCode === 0;
|
|
167
156
|
};
|
|
168
157
|
var createSystemdService = async (context, serviceName, pathToServiceFile) => {
|
|
@@ -182,6 +171,10 @@ var installPodman = async () => {
|
|
|
182
171
|
};
|
|
183
172
|
var createNetwork = async () => {
|
|
184
173
|
const netwroks = await execCommand("podman network inspect $(podman network ls -q) -f '{{.NetworkInterface}}'");
|
|
174
|
+
const podmanNetworks = await execCommand("podman network ls");
|
|
175
|
+
if (podmanNetworks.output.includes("ramm")) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
185
178
|
if (netwroks.output.includes("podman_ramm")) {
|
|
186
179
|
return;
|
|
187
180
|
}
|
|
@@ -247,7 +240,7 @@ var createNftTable = (allowed_ssh_ipv4) => {
|
|
|
247
240
|
return nftTable;
|
|
248
241
|
};
|
|
249
242
|
var setupNftable = async (allowedIpSsh) => {
|
|
250
|
-
const listTable = await
|
|
243
|
+
const listTable = await execCommand("nft list table inet ramm");
|
|
251
244
|
if (listTable.spawnResult.exitCode === 0) {
|
|
252
245
|
await execCommand("nft delete table inet ramm");
|
|
253
246
|
}
|
|
@@ -287,6 +280,7 @@ var normalizeFileContent = (str) => {
|
|
|
287
280
|
};
|
|
288
281
|
var createDir = async (str) => {
|
|
289
282
|
const dirname = str.split("/").slice(0, -1).join("/");
|
|
283
|
+
debugApiCall(`exists(${dirname})`);
|
|
290
284
|
const exist = await exists(dirname);
|
|
291
285
|
if (exist) {
|
|
292
286
|
return;
|
|
@@ -295,9 +289,11 @@ var createDir = async (str) => {
|
|
|
295
289
|
};
|
|
296
290
|
var checkStrInFile = async (filePath, str) => {
|
|
297
291
|
const file2 = Bun.file(filePath);
|
|
292
|
+
debugApiCall(`file(${filePath}).exists())`);
|
|
298
293
|
if (!await file2.exists()) {
|
|
299
294
|
return false;
|
|
300
295
|
}
|
|
296
|
+
debugApiCall(`file(${filePath}).text()`);
|
|
301
297
|
const fileText = await file2.text();
|
|
302
298
|
if (fileText.includes(str)) {
|
|
303
299
|
return true;
|
|
@@ -307,7 +303,8 @@ var checkStrInFile = async (filePath, str) => {
|
|
|
307
303
|
var createFileIfNeed = async (rawFilePath) => {
|
|
308
304
|
const filePath = normalizePath(rawFilePath);
|
|
309
305
|
await createDir(filePath);
|
|
310
|
-
|
|
306
|
+
debugApiCall(`file(${filePath}).exists())`);
|
|
307
|
+
if (!await file(filePath).exists()) {
|
|
311
308
|
await execCommand(`touch ${filePath}`);
|
|
312
309
|
}
|
|
313
310
|
};
|
|
@@ -317,24 +314,29 @@ var writeIfNew = async (rawFilePath, str) => {
|
|
|
317
314
|
if (await checkStrInFile(filePath, str)) {
|
|
318
315
|
return;
|
|
319
316
|
}
|
|
317
|
+
debugApiCall(`appendFile(${filePath})`);
|
|
320
318
|
await appendFile(filePath, normalizeFileContent(str));
|
|
321
319
|
};
|
|
322
320
|
var writeFile = async (pathToFile, str) => {
|
|
323
321
|
const normalizedPath = normalizePath(pathToFile);
|
|
324
322
|
await createFileIfNeed(normalizedPath);
|
|
323
|
+
debugApiCall(`write(${normalizedPath})`);
|
|
325
324
|
await write(normalizedPath, str);
|
|
326
325
|
};
|
|
327
326
|
var writeFileIfNotMatch = async (pathToFile, str) => {
|
|
328
327
|
const normalizedPath = normalizePath(pathToFile);
|
|
329
328
|
await createFileIfNeed(normalizedPath);
|
|
329
|
+
debugApiCall(`file(${normalizedPath}).text()`);
|
|
330
330
|
const fileText = await file(normalizedPath).text();
|
|
331
331
|
if (fileText === str) {
|
|
332
332
|
return;
|
|
333
333
|
}
|
|
334
|
+
debugApiCall(`write(${normalizedPath})`);
|
|
334
335
|
await write(normalizedPath, str);
|
|
335
336
|
};
|
|
336
337
|
// src/ssh.ts
|
|
337
338
|
import { debug } from "console";
|
|
339
|
+
var {file: file2 } = globalThis.Bun;
|
|
338
340
|
var addKeyToHostConfig = async (pathToHost, address, pathToKey) => {
|
|
339
341
|
const text = `Host ${address}
|
|
340
342
|
IdentityFile ${pathToKey}
|
|
@@ -349,14 +351,17 @@ async function createSshKey(pathToKey, comment) {
|
|
|
349
351
|
const name = pathToKey.split("/").at(-1);
|
|
350
352
|
const pathToKeyPub = `${pathToKey}.pub`;
|
|
351
353
|
const pathToDir = pathToKey.split("/").slice(0, -1).join("/");
|
|
352
|
-
const pathToKeyFile =
|
|
353
|
-
const pathToKeyPubFile =
|
|
354
|
+
const pathToKeyFile = file2(pathToKey);
|
|
355
|
+
const pathToKeyPubFile = file2(pathToKeyPub);
|
|
356
|
+
debugApiCall(`file(${pathToKey}).exist()`);
|
|
357
|
+
debugApiCall(`file(${pathToKeyPub}).exist()`);
|
|
354
358
|
if (await pathToKeyFile.exists() && await pathToKeyPubFile.exists()) {
|
|
355
359
|
return await pathToKeyPubFile.text();
|
|
356
360
|
}
|
|
357
361
|
await execCommand(`mkdir -p ${pathToDir}`);
|
|
358
362
|
await execCommand(`ssh-keygen -t ed25519 -f ${pathToKey} -N "" -C "${comment || name}"`);
|
|
359
363
|
await execCommand(`chmod 600 ${pathToKey}`);
|
|
364
|
+
debugApiCall(`file(${pathToKeyPub}).text()`);
|
|
360
365
|
const pubKey = await Bun.file(pathToKeyPub).text();
|
|
361
366
|
return pubKey;
|
|
362
367
|
}
|
|
@@ -379,8 +384,8 @@ var createCron = async ({
|
|
|
379
384
|
}) => {
|
|
380
385
|
const pathToFileNorm = normalizePath(pathToFile);
|
|
381
386
|
const constructedLine = `${time} ${pathToFileNorm}`;
|
|
382
|
-
const tempFile = `/tmp/
|
|
383
|
-
const { output: cronConfig } = await
|
|
387
|
+
const tempFile = `/tmp/ramm_cron}`;
|
|
388
|
+
const { output: cronConfig } = await execCommandMayError("crontab -l");
|
|
384
389
|
let newCronConfig = cronConfig;
|
|
385
390
|
if (cronConfig.includes(constructedLine)) {
|
|
386
391
|
return;
|
|
@@ -392,12 +397,12 @@ var createCron = async ({
|
|
|
392
397
|
}
|
|
393
398
|
newCronConfig = normalizeFileContent(normalizeFileContent(cronConfig) + constructedLine);
|
|
394
399
|
await writeFile(tempFile, newCronConfig);
|
|
395
|
-
await
|
|
396
|
-
await
|
|
397
|
-
await
|
|
400
|
+
await execCommandMayError(`cat ${tempFile}`);
|
|
401
|
+
await execCommandMayError(`crontab ${tempFile}`);
|
|
402
|
+
await execCommandMayError(`rm ${tempFile}`);
|
|
398
403
|
};
|
|
399
404
|
// src/build.ts
|
|
400
|
-
var {build, file:
|
|
405
|
+
var {build, file: file3 } = globalThis.Bun;
|
|
401
406
|
var buildAndRunOverSsh = async ({
|
|
402
407
|
entrypoint,
|
|
403
408
|
context
|
|
@@ -416,15 +421,18 @@ var buildAndRunOverSsh = async ({
|
|
|
416
421
|
await execBySsh(`bun run ${distDir}/${relativePathToFile}`, context);
|
|
417
422
|
await execCommand(`rm -rf ${distDir}`);
|
|
418
423
|
};
|
|
424
|
+
var pathToJson = "/tmp/ramm_json";
|
|
419
425
|
var passVarsClient = async (data, context) => {
|
|
420
426
|
const json = JSON.stringify(data);
|
|
421
|
-
|
|
422
|
-
await
|
|
423
|
-
await
|
|
427
|
+
debugApiCall(`writeFile(${pathToJson})`);
|
|
428
|
+
await writeFile(pathToJson, json);
|
|
429
|
+
await copyFilesBySsh(pathToJson, pathToJson, context);
|
|
430
|
+
await execCommand(`rm -rf ${pathToJson}`);
|
|
424
431
|
};
|
|
425
432
|
var passVarsServer = async () => {
|
|
426
|
-
|
|
427
|
-
await
|
|
433
|
+
debugApiCall(`file(${pathToJson}).json`);
|
|
434
|
+
const jsonData = await file3(pathToJson).json();
|
|
435
|
+
await execCommand(`rm -rf ${pathToJson}`);
|
|
428
436
|
return jsonData;
|
|
429
437
|
};
|
|
430
438
|
export {
|
|
@@ -444,7 +452,7 @@ export {
|
|
|
444
452
|
installPodman,
|
|
445
453
|
installBun,
|
|
446
454
|
getServerFingerprintBySsh,
|
|
447
|
-
execCommand,
|
|
455
|
+
execCommandMayError as execCommand,
|
|
448
456
|
execBySsh,
|
|
449
457
|
debugBlock,
|
|
450
458
|
createCron,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context } from "../context.ts";
|
|
2
|
+
export declare const defaultContext: Context;
|
|
3
|
+
export declare const execCommandMayError: (command: string) => Promise<{
|
|
4
|
+
outputErr: string;
|
|
5
|
+
output: string;
|
|
6
|
+
spawnResult: import("bun").Subprocess<"inherit", "pipe", "pipe">;
|
|
7
|
+
}>;
|
|
8
|
+
export declare const execCommand: (command: string) => Promise<{
|
|
9
|
+
outputErr: string;
|
|
10
|
+
output: string;
|
|
11
|
+
spawnResult: import("bun").Subprocess<"inherit", "pipe", "pipe">;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const copyFilesBySsh: (from: string, to: string, context: Context) => Promise<void>;
|
|
14
|
+
export declare const execBySsh: (command: string, context: Context) => Promise<{
|
|
15
|
+
outputErr: string;
|
|
16
|
+
output: string;
|
|
17
|
+
spawnResult: import("bun").Subprocess<"inherit", "pipe", "pipe">;
|
|
18
|
+
}>;
|
package/dist/types/debug.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const debugSilentCommand: (command: string) => void;
|
|
2
1
|
export declare const debugCommand: (command: string) => void;
|
|
2
|
+
export declare const debugApiCall: (command: string) => void;
|
|
3
3
|
export declare const debugBlock: (text: string) => void;
|
|
4
4
|
export declare const debug: (text: string) => void;
|
package/dist/types/ramm.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { execBySsh, execCommand, copyFilesBySsh } from "./base.ts";
|
|
1
|
+
export { execBySsh, execCommandMayError as execCommand, copyFilesBySsh, } from "./base/base.ts";
|
|
2
2
|
export { Context } from "./context.ts";
|
|
3
3
|
export { installBun } from "./init.ts";
|
|
4
4
|
export { installPodman, runPodmanContainer, loginPodman } from "./podman.ts";
|
package/package.json
CHANGED