10 Commits
Author SHA1 Message Date
James Stringer 6d2e10fd0b Fix Ubuntu ISO build dependency version selection 2026-09-13 13:14:44 -04:00
James Stringer 978f52b8f5 Fix VM setup, storage, snapshots, and viewer behavior 2026-09-07 13:02:28 -04:00
James Stringer e5acdaaf8b Add ARM64 support for the Linux guest (iso-patch)
iso-patch builds an arm64 Ubuntu VHDX: the grub/shim/EFI, apt, dxcore and
mesa paths are selected from the build arch at compile time via the new
target_arch.h, and the arm64 serial console is ttyAMA0 (PL011) not ttyS0.
x64 behavior is unchanged. (Windows-on-ARM support landed in the previous
commit.)

Known issue: an arm64 Ubuntu 26.04 LTS guest boots very slowly on this
platform and is not usable in practice yet — Windows is the supported
arm64 guest for now. The 26.04 generic kernel is built
CONFIG_BPF_JIT_ALWAYS_ON (+RODATA_FULL), so systemd's constant BPF churn
JIT-allocs and frees executable memory, and each free issues a broadcast
cross-CPU TLB/cache-maintenance op (TLBI ..IS). arm64 has no Hyper-V
paravirt TLB flush, so the hypervisor traps every one and the cost scales
with vCPU count; the host's experimental Insider Hyper-V services them
slowly. Fewer vCPUs or a stable Hyper-V build mitigate it.

Also trim the previous commit's ARM code comments down to the essential
architectural differences.
2026-06-05 18:42:50 -04:00
James Stringer 8cda2fe452 Harden iso-patch image parsing and build/cleanup paths
- C1/C2/H7/H8/H9 engine/squashfs.c: validate block_size (non-zero, power
  of two, == 1<<block_log, <= 1 MiB); bound walk_directory to the dir
  stream; bound the inode block_sizes[] list and each per-block write to
  the output buffer.
- C6/H6 engine/ext4.c: cap inodes_per_group at BLOCK_SIZE*8 and size the
  inode table by whole blocks so the bitmap/table buffers can't overrun.
- C7 + M8-sibling iso-patch.c: bound qcow2 l1_size (reject under/oversize,
  avoid 32-bit length overflow) and propagate IStream::Read failures.
- H10/H11 prefetch_build_deps.c: reject an over-long Filename and clamp
  WriteFile lengths derived from snprintf return values.
- L17 prefetch_wsl_deps.c: route download/extract/copy failures through a
  cleanup label that removes the unique temp directory.
- M10/M11 ubuntu_vhdx.c: abort (don't finalize a partial VHDX) when the
  squashfs walk reports errors; stop and join workers if a thread fails
  to start so they can't touch the freed stack-local pipeline.
2026-06-02 21:51:32 -04:00
James Stringer 0e1ad3cbe3 Remove dead vhdx_create_differencing_resized (no callers)
The resized differencing-create helper was only used by the removed
cloud-image flow (it stretched a small cached cloud-image base to the
user-requested disk size). Confirmed zero callers repo-wide. Delete the
definition (disk_util.c) + declaration (disk_util.h) and drop the comment
reference in iso-patch.c's raw_to_vhdx. The plain vhdx_create_differencing
stays — still used by the template + snapshot paths. Both binaries rebuild
clean.
2026-05-30 15:01:40 -04:00
James Stringer 434bfb64ab Build-on-VM provisioning + modal-driven SSH credentials
Replace the prebuilt-ELF/prebuilt-.ko shipping model with three
in-process prefetchers that populate per-VM staging from authoritative
sources at create time:

  --prefetch-repo         GitHub tarball (agent + DKMS sources, units)
  --prefetch-build-deps   archive.ubuntu.com Packages closure walk
                          (xz-embedded for Packages.xz, BCrypt SHA-256
                          verify, synthetic Packages file for offline apt)
  --prefetch-wsl-deps     Microsoft NuGet libd3d12*/libdxcore.so

The Ubuntu guest's firstboot script then builds the agent from source
(make + make install), installs both kernel modules via DKMS, and
optionally enables openssh-server — all offline, against an isolated
apt sources dir pinned to /opt/appsandbox/local-apt{,-extras}.

xz-embedded gained CRC64 support (XZ_USE_CRC64 + xz_crc64.c compiled in)
because Ubuntu's Packages.xz uses 0x04/CRC64 in its stream check; without
this the decoder bails at the first block header. Decompression also
streams to disk in 4 MiB chunks instead of buffering the whole ~50 MiB
output in RAM.

Linux VM credentials now flow from the create-VM modal:
  - host hashes admin_pass into glibc $6$ SHA-512 (unix_password_hash,
    same path Windows autounattend uses); plaintext is wiped immediately
  - two marker files staged into the rootfs:
      /etc/appsandbox-admin-user   (UTF-8 username)
      /etc/appsandbox-admin-hash   (consumed and wiped by STEP 5)
  - firstboot useradd + usermod -p so /etc/shadow gets the hash directly
  - gdm autologin + GNOME OOBE skip now use $ASB_USER, not hardcoded test
  - SSH gated on /etc/appsandbox-ssh-enabled marker; STEP 7.5 installs
    openssh-server from local-apt-extras, enables ssh.service + ssh.socket,
    opens ufw

ComPorts/com1 restored as a Linux-only debug pipe — systemd's
console output goes to \.\pipe\<vm>.com1 so the host can see firstboot
progress without an SSH session into the guest.

STEP 17 verification now resolves the asb_drm card by walking
/sys/class/drm/card*/device/driver instead of hardcoding card0 — with
efifb=off and asb-evict-simpledrm.service, asb_drm lands as card1.
2026-05-27 21:53:46 -04:00
James Stringer 2135f5cbeb Direct Ubuntu ISO->VHDX build (no subiquity, no cidata)
iso-patch.exe gains a new --ubuntu-to-vhdx mode that produces a fully
installed, bootable Ubuntu VHDX in one shot:
  - vendored xz-embedded + custom ext4 writer + squashfs reader
  - mounts the ISO, partitions GPT (ESP + Linux root), streams
    casper/minimal.squashfs into a freshly-built ext4 rootfs through
    a producer/N-decompress-worker/single-writer pipeline
  - installs signed shim + grub from the ISO's pool .debs onto ESP,
    writes a redirect grub.cfg pointing at the rootfs by UUID
  - plants a defensive one-shot first-boot systemd unit that runs
    grub-install + update-grub + AppSandbox guest setup (agent ELFs,
    kernel modules, systemd units, wsl-mesa, wsl-deps, ldconfig,
    no-sleep dconf, etc.) and reboots

linux_create_thread now spawns iso-patch with --ubuntu-to-vhdx
and a --stage manifest covering the full extras tree (reuses
stage_linux_agent_and_extras to populate a staging dir then walks
it). image_path is cleared post-build so the ISO isn't re-attached
to the runtime VM. ComPorts/com1 named pipe and the do_connect_rdp
window path are dropped (IDD is the only live display path now).

VideoMonitor stays unconditional (vmwp.exe crashes 0xC0000005
without it) — but with no ConnectionOptions/named pipe, matching
master.

JS frontend: "Installing Linux" branch added so the spinner label
no longer says "Installing Windows" for Linux VMs. Progress %
now tracks ingest fraction (n_processed / total_inodes) mapped
into 10..75%, with post-ingest phases at 82..99%.
2026-05-25 22:34:57 -04:00
James Stringer 2309cec029 Add Linux VM support with GPU-PV
Ubuntu 26.04 LTS guest end-to-end:

- cidata-driven autoinstall pipeline (subiquity user-data + nested
  cloud-init bootcmd) in disk_util.c. Static NAT IP, ssh-via-vsock
  marker, serial-debug kernel cmdline injected into ESP grub.cfg by
  iso-patch.exe. Five separate firstboot pipeline fixes get the VM
  to GDM unattended on Hyper-V Gen 2.

- Linux guest stack under tools/linux/:
    - appsandbox-agent  (vsock :1 control + clipboard helper spawn)
    - appsandbox-audio  (snd-aloop -> vsock :4)
    - appsandbox-display (KMS framebuffer capture -> vsock :2)
    - appsandbox-input  (uinput injection <- vsock :3)
    - appsandbox-clipboard (XCB selection bridge <-> vsock :5/:6)
  Helper binaries staged via release/resources/linux/.

- asb_drm DRM module: virtual single-CRTC display sink the host
  captures over vsock. Platform-bus, DRIVER_GEM/MODESET/ATOMIC/RENDER,
  linear shmem framebuffers. asb-evict-simpledrm.service unbinds the
  EFI simple-framebuffer before display-manager so mutter binds
  asb_drm as the sole DRM card.

- dxgkrnl vendored byte-identical from microsoft/WSL2-Linux-Kernel
  linux-msft-wsl-6.18.y with our DKMS/out-of-tree shim (dxgkrnl_compat.h
  + Kbuild + dkms.conf). Autoinstall late-commands dkms-builds against
  every /target/lib/modules/<kver> so kernel-version drift between ISO
  and post-update reboot still leaves a working .ko.

- wsl-mesa custom build (Mesa 25.3 + d3d12 gallium + microsoft-
  experimental dzn Vulkan). Installs to /opt/wsl-mesa parallel to
  Ubuntu's stock Mesa. Prebuilt tarball for ubuntu-26.04-amd64
  shipped under tools/linux/wsl-mesa/prebuilt/ (21 MB).

- Per-VM GPU acceleration policy:
    - /etc/systemd/user-environment-generators/50-appsandbox-gpu
      emits GALLIUM_DRIVER=d3d12 + LD_LIBRARY_PATH + VK_DRIVER_FILES
      into the user@1000 systemd-user environment when /dev/dxg and
      /opt/wsl-mesa are present. Inherited by every app-*.scope a
      .desktop launch creates.
    - /etc/systemd/user/org.gnome.Shell@.service.d/no-gpu.conf
      UnsetEnvironment= strips these for the compositor — mutter
      stays on llvmpipe so asb_drm scanout works (the d3d12 pipe has
      no GBM compatibility with asb_drm).
    - /usr/local/bin/appsandbox-gpu wrapper for terminal-launched
      opt-in GPU acceleration (probes /dev/dxg; no-op on no-GPU VMs).

- Host changes:
    - vm_display_idd.c, vm_clipboard.c, vm_agent.c, vm_ssh_proxy.c,
      asb_display.c: hcs_service_guid(os_type, port) so the same code
      paths reach the per-OS service identifiers (HV_GUID for Windows,
      vsock template for Linux).
    - asb_core.c: linux_create_thread builds an empty VHDX, cidata
      ISO with extras (agent ELFs, dxgkrnl src, asb_drm src, wsl-mesa
      tarball, wsl-deps libs), and boots the desktop ISO + cidata.
    - hcs_vm.c: HostLxssLib Plan9 share appended for Linux VMs;
      VideoMonitor + ComPorts retained for serial debug.
    - gpu_enum.c/h: gpu_append_lxsslib_share helper.
    - vm_clipboard.c file-drop support (CF_HDROP / x-special/gnome-
      copied-files round-trip).
    - vm_display_idd.c: 32-bit S32_LE PCM audio path matches the
      Linux daemon's snd-aloop capture format.

- iso-patch.c gains a patch_ubuntu_esp_grub_for_debug pass that
  rewrites /EFI/ubuntu/grub.cfg via the FAT32 ESP, plus a qcow2->
  vhdx converter with a RFC 1951 DEFLATE inflater for compressed
  cluster handling.

- wsl-deps: Microsoft's libd3d12.so / libd3d12core.so / libdxcore.so
  fetched on demand from the public NuGet feed
  pkgs.dev.azure.com/shine-oss/wsl (no auth). Staged at
  /opt/appsandbox/wsl-deps on the guest and put on /etc/ld.so.conf.d
  rather than /usr/lib/wsl/lib (which is overlaid by the agent's
  9P mount).

UI: web/{app.js,index.html} expose Linux VM creation + GPU selection,
distribution dropdown for cached Ubuntu ISOs, and the ISO picker for
custom images.
2026-05-19 20:21:43 -04:00
James Stringer e039ebc2e5 auto set VM language based on ISO language 2026-03-19 21:02:22 -04:00
James Stringer 5db568ea4e Initial commit 2026-03-18 18:44:36 -04:00