From 2a8c6b260f2c57bce2f5a626197de5fd2d207823 Mon Sep 17 00:00:00 2001 From: MickLesk Date: Thu, 7 May 2026 10:16:16 +0200 Subject: [PATCH] Add optional Cloud-Init and q35 support Introduce optional Cloud-Init integration and better machine type handling for VMs. Changes include: loading cloud-init helpers lazily (load_cloud_init_functions), interactive cloud-init prompt/configuration (vm_prompt_cloud_init) and SSH key handling, a cloud icon for UI, and vm_machine_type_label for readable machine type display. Default machine type switched to q35 and displays the label in prompts and summaries. VM creation logic now conditionally attaches the cloudinit drive (ide2) and runs setup_cloud_init when enabled; otherwise it creates the VM without the cloudinit device. Post-install messaging now either shows cloud-init details or a guidance message about manual guest filesystem expansion. Minor UI/output adjustments and defaults updated accordingly. --- misc/vm-core.func | 42 +++++++++++++++++++++++++++++++++++- vm/ubuntu2604-vm.sh | 52 ++++++++++++++++++++++++++++++++------------- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/misc/vm-core.func b/misc/vm-core.func index a2f0ff0c..2c665814 100644 --- a/misc/vm-core.func +++ b/misc/vm-core.func @@ -40,6 +40,12 @@ load_functions() { arch_check } +load_cloud_init_functions() { + if ! declare -f setup_cloud_init >/dev/null 2>&1; then + source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/cloud-init.func") 2>/dev/null || true + fi +} + # Function to download & save header files get_header() { local app_name=$(echo "${APP,,}" | tr ' ' '-') @@ -107,6 +113,7 @@ icons() { DNSOK="✔️ " DNSFAIL="${TAB}✖️${TAB}" INFO="${TAB}💡${TAB}${CL}" + CLOUD="${TAB}☁️${TAB}${CL}" OS="${TAB}🖥️${TAB}${CL}" OSVERSION="${TAB}🌟${TAB}${CL}" CONTAINERTYPE="${TAB}📦${TAB}${CL}" @@ -704,6 +711,17 @@ vm_apply_machine_type() { fi } +vm_machine_type_label() { + case "${1:-i440fx}" in + q35) + echo "Q35 (Modern)" + ;; + *) + echo "i440fx" + ;; + esac +} + vm_prompt_machine_type() { local default_machine="${1:-i440fx}" local i440fx_default="ON" @@ -720,12 +738,34 @@ vm_prompt_machine_type() { "q35" "Machine q35" "$q35_default" \ 3>&1 1>&2 2>&3); then vm_apply_machine_type "$machine_choice" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}${MACHINE_TYPE}${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$(vm_machine_type_label "$MACHINE_TYPE")${CL}" else exit_script fi } +vm_prompt_cloud_init() { + local default_user="${1:-root}" + + USE_CLOUD_INIT="no" + load_cloud_init_functions + + if ! declare -f configure_cloud_init_interactive >/dev/null 2>&1; then + echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}unavailable${CL}" + return 1 + fi + + configure_cloud_init_interactive "$default_user" || true + USE_CLOUD_INIT="${CLOUDINIT_ENABLE:-no}" + echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}" + + if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f configure_cloudinit_ssh_keys >/dev/null 2>&1; then + configure_cloudinit_ssh_keys || true + fi + + return 0 +} + vm_prompt_disk_size() { local default_size="${1:-8G}" local prompt_message="${2:-Set Disk Size in GiB (e.g., 10, 20)}" diff --git a/vm/ubuntu2604-vm.sh b/vm/ubuntu2604-vm.sh index aac821b8..45c6ea85 100644 --- a/vm/ubuntu2604-vm.sh +++ b/vm/ubuntu2604-vm.sh @@ -28,6 +28,7 @@ NSAPP="ubuntu2604-vm" var_os="ubuntu" var_version="2604" THIN="discard=on,ssd=1," +USE_CLOUD_INIT="no" header_info echo -e "\n Loading..." @@ -48,9 +49,15 @@ else header_info && exit_script fi +check_root +arch_check +pve_check +ssh_check +vm_prompt_cloud_init "ubuntu" + function default_settings() { VMID=$(get_valid_nextid) - vm_apply_machine_type "i440fx" + vm_apply_machine_type "q35" DISK_SIZE="7G" DISK_CACHE="" HN="ubuntu" @@ -65,13 +72,14 @@ function default_settings() { METHOD="default" echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}${MACHINE_TYPE}${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$(vm_machine_type_label "$MACHINE_TYPE")${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}" echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}" echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}" + echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}" echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}" echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}" echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}" @@ -82,8 +90,9 @@ function default_settings() { function advanced_settings() { METHOD="advanced" + echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}" vm_prompt_vmid "${VMID:-$(get_valid_nextid)}" - vm_prompt_machine_type "i440fx" + vm_prompt_machine_type "q35" vm_prompt_disk_size "${DISK_SIZE:-7G}" "Set Disk Size in GiB (e.g., 10, 20)" vm_prompt_disk_cache "none" vm_prompt_hostname "ubuntu" @@ -117,10 +126,6 @@ function start_script() { fi } -check_root -arch_check -pve_check -ssh_check start_script post_to_api_vm @@ -142,17 +147,31 @@ qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/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} \ - -ide2 ${STORAGE}:cloudinit \ - -boot order=scsi0 \ - -serial0 socket >/dev/null +if [ "$USE_CLOUD_INIT" = "yes" ]; then + qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \ + -ide2 ${STORAGE}:cloudinit \ + -boot order=scsi0 \ + -serial0 socket >/dev/null +else + qm set $VMID \ + -efidisk0 ${DISK0_REF}${FORMAT} \ + -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \ + -boot order=scsi0 \ + -serial0 socket >/dev/null +fi 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 + msg_info "Configuring Cloud-Init" + 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}}" + msg_ok "Configured Cloud-Init" +fi + msg_ok "Created a Ubuntu 26.04 VM ${CL}${BL}(${HN})" if [ "$START_VM" = "yes" ]; then msg_info "Starting Ubuntu 26.04 VM" @@ -162,5 +181,8 @@ fi post_update_to_api "done" "none" msg_ok "Completed successfully!\n" -echo -e "Setup Cloud-Init before starting \n -More info at https://github.com/community-scripts/ProxmoxVED/discussions/272 \n" +if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f display_cloud_init_info >/dev/null 2>&1; then + display_cloud_init_info "$VMID" "$HN" +else + echo -e "Cloud-Init is disabled. The VM disk was resized on the Proxmox side only.\nIf the guest does not auto-expand its root filesystem after first boot, expand it manually inside the VM.\n\nMore info at https://github.com/community-scripts/ProxmoxVED/discussions/272 \n" +fi