Skip to content

Add Debian Moonlight kiosk VM - #2477

Draft
Tomblarom wants to merge 2 commits into
community-scripts:mainfrom
Tomblarom:feat/debian-game-streaming
Draft

Tomblarom wants to merge 2 commits into
community-scripts:mainfrom
Tomblarom:feat/debian-game-streaming

Conversation

@Tomblarom

@Tomblarom Tomblarom commented Oct 27, 2026 •

Copy link
Copy Markdown

✍️ Description

Create a Debian 13 Moonlight appliance VM for a GPU-connected TV/monitor. The guest boots into a small Xorg/Openbox session instead of requiring a full desktop and display manager. Sunshine server provisioning is outside this PR.

  • Local tty1 login starts Xorg, then Openbox and the Moonlight GUI. Console autologin is an explicit option; SSH and the Proxmox serial console remain management sessions.
  • The kiosk disables blanking/DPMS, prefers an advertised 3840×2160/60 mode, hides the pointer, keeps Moonlight fullscreen and relaunches it after exit. Unsupported display modes retain the existing display configuration.
  • The upstream x86_64 AppImage remains /opt/moonlight/Moonlight.AppImage. A neutral launcher/configuration keeps the GUI scale and Vulkan preference adjustable and selects radeonsi only for an AMD graphics device. Pairing and the remote application choice stay in Moonlight.
  • The Cloud-Init user receives the graphics/input groups needed for the dedicated client. Bash-it with the pure theme is installed for that interactive user while preserving existing shell configuration.
  • Optional PCI assignment attaches only the explicitly chosen display function, with q35/OVMF, CPU host, onboot and vga: serial0. It checks VFIO preparation, IOMMU grouping, existing ownership and confirmation. Host boot-display use needs separate explicit consent. Optional USB assignment uses physical ports and rejects occupied, storage, hub and network devices.
  • An opt-in Raven Ridge workaround is restricted to the selected 1002:15dd device. A host oneshot service checks its identity/VFIO binding and disables that function's reset methods before pve-guests.service. It does not bind host drivers, alter host boot parameters or guarantee every GPU restart scenario. Its unit/script names include the new VM ID; the final steps explain removal.

Guest packages come from Debian 13, including firmware, Mesa/VA-API, Xorg/Openbox and standard audio services. No audio-device routing, ALSA aliases, QEMU audio arguments, automatic stream connection, server installation or game/emulator provisioning are included. NVIDIA needs a compatible guest driver supplied separately.

Evidence and deliberate differences from the reference

The existing working reference was inspected read-only over SSH. It confirms tty1 → .bash_profile → startx → .xinitrc → Openbox, the AppImage checksum, physical 3840×2160 at 60 Hz and Mesa radeonsi HEVC decoding support. The user reports controller navigation in both the GUI and stream and about 1.14 ms decode time. The reference received about 33 stream FPS: a 60 Hz display is not evidence of 60 received frames.

The installer generalizes the username, PCI/output addresses, launcher paths and VA-API selection, preserves user files, and does not copy hosts, pairing keys or stream presets. Current reference-host configuration also contains a larger pre-start hook and IOMMU/PCI-function changes; those are not presented as part of the earlier video/controller baseline or silently reproduced here.

This is reproduction of a working configuration, not yet a successful clean-install test of this script. No live VM, GPU binding or host setting was changed during this work.

Installation sources and runtime

Moonlight is native C++/Qt with no database. Its upstream AppImage bundles the application runtime; Debian supplies FUSE, graphics drivers and VA-API. The upstream AppImage workflow/build script and launcher sources were reviewed. vm_release_asset resolves the official x86_64 asset and published SHA-256 digest; vm_fetch_image verifies the download. Verified upstream release: 6.2.0. Bash-it has no uploaded release assets, so Core's index/download helpers retrieve its current tagged source archive; no upstream checksum is published for that archive.

🔗 Related PR / Issue

No issue closure is claimed. Existing Moonlight/Sunshine contributions were researched; this contribution is limited to the independent Moonlight VM.

✅ Prerequisites

  • Self-review completed – Includes reference/configuration comparison and generated-guest review.
  • Tested thoroughly – Clean Proxmox installation and hardware acceptance remain pending.
  • No breaking changes – Existing production VM scripts are unchanged.
  • No security risks – Device guards are tested synthetically; new guest permissions/device isolation need real-platform validation.

🏗️ arm64 Support

  • arm64 supported
  • arm64 not tested
  • arm64 not supported – This VM explicitly requires amd64 and selects the official x86_64 AppImage.

🖥️ Tested on

  • Proxmox VE – Reference inspected; clean installer execution still pending.
  • Incus – Proxmox-only implementation.

Automated QA

Using Core 3c1ef2a14e6dbfc93e9200098d0abdeeba916d72:

bash -n: 237 application/VM/tool scripts passed
ShellCheck 0.10.0: host script and rendered guest passed
All 11 VM wizards: default, advanced, unattended and cancellation passed
All 11 VM scripts: 66 complete mocked runs and 53 failure cases passed
31 device/kiosk/guest tests passed
Moonlight live release/digest resolution and Bash-it tagged archive retrieval passed
Catalog paths, defaults, architecture/platform and note limits passed

The kiosk tests execute the login trigger, GPU-specific launcher, display fallback and relaunch/fullscreen loop with command stubs. Repeated shell configuration preserves existing content/backups and adds the managed initialization once. Reset tests execute the generated guard against a synthetic device and reject changed identities. The pre-existing HAOS mock correction from this branch remains test-only: its channel payload lacked a field already consumed by its existing VM script.

GitHub script-requirements validation passed. VM metadata, Bash syntax and VM wizard workflow runs currently require upstream approval (action_required); their execution is not claimed as passing.

Reproduce with a local Core checkout:

clear
CORE=/path/to/core/pve/vm-core.func bash .github/workflows/scripts/vm-wizard-test.sh
CORE=/path/to/core/pve/vm-core.func bash .github/workflows/scripts/vm-lifecycle-test.sh
python3 .github/workflows/scripts/vm-game-streaming-test.py
shellcheck --severity=warning --exclude=SC1090,SC2034 vm/moonlight-vm.sh

Device tests use synthetic sysfs/configuration trees and mocked Proxmox/systemd commands. Hardware checks still needed on a newly provisioned VM: bootstrap/reboot, tty1 autologin and manual login, physical display, GUI/stream controller input, HEVC hardware decoding, actual received FPS, relaunch/fullscreen, serial/SSH management and host-reboot behavior. Audio acceptance is outside this work.

🛠️ Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🆕 New script – Debian Moonlight kiosk VM.
  • 🌍 Website update – Matching catalog entry.
  • 🔧 Refactoring / Code Cleanup
  • 📝 Documentation update

🔍 Code & Security Review

  • Follows CODE-AUDIT.md & CONTRIBUTING.md guidelines, using the VM-specific Core contract.
  • Uses correct script structure – vm/*.sh and matching VM metadata.
  • No hardcoded credentials
  • No Docker / Docker Compose
  • No git pull – Core handles release resolution/downloads.

🤖 AI Assistance

  • No AI used
  • AI was used – AGENTS.md and .github/agents/pve-script-creator.agent.md guided the work; output was reviewed and corrected using the VM-specific contract.

GPT-6.1-Sol (high) coordinated the reference comparison, integration, review and tests. Muse 1.3 Contributor (max) worked on public-code research and guest-script drafting.

📋 Additional Information

VM_CLIENT_AUTOSTART=yes|no defaults to yes; VM_DESKTOP_AUTOLOGIN=yes|no defaults to no. The interactive wizard offers both. Device options are VM_GPU_PCI, VM_USB_PORTS, VM_ALLOW_BOOT_GPU=yes|no and VM_RAVEN_RESET_GUARD=yes|no. The last two default to no. Resource defaults are 4 vCPU, 2048 MiB and 16 GiB, configurable through the normal VM wizard; the lower RAM default has not been hardware-validated by this installer. Unattended device assignment additionally requires VM_PASSTHROUGH_CONFIRM=yes.

📦 Application Requirements (for new scripts)

  • The application is at least 6 months old
  • The application is actively maintained
  • The application has 600+ GitHub stars
  • Official release tarballs are published
  • I understand that not all scripts will be accepted due to various reasons and criteria by the community-scripts ORG

🌐 Source

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Try this script

vm/moonlight-vm.sh, run in the Proxmox VE shell:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/Tomblarom/DevScripts/feat/debian-game-streaming/vm/moonlight-vm.sh)"
Against a core branch as well

Add COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/OWNER/core/BRANCH
to test an engine change at the same time. The two resolve independently.

Provision the client through tty1, Xorg and Openbox using the upstream AppImage. Keep GUI pairing, fullscreen relaunch and serial management, and add an explicit device-scoped Raven Ridge reset option. Limit the contribution to the Moonlight VM.

Co-authored-by: Tomblarom <12703270+Tomblarom@users.noreply.github.com>
@Tomblarom Tomblarom changed the title Add Debian Sunshine and Moonlight VMs Add Debian Moonlight kiosk VM Oct 29, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant