unitup 0.0.9 → 0.0.10
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/README.md +395 -180
- package/docs/index.html +531 -0
- package/index.d.ts +133 -152
- package/package.json +4 -1
- package/src/cli.js +254 -53
- package/src/doctor.js +73 -14
- package/src/index.js +16 -1
- package/src/runtimes/bun.js +46 -0
- package/src/runtimes/common.js +73 -0
- package/src/runtimes/deno.js +46 -0
- package/src/runtimes/elixir.js +46 -0
- package/src/runtimes/go.js +46 -0
- package/src/runtimes/index.js +155 -0
- package/src/runtimes/native.js +38 -0
- package/src/runtimes/node.js +57 -0
- package/src/runtimes/php.js +46 -0
- package/src/runtimes/python.js +46 -0
- package/src/runtimes/ruby.js +46 -0
- package/src/runtimes/shell.js +46 -0
- package/src/systemd.js +221 -28
- package/src/unit.js +59 -21
- package/src/utils.js +139 -4
package/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* unitup -
|
|
2
|
+
* unitup - Systemd user service manager for any executable & runtime
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { ChildProcess } from 'node:child_process';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Options for creating/adding a
|
|
8
|
+
* Options for creating/adding a systemd user service.
|
|
9
9
|
*/
|
|
10
10
|
export interface CreateServiceOptions {
|
|
11
11
|
/**
|
|
12
|
-
* Name of the service (e.g., 'api' or '
|
|
12
|
+
* Name of the service (e.g., 'api' or 'worker').
|
|
13
13
|
* Safe characters: lowercase letters, numbers, hyphens, underscores.
|
|
14
14
|
*/
|
|
15
15
|
name: string;
|
|
@@ -21,9 +21,24 @@ export interface CreateServiceOptions {
|
|
|
21
21
|
group?: string;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Target runtime name (e.g. 'node', 'python', 'ruby', 'php', 'bun', 'deno', 'shell', 'go', 'elixir', 'native').
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
runtime?: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Runtime-specific flags/arguments passed before script (e.g. ['--allow-net'] for Deno or ['-S', '0.0.0.0:8080'] for PHP).
|
|
30
|
+
*/
|
|
31
|
+
runtimeArgs?: string[];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Explicit executable command binary path (bypasses runtime auto-detection).
|
|
35
|
+
*/
|
|
36
|
+
command?: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Absolute or relative path to the target script file.
|
|
40
|
+
*/
|
|
41
|
+
script?: string;
|
|
27
42
|
|
|
28
43
|
/**
|
|
29
44
|
* Working directory path for the service execution (defaults to script directory).
|
|
@@ -31,7 +46,7 @@ export interface CreateServiceOptions {
|
|
|
31
46
|
cwd?: string;
|
|
32
47
|
|
|
33
48
|
/**
|
|
34
|
-
* Absolute path to explicit Node.js executable binary (
|
|
49
|
+
* Absolute path to explicit Node.js executable binary (legacy support).
|
|
35
50
|
*/
|
|
36
51
|
nodePath?: string;
|
|
37
52
|
|
|
@@ -52,7 +67,7 @@ export interface CreateServiceOptions {
|
|
|
52
67
|
restart?: string;
|
|
53
68
|
|
|
54
69
|
/**
|
|
55
|
-
* Positional arguments to pass to the script execution line.
|
|
70
|
+
* Positional arguments to pass to the script/command execution line.
|
|
56
71
|
*/
|
|
57
72
|
args?: string[];
|
|
58
73
|
|
|
@@ -61,6 +76,47 @@ export interface CreateServiceOptions {
|
|
|
61
76
|
* @default false
|
|
62
77
|
*/
|
|
63
78
|
start?: boolean;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Soft memory limit directive (e.g. '400M').
|
|
82
|
+
*/
|
|
83
|
+
memoryHigh?: string;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Hard memory limit directive (e.g. '512M').
|
|
87
|
+
*/
|
|
88
|
+
memoryMax?: string;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Swap memory limit directive (e.g. '256M').
|
|
92
|
+
*/
|
|
93
|
+
memorySwapMax?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Options for setting or resetting service memory limits.
|
|
98
|
+
*/
|
|
99
|
+
export interface ServiceLimitsOptions {
|
|
100
|
+
/**
|
|
101
|
+
* Soft memory limit directive (e.g. '400M').
|
|
102
|
+
*/
|
|
103
|
+
memoryHigh?: string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Hard memory limit directive (e.g. '512M').
|
|
107
|
+
*/
|
|
108
|
+
memoryMax?: string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Swap memory limit directive (e.g. '256M').
|
|
112
|
+
*/
|
|
113
|
+
memorySwapMax?: string;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Resets all memory limits back to defaults/infinity.
|
|
117
|
+
* @default false
|
|
118
|
+
*/
|
|
119
|
+
resetMemory?: boolean;
|
|
64
120
|
}
|
|
65
121
|
|
|
66
122
|
/**
|
|
@@ -140,6 +196,21 @@ export interface ServiceStatus {
|
|
|
140
196
|
*/
|
|
141
197
|
startedRaw?: string;
|
|
142
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Executable command path.
|
|
201
|
+
*/
|
|
202
|
+
command: string;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Command arguments string.
|
|
206
|
+
*/
|
|
207
|
+
arguments: string;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Array of command arguments.
|
|
211
|
+
*/
|
|
212
|
+
args: string[];
|
|
213
|
+
|
|
143
214
|
/**
|
|
144
215
|
* Path to target script parsed from unit file.
|
|
145
216
|
*/
|
|
@@ -160,6 +231,11 @@ export interface ListServiceItem {
|
|
|
160
231
|
*/
|
|
161
232
|
name: string;
|
|
162
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Runtime name.
|
|
236
|
+
*/
|
|
237
|
+
runtime: string;
|
|
238
|
+
|
|
163
239
|
/**
|
|
164
240
|
* Group name.
|
|
165
241
|
*/
|
|
@@ -180,6 +256,11 @@ export interface ListServiceItem {
|
|
|
180
256
|
*/
|
|
181
257
|
pid: string;
|
|
182
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Command summary (e.g. 'node server.js' or 'python3 worker.py').
|
|
261
|
+
*/
|
|
262
|
+
command: string;
|
|
263
|
+
|
|
183
264
|
/**
|
|
184
265
|
* Formatted uptime string.
|
|
185
266
|
*/
|
|
@@ -197,6 +278,9 @@ export interface ListServiceItem {
|
|
|
197
278
|
export interface AppMetadata {
|
|
198
279
|
name: string;
|
|
199
280
|
unit: string;
|
|
281
|
+
runtime?: string;
|
|
282
|
+
command?: string;
|
|
283
|
+
args?: string[];
|
|
200
284
|
group: string;
|
|
201
285
|
script: string;
|
|
202
286
|
cwd: string;
|
|
@@ -208,18 +292,30 @@ export interface AppMetadata {
|
|
|
208
292
|
*/
|
|
209
293
|
export interface InspectInfo {
|
|
210
294
|
name: string;
|
|
295
|
+
runtime: string;
|
|
211
296
|
unit: string;
|
|
212
297
|
unitPath: string;
|
|
213
298
|
group: string;
|
|
214
|
-
script: string;
|
|
215
|
-
cwd: string;
|
|
216
|
-
node: string;
|
|
217
299
|
status: string;
|
|
218
300
|
activeState: string;
|
|
219
301
|
subState: string;
|
|
302
|
+
command: string;
|
|
303
|
+
arguments: string;
|
|
304
|
+
args: string[];
|
|
305
|
+
cwd: string;
|
|
220
306
|
pid: string;
|
|
221
307
|
restarts: string;
|
|
222
308
|
started: string;
|
|
309
|
+
|
|
310
|
+
memory?: string;
|
|
311
|
+
memoryPeak?: string;
|
|
312
|
+
memoryHigh?: string;
|
|
313
|
+
memoryMax?: string;
|
|
314
|
+
memorySwapMax?: string;
|
|
315
|
+
|
|
316
|
+
// Legacy compatibility fields
|
|
317
|
+
script?: string;
|
|
318
|
+
node?: string;
|
|
223
319
|
}
|
|
224
320
|
|
|
225
321
|
/**
|
|
@@ -238,44 +334,13 @@ export interface FailureItem {
|
|
|
238
334
|
* Diagnostic results for Node.js runtime environment.
|
|
239
335
|
*/
|
|
240
336
|
export interface NodeDiagnostics {
|
|
241
|
-
/**
|
|
242
|
-
* True if Node.js binary was found.
|
|
243
|
-
*/
|
|
244
337
|
found: boolean;
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* True if Node.js binary is executable and runs -v.
|
|
248
|
-
*/
|
|
249
338
|
executable: boolean;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Resolved Node.js executable path.
|
|
253
|
-
*/
|
|
254
339
|
execPath: string;
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Path returned by which/where node.
|
|
258
|
-
*/
|
|
259
340
|
whichPath: string;
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Node.js version string (e.g. 'v20.11.0').
|
|
263
|
-
*/
|
|
264
341
|
version: string;
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* True if node binary is in system PATH environment.
|
|
268
|
-
*/
|
|
269
342
|
inPath: boolean;
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Diagnostic error message if check failed.
|
|
273
|
-
*/
|
|
274
343
|
error: string | null;
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Troubleshooting solution recommendation.
|
|
278
|
-
*/
|
|
279
344
|
solution: string | null;
|
|
280
345
|
}
|
|
281
346
|
|
|
@@ -283,59 +348,21 @@ export interface NodeDiagnostics {
|
|
|
283
348
|
* Diagnostic report object from unitup doctor.
|
|
284
349
|
*/
|
|
285
350
|
export interface DoctorInfo {
|
|
286
|
-
/**
|
|
287
|
-
* True if OS is Linux.
|
|
288
|
-
*/
|
|
289
351
|
linux: boolean;
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* True if systemctl binary is found in PATH.
|
|
293
|
-
*/
|
|
294
352
|
systemctl: boolean;
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* True if systemd is running as PID 1.
|
|
298
|
-
*/
|
|
299
353
|
systemdRunning: boolean;
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* True if systemd user session bus is accessible.
|
|
303
|
-
*/
|
|
304
354
|
userSystemdAvailable: boolean;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
355
|
+
cgroupV2?: boolean;
|
|
356
|
+
memoryController?: boolean;
|
|
357
|
+
memoryMaxSupported?: boolean;
|
|
358
|
+
memorySwapMaxSupported?: boolean;
|
|
309
359
|
nodeDiag: NodeDiagnostics;
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Resolved Node.js executable path.
|
|
313
|
-
*/
|
|
314
360
|
nodePath: string;
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Node.js version string.
|
|
318
|
-
*/
|
|
319
361
|
nodeVersion: string;
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Systemd user unit directory path.
|
|
323
|
-
*/
|
|
362
|
+
runtimes: Record<string, string | null>;
|
|
324
363
|
unitDir: string;
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* True if unit directory is writable.
|
|
328
|
-
*/
|
|
329
364
|
unitDirWritable: boolean;
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* True if user lingering is enabled (loginctl enable-linger).
|
|
333
|
-
*/
|
|
334
365
|
lingering: boolean;
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Current OS username.
|
|
338
|
-
*/
|
|
339
366
|
username: string;
|
|
340
367
|
}
|
|
341
368
|
|
|
@@ -343,14 +370,7 @@ export interface DoctorInfo {
|
|
|
343
370
|
* Result returned when creating/adding a new unitup service.
|
|
344
371
|
*/
|
|
345
372
|
export interface AddServiceResult {
|
|
346
|
-
/**
|
|
347
|
-
* Cleaned service name.
|
|
348
|
-
*/
|
|
349
373
|
name: string;
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Path to created unit file.
|
|
353
|
-
*/
|
|
354
374
|
unitPath: string;
|
|
355
375
|
}
|
|
356
376
|
|
|
@@ -358,9 +378,14 @@ export interface AddServiceResult {
|
|
|
358
378
|
* Parsed systemd unit file content metadata.
|
|
359
379
|
*/
|
|
360
380
|
export interface ParsedUnitContent {
|
|
381
|
+
command?: string;
|
|
382
|
+
args?: string[];
|
|
361
383
|
script?: string;
|
|
362
384
|
cwd?: string;
|
|
363
385
|
restart?: string;
|
|
386
|
+
memoryHigh?: string;
|
|
387
|
+
memoryMax?: string;
|
|
388
|
+
memorySwapMax?: string;
|
|
364
389
|
}
|
|
365
390
|
|
|
366
391
|
/**
|
|
@@ -376,74 +401,36 @@ export type CommandRunnerFn = (
|
|
|
376
401
|
// Programmatic API Function Declarations
|
|
377
402
|
// ---------------------------------------------------------------------------
|
|
378
403
|
|
|
379
|
-
/**
|
|
380
|
-
* Creates and writes a systemd user service unit file, then reloads the systemd daemon.
|
|
381
|
-
*/
|
|
382
404
|
export function createService(options: CreateServiceOptions): Promise<AddServiceResult>;
|
|
383
405
|
export function addService(options: CreateServiceOptions): Promise<AddServiceResult>;
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Starts a systemd user service unit.
|
|
387
|
-
* @param name Service name (e.g. 'api')
|
|
388
|
-
* @param enable If true, enables the service on boot (--enable)
|
|
389
|
-
*/
|
|
390
406
|
export function startService(name: string, enable?: boolean): Promise<boolean>;
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Stops a running systemd user service unit.
|
|
394
|
-
*/
|
|
395
407
|
export function stopService(name: string): Promise<boolean>;
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Restarts a systemd user service unit.
|
|
399
|
-
*/
|
|
400
408
|
export function restartService(name: string): Promise<boolean>;
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Stops, disables, and deletes a systemd user service unit file, then reloads daemon.
|
|
404
|
-
*/
|
|
405
409
|
export function removeService(name: string): Promise<boolean>;
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Retrieves compact parsed status information for a service.
|
|
409
|
-
*/
|
|
410
410
|
export function getServiceStatus(name: string): Promise<ServiceStatus>;
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Retrieves raw string output of systemctl --user status.
|
|
414
|
-
*/
|
|
415
411
|
export function getServiceStatusRaw(name: string): Promise<string>;
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Lists all unitup-*.service user units.
|
|
419
|
-
* Optionally filter by group name.
|
|
420
|
-
*/
|
|
421
412
|
export function listServices(options?: { group?: string }): Promise<ListServiceItem[]>;
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Inspects a service's configuration and status (unitup inspect).
|
|
425
|
-
*/
|
|
426
413
|
export function inspectService(name: string): Promise<InspectInfo>;
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Retrieves all currently failed services (unitup failures).
|
|
430
|
-
*/
|
|
431
414
|
export function getServiceFailures(): Promise<FailureItem[]>;
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Returns array of service names belonging to a group (@groupName).
|
|
435
|
-
*/
|
|
436
415
|
export function getServicesByGroup(groupName: string): Promise<string[]>;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
* Fetches or streams journalctl logs for a service.
|
|
440
|
-
*/
|
|
416
|
+
export function setServiceLimits(name: string, options?: ServiceLimitsOptions): Promise<InspectInfo>;
|
|
417
|
+
export function executeJournalctlMaintenance(action: string, options?: Record<string, unknown>): Promise<string>;
|
|
441
418
|
export function getServiceLogs(name: string, options?: LogOptions): Promise<string | ChildProcess>;
|
|
442
419
|
|
|
443
|
-
//
|
|
444
|
-
|
|
445
|
-
|
|
420
|
+
// Validation & Formatting Helpers
|
|
421
|
+
export function validateMemorySize(val: string | number, paramName?: string): string;
|
|
422
|
+
export function formatMemoryBytes(bytes: number | string): string;
|
|
446
423
|
|
|
424
|
+
// Runtime Helpers
|
|
425
|
+
export function detectRuntime(filepath: string): string;
|
|
426
|
+
export function resolveRuntimeConfig(options: CreateServiceOptions): Promise<{
|
|
427
|
+
command: string;
|
|
428
|
+
args: string[];
|
|
429
|
+
runtime: string;
|
|
430
|
+
version: string;
|
|
431
|
+
}>;
|
|
432
|
+
|
|
433
|
+
// Diagnostics & Doctor
|
|
447
434
|
export function isSystemdAvailable(): Promise<boolean>;
|
|
448
435
|
export function isSystemctlAvailable(): Promise<boolean>;
|
|
449
436
|
export function isLinux(): boolean;
|
|
@@ -454,10 +441,7 @@ export function checkNodeDiagnostics(customNodePath?: string): Promise<NodeDiagn
|
|
|
454
441
|
export function findNodeExecutable(customPath?: string): Promise<string | null>;
|
|
455
442
|
export function getDoctorInfo(): Promise<DoctorInfo>;
|
|
456
443
|
|
|
457
|
-
//
|
|
458
|
-
// Unit File & Path Helpers
|
|
459
|
-
// ---------------------------------------------------------------------------
|
|
460
|
-
|
|
444
|
+
// Path & Unit Helpers
|
|
461
445
|
export function getUserUnitDir(): string;
|
|
462
446
|
export function getUnitPath(name: string): string;
|
|
463
447
|
export function unitFileExists(name: string): boolean;
|
|
@@ -470,9 +454,6 @@ export function getAppMetadataPath(name: string): string;
|
|
|
470
454
|
export function getAppsDir(): string;
|
|
471
455
|
export function getUnitupDir(): string;
|
|
472
456
|
|
|
473
|
-
//
|
|
474
|
-
// Runner Override Helpers for Testing
|
|
475
|
-
// ---------------------------------------------------------------------------
|
|
476
|
-
|
|
457
|
+
// Testing Mock Helpers
|
|
477
458
|
export function setCommandRunner(runner: CommandRunnerFn): void;
|
|
478
459
|
export function resetCommandRunner(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unitup",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Minimal systemd user service wrapper for Node.js scripts",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"test": "node --test test/*.test.js"
|
|
13
13
|
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"typescript": "^5.7.3"
|
|
16
|
+
},
|
|
14
17
|
"keywords": [
|
|
15
18
|
"systemd",
|
|
16
19
|
"service",
|