115 lines
3.9 KiB
Bash
115 lines
3.9 KiB
Bash
#!/usr/bin/env bash
|
||
# Deploy Rina VM on a remote host running QEMU/libvirt (virsh).
|
||
# Uses Debian cloud image + cloud-init for automated minimal install.
|
||
#
|
||
# Run on the remote machine (or from your machine with LIBVIRT_DEFAULT_URI).
|
||
# Requires: libvirt, virt-install, qemu-img, genisoimage (or cloud-image-utils)
|
||
|
||
set -e
|
||
|
||
VM_NAME="${VM_NAME:-CUBE}"
|
||
CPU="${CPU:-2}"
|
||
MEMORY_GB="${MEMORY_GB:-4}"
|
||
DISK_GB="${DISK_GB:-128}"
|
||
# Debian 13 (Trixie) generic cloud image with cloud-init
|
||
DEBIAN_IMAGE_URL="${DEBIAN_IMAGE_URL:-https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2}"
|
||
IMAGE_NAME=$(basename "$DEBIAN_IMAGE_URL")
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
CLOUD_INIT_DIR="$SCRIPT_DIR/cloud-init"
|
||
POOL_DIR="${POOL_DIR:-/var/lib/libvirt/images}"
|
||
BASE_IMAGE="$POOL_DIR/$IMAGE_NAME"
|
||
VM_DISK="$POOL_DIR/${VM_NAME}.qcow2"
|
||
SEED_ISO="$POOL_DIR/${VM_NAME}-seed.iso"
|
||
# Network: libvirt virtual network (e.g. 'default') or host bridge
|
||
# VLAN 40 (eth1.40 + br1.40): run systemd-networkd config on the host first, then:
|
||
# BRIDGE=br1.40 ./deploy-rina-vm.sh
|
||
# Other: BRIDGE=br0 or NETWORK=default
|
||
NETWORK="${NETWORK:-default}"
|
||
BRIDGE="${BRIDGE:-br1.40}"
|
||
|
||
echo "=== Rina VM deployment ==="
|
||
echo " VM name: $VM_NAME"
|
||
echo " CPU: $CPU Memory: ${MEMORY_GB}G Disk: ${DISK_GB}G"
|
||
echo " Base image: $DEBIAN_IMAGE_URL"
|
||
echo " Pool dir: $POOL_DIR"
|
||
if [[ -n "$BRIDGE" ]]; then
|
||
echo " Network: bridge $BRIDGE"
|
||
else
|
||
echo " Network: $NETWORK"
|
||
fi
|
||
echo ""
|
||
|
||
# 1) Ensure base image exists and resize copy for VM
|
||
if [[ ! -f "$BASE_IMAGE" ]]; then
|
||
echo "Downloading Debian cloud image..."
|
||
sudo mkdir -p "$POOL_DIR"
|
||
sudo curl -L -o "$BASE_IMAGE" "$DEBIAN_IMAGE_URL"
|
||
echo "Downloaded $BASE_IMAGE"
|
||
fi
|
||
|
||
if [[ -f "$VM_DISK" ]]; then
|
||
echo "VM disk already exists: $VM_DISK"
|
||
read -p "Overwrite? (y/N) " -n 1 -r; echo
|
||
if [[ ! $REPLY =~ ^[yY]$ ]]; then
|
||
echo "Aborted."
|
||
exit 1
|
||
fi
|
||
sudo rm -f "$VM_DISK"
|
||
fi
|
||
|
||
echo "Creating VM disk (${DISK_GB}G) from base image..."
|
||
sudo qemu-img create -f qcow2 -F qcow2 -b "$BASE_IMAGE" "$VM_DISK"
|
||
sudo qemu-img resize "$VM_DISK" "${DISK_GB}G"
|
||
echo "Done: $VM_DISK"
|
||
|
||
# 2) Build cloud-init NoCloud seed ISO
|
||
for f in user-data meta-data network-config; do
|
||
if [[ ! -f "$CLOUD_INIT_DIR/$f" ]]; then
|
||
echo "Missing cloud-init file: $CLOUD_INIT_DIR/$f"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
if command -v cloud-localds &>/dev/null; then
|
||
echo "Building seed ISO with cloud-localds..."
|
||
cloud-localds -v "$SEED_ISO" \
|
||
"$CLOUD_INIT_DIR/user-data" \
|
||
"$CLOUD_INIT_DIR/meta-data"
|
||
else
|
||
echo "Building seed ISO with genisoimage..."
|
||
TMP_CI="$SCRIPT_DIR/.cloud-init-seed"
|
||
mkdir -p "$TMP_CI"
|
||
cp "$CLOUD_INIT_DIR/user-data" "$CLOUD_INIT_DIR/meta-data" "$TMP_CI/"
|
||
sudo genisoimage -output "$SEED_ISO" -volid cidata -joliet -rock "$TMP_CI"/user-data "$TMP_CI"/meta-data
|
||
rm -rf "$TMP_CI"
|
||
fi
|
||
echo "Seed ISO: $SEED_ISO"
|
||
|
||
# 3) Create and start VM
|
||
if sudo virsh list --all --name | grep -qx "$VM_NAME"; then
|
||
echo "VM '$VM_NAME' already defined. Undefine it first: virsh undefine $VM_NAME"
|
||
exit 1
|
||
fi
|
||
|
||
echo "Creating VM..."
|
||
sudo virt-install \
|
||
--name "$VM_NAME" \
|
||
--memory "$(( MEMORY_GB * 1024 ))" \
|
||
--vcpus "$CPU" \
|
||
--import \
|
||
--disk "path=$VM_DISK,format=qcow2,bus=virtio" \
|
||
--disk "path=$SEED_ISO,device=cdrom,bus=sata" \
|
||
--network "$(if [[ -n "$BRIDGE" ]]; then echo "bridge=$BRIDGE,model=virtio"; else echo "network=$NETWORK,model=virtio"; fi)" \
|
||
--os-variant debiantrixie \
|
||
--noautoconsole
|
||
|
||
# 4) Dump domain XML to project directory for reference/version control
|
||
VM_XML="$SCRIPT_DIR/${VM_NAME}.xml"
|
||
sudo virsh dumpxml "$VM_NAME" > "$VM_XML"
|
||
echo "VM definition saved to: $VM_XML"
|
||
|
||
echo ""
|
||
echo "VM '$VM_NAME' is starting. First boot runs cloud-init (user rina, password rinapwd; IP from cloud-init/user-data, e.g. 192.168.0.225)."
|
||
echo "To open console: virsh console $VM_NAME"
|
||
echo "To check: virsh list; ssh rina@<VM_IP> (after cloud-init finishes, ~1–2 min)."
|