@@ -592,10 +592,15 @@ func cloudInitOptionalReadyChecks(cfg Config) string {
592592 b .WriteString (" grep -Eq '^100\\ .' /var/lib/crabbox/tailscale-ipv4\n " )
593593 }
594594 if cfg .Desktop {
595- b .WriteString (" systemctl is-active --quiet crabbox-xvfb.service\n " )
596- b .WriteString (" systemctl is-active --quiet crabbox-desktop.service\n " )
597- b .WriteString (" systemctl is-active --quiet crabbox-desktop-session.service\n " )
598- b .WriteString (" systemctl is-active --quiet crabbox-x11vnc.service\n " )
595+ if normalizedDesktopEnv (cfg .DesktopEnv ) == desktopEnvWayland {
596+ b .WriteString (" systemctl is-active --quiet crabbox-desktop.service\n " )
597+ b .WriteString (" systemctl is-active --quiet crabbox-wayvnc.service\n " )
598+ } else {
599+ b .WriteString (" systemctl is-active --quiet crabbox-xvfb.service\n " )
600+ b .WriteString (" systemctl is-active --quiet crabbox-desktop.service\n " )
601+ b .WriteString (" systemctl is-active --quiet crabbox-desktop-session.service\n " )
602+ b .WriteString (" systemctl is-active --quiet crabbox-x11vnc.service\n " )
603+ }
599604 b .WriteString (" ss -ltn | grep -q '127.0.0.1:5900'\n " )
600605 }
601606 if cfg .Browser {
@@ -616,7 +621,9 @@ func cloudInitOptionalWriteFiles(cfg Config) string {
616621 if cfg .Provider == "gcp" {
617622 parts = append (parts , cloudInitGCPExpiryGuardFiles ())
618623 }
619- if cfg .Desktop {
624+ if cfg .Desktop && normalizedDesktopEnv (cfg .DesktopEnv ) == desktopEnvWayland {
625+ parts = append (parts , cloudInitWaylandDesktopWriteFiles ())
626+ } else if cfg .Desktop {
620627 parts = append (parts , ` - path: /etc/systemd/system/crabbox-xvfb.service
621628 permissions: '0644'
622629 content: |
@@ -882,12 +889,149 @@ func cloudInitOptionalWriteFiles(cfg Config) string {
882889 return strings .Join (parts , "\n " )
883890}
884891
892+ func cloudInitWaylandDesktopWriteFiles () string {
893+ return ` - path: /usr/local/bin/crabbox-start-wayland-desktop
894+ permissions: '0755'
895+ content: |
896+ #!/bin/sh
897+ set -eu
898+ runtime="${XDG_RUNTIME_DIR:-/tmp/crabbox-runtime-$(id -u)}"
899+ install -d -m 0700 "$runtime"
900+ export XDG_RUNTIME_DIR="$runtime"
901+ export WLR_BACKENDS=headless
902+ export WLR_LIBINPUT_NO_DEVICES=1
903+ export WLR_RENDERER="${WLR_RENDERER:-pixman}"
904+ export MOZ_ENABLE_WAYLAND=1
905+ exec dbus-run-session sway --unsupported-gpu
906+ - path: /usr/local/bin/crabbox-sway-status
907+ permissions: '0755'
908+ content: |
909+ #!/bin/sh
910+ while :; do
911+ printf 'Crabbox Wayland - Mod+Enter/D terminal - %s\n' "$(date '+%H:%M:%S')"
912+ sleep 1
913+ done
914+ - path: /etc/systemd/system/crabbox-desktop.service
915+ permissions: '0644'
916+ content: |
917+ [Unit]
918+ Description=Crabbox Wayland desktop session
919+ After=network.target
920+
921+ [Service]
922+ User=crabbox
923+ Environment=WLR_BACKENDS=headless
924+ Environment=WLR_LIBINPUT_NO_DEVICES=1
925+ Environment=WLR_RENDERER=pixman
926+ ExecStart=/usr/local/bin/crabbox-start-wayland-desktop
927+ Restart=always
928+
929+ [Install]
930+ WantedBy=multi-user.target
931+ - path: /usr/local/bin/crabbox-start-wayvnc
932+ permissions: '0755'
933+ content: |
934+ #!/bin/sh
935+ set -eu
936+ runtime="${XDG_RUNTIME_DIR:-/tmp/crabbox-runtime-$(id -u)}"
937+ export XDG_RUNTIME_DIR="$runtime"
938+ for i in $(seq 1 60); do
939+ for socket in "$XDG_RUNTIME_DIR"/wayland-*; do
940+ [ -S "$socket" ] || continue
941+ export WAYLAND_DISPLAY="${socket##*/}"
942+ cat >/var/lib/crabbox/desktop.env <<EOF
943+ CRABBOX_DESKTOP_ENV=wayland
944+ XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
945+ WAYLAND_DISPLAY=$WAYLAND_DISPLAY
946+ EOF
947+ exec /usr/bin/wayvnc --config "$HOME/.config/wayvnc/config" --render-cursor --max-fps=30
948+ done
949+ sleep 1
950+ done
951+ echo "wayland socket not ready" >&2
952+ exit 1
953+ - path: /etc/systemd/system/crabbox-wayvnc.service
954+ permissions: '0644'
955+ content: |
956+ [Unit]
957+ Description=Crabbox loopback WayVNC server
958+ After=crabbox-desktop.service
959+ Requires=crabbox-desktop.service
960+
961+ [Service]
962+ User=crabbox
963+ ExecStart=/usr/local/bin/crabbox-start-wayvnc
964+ Restart=always
965+
966+ [Install]
967+ WantedBy=multi-user.target
968+ `
969+ }
970+
885971func cloudInitOptionalBootstrap (cfg Config ) string {
886972 var parts []string
887973 if cfg .Tailscale .Enabled {
888974 parts = append (parts , cloudInitTailscaleBootstrap (cfg ))
889975 }
890- if cfg .Desktop {
976+ if cfg .Desktop && normalizedDesktopEnv (cfg .DesktopEnv ) == desktopEnvWayland {
977+ parts = append (parts , ` retry apt-get install -y --no-install-recommends sway wayvnc foot grim slurp wtype wl-clipboard dbus-user-session xwayland xdg-desktop-portal-wlr fonts-dejavu-core fonts-liberation iproute2 openssl procps
978+ install -d -m 0750 -o crabbox -g crabbox /var/lib/crabbox
979+ if [ ! -s /var/lib/crabbox/vnc.password ]; then
980+ (umask 077 && openssl rand -base64 18 > /var/lib/crabbox/vnc.password)
981+ fi
982+ chown crabbox:crabbox /var/lib/crabbox/vnc.password
983+ chmod 0600 /var/lib/crabbox/vnc.password
984+ crabbox_uid="$(id -u crabbox)"
985+ crabbox_runtime="/tmp/crabbox-runtime-$crabbox_uid"
986+ install -d -m 0700 -o crabbox -g crabbox "$crabbox_runtime"
987+ install -d -m 0700 -o crabbox -g crabbox /home/crabbox/.config/sway /home/crabbox/.config/wayvnc
988+ cat >/home/crabbox/.config/sway/config <<'SWAY'
989+ set $mod Mod4
990+ set $term foot
991+ set $menu foot --title='Crabbox Desktop'
992+ output * resolution 1920x1080 position 0,0
993+ default_border pixel 2
994+ default_floating_border pixel 2
995+ gaps inner 8
996+ gaps outer 12
997+ focus_follows_mouse no
998+ client.focused #2dd4bf #1f2937 #f8fafc #2dd4bf #2dd4bf
999+ client.unfocused #475569 #111827 #cbd5e1 #475569 #475569
1000+ bindsym $mod+Return exec $term
1001+ bindsym $mod+d exec $menu
1002+ bindsym $mod+Shift+c reload
1003+ bindsym $mod+Shift+q kill
1004+ for_window [app_id="foot"] floating enable, resize set width 900 px height 640 px, move position 48 px 72 px
1005+ for_window [app_id="google-chrome"] floating enable, resize set width 1500 px height 900 px, move position 360 px 96 px
1006+ for_window [app_id="chromium"] floating enable, resize set width 1500 px height 900 px, move position 360 px 96 px
1007+ exec foot --title='Crabbox Desktop'
1008+ bar {
1009+ position top
1010+ status_command /usr/local/bin/crabbox-sway-status
1011+ colors {
1012+ background #111827
1013+ statusline #e5e7eb
1014+ focused_workspace #2dd4bf #1f2937 #f8fafc
1015+ inactive_workspace #1f2937 #111827 #cbd5e1
1016+ }
1017+ }
1018+ SWAY
1019+ cat >/home/crabbox/.config/wayvnc/config <<'WAYVNC'
1020+ address=127.0.0.1
1021+ port=5900
1022+ enable_auth=false
1023+ xkb_layout=us
1024+ WAYVNC
1025+ cat >/var/lib/crabbox/desktop.env <<EOF
1026+ CRABBOX_DESKTOP_ENV=wayland
1027+ XDG_RUNTIME_DIR=$crabbox_runtime
1028+ WAYLAND_DISPLAY=wayland-1
1029+ EOF
1030+ chown -R crabbox:crabbox /home/crabbox/.config/sway /home/crabbox/.config/wayvnc /var/lib/crabbox/desktop.env
1031+ chmod 0644 /var/lib/crabbox/desktop.env
1032+ systemctl daemon-reload
1033+ systemctl enable --now crabbox-desktop.service crabbox-wayvnc.service` )
1034+ } else if cfg .Desktop {
8911035 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 xclip xsel fonts-dejavu-core fonts-liberation iproute2 openssl arc-theme
8921036 install -d -m 0750 -o crabbox -g crabbox /var/lib/crabbox
8931037 if [ ! -s /var/lib/crabbox/vnc.password ]; then
@@ -896,6 +1040,9 @@ func cloudInitOptionalBootstrap(cfg Config) string {
8961040 x11vnc -storepasswd "$(cat /var/lib/crabbox/vnc.password)" /var/lib/crabbox/vnc.pass >/dev/null
8971041 chown crabbox:crabbox /var/lib/crabbox/vnc.password /var/lib/crabbox/vnc.pass
8981042 chmod 0600 /var/lib/crabbox/vnc.password /var/lib/crabbox/vnc.pass
1043+ printf 'CRABBOX_DESKTOP_ENV=xfce\nDISPLAY=:99\n' >/var/lib/crabbox/desktop.env
1044+ chown crabbox:crabbox /var/lib/crabbox/desktop.env
1045+ chmod 0644 /var/lib/crabbox/desktop.env
8991046 CRABBOX_DESKTOP_USER=crabbox /usr/local/bin/crabbox-configure-desktop-theme
9001047 systemctl daemon-reload
9011048 systemctl enable --now crabbox-xvfb.service crabbox-desktop.service crabbox-desktop-session.service crabbox-x11vnc.service` )
@@ -930,7 +1077,11 @@ func cloudInitOptionalBootstrap(cfg Config) string {
9301077 install -d -m 0755 /etc/opt/chrome/policies/managed /etc/chromium/policies/managed
9311078 printf '%s\n' '{"DefaultBrowserSettingEnabled":false,"MetricsReportingEnabled":false,"PromotionalTabsEnabled":false}' > /etc/opt/chrome/policies/managed/crabbox.json
9321079 cp /etc/opt/chrome/policies/managed/crabbox.json /etc/chromium/policies/managed/crabbox.json
933- printf '%s\n' '#!/bin/sh' "exec \"$browser_path\" --no-first-run --no-default-browser-check --disable-default-apps --window-size=1500,900 --window-position=80,80 \"\$@\"" > "$browser_wrapper"
1080+ if [ -f /var/lib/crabbox/desktop.env ] && grep -q '^CRABBOX_DESKTOP_ENV=wayland$' /var/lib/crabbox/desktop.env; then
1081+ printf '%s\n' '#!/bin/sh' 'if [ -f /var/lib/crabbox/desktop.env ]; then . /var/lib/crabbox/desktop.env; fi' 'export XDG_RUNTIME_DIR WAYLAND_DISPLAY' 'export MOZ_ENABLE_WAYLAND=1' "exec \"$browser_path\" --no-first-run --no-default-browser-check --disable-default-apps --hide-crash-restore-bubble --ozone-platform=wayland --window-size=1500,900 --window-position=80,80 \"\$@\"" > "$browser_wrapper"
1082+ else
1083+ printf '%s\n' '#!/bin/sh' "exec \"$browser_path\" --no-first-run --no-default-browser-check --disable-default-apps --hide-crash-restore-bubble --window-size=1500,900 --window-position=80,80 \"\$@\"" > "$browser_wrapper"
1084+ fi
9341085 chmod 0755 "$browser_wrapper"
9351086 printf 'CHROME_BIN=%s\nBROWSER=%s\n' "$browser_wrapper" "$browser_wrapper" > /var/lib/crabbox/browser.env
9361087 chown crabbox:crabbox /var/lib/crabbox/browser.env
0 commit comments