cicy-desktop 2.1.296 → 2.1.298
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.
|
@@ -119,6 +119,19 @@ jobs:
|
|
|
119
119
|
if (-not $exe) { Write-Error "no exe found in dist"; exit 1 }
|
|
120
120
|
$base = "oss://cicy-1372193042-cn/releases"
|
|
121
121
|
|
|
122
|
+
# 0) WSL2 内核裸文件(一次性,已存在就跳过):精简版 Windows 没有 msiexec 装不了
|
|
123
|
+
# wsl_update_x64.msi,桌面端改为直接下这个文件放到 System32\lxss\tools\kernel。
|
|
124
|
+
$kernelKey = "$base/wsl-kernel/kernel"
|
|
125
|
+
& $oss stat "$kernelKey" 2>$null | Out-Null
|
|
126
|
+
if ($LASTEXITCODE -ne 0) {
|
|
127
|
+
Write-Host "Publishing raw WSL2 kernel -> $kernelKey"
|
|
128
|
+
Invoke-WebRequest -Uri "https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" -OutFile wsl_update_x64.msi
|
|
129
|
+
$kdir = Join-Path $PWD "wsl-kernel-extract"
|
|
130
|
+
Start-Process msiexec.exe -ArgumentList "/a","`"$PWD\wsl_update_x64.msi`"","/qn","TARGETDIR=$kdir" -Wait
|
|
131
|
+
$kfile = Get-ChildItem $kdir -Recurse -File | Where-Object { $_.Name -eq "kernel" } | Select-Object -First 1
|
|
132
|
+
if ($kfile) { & $oss cp "$($kfile.FullName)" "$kernelKey" -f --acl public-read } else { Write-Warning "kernel not found in msi extract" }
|
|
133
|
+
} else { Write-Host "WSL2 kernel already on OSS, skip" }
|
|
134
|
+
|
|
122
135
|
# 1) 永久版本化副本(unique key — 不会被后续发版覆盖)
|
|
123
136
|
$verKey = "$base/cicy-desktop-$version.exe"
|
|
124
137
|
Write-Host "Uploading versioned -> $verKey"
|
package/package.json
CHANGED
package/src/sidecar/docker.js
CHANGED
|
@@ -668,6 +668,8 @@ function featureEnabled(feature) {
|
|
|
668
668
|
}
|
|
669
669
|
|
|
670
670
|
const WSL_KERNEL_MSI_URL = process.env.CICY_WSL_KERNEL_URL || "https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi";
|
|
671
|
+
// 裸内核文件(由发布工作流从 MSI 解出后放到 OSS):精简版 Windows 没有 msiexec 时直接放到位。
|
|
672
|
+
const WSL_KERNEL_RAW_URL = process.env.CICY_WSL_KERNEL_RAW_URL || (require("./mirrors").OSS_RELEASES_BASE + "/wsl-kernel/kernel");
|
|
671
673
|
// WSL2 kernel present? The inbox (feature-based) WSL keeps it at System32\lxss\tools\kernel;
|
|
672
674
|
// the Store WSL bundles its own, in which case the file is absent but `wsl --status`
|
|
673
675
|
// reports a kernel version — callers treat "functional + version" as present too.
|
|
@@ -742,7 +744,15 @@ function elevatedWslSetup({ emit, need = {} } = {}) {
|
|
|
742
744
|
' & $SFC /scannow | Out-Null; Say ("sfc exit=" + $LASTEXITCODE)',
|
|
743
745
|
' foreach ($f in $bad) { $c = En $f }',
|
|
744
746
|
'}',
|
|
745
|
-
|
|
747
|
+
`$KDIR = Join-Path $S32 "lxss\\tools"; $KFILE = Join-Path $KDIR "kernel"`,
|
|
748
|
+
`if (-not (Test-Path $KFILE)) {`,
|
|
749
|
+
` if ((Test-Path $MSIEXEC) -and (Test-Path "${msi.replace(/"/g, '""')}")) { $p = Start-Process $MSIEXEC -ArgumentList "/i","\`"${msi.replace(/"/g, '""')}\`"","/qn","/norestart" -Wait -PassThru; Say ("kernel msi exit=" + $p.ExitCode) }`,
|
|
750
|
+
` if (-not (Test-Path $KFILE)) {`,
|
|
751
|
+
` Say "msiexec missing or failed — downloading the raw WSL2 kernel file"`,
|
|
752
|
+
` New-Item -ItemType Directory -Force $KDIR | Out-Null`,
|
|
753
|
+
` try { Invoke-WebRequest -UseBasicParsing -Uri "${WSL_KERNEL_RAW_URL}" -OutFile $KFILE; Say ("kernel file " + (Get-Item $KFILE).Length + " bytes") } catch { Say ("kernel download failed: " + $_.Exception.Message) }`,
|
|
754
|
+
` }`,
|
|
755
|
+
`}`,
|
|
746
756
|
'Say ("final subsystem=" + (St "Microsoft-Windows-Subsystem-Linux") + " vmPlatform=" + (St "VirtualMachinePlatform"))',
|
|
747
757
|
'Say "DONE"',
|
|
748
758
|
].join("\r\n");
|
|
@@ -559,11 +559,48 @@ function toWslPath(winPath) {
|
|
|
559
559
|
async function loadImage(winTarballPath, { emit } = {}) {
|
|
560
560
|
emit && emit({ phase: "image", status: "loading", message: "正在导入镜像到 Docker(较大,约 1-3 分钟,下面是实时进度)…" });
|
|
561
561
|
const p = toWslPath(winTarballPath);
|
|
562
|
-
|
|
562
|
+
// 精简版 Windows 上见过:发行版里 /mnt/c 没有自动挂载(drvfs 挂载失败),`docker load -i /mnt/c/...`
|
|
563
|
+
// 直接 "no such file"。先探一下;不可读就试手动挂载;还不行就把包从 Windows 侧通过 stdin 灌进
|
|
564
|
+
// `docker load`,完全不依赖 /mnt/c。
|
|
565
|
+
let readable = false;
|
|
566
|
+
try { await wslRun(`test -r "${p}"`, { timeout: 20000 }); readable = true; } catch {}
|
|
567
|
+
if (!readable) {
|
|
568
|
+
try { await wslRun(`mount -t drvfs C: /mnt/c 2>/dev/null || true; test -r "${p}"`, { timeout: 30000 }); readable = true; } catch {}
|
|
569
|
+
}
|
|
570
|
+
let stdout = "";
|
|
571
|
+
if (readable) {
|
|
572
|
+
({ stdout } = await wslRunStream(`docker load -i "${p}"`, { emit, phase: "image", timeout: 600000 }));
|
|
573
|
+
} else {
|
|
574
|
+
emit && emit({ phase: "image", status: "loading", message: "发行版内看不到 /mnt/c,改为通过管道导入镜像(无实时进度,约 1-3 分钟)…" });
|
|
575
|
+
stdout = await loadImageViaStdin(winTarballPath, { emit });
|
|
576
|
+
}
|
|
563
577
|
const m = String(stdout).match(/Loaded image:\s*(\S+)/i);
|
|
564
578
|
if (m && m[1] !== IMAGE) { try { await wslRun(`docker tag ${m[1]} ${IMAGE}`, { timeout: 15000 }); } catch {} }
|
|
565
579
|
}
|
|
566
580
|
|
|
581
|
+
// `type tarball | wsl -d distro docker load`:从 Windows 侧把镜像包流进发行版,不经过 /mnt/c。
|
|
582
|
+
function loadImageViaStdin(winTarballPath, { emit } = {}) {
|
|
583
|
+
return new Promise((resolve, reject) => {
|
|
584
|
+
const child = spawn(docker.wslExe(), ["-d", DISTRO, "-u", "root", "--", "docker", "load"], { windowsHide: true, stdio: ["pipe", "pipe", "pipe"] });
|
|
585
|
+
let out = "", err = "";
|
|
586
|
+
const total = (() => { try { return fs.statSync(winTarballPath).size; } catch { return 0; } })();
|
|
587
|
+
let sent = 0, lastPct = -1;
|
|
588
|
+
const timer = setTimeout(() => { try { child.kill(); } catch {} reject(new Error("docker load (stdin) timed out")); }, 900000);
|
|
589
|
+
child.stdout.on("data", (d) => { out += String(d); });
|
|
590
|
+
child.stderr.on("data", (d) => { err += String(d); });
|
|
591
|
+
child.on("error", (e) => { clearTimeout(timer); reject(e); });
|
|
592
|
+
child.on("close", (code) => { clearTimeout(timer); if (code === 0) resolve(out); else reject(new Error(`docker load (stdin) exit ${code}: ${(err || out).slice(0, 300)}`)); });
|
|
593
|
+
const rs = fs.createReadStream(winTarballPath);
|
|
594
|
+
rs.on("data", (chunk) => {
|
|
595
|
+
sent += chunk.length;
|
|
596
|
+
const pct = total ? Math.floor((sent / total) * 100) : -1;
|
|
597
|
+
if (pct !== lastPct && pct % 5 === 0) { lastPct = pct; emit && emit({ phase: "image", status: "loading", message: `通过管道导入镜像… ${pct}%`, progress: pct }); }
|
|
598
|
+
});
|
|
599
|
+
rs.on("error", (e) => { try { child.kill(); } catch {} reject(e); });
|
|
600
|
+
rs.pipe(child.stdin);
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
|
|
567
604
|
// 修复「卡在旧镜像」: imagePresent() 只看本地有没有 `:latest`,旧镜像在就永远跳过下载。
|
|
568
605
|
// 改成校验 OSS tarball ETag:缺镜像、或 ETag 跟上次 load 不一致 → 重下重载(删旧缓存包)。
|
|
569
606
|
// 非破坏性:不删发行版/不删 volume。返回是否真刷新了。与 colima 端逻辑一致。
|
|
@@ -79,3 +79,17 @@ test("missing WSL2 kernel is installed through the same single elevation", () =>
|
|
|
79
79
|
assert.match(d, /if \(!wslKernelPresent\(\)\) \{[^]*elevatedWslSetup\(\{ emit, need: \{\} \}\)/);
|
|
80
80
|
assert.match(d, /reason: "wsl_kernel_missing"/);
|
|
81
81
|
});
|
|
82
|
+
|
|
83
|
+
test("kernel install falls back to the raw kernel file when msiexec is absent", () => {
|
|
84
|
+
const d = read("src/sidecar/docker.js");
|
|
85
|
+
assert.match(d, /WSL_KERNEL_RAW_URL/);
|
|
86
|
+
assert.match(d, /msiexec missing or failed/);
|
|
87
|
+
assert.match(read(".github/workflows/windows-exe-release.yml"), /wsl-kernel\/kernel/);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("image load survives a missing /mnt/c mount (drvfs retry, then stdin pipe)", () => {
|
|
91
|
+
const w = read("src/sidecar/wsl-docker.js");
|
|
92
|
+
assert.match(w, /mount -t drvfs C: \/mnt\/c/);
|
|
93
|
+
assert.match(w, /function loadImageViaStdin\(/);
|
|
94
|
+
assert.match(w, /\["-d", DISTRO, "-u", "root", "--", "docker", "load"\]/);
|
|
95
|
+
});
|