openilink-app-runner 0.2.1 → 0.3.0
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/dist/src/daemon.d.ts +1 -1
- package/dist/src/daemon.js +33 -52
- package/package.json +1 -1
package/dist/src/daemon.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function install(configPath
|
|
1
|
+
export declare function install(configPath?: string): void;
|
|
2
2
|
export declare function uninstall(): void;
|
package/dist/src/daemon.js
CHANGED
|
@@ -39,43 +39,27 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const os = __importStar(require("os"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
const child_process_1 = require("child_process");
|
|
42
|
+
const config_1 = require("./config");
|
|
42
43
|
const SERVICE_NAME = "openilink-app-runner";
|
|
43
44
|
function getBinPath() {
|
|
44
45
|
try {
|
|
45
46
|
return (0, child_process_1.execSync)("which openilink-app-runner", { encoding: "utf-8" }).trim();
|
|
46
47
|
}
|
|
47
48
|
catch {
|
|
48
|
-
// Fallback: resolve from node_modules
|
|
49
49
|
return path.resolve(__dirname, "../bin/runner.js");
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
return process.execPath;
|
|
54
|
-
}
|
|
55
|
-
// ========== Linux (systemd) ==========
|
|
56
|
-
function getRealUser() {
|
|
57
|
-
const sudoUser = process.env.SUDO_USER;
|
|
58
|
-
if (sudoUser) {
|
|
59
|
-
try {
|
|
60
|
-
const home = (0, child_process_1.execSync)(`eval echo ~${sudoUser}`, { encoding: "utf-8", shell: "/bin/sh" }).trim();
|
|
61
|
-
return { name: sudoUser, home };
|
|
62
|
-
}
|
|
63
|
-
catch { }
|
|
64
|
-
}
|
|
65
|
-
return { name: os.userInfo().username, home: os.homedir() };
|
|
66
|
-
}
|
|
52
|
+
// ========== Linux (systemd --user) ==========
|
|
67
53
|
function systemdUnit(configPath) {
|
|
68
54
|
const absConfig = path.resolve(configPath);
|
|
69
55
|
const binPath = getBinPath();
|
|
70
56
|
const workDir = path.dirname(absConfig);
|
|
71
|
-
const user = getRealUser();
|
|
72
57
|
return `[Unit]
|
|
73
58
|
Description=OpeniLink App Runner
|
|
74
59
|
After=network.target
|
|
75
60
|
|
|
76
61
|
[Service]
|
|
77
62
|
Type=simple
|
|
78
|
-
User=${user.name}
|
|
79
63
|
ExecStart=${binPath} start --config ${absConfig}
|
|
80
64
|
WorkingDirectory=${workDir}
|
|
81
65
|
Restart=always
|
|
@@ -83,37 +67,43 @@ RestartSec=5
|
|
|
83
67
|
Environment=NODE_ENV=production
|
|
84
68
|
|
|
85
69
|
[Install]
|
|
86
|
-
WantedBy=
|
|
70
|
+
WantedBy=default.target
|
|
87
71
|
`;
|
|
88
72
|
}
|
|
89
73
|
function installSystemd(configPath) {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
(
|
|
94
|
-
(0, child_process_1.execSync)(`systemctl
|
|
95
|
-
(0, child_process_1.execSync)(`systemctl
|
|
96
|
-
|
|
74
|
+
const userDir = path.join(os.homedir(), ".config/systemd/user");
|
|
75
|
+
fs.mkdirSync(userDir, { recursive: true });
|
|
76
|
+
const unitPath = path.join(userDir, `${SERVICE_NAME}.service`);
|
|
77
|
+
fs.writeFileSync(unitPath, systemdUnit(configPath));
|
|
78
|
+
(0, child_process_1.execSync)(`systemctl --user daemon-reload`);
|
|
79
|
+
(0, child_process_1.execSync)(`systemctl --user enable ${SERVICE_NAME}`);
|
|
80
|
+
(0, child_process_1.execSync)(`systemctl --user start ${SERVICE_NAME}`);
|
|
81
|
+
// Enable lingering so user services run without login
|
|
82
|
+
try {
|
|
83
|
+
(0, child_process_1.execSync)(`loginctl enable-linger ${os.userInfo().username}`, { stdio: "ignore" });
|
|
84
|
+
}
|
|
85
|
+
catch { }
|
|
86
|
+
console.log(`✓ 已安装 systemd 用户服务(无需 sudo)`);
|
|
97
87
|
console.log(` 服务文件: ${unitPath}`);
|
|
98
88
|
console.log(` 配置文件: ${path.resolve(configPath)}`);
|
|
99
|
-
console.log(` 查看状态: systemctl status ${SERVICE_NAME}`);
|
|
100
|
-
console.log(` 查看日志: journalctl -u ${SERVICE_NAME} -f`);
|
|
89
|
+
console.log(` 查看状态: systemctl --user status ${SERVICE_NAME}`);
|
|
90
|
+
console.log(` 查看日志: journalctl --user -u ${SERVICE_NAME} -f`);
|
|
101
91
|
}
|
|
102
92
|
function uninstallSystemd() {
|
|
103
93
|
try {
|
|
104
|
-
(0, child_process_1.execSync)(`systemctl stop ${SERVICE_NAME}`, { stdio: "ignore" });
|
|
94
|
+
(0, child_process_1.execSync)(`systemctl --user stop ${SERVICE_NAME}`, { stdio: "ignore" });
|
|
105
95
|
}
|
|
106
96
|
catch { }
|
|
107
97
|
try {
|
|
108
|
-
(0, child_process_1.execSync)(`systemctl disable ${SERVICE_NAME}`, { stdio: "ignore" });
|
|
98
|
+
(0, child_process_1.execSync)(`systemctl --user disable ${SERVICE_NAME}`, { stdio: "ignore" });
|
|
109
99
|
}
|
|
110
100
|
catch { }
|
|
111
|
-
const unitPath =
|
|
101
|
+
const unitPath = path.join(os.homedir(), `.config/systemd/user/${SERVICE_NAME}.service`);
|
|
112
102
|
if (fs.existsSync(unitPath)) {
|
|
113
103
|
fs.unlinkSync(unitPath);
|
|
114
|
-
(0, child_process_1.execSync)(
|
|
104
|
+
(0, child_process_1.execSync)(`systemctl --user daemon-reload`);
|
|
115
105
|
}
|
|
116
|
-
console.log(`✓ 已卸载 systemd
|
|
106
|
+
console.log(`✓ 已卸载 systemd 用户服务`);
|
|
117
107
|
}
|
|
118
108
|
// ========== macOS (launchd) ==========
|
|
119
109
|
function launchdPlist(configPath) {
|
|
@@ -146,55 +136,46 @@ function launchdPlist(configPath) {
|
|
|
146
136
|
`;
|
|
147
137
|
}
|
|
148
138
|
function installLaunchd(configPath) {
|
|
149
|
-
const plistPath = path.join(os.homedir(),
|
|
150
|
-
const plist = launchdPlist(configPath);
|
|
139
|
+
const plistPath = path.join(os.homedir(), "Library/LaunchAgents/com.openilink.app-runner.plist");
|
|
151
140
|
fs.mkdirSync(path.dirname(plistPath), { recursive: true });
|
|
152
|
-
fs.writeFileSync(plistPath,
|
|
141
|
+
fs.writeFileSync(plistPath, launchdPlist(configPath));
|
|
153
142
|
try {
|
|
154
143
|
(0, child_process_1.execSync)(`launchctl unload ${plistPath}`, { stdio: "ignore" });
|
|
155
144
|
}
|
|
156
145
|
catch { }
|
|
157
146
|
(0, child_process_1.execSync)(`launchctl load ${plistPath}`);
|
|
158
|
-
console.log(`✓ 已安装 launchd
|
|
147
|
+
console.log(`✓ 已安装 launchd 服务(无需 sudo)`);
|
|
159
148
|
console.log(` 配置文件: ${plistPath}`);
|
|
160
149
|
console.log(` 日志: ~/Library/Logs/openilink-app-runner.log`);
|
|
161
150
|
}
|
|
162
151
|
function uninstallLaunchd() {
|
|
163
|
-
const plistPath = path.join(os.homedir(),
|
|
152
|
+
const plistPath = path.join(os.homedir(), "Library/LaunchAgents/com.openilink.app-runner.plist");
|
|
164
153
|
try {
|
|
165
154
|
(0, child_process_1.execSync)(`launchctl unload ${plistPath}`, { stdio: "ignore" });
|
|
166
155
|
}
|
|
167
156
|
catch { }
|
|
168
|
-
if (fs.existsSync(plistPath))
|
|
157
|
+
if (fs.existsSync(plistPath))
|
|
169
158
|
fs.unlinkSync(plistPath);
|
|
170
|
-
}
|
|
171
159
|
console.log(`✓ 已卸载 launchd 服务`);
|
|
172
160
|
}
|
|
173
161
|
// ========== Public API ==========
|
|
174
162
|
function install(configPath) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (!fs.existsSync(absConfig) && process.env.SUDO_USER) {
|
|
178
|
-
const user = getRealUser();
|
|
179
|
-
const userConfig = path.join(user.home, ".config/openilink-app-runner/runner.yaml");
|
|
180
|
-
if (fs.existsSync(userConfig)) {
|
|
181
|
-
absConfig = userConfig;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
163
|
+
const resolved = configPath || (0, config_1.getConfigPath)();
|
|
164
|
+
const absConfig = path.resolve(resolved);
|
|
184
165
|
if (!fs.existsSync(absConfig)) {
|
|
185
166
|
console.error(`配置文件不存在: ${absConfig}`);
|
|
186
167
|
console.error(`请先运行: openilink-app-runner init --hub-url <url> --token <token>`);
|
|
187
168
|
process.exit(1);
|
|
188
169
|
}
|
|
189
170
|
if (os.platform() === "darwin") {
|
|
190
|
-
installLaunchd(
|
|
171
|
+
installLaunchd(absConfig);
|
|
191
172
|
}
|
|
192
173
|
else if (os.platform() === "linux") {
|
|
193
|
-
installSystemd(
|
|
174
|
+
installSystemd(absConfig);
|
|
194
175
|
}
|
|
195
176
|
else {
|
|
196
177
|
console.error(`不支持的平台: ${os.platform()}`);
|
|
197
|
-
console.error(`请手动运行: openilink-app-runner start
|
|
178
|
+
console.error(`请手动运行: openilink-app-runner start`);
|
|
198
179
|
process.exit(1);
|
|
199
180
|
}
|
|
200
181
|
}
|