magalh 1.0.2 → 1.0.4
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 +150 -52
- package/msh.js +1 -18278
- package/package.json +114 -118
package/bin/mgl.js
CHANGED
|
@@ -1,53 +1,151 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
const fs = require("node:fs");
|
|
6
|
-
const path = require("node:path");
|
|
7
|
-
const { spawn } = require("node:child_process");
|
|
8
|
-
|
|
9
|
-
const args = process.argv.slice(2);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
" - Pass PORTS env var to control ports (e.g., PORTS=80,800,737)",
|
|
22
|
-
"",
|
|
23
|
-
].join("\n"),
|
|
24
|
-
);
|
|
25
|
-
process.exit(0);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const fs = require("node:fs");
|
|
6
|
+
const path = require("node:path");
|
|
7
|
+
const { spawn, execFileSync } = require("node:child_process");
|
|
8
|
+
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const rootDir = path.resolve(__dirname, "..");
|
|
11
|
+
|
|
12
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
13
|
+
process.stdout.write(
|
|
14
|
+
[
|
|
15
|
+
"msh - start Magala server",
|
|
16
|
+
"",
|
|
17
|
+
"Usage:",
|
|
18
|
+
" msh [--help]",
|
|
19
|
+
"",
|
|
20
|
+
"Notes:",
|
|
21
|
+
" - Pass PORTS env var to control ports (e.g., PORTS=80,800,737)",
|
|
22
|
+
"",
|
|
23
|
+
].join("\n"),
|
|
24
|
+
);
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (args.includes("--install-service")) {
|
|
29
|
+
const SERVICE_NAME = "magalh";
|
|
30
|
+
const nodeBin = process.execPath;
|
|
31
|
+
const mglBin = path.join(rootDir, "bin", "mgl.js");
|
|
32
|
+
|
|
33
|
+
function installLinux() {
|
|
34
|
+
if (process.getuid?.() !== 0) {
|
|
35
|
+
console.log(
|
|
36
|
+
"[magalh] Skipping systemd setup (not running as root).\n" +
|
|
37
|
+
" To install manually: sudo npm install -g magalh",
|
|
38
|
+
);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const SYSTEMD_DIR = "/etc/systemd/system";
|
|
42
|
+
if (!fs.existsSync(SYSTEMD_DIR)) {
|
|
43
|
+
console.log("[magalh] Skipping systemd setup (systemd not found).");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const serviceFile = path.join(SYSTEMD_DIR, `${SERVICE_NAME}.service`);
|
|
47
|
+
const content = [
|
|
48
|
+
"[Unit]",
|
|
49
|
+
"Description=Magala Media Server",
|
|
50
|
+
"After=network-online.target",
|
|
51
|
+
"Wants=network-online.target",
|
|
52
|
+
"",
|
|
53
|
+
"[Service]",
|
|
54
|
+
"Type=simple",
|
|
55
|
+
`WorkingDirectory=${rootDir}`,
|
|
56
|
+
`ExecStart=${nodeBin} ${mglBin}`,
|
|
57
|
+
"Restart=on-failure",
|
|
58
|
+
"RestartSec=5",
|
|
59
|
+
"StandardOutput=journal",
|
|
60
|
+
"StandardError=journal",
|
|
61
|
+
`SyslogIdentifier=${SERVICE_NAME}`,
|
|
62
|
+
"",
|
|
63
|
+
"[Install]",
|
|
64
|
+
"WantedBy=multi-user.target",
|
|
65
|
+
"",
|
|
66
|
+
].join("\n");
|
|
67
|
+
try {
|
|
68
|
+
fs.writeFileSync(serviceFile, content, { mode: 0o644 });
|
|
69
|
+
console.log(`[magalh] Service file written -> ${serviceFile}`);
|
|
70
|
+
execFileSync("systemctl", ["daemon-reload"], { stdio: "inherit" });
|
|
71
|
+
execFileSync("systemctl", ["enable", SERVICE_NAME], { stdio: "inherit" });
|
|
72
|
+
execFileSync("systemctl", ["restart", SERVICE_NAME], { stdio: "inherit" });
|
|
73
|
+
console.log(
|
|
74
|
+
`[magalh] systemd service enabled and started.\n` +
|
|
75
|
+
` Status : systemctl status ${SERVICE_NAME}\n` +
|
|
76
|
+
` Logs : journalctl -u ${SERVICE_NAME} -f`,
|
|
77
|
+
);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.warn(`[magalh] Warning: systemd setup failed: ${err?.message || err}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function installWindows() {
|
|
84
|
+
try {
|
|
85
|
+
fs.accessSync(
|
|
86
|
+
path.join(process.env.SystemRoot || "C:\\Windows", "System32"),
|
|
87
|
+
fs.constants.W_OK,
|
|
88
|
+
);
|
|
89
|
+
} catch {
|
|
90
|
+
console.log(
|
|
91
|
+
"[magalh] Skipping Windows service setup (not running as Administrator).\n" +
|
|
92
|
+
" To install manually: run npm install -g magalh as Administrator.",
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const binPath = `"${nodeBin}" "${mglBin}"`;
|
|
97
|
+
try {
|
|
98
|
+
try { execFileSync("sc", ["stop", SERVICE_NAME], { stdio: "pipe" }); } catch { }
|
|
99
|
+
try { execFileSync("sc", ["delete", SERVICE_NAME], { stdio: "pipe" }); } catch { }
|
|
100
|
+
execFileSync("sc", [
|
|
101
|
+
"create", SERVICE_NAME,
|
|
102
|
+
"binPath=", binPath,
|
|
103
|
+
"start=", "auto",
|
|
104
|
+
"DisplayName=", "Magala Media Server",
|
|
105
|
+
], { stdio: "inherit" });
|
|
106
|
+
execFileSync("sc", [
|
|
107
|
+
"description", SERVICE_NAME,
|
|
108
|
+
"Magala self-hosted media streaming server",
|
|
109
|
+
], { stdio: "inherit" });
|
|
110
|
+
execFileSync("sc", [
|
|
111
|
+
"failure", SERVICE_NAME,
|
|
112
|
+
"reset=", "60",
|
|
113
|
+
"actions=", "restart/5000/restart/5000/restart/5000",
|
|
114
|
+
], { stdio: "inherit" });
|
|
115
|
+
execFileSync("sc", ["start", SERVICE_NAME], { stdio: "inherit" });
|
|
116
|
+
console.log(
|
|
117
|
+
`[magalh] Windows service created and started.\n` +
|
|
118
|
+
` Status : sc query ${SERVICE_NAME}\n` +
|
|
119
|
+
` Stop : sc stop ${SERVICE_NAME}\n` +
|
|
120
|
+
` Logs : Event Viewer -> Windows Logs -> Application`,
|
|
121
|
+
);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
console.warn(`[magalh] Warning: Windows service setup failed: ${err?.message || err}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (process.platform === "linux") installLinux();
|
|
128
|
+
else if (process.platform === "win32") installWindows();
|
|
129
|
+
process.exit(0);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const entryFile = path.join(rootDir, "msh.js");
|
|
133
|
+
|
|
134
|
+
const child = spawn(process.execPath, [entryFile, ...args], {
|
|
135
|
+
cwd: rootDir,
|
|
136
|
+
env: process.env,
|
|
137
|
+
stdio: "inherit",
|
|
138
|
+
windowsHide: true,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
child.on("exit", (code, signal) => {
|
|
142
|
+
if (signal) process.exit(1);
|
|
143
|
+
process.exit(typeof code === "number" ? code : 0);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
child.on("error", (err) => {
|
|
147
|
+
try {
|
|
148
|
+
process.stderr.write(`Failed to start msh: ${err?.message || String(err)}\n`);
|
|
149
|
+
} catch { }
|
|
150
|
+
process.exit(1);
|
|
53
151
|
});
|