cicy-desktop 2.1.298 → 2.1.299
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
|
@@ -147,8 +147,8 @@ function register({ sidecarLogPath } = {}) {
|
|
|
147
147
|
let _autoBootstrapPaused = null;
|
|
148
148
|
let _autoBootstrapRetryAt = 0; // 硬失败后的自动重试时间点(退避,不是永久暂停:用户不会自己修)
|
|
149
149
|
// 退避:子进程被拦(安全软件开机后一段时间会自己放行)2 分钟一试;其余 15 分钟一试。
|
|
150
|
-
const AUTO_RETRY_MS = { spawn_blocked: 2 * 60 * 1000, default: 15 * 60 * 1000 };
|
|
151
|
-
const HARD_BOOTSTRAP_REASONS = new Set(["spawn_blocked", "virtualization_disabled", "wsl_enable_failed", "wsl_kernel_missing", "wsl_reboot_required"]);
|
|
150
|
+
const AUTO_RETRY_MS = { spawn_blocked: 2 * 60 * 1000, windows_component_store_broken: 6 * 60 * 60 * 1000, virtualization_disabled: 60 * 60 * 1000, default: 15 * 60 * 1000 };
|
|
151
|
+
const HARD_BOOTSTRAP_REASONS = new Set(["spawn_blocked", "virtualization_disabled", "wsl_enable_failed", "windows_component_store_broken", "wsl_kernel_missing", "wsl_reboot_required"]);
|
|
152
152
|
function recordBootstrapResult(result, err) {
|
|
153
153
|
if (err) {
|
|
154
154
|
const code = err && err.code;
|
package/src/sidecar/docker.js
CHANGED
|
@@ -738,7 +738,10 @@ function elevatedWslSetup({ emit, need = {} } = {}) {
|
|
|
738
738
|
'Say "start admin=$(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(\'Administrators\'))"',
|
|
739
739
|
'$feats = @("Microsoft-Windows-Subsystem-Linux","VirtualMachinePlatform")',
|
|
740
740
|
'$bad = @(); foreach ($f in $feats) { if ((St $f) -ne 1) { $c = En $f; if ($c -ne 0 -and $c -ne 3010) { $bad += $f } } }',
|
|
741
|
-
|
|
741
|
+
`$REPAIRED = "${path.join(dir, "wsl-repair-attempted.txt").replace(/"/g, '""')}"`,
|
|
742
|
+
'if ($bad.Count -gt 0 -and (Test-Path $REPAIRED)) { Say "repair already attempted before and the feature still cannot be enabled — skipping the 30-min repair; this Windows image is missing the feature payload (reinstall/repair Windows needed)" }',
|
|
743
|
+
'if ($bad.Count -gt 0 -and -not (Test-Path $REPAIRED)) {',
|
|
744
|
+
' Set-Content -Path $REPAIRED -Value (Get-Date -Format s)',
|
|
742
745
|
' Say "repair: DISM /RestoreHealth (component store refused: $($bad -join \',\')) — this can take 10-30 min"',
|
|
743
746
|
' & $DISM /online /cleanup-image /restorehealth /norestart | Out-Null; Say ("restorehealth exit=" + $LASTEXITCODE)',
|
|
744
747
|
' & $SFC /scannow | Out-Null; Say ("sfc exit=" + $LASTEXITCODE)',
|
|
@@ -768,7 +771,7 @@ function elevatedWslSetup({ emit, need = {} } = {}) {
|
|
|
768
771
|
try { lines = fs.readFileSync(resultFile, "utf8").split(/\r?\n/).filter(Boolean); } catch {}
|
|
769
772
|
for (const l of lines.slice(seen)) {
|
|
770
773
|
emit && emit({ phase: "install-docker", status: "running", message: `提权脚本:${l.replace(/^\[[^\]]*\] /, "")}` });
|
|
771
|
-
if (/exit=(?!0\b|3010\b)\d
|
|
774
|
+
if (/exit=(?!0\b|3010\b)\d+|repair already attempted/.test(l)) detail = l;
|
|
772
775
|
}
|
|
773
776
|
seen = lines.length;
|
|
774
777
|
if (lines.some((l) => /DONE/.test(l))) break;
|
|
@@ -869,10 +872,13 @@ async function ensureWsl({ emit } = {}) {
|
|
|
869
872
|
const r = await elevatedWslSetup({ emit, need: { subsystem: !subsystemEnabled, vmPlatform: !vmPlatformEnabled } });
|
|
870
873
|
const a = r.subsystem, b = r.vmPlatform;
|
|
871
874
|
if (!a || !b) {
|
|
872
|
-
const
|
|
875
|
+
const storeBroken = /exit=(14107|3017)|repair already attempted/.test(r.detail || "");
|
|
876
|
+
const message = storeBroken
|
|
877
|
+
? `Windows 系统组件缺失或损坏,无法启用「虚拟机平台」(DISM 修复后仍失败,错误 14107)。这台 Windows 需要用安装镜像修复(DISM /Source)或重装系统后才能使用 WSL2/Docker。`
|
|
878
|
+
: `WSL 功能未能全部启用(Linux 子系统=${a ? "已启用" : "失败"},虚拟机平台=${b ? "已启用" : "失败"}${r.detail ? `;${r.detail}` : ";通常是 UAC 被取消或当前账号无管理员权限"})——会自动重试;也可以点「重试」。`;
|
|
873
879
|
log.error(`[bootstrap] ✗ ensure-wsl reason=wsl_enable_failed subsystem=${a} vmPlatform=${b}`);
|
|
874
880
|
emit && emit({ phase: "done", status: "error", message });
|
|
875
|
-
return { ok: false, needsReboot: false, failed: true, reason: "wsl_enable_failed", message };
|
|
881
|
+
return { ok: false, needsReboot: false, failed: true, reason: storeBroken ? "windows_component_store_broken" : "wsl_enable_failed", message };
|
|
876
882
|
}
|
|
877
883
|
// Best-effort: also pull the WSL2 kernel/plumbing when the executable itself
|
|
878
884
|
// is missing. Feature-only repairs must stop here and wait for reboot.
|
|
@@ -93,3 +93,10 @@ test("image load survives a missing /mnt/c mount (drvfs retry, then stdin pipe)"
|
|
|
93
93
|
assert.match(w, /function loadImageViaStdin\(/);
|
|
94
94
|
assert.match(w, /\["-d", DISTRO, "-u", "root", "--", "docker", "load"\]/);
|
|
95
95
|
});
|
|
96
|
+
|
|
97
|
+
test("a broken component store is reported once and backed off for hours, not re-repaired every 15 min", () => {
|
|
98
|
+
const d = read("src/sidecar/docker.js");
|
|
99
|
+
assert.match(d, /wsl-repair-attempted\.txt/);
|
|
100
|
+
assert.match(d, /reason: storeBroken \? "windows_component_store_broken" : "wsl_enable_failed"/);
|
|
101
|
+
assert.match(read("src/backends/sidecar-ipc.js"), /windows_component_store_broken: 6 \* 60 \* 60 \* 1000/);
|
|
102
|
+
});
|
|
@@ -14,7 +14,7 @@ test("ensureWsl explains a disabled-virtualization host in the log and the card"
|
|
|
14
14
|
assert.match(ensure, /reason: "virtualization_disabled"/);
|
|
15
15
|
assert.match(ensure, /log\.error\(`\[bootstrap\] ✗ ensure-wsl reason=virtualization_disabled/);
|
|
16
16
|
assert.match(ensure, /BIOS/);
|
|
17
|
-
assert.match(ensure, /reason: "wsl_enable_failed", message/);
|
|
17
|
+
assert.match(ensure, /reason: storeBroken \? "windows_component_store_broken" : "wsl_enable_failed", message/);
|
|
18
18
|
assert.match(read("src/sidecar/wsl-docker.js"), /const reason = w\.reason \|\| "wsl_enable_failed"; fail\(reason, w\.message\)/);
|
|
19
19
|
const ipc = read("src/backends/sidecar-ipc.js");
|
|
20
20
|
assert.match(ipc, /lastError: \(!s\.running && _lastBootstrapError\)/);
|