agent-dev-env 0.1.0-canary.2.fbbd044
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/LICENSE +21 -0
- package/README.md +106 -0
- package/dist/assets/bridge/bridge.js +202 -0
- package/dist/assets/guest/guest-agent-mac.js +586 -0
- package/dist/assets/guest/guest-agent-ubuntu.js +481 -0
- package/dist/assets/guest/guest-agent-windows.js +466 -0
- package/dist/assets/images/mac/CHANGELOG.md +265 -0
- package/dist/assets/images/mac/README.md +63 -0
- package/dist/assets/images/mac/sandbox.pkr.hcl +468 -0
- package/dist/assets/images/mac/vars/sandbox-macos-tahoe.pkrvars.hcl +39 -0
- package/dist/assets/images/ubuntu-arm64-vmware/CHANGELOG.md +239 -0
- package/dist/assets/images/ubuntu-arm64-vmware/README.md +177 -0
- package/dist/assets/images/ubuntu-arm64-vmware/autoinstall/meta-data +2 -0
- package/dist/assets/images/ubuntu-arm64-vmware/autoinstall/user-data +34 -0
- package/dist/assets/images/ubuntu-arm64-vmware/sandbox.pkr.hcl +776 -0
- package/dist/assets/images/ubuntu-arm64-vmware/vars/sandbox-ubuntu-24-04-arm64-vmware.pkrvars.hcl +71 -0
- package/dist/assets/images/windows-arm64-qemu/CHANGELOG.md +209 -0
- package/dist/assets/images/windows-arm64-qemu/README.md +142 -0
- package/dist/assets/images/windows-arm64-qemu/autounattend.xml +325 -0
- package/dist/assets/images/windows-arm64-qemu/qemu-with-tpm.sh +170 -0
- package/dist/assets/images/windows-arm64-qemu/sandbox.pkr.hcl +1012 -0
- package/dist/assets/images/windows-arm64-qemu/vars/sandbox-windows-11-arm64-qemu.pkrvars.hcl +83 -0
- package/dist/assets/images/windows-arm64-vmware/CHANGELOG.md +270 -0
- package/dist/assets/images/windows-arm64-vmware/README.md +171 -0
- package/dist/assets/images/windows-arm64-vmware/autounattend.xml +311 -0
- package/dist/assets/images/windows-arm64-vmware/sandbox.pkr.hcl +1036 -0
- package/dist/assets/images/windows-arm64-vmware/vars/sandbox-windows-11-arm64-vmware.pkrvars.hcl +83 -0
- package/dist/assets/rules/agent-rules-linux.md +68 -0
- package/dist/assets/rules/agent-rules.md +71 -0
- package/dist/assets/watchdog/watch-build-ocr.swift +40 -0
- package/dist/assets/watchdog/watch-build.py +275 -0
- package/dist/cli.js +52 -0
- package/dist/commands/delete.js +179 -0
- package/dist/commands/doctor.js +165 -0
- package/dist/commands/list.js +38 -0
- package/dist/commands/not-yet.js +15 -0
- package/dist/commands/register.js +150 -0
- package/dist/commands/run.js +65 -0
- package/dist/commands/status.js +142 -0
- package/dist/commands/stop.js +186 -0
- package/dist/commands/sync.js +98 -0
- package/dist/lib/exec.js +250 -0
- package/dist/lib/ghcr.js +82 -0
- package/dist/lib/git.js +100 -0
- package/dist/lib/logger.js +87 -0
- package/dist/lib/network.js +63 -0
- package/dist/lib/paths.js +116 -0
- package/dist/lib/platform.js +87 -0
- package/dist/lib/prompt.js +66 -0
- package/dist/lib/qemu.js +373 -0
- package/dist/lib/regex.js +9 -0
- package/dist/lib/ssh.js +230 -0
- package/dist/lib/tart.js +210 -0
- package/dist/lib/template.js +35 -0
- package/dist/lib/vars.js +99 -0
- package/dist/lib/vmrun.js +334 -0
- package/dist/lifecycle/build-macos.js +23 -0
- package/dist/lifecycle/build-qemu.js +204 -0
- package/dist/lifecycle/build-shared.js +355 -0
- package/dist/lifecycle/build-ubuntu.js +184 -0
- package/dist/lifecycle/build-watchdog.js +146 -0
- package/dist/lifecycle/build-windows-vmware.js +112 -0
- package/dist/lifecycle/build.js +55 -0
- package/dist/lifecycle/catalog.js +165 -0
- package/dist/lifecycle/deploy.js +161 -0
- package/dist/lifecycle/tag.js +77 -0
- package/dist/lifecycle/watch-build.js +64 -0
- package/dist/runners/bridges.js +156 -0
- package/dist/runners/framework.js +66 -0
- package/dist/runners/macos-bridges.js +143 -0
- package/dist/runners/macos-guest.js +76 -0
- package/dist/runners/macos-rules.js +77 -0
- package/dist/runners/macos-summary.js +145 -0
- package/dist/runners/macos.js +258 -0
- package/dist/runners/openchamber.js +60 -0
- package/dist/runners/options.js +56 -0
- package/dist/runners/qemu-image.js +183 -0
- package/dist/runners/rules.js +49 -0
- package/dist/runners/ubuntu-bridges.js +154 -0
- package/dist/runners/ubuntu-guest.js +136 -0
- package/dist/runners/ubuntu-image.js +26 -0
- package/dist/runners/ubuntu-rules.js +86 -0
- package/dist/runners/ubuntu-shared.js +65 -0
- package/dist/runners/ubuntu-summary.js +141 -0
- package/dist/runners/ubuntu.js +117 -0
- package/dist/runners/vmware-common.js +158 -0
- package/dist/runners/vmware-image.js +242 -0
- package/dist/runners/windows-autologon.js +119 -0
- package/dist/runners/windows-bridges.js +136 -0
- package/dist/runners/windows-guest.js +213 -0
- package/dist/runners/windows-image.js +23 -0
- package/dist/runners/windows-qemu-summary.js +85 -0
- package/dist/runners/windows-qemu.js +189 -0
- package/dist/runners/windows-shared.js +68 -0
- package/dist/runners/windows-summary.js +104 -0
- package/dist/runners/windows.js +96 -0
- package/dist/settings/common.js +107 -0
- package/dist/settings/macos-copy.js +223 -0
- package/dist/settings/macos.js +41 -0
- package/dist/settings/ubuntu-copy.js +223 -0
- package/dist/settings/ubuntu.js +68 -0
- package/package.json +52 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Ubuntu sandbox images (VMware).
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
The image version lives in the image's vars file (`image_version`); every
|
|
9
|
+
release bumps it, adds an entry below, and tags the release commit
|
|
10
|
+
`<platform>-v<version>` (e.g. `ubuntu-arm64-vmware-v1.0.0`). The
|
|
11
|
+
`[Unreleased]` section on top is never removed — changes land there until
|
|
12
|
+
the next release.
|
|
13
|
+
|
|
14
|
+
## [Unreleased]
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Host user settings sync into the Ubuntu guest** — the runner now copies
|
|
19
|
+
the host's user settings into the guest like the macOS sandbox does
|
|
20
|
+
(opencode config + auth, OpenCodeReview config, Copilot config + skills,
|
|
21
|
+
VS Code extensions + user config, mcp-compress-router settings, SSH
|
|
22
|
+
dotfiles, `.gitconfig`), once per VM, tracked by a versioned marker
|
|
23
|
+
(`~/.config/agent-dev-env/settings-copied`), with `--no-settings` to skip
|
|
24
|
+
and `agent-dev-env sync` (ubuntu-vmware) to re-sync on demand. The
|
|
25
|
+
shared logic is `settings/ubuntu.ts` + `settings/ubuntu-copy.ts` (ssh2
|
|
26
|
+
transport, host-to-guest path mapping for the VS Code user dir and
|
|
27
|
+
mcp-compress-router, `.gitconfig` rewritten for `/home/admin`,
|
|
28
|
+
OpenChamber restart). See `docs/ubuntu-vmware.md`.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Node.js is bumped from 22 to 26 (`node_version = "26"` in the vars
|
|
33
|
+
file): nvm installs Node 26 and sets it as the default.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **The shared host directory no longer fails when the share is
|
|
38
|
+
registered before VMware Tools are up** — `agent-dev-env run`
|
|
39
|
+
(ubuntu-vmware) called `vmrun addSharedFolder` as soon as sshd answered,
|
|
40
|
+
but open-vm-tools can still be starting then: `getGuestIPAddress`/sshd
|
|
41
|
+
were already up while the tools state vmrun needs for the HGFS
|
|
42
|
+
registration was not, so the runner logged `Error: The VMware Tools are
|
|
43
|
+
not running in the virtual machine` and `/mnt/hgfs/work` never appeared
|
|
44
|
+
in the guest. The runner now waits for `vmrun checkToolsState` to report
|
|
45
|
+
`running` (up to 5 min) and retries `addSharedFolder` a few times, then
|
|
46
|
+
warns only if it still failed. A share persisted by a previous run
|
|
47
|
+
(`Error: Already exists`) is treated as success.
|
|
48
|
+
- **Host user settings copy no longer fails on the root-owned `~/.local`** —
|
|
49
|
+
the sync unpack hit `tar: Cannot utime` / `Permission denied` and aborted:
|
|
50
|
+
the image's `install -d -o admin -g admin
|
|
51
|
+
/home/admin/.local/share ...` left the *intermediate* `.local` directory
|
|
52
|
+
root-owned (install only applies `-o/-g` to its operands), so the sandbox
|
|
53
|
+
user could not write into `~/.local` or restore its timestamps during
|
|
54
|
+
`tar -C $HOME` extraction. `install -d` now lists `/home/admin/.local`
|
|
55
|
+
as its own operand, and the runner's settings copy
|
|
56
|
+
(`settings/ubuntu-copy.ts`) chowns `~/.local` back to the
|
|
57
|
+
sandbox user before unpacking (via `sudo -S` with the guest password the
|
|
58
|
+
runner already knows), so existing images are fixed on the next run
|
|
59
|
+
without a rebuild. The copy also strips macOS AppleDouble companions
|
|
60
|
+
(`._*`) and `.DS_Store` from the staged archive and cleans up any `._*`
|
|
61
|
+
junk a previous partial copy left in the guest — the AppleDouble files
|
|
62
|
+
were packed as ordinary files, and one of them (`._share`) is what first
|
|
63
|
+
made the extraction hit the root-owned directory.
|
|
64
|
+
- **mcp-compress-router settings land where the router looks for them** —
|
|
65
|
+
the settings copy mapped the host's
|
|
66
|
+
`~/Library/Application Support/mcp-compress-router/` to
|
|
67
|
+
`~/.config/mcp-compress-router/`, but mcp-compress-router's
|
|
68
|
+
`defaultConfigDir` on Linux is the XDG **data** dir,
|
|
69
|
+
`~/.local/share/mcp-compress-router/` (a different path from macOS and
|
|
70
|
+
Windows), so the synced `mcp.json`/credentials were never picked up.
|
|
71
|
+
The mapping now targets `~/.local/share/mcp-compress-router/` (where
|
|
72
|
+
`mcp.json`/`.jsonc`, `credentials.json`, `tools-cache.json` and `.env`
|
|
73
|
+
all live), the settings version was bumped so already-provisioned
|
|
74
|
+
guests re-copy, and the unpack drops the stale `~/.config` copy.
|
|
75
|
+
- **The build watchdog no longer misses the grub menu** — the Ubuntu build
|
|
76
|
+
can fail with "Timeout waiting for SSH" when the grub autoinstall
|
|
77
|
+
command is never typed: grub's menu countdown is ~20 s wide, but
|
|
78
|
+
`assets/watchdog/watch-build.py` polled once per ~2 min (90 s worker
|
|
79
|
+
timeout + 20 s sleep), so the menu default booted the interactive
|
|
80
|
+
Subiquity installer and the build sat on the installer's proxy screen
|
|
81
|
+
until SSH timed out. The supervisor now fast-polls (3 s interval — the
|
|
82
|
+
worker timeout stays at 90 s, since a kill mid-typing would corrupt the
|
|
83
|
+
grub shell input line) while the autoinstall command is untyped (no
|
|
84
|
+
`.boot-typed` marker), falling back to the old slow cadence once typed
|
|
85
|
+
or after a 4 min cap; the relaying is unchanged. The build flow's
|
|
86
|
+
watchdog stop also kills the supervisor's in-flight `--worker`
|
|
87
|
+
children (they survive a supervisor kill and keep the VNC port open,
|
|
88
|
+
blocking the next build).
|
|
89
|
+
|
|
90
|
+
## [ubuntu-arm64-vmware-v1.1.0] - 2026-08-25
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **GNOME desktop in the image** — `ubuntu-desktop-minimal` (GNOME Shell +
|
|
95
|
+
GDM3 + core apps) and `open-vm-tools-desktop` (SVGA Xorg driver,
|
|
96
|
+
clipboard, drag-and-drop) are installed by the Packer provisioners, the
|
|
97
|
+
VM boots to `graphical.target`, and GDM3 auto-logs in `admin` — the
|
|
98
|
+
Fusion window opens straight on the desktop (VS Code, Firefox,
|
|
99
|
+
OpenChamber-in-browser). The session runs on Xorg (`WaylandEnable=false`):
|
|
100
|
+
Fusion guests get no GPU acceleration, and the Xorg session works best
|
|
101
|
+
with the open-vm-tools input drivers. Display is
|
|
102
|
+
software-rendered (llvmpipe) — for human interaction, not 3D.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- The grub kernel command is typed by the **build watchdog**
|
|
107
|
+
(`scripts/watch-build.py` gained a `WATCH_BUILD_BOOT_CMD` mode: grub
|
|
108
|
+
menu/shell detected in the OCR → type the autoinstall command, once per
|
|
109
|
+
build, marker-guarded) instead of the Packer `boot_command` — the
|
|
110
|
+
firmware's No-Media/PXE probe cycle before grub appears is
|
|
111
|
+
variable-length (~20-40 s on Fusion), so packer-side typing fired
|
|
112
|
+
before grub was up and the menu's default entry booted the interactive
|
|
113
|
+
Subiquity installer. A `boot-typed.png` frame is captured after typing
|
|
114
|
+
for debugging.
|
|
115
|
+
- The autoinstall seed is served by a small HTTP server the build wrapper
|
|
116
|
+
starts on a fixed port (`python3 -m http.server 8004` over
|
|
117
|
+
`autoinstall/`; the seed is fetched via
|
|
118
|
+
`ds=nocloud-net;s=http://<vmnet8-host>:8004/`) instead of
|
|
119
|
+
`http_directory` — the plugin's HTTP server uses a random port and does
|
|
120
|
+
not accept an `http_port` override, and the URL must be known when the
|
|
121
|
+
grub command is typed. The vmnet8 host address is read from Fusion's
|
|
122
|
+
DHCP config.
|
|
123
|
+
- `identity.password` in the seed uses a clean crypt salt (the previous
|
|
124
|
+
salt contained '!', not a valid crypt salt character).
|
|
125
|
+
|
|
126
|
+
### Fixed
|
|
127
|
+
|
|
128
|
+
- The provisioner heredocs used `$$` for shell variables (HCL only
|
|
129
|
+
escapes `$${`; bash expanded `$$` to its PID — observed as `$NVM_DIR`
|
|
130
|
+
set to "4330HOME/.nvm"). They now use plain `$`.
|
|
131
|
+
- `set_vm_display_name` in `scripts/lib/vmware.sh` matched only the
|
|
132
|
+
camelCase `displayName` key, but `vmrun clone` writes lowercase
|
|
133
|
+
`displayname` — the rename then *appended* a second, case-variant key,
|
|
134
|
+
and Fusion refuses a vmx with duplicate keys ("Cannot read the virtual
|
|
135
|
+
machine configuration file"), so the runner's first `vmrun start` failed
|
|
136
|
+
on freshly cloned VMs. It now matches case-insensitively and writes the
|
|
137
|
+
canonical lowercase key, dropping duplicates.
|
|
138
|
+
- The guest-side bridge setup used plain `sudo`, but the runner's SSH
|
|
139
|
+
sessions are deliberately pty-less (raw-stdin uploads depend on it), so
|
|
140
|
+
sudo failed with "a terminal is required". `sudo` now runs with `-S`
|
|
141
|
+
(password from stdin, answered by the runner's expect session, whose
|
|
142
|
+
prompt pattern matches "[sudo] password for ..." too), and
|
|
143
|
+
`guest-setup.sh` writes the profile.d file to a temp path and installs
|
|
144
|
+
it with `sudo -S install` — `sudo -S tee <<EOF` would eat the first
|
|
145
|
+
heredoc line as the password.
|
|
146
|
+
- The base apt list uses the 24.04 `t64` names (`libasound2t64`,
|
|
147
|
+
`libfuse2t64`, `libgtk-3-0t64`) — the plain names have no install
|
|
148
|
+
candidates.
|
|
149
|
+
- Docker plugin installs use the `docker-` prefixed names
|
|
150
|
+
(`docker-compose`, `docker-buildx` — docker only discovers prefixed
|
|
151
|
+
plugin files) and mirror them into the user plugin dirs; the buildx
|
|
152
|
+
URL includes the release's `v` prefix (the tag and asset are
|
|
153
|
+
`v0.36.1`/`buildx-v0.36.1.linux-arm64`).
|
|
154
|
+
- opencode is installed via the official installer script
|
|
155
|
+
(`curl https://opencode.ai/install | bash`) — the npm package
|
|
156
|
+
postinstall mis-selects the arm64-musl binary on glibc systems
|
|
157
|
+
(EBADPLATFORM) — and the XDG dirs (`~/.local/share` and friends) are
|
|
158
|
+
pre-created with correct ownership (opencode's first run hit EACCES).
|
|
159
|
+
- Google Chrome is not part of the image: CfT publishes no linux-arm64
|
|
160
|
+
build (only x86_64 linux64) and Ubuntu's chromium is snap-only; Firefox
|
|
161
|
+
(official linux-aarch64 releases) is the browser.
|
|
162
|
+
- The final verification checks nvm/node/npm, opencode/ocr/openchamber
|
|
163
|
+
and rust through the sandbox user (they live in the user's home, and
|
|
164
|
+
the verification shell runs as root).
|
|
165
|
+
- Removed the invalid `user-data:`/`late-commands` blocks from the seed:
|
|
166
|
+
subiquity's schema rejected them ("Cloud config schema errors ...
|
|
167
|
+
Additional properties are not allowed"), aborting autoinstall —
|
|
168
|
+
despite the seed being served fine. The seed exactly matches the first
|
|
169
|
+
proven build.
|
|
170
|
+
|
|
171
|
+
## [ubuntu-arm64-vmware-v1.0.0] - 2026-08-25
|
|
172
|
+
|
|
173
|
+
### Added
|
|
174
|
+
|
|
175
|
+
- **New platform: Ubuntu 24.04 LTS (ARM64) sandbox image for VMware
|
|
176
|
+
Fusion** — `images/ubuntu-arm64-vmware/`:
|
|
177
|
+
- `sandbox.pkr.hcl` — Packer `vmware-iso` template (same Proven
|
|
178
|
+
ARM64 wiring as the Windows VMware image: `guest_os_type
|
|
179
|
+
"arm-ubuntu-64"`, hardware version 20, NVMe disk, vmxnet3 NIC under
|
|
180
|
+
NAT, EFI firmware, headless + VNC on the pinned port 5901). Ubuntu
|
|
181
|
+
Server 24.04 ARM64 is autoinstalled via Subiquity: the installer
|
|
182
|
+
kernel gets `autoinstall ds=nocloud-net;s=http://.../` in the
|
|
183
|
+
`boot_command` and fetches `autoinstall/user-data` +
|
|
184
|
+
`meta-data` from Packer's HTTP server (LVM layout, user
|
|
185
|
+
`admin`/sandbox1, openssh-server, open-vm-tools). Provisioned over
|
|
186
|
+
SSH; the image ships the same toolchain as the other sandboxes
|
|
187
|
+
(apt base toolchain, hash-pinned Go/Rust/nvm Node/GitHub CLI/VS
|
|
188
|
+
Code/Chrome CfT/Firefox/Docker CLI + compose + buildx, npm globals
|
|
189
|
+
opencode/`ocr`/OpenChamber). OpenChamber runs as a systemd **user**
|
|
190
|
+
service (`agent-dev-env-openchamber`, linger enabled) on
|
|
191
|
+
`0.0.0.0:4000`.
|
|
192
|
+
- `vars/sandbox-ubuntu-24-04-arm64-vmware.pkrvars.hcl` — Ubuntu point
|
|
193
|
+
release, ISO SHA256, all pinned toolchain versions + hashes, VM
|
|
194
|
+
resources, credentials, OpenChamber, `image_version`.
|
|
195
|
+
- `build.sh` — platform wrapper: ISO SHA256 verification, `packer
|
|
196
|
+
init` + `packer build` into `build/ubuntu-arm64-vmware/`, VNC build
|
|
197
|
+
watchdog, post-build `vmrun upgradevm` hardware upgrade (shared
|
|
198
|
+
helper, see below). No driver/tools staging from Fusion is needed —
|
|
199
|
+
the vmxnet3 + NVMe drivers are in-box in the Ubuntu kernel
|
|
200
|
+
(verified: `vmxnet3.ko` ships in the base `linux-modules` package)
|
|
201
|
+
and open-vm-tools come from the Ubuntu archive (Fusion ships no
|
|
202
|
+
Linux tools ISO for arm64 guests).
|
|
203
|
+
- `deploy.sh` — platform wrapper: packs the output directory into a
|
|
204
|
+
tar.gz and pushes `ghcr.io/<owner>/<image>:<version>,latest` as an
|
|
205
|
+
OCI artifact via `oras`.
|
|
206
|
+
- `README.md` — build/publish flow, "What's in the image", gotchas.
|
|
207
|
+
- **`scripts/lib/vmware.sh`** — the generic vmrun helpers (vmrun
|
|
208
|
+
resolution, hardware-version upgrade, vmx displayName) factored out of
|
|
209
|
+
`scripts/lib/windows-vmware/lib.sh` (which is now a thin shim sourcing
|
|
210
|
+
it), shared by both VMware platforms.
|
|
211
|
+
- **`scripts/run-ubuntu-vmware-sandbox.sh`** — user-facing runner: picks
|
|
212
|
+
the archive (env override → local build output → GHCR pull via oras),
|
|
213
|
+
extracts the pristine VM + `vmrun clone`s a working VM (one-time
|
|
214
|
+
hardware-version upgrade), boots it (headless or windowed), discovers
|
|
215
|
+
the guest IP via open-vm-tools, and bridges the host's SSH agent and
|
|
216
|
+
Docker engine into the guest — host-side `socat` on TCP 4400/4401
|
|
217
|
+
bound to the vmnet8 address + guest-side systemd user services
|
|
218
|
+
(`scripts/lib/ubuntu-vmware/guest-setup.sh` renders socat relays for
|
|
219
|
+
`/tmp/ssh-agent.sock` and `/tmp/docker.sock` plus the
|
|
220
|
+
`/etc/profile.d` exports, auto-start via linger). Optionally shares a
|
|
221
|
+
host directory (`--work-dir`, HGFS → `/mnt/hgfs/work`), installs the
|
|
222
|
+
sandbox agent rules (`scripts/agent-rules-linux.md`) into the guest's
|
|
223
|
+
opencode + Copilot configs, and verifies OpenChamber.
|
|
224
|
+
- **`scripts/stop-ubuntu-vmware-sandbox.sh` / `delete-ubuntu-vmware-sandbox.sh`** —
|
|
225
|
+
stop the working VM (`vmrun -T fusion stop`, graceful + hard fallback)
|
|
226
|
+
and kill the host bridge listeners; delete the state dir (extracted
|
|
227
|
+
base + working clone + pulled image cache) after a confirmation.
|
|
228
|
+
- **`scripts/agent-rules-linux.md`** — sandbox environment rules for the
|
|
229
|
+
Ubuntu guest (shared-directory path mapping, host Docker engine via
|
|
230
|
+
`/tmp/docker.sock`, published ports at the NAT gateway, SSH agent
|
|
231
|
+
socket).
|
|
232
|
+
- **Docs**: `docs/linux.md` replaces its "not supported yet" placeholder
|
|
233
|
+
with the full Ubuntu VMware sandbox guide; `README.md`,
|
|
234
|
+
`DEVELOPMENT.md` and `AGENTS.md` list the new platform and the
|
|
235
|
+
shared `scripts/lib/vmware.sh` helper.
|
|
236
|
+
|
|
237
|
+
[unreleased]: https://github.com/ameshkov/agent-dev-env/compare/ubuntu-arm64-vmware-v1.1.0...HEAD
|
|
238
|
+
[ubuntu-arm64-vmware-v1.1.0]: https://github.com/ameshkov/agent-dev-env/releases/tag/ubuntu-arm64-vmware-v1.1.0
|
|
239
|
+
[ubuntu-arm64-vmware-v1.0.0]: https://github.com/ameshkov/agent-dev-env/releases/tag/ubuntu-arm64-vmware-v1.0.0
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Ubuntu Sandbox Images — VMware
|
|
2
|
+
|
|
3
|
+
Ubuntu 24.04 LTS (ARM64) sandbox VM images built with
|
|
4
|
+
[Packer](https://www.packer.io/) and the
|
|
5
|
+
[VMware plugin](https://github.com/vmware/packer-plugin-vmware)
|
|
6
|
+
(`vmware-iso` builder) on an Apple Silicon Mac. The output is a runnable
|
|
7
|
+
vmx + vmdk VM (built at the vmware-iso hardware level, upgraded post-build
|
|
8
|
+
to the host Fusion's current hardware version — see
|
|
9
|
+
[How to Build](#how-to-build)), packed into a tar.gz for publishing; the
|
|
10
|
+
macOS host runs it under Fusion's `vmrun` CLI. Fusion
|
|
11
|
+
virtualizes ARM64 guests natively; the guest uses **open-vm-tools** from
|
|
12
|
+
the Ubuntu archive (Fusion ships no VMware Tools for arm64 Linux — the
|
|
13
|
+
`isoimages/arm64/` folder contains only `windows.iso`), which provide
|
|
14
|
+
`vmrun getGuestIPAddress`, graceful power operations and HGFS shared
|
|
15
|
+
folders.
|
|
16
|
+
|
|
17
|
+
The sibling images are the macOS
|
|
18
|
+
([Tart](../mac/README.md)) and Windows 11 ARM64
|
|
19
|
+
([QEMU](../windows-arm64-qemu/README.md),
|
|
20
|
+
[VMware](../windows-arm64-vmware/README.md)) sandboxes. See
|
|
21
|
+
[docs/ubuntu-vmware.md](../../docs/ubuntu-vmware.md) for the user
|
|
22
|
+
guide (boot it with `npx agent-dev-env run ubuntu-vmware`).
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
- Apple Silicon Mac (M-series). Fusion cannot virtualize ARM64 guests on
|
|
27
|
+
Intel, so this image is ARM64-only.
|
|
28
|
+
- [VMware Fusion](https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion)
|
|
29
|
+
(free for personal use; the Packer plugin requires Fusion 13.6+).
|
|
30
|
+
- [Packer](https://www.packer.io/): `brew install hashicorp/tap/packer`
|
|
31
|
+
(the VMware plugin is installed automatically by `packer init`).
|
|
32
|
+
- The **Ubuntu Server 24.04 ARM64 ISO** — bring your own, ~3 GB:
|
|
33
|
+
|
|
34
|
+
1. Download the latest point release from
|
|
35
|
+
https://cdimage.ubuntu.com/releases/24.04/release/ — the
|
|
36
|
+
`ubuntu-24.04.x-live-server-arm64.iso` file.
|
|
37
|
+
2. Copy its SHA256 from the release `SHA256SUMS`
|
|
38
|
+
(https://cdimage.ubuntu.com/releases/24.04/release/SHA256SUMS) into
|
|
39
|
+
`iso_sha256` in the vars file.
|
|
40
|
+
3. Set `UBUNTU_ISO_PATH` to its absolute path when building.
|
|
41
|
+
|
|
42
|
+
That is all: the guest's vmxnet3 NIC and NVMe disk drivers are in-box in
|
|
43
|
+
the Ubuntu kernel (vmxnet3.ko ships in the base `linux-modules` package),
|
|
44
|
+
and open-vm-tools come from the Ubuntu archive — no driver or tools
|
|
45
|
+
staging from Fusion is needed (unlike the Windows image).
|
|
46
|
+
|
|
47
|
+
## How to Build
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# From the repository root
|
|
51
|
+
UBUNTU_ISO_PATH=/path/to/ubuntu-24.04.4-live-server-arm64.iso \
|
|
52
|
+
npx agent-dev-env build sandbox-ubuntu-24-04-arm64-vmware
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`agent-dev-env` is the CLI shipped by this repo (see
|
|
56
|
+
[docs/cli.md](../../docs/cli.md)). The ubuntu-vmware build flow:
|
|
57
|
+
|
|
58
|
+
1. Verifies the host (Apple Silicon), the local ISO (SHA256 against
|
|
59
|
+
`iso_sha256` from the vars file) and the Fusion install (only needed
|
|
60
|
+
for the post-build hardware upgrade).
|
|
61
|
+
2. Starts the autoinstall seed server (`python3 -m http.server 8004`
|
|
62
|
+
over `autoinstall/`) and runs `packer init` + `packer build`. The
|
|
63
|
+
build is headless with **no `boot_command` typing**: the build
|
|
64
|
+
watchdog (see below) waits for the grub menu/shell in the VNC OCR and
|
|
65
|
+
types the autoinstall kernel line
|
|
66
|
+
(`ds=nocloud-net;s=http://<vmnet8-host>:8004/` — the firmware's
|
|
67
|
+
No-Media/PXE probe cycle before grub appears is variable-length, so
|
|
68
|
+
the plugin's own typing was unreliable). Subiquity fetches the seed:
|
|
69
|
+
LVM over the whole disk, user `admin` (password from the vars file),
|
|
70
|
+
openssh-server, open-vm-tools — then reboots into the installed system
|
|
71
|
+
and is provisioned over SSH.
|
|
72
|
+
3. Runs the VNC **build watchdog** (bundled `assets/watchdog/`) alongside
|
|
73
|
+
`packer build` (pinned VNC port 5901) to auto-dismiss installer dialogs
|
|
74
|
+
and rescue a boot that lands in the UEFI shell. Needs
|
|
75
|
+
`pip3 install vncdotool` + Xcode command line tools; skipped with a
|
|
76
|
+
warning when missing.
|
|
77
|
+
4. Upgrades the output VM with `vmrun upgradevm` to the hardware version
|
|
78
|
+
the installed Fusion writes for a new VM (hardware version 20 → 22 on
|
|
79
|
+
Fusion 26). The headless build never shows Fusion's one-time
|
|
80
|
+
"Upgrade this virtual machine?" prompt, but a first GUI start of a
|
|
81
|
+
version-20 VM would; the upgrade also rewrites the vmdk descriptor.
|
|
82
|
+
The runner upgrades its working clone the same way for artifacts built
|
|
83
|
+
by older Fusion versions (see
|
|
84
|
+
[docs/ubuntu-vmware.md](../../docs/ubuntu-vmware.md)).
|
|
85
|
+
|
|
86
|
+
A build takes roughly 30 minutes on an M-series Mac (the Ubuntu installer
|
|
87
|
+
dominates, plus the ~8 min GNOME desktop apt install; Fusion runs the
|
|
88
|
+
guest near-native). Everything per image lives under the CLI's data root:
|
|
89
|
+
`~/Library/Application Support/agent-dev-env/build/ubuntu-vmware/output/`
|
|
90
|
+
(the vmx + vmdk + nvram), plus `packer_cache/`. The macOS/tart images
|
|
91
|
+
build no files and have no such directory.
|
|
92
|
+
|
|
93
|
+
## What's in the image
|
|
94
|
+
|
|
95
|
+
| Component | Detail |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| Ubuntu Server 24.04 LTS (ARM64) | Point release from the vars file; LVM over the whole disk |
|
|
98
|
+
| open-vm-tools | From the Ubuntu archive (Fusion ships no Linux tools for arm64); enables `vmrun getGuestIPAddress`, soft power ops, HGFS shared folders |
|
|
99
|
+
| GNOME desktop | `ubuntu-desktop-minimal` + `open-vm-tools-desktop`; boots to `graphical.target`, GDM3 auto-login as `admin`, Xorg session (software-rendered — no GPU accel in a Fusion arm64 guest) |
|
|
100
|
+
| apt toolchain | build-essential (gcc/g++/make), cmake, autoconf, git, curl, wget, jq, ripgrep, vim, tmux, socat, python3 + pip/venv, ruby; browser + X libs for Firefox |
|
|
101
|
+
| Go | `go<version>` tarball from go.dev/dl, hash-pinned; `/usr/local/go` |
|
|
102
|
+
| Rust | Via rustup (arm64 host toolchain), `rust`/`cargo` on PATH |
|
|
103
|
+
| Node.js | Via nvm (major from the vars file, default alias); npm globals in the nvm dir |
|
|
104
|
+
| GitHub CLI | `gh_<version>_linux_arm64.deb`, hash-pinned |
|
|
105
|
+
| Visual Studio Code | `code_<version>_arm64.deb`, hash-pinned; `code` on PATH |
|
|
106
|
+
| Firefox | Official linux-aarch64 release tarball, hash-pinned; `/opt/firefox` (no Chrome: CfT publishes no linux-arm64 build, Ubuntu's chromium is snap-only) |
|
|
107
|
+
| Docker CLI | Client only (`docker` + `docker compose` + `docker buildx`, static aarch64 binaries, hash-pinned); no engine — bridged from the host |
|
|
108
|
+
| OpenCode (`opencode-ai`) | npm global |
|
|
109
|
+
| OpenCodeReview (`ocr`) | npm global (`@alibaba-group/open-code-review`) |
|
|
110
|
+
| OpenChamber web UI | npm global (`@openchamber/web`), systemd **user** service (`agent-dev-env-openchamber`) on `0.0.0.0:4000`, started at boot (`loginctl enable-linger`) |
|
|
111
|
+
| SSH | openssh-server with password auth; `admin`/sandbox1 (see the vars file); Ubuntu's default cloud-init finalization |
|
|
112
|
+
| systemd user services | Linger enabled for `admin`; the guest agent's bridge services and OpenChamber auto-start in the guest |
|
|
113
|
+
|
|
114
|
+
## Versioning
|
|
115
|
+
|
|
116
|
+
Same convention as the other images: the image version lives in
|
|
117
|
+
`image_version` in the vars file; every release bumps it, adds a
|
|
118
|
+
`CHANGELOG.md` entry, and creates a `ubuntu-arm64-vmware-v<version>` git
|
|
119
|
+
tag via `npx agent-dev-env tag <image>`.
|
|
120
|
+
|
|
121
|
+
## Running and publishing
|
|
122
|
+
|
|
123
|
+
- Run the sandbox: `npx agent-dev-env run ubuntu-vmware` — extracts
|
|
124
|
+
the archive, clones a working VM with `vmrun`, discovers the guest IP
|
|
125
|
+
via open-vm-tools, and bridges the host's Docker engine and SSH agent
|
|
126
|
+
into the guest (see
|
|
127
|
+
[docs/ubuntu-vmware.md](../../docs/ubuntu-vmware.md)).
|
|
128
|
+
- Publish: `npx agent-dev-env deploy sandbox-ubuntu-24-04-arm64-vmware`
|
|
129
|
+
packs the output directory into `${image_name}.tar.gz` and pushes it to
|
|
130
|
+
`ghcr.io/<owner>/sandbox-ubuntu-24-04-arm64-vmware:<version>` +
|
|
131
|
+
`:latest` as an OCI artifact via `oras` (the CLI packs and pushes
|
|
132
|
+
directly — no platform wrapper — because `tart push` only works for
|
|
133
|
+
Tart VMs). Needs `brew install oras` and a GHCR token with
|
|
134
|
+
`write:packages` (`oras login ghcr.io`).
|
|
135
|
+
|
|
136
|
+
## Gotchas
|
|
137
|
+
|
|
138
|
+
- **The Ubuntu ISO is not in the repo.** The build fails fast without
|
|
139
|
+
`UBUNTU_ISO_PATH`; the sha256 in the vars file protects against a
|
|
140
|
+
corrupt download. The ISO is ~3 GB.
|
|
141
|
+
- **ARM64 only.** Fusion on Intel can only run x86_64 guests, so this
|
|
142
|
+
image requires Apple Silicon.
|
|
143
|
+
- **Fusion 13.6+ and the VMware plugin v2+.** The template uses
|
|
144
|
+
`github.com/vmware/vmware` (Broadcom's maintained fork); the older
|
|
145
|
+
`github.com/hashicorp/vmware` plugin has different options.
|
|
146
|
+
- **No VMware Tools from Fusion — ever.** Fusion's arm64 `isoimages/`
|
|
147
|
+
folder ships only `windows.iso`; open-vm-tools are the only in-guest
|
|
148
|
+
tools available for arm64 Linux VMs. The image installs them from the
|
|
149
|
+
Ubuntu archive, so their version tracks Ubuntu, not Fusion.
|
|
150
|
+
- **The autoinstall seed comes over the build flow's HTTP server, and the
|
|
151
|
+
grub typing is done by the build watchdog.** The seed is fetched via
|
|
152
|
+
`ds=nocloud-net` from `python3 -m http.server 8004` (`autoinstall/`),
|
|
153
|
+
and the bundled `watch-build.py` types the kernel command when grub
|
|
154
|
+
appears (`WATCH_BUILD_BOOT_CMD`; the firmware's No-Media/PXE probe
|
|
155
|
+
cycle before grub is variable-length, so the plugin's own boot_command
|
|
156
|
+
typing was unreliable and could boot the interactive Subiquity installer
|
|
157
|
+
— a build then hangs waiting for SSH; check the VNC watchdog frames in
|
|
158
|
+
`~/Library/Application Support/agent-dev-env/build/ubuntu-vmware/packer_cache/watchdog/`).
|
|
159
|
+
The watchdog polls every 3 s until the command is typed (grub's menu
|
|
160
|
+
countdown is ~20 s wide — the slow ~2 min-per-frame poll could miss it
|
|
161
|
+
entirely), then relaxes to the slow cadence.
|
|
162
|
+
- **Keep `autoinstall/user-data` in sync with the vars file**: the seed
|
|
163
|
+
bakes the sandbox user (name + crypt hash of `ssh_password`). Change
|
|
164
|
+
the credentials in the vars file *and* the `identity:` block together.
|
|
165
|
+
- **No snapshot in the published image.** `snapshot_name` is deliberately
|
|
166
|
+
unset: the sandbox runner makes a *full* clone as its working VM, and a
|
|
167
|
+
snapshot inside the published archive would only complicate disk
|
|
168
|
+
compaction and re-cloning.
|
|
169
|
+
- **The shared folder is best-effort.** HGFS via `vmhgfs-fuse`
|
|
170
|
+
(`open-vm-tools`) is mounted by the runner at `/mnt/hgfs/work`; a
|
|
171
|
+
missing mount is a warning, not an error (git, OpenChamber UI, and the
|
|
172
|
+
agent bridges do not need it).
|
|
173
|
+
- **The desktop is software-rendered.** A Fusion arm64 guest has no GPU
|
|
174
|
+
acceleration, so GNOME runs on llvmpipe (Xorg session,
|
|
175
|
+
`WaylandEnable=false` in GDM3's custom.conf). It is meant for human
|
|
176
|
+
interaction (VS Code, Firefox, OpenChamber in a browser) — not for 3D
|
|
177
|
+
work; the agents do not use the GUI at all.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#cloud-config
|
|
2
|
+
#
|
|
3
|
+
# Subiquity autoinstall seed for the Ubuntu sandbox image — served by
|
|
4
|
+
# Packer's HTTP server (http_directory, ds=nocloud-net) and fetched by the
|
|
5
|
+
# installer kernel, as configured by the boot_command in
|
|
6
|
+
# sandbox.pkr.hcl.
|
|
7
|
+
#
|
|
8
|
+
# Keep in sync with sandbox.pkr.hcl:
|
|
9
|
+
# - identity.password is the crypt hash of var.ssh_password ("sandbox1"),
|
|
10
|
+
# - identity.username is var.ssh_username ("admin"),
|
|
11
|
+
# - the ssh block enables sshd + password auth for Packer's communicator.
|
|
12
|
+
#
|
|
13
|
+
# Everything else (toolchain, OpenChamber, ...) is installed by the
|
|
14
|
+
# provisioners — this seed only gets a bootable system with SSH + tools
|
|
15
|
+
# (open-vm-tools must be present before the first boot so `vmrun
|
|
16
|
+
# getGuestIPAddress` works immediately in the sandbox runner).
|
|
17
|
+
autoinstall:
|
|
18
|
+
version: 1
|
|
19
|
+
locale: en_US.UTF-8
|
|
20
|
+
keyboard:
|
|
21
|
+
layout: us
|
|
22
|
+
timezone: UTC
|
|
23
|
+
identity:
|
|
24
|
+
hostname: ubuntu-sandbox
|
|
25
|
+
username: admin
|
|
26
|
+
password: "$6$rand0mS4lt$fgNjBzoL2PEvCW.OGnGIH/13sT54EDF3C0SB2WHzcQla4uvGel3BErD87ZhQTW/7eFv.Mtoaenc7t0UzKEh6q0"
|
|
27
|
+
ssh:
|
|
28
|
+
install-server: true
|
|
29
|
+
allow-pw: true
|
|
30
|
+
storage:
|
|
31
|
+
layout:
|
|
32
|
+
name: lvm
|
|
33
|
+
packages:
|
|
34
|
+
- open-vm-tools
|