ramm 0.0.22 → 0.0.24

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 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("\x1B[32mCommand\x1B[0m", `\x1B[38;5;85m${command}\x1B[0m`);
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
- var readStreamToStr = async (read) => {
79
- const reader = read.getReader();
80
- let output = "";
81
- while (true) {
82
- const { value, done: doneReading } = await reader.read();
83
- if (doneReading) {
84
- return output;
85
- }
86
- const decoder = new TextDecoder("utf-8");
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 execCommandSilent = async (command) => {
109
- debugSilentCommand(command);
110
- const result = spawn(["bash", "-c", command]);
111
- const output = await readStreamToStr(result.stdout);
112
- await result.exited;
113
- return {
114
- output,
115
- spawnResult: result
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 execCommand(`apt-get install -y ${packageName}`);
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 execCommand(formatUserspace(context, `systemctl is-active ${serviceName}`));
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) => {
@@ -191,6 +180,9 @@ var getCreateCommand = async (name) => {
191
180
  const podmanCreateCommand = await $2`podman inspect --format '{{.Config.CreateCommand}}' ${name}`.nothrow().quiet();
192
181
  return podmanCreateCommand.text().slice(0, -1).slice(1, -1) || "";
193
182
  };
183
+ var loginPodman = async (address, login, password) => {
184
+ return await execCommand(`echo "${password}" | podman login --username "${login}" --password-stdin ${address}`);
185
+ };
194
186
  var runPodmanContainer = async (name, command) => {
195
187
  if (await getCreateCommand(name) !== command) {
196
188
  await $2`podman rm -f ${name}`;
@@ -244,7 +236,7 @@ var createNftTable = (allowed_ssh_ipv4) => {
244
236
  return nftTable;
245
237
  };
246
238
  var setupNftable = async (allowedIpSsh) => {
247
- const listTable = await execCommandSilent("nft list table inet ramm");
239
+ const listTable = await execCommand("nft list table inet ramm");
248
240
  if (listTable.spawnResult.exitCode === 0) {
249
241
  await execCommand("nft delete table inet ramm");
250
242
  }
@@ -284,6 +276,7 @@ var normalizeFileContent = (str) => {
284
276
  };
285
277
  var createDir = async (str) => {
286
278
  const dirname = str.split("/").slice(0, -1).join("/");
279
+ debugApiCall(`exists(${dirname})`);
287
280
  const exist = await exists(dirname);
288
281
  if (exist) {
289
282
  return;
@@ -292,9 +285,11 @@ var createDir = async (str) => {
292
285
  };
293
286
  var checkStrInFile = async (filePath, str) => {
294
287
  const file2 = Bun.file(filePath);
288
+ debugApiCall(`file(${filePath}).exists())`);
295
289
  if (!await file2.exists()) {
296
290
  return false;
297
291
  }
292
+ debugApiCall(`file(${filePath}).text()`);
298
293
  const fileText = await file2.text();
299
294
  if (fileText.includes(str)) {
300
295
  return true;
@@ -304,7 +299,8 @@ var checkStrInFile = async (filePath, str) => {
304
299
  var createFileIfNeed = async (rawFilePath) => {
305
300
  const filePath = normalizePath(rawFilePath);
306
301
  await createDir(filePath);
307
- if (!await Bun.file(filePath).exists()) {
302
+ debugApiCall(`file(${filePath}).exists())`);
303
+ if (!await file(filePath).exists()) {
308
304
  await execCommand(`touch ${filePath}`);
309
305
  }
310
306
  };
@@ -314,24 +310,29 @@ var writeIfNew = async (rawFilePath, str) => {
314
310
  if (await checkStrInFile(filePath, str)) {
315
311
  return;
316
312
  }
313
+ debugApiCall(`appendFile(${filePath})`);
317
314
  await appendFile(filePath, normalizeFileContent(str));
318
315
  };
319
316
  var writeFile = async (pathToFile, str) => {
320
317
  const normalizedPath = normalizePath(pathToFile);
321
318
  await createFileIfNeed(normalizedPath);
319
+ debugApiCall(`write(${normalizedPath})`);
322
320
  await write(normalizedPath, str);
323
321
  };
324
322
  var writeFileIfNotMatch = async (pathToFile, str) => {
325
323
  const normalizedPath = normalizePath(pathToFile);
326
324
  await createFileIfNeed(normalizedPath);
325
+ debugApiCall(`file(${normalizedPath}).text()`);
327
326
  const fileText = await file(normalizedPath).text();
328
327
  if (fileText === str) {
329
328
  return;
330
329
  }
330
+ debugApiCall(`write(${normalizedPath})`);
331
331
  await write(normalizedPath, str);
332
332
  };
333
333
  // src/ssh.ts
334
334
  import { debug } from "console";
335
+ var {file: file2 } = globalThis.Bun;
335
336
  var addKeyToHostConfig = async (pathToHost, address, pathToKey) => {
336
337
  const text = `Host ${address}
337
338
  IdentityFile ${pathToKey}
@@ -346,14 +347,17 @@ async function createSshKey(pathToKey, comment) {
346
347
  const name = pathToKey.split("/").at(-1);
347
348
  const pathToKeyPub = `${pathToKey}.pub`;
348
349
  const pathToDir = pathToKey.split("/").slice(0, -1).join("/");
349
- const pathToKeyFile = Bun.file(pathToKey);
350
- const pathToKeyPubFile = Bun.file(pathToKeyPub);
350
+ const pathToKeyFile = file2(pathToKey);
351
+ const pathToKeyPubFile = file2(pathToKeyPub);
352
+ debugApiCall(`file(${pathToKey}).exist()`);
353
+ debugApiCall(`file(${pathToKeyPub}).exist()`);
351
354
  if (await pathToKeyFile.exists() && await pathToKeyPubFile.exists()) {
352
355
  return await pathToKeyPubFile.text();
353
356
  }
354
357
  await execCommand(`mkdir -p ${pathToDir}`);
355
358
  await execCommand(`ssh-keygen -t ed25519 -f ${pathToKey} -N "" -C "${comment || name}"`);
356
359
  await execCommand(`chmod 600 ${pathToKey}`);
360
+ debugApiCall(`file(${pathToKeyPub}).text()`);
357
361
  const pubKey = await Bun.file(pathToKeyPub).text();
358
362
  return pubKey;
359
363
  }
@@ -376,8 +380,8 @@ var createCron = async ({
376
380
  }) => {
377
381
  const pathToFileNorm = normalizePath(pathToFile);
378
382
  const constructedLine = `${time} ${pathToFileNorm}`;
379
- const tempFile = `/tmp/cron_${new Date().getTime().toString()}`;
380
- const { output: cronConfig } = await execCommand("crontab -l");
383
+ const tempFile = `/tmp/ramm_cron}`;
384
+ const { output: cronConfig } = await execCommandMayError("crontab -l");
381
385
  let newCronConfig = cronConfig;
382
386
  if (cronConfig.includes(constructedLine)) {
383
387
  return;
@@ -389,12 +393,12 @@ var createCron = async ({
389
393
  }
390
394
  newCronConfig = normalizeFileContent(normalizeFileContent(cronConfig) + constructedLine);
391
395
  await writeFile(tempFile, newCronConfig);
392
- await execCommand(`cat ${tempFile}`);
393
- await execCommand(`crontab ${tempFile}`);
394
- await execCommand(`rm ${tempFile}`);
396
+ await execCommandMayError(`cat ${tempFile}`);
397
+ await execCommandMayError(`crontab ${tempFile}`);
398
+ await execCommandMayError(`rm ${tempFile}`);
395
399
  };
396
400
  // src/build.ts
397
- var {build, file: file2 } = globalThis.Bun;
401
+ var {build, file: file3 } = globalThis.Bun;
398
402
  var buildAndRunOverSsh = async ({
399
403
  entrypoint,
400
404
  context
@@ -413,15 +417,18 @@ var buildAndRunOverSsh = async ({
413
417
  await execBySsh(`bun run ${distDir}/${relativePathToFile}`, context);
414
418
  await execCommand(`rm -rf ${distDir}`);
415
419
  };
420
+ var pathToJson = "/tmp/ramm_json";
416
421
  var passVarsClient = async (data, context) => {
417
422
  const json = JSON.stringify(data);
418
- await writeFile("/tmp/ramm_json", json);
419
- await copyFilesBySsh("/tmp/ramm_json", "/tmp/ramm_json", context);
420
- await execCommand("rm -rf /tmp/ramm_json");
423
+ debugApiCall(`writeFile(${pathToJson})`);
424
+ await writeFile(pathToJson, json);
425
+ await copyFilesBySsh(pathToJson, pathToJson, context);
426
+ await execCommand(`rm -rf ${pathToJson}`);
421
427
  };
422
428
  var passVarsServer = async () => {
423
- const jsonData = await file2("/tmp/ramm_json").json();
424
- await execCommand("rm -rf /tmp/ramm_json");
429
+ debugApiCall(`file(${pathToJson}).json`);
430
+ const jsonData = await file3(pathToJson).json();
431
+ await execCommand(`rm -rf ${pathToJson}`);
425
432
  return jsonData;
426
433
  };
427
434
  export {
@@ -436,11 +443,12 @@ export {
436
443
  passVarsClient,
437
444
  normalizePath,
438
445
  normalizeFileContent,
446
+ loginPodman,
439
447
  installSystemPackage,
440
448
  installPodman,
441
449
  installBun,
442
450
  getServerFingerprintBySsh,
443
- execCommand,
451
+ execCommandMayError as execCommand,
444
452
  execBySsh,
445
453
  debugBlock,
446
454
  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
+ }>;
@@ -0,0 +1,3 @@
1
+ export declare const tee: (read: ReadableStream) => Promise<string>;
2
+ export declare const teeErr: (read: ReadableStream) => Promise<string>;
3
+ export declare const readStreamToStr: (read: ReadableStream) => Promise<string>;
@@ -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;
@@ -1,6 +1,11 @@
1
1
  import type { Context } from "./context.ts";
2
2
  export declare const installPodman: () => Promise<void>;
3
3
  export declare const getCreateCommand: (name: string) => Promise<string>;
4
+ export declare const loginPodman: (address: string, login: string, password: string) => Promise<{
5
+ outputErr: string;
6
+ output: string;
7
+ spawnResult: import("bun").Subprocess<"inherit", "pipe", "pipe">;
8
+ }>;
4
9
  export declare const runPodmanContainer: (name: string, command: string) => Promise<void>;
5
10
  export declare const runPodmanContainerService: (name: string, command: string, context?: Context) => Promise<void>;
6
11
  export declare const addNftPodmanRule: () => Promise<void>;
@@ -1,7 +1,7 @@
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
- export { installPodman, runPodmanContainer } from "./podman.ts";
4
+ export { installPodman, runPodmanContainer, loginPodman } from "./podman.ts";
5
5
  export { runPodmanContainerService, addNftPodmanRule } from "./podman.ts";
6
6
  export { restartSystemdService } from "./systemd.ts";
7
7
  export { installSystemPackage } from "./packages.ts";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ramm",
3
3
  "type": "module",
4
- "version": "0.0.22",
4
+ "version": "0.0.24",
5
5
  "scripts": {
6
6
  "build": "bun build ./src/ramm.ts --target bun --outdir ./dist && cp ./src/bun.sh ./dist/bun.sh && bun run types",
7
7
  "types": "tsc --project tsconfig.types.json"