diff --git a/json/waydroid-vm.json b/json/waydroid-vm.json new file mode 100644 index 00000000..595dd24a --- /dev/null +++ b/json/waydroid-vm.json @@ -0,0 +1,53 @@ +{ + "name": "Waydroid", + "slug": "waydroid-vm", + "categories": [ + 20, + 3 + ], + "date_created": "2026-05-26", + "type": "vm", + "updateable": false, + "privileged": false, + "interface_port": null, + "documentation": "https://docs.waydro.id/", + "website": "https://waydro.id/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/waydroid.webp", + "description": "Waydroid is a container-based approach to boot a full Android system on a regular GNU/Linux system. It uses Linux namespaces (LXC) to run Android in a container and bridges the Wayland compositor to display Android apps natively. This VM script creates a KVM virtual machine with Ubuntu 24.04 or Debian 13 as the base OS, ready for Waydroid installation.", + "install_methods": [ + { + "type": "default", + "script": "vm/waydroid-vm.sh", + "config_path": "", + "resources": { + "cpu": 4, + "ram": 4096, + "hdd": 20, + "os": null, + "version": null + } + } + ], + "default_credentials": { + "username": "ubuntu", + "password": null + }, + "notes": [ + { + "text": "The OS can be selected during setup: Ubuntu 24.04 LTS or Debian 13 (Trixie). The default user is 'ubuntu' for Ubuntu and 'debian' for Debian.", + "type": "info" + }, + { + "text": "Waydroid is NOT pre-installed. After first boot, run: curl -s https://repo.waydro.id | bash && apt install -y waydroid", + "type": "warning" + }, + { + "text": "Waydroid requires a running Wayland compositor. For headless setups install 'weston'. GPU acceleration requires VirtIO GPU or GPU passthrough.", + "type": "info" + }, + { + "text": "Enable Cloud-Init during setup to configure SSH keys and network automatically.", + "type": "info" + } + ] +} \ No newline at end of file diff --git a/tools/addon/netdata.sh b/tools/addon/netdata.sh index 8d7d3a26..500614a9 100644 --- a/tools/addon/netdata.sh +++ b/tools/addon/netdata.sh @@ -55,29 +55,25 @@ pve_check() { local MINOR="${BASH_REMATCH[1]}" if ((MINOR < 0 || MINOR > 9)); then msg_error "Unsupported Proxmox VE version: $PVE_VER" - msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.1" + msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.2" exit 1 fi return 0 fi - # Proxmox VE 9.x: allow 9.0 – 9.1 + # Proxmox VE 9.x: allow 9.0 – 9.2 if [[ "$PVE_VER" =~ ^9\.([0-9]+)$ ]]; then local MINOR="${BASH_REMATCH[1]}" - if ((MINOR < 0 || MINOR > 1)); then + if ((MINOR < 0 || MINOR > 2)); then msg_error "Unsupported Proxmox VE version: $PVE_VER" - msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.1" + msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.2" exit 1 fi return 0 fi msg_error "Unsupported Proxmox VE version: $PVE_VER" - msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.1" - exit 1 -} - -detect_codename() { + msg_error "Supported versions: 8.0 – 8.9 or 9.0 – 9.2"() { source /etc/os-release if [[ "$ID" != "debian" ]]; then msg_error "Unsupported base OS: $ID (only Proxmox VE / Debian supported)." diff --git a/vm/ubuntu2410-vm.sh b/vm/ubuntu2410-vm.sh index 43823fae..6a330cab 100644 --- a/vm/ubuntu2410-vm.sh +++ b/vm/ubuntu2410-vm.sh @@ -141,7 +141,7 @@ function check_root() { function pve_check() { if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-2])(\.[0-9]+)*"; then msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported" - echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1." + echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.2." echo -e "Exiting..." sleep 2 exit diff --git a/vm/waydroid-vm.sh b/vm/waydroid-vm.sh new file mode 100644 index 00000000..002e1e9b --- /dev/null +++ b/vm/waydroid-vm.sh @@ -0,0 +1,332 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: community-scripts ORG +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://waydro.id/ + +source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}/misc/vm-core.func") +load_functions + +function header_info { + clear + cat <<"EOF" + __ __ _ _ _ + \ \ / / | | (_) | | + \ \ /\ / /__ _ _ _ __| |_ __ ___ __| | + \ \/ \/ / _` | | | |/ _` | '__/ _ \/ _` | + \ /\ / (_| | |_| | (_| | | | (_) | (_| | + \/ \/ \__,_|\__, |\__,_|_| \___/ \__,_| + __/ | + |___/ Android Container on Linux +EOF +} + +APP="Waydroid VM" +APP_TYPE="vm" +GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//') +RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" +METHOD="" +NSAPP="waydroid-vm" +THIN="discard=on,ssd=1," +USE_CLOUD_INIT="no" +SNIPPETS_STOR="" +SNIPPETS_DIR="" + +# OS selection defaults +OS_CHOICE="ubuntu2404" +OS_LABEL="Ubuntu 24.04 LTS (Noble Numbat)" +WAYDROID_DISTRO="noble" + +header_info +echo -e "\n Loading..." + +set -e +trap 'error_handler $LINENO "$BASH_COMMAND"' ERR +trap cleanup EXIT +trap 'post_update_to_api "failed" "130"' SIGINT +trap 'post_update_to_api "failed" "143"' SIGTERM +trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP + +TEMP_DIR=$(mktemp -d) +pushd "$TEMP_DIR" >/dev/null + +if vm_confirm_new_vm "$APP" "This will create a New $APP. Proceed?"; then + : +else + header_info && exit_script +fi + +check_root +arch_check +pve_check +ssh_check + +# --------------------------------------------------------------------------- +# OS Selection +# --------------------------------------------------------------------------- +function prompt_os_choice() { + local choice + if choice=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "OS SELECTION" \ + --radiolist "Choose the base operating system:" --cancel-button Exit-Script 12 68 2 \ + "ubuntu2404" "Ubuntu 24.04 LTS (Noble Numbat)" ON \ + "debian13" "Debian 13 (Trixie)" OFF \ + 3>&1 1>&2 2>&3); then + OS_CHOICE="$choice" + case "$OS_CHOICE" in + ubuntu2404) + OS_LABEL="Ubuntu 24.04 LTS (Noble Numbat)" + WAYDROID_DISTRO="noble" + ;; + debian13) + OS_LABEL="Debian 13 (Trixie)" + WAYDROID_DISTRO="trixie" + ;; + esac + echo -e "${OS}${BOLD}${DGN}Base OS: ${BGN}${OS_LABEL}${CL}" + else + exit_script + fi +} + +prompt_os_choice +vm_prompt_cloud_init "ubuntu" + +# --------------------------------------------------------------------------- +# Find snippets-capable storage for cicustom vendor-data +# --------------------------------------------------------------------------- +function find_snippets_storage() { + local stor path + stor=$(awk ' + /^dir:/ { cur=$2 } + /^nfs:/ { cur=$2 } + /^btrfs:/ { cur=$2 } + cur && /content/ && /snippets/ { print cur; exit } + ' /etc/pve/storage.cfg 2>/dev/null) + [[ -z "$stor" ]] && return 1 + + path=$(awk -v s="$stor" ' + $0 ~ "^(dir|nfs|btrfs): " s { found=1; next } + found && /^\tpath/ { print $2; exit } + found && /^[a-z]/ { exit } + ' /etc/pve/storage.cfg 2>/dev/null) + path="${path:-/var/lib/vz}" + + SNIPPETS_STOR="$stor" + SNIPPETS_DIR="${path}/snippets" + mkdir -p "$SNIPPETS_DIR" + return 0 +} + +# --------------------------------------------------------------------------- +# Write cloud-init vendor-data snippet for Waydroid installation +# --------------------------------------------------------------------------- +function write_waydroid_vendor_data() { + local distro="$1" + cat >"${SNIPPETS_DIR}/waydroid-${VMID}-vendor.yaml" <&/dev/null +qm importdisk $VMID $FILE $STORAGE ${DISK_IMPORT:-} 1>&/dev/null +qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \ + -boot order=scsi0 \ + -serial0 socket >/dev/null +set_description + +msg_info "Resizing disk to $DISK_SIZE" +qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null + +if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f setup_cloud_init >/dev/null 2>&1; then + case "$OS_CHOICE" in + ubuntu2404) setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes" "${CLOUDINIT_USER:-ubuntu}" "${CLOUDINIT_NETWORK_MODE:-dhcp}" "${CLOUDINIT_IP:-}" "${CLOUDINIT_GW:-}" "${CLOUDINIT_DNS:-${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}}" ;; + debian13) setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes" "${CLOUDINIT_USER:-debian}" "${CLOUDINIT_NETWORK_MODE:-dhcp}" "${CLOUDINIT_IP:-}" "${CLOUDINIT_GW:-}" "${CLOUDINIT_DNS:-${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}}" ;; + esac +else + # Even without interactive cloud-init config, attach a CI drive for network (DHCP) + qm set $VMID --ide2 "${STORAGE}:cloudinit" >/dev/null 2>&1 || + qm set $VMID --scsi1 "${STORAGE}:cloudinit" >/dev/null 2>&1 || true + qm set $VMID --ipconfig0 "ip=dhcp" >/dev/null 2>&1 || true +fi + +# Inject Waydroid auto-install via cicustom vendor-data (runs on first boot) +msg_info "Setting up Waydroid auto-install via cloud-init" +if find_snippets_storage; then + write_waydroid_vendor_data "$WAYDROID_DISTRO" + qm set $VMID --cicustom "vendor=${SNIPPETS_STOR}:snippets/waydroid-${VMID}-vendor.yaml" >/dev/null + qm cloudinit update $VMID >/dev/null 2>&1 || true + msg_ok "Waydroid will be installed automatically on first boot" +else + msg_warn "No snippets-capable storage found — Waydroid must be installed manually after boot" +fi + +msg_ok "Created a ${OS_LABEL} Waydroid VM ${CL}${BL}(${HN})" +if [ "$START_VM" = "yes" ]; then + msg_info "Starting Waydroid VM" + qm start $VMID + msg_ok "Started Waydroid VM" +fi + +post_update_to_api "done" "none" +msg_ok "Completed successfully!\n" + +if [[ -n "$SNIPPETS_STOR" ]]; then + cat </dev/null 2>&1; then + display_cloud_init_info "$VMID" "$HN" +fi