perf: preinstall desktop QA helpers

This commit is contained in:
Peter Steinberger 2026-05-05 19:57:03 +01:00
parent c1eb1dd666
commit bbda2d46ea
No known key found for this signature in database
8 changed files with 20 additions and 12 deletions

View File

@ -10,6 +10,7 @@
### Fixed
- Fixed managed Linux desktop/browser leases to preinstall video capture and native addon build helpers, avoiding per-scenario apt installs in browser QA runs.
- Fixed managed Linux desktop bootstrap performance by using a lean Openbox/Xvfb desktop stack instead of the heavier XFCE meta package.
- Fixed SSH readiness progress logs to distinguish open TCP ports, failed SSH authentication, and failed Crabbox ready checks.
- Fixed auto-shell command reconstruction so arguments with spaces stay quoted when shell operators such as `&&` are present.

View File

@ -146,7 +146,7 @@ host's VNC or Screen Sharing prompt.
| Provider / target | Managed VNC | Notes |
| --- | --- | --- |
| Hetzner Linux | Yes | Requires `--desktop`; installs XFCE, Xvfb, and x11vnc. |
| Hetzner Linux | Yes | Requires `--desktop`; installs Openbox, Xvfb, x11vnc, and capture tools. |
| AWS Linux | Yes | Requires `--desktop`; same Linux desktop profile. |
| AWS Windows | Yes | Requires `--target windows --desktop`; installs Git for Windows and TightVNC after EC2Launch enables OpenSSH. Spot or On-Demand follows the AWS capacity config. |
| AWS macOS | Yes | Requires `--target macos --desktop --market on-demand` plus `CRABBOX_AWS_MAC_HOST_ID` or `aws.macHostId`. |

View File

@ -26,10 +26,13 @@ Bootstrap installs:
Bootstrap intentionally does not install project language runtimes such as Go, Node, pnpm, Docker, databases, or service dependencies. Those belong in GitHub Actions hydration, devcontainers, Nix, mise/asdf, or repository setup scripts. A brokered machine should not pass readiness until `crabbox-ready` succeeds over SSH.
Interactive desktop tooling is an optional lease profile, not part of the
minimal bootstrap. See [Interactive desktop and VNC](interactive-desktop-vnc.md)
for the planned boundary: Crabbox owns the desktop/VNC machine capability, while
scenario systems own browser automation and proof artifacts.
Interactive desktop and browser tooling are optional lease profiles, not part
of the minimal bootstrap. The desktop profile installs Xvfb/Openbox, x11vnc,
screenshots, and video capture tools. The browser profile installs
Chrome/Chromium plus native addon build helpers that browser-channel QA often
needs during dependency fallback installs. Crabbox owns these machine
capabilities; scenario systems still own browser automation and proof artifacts.
See [Interactive desktop and VNC](interactive-desktop-vnc.md).
Tailscale is optional too. `--tailscale` on a managed Linux lease installs the
Tailscale package, joins the configured tailnet, writes non-secret metadata

View File

@ -24,8 +24,10 @@ Managed Linux desktop leases include:
- Xvfb on `:99`;
- a lightweight desktop/window-manager session;
- x11vnc bound to `127.0.0.1:5900`;
- screenshot and video capture tools (`scrot` and `ffmpeg`);
- a generated per-lease VNC password at `/var/lib/crabbox/vnc.password`;
- optional Chrome stable or Chromium fallback when `--browser` is requested;
- optional Chrome stable or Chromium fallback, first-run suppression, and native
addon build helpers when `--browser` is requested;
- readiness checks that verify desktop services when `desktop=true`.
`crabbox run --desktop` injects `CRABBOX_DESKTOP=1` and `DISPLAY=:99`.

View File

@ -528,7 +528,7 @@ func cloudInitOptionalBootstrap(cfg Config) string {
parts = append(parts, cloudInitTailscaleBootstrap(cfg))
}
if cfg.Desktop {
parts = append(parts, ` retry apt-get install -y --no-install-recommends xvfb openbox x11vnc xauth dbus-x11 x11-xserver-utils xterm scrot xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
parts = append(parts, ` retry apt-get install -y --no-install-recommends xvfb openbox x11vnc xauth dbus-x11 x11-xserver-utils xterm scrot ffmpeg xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
install -d -m 0750 -o crabbox -g crabbox /var/lib/crabbox
if [ ! -s /var/lib/crabbox/vnc.password ]; then
(umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)
@ -540,7 +540,7 @@ func cloudInitOptionalBootstrap(cfg Config) string {
systemctl enable --now crabbox-xvfb.service crabbox-desktop.service crabbox-desktop-session.service crabbox-x11vnc.service`)
}
if cfg.Browser {
parts = append(parts, ` retry apt-get install -y --no-install-recommends gnupg
parts = append(parts, ` retry apt-get install -y --no-install-recommends gnupg build-essential python3
browser_path=""
if [ "$(dpkg --print-architecture)" = "amd64" ]; then
install -d -m 0755 /etc/apt/trusted.gpg.d

View File

@ -57,7 +57,7 @@ func TestCloudInitDesktopProfile(t *testing.T) {
got := cloudInit(cfg, "ssh-ed25519 test")
for _, want := range []string{
"xvfb openbox x11vnc xauth dbus-x11",
"x11-xserver-utils xterm scrot xdotool wmctrl",
"x11-xserver-utils xterm scrot ffmpeg xdotool wmctrl",
"/etc/systemd/system/crabbox-xvfb.service",
"/etc/systemd/system/crabbox-desktop.service",
"/usr/local/bin/crabbox-desktop-session",
@ -84,6 +84,7 @@ func TestCloudInitBrowserProfile(t *testing.T) {
cfg.Browser = true
got := cloudInit(cfg, "ssh-ed25519 test")
for _, want := range []string{
"gnupg build-essential python3",
"https://dl.google.com/linux/linux_signing_key.pub",
"chmod 0644 /etc/apt/trusted.gpg.d/google.asc",
"https://dl.google.com/linux/chrome/deb/",

View File

@ -408,7 +408,7 @@ function optionalBootstrap(config: LeaseConfig): string {
parts.push(tailscaleBootstrap(config));
}
if (config.desktop) {
parts.push(` retry apt-get install -y --no-install-recommends xvfb openbox x11vnc xauth dbus-x11 x11-xserver-utils xterm scrot xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
parts.push(` retry apt-get install -y --no-install-recommends xvfb openbox x11vnc xauth dbus-x11 x11-xserver-utils xterm scrot ffmpeg xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
install -d -m 0750 -o crabbox -g crabbox /var/lib/crabbox
if [ ! -s /var/lib/crabbox/vnc.password ]; then
(umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)
@ -420,7 +420,7 @@ function optionalBootstrap(config: LeaseConfig): string {
systemctl enable --now crabbox-xvfb.service crabbox-desktop.service crabbox-desktop-session.service crabbox-x11vnc.service`);
}
if (config.browser) {
parts.push(` retry apt-get install -y --no-install-recommends gnupg
parts.push(` retry apt-get install -y --no-install-recommends gnupg build-essential python3
browser_path=""
if [ "$(dpkg --print-architecture)" = "amd64" ]; then
install -d -m 0755 /etc/apt/trusted.gpg.d

View File

@ -79,7 +79,7 @@ describe("cloud-init bootstrap", () => {
expect(got).toContain("ExecStart=/usr/bin/openbox");
expect(got).toContain("systemctl is-active --quiet crabbox-desktop.service");
expect(got).toContain("systemctl is-active --quiet crabbox-desktop-session.service");
expect(got).toContain("x11-xserver-utils xterm scrot xdotool wmctrl");
expect(got).toContain("x11-xserver-utils xterm scrot ffmpeg xdotool wmctrl");
expect(got).toContain("xsetroot -solid '#20242b'");
expect(got).toContain("xterm -title 'Crabbox Desktop'");
expect(got).toContain("(umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)");
@ -105,6 +105,7 @@ describe("cloud-init bootstrap", () => {
it("adds browser setup only when requested", () => {
const got = cloudInit({ ...config, browser: true });
expect(got).toContain("gnupg build-essential python3");
expect(got).toContain("https://dl.google.com/linux/linux_signing_key.pub");
expect(got).toContain("chmod 0644 /etc/apt/trusted.gpg.d/google.asc");
expect(got).toContain("https://dl.google.com/linux/chrome/deb/");