Skip to content

Commit d09b2d8

Browse files
committed
plan
1 parent 5e522f2 commit d09b2d8

File tree

2 files changed

+655
-0
lines changed

2 files changed

+655
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
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

Comments
 (0)