cicy-desktop 2.1.304 → 2.1.306
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/package.json
CHANGED
|
@@ -90,12 +90,24 @@ async function ensureWslKernel({ emit } = {}) {
|
|
|
90
90
|
// Run a bash command as root inside the distro. execFile (no host shell) → the
|
|
91
91
|
// command string is passed verbatim to `bash -lc`, so only bash-level quoting
|
|
92
92
|
// matters inside `cmd`.
|
|
93
|
+
// wsl.exe 连不上发行版的 VM(注册了、显示 Running,但 init 不可达):任何 `wsl -d` 立刻以
|
|
94
|
+
// 4294967295(-1)退出,stdout 是 UTF-16 的 Windows 套接字错误「由于连接方在一段时间后没有正确答复
|
|
95
|
+
// …连接尝试失败」。实测 `wsl --shutdown` 后恢复。据此标记,bootstrap 遇到就重置一次再重试。
|
|
96
|
+
function isWslVmUnreachable(err) {
|
|
97
|
+
if (!err) return false;
|
|
98
|
+
const code = err.code === 4294967295 || err.code === -1 || err.code === 0xffffffff;
|
|
99
|
+
let text = "";
|
|
100
|
+
try { const raw = err.stdout || ""; text = Buffer.isBuffer(raw) ? raw.toString("utf16le") : String(raw); } catch {}
|
|
101
|
+
try { text += Buffer.from(String(err.stdout || ""), "binary").toString("utf16le"); } catch {}
|
|
102
|
+
const msg = /连接尝试失败|connection attempt failed|没有正确答复|did not properly respond|0x80072746|0x8007274c/i.test(text + " " + (err.message || ""));
|
|
103
|
+
return code && msg || (code && /^Command failed: [^\n]*wsl[^\n]*\n?\s*$/.test(err.message || "") && !err.stderr);
|
|
104
|
+
}
|
|
93
105
|
function wslRun(cmd, { timeout = 60000, distro = DISTRO } = {}) {
|
|
94
106
|
return new Promise((resolve, reject) => {
|
|
95
107
|
execFile(docker.wslExe(), ["-d", distro, "-u", "root", "--", "bash", "-lc", cmd],
|
|
96
108
|
{ timeout, windowsHide: true, maxBuffer: 1 << 26 },
|
|
97
109
|
(err, stdout, stderr) => {
|
|
98
|
-
if (err) { err.stdout = String(stdout || ""); err.stderr = String(stderr || ""); return reject(err); }
|
|
110
|
+
if (err) { err.stdout = String(stdout || ""); err.stderr = String(stderr || ""); err.wslVmUnreachable = isWslVmUnreachable(err); return reject(err); }
|
|
99
111
|
resolve({ stdout: String(stdout), stderr: String(stderr) });
|
|
100
112
|
});
|
|
101
113
|
});
|
|
@@ -844,11 +856,20 @@ async function runContainer({ port = 8008, container = "cicy-code-docker", volum
|
|
|
844
856
|
// must then NOT open with a wrong/host token — that strands the user at login).
|
|
845
857
|
// 原则:执行什么命令、输出什么、报什么错,全都要可见(onLog),且每一步可重试。
|
|
846
858
|
// onLog({ status, message }) —— 上层把它接进 drawer。不传也安全(默认静默 + 写 log 文件)。
|
|
859
|
+
// 失败节流:WSL 卡死时每次 readContainerToken 都会起 wsl.exe 挂 8s+,多个调用方(标签恢复 /
|
|
860
|
+
// openTeam / 守护循环)每 10 秒来一次 → 僵死的 wsl.exe 越积越多。读不到就记一下,60 秒内直接返回 ""。
|
|
861
|
+
let _tokenFailAt = 0;
|
|
847
862
|
async function readContainerToken(port = 8008, container = "cicy-code-docker", volume = "cicy-team-8008", { onLog } = {}) {
|
|
848
863
|
const say = (status, message) => {
|
|
849
864
|
try { (status === "error" ? log.warn : log.info)(`[readContainerToken] ${message}`); } catch (e) {}
|
|
850
865
|
try { onLog && onLog({ status, message }); } catch (e) {}
|
|
851
866
|
};
|
|
867
|
+
if (Date.now() - _tokenFailAt < 60000) return "";
|
|
868
|
+
const _r = await _readContainerTokenOnce(port, container, volume, say);
|
|
869
|
+
if (!_r) _tokenFailAt = Date.now();
|
|
870
|
+
return _r;
|
|
871
|
+
}
|
|
872
|
+
async function _readContainerTokenOnce(port, container, volume, say) {
|
|
852
873
|
const volCmd = `cat /var/lib/docker/volumes/${volume}/_data/cicy-ai/global.json`;
|
|
853
874
|
const execCmd = `docker exec ${container} cat /home/cicy/cicy-ai/global.json`;
|
|
854
875
|
for (let attempt = 1; attempt <= 5; attempt++) {
|
|
@@ -1288,7 +1309,16 @@ async function _bootstrap({ onProgress, port = 8008, container = "cicy-code-dock
|
|
|
1288
1309
|
// 3) Docker Engine inside Ubuntu
|
|
1289
1310
|
begin("install-docker-engine");
|
|
1290
1311
|
if (!(await dockerInstalled())) {
|
|
1291
|
-
try { await installDockerEngine({ emit }); } catch (e) {
|
|
1312
|
+
try { await installDockerEngine({ emit }); } catch (e) {
|
|
1313
|
+
if (e && e.wslVmUnreachable) {
|
|
1314
|
+
// VM 半死:wsl.exe 连不上 init。重置 WSL(terminate + shutdown)后由下一轮自动重试。
|
|
1315
|
+
fail("wsl_vm_unreachable", e.message);
|
|
1316
|
+
emit({ phase: "install-docker", status: "running", message: "wsl.exe 连不上 WSL 虚拟机(半死状态),正在重置 WSL 后自动重试…" });
|
|
1317
|
+
try { await wslTerminate(); } catch {}
|
|
1318
|
+
try { await wslShutdown(); } catch {}
|
|
1319
|
+
finish(false, "wsl_vm_unreachable"); return { ok: false, reason: "wsl_vm_unreachable", message: "WSL 虚拟机无响应,已重置,稍后自动重试" };
|
|
1320
|
+
}
|
|
1321
|
+
fail("docker_install_failed", e.message); emit({ phase: "install-docker", status: "error", message: `Docker 安装失败:${e.message}(点重试)${errTail(e)}` }); finish(false, "docker_install_failed"); return { ok: false, reason: "docker_install_failed" }; }
|
|
1292
1322
|
done();
|
|
1293
1323
|
} else done(true);
|
|
1294
1324
|
|
|
@@ -122,3 +122,15 @@ test("a wedged WSL (status unknown) is auto-repaired, then auto-rebooted if stil
|
|
|
122
122
|
const w = read("src/sidecar/wsl-docker.js");
|
|
123
123
|
assert.match(w, /const stillHung = async \(\) => \(await lxssWedged\(\)\) \|\| \(await distroInstalled\(\)\) === null;/);
|
|
124
124
|
});
|
|
125
|
+
|
|
126
|
+
test("readContainerToken throttles after a failure so a wedged WSL is not hammered", () => {
|
|
127
|
+
const w = read("src/sidecar/wsl-docker.js");
|
|
128
|
+
assert.match(w, /if \(Date\.now\(\) - _tokenFailAt < 60000\) return "";/);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("an unreachable WSL VM (socket timeout from wsl.exe) resets WSL and retries instead of failing docker install", () => {
|
|
132
|
+
const w = read("src/sidecar/wsl-docker.js");
|
|
133
|
+
assert.match(w, /function isWslVmUnreachable\(err\)/);
|
|
134
|
+
assert.match(w, /err\.wslVmUnreachable = isWslVmUnreachable\(err\)/);
|
|
135
|
+
assert.match(w, /if \(e && e\.wslVmUnreachable\) \{[^]*await wslTerminate\(\)[^]*await wslShutdown\(\)[^]*reason: "wsl_vm_unreachable"/);
|
|
136
|
+
});
|