cicy-desktop 2.1.297 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.297",
3
+ "version": "2.1.298",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -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
- const { stdout } = await wslRunStream(`docker load -i "${p}"`, { emit, phase: "image", timeout: 600000 });
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 端逻辑一致。
@@ -86,3 +86,10 @@ test("kernel install falls back to the raw kernel file when msiexec is absent",
86
86
  assert.match(d, /msiexec missing or failed/);
87
87
  assert.match(read(".github/workflows/windows-exe-release.yml"), /wsl-kernel\/kernel/);
88
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
+ });