magalh 1.0.13 → 1.0.15
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/bin/mgl.js +350 -214
- package/msh.js +1 -1
- package/package.json +1 -1
- package/bin/msh.js +0 -53
package/bin/mgl.js
CHANGED
|
@@ -8,255 +8,391 @@ const { spawn, execFileSync } = require("child_process");
|
|
|
8
8
|
|
|
9
9
|
const args = process.argv.slice(2);
|
|
10
10
|
const rootDir = path.resolve(__dirname, "..");
|
|
11
|
+
const entryFile = path.join(rootDir, "msh.js");
|
|
12
|
+
|
|
13
|
+
const SERVICE_NAME = "magalh";
|
|
14
|
+
const SERVICE_DISPLAY_NAME = "Magala Media Server";
|
|
15
|
+
const SERVICE_DESCRIPTION = "Magala self-hosted media streaming server";
|
|
16
|
+
|
|
17
|
+
function hasArg(name) {
|
|
18
|
+
return args.includes(name);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function log(message) {
|
|
22
|
+
console.log(`[magalh] ${message}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function warn(message) {
|
|
26
|
+
console.warn(`[magalh] ${message}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function fail(message, exitCode = 1) {
|
|
30
|
+
try {
|
|
31
|
+
process.stderr.write(`[magalh] ${message}\n`);
|
|
32
|
+
} catch {
|
|
33
|
+
console.error(`[magalh] ${message}`);
|
|
34
|
+
}
|
|
35
|
+
process.exit(exitCode);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isRootOnLinux() {
|
|
39
|
+
return typeof process.getuid === "function" && process.getuid() === 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isWindowsAdminLike() {
|
|
43
|
+
try {
|
|
44
|
+
fs.accessSync(
|
|
45
|
+
path.join(process.env.SystemRoot || "C:\\Windows", "System32"),
|
|
46
|
+
fs.constants.W_OK,
|
|
47
|
+
);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function fileExists(filePath) {
|
|
55
|
+
try {
|
|
56
|
+
fs.accessSync(filePath, fs.constants.F_OK);
|
|
57
|
+
return true;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function runCommand(command, commandArgs, options = {}) {
|
|
64
|
+
return execFileSync(command, commandArgs, {
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
...options,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
11
69
|
|
|
12
|
-
|
|
70
|
+
function runCommandQuiet(command, commandArgs, options = {}) {
|
|
71
|
+
try {
|
|
72
|
+
return execFileSync(command, commandArgs, {
|
|
73
|
+
stdio: "pipe",
|
|
74
|
+
encoding: "utf8",
|
|
75
|
+
...options,
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function printHelp() {
|
|
13
83
|
process.stdout.write(
|
|
14
84
|
[
|
|
15
85
|
"magalh - Magala Media Server",
|
|
16
86
|
"",
|
|
17
87
|
"Usage:",
|
|
18
|
-
" magalh
|
|
88
|
+
" magalh",
|
|
89
|
+
" magalh --help",
|
|
19
90
|
" magalh --install-service",
|
|
20
|
-
" magalh --
|
|
91
|
+
" magalh --uninstall-service",
|
|
92
|
+
" magalh --service-status",
|
|
93
|
+
"",
|
|
94
|
+
"Notes:",
|
|
95
|
+
" - The server starts normally with: magalh",
|
|
96
|
+
" - Service installation is explicit only; it is never done automatically.",
|
|
21
97
|
"",
|
|
22
98
|
].join("\n"),
|
|
23
99
|
);
|
|
24
|
-
process.exit(0);
|
|
25
100
|
}
|
|
26
101
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
102
|
+
function getCliBin() {
|
|
103
|
+
return path.join(rootDir, "bin", "mgl.js");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getLinuxServiceFile() {
|
|
107
|
+
return `/etc/systemd/system/${SERVICE_NAME}.service`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function ensureEntryFileExists() {
|
|
111
|
+
if (!fileExists(entryFile)) {
|
|
112
|
+
fail(`Entry file not found: ${entryFile}`);
|
|
31
113
|
}
|
|
114
|
+
}
|
|
32
115
|
|
|
33
|
-
|
|
34
|
-
|
|
116
|
+
function getLinuxServiceContent() {
|
|
117
|
+
const nodeBin = process.execPath;
|
|
118
|
+
const cliBin = getCliBin();
|
|
35
119
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
120
|
+
return [
|
|
121
|
+
"[Unit]",
|
|
122
|
+
`Description=${SERVICE_DISPLAY_NAME}`,
|
|
123
|
+
"After=network-online.target",
|
|
124
|
+
"Wants=network-online.target",
|
|
125
|
+
"",
|
|
126
|
+
"[Service]",
|
|
127
|
+
"Type=simple",
|
|
128
|
+
`WorkingDirectory=${rootDir}`,
|
|
129
|
+
`ExecStart=${nodeBin} ${cliBin}`,
|
|
130
|
+
"Restart=on-failure",
|
|
131
|
+
"RestartSec=5",
|
|
132
|
+
"StandardOutput=journal",
|
|
133
|
+
"StandardError=journal",
|
|
134
|
+
`SyslogIdentifier=${SERVICE_NAME}`,
|
|
135
|
+
"",
|
|
136
|
+
"[Install]",
|
|
137
|
+
"WantedBy=multi-user.target",
|
|
138
|
+
"",
|
|
139
|
+
].join("\n");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function isLinuxServiceInstalled() {
|
|
143
|
+
return fileExists(getLinuxServiceFile());
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function isWindowsServiceInstalled() {
|
|
147
|
+
const out = runCommandQuiet("sc", ["query", SERVICE_NAME]);
|
|
148
|
+
return typeof out === "string" && out.includes("SERVICE_NAME");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function installLinuxService() {
|
|
152
|
+
if (!isRootOnLinux()) {
|
|
153
|
+
fail("Linux service installation requires root. Run: sudo magalh --install-service");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const systemdDir = "/etc/systemd/system";
|
|
157
|
+
if (!fileExists(systemdDir)) {
|
|
158
|
+
fail("systemd directory not found. Service install is not supported on this Linux system.");
|
|
39
159
|
}
|
|
40
160
|
|
|
41
|
-
|
|
161
|
+
const cliBin = getCliBin();
|
|
162
|
+
if (!fileExists(cliBin)) {
|
|
163
|
+
fail(`CLI file not found: ${cliBin}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const serviceFile = getLinuxServiceFile();
|
|
167
|
+
const content = getLinuxServiceContent();
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
fs.writeFileSync(serviceFile, content, { mode: 0o644 });
|
|
171
|
+
log(`Service file written -> ${serviceFile}`);
|
|
42
172
|
|
|
43
|
-
|
|
44
|
-
(
|
|
45
|
-
|
|
173
|
+
runCommand("systemctl", ["daemon-reload"]);
|
|
174
|
+
runCommand("systemctl", ["enable", SERVICE_NAME]);
|
|
175
|
+
runCommand("systemctl", ["restart", SERVICE_NAME]);
|
|
176
|
+
|
|
177
|
+
log(
|
|
178
|
+
"systemd service enabled and started.\n" +
|
|
179
|
+
` Status : systemctl status ${SERVICE_NAME}\n` +
|
|
180
|
+
` Logs : journalctl -u ${SERVICE_NAME} -f`,
|
|
181
|
+
);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
fail(`Linux service installation failed: ${error.message || String(error)}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function uninstallLinuxService() {
|
|
188
|
+
if (!isRootOnLinux()) {
|
|
189
|
+
fail("Linux service removal requires root. Run: sudo magalh --uninstall-service");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const serviceFile = getLinuxServiceFile();
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
runCommandQuiet("systemctl", ["stop", SERVICE_NAME]);
|
|
196
|
+
runCommandQuiet("systemctl", ["disable", SERVICE_NAME]);
|
|
197
|
+
|
|
198
|
+
if (fileExists(serviceFile)) {
|
|
199
|
+
fs.unlinkSync(serviceFile);
|
|
200
|
+
log(`Removed service file -> ${serviceFile}`);
|
|
201
|
+
} else {
|
|
202
|
+
log("Service file does not exist. Nothing to remove.");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
runCommand("systemctl", ["daemon-reload"]);
|
|
206
|
+
log("Linux service removed.");
|
|
207
|
+
} catch (error) {
|
|
208
|
+
fail(`Linux service removal failed: ${error.message || String(error)}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function printLinuxServiceStatus() {
|
|
213
|
+
if (!isLinuxServiceInstalled()) {
|
|
214
|
+
log("Linux service is not installed.");
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
46
217
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"nvm install " + MIN_NODE_MAJOR,
|
|
52
|
-
"nvm alias default " + MIN_NODE_MAJOR,
|
|
53
|
-
"nvm use " + MIN_NODE_MAJOR,
|
|
54
|
-
].join(" && ");
|
|
218
|
+
log(`Linux service file exists -> ${getLinuxServiceFile()}`);
|
|
219
|
+
const status = runCommandQuiet("systemctl", ["status", SERVICE_NAME, "--no-pager"]);
|
|
220
|
+
if (status) {
|
|
221
|
+
process.stdout.write(`${status}\n`);
|
|
55
222
|
} else {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
223
|
+
warn("Could not read systemd status output.");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function installWindowsService() {
|
|
228
|
+
if (!isWindowsAdminLike()) {
|
|
229
|
+
fail("Windows service installation requires Administrator privileges.");
|
|
63
230
|
}
|
|
64
231
|
|
|
232
|
+
const cliBin = getCliBin();
|
|
233
|
+
if (!fileExists(cliBin)) {
|
|
234
|
+
fail(`CLI file not found: ${cliBin}`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const nodeBin = process.execPath;
|
|
238
|
+
const binPath = `"${nodeBin}" "${cliBin}"`;
|
|
239
|
+
|
|
65
240
|
try {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
241
|
+
runCommandQuiet("sc", ["stop", SERVICE_NAME]);
|
|
242
|
+
runCommandQuiet("sc", ["delete", SERVICE_NAME]);
|
|
243
|
+
|
|
244
|
+
runCommand("sc", [
|
|
245
|
+
"create",
|
|
246
|
+
SERVICE_NAME,
|
|
247
|
+
"binPath=",
|
|
248
|
+
binPath,
|
|
249
|
+
"start=",
|
|
250
|
+
"auto",
|
|
251
|
+
"DisplayName=",
|
|
252
|
+
SERVICE_DISPLAY_NAME,
|
|
253
|
+
]);
|
|
254
|
+
|
|
255
|
+
runCommand("sc", [
|
|
256
|
+
"description",
|
|
257
|
+
SERVICE_NAME,
|
|
258
|
+
SERVICE_DESCRIPTION,
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
runCommand("sc", [
|
|
262
|
+
"failure",
|
|
263
|
+
SERVICE_NAME,
|
|
264
|
+
"reset=",
|
|
265
|
+
"60",
|
|
266
|
+
"actions=",
|
|
267
|
+
"restart/5000/restart/5000/restart/5000",
|
|
268
|
+
]);
|
|
269
|
+
|
|
270
|
+
runCommand("sc", ["start", SERVICE_NAME]);
|
|
271
|
+
|
|
272
|
+
log(
|
|
273
|
+
"Windows service created and started.\n" +
|
|
274
|
+
` Status : sc query ${SERVICE_NAME}\n` +
|
|
275
|
+
` Stop : sc stop ${SERVICE_NAME}\n` +
|
|
276
|
+
" Logs : Event Viewer -> Windows Logs -> Application",
|
|
277
|
+
);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
fail(`Windows service installation failed: ${error.message || String(error)}`);
|
|
71
280
|
}
|
|
72
|
-
process.exit(0);
|
|
73
281
|
}
|
|
74
282
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const mglBin = path.join(rootDir, "bin", "mgl.js");
|
|
79
|
-
|
|
80
|
-
function installLinux() {
|
|
81
|
-
if (typeof process.getuid !== "function" || process.getuid() !== 0) {
|
|
82
|
-
console.log(
|
|
83
|
-
"[magalh] Skipping systemd setup (not running as root).\n" +
|
|
84
|
-
" To install manually: sudo npm install -g magalh",
|
|
85
|
-
);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
const SYSTEMD_DIR = "/etc/systemd/system";
|
|
89
|
-
if (!fs.existsSync(SYSTEMD_DIR)) {
|
|
90
|
-
console.log("[magalh] Skipping systemd setup (systemd not found).");
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const serviceFile = path.join(SYSTEMD_DIR, `${SERVICE_NAME}.service`);
|
|
94
|
-
const content = [
|
|
95
|
-
"[Unit]",
|
|
96
|
-
"Description=Magala Media Server",
|
|
97
|
-
"After=network-online.target",
|
|
98
|
-
"Wants=network-online.target",
|
|
99
|
-
"",
|
|
100
|
-
"[Service]",
|
|
101
|
-
"Type=simple",
|
|
102
|
-
`WorkingDirectory=${rootDir}`,
|
|
103
|
-
`ExecStart=${nodeBin} ${mglBin}`,
|
|
104
|
-
"Restart=on-failure",
|
|
105
|
-
"RestartSec=5",
|
|
106
|
-
"StandardOutput=journal",
|
|
107
|
-
"StandardError=journal",
|
|
108
|
-
`SyslogIdentifier=${SERVICE_NAME}`,
|
|
109
|
-
"",
|
|
110
|
-
"[Install]",
|
|
111
|
-
"WantedBy=multi-user.target",
|
|
112
|
-
"",
|
|
113
|
-
].join("\n");
|
|
114
|
-
try {
|
|
115
|
-
fs.writeFileSync(serviceFile, content, { mode: 0o644 });
|
|
116
|
-
console.log(`[magalh] Service file written -> ${serviceFile}`);
|
|
117
|
-
execFileSync("systemctl", ["daemon-reload"], { stdio: "inherit" });
|
|
118
|
-
execFileSync("systemctl", ["enable", SERVICE_NAME], { stdio: "inherit" });
|
|
119
|
-
execFileSync("systemctl", ["restart", SERVICE_NAME], { stdio: "inherit" });
|
|
120
|
-
console.log(
|
|
121
|
-
`[magalh] systemd service enabled and started.\n` +
|
|
122
|
-
` Status : systemctl status ${SERVICE_NAME}\n` +
|
|
123
|
-
` Logs : journalctl -u ${SERVICE_NAME} -f`,
|
|
124
|
-
);
|
|
125
|
-
} catch (err) {
|
|
126
|
-
console.warn("[magalh] Warning: systemd setup failed: " + ((err && err.message) || String(err)));
|
|
127
|
-
}
|
|
283
|
+
function uninstallWindowsService() {
|
|
284
|
+
if (!isWindowsAdminLike()) {
|
|
285
|
+
fail("Windows service removal requires Administrator privileges.");
|
|
128
286
|
}
|
|
129
287
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const binPath = `"${nodeBin}" "${mglBin}"`;
|
|
144
|
-
try {
|
|
145
|
-
try { execFileSync("sc", ["stop", SERVICE_NAME], { stdio: "pipe" }); } catch (_e) { }
|
|
146
|
-
try { execFileSync("sc", ["delete", SERVICE_NAME], { stdio: "pipe" }); } catch (_e) { }
|
|
147
|
-
execFileSync("sc", [
|
|
148
|
-
"create", SERVICE_NAME,
|
|
149
|
-
"binPath=", binPath,
|
|
150
|
-
"start=", "auto",
|
|
151
|
-
"DisplayName=", "Magala Media Server",
|
|
152
|
-
], { stdio: "inherit" });
|
|
153
|
-
execFileSync("sc", [
|
|
154
|
-
"description", SERVICE_NAME,
|
|
155
|
-
"Magala self-hosted media streaming server",
|
|
156
|
-
], { stdio: "inherit" });
|
|
157
|
-
execFileSync("sc", [
|
|
158
|
-
"failure", SERVICE_NAME,
|
|
159
|
-
"reset=", "60",
|
|
160
|
-
"actions=", "restart/5000/restart/5000/restart/5000",
|
|
161
|
-
], { stdio: "inherit" });
|
|
162
|
-
execFileSync("sc", ["start", SERVICE_NAME], { stdio: "inherit" });
|
|
163
|
-
console.log(
|
|
164
|
-
`[magalh] Windows service created and started.\n` +
|
|
165
|
-
` Status : sc query ${SERVICE_NAME}\n` +
|
|
166
|
-
` Stop : sc stop ${SERVICE_NAME}\n` +
|
|
167
|
-
` Logs : Event Viewer -> Windows Logs -> Application`,
|
|
168
|
-
);
|
|
169
|
-
} catch (err) {
|
|
170
|
-
console.warn("[magalh] Warning: Windows service setup failed: " + ((err && err.message) || String(err)));
|
|
171
|
-
}
|
|
288
|
+
try {
|
|
289
|
+
runCommandQuiet("sc", ["stop", SERVICE_NAME]);
|
|
290
|
+
runCommandQuiet("sc", ["delete", SERVICE_NAME]);
|
|
291
|
+
log("Windows service removed.");
|
|
292
|
+
} catch (error) {
|
|
293
|
+
fail(`Windows service removal failed: ${error.message || String(error)}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function printWindowsServiceStatus() {
|
|
298
|
+
if (!isWindowsServiceInstalled()) {
|
|
299
|
+
log("Windows service is not installed.");
|
|
300
|
+
process.exit(0);
|
|
172
301
|
}
|
|
173
302
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
303
|
+
const status = runCommandQuiet("sc", ["query", SERVICE_NAME]);
|
|
304
|
+
if (status) {
|
|
305
|
+
process.stdout.write(`${status}\n`);
|
|
306
|
+
} else {
|
|
307
|
+
warn("Could not read Windows service status output.");
|
|
308
|
+
}
|
|
177
309
|
}
|
|
178
310
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
'if [ -s "' + _nvmSh + '" ]; then',
|
|
189
|
-
' source "' + _nvmSh + '" && nvm install ' + _MIN + ' && nvm alias default ' + _MIN,
|
|
190
|
-
'elif curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh -o /tmp/_nvm_setup.sh 2>/dev/null && bash /tmp/_nvm_setup.sh && [ -s "' + _nvmSh + '" ]; then',
|
|
191
|
-
' source "' + _nvmSh + '" && nvm install ' + _MIN + ' && nvm alias default ' + _MIN,
|
|
192
|
-
'else',
|
|
193
|
-
' echo "[magalh] Falling back to npm n..." && npm install -g n && n ' + _MIN,
|
|
194
|
-
'fi',
|
|
195
|
-
].join('\n');
|
|
196
|
-
var _newNode = null;
|
|
197
|
-
try {
|
|
198
|
-
execFileSync("bash", ["-c", _upCmd], { stdio: "inherit" });
|
|
199
|
-
if (fs.existsSync(_nvmSh)) {
|
|
200
|
-
try {
|
|
201
|
-
_newNode = execFileSync("bash", ["-c", 'source "' + _nvmSh + '" && nvm which ' + _MIN], { encoding: "utf8" }).trim();
|
|
202
|
-
} catch (_e) {}
|
|
203
|
-
}
|
|
204
|
-
if (!_newNode) {
|
|
205
|
-
var _cands = ["/usr/local/bin/node", "/usr/bin/node"];
|
|
206
|
-
for (var _ci = 0; _ci < _cands.length; _ci++) {
|
|
207
|
-
if (fs.existsSync(_cands[_ci])) {
|
|
208
|
-
try {
|
|
209
|
-
var _nv = execFileSync(_cands[_ci], ["--version"], { encoding: "utf8" }).trim();
|
|
210
|
-
if (parseInt(_nv.replace("v", "").split(".")[0], 10) >= _MIN) {
|
|
211
|
-
_newNode = _cands[_ci];
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
} catch (_e) {}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} catch (_e) {
|
|
219
|
-
console.warn("[magalh] Auto-upgrade failed. Run manually: magalh --upgrade-node");
|
|
220
|
-
}
|
|
221
|
-
if (_newNode && fs.existsSync(_newNode)) {
|
|
222
|
-
var _newNpm = path.join(path.dirname(_newNode), "npm");
|
|
223
|
-
if (fs.existsSync(_newNpm)) {
|
|
224
|
-
console.log("[magalh] Reinstalling magalh with Node v" + _MIN + " (rebuilds native modules)...");
|
|
225
|
-
try {
|
|
226
|
-
execFileSync(_newNpm, ["install", "-g", "magalh"], { stdio: "inherit" });
|
|
227
|
-
} catch (_re) {
|
|
228
|
-
console.warn("[magalh] Reinstall warning: " + String(_re));
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
console.log("[magalh] Restarting with Node.js v" + _MIN + "...");
|
|
232
|
-
var _env = Object.assign({}, process.env, { MAGALH_UPGRADED: "1" });
|
|
233
|
-
var _rs = spawn(_newNode, [__filename].concat(args), { cwd: rootDir, env: _env, stdio: "inherit" });
|
|
234
|
-
_rs.on("exit", function(c, s) { process.exit(s ? 1 : (typeof c === "number" ? c : 0)); });
|
|
235
|
-
_rs.on("error", function(e) { process.stderr.write(String(e) + "\n"); process.exit(1); });
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
console.error("[magalh] Cannot start: requires Node.js v" + _MIN + "+. Run: magalh --upgrade-node");
|
|
239
|
-
process.exit(1);
|
|
311
|
+
function installService() {
|
|
312
|
+
if (process.platform === "linux") {
|
|
313
|
+
installLinuxService();
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (process.platform === "win32") {
|
|
318
|
+
installWindowsService();
|
|
319
|
+
return;
|
|
240
320
|
}
|
|
321
|
+
|
|
322
|
+
fail(`Service installation is not supported on platform: ${process.platform}`);
|
|
241
323
|
}
|
|
242
324
|
|
|
243
|
-
|
|
325
|
+
function uninstallService() {
|
|
326
|
+
if (process.platform === "linux") {
|
|
327
|
+
uninstallLinuxService();
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (process.platform === "win32") {
|
|
332
|
+
uninstallWindowsService();
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
244
335
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
env: process.env,
|
|
248
|
-
stdio: "inherit",
|
|
249
|
-
windowsHide: true,
|
|
250
|
-
});
|
|
336
|
+
fail(`Service removal is not supported on platform: ${process.platform}`);
|
|
337
|
+
}
|
|
251
338
|
|
|
252
|
-
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
339
|
+
function printServiceStatus() {
|
|
340
|
+
if (process.platform === "linux") {
|
|
341
|
+
printLinuxServiceStatus();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
256
344
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
});
|
|
345
|
+
if (process.platform === "win32") {
|
|
346
|
+
printWindowsServiceStatus();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
log(`Service status is not supported on platform: ${process.platform}`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function startMainProcess() {
|
|
354
|
+
ensureEntryFileExists();
|
|
355
|
+
|
|
356
|
+
const child = spawn(process.execPath, [entryFile, ...args], {
|
|
357
|
+
cwd: rootDir,
|
|
358
|
+
env: process.env,
|
|
359
|
+
stdio: "inherit",
|
|
360
|
+
windowsHide: true,
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
child.on("exit", (code, signal) => {
|
|
364
|
+
if (signal) {
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
child.on("error", (error) => {
|
|
370
|
+
fail(`Failed to start msh: ${error.message || String(error)}`);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function main() {
|
|
375
|
+
if (hasArg("--help") || hasArg("-h")) {
|
|
376
|
+
printHelp();
|
|
377
|
+
process.exit(0);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (hasArg("--install-service")) {
|
|
381
|
+
installService();
|
|
382
|
+
process.exit(0);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (hasArg("--uninstall-service")) {
|
|
386
|
+
uninstallService();
|
|
387
|
+
process.exit(0);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (hasArg("--service-status")) {
|
|
391
|
+
printServiceStatus();
|
|
392
|
+
process.exit(0);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
startMainProcess();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
main();
|