|
| 1 | +--- |
| 2 | +name: EC2-Style Full VM Support |
| 3 | +overview: Add a new "full VM" mode alongside the existing container-exec mode, allowing users to boot ISOs/cloud images or systemd-based OCI images with proper PID 1 (systemd), while still running the hypeman guest-agent for exec/shell capabilities. |
| 4 | +todos: |
| 5 | + - id: phase1-mode-flag |
| 6 | + content: Add --mode full flag to CLI and mode field to API |
| 7 | + status: pending |
| 8 | + - id: phase1-config-disk |
| 9 | + content: Add FULL_VM_MODE to config disk generation |
| 10 | + status: pending |
| 11 | + - id: phase1-init-script |
| 12 | + content: Modify init script with pivot_root path for systemd handoff |
| 13 | + status: pending |
| 14 | + - id: phase1-agent-service |
| 15 | + content: Create systemd service unit for guest-agent injection |
| 16 | + status: pending |
| 17 | + - id: phase2-uefi-firmware |
| 18 | + content: Download and bundle hypervisor-fw for UEFI boot |
| 19 | + status: pending |
| 20 | + - id: phase2-cloud-image |
| 21 | + content: Add cloud image download and conversion support |
| 22 | + status: pending |
| 23 | + - id: phase2-cloudinit-disk |
| 24 | + content: Implement cloud-init NoCloud datasource disk generation |
| 25 | + status: pending |
| 26 | + - id: phase3-imds |
| 27 | + content: Implement EC2-compatible IMDS in guest-agent |
| 28 | + status: pending |
| 29 | +--- |
| 30 | + |
| 31 | +# EC2-Style Full VM Support for Hypeman |
| 32 | + |
| 33 | +## Current Architecture |
| 34 | + |
| 35 | +```mermaid |
| 36 | +flowchart LR |
| 37 | + subgraph boot [Current Boot Chain] |
| 38 | + CH[Cloud Hypervisor] --> Kernel[Direct Kernel Boot] |
| 39 | + Kernel --> Initrd[Custom Initrd] |
| 40 | + Initrd --> InitScript[Shell Init PID 1] |
| 41 | + InitScript --> GuestAgent[guest-agent] |
| 42 | + InitScript --> Entrypoint[Container Entrypoint] |
| 43 | + end |
| 44 | +``` |
| 45 | + |
| 46 | +Your current approach is optimized for container-like workloads: |
| 47 | + |
| 48 | +- **Direct kernel boot** with custom initrd (no bootloader) |
| 49 | +- **Shell script as PID 1** that runs entrypoint + guest-agent |
| 50 | +- **OCI images as rootfs** via overlay filesystem |
| 51 | + |
| 52 | +## Proposed Architecture: Two VM Modes |
| 53 | + |
| 54 | +```mermaid |
| 55 | +flowchart TB |
| 56 | + subgraph modes [Instance Mode Selection] |
| 57 | + Create[hypeman run] --> ModeCheck{--mode?} |
| 58 | + ModeCheck -->|exec default| ExecMode[Exec Mode] |
| 59 | + ModeCheck -->|full| FullMode[Full VM Mode] |
| 60 | + end |
| 61 | + |
| 62 | + subgraph exec [Exec Mode - Current] |
| 63 | + ExecMode --> DirectBoot[Direct Kernel Boot] |
| 64 | + DirectBoot --> CustomInitrd[Custom Initrd] |
| 65 | + CustomInitrd --> ShellPID1[Shell PID 1] |
| 66 | + ShellPID1 --> AgentBG[guest-agent background] |
| 67 | + ShellPID1 --> AppFG[Entrypoint foreground] |
| 68 | + end |
| 69 | + |
| 70 | + subgraph full [Full VM Mode - New] |
| 71 | + FullMode --> BootType{Boot Source?} |
| 72 | + BootType -->|cloud image| CloudImg[Cloud Image] |
| 73 | + BootType -->|systemd OCI| SystemdOCI[Systemd OCI Image] |
| 74 | + CloudImg --> UEFI[UEFI Boot] |
| 75 | + SystemdOCI --> DirectBoot2[Direct Kernel Boot] |
| 76 | + DirectBoot2 --> PivotRoot[pivot_root to rootfs] |
| 77 | + PivotRoot --> Systemd[systemd PID 1] |
| 78 | + UEFI --> Systemd |
| 79 | + Systemd --> AgentService[guest-agent.service] |
| 80 | + end |
| 81 | +``` |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +## How EC2 Does It |
| 86 | + |
| 87 | +1. **AMI = Bootable EBS Volume**: Contains bootloader (GRUB), kernel, initramfs, full OS with systemd |
| 88 | +2. **IMDS (Instance Metadata Service)**: HTTP endpoint at `169.254.169.254` provides instance config, credentials, user-data |
| 89 | +3. **cloud-init**: Runs on boot to configure networking, SSH keys, run user-data scripts |
| 90 | +4. **SSM Agent / SSH**: Enables remote access post-boot |
| 91 | + |
| 92 | +## Recommended Approach |
| 93 | + |
| 94 | +### Option A: UEFI Boot with Cloud Images (Recommended for ISOs/Cloud Images) |
| 95 | + |
| 96 | +For booting Ubuntu/Debian cloud images or custom ISOs: |
| 97 | + |
| 98 | +1. **Use Cloud Hypervisor's UEFI firmware** (`hypervisor-fw`) |
| 99 | +2. **Boot from disk image** (qcow2/raw) containing full OS with systemd |
| 100 | +3. **cloud-init for configuration**: Create a cloud-init NoCloud datasource disk with: |
| 101 | + |
| 102 | +- Network configuration |
| 103 | +- SSH keys |
| 104 | +- Guest-agent installation/startup |
| 105 | + |
| 106 | +4. **Guest-agent as systemd service**: Install and enable via cloud-init |
| 107 | +```bash |
| 108 | +# Example: Convert cloud image for Cloud Hypervisor |
| 109 | +wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img |
| 110 | +qemu-img convert -p -f qcow2 -O raw noble-server-cloudimg-amd64.img noble.raw |
| 111 | + |
| 112 | +# Boot with UEFI |
| 113 | +cloud-hypervisor \ |
| 114 | + --kernel hypervisor-fw \ |
| 115 | + --disk path=noble.raw path=cloud-init.img \ |
| 116 | + --cpus boot=4 --memory size=2G \ |
| 117 | + --net tap=tap0,mac=... |
| 118 | +``` |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | + |
| 123 | +### Option B: Direct Kernel Boot with Systemd Handoff (Recommended for Systemd OCI Images) |
| 124 | + |
| 125 | +For OCI images that contain systemd (e.g., `systemd/systemd` base images): |
| 126 | + |
| 127 | +1. **Keep current direct kernel boot** (fast, no bootloader) |
| 128 | +2. **Modify init script** to detect `FULL_VM_MODE=1` in config |
| 129 | +3. **Use `pivot_root` + `exec /sbin/init`** instead of running entrypoint |
| 130 | +4. **Pre-install guest-agent** as systemd service in the image or inject via overlay |
| 131 | +```1:294:hypeman/lib/system/init_script.go |
| 132 | +// Extend init_script.go with full-vm mode: |
| 133 | + |
| 134 | +# After overlay setup and network config, add: |
| 135 | +if [ "${FULL_VM_MODE:-0}" = "1" ]; then |
| 136 | + # Full VM mode: hand off to systemd |
| 137 | + echo "overlay-init: full-vm mode - switching to systemd" |
| 138 | + |
| 139 | + # Install guest-agent as systemd service |
| 140 | + mkdir -p /overlay/newroot/etc/systemd/system |
| 141 | + cat > /overlay/newroot/etc/systemd/system/hypeman-agent.service << 'EOF' |
| 142 | +[Unit] |
| 143 | +Description=Hypeman Guest Agent |
| 144 | +After=network.target |
| 145 | + |
| 146 | +[Service] |
| 147 | +ExecStart=/usr/local/bin/guest-agent |
| 148 | +Restart=always |
| 149 | +RestartSec=5 |
| 150 | + |
| 151 | +[Install] |
| 152 | +WantedBy=multi-user.target |
| 153 | +EOF |
| 154 | + |
| 155 | + ln -sf /etc/systemd/system/hypeman-agent.service \ |
| 156 | + /overlay/newroot/etc/systemd/system/multi-user.target.wants/hypeman-agent.service |
| 157 | + |
| 158 | + # pivot_root and exec systemd |
| 159 | + cd /overlay/newroot |
| 160 | + pivot_root . oldroot |
| 161 | + exec /sbin/init |
| 162 | +fi |
| 163 | +``` |
| 164 | + |
| 165 | + |
| 166 | + |
| 167 | + |
| 168 | +### Option C: Hybrid Metadata Service (EC2-Compatible) |
| 169 | + |
| 170 | +For maximum EC2 compatibility: |
| 171 | + |
| 172 | +1. **Implement IMDS-compatible endpoint** in guest-agent at `169.254.169.254` |
| 173 | +2. **Serve instance metadata, user-data, credentials** via this endpoint |
| 174 | +3. **Works with standard cloud-init** out of the box |
| 175 | + |
| 176 | +## Recommended Implementation Path |
| 177 | + |
| 178 | +| Feature | Complexity | EC2-Feel | Notes ||---------|------------|----------|-------|| Option B (systemd OCI) | Low | Medium | Extends current init script, minimal changes || Option A (UEFI + cloud images) | Medium | High | Requires UEFI firmware, cloud-init disk generation || Option C (IMDS) | Medium | Very High | Makes cloud-init "just work" | |
| 179 | + |
| 180 | +### Suggested Phased Approach |
| 181 | + |
| 182 | +**Phase 1: Systemd OCI Support (Option B)** |
| 183 | + |
| 184 | +- Add `--mode full` flag to `hypeman run` |
| 185 | +- Add `FULL_VM_MODE` to config disk generation |
| 186 | +- Modify init script to pivot_root + exec systemd |
| 187 | +- Inject guest-agent.service into overlay |
| 188 | + |
| 189 | +**Phase 2: Cloud Image Support (Option A)** |
| 190 | + |
| 191 | +- Add `--boot-image` flag for raw/qcow2 images |
| 192 | +- Download and bundle UEFI firmware (hypervisor-fw) |
| 193 | +- Generate cloud-init NoCloud datasource disks |
| 194 | +- Package guest-agent as installable .deb/.rpm |
| 195 | + |
| 196 | +**Phase 3: IMDS Compatibility (Option C)** |
| 197 | + |
| 198 | +- Add HTTP server to guest-agent listening on 169.254.169.254:80 |
| 199 | +- Implement EC2 IMDS v1/v2 compatible endpoints |
| 200 | +- Remove need for custom cloud-init config |
| 201 | + |
| 202 | +## Processing ISOs into Bootable Images |
| 203 | + |
| 204 | +For ISOs, you have two paths: |
| 205 | + |
| 206 | +1. **One-time conversion** (recommended): Install the ISO to a disk image using QEMU/virt-install, then use the resulting disk image as a template |
| 207 | + ```bash |
| 208 | + # Create empty disk |
| 209 | + qemu-img create -f raw base.raw 20G |
| 210 | + |
| 211 | + # Install from ISO (interactive or via preseed/kickstart) |
| 212 | + qemu-system-x86_64 -enable-kvm -m 2G \ |
| 213 | + -cdrom ubuntu-22.04.iso \ |
| 214 | + -drive file=base.raw,format=raw \ |
| 215 | + -boot d |
| 216 | + |
| 217 | + # After installation, use base.raw as template |
| 218 | + |
| 219 | + ``` |
0 commit comments