added proxmox cloud image script

This commit is contained in:
2026-07-13 06:59:18 -04:00
parent b078fe66e2
commit 032db2bb93
2 changed files with 880 additions and 0 deletions
+188
View File
@@ -0,0 +1,188 @@
# Proxmox Cloud Image Manager
Download, customize, and create VM templates from cloud images for popular Linux distributions. Enables fast VM deployment with cloud-init — just like a real cloud provider.
## Requirements
- **Proxmox VE host** (script auto-elevates with `sudo` if needed)
- Packages: `curl`, `qemu-utils`, `libguestfs-tools` (optional, for qemu-guest-agent injection)
## Usage
```
Usage: pve-cloudimg.sh [options] <command> [args]
Commands:
list [distro] List available distros, cached images, and VM templates
download <distro> [ver] Download image into cache only (no VM, no modifications).
Use "all" to download every supported distro.
create <distro> [ver] Download cloud image (if needed) and create VM template
update <distro> [ver] Re-download and re-create a template (remove + create)
remove <distro> [ver] Remove cached image and VM template for a distro
Options:
-d, --dir DIR Image cache directory (default: <script-dir>/cloud-images/; set \$PVE_CLOUDIMG_DIR to change default)
--storage STORAGE Proxmox storage for VM disks (default: main-storage)
--bridge BRIDGE Network bridge (default: vmbr0)
--vlan VLAN VLAN tag for the network interface
--bios BIOS Firmware: seabios (default) or ovmf (UEFI)
--vm-id VMID VM ID for the template (default: auto from 9000)
--cores CORES CPU cores (default: 2)
--memory MEMORY Memory in MB (default: 2048)
--disk-size SIZE Disk size in GB (default: 10)
--user USER Cloud-init default user (default: distro-specific)
--ssh-key FILE SSH public key file to inject via cloud-init
--no-agent Skip installing qemu-guest-agent
--packages PKGS Extra packages to install (comma/space-separated, passed to virt-customize)
-f, --force Re-download image even if already cached
-y, --yes Skip confirmation prompts
```
### Examples
```bash
# List available distros, cached images, and templates
./pve-cloudimg.sh list
# Pre-cache an image (download only, no modifications)
./pve-cloudimg.sh download debian
# Pre-cache every supported distro
./pve-cloudimg.sh download all
# Create a template from the default distro version (Ubuntu 26.04)
./pve-cloudimg.sh create ubuntu
# Create from a specific version with custom settings
./pve-cloudimg.sh create ubuntu 24.04 --storage local-btrfs --disk-size 64 --ssh-key ~/.ssh/id_rsa.pub
# Create with custom user and resources
./pve-cloudimg.sh create debian --user admin --cores 4 --memory 8192 --bridge vmbr1
# Create on a specific VLAN
./pve-cloudimg.sh create ubuntu --vlan 100
# Install extra packages alongside the guest agent
./pve-cloudimg.sh create ubuntu --packages "htop nfs-common"
# Live dangerously — Arch Linux rolling release
./pve-cloudimg.sh create arch
# Force re-download even if cached (adds --force to any command)
./pve-cloudimg.sh download ubuntu --force
./pve-cloudimg.sh create ubuntu --force
# Update to the latest image (re-download and re-create template)
./pve-cloudimg.sh update ubuntu
# Replace an existing template with a completely different distro
./pve-cloudimg.sh remove ubuntu
./pve-cloudimg.sh create debian
# Remove a template and its cached image
./pve-cloudimg.sh remove ubuntu 24.04
```
## Supported Distributions
| Distro | Default | Versions | Default User |
|--------|---------|----------|-------------|
| Ubuntu | 26.04 | 26.04, 24.04 | `ubuntu` |
| Debian | 13 | 13, 12 | `debian` |
| Arch Linux | rolling | rolling | `arch` |
## How It Works
1. **Download** (download command) — Fetches the official cloud image from the distro's mirrors and caches it locally. No modifications.
2. **Resize** (create command only) — Expands the disk to the requested size on a working copy (cloud-init's `growpart` resizes the partition on first boot)
3. **First-boot script** (create command only) — Writes a systemd oneshot service via `virt-customize` that installs packages (qemu-guest-agent + any extras) on first boot of each cloned VM
4. **Create VM** (create command only) — Configures CPU, memory, VirtIO SCSI controller, serial console, and QEMU guest agent
5. **Cloud-Init** (create command only) — Sets default user, optional SSH key, and DHCP networking
6. **Template** (create command only) — Converts the VM to a Proxmox template ready for cloning
Use `download` to just fetch and cache the image without any modifications. Use `create` for the full pipeline (resize + firstboot installer + import + template).
## Deploying a VM from a Template
```bash
# Clone the template — repeat for as many VMs as you need
qm clone <template-vmid> <new-vmid> --name my-vm --full
# Or with a specific target storage
qm clone <template-vmid> <new-vmid> --name my-vm --full --storage local-btrfs
```
## Customizing Cloud-Init Per-VM
After cloning, edit the clone's cloud-init config:
```bash
qm set <new-vmid> --ciuser myuser --sshkeys ~/.ssh/id_rsa.pub
qm set <new-vmid> --ipconfig0 ip=192.168.1.100/24,gw=192.168.1.1
qm set <new-vmid> --nameserver 1.1.1.1
qm set <new-vmid> --searchdomain example.com
qm start <new-vmid>
```
## QEMU Guest Agent
Rather than installing packages inside a chroot during image preparation (which breaks on many distros due to Landlock, missing dnf, incompatible arch detection, etc.), the `create` command writes a first-boot installer into the working copy via `virt-customize --firstboot-command`. This creates a systemd oneshot service that runs on the first boot of each cloned VM:
| Distro family | Runs on first boot |
|---------------|-------------------|
| Ubuntu, Debian | `apt-get update && apt-get install -y qemu-guest-agent` |
| Arch Linux | `pacman -S --noconfirm qemu-guest-agent` |
The installer runs in the actual VM environment with full kernel support, network access, and proper repos — no chroot limitations.
The `download` command does **not** apply any first-boot scripts — it only fetches and caches the raw cloud image.
To skip agent installation: `--no-agent`
## Installing Extra Packages
Two ways to add packages beyond `qemu-guest-agent`:
**Per-run** with `--packages`:
```bash
./pve-cloudimg.sh create ubuntu --packages "htop nfs-common"
```
**Per-distro** by adding entries right under each `DISTROS` definition in the script:
```bash
DISTROS["ubuntu:26.04"]="..."
DISTRO_PACKAGES["ubuntu:26.04"]="htop nfs-common"
```
Packages with different names across distros get their own `DISTRO_PACKAGES` entry.
## Adding a New Distribution
Edit `pve-cloudimg.sh` and add entries near the top of the file. Each distro gets one or more `DISTROS` lines, with an optional `DISTRO_PACKAGES` line directly below:
```bash
# Image definition
DISTROS["mydistro:1.0"]="https://example.com/image.qcow2|filename.qcow2|default-user|qcow2"
# Extra packages (optional, right below its DISTROS entry)
DISTRO_PACKAGES["mydistro:1.0"]="my-package other-package"
```
The `DISTROS` format is: `url|filename|default_user|image_format`
Then add a default version so `create mydistro` (without a version) works:
```bash
DISTRO_DEFAULT_VERSION[mydistro]="1.0"
```
## Notes
- Run on the Proxmox host — the script auto-elevates with `sudo` if not run as root
- Images are cached in `<script-dir>/cloud-images/` by default — override with `-d` or `$PVE_CLOUDIMG_DIR`
- If you add the script to PATH (e.g. `/usr/local/bin/`), set `PVE_CLOUDIMG_DIR=/var/cache/proxmox-cloudimg` in your shell rc so it doesn't try to write into `/usr/local/bin/cloud-images/`
- The script auto-increments VM IDs starting at 9000
- Cloud images from official distro mirrors — always up to date
- Use `-f`/`--force` to re-download an image even if already cached (e.g., to refresh a stale image)
- Resized disks use cloud-init's built-in `growpart` for automatic partition resizing on first boot
- Templates, clones, and cached images are independent — removing a template or cached image **does not** affect running VMs cloned from it
- To replace a template with a different distro, `remove` the old one then `create` the new one — they get separate VM IDs