cicy-desktop 2.1.369 → 2.1.370
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
package/src/sidecar/docker.js
CHANGED
|
@@ -380,7 +380,9 @@ function curlDownload(url, dest, { emit, phase = "image", label = "下载镜像"
|
|
|
380
380
|
// --retry-connrefused (curl 7.52+) covers a not-yet-ready net. On curl 7.71+
|
|
381
381
|
// also add --retry-all-errors so a transient DNS blip (exit 6, common right
|
|
382
382
|
// after app start) retries on the fast curl path instead of the slow node one.
|
|
383
|
-
|
|
383
|
+
// --connect-timeout + --speed-limit/--speed-time:被墙的源几秒就放弃,传着传着卡死(<10KB/s 持续 2 分钟)
|
|
384
|
+
// 也会退出 —— 否则 curl 永远挂着,bootstrap 和守护循环一起卡住(国内链路上真会发生)。
|
|
385
|
+
const args = ["-sL", "-A", DL_UA, "-C", "-", "--connect-timeout", "20", "--speed-limit", "10240", "--speed-time", "120", "--retry", "8", "--retry-delay", "3", "--retry-connrefused"];
|
|
384
386
|
if (curlSupportsRetryAllErrors(bin)) args.push("--retry-all-errors");
|
|
385
387
|
args.push("-o", dest, url);
|
|
386
388
|
let child;
|
|
@@ -88,13 +88,25 @@ function sshConnect() {
|
|
|
88
88
|
}
|
|
89
89
|
// 等价于 wslRun:成功 resolve {stdout, stderr};非零退出 reject(err.stdout/err.stderr/err.code)。
|
|
90
90
|
// opts.stdin:可读流,灌进命令的 stdin(docker load 用)。opts.onLine:逐行回调(流式进度)。
|
|
91
|
+
// ⚠️ 超时必须从调用开始就算(含建连、开通道):虚拟机慢启动时 sshd 可能接了 TCP 却迟迟不开 exec 通道,
|
|
92
|
+
// 以前计时器只在 exec 回调里才挂上 → 回调永不来 → 这个 promise 永不结束 → status()/守护循环整条卡死
|
|
93
|
+
// (xs-2002 2026-10-22 起卡了一夜,docker-status 一直停在旧时间)。
|
|
91
94
|
async function vmRun(cmd, { timeout = 60000, stdin, onLine } = {}) {
|
|
92
|
-
const
|
|
95
|
+
const t0 = Date.now();
|
|
96
|
+
const c = await Promise.race([sshConnect(), new Promise((_, rej) => setTimeout(() => rej(new Error("ssh connect timeout")), Math.min(timeout, 30000)))]);
|
|
93
97
|
return new Promise((resolve, reject) => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
let stream = null, done = false;
|
|
99
|
+
let out = "", errOut = "", buf = "";
|
|
100
|
+
const timer = setTimeout(() => {
|
|
101
|
+
if (done) return; done = true;
|
|
102
|
+
try { stream && stream.close(); } catch {}
|
|
103
|
+
if (!stream) { _conn = null; try { c.end(); } catch {} } // 通道都没开出来:这条连接已不可信,丢掉重连
|
|
104
|
+
reject(Object.assign(new Error(`vmRun timeout after ${timeout}ms: ${cmd.slice(0, 120)}`), { stdout: out, stderr: errOut }));
|
|
105
|
+
}, Math.max(1000, timeout - (Date.now() - t0)));
|
|
106
|
+
c.exec(`sudo -n sh -c ${shQuote(cmd)}`, (err, st) => {
|
|
107
|
+
if (done) { try { st && st.close(); } catch {} return; }
|
|
108
|
+
if (err) { done = true; clearTimeout(timer); _conn = null; try { c.end(); } catch {} return reject(err); }
|
|
109
|
+
stream = st;
|
|
98
110
|
const line = (chunk) => {
|
|
99
111
|
if (!onLine) return;
|
|
100
112
|
buf += chunk;
|
|
@@ -104,6 +116,7 @@ async function vmRun(cmd, { timeout = 60000, stdin, onLine } = {}) {
|
|
|
104
116
|
stream.stderr.on("data", (d) => { const s = d.toString("utf8"); errOut += s; line(s); });
|
|
105
117
|
stream.on("close", (code) => {
|
|
106
118
|
clearTimeout(timer);
|
|
119
|
+
if (done) return; done = true;
|
|
107
120
|
if (code === 0) resolve({ stdout: out, stderr: errOut });
|
|
108
121
|
else reject(Object.assign(new Error(`exit ${code}: ${(errOut || out).trim().slice(-300)}`), { code, stdout: out, stderr: errOut }));
|
|
109
122
|
});
|
package/src/sidecar/qemu-vm.cjs
CHANGED
|
@@ -307,8 +307,10 @@ function httpOk(port, p) {
|
|
|
307
307
|
function accelOf() {
|
|
308
308
|
const t = tailOf(F.qemuLog, 32 * 1024);
|
|
309
309
|
if (!t && !pidAlive(readPid(F.qemuPid))) return "";
|
|
310
|
-
// qemu 依次试 -accel:whpx
|
|
311
|
-
|
|
310
|
+
// qemu 依次试 -accel:whpx 起不来会打「failed to initialize whpx: …」再「falling back to tcg」。
|
|
311
|
+
// 只认这两句 —— WHPX 正常时也会打无害的 warning(如「WHPX: Failed to get performance monitoring
|
|
312
|
+
// features」),以前按「whpx + fail」判,把 9 台跑在 WHPX 上的机器误报成软件模拟(2026-10-23)。
|
|
313
|
+
return /falling back to tcg|failed to initialize whpx/i.test(t) ? "tcg" : "whpx";
|
|
312
314
|
}
|
|
313
315
|
function whpxFeature() { return WIN && fs.existsSync(path.join(process.env.SystemRoot || "C:\\Windows", "System32", "WinHvPlatform.dll")); }
|
|
314
316
|
// 串口日志最后一行可读的话 = 开机进度(给卡片「启动中」下面那一行小字)
|