fix: restore slim xfce desktop leases

This commit is contained in:
Peter Steinberger 2026-05-06 02:35:50 +01:00
parent 0bb34bdcad
commit c9e28c2bf3
No known key found for this signature in database
11 changed files with 35 additions and 23 deletions

View File

@ -14,7 +14,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 managed Linux desktop leases to use a slim XFCE session instead of bare Openbox, preserving a real panel/window-manager desktop while avoiding the full 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.
- Fixed managed Linux bootstrap ordering so SSH is reachable before slow desktop/browser package setup while readiness still waits for the full desktop/browser contract.

View File

@ -146,7 +146,7 @@ host's VNC or Screen Sharing prompt.
| Provider / target | Managed VNC | Notes |
| --- | --- | --- |
| Hetzner Linux | Yes | Requires `--desktop`; installs Openbox, Xvfb, x11vnc, and capture tools. |
| Hetzner Linux | Yes | Requires `--desktop`; installs slim XFCE, 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

@ -97,7 +97,7 @@ Warmup records a local claim tying the lease to the current repo; `--reclaim` ov
browser automation. Managed Linux tries Google Chrome stable first, then a
Chromium package fallback.
`--desktop` provisions Xvfb, Openbox, and loopback-bound x11vnc for visible UI
`--desktop` provisions Xvfb, slim XFCE, and loopback-bound x11vnc for visible UI
automation and operator takeover. It does not imply a browser. Use
`--desktop --browser` when a headed browser should run in the visible display.

View File

@ -29,7 +29,7 @@ Bake machine capabilities:
- current OS security updates;
- SSH, Git, rsync, curl, jq, and readiness helpers;
- Xvfb/Openbox/VNC for desktop leases;
- Xvfb/slim XFCE/VNC for desktop leases;
- Chrome/Chromium for browser leases;
- `ffmpeg`, `ffprobe`, `scrot`, `xdotool`, and other capture helpers;
- Node 22, npm, corepack, pnpm;

View File

@ -27,7 +27,7 @@ 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 and browser tooling are optional lease profiles, not part
of the minimal bootstrap. The desktop profile installs Xvfb/Openbox, x11vnc,
of the minimal bootstrap. The desktop profile installs Xvfb/slim XFCE, 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

View File

@ -127,7 +127,11 @@ Install the smallest useful visible-session stack:
```text
xvfb
openbox
xfce4-session
xfwm4
xfce4-panel
xfdesktop4
xfce4-terminal
x11vnc
xauth
dbus-x11
@ -139,7 +143,7 @@ ca-certificates
Use systemd units so the desktop survives command boundaries on kept leases:
- `crabbox-xvfb.service`
- `crabbox-openbox.service`
- `crabbox-desktop.service`
- `crabbox-x11vnc.service`
Suggested unit behavior:
@ -148,8 +152,8 @@ Suggested unit behavior:
crabbox-xvfb:
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp -ac
crabbox-openbox:
DISPLAY=:99 openbox
crabbox-desktop:
DISPLAY=:99 startxfce4
crabbox-x11vnc:
x11vnc -display :99 -localhost -rfbport 5900 -forever -shared -nopw
@ -159,7 +163,7 @@ crabbox-x11vnc:
```sh
systemctl is-active --quiet crabbox-xvfb.service
systemctl is-active --quiet crabbox-openbox.service
systemctl is-active --quiet crabbox-desktop.service
systemctl is-active --quiet crabbox-x11vnc.service
ss -ltn | grep -q '127.0.0.1:5900'
```

View File

@ -54,7 +54,7 @@ This page maps user-facing behavior back to implementation files. Keep docs desc
Bootstrap is intentionally tiny unless optional lease capabilities are requested:
OpenSSH, CA certificates, curl, Git, rsync, jq, `/work/crabbox`, cache
directories, and `crabbox-ready`. `--desktop` adds Xvfb/Openbox/x11vnc and
directories, and `crabbox-ready`. `--desktop` adds Xvfb/slim XFCE/x11vnc and
loopback VNC. `--browser` adds Chrome stable or a Chromium fallback. `--code`
adds code-server for authenticated portal editor access. Project
runtimes such as Go, Node, pnpm, Docker, databases, and services are

View File

@ -467,14 +467,14 @@ func cloudInitOptionalWriteFiles(cfg Config) string {
permissions: '0644'
content: |
[Unit]
Description=Crabbox lightweight desktop session
Description=Crabbox XFCE desktop session
After=crabbox-xvfb.service
Requires=crabbox-xvfb.service
[Service]
User=crabbox
Environment=DISPLAY=:99
ExecStart=/usr/bin/openbox
ExecStart=/usr/bin/startxfce4
Restart=always
[Install]
@ -488,7 +488,9 @@ func cloudInitOptionalWriteFiles(cfg Config) string {
if command -v xsetroot >/dev/null 2>&1; then
xsetroot -solid '#20242b' || true
fi
if command -v xterm >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xterm -title Crabbox Desktop' >/dev/null 2>&1; then
if command -v xfce4-terminal >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xfce4-terminal.*Crabbox Desktop' >/dev/null 2>&1; then
xfce4-terminal --title='Crabbox Desktop' --geometry=110x32+48+48 &
elif command -v xterm >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xterm -title Crabbox Desktop' >/dev/null 2>&1; then
xterm -title 'Crabbox Desktop' -geometry 110x32+48+48 -bg '#111827' -fg '#e5e7eb' &
fi
tail -f /dev/null
@ -532,7 +534,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 ffmpeg xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
parts = append(parts, ` retry apt-get install -y --no-install-recommends xvfb xfce4-session xfwm4 xfce4-panel xfdesktop4 xfce4-terminal xfconf xfce4-settings 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)

View File

@ -56,17 +56,19 @@ func TestCloudInitDesktopProfile(t *testing.T) {
cfg.Desktop = true
got := cloudInit(cfg, "ssh-ed25519 test")
for _, want := range []string{
"xvfb openbox x11vnc xauth dbus-x11",
"xvfb xfce4-session xfwm4 xfce4-panel xfdesktop4 xfce4-terminal",
"xfconf xfce4-settings x11vnc xauth dbus-x11",
"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",
"/etc/systemd/system/crabbox-desktop-session.service",
"/etc/systemd/system/crabbox-x11vnc.service",
"ExecStart=/usr/bin/openbox",
"ExecStart=/usr/bin/startxfce4",
"systemctl is-active --quiet crabbox-desktop.service",
"systemctl is-active --quiet crabbox-desktop-session.service",
"xsetroot -solid '#20242b'",
"xfce4-terminal --title='Crabbox Desktop'",
"xterm -title 'Crabbox Desktop'",
"(umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)",
"x11vnc -storepasswd",

View File

@ -349,14 +349,14 @@ function optionalWriteFiles(config: LeaseConfig): string {
permissions: '0644'
content: |
[Unit]
Description=Crabbox lightweight desktop session
Description=Crabbox XFCE desktop session
After=crabbox-xvfb.service
Requires=crabbox-xvfb.service
[Service]
User=crabbox
Environment=DISPLAY=:99
ExecStart=/usr/bin/openbox
ExecStart=/usr/bin/startxfce4
Restart=always
[Install]
@ -370,7 +370,9 @@ function optionalWriteFiles(config: LeaseConfig): string {
if command -v xsetroot >/dev/null 2>&1; then
xsetroot -solid '#20242b' || true
fi
if command -v xterm >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xterm -title Crabbox Desktop' >/dev/null 2>&1; then
if command -v xfce4-terminal >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xfce4-terminal.*Crabbox Desktop' >/dev/null 2>&1; then
xfce4-terminal --title='Crabbox Desktop' --geometry=110x32+48+48 &
elif command -v xterm >/dev/null 2>&1 && ! pgrep -u "$(id -u)" -f 'xterm -title Crabbox Desktop' >/dev/null 2>&1; then
xterm -title 'Crabbox Desktop' -geometry 110x32+48+48 -bg '#111827' -fg '#e5e7eb' &
fi
tail -f /dev/null
@ -414,7 +416,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 ffmpeg xdotool wmctrl fonts-dejavu-core fonts-liberation iproute2 openssl
parts.push(` retry apt-get install -y --no-install-recommends xvfb xfce4-session xfwm4 xfce4-panel xfdesktop4 xfce4-terminal xfconf xfce4-settings 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)

View File

@ -71,17 +71,19 @@ describe("cloud-init bootstrap", () => {
it("adds desktop services only when requested", () => {
const got = cloudInit({ ...config, desktop: true });
expect(got).toContain("xvfb openbox x11vnc xauth dbus-x11");
expect(got).toContain("xvfb xfce4-session xfwm4 xfce4-panel xfdesktop4 xfce4-terminal");
expect(got).toContain("xfconf xfce4-settings x11vnc xauth dbus-x11");
expect(got).toContain("/etc/systemd/system/crabbox-xvfb.service");
expect(got).toContain("/etc/systemd/system/crabbox-desktop.service");
expect(got).toContain("/usr/local/bin/crabbox-desktop-session");
expect(got).toContain("/etc/systemd/system/crabbox-desktop-session.service");
expect(got).toContain("/etc/systemd/system/crabbox-x11vnc.service");
expect(got).toContain("ExecStart=/usr/bin/openbox");
expect(got).toContain("ExecStart=/usr/bin/startxfce4");
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 ffmpeg xdotool wmctrl");
expect(got).toContain("xsetroot -solid '#20242b'");
expect(got).toContain("xfce4-terminal --title='Crabbox Desktop'");
expect(got).toContain("xterm -title 'Crabbox Desktop'");
expect(got).toContain("(umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)");
expect(got).toContain("-rfbauth /var/lib/crabbox/vnc.pass");