@ulyssedu45/service_api 1.0.5 → 1.1.1
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 +47 -25
- package/package.json +3 -1
- package/src/linux.d.ts +4 -7
- package/src/linux.d.ts.map +1 -1
- package/src/linux.js +233 -79
- package/src/linux.js.map +1 -1
- package/test/service.test.js +290 -154
- package/test/service.test.js.map +1 -1
package/README.md
CHANGED
|
@@ -4,10 +4,10 @@ Cross-platform Node.js library to **check the existence and status of OS service
|
|
|
4
4
|
|
|
5
5
|
**The same code runs unchanged on Windows and Linux** — the library selects the correct OS backend automatically. No `if (platform === 'win32')` guards are needed in your application.
|
|
6
6
|
|
|
7
|
-
| Platform | Backend
|
|
8
|
-
| ----------- |
|
|
9
|
-
| **Windows** | `advapi32.dll` — calls the Windows Service Control Manager (SCM) directly via [koffi](https://koffi.dev/) FFI bindings. No PowerShell, no `sc.exe`.
|
|
10
|
-
| **Linux** |
|
|
7
|
+
| Platform | Backend |
|
|
8
|
+
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| **Windows** | `advapi32.dll` — calls the Windows Service Control Manager (SCM) directly via [koffi](https://koffi.dev/) FFI bindings. No PowerShell, no `sc.exe`. |
|
|
10
|
+
| **Linux** | Auto-detected native backend. See table below. |
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -49,7 +49,7 @@ console.log(status);
|
|
|
49
49
|
| Platform | Name to use | Examples |
|
|
50
50
|
| -------- | -------------------------------------- | ------------------------------------ |
|
|
51
51
|
| Windows | Short service name | `"wuauserv"`, `"spooler"`, `"W3SVC"` |
|
|
52
|
-
| Linux |
|
|
52
|
+
| Linux | Service unit name (without `.service` for systemd) | `"nginx"`, `"sshd"`, `"cron"` |
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -105,17 +105,6 @@ for (const s of results) {
|
|
|
105
105
|
}
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
### Runnable demo
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
# Uses a sensible default service for the current OS
|
|
112
|
-
node examples/check-service.js
|
|
113
|
-
|
|
114
|
-
# Pass any service name as an argument
|
|
115
|
-
node examples/check-service.js nginx # Linux
|
|
116
|
-
node examples/check-service.js spooler # Windows
|
|
117
|
-
```
|
|
118
|
-
|
|
119
108
|
---
|
|
120
109
|
|
|
121
110
|
## API
|
|
@@ -143,18 +132,51 @@ Returns a `ServiceStatus` object:
|
|
|
143
132
|
|
|
144
133
|
### State values
|
|
145
134
|
|
|
146
|
-
| `state` |
|
|
147
|
-
| ------------------ | --------------------- | ------------------------ |
|
|
148
|
-
| `RUNNING` | `active` | `4` (SERVICE_RUNNING) |
|
|
149
|
-
| `STOPPED` | `inactive` / `failed` | `1` (SERVICE_STOPPED) |
|
|
150
|
-
| `START_PENDING` | `activating` | `2` |
|
|
151
|
-
| `STOP_PENDING` | `deactivating` | `3` |
|
|
152
|
-
| `CONTINUE_PENDING` | `reloading` | `5` |
|
|
153
|
-
| `PAUSE_PENDING` | — | `6` |
|
|
154
|
-
| `PAUSED` | — | `7` |
|
|
135
|
+
| `state` | systemd (ActiveState) | OpenRC | Windows (dwCurrentState) |
|
|
136
|
+
| ------------------ | --------------------- | --------------------------- | ------------------------ |
|
|
137
|
+
| `RUNNING` | `active` | started | `4` (SERVICE_RUNNING) |
|
|
138
|
+
| `STOPPED` | `inactive` / `failed` | not started | `1` (SERVICE_STOPPED) |
|
|
139
|
+
| `START_PENDING` | `activating` | starting | `2` |
|
|
140
|
+
| `STOP_PENDING` | `deactivating` | stopping | `3` |
|
|
141
|
+
| `CONTINUE_PENDING` | `reloading` | — | `5` |
|
|
142
|
+
| `PAUSE_PENDING` | — | — | `6` |
|
|
143
|
+
| `PAUSED` | — | — | `7` |
|
|
155
144
|
|
|
156
145
|
---
|
|
157
146
|
|
|
147
|
+
## How it works on Linux
|
|
148
|
+
|
|
149
|
+
The Linux backend is selected automatically at runtime.
|
|
150
|
+
|
|
151
|
+
| Init system | Distros | Detection | API used |
|
|
152
|
+
| ----------- | ------------------------------------------ | ---------------------------------- | --------------------------------------------------------------------------- |
|
|
153
|
+
| **systemd** | Ubuntu, Debian, Fedora, RHEL, Arch, SUSE… | `/run/systemd/private` exists | `libsystemd.so.0` via koffi (sd_bus D-Bus), with `systemctl` CLI fallback |
|
|
154
|
+
| **OpenRC** | Alpine, Gentoo, Artix… | `/run/openrc/softlevel` exists | `/run/openrc/started/` filesystem reads |
|
|
155
|
+
| **SysV** | legacy Debian, RHEL 6, embedded… | `/etc/init.d/` exists | `/etc/init.d/` + `/proc/<pid>` reads |
|
|
156
|
+
|
|
157
|
+
### systemd backend (koffi + libsystemd)
|
|
158
|
+
|
|
159
|
+
Uses [koffi](https://koffi.dev/) to call `libsystemd.so.0` directly — the same library that `systemctl` uses internally:
|
|
160
|
+
|
|
161
|
+
1. **`sd_bus_open_system`** — opens a connection to the D-Bus system bus.
|
|
162
|
+
2. **`sd_bus_get_property_string`** — reads `LoadState`, `ActiveState`, `SubState`, `MainPID` from the `org.freedesktop.systemd1.Unit` D-Bus interface.
|
|
163
|
+
3. **`sd_bus_unref`** — releases the bus connection.
|
|
164
|
+
|
|
165
|
+
If `libsystemd.so.0` is not available (containers, musl builds without systemd), the backend falls back to `systemctl show` CLI parsing, then to SysV-style checks via `/proc`.
|
|
166
|
+
|
|
167
|
+
### OpenRC backend (Alpine, Gentoo)
|
|
168
|
+
|
|
169
|
+
Pure filesystem reads — no library, no binary:
|
|
170
|
+
|
|
171
|
+
- **Existence**: `/etc/init.d/<name>` present
|
|
172
|
+
- **State**: `/run/openrc/started/<name>` → `RUNNING` · `/run/openrc/starting/<name>` → `START_PENDING` · `/run/openrc/stopping/<name>` → `STOP_PENDING`
|
|
173
|
+
- **PID**: `/run/<name>.pid` or `/var/run/<name>.pid`
|
|
174
|
+
|
|
175
|
+
### SysV backend (legacy systems)
|
|
176
|
+
|
|
177
|
+
- **Existence**: `/etc/init.d/<name>` present
|
|
178
|
+
- **Running**: PID file read + `/proc/<pid>` existence check
|
|
179
|
+
|
|
158
180
|
## How it works on Windows
|
|
159
181
|
|
|
160
182
|
The library uses [koffi](https://koffi.dev/) to call `advapi32.dll` functions directly from Node.js — no PowerShell, no `sc.exe`, no child processes:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulyssedu45/service_api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Cross-platform Node.js library to check Windows/Linux service existence and status via native OS APIs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"service",
|
|
14
14
|
"linux",
|
|
15
15
|
"systemd",
|
|
16
|
+
"openrc",
|
|
17
|
+
"sysv",
|
|
16
18
|
"scm",
|
|
17
19
|
"winapi",
|
|
18
20
|
"ffi"
|
package/src/linux.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Linux implementation of service_api.
|
|
3
|
-
* Uses systemctl (systemd) to query service status, with a fallback to
|
|
4
|
-
* the legacy SysV `service` command for non-systemd systems.
|
|
5
|
-
*/
|
|
6
1
|
import { ServiceStatus } from './types';
|
|
2
|
+
type InitSystem = 'systemd' | 'openrc' | 'sysv';
|
|
3
|
+
export declare function detectInitSystem(): InitSystem;
|
|
7
4
|
/**
|
|
8
5
|
* Checks whether a Linux service exists.
|
|
9
6
|
*
|
|
10
7
|
* @param serviceName - The service name (e.g. "nginx", "sshd").
|
|
11
|
-
* @returns Resolves to `true` if the service is known.
|
|
12
|
-
* @throws If the service manager cannot be contacted.
|
|
8
|
+
* @returns Resolves to `true` if the service is known to the init system.
|
|
13
9
|
*/
|
|
14
10
|
export declare function serviceExists(serviceName: string): Promise<boolean>;
|
|
15
11
|
/**
|
|
@@ -20,4 +16,5 @@ export declare function serviceExists(serviceName: string): Promise<boolean>;
|
|
|
20
16
|
* @throws If the service does not exist or cannot be queried.
|
|
21
17
|
*/
|
|
22
18
|
export declare function getServiceStatus(serviceName: string): Promise<ServiceStatus>;
|
|
19
|
+
export {};
|
|
23
20
|
//# sourceMappingURL=linux.d.ts.map
|
package/src/linux.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linux.d.ts","sourceRoot":"","sources":["../../src/linux.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"linux.d.ts","sourceRoot":"","sources":["../../src/linux.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA4BxC,KAAK,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhD,wBAAgB,gBAAgB,IAAI,UAAU,CAQ7C;AAgKD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCzE;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmDlF"}
|
package/src/linux.js
CHANGED
|
@@ -1,29 +1,54 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.detectInitSystem = detectInitSystem;
|
|
3
7
|
exports.serviceExists = serviceExists;
|
|
4
8
|
exports.getServiceStatus = getServiceStatus;
|
|
5
9
|
/**
|
|
6
|
-
*
|
|
10
|
+
* Linux implementation of service_api.
|
|
11
|
+
* Uses three native backends in cascade:
|
|
12
|
+
* 1. systemd — libsystemd.so.0 via koffi (D-Bus sd_bus), with systemctl CLI fallback
|
|
13
|
+
* 2. OpenRC — pure filesystem reads (/run/openrc/…)
|
|
14
|
+
* 3. SysV — /etc/init.d/ + /proc/<pid>
|
|
7
15
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const child_process_1 = require("child_process");
|
|
18
|
+
// ─── Filesystem helpers ───────────────────────────────────────────────────────
|
|
19
|
+
function fsExistsSync(p) {
|
|
20
|
+
try {
|
|
21
|
+
fs_1.default.accessSync(p);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function readPidFile(...paths) {
|
|
29
|
+
for (const p of paths) {
|
|
30
|
+
try {
|
|
31
|
+
const raw = fs_1.default.readFileSync(p, 'utf8').trim();
|
|
32
|
+
const pid = parseInt(raw, 10);
|
|
33
|
+
if (pid > 0)
|
|
34
|
+
return pid;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// try next
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
function detectInitSystem() {
|
|
43
|
+
if (fsExistsSync('/run/systemd/private') || fsExistsSync('/sys/fs/cgroup/systemd')) {
|
|
44
|
+
return 'systemd';
|
|
45
|
+
}
|
|
46
|
+
if (fsExistsSync('/run/openrc/softlevel') || fsExistsSync('/run/openrc')) {
|
|
47
|
+
return 'openrc';
|
|
48
|
+
}
|
|
49
|
+
return 'sysv';
|
|
21
50
|
}
|
|
22
51
|
// ─── Systemd state map ────────────────────────────────────────────────────────
|
|
23
|
-
/**
|
|
24
|
-
* Maps systemctl ActiveState values to the canonical state strings used
|
|
25
|
-
* by service_api (mirrors Windows SERVICE_STATES for a consistent API).
|
|
26
|
-
*/
|
|
27
52
|
const SYSTEMD_STATE_MAP = {
|
|
28
53
|
active: 'RUNNING',
|
|
29
54
|
activating: 'START_PENDING',
|
|
@@ -32,80 +57,157 @@ const SYSTEMD_STATE_MAP = {
|
|
|
32
57
|
failed: 'STOPPED',
|
|
33
58
|
reloading: 'CONTINUE_PENDING'
|
|
34
59
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
let _libsystemd = null;
|
|
61
|
+
let _libsystemdAvailable = null;
|
|
62
|
+
function tryLoadLibsystemd() {
|
|
63
|
+
if (_libsystemdAvailable !== null)
|
|
64
|
+
return _libsystemdAvailable;
|
|
40
65
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
66
|
+
const koffi = require('koffi');
|
|
67
|
+
const lib = koffi.load('libsystemd.so.0');
|
|
68
|
+
_libsystemd = {
|
|
69
|
+
sd_bus_open_system: lib.func('int sd_bus_open_system(void **ret)'),
|
|
70
|
+
sd_bus_get_property_string: lib.func('int sd_bus_get_property_string(void *bus, str dest, str path, str iface, str member, void **error, char **ret)'),
|
|
71
|
+
sd_bus_unref: lib.func('void *sd_bus_unref(void *bus)')
|
|
72
|
+
};
|
|
73
|
+
_libsystemdAvailable = true;
|
|
43
74
|
}
|
|
44
75
|
catch {
|
|
45
|
-
|
|
76
|
+
_libsystemdAvailable = false;
|
|
46
77
|
}
|
|
78
|
+
return _libsystemdAvailable;
|
|
47
79
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
80
|
+
const SYSTEMD_DEST = 'org.freedesktop.systemd1';
|
|
81
|
+
const UNIT_IFACE = 'org.freedesktop.systemd1.Unit';
|
|
82
|
+
function unitObjectPath(serviceName) {
|
|
83
|
+
const unit = serviceName.includes('.') ? serviceName : `${serviceName}.service`;
|
|
84
|
+
const encoded = Array.from(unit).map(c => {
|
|
85
|
+
if (/[A-Za-z0-9]/.test(c))
|
|
86
|
+
return c;
|
|
87
|
+
return `_${c.charCodeAt(0).toString(16).padStart(2, '0')}`;
|
|
88
|
+
}).join('');
|
|
89
|
+
return `/org/freedesktop/systemd1/unit/${encoded}`;
|
|
90
|
+
}
|
|
91
|
+
function queryLibsystemd(serviceName) {
|
|
92
|
+
const lib = _libsystemd;
|
|
93
|
+
const busRef = [null];
|
|
94
|
+
if (lib.sd_bus_open_system(busRef) < 0 || busRef[0] === null) {
|
|
95
|
+
throw new Error('sd_bus_open_system failed');
|
|
96
|
+
}
|
|
97
|
+
const bus = busRef[0];
|
|
98
|
+
const path = unitObjectPath(serviceName);
|
|
99
|
+
function getProp(member) {
|
|
100
|
+
const retRef = [null];
|
|
101
|
+
const r = lib.sd_bus_get_property_string(bus, SYSTEMD_DEST, path, UNIT_IFACE, member, [null], retRef);
|
|
102
|
+
if (r < 0)
|
|
103
|
+
return '';
|
|
104
|
+
return retRef[0] ? String(retRef[0]) : '';
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const loadState = getProp('LoadState');
|
|
108
|
+
const activeState = getProp('ActiveState');
|
|
109
|
+
const subState = getProp('SubState');
|
|
110
|
+
const mainPidStr = getProp('MainPID');
|
|
111
|
+
return {
|
|
112
|
+
loadState,
|
|
113
|
+
activeState,
|
|
114
|
+
subState,
|
|
115
|
+
mainPid: parseInt(mainPidStr, 10) || 0
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
lib.sd_bus_unref(bus);
|
|
64
120
|
}
|
|
65
|
-
return {
|
|
66
|
-
loadState: (props.LoadState || '').trim(),
|
|
67
|
-
activeState: (props.ActiveState || '').trim(),
|
|
68
|
-
subState: (props.SubState || '').trim(),
|
|
69
|
-
mainPid: parseInt(props.MainPID || '0', 10) || 0
|
|
70
|
-
};
|
|
71
121
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
async function querySysV(serviceName) {
|
|
122
|
+
// ─── systemd fallback — systemctl CLI ─────────────────────────────────────────
|
|
123
|
+
function querySystemctl(serviceName) {
|
|
124
|
+
const unit = serviceName.includes('.') ? serviceName : `${serviceName}.service`;
|
|
76
125
|
try {
|
|
77
|
-
|
|
78
|
-
|
|
126
|
+
const output = (0, child_process_1.execFileSync)('systemctl', ['show', unit, '--property=LoadState,ActiveState,SubState,MainPID', '--no-pager'], { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
127
|
+
const props = {};
|
|
128
|
+
for (const line of output.trim().split('\n')) {
|
|
129
|
+
const idx = line.indexOf('=');
|
|
130
|
+
if (idx > 0) {
|
|
131
|
+
props[line.slice(0, idx)] = line.slice(idx + 1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
loadState: props['LoadState'] || '',
|
|
136
|
+
activeState: props['ActiveState'] || '',
|
|
137
|
+
subState: props['SubState'] || '',
|
|
138
|
+
mainPid: parseInt(props['MainPID'] || '0', 10) || 0
|
|
139
|
+
};
|
|
79
140
|
}
|
|
80
141
|
catch {
|
|
81
|
-
|
|
142
|
+
throw new Error(`systemctl query failed for "${serviceName}"`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// ─── OpenRC backend ───────────────────────────────────────────────────────────
|
|
146
|
+
function openrcExists(serviceName) {
|
|
147
|
+
return (fsExistsSync(`/etc/init.d/${serviceName}`) ||
|
|
148
|
+
fsExistsSync(`/etc/runlevels/default/${serviceName}`));
|
|
149
|
+
}
|
|
150
|
+
function openrcState(serviceName) {
|
|
151
|
+
if (fsExistsSync(`/run/openrc/started/${serviceName}`))
|
|
152
|
+
return 'RUNNING';
|
|
153
|
+
if (fsExistsSync(`/run/openrc/starting/${serviceName}`))
|
|
154
|
+
return 'START_PENDING';
|
|
155
|
+
if (fsExistsSync(`/run/openrc/stopping/${serviceName}`))
|
|
156
|
+
return 'STOP_PENDING';
|
|
157
|
+
return 'STOPPED';
|
|
158
|
+
}
|
|
159
|
+
// ─── SysV backend ─────────────────────────────────────────────────────────────
|
|
160
|
+
function sysvExists(serviceName) {
|
|
161
|
+
return fsExistsSync(`/etc/init.d/${serviceName}`);
|
|
162
|
+
}
|
|
163
|
+
function sysvRunning(serviceName) {
|
|
164
|
+
const pid = readPidFile(`/var/run/${serviceName}.pid`, `/run/${serviceName}.pid`);
|
|
165
|
+
if (pid > 0) {
|
|
166
|
+
return { running: fsExistsSync(`/proc/${pid}`), pid };
|
|
82
167
|
}
|
|
168
|
+
const hasLock = fsExistsSync(`/var/run/${serviceName}.lock`) ||
|
|
169
|
+
fsExistsSync(`/run/${serviceName}.lock`);
|
|
170
|
+
return { running: hasLock, pid: 0 };
|
|
83
171
|
}
|
|
84
172
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
85
173
|
/**
|
|
86
174
|
* Checks whether a Linux service exists.
|
|
87
175
|
*
|
|
88
176
|
* @param serviceName - The service name (e.g. "nginx", "sshd").
|
|
89
|
-
* @returns Resolves to `true` if the service is known.
|
|
90
|
-
* @throws If the service manager cannot be contacted.
|
|
177
|
+
* @returns Resolves to `true` if the service is known to the init system.
|
|
91
178
|
*/
|
|
92
179
|
async function serviceExists(serviceName) {
|
|
93
180
|
if (!serviceName || typeof serviceName !== 'string') {
|
|
94
181
|
throw new TypeError('serviceName must be a non-empty string');
|
|
95
182
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
183
|
+
const init = detectInitSystem();
|
|
184
|
+
if (init === 'systemd') {
|
|
185
|
+
if (tryLoadLibsystemd()) {
|
|
186
|
+
try {
|
|
187
|
+
const { loadState } = queryLibsystemd(serviceName);
|
|
188
|
+
return loadState !== 'not-found' && loadState !== '';
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// fall through to SysV
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// libsystemd unavailable or query failed — try systemctl CLI
|
|
195
|
+
try {
|
|
196
|
+
const { loadState } = querySystemctl(serviceName);
|
|
197
|
+
if (loadState !== '' && loadState !== 'not-found')
|
|
198
|
+
return true;
|
|
199
|
+
// systemctl says not-found — check SysV fallback
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// systemctl unavailable — fallback to SysV
|
|
203
|
+
}
|
|
204
|
+
return sysvExists(serviceName);
|
|
105
205
|
}
|
|
106
|
-
|
|
107
|
-
return
|
|
206
|
+
if (init === 'openrc') {
|
|
207
|
+
return openrcExists(serviceName);
|
|
108
208
|
}
|
|
209
|
+
// SysV
|
|
210
|
+
return sysvExists(serviceName);
|
|
109
211
|
}
|
|
110
212
|
/**
|
|
111
213
|
* Returns the current status of a Linux service.
|
|
@@ -118,32 +220,84 @@ async function getServiceStatus(serviceName) {
|
|
|
118
220
|
if (!serviceName || typeof serviceName !== 'string') {
|
|
119
221
|
throw new TypeError('serviceName must be a non-empty string');
|
|
120
222
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
223
|
+
const init = detectInitSystem();
|
|
224
|
+
// ── systemd ────────────────────────────────────────────────────────────────
|
|
225
|
+
if (init === 'systemd') {
|
|
226
|
+
if (tryLoadLibsystemd()) {
|
|
227
|
+
let result;
|
|
228
|
+
try {
|
|
229
|
+
result = queryLibsystemd(serviceName);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// libsystemd query failed — try systemctl CLI
|
|
233
|
+
return _systemctlStatus(serviceName);
|
|
234
|
+
}
|
|
235
|
+
const { loadState, activeState, mainPid } = result;
|
|
236
|
+
if (loadState === 'not-found' || loadState === '') {
|
|
237
|
+
throw new Error(`Service "${serviceName}" does not exist`);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
name: serviceName,
|
|
241
|
+
exists: true,
|
|
242
|
+
state: SYSTEMD_STATE_MAP[activeState] || `UNKNOWN(${activeState})`,
|
|
243
|
+
pid: mainPid,
|
|
244
|
+
rawCode: activeState
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// libsystemd unavailable — try systemctl CLI
|
|
248
|
+
return _systemctlStatus(serviceName);
|
|
249
|
+
}
|
|
250
|
+
// ── OpenRC ─────────────────────────────────────────────────────────────────
|
|
251
|
+
if (init === 'openrc') {
|
|
252
|
+
if (!openrcExists(serviceName)) {
|
|
124
253
|
throw new Error(`Service "${serviceName}" does not exist`);
|
|
125
254
|
}
|
|
126
|
-
const state =
|
|
255
|
+
const state = openrcState(serviceName);
|
|
256
|
+
const pid = readPidFile(`/run/${serviceName}.pid`, `/var/run/${serviceName}.pid`);
|
|
127
257
|
return {
|
|
128
258
|
name: serviceName,
|
|
129
259
|
exists: true,
|
|
130
260
|
state,
|
|
131
|
-
pid
|
|
132
|
-
rawCode:
|
|
261
|
+
pid,
|
|
262
|
+
rawCode: state.toLowerCase()
|
|
133
263
|
};
|
|
134
264
|
}
|
|
135
|
-
// SysV
|
|
136
|
-
|
|
137
|
-
|
|
265
|
+
// ── SysV ───────────────────────────────────────────────────────────────────
|
|
266
|
+
return _sysvStatus(serviceName);
|
|
267
|
+
}
|
|
268
|
+
function _sysvStatus(serviceName) {
|
|
269
|
+
if (!sysvExists(serviceName)) {
|
|
138
270
|
throw new Error(`Service "${serviceName}" does not exist`);
|
|
139
271
|
}
|
|
140
|
-
const { running } =
|
|
272
|
+
const { running, pid } = sysvRunning(serviceName);
|
|
141
273
|
return {
|
|
142
274
|
name: serviceName,
|
|
143
275
|
exists: true,
|
|
144
276
|
state: running ? 'RUNNING' : 'STOPPED',
|
|
145
|
-
pid
|
|
277
|
+
pid,
|
|
146
278
|
rawCode: running ? 'active' : 'inactive'
|
|
147
279
|
};
|
|
148
280
|
}
|
|
281
|
+
function _systemctlStatus(serviceName) {
|
|
282
|
+
let result;
|
|
283
|
+
try {
|
|
284
|
+
result = querySystemctl(serviceName);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// systemctl unavailable — fall through to SysV
|
|
288
|
+
return _sysvStatus(serviceName);
|
|
289
|
+
}
|
|
290
|
+
const { loadState, activeState, mainPid } = result;
|
|
291
|
+
if (loadState === 'not-found' || loadState === '') {
|
|
292
|
+
// Service not known to systemd — fall through to SysV
|
|
293
|
+
return _sysvStatus(serviceName);
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
name: serviceName,
|
|
297
|
+
exists: true,
|
|
298
|
+
state: SYSTEMD_STATE_MAP[activeState] || `UNKNOWN(${activeState})`,
|
|
299
|
+
pid: mainPid,
|
|
300
|
+
rawCode: activeState
|
|
301
|
+
};
|
|
302
|
+
}
|
|
149
303
|
//# sourceMappingURL=linux.js.map
|
package/src/linux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linux.js","sourceRoot":"","sources":["../../src/linux.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"linux.js","sourceRoot":"","sources":["../../src/linux.ts"],"names":[],"mappings":"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"}
|
package/test/service.test.js
CHANGED
|
@@ -32,192 +32,328 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
/**
|
|
37
40
|
* Tests for the Linux implementation (src/linux.ts).
|
|
38
|
-
*
|
|
39
|
-
* requiring a real system service manager.
|
|
41
|
+
* Mocks fs.accessSync and fs.readFileSync to avoid requiring a real init system.
|
|
40
42
|
*/
|
|
41
43
|
const node_test_1 = require("node:test");
|
|
42
44
|
const assert = __importStar(require("node:assert/strict"));
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
45
|
+
const fs_1 = __importDefault(require("fs"));
|
|
46
|
+
// Use require to get the mutable child_process module (not a frozen __importStar wrapper)
|
|
47
|
+
const child_process = require('child_process');
|
|
48
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* Runs `fn` with fs.accessSync and fs.readFileSync patched.
|
|
51
|
+
* `existsSet` is the set of paths that "exist" (accessSync succeeds for them).
|
|
52
|
+
* `pidMap` maps pid-file paths to their string contents.
|
|
53
|
+
*
|
|
54
|
+
* NOTE: requireLinux() must be called BEFORE withFsMock so that Node.js's
|
|
55
|
+
* module loader uses the real fs to read the .js file.
|
|
56
|
+
*/
|
|
57
|
+
async function withFsMock(existsSet, pidMap, fn) {
|
|
58
|
+
const origAccess = fs_1.default.accessSync;
|
|
59
|
+
const origReadFile = fs_1.default.readFileSync;
|
|
60
|
+
fs_1.default.accessSync = (p) => {
|
|
61
|
+
if (existsSet.has(String(p)))
|
|
62
|
+
return;
|
|
63
|
+
const err = new Error(`ENOENT: ${p}`);
|
|
64
|
+
err.code = 'ENOENT';
|
|
65
|
+
throw err;
|
|
66
|
+
};
|
|
67
|
+
fs_1.default.readFileSync = (p, enc) => {
|
|
68
|
+
const key = String(p);
|
|
69
|
+
if (key in pidMap)
|
|
70
|
+
return pidMap[key];
|
|
71
|
+
const err = new Error(`ENOENT: ${p}`);
|
|
72
|
+
err.code = 'ENOENT';
|
|
73
|
+
throw err;
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
await fn();
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
fs_1.default.accessSync = origAccess;
|
|
80
|
+
fs_1.default.readFileSync = origReadFile;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Re-require linux module with a fresh cache entry. */
|
|
84
|
+
function requireLinux() {
|
|
85
|
+
delete require.cache[require.resolve('../src/linux')];
|
|
86
|
+
return require('../src/linux');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Runs `fn` with fs.accessSync, fs.readFileSync, and child_process.execSync patched.
|
|
90
|
+
* `systemctlOutput` controls what execSync returns (or throws if null).
|
|
91
|
+
*/
|
|
92
|
+
async function withFullMock(existsSet, pidMap, systemctlOutput, fn) {
|
|
93
|
+
const origAccess = fs_1.default.accessSync;
|
|
94
|
+
const origReadFile = fs_1.default.readFileSync;
|
|
95
|
+
const origExecFileSync = child_process.execFileSync;
|
|
96
|
+
fs_1.default.accessSync = (p) => {
|
|
97
|
+
if (existsSet.has(String(p)))
|
|
98
|
+
return;
|
|
99
|
+
const err = new Error(`ENOENT: ${p}`);
|
|
100
|
+
err.code = 'ENOENT';
|
|
101
|
+
throw err;
|
|
102
|
+
};
|
|
103
|
+
fs_1.default.readFileSync = (p, enc) => {
|
|
104
|
+
const key = String(p);
|
|
105
|
+
if (key in pidMap)
|
|
106
|
+
return pidMap[key];
|
|
107
|
+
const err = new Error(`ENOENT: ${p}`);
|
|
108
|
+
err.code = 'ENOENT';
|
|
109
|
+
throw err;
|
|
110
|
+
};
|
|
111
|
+
child_process.execFileSync = (_file, _args, _opts) => {
|
|
112
|
+
if (systemctlOutput === null) {
|
|
113
|
+
throw new Error('execFileSync mock: command not found');
|
|
114
|
+
}
|
|
115
|
+
return systemctlOutput;
|
|
116
|
+
};
|
|
117
|
+
try {
|
|
118
|
+
await fn();
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
fs_1.default.accessSync = origAccess;
|
|
122
|
+
fs_1.default.readFileSync = origReadFile;
|
|
123
|
+
child_process.execFileSync = origExecFileSync;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// ─── detectInitSystem ─────────────────────────────────────────────────────────
|
|
127
|
+
(0, node_test_1.describe)('Linux implementation — detectInitSystem', () => {
|
|
128
|
+
(0, node_test_1.it)('returns systemd when /run/systemd/private exists', async () => {
|
|
129
|
+
const { detectInitSystem } = requireLinux();
|
|
130
|
+
await withFsMock(new Set(['/run/systemd/private']), {}, () => {
|
|
131
|
+
assert.equal(detectInitSystem(), 'systemd');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
(0, node_test_1.it)('returns openrc when /run/openrc/softlevel exists', async () => {
|
|
135
|
+
const { detectInitSystem } = requireLinux();
|
|
136
|
+
await withFsMock(new Set(['/run/openrc/softlevel']), {}, () => {
|
|
137
|
+
assert.equal(detectInitSystem(), 'openrc');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
(0, node_test_1.it)('returns sysv when only /etc/init.d exists', async () => {
|
|
141
|
+
const { detectInitSystem } = requireLinux();
|
|
142
|
+
await withFsMock(new Set(['/etc/init.d']), {}, () => {
|
|
143
|
+
assert.equal(detectInitSystem(), 'sysv');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
// ─── serviceExists — systemd (libsystemd unavailable → SysV fallback) ─────────
|
|
148
|
+
(0, node_test_1.describe)('Linux implementation — serviceExists (systemd via libsystemd)', () => {
|
|
149
|
+
(0, node_test_1.it)('returns true when libsystemd unavailable and /etc/init.d/<name> exists (fallback SysV)', async () => {
|
|
150
|
+
const { serviceExists } = requireLinux();
|
|
151
|
+
await withFsMock(new Set(['/run/systemd/private', '/etc/init.d/nginx']), {}, async () => {
|
|
64
152
|
const result = await serviceExists('nginx');
|
|
65
153
|
assert.equal(result, true);
|
|
66
|
-
}
|
|
67
|
-
finally {
|
|
68
|
-
cp.execFile = orig;
|
|
69
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
70
|
-
}
|
|
154
|
+
});
|
|
71
155
|
});
|
|
72
|
-
(0, node_test_1.it)('returns false
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
let callCount = 0;
|
|
76
|
-
cp.execFile = function (cmd, args, opts, cb) {
|
|
77
|
-
callCount++;
|
|
78
|
-
if (callCount === 1) {
|
|
79
|
-
cb(null, 'systemd 252\n', '');
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// systemd reports not-found
|
|
83
|
-
cb(null, 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nMainPID=0\n', '');
|
|
84
|
-
}
|
|
85
|
-
return { kill: () => { } };
|
|
86
|
-
};
|
|
87
|
-
try {
|
|
88
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
89
|
-
const { serviceExists } = require('../src/linux');
|
|
156
|
+
(0, node_test_1.it)('returns false when libsystemd unavailable and /etc/init.d/<name> absent', async () => {
|
|
157
|
+
const { serviceExists } = requireLinux();
|
|
158
|
+
await withFsMock(new Set(['/run/systemd/private']), {}, async () => {
|
|
90
159
|
const result = await serviceExists('doesnotexist');
|
|
91
160
|
assert.equal(result, false);
|
|
92
|
-
}
|
|
93
|
-
finally {
|
|
94
|
-
cp.execFile = orig;
|
|
95
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
96
|
-
}
|
|
161
|
+
});
|
|
97
162
|
});
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await
|
|
163
|
+
});
|
|
164
|
+
// ─── serviceExists — OpenRC ───────────────────────────────────────────────────
|
|
165
|
+
(0, node_test_1.describe)('Linux implementation — serviceExists (OpenRC)', () => {
|
|
166
|
+
(0, node_test_1.it)('returns true when /etc/init.d/<name> exists', async () => {
|
|
167
|
+
const { serviceExists } = requireLinux();
|
|
168
|
+
await withFsMock(new Set(['/run/openrc/softlevel', '/etc/init.d/nginx']), {}, async () => {
|
|
169
|
+
assert.equal(await serviceExists('nginx'), true);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
(0, node_test_1.it)('returns false when /etc/init.d/<name> does not exist', async () => {
|
|
173
|
+
const { serviceExists } = requireLinux();
|
|
174
|
+
await withFsMock(new Set(['/run/openrc/softlevel']), {}, async () => {
|
|
175
|
+
assert.equal(await serviceExists('ghost'), false);
|
|
176
|
+
});
|
|
104
177
|
});
|
|
105
178
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
179
|
+
// ─── serviceExists — SysV ────────────────────────────────────────────────────
|
|
180
|
+
(0, node_test_1.describe)('Linux implementation — serviceExists (SysV)', () => {
|
|
181
|
+
(0, node_test_1.it)('returns true when /etc/init.d/<name> exists', async () => {
|
|
182
|
+
const { serviceExists } = requireLinux();
|
|
183
|
+
await withFsMock(new Set(['/etc/init.d/cron']), {}, async () => {
|
|
184
|
+
assert.equal(await serviceExists('cron'), true);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
(0, node_test_1.it)('returns false when /etc/init.d/<name> does not exist', async () => {
|
|
188
|
+
const { serviceExists } = requireLinux();
|
|
189
|
+
await withFsMock(new Set([]), {}, async () => {
|
|
190
|
+
assert.equal(await serviceExists('ghost'), false);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
// ─── getServiceStatus — systemd (libsystemd unavailable → SysV fallback) ──────
|
|
195
|
+
(0, node_test_1.describe)('Linux implementation — getServiceStatus (systemd via libsystemd)', () => {
|
|
196
|
+
(0, node_test_1.it)('RUNNING: /etc/init.d exists and /proc/<pid> exists (fallback SysV)', async () => {
|
|
197
|
+
const { getServiceStatus } = requireLinux();
|
|
198
|
+
await withFsMock(new Set(['/run/systemd/private', '/etc/init.d/sshd', '/proc/4321']), { '/var/run/sshd.pid': '4321\n' }, async () => {
|
|
124
199
|
const status = await getServiceStatus('sshd');
|
|
125
200
|
assert.equal(status.name, 'sshd');
|
|
126
201
|
assert.equal(status.exists, true);
|
|
127
202
|
assert.equal(status.state, 'RUNNING');
|
|
128
203
|
assert.equal(status.pid, 4321);
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
cp.execFile = orig;
|
|
133
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
134
|
-
}
|
|
204
|
+
});
|
|
135
205
|
});
|
|
136
|
-
(0, node_test_1.it)('
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
let callCount = 0;
|
|
140
|
-
cp.execFile = function (cmd, args, opts, cb) {
|
|
141
|
-
callCount++;
|
|
142
|
-
if (callCount === 1) {
|
|
143
|
-
cb(null, 'systemd 252\n', '');
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
cb(null, 'LoadState=loaded\nActiveState=inactive\nSubState=dead\nMainPID=0\n', '');
|
|
147
|
-
}
|
|
148
|
-
return { kill: () => { } };
|
|
149
|
-
};
|
|
150
|
-
try {
|
|
151
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
152
|
-
const { getServiceStatus } = require('../src/linux');
|
|
206
|
+
(0, node_test_1.it)('STOPPED: /etc/init.d exists but no pid/proc (fallback SysV)', async () => {
|
|
207
|
+
const { getServiceStatus } = requireLinux();
|
|
208
|
+
await withFsMock(new Set(['/run/systemd/private', '/etc/init.d/nginx']), {}, async () => {
|
|
153
209
|
const status = await getServiceStatus('nginx');
|
|
154
210
|
assert.equal(status.state, 'STOPPED');
|
|
155
211
|
assert.equal(status.pid, 0);
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
cp.execFile = orig;
|
|
159
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
160
|
-
}
|
|
212
|
+
});
|
|
161
213
|
});
|
|
162
|
-
(0, node_test_1.it)('
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
let callCount = 0;
|
|
166
|
-
cp.execFile = function (cmd, args, opts, cb) {
|
|
167
|
-
callCount++;
|
|
168
|
-
if (callCount === 1) {
|
|
169
|
-
cb(null, 'systemd 252\n', '');
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
cb(null, 'LoadState=loaded\nActiveState=activating\nSubState=start\nMainPID=0\n', '');
|
|
173
|
-
}
|
|
174
|
-
return { kill: () => { } };
|
|
175
|
-
};
|
|
176
|
-
try {
|
|
177
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
178
|
-
const { getServiceStatus } = require('../src/linux');
|
|
179
|
-
const status = await getServiceStatus('myservice');
|
|
180
|
-
assert.equal(status.state, 'START_PENDING');
|
|
181
|
-
}
|
|
182
|
-
finally {
|
|
183
|
-
cp.execFile = orig;
|
|
184
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
(0, node_test_1.it)('throws when the service does not exist', async () => {
|
|
188
|
-
const cp = require('child_process');
|
|
189
|
-
const orig = cp.execFile;
|
|
190
|
-
let callCount = 0;
|
|
191
|
-
cp.execFile = function (cmd, args, opts, cb) {
|
|
192
|
-
callCount++;
|
|
193
|
-
if (callCount === 1) {
|
|
194
|
-
cb(null, 'systemd 252\n', '');
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
cb(null, 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nMainPID=0\n', '');
|
|
198
|
-
}
|
|
199
|
-
return { kill: () => { } };
|
|
200
|
-
};
|
|
201
|
-
try {
|
|
202
|
-
delete require.cache[require.resolve('../src/linux')];
|
|
203
|
-
const { getServiceStatus } = require('../src/linux');
|
|
214
|
+
(0, node_test_1.it)('throws when /etc/init.d/<name> does not exist (fallback SysV)', async () => {
|
|
215
|
+
const { getServiceStatus } = requireLinux();
|
|
216
|
+
await withFsMock(new Set(['/run/systemd/private']), {}, async () => {
|
|
204
217
|
await assert.rejects(() => getServiceStatus('ghost'), (err) => err.message.includes('does not exist'));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
// ─── getServiceStatus — OpenRC ────────────────────────────────────────────────
|
|
222
|
+
(0, node_test_1.describe)('Linux implementation — getServiceStatus (OpenRC)', () => {
|
|
223
|
+
(0, node_test_1.it)('RUNNING when /run/openrc/started/<name> exists', async () => {
|
|
224
|
+
const { getServiceStatus } = requireLinux();
|
|
225
|
+
await withFsMock(new Set(['/run/openrc/softlevel', '/etc/init.d/nginx', '/run/openrc/started/nginx']), { '/run/nginx.pid': '9999\n' }, async () => {
|
|
226
|
+
const status = await getServiceStatus('nginx');
|
|
227
|
+
assert.equal(status.state, 'RUNNING');
|
|
228
|
+
assert.equal(status.pid, 9999);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
(0, node_test_1.it)('STOPPED when no openrc state files present', async () => {
|
|
232
|
+
const { getServiceStatus } = requireLinux();
|
|
233
|
+
await withFsMock(new Set(['/run/openrc/softlevel', '/etc/init.d/nginx']), {}, async () => {
|
|
234
|
+
const status = await getServiceStatus('nginx');
|
|
235
|
+
assert.equal(status.state, 'STOPPED');
|
|
236
|
+
assert.equal(status.pid, 0);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
(0, node_test_1.it)('pid read from /run/<name>.pid', async () => {
|
|
240
|
+
const { getServiceStatus } = requireLinux();
|
|
241
|
+
await withFsMock(new Set(['/run/openrc/softlevel', '/etc/init.d/sshd', '/run/openrc/started/sshd']), { '/run/sshd.pid': '1234\n' }, async () => {
|
|
242
|
+
const status = await getServiceStatus('sshd');
|
|
243
|
+
assert.equal(status.pid, 1234);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
// ─── getServiceStatus — SysV ──────────────────────────────────────────────────
|
|
248
|
+
(0, node_test_1.describe)('Linux implementation — getServiceStatus (SysV)', () => {
|
|
249
|
+
(0, node_test_1.it)('RUNNING when /etc/init.d/<name> exists and /proc/<pid> exists', async () => {
|
|
250
|
+
const { getServiceStatus } = requireLinux();
|
|
251
|
+
await withFsMock(new Set(['/etc/init.d/cron', '/proc/5678']), { '/var/run/cron.pid': '5678\n' }, async () => {
|
|
252
|
+
const status = await getServiceStatus('cron');
|
|
253
|
+
assert.equal(status.state, 'RUNNING');
|
|
254
|
+
assert.equal(status.pid, 5678);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
(0, node_test_1.it)('STOPPED when pid=0 and no lock file', async () => {
|
|
258
|
+
const { getServiceStatus } = requireLinux();
|
|
259
|
+
await withFsMock(new Set(['/etc/init.d/cron']), {}, async () => {
|
|
260
|
+
const status = await getServiceStatus('cron');
|
|
261
|
+
assert.equal(status.state, 'STOPPED');
|
|
262
|
+
assert.equal(status.pid, 0);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
// ─── TypeError guards ─────────────────────────────────────────────────────────
|
|
267
|
+
(0, node_test_1.describe)('Linux implementation — TypeError guards', () => {
|
|
268
|
+
(0, node_test_1.it)('serviceExists("") → TypeError', async () => {
|
|
269
|
+
const { serviceExists } = requireLinux();
|
|
270
|
+
await assert.rejects(() => serviceExists(''), TypeError);
|
|
271
|
+
});
|
|
272
|
+
(0, node_test_1.it)('serviceExists(null) → TypeError', async () => {
|
|
273
|
+
const { serviceExists } = requireLinux();
|
|
274
|
+
await assert.rejects(() => serviceExists(null), TypeError);
|
|
210
275
|
});
|
|
211
|
-
(0, node_test_1.it)('
|
|
212
|
-
|
|
213
|
-
const { getServiceStatus } = require('../src/linux');
|
|
276
|
+
(0, node_test_1.it)('getServiceStatus("") → TypeError', async () => {
|
|
277
|
+
const { getServiceStatus } = requireLinux();
|
|
214
278
|
await assert.rejects(() => getServiceStatus(''), TypeError);
|
|
279
|
+
});
|
|
280
|
+
(0, node_test_1.it)('getServiceStatus(undefined) → TypeError', async () => {
|
|
281
|
+
const { getServiceStatus } = requireLinux();
|
|
215
282
|
await assert.rejects(() => getServiceStatus(undefined), TypeError);
|
|
216
283
|
});
|
|
217
284
|
});
|
|
285
|
+
// ─── getServiceStatus — systemd (systemctl CLI fallback) ──────────────────────
|
|
286
|
+
(0, node_test_1.describe)('Linux implementation — getServiceStatus (systemctl CLI fallback)', () => {
|
|
287
|
+
(0, node_test_1.it)('RUNNING when systemctl reports ActiveState=active (e.g. active exited)', async () => {
|
|
288
|
+
const { getServiceStatus } = requireLinux();
|
|
289
|
+
await withFullMock(new Set(['/run/systemd/private']), {}, 'LoadState=loaded\nActiveState=active\nSubState=exited\nMainPID=0\n', async () => {
|
|
290
|
+
const status = await getServiceStatus('networking');
|
|
291
|
+
assert.equal(status.name, 'networking');
|
|
292
|
+
assert.equal(status.exists, true);
|
|
293
|
+
assert.equal(status.state, 'RUNNING');
|
|
294
|
+
assert.equal(status.pid, 0);
|
|
295
|
+
assert.equal(status.rawCode, 'active');
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
(0, node_test_1.it)('STOPPED when systemctl reports ActiveState=inactive', async () => {
|
|
299
|
+
const { getServiceStatus } = requireLinux();
|
|
300
|
+
await withFullMock(new Set(['/run/systemd/private']), {}, 'LoadState=loaded\nActiveState=inactive\nSubState=dead\nMainPID=0\n', async () => {
|
|
301
|
+
const status = await getServiceStatus('nginx');
|
|
302
|
+
assert.equal(status.state, 'STOPPED');
|
|
303
|
+
assert.equal(status.rawCode, 'inactive');
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
(0, node_test_1.it)('RUNNING with PID when systemctl reports ActiveState=active with MainPID', async () => {
|
|
307
|
+
const { getServiceStatus } = requireLinux();
|
|
308
|
+
await withFullMock(new Set(['/run/systemd/private']), {}, 'LoadState=loaded\nActiveState=active\nSubState=running\nMainPID=1234\n', async () => {
|
|
309
|
+
const status = await getServiceStatus('nginx');
|
|
310
|
+
assert.equal(status.state, 'RUNNING');
|
|
311
|
+
assert.equal(status.pid, 1234);
|
|
312
|
+
assert.equal(status.rawCode, 'active');
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
(0, node_test_1.it)('falls through to SysV when systemctl reports not-found and /etc/init.d exists', async () => {
|
|
316
|
+
const { getServiceStatus } = requireLinux();
|
|
317
|
+
await withFullMock(new Set(['/run/systemd/private', '/etc/init.d/legacy', '/proc/5555']), { '/var/run/legacy.pid': '5555\n' }, 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nMainPID=0\n', async () => {
|
|
318
|
+
const status = await getServiceStatus('legacy');
|
|
319
|
+
assert.equal(status.state, 'RUNNING');
|
|
320
|
+
assert.equal(status.pid, 5555);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
(0, node_test_1.it)('falls through to SysV when systemctl is unavailable', async () => {
|
|
324
|
+
const { getServiceStatus } = requireLinux();
|
|
325
|
+
await withFullMock(new Set(['/run/systemd/private', '/etc/init.d/myapp', '/proc/7777']), { '/var/run/myapp.pid': '7777\n' }, null, // systemctl unavailable
|
|
326
|
+
async () => {
|
|
327
|
+
const status = await getServiceStatus('myapp');
|
|
328
|
+
assert.equal(status.state, 'RUNNING');
|
|
329
|
+
assert.equal(status.pid, 7777);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
// ─── serviceExists — systemd (systemctl CLI fallback) ─────────────────────────
|
|
334
|
+
(0, node_test_1.describe)('Linux implementation — serviceExists (systemctl CLI fallback)', () => {
|
|
335
|
+
(0, node_test_1.it)('returns true when systemctl reports LoadState=loaded', async () => {
|
|
336
|
+
const { serviceExists } = requireLinux();
|
|
337
|
+
await withFullMock(new Set(['/run/systemd/private']), {}, 'LoadState=loaded\nActiveState=active\nSubState=exited\nMainPID=0\n', async () => {
|
|
338
|
+
assert.equal(await serviceExists('networking'), true);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
(0, node_test_1.it)('falls through to SysV when systemctl reports not-found', async () => {
|
|
342
|
+
const { serviceExists } = requireLinux();
|
|
343
|
+
await withFullMock(new Set(['/run/systemd/private', '/etc/init.d/legacy']), {}, 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nMainPID=0\n', async () => {
|
|
344
|
+
assert.equal(await serviceExists('legacy'), true);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
(0, node_test_1.it)('returns false when systemctl reports not-found and no SysV script', async () => {
|
|
348
|
+
const { serviceExists } = requireLinux();
|
|
349
|
+
await withFullMock(new Set(['/run/systemd/private']), {}, 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nMainPID=0\n', async () => {
|
|
350
|
+
assert.equal(await serviceExists('ghost'), false);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
// ─── index.ts — module contract ───────────────────────────────────────────────
|
|
218
355
|
(0, node_test_1.describe)('index.ts — module contract', () => {
|
|
219
356
|
(0, node_test_1.it)('exports serviceExists and getServiceStatus functions', () => {
|
|
220
|
-
// On Linux (our CI), the main index loads linux.
|
|
221
357
|
delete require.cache[require.resolve('../index')];
|
|
222
358
|
const api = require('../index');
|
|
223
359
|
assert.equal(typeof api.serviceExists, 'function');
|
package/test/service.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.test.js","sourceRoot":"","sources":["../../test/service.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.test.js","sourceRoot":"","sources":["../../test/service.test.ts"],"names":[],"mappings":"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"}
|