Created
June 27, 2026 06:58
-
-
Save gbraad/4ebc13a14e65c694240ad5f8f14b8e6a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # --- CONFIGURATION --- | |
| VM_NAME="ducttape-guest" | |
| IMAGE_PATH="./ducttape-output.qcow2" # Path to your ducttape QCOW2 image | |
| FW_PATH="./hypervisor-fw" # Path to store/read the CH firmware | |
| SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK...your...ssh...key...here..." | |
| VM_CPUS="2" | |
| VM_MEM="2G" | |
| # --- VALIDATION --- | |
| if [ ! -f "$IMAGE_PATH" ]; then | |
| echo "[-] Error: ducttape image not found at $IMAGE_PATH" | |
| exit 1 | |
| fi | |
| # Automatically fetch cloud-hypervisor firmware if it's missing | |
| if [ ! -f "$FW_PATH" ]; then | |
| echo "[+] Downloading cloud-hypervisor UEFI firmware..." | |
| curl -sL "https://github.com/cloud-hypervisor/cloud-hypervisor/releases/latest/download/hypervisor-fw" -o "$FW_PATH" | |
| fi | |
| # --- CLOUD-INIT GENERATION --- | |
| echo "[+] Generating cloud-init configuration..." | |
| TEMP_DIR=$(mktemp -d) | |
| # 1. Create user-data (defines users, keys, and packages) | |
| cat << EOF > "${TEMP_DIR}/user-data" | |
| #cloud-config | |
| users: | |
| - name: clouduser | |
| sudo: ALL=(ALL) NOPASSWD:ALL | |
| shell: /bin/bash | |
| ssh_authorized_keys: | |
| - ${SSH_KEY} | |
| package_update: true | |
| packages: | |
| - curl | |
| - htop | |
| EOF | |
| # 2. Create meta-data (defines instance ID and hostname) | |
| INSTANCE_ID=$(uuidgen 2>/dev/null || echo "id-$(date +%s)") | |
| cat << EOF > "${TEMP_DIR}/meta-data" | |
| instance-id: ${INSTANCE_ID} | |
| local-hostname: ${VM_NAME} | |
| EOF | |
| # 3. Bake into a NoCloud ISO | |
| echo "[+] Creating cloud-init seed ISO (cidata.iso)..." | |
| genisoimage -output ./cidata.iso -V cidata -r -J "${TEMP_DIR}/user-data" "${TEMP_DIR}/meta-data" &>/dev/null | |
| # Clean up local raw text files | |
| rm -rf "$TEMP_DIR" | |
| # --- LAUNCH HYPERVISOR --- | |
| echo "[+] Booting VM with cloud-hypervisor..." | |
| echo "[*] Press Ctrl+O to exit the console once inside the VM." | |
| echo "--------------------------------------------------------" | |
| # Note: Accessing /dev/kvm typically requires sudo or membership in the kvm group | |
| sudo cloud-hypervisor \ | |
| --kernel "$FW_PATH" \ | |
| --disk path="$IMAGE_PATH" path="./cidata.iso" \ | |
| --cpus boot="$VM_CPUS" \ | |
| --memory size="$VM_MEM" \ | |
| --console off \ | |
| --serial tty |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment