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