yymaxapi 1.0.28 → 1.0.29
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/yymaxapi.js +43 -21
- package/package.json +1 -1
package/bin/yymaxapi.js
CHANGED
|
@@ -841,20 +841,27 @@ async function selectDockerContainer() {
|
|
|
841
841
|
// 在 Docker 容器内执行命令
|
|
842
842
|
function execInDocker(containerId, cmd, options = {}) {
|
|
843
843
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
844
|
+
// 尝试 sh -c,fallback bash -lc
|
|
845
|
+
const r = safeExec(dockerCmd(`exec ${containerId} sh -c '${escaped}'`), { timeout: 30000, ...options });
|
|
846
|
+
if (r.ok) return r;
|
|
844
847
|
return safeExec(dockerCmd(`exec ${containerId} bash -lc '${escaped}'`), { timeout: 30000, ...options });
|
|
845
848
|
}
|
|
846
849
|
|
|
847
850
|
// 在 Docker 容器内异步执行命令(后台启动 gateway 等)
|
|
848
|
-
|
|
851
|
+
// shell 参数: 'sh -c' | 'bash -lc' | 'bash -c'
|
|
852
|
+
function spawnDetachedInDocker(containerId, cmd, shell = 'sh -c') {
|
|
849
853
|
try {
|
|
854
|
+
const shellParts = shell.split(' ');
|
|
855
|
+
const shellBin = shellParts[0];
|
|
856
|
+
const shellFlag = shellParts.slice(1).join(' ');
|
|
850
857
|
const prefix = _dockerNeedsSudo ? 'sudo' : 'docker';
|
|
851
858
|
const args = _dockerNeedsSudo
|
|
852
|
-
? ['-n', 'docker', 'exec', '-d', containerId,
|
|
853
|
-
: ['exec', '-d', containerId,
|
|
854
|
-
const child = spawn(prefix, args, {
|
|
859
|
+
? ['-n', 'docker', 'exec', '-d', containerId, shellBin, shellFlag, cmd]
|
|
860
|
+
: ['exec', '-d', containerId, shellBin, shellFlag, cmd];
|
|
861
|
+
const child = spawn(prefix, args.filter(Boolean), {
|
|
855
862
|
detached: true,
|
|
856
863
|
stdio: 'ignore',
|
|
857
|
-
env: { ...process.env
|
|
864
|
+
env: { ...process.env }
|
|
858
865
|
});
|
|
859
866
|
child.unref();
|
|
860
867
|
return true;
|
|
@@ -1058,7 +1065,7 @@ function cleanupAgentProcesses() {
|
|
|
1058
1065
|
if (detectGatewayEnv() === 'docker' && _selectedDockerContainer) {
|
|
1059
1066
|
try {
|
|
1060
1067
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
1061
|
-
safeExec(dockerCmd(`exec ${_selectedDockerContainer.id}
|
|
1068
|
+
safeExec(dockerCmd(`exec ${_selectedDockerContainer.id} sh -c "pkill -f '${name}.*agent' 2>/dev/null || true"`), { timeout: 10000 });
|
|
1062
1069
|
}
|
|
1063
1070
|
} catch { /* ignore */ }
|
|
1064
1071
|
}
|
|
@@ -1703,6 +1710,7 @@ async function tryAutoStartGateway(port, allowAutoDaemon) {
|
|
|
1703
1710
|
if (container.cli === 'node') {
|
|
1704
1711
|
dockerCmds.push(`node ${container.cliPath} gateway`);
|
|
1705
1712
|
} else {
|
|
1713
|
+
if (container.cliPath) dockerCmds.push(`${container.cliPath} gateway`);
|
|
1706
1714
|
dockerCmds.push(`${container.cli} gateway`);
|
|
1707
1715
|
}
|
|
1708
1716
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
@@ -1711,10 +1719,13 @@ async function tryAutoStartGateway(port, allowAutoDaemon) {
|
|
|
1711
1719
|
|
|
1712
1720
|
for (const cmd of [...new Set(dockerCmds)].filter(Boolean)) {
|
|
1713
1721
|
console.log(chalk.yellow(`⚠️ 尝试在容器内启动 Gateway: ${cmd}`));
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1722
|
+
// 尝试多种 shell
|
|
1723
|
+
for (const shell of ['sh -c', 'bash -lc', 'bash -c']) {
|
|
1724
|
+
if (spawnDetachedInDocker(container.id, cmd, shell)) {
|
|
1725
|
+
if (await waitForGateway(port, '127.0.0.1', 15000)) {
|
|
1726
|
+
console.log(chalk.green(`✅ Gateway 已在 Docker 容器 ${container.name} 内启动`));
|
|
1727
|
+
return { started: true, method: 'docker', container: container.name };
|
|
1728
|
+
}
|
|
1718
1729
|
}
|
|
1719
1730
|
}
|
|
1720
1731
|
}
|
|
@@ -3055,26 +3066,34 @@ async function restartGateway() {
|
|
|
3055
3066
|
|
|
3056
3067
|
const dockerCmds = [];
|
|
3057
3068
|
if (container.cli === 'node') {
|
|
3058
|
-
// 脚本路径模式(如 /opt/moltbot/moltbot.mjs)
|
|
3059
3069
|
dockerCmds.push(`node ${container.cliPath} gateway restart`);
|
|
3060
3070
|
} else {
|
|
3071
|
+
if (container.cliPath) dockerCmds.push(`${container.cliPath} gateway restart`);
|
|
3061
3072
|
dockerCmds.push(`${container.cli} gateway restart`);
|
|
3062
3073
|
}
|
|
3063
|
-
// 通用回退
|
|
3064
3074
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
3065
3075
|
dockerCmds.push(`${name} gateway restart`);
|
|
3066
3076
|
}
|
|
3067
3077
|
|
|
3078
|
+
// 每个命令尝试多种 shell(sh -c / bash -lc / bash -c)
|
|
3079
|
+
const shellVariants = ['sh -c', 'bash -lc', 'bash -c'];
|
|
3080
|
+
|
|
3068
3081
|
return new Promise((resolve) => {
|
|
3082
|
+
// 展开为 [cmd1+sh, cmd1+bash-lc, cmd1+bash-c, cmd2+sh, ...]
|
|
3083
|
+
const allAttempts = [];
|
|
3084
|
+
for (const cmd of [...new Set(dockerCmds)].filter(Boolean)) {
|
|
3085
|
+
for (const shell of shellVariants) {
|
|
3086
|
+
allAttempts.push(dockerCmd(`exec ${container.id} ${shell} "${cmd}"`));
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3069
3089
|
let tried = 0;
|
|
3070
3090
|
const tryNext = () => {
|
|
3071
|
-
if (tried >=
|
|
3091
|
+
if (tried >= allAttempts.length) {
|
|
3072
3092
|
console.log(chalk.yellow('Docker 容器内 Gateway 重启失败,尝试本地重启...'));
|
|
3073
3093
|
restartGatewayNative().then(resolve);
|
|
3074
3094
|
return;
|
|
3075
3095
|
}
|
|
3076
|
-
const
|
|
3077
|
-
const fullCmd = dockerCmd(`exec ${container.id} bash -lc "${cmd}"`);
|
|
3096
|
+
const fullCmd = allAttempts[tried++];
|
|
3078
3097
|
exec(fullCmd, { timeout: 30000 }, (error) => {
|
|
3079
3098
|
if (error) {
|
|
3080
3099
|
tryNext();
|
|
@@ -3140,9 +3159,9 @@ async function forceRestartGateway(resolved, nodeInfo, useNode, env, gatewayPort
|
|
|
3140
3159
|
// 1. 杀掉容器内旧 Gateway 进程
|
|
3141
3160
|
try {
|
|
3142
3161
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
3143
|
-
safeExec(dockerCmd(`exec ${cid}
|
|
3162
|
+
safeExec(dockerCmd(`exec ${cid} sh -c "pkill -f '${name}.*gateway' 2>/dev/null || true"`), { timeout: 5000 });
|
|
3144
3163
|
}
|
|
3145
|
-
safeExec(dockerCmd(`exec ${cid}
|
|
3164
|
+
safeExec(dockerCmd(`exec ${cid} sh -c "lsof -ti :${gatewayPort} 2>/dev/null | xargs -r kill -9 2>/dev/null || true"`), { timeout: 5000 });
|
|
3146
3165
|
console.log(chalk.gray(' 已尝试清理容器内旧 Gateway 进程'));
|
|
3147
3166
|
} catch { /* ignore */ }
|
|
3148
3167
|
|
|
@@ -3153,6 +3172,7 @@ async function forceRestartGateway(resolved, nodeInfo, useNode, env, gatewayPort
|
|
|
3153
3172
|
if (_selectedDockerContainer.cli === 'node') {
|
|
3154
3173
|
dockerCmds.push(`node ${_selectedDockerContainer.cliPath} gateway`);
|
|
3155
3174
|
} else {
|
|
3175
|
+
if (_selectedDockerContainer.cliPath) dockerCmds.push(`${_selectedDockerContainer.cliPath} gateway`);
|
|
3156
3176
|
dockerCmds.push(`${_selectedDockerContainer.cli} gateway`);
|
|
3157
3177
|
}
|
|
3158
3178
|
for (const name of ['openclaw', 'clawdbot', 'moltbot']) {
|
|
@@ -3161,10 +3181,12 @@ async function forceRestartGateway(resolved, nodeInfo, useNode, env, gatewayPort
|
|
|
3161
3181
|
|
|
3162
3182
|
for (const cmd of [...new Set(dockerCmds)].filter(Boolean)) {
|
|
3163
3183
|
console.log(chalk.gray(` 尝试在容器内启动: ${cmd}`));
|
|
3164
|
-
|
|
3165
|
-
if (
|
|
3166
|
-
|
|
3167
|
-
|
|
3184
|
+
for (const shell of ['sh -c', 'bash -lc', 'bash -c']) {
|
|
3185
|
+
if (spawnDetachedInDocker(cid, cmd, shell)) {
|
|
3186
|
+
if (await waitForGateway(gatewayPort, '127.0.0.1', 12000)) {
|
|
3187
|
+
console.log(chalk.green(`✅ Gateway 已在 Docker 容器 ${cName} 内强制重启成功`));
|
|
3188
|
+
return true;
|
|
3189
|
+
}
|
|
3168
3190
|
}
|
|
3169
3191
|
}
|
|
3170
3192
|
}
|