Skip to content

Commit f0d8608

Browse files
committed
tweaks
1 parent 1d67894 commit f0d8608

File tree

4 files changed

+56
-77
lines changed

4 files changed

+56
-77
lines changed

Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,10 @@ lib/system/guest_agent/guest-agent: lib/system/guest_agent/*.go
170170
cd lib/system/guest_agent && CGO_ENABLED=0 go build -ldflags="-s -w" -o guest-agent .
171171

172172
# Build init binary (runs as PID 1 in guest VM) for embedding
173-
# Uses static linking for portability across different guest environments
174173
lib/system/init/init: lib/system/init/*.go
175174
@echo "Building init binary..."
176175
cd lib/system/init && CGO_ENABLED=0 go build -ldflags="-s -w" -o init .
177176

178-
# Build all embedded binaries
179177
build-embedded: lib/system/guest_agent/guest-agent lib/system/init/init
180178

181179
# Build the binary

cmd/api/api/exec_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ func TestExecInstanceNonTTY(t *testing.T) {
115115
t.Logf("vsock socket exists: %s", actualInst.VsockSocket)
116116
}
117117

118-
// Wait for exec agent to be ready using WaitForAgent
119118
var stdout, stderr outputBuffer
120119

121120
dialer, err := hypervisor.NewVsockDialer(actualInst.HypervisorType, actualInst.VsockSocket, actualInst.VsockCID)

lib/system/README.md

Lines changed: 39 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Manages versioned kernel and initrd files for Cloud Hypervisor VMs.
44

55
## Features
66

7-
- **Automatic Downloads**: Kernel downloaded from Cloud Hypervisor releases on first use
7+
- **Automatic Downloads**: Kernel downloaded from onkernel/linux releases on first use
88
- **Automatic Build**: Initrd built from Alpine base + Go init binary + guest-agent
9-
- **Versioned**: Side-by-side support for multiple kernel/initrd versions
9+
- **Versioned**: Side-by-side support for multiple kernel versions
1010
- **Zero Docker**: Uses OCI directly (reuses image manager infrastructure)
1111
- **Zero Image Modifications**: All init logic in initrd, OCI images used as-is
1212
- **Dual Mode Support**: Exec mode (container-like) and systemd mode (full VM)
@@ -18,27 +18,27 @@ Manages versioned kernel and initrd files for Cloud Hypervisor VMs.
1818
```
1919
{dataDir}/system/
2020
├── kernel/
21-
│ ├── ch-v6.12.8/
21+
│ ├── ch-6.12.8-kernel-1-202511182/
2222
│ │ ├── x86_64/vmlinux (~70MB)
2323
│ │ └── aarch64/Image (~70MB)
24-
│ └── ch-v6.12.9/
25-
│ └── ... (future version)
24+
│ └── ch-6.12.8-kernel-1.2-20251213/
25+
│ └── ... (newer version)
2626
├── initrd/
27-
│ ├── v1.0.0/
28-
│ │ ├── x86_64/initrd (~1-2MB)
29-
│ │ └── aarch64/initrd (~1-2MB)
30-
── v1.1.0/
31-
└── ... (when init script changes)
32-
└── oci-cache/ (shared with images manager)
33-
└── blobs/sha256/ (busybox layers cached)
27+
│ ├── 1734567890/ (timestamp-based)
28+
│ │ ├── x86_64/initrd (~5-10MB)
29+
│ │ └── aarch64/initrd
30+
── x86_64/latest -> 1734567890 (symlink to latest)
31+
│ └── aarch64/latest -> 1734567890
32+
└── oci-cache/ (shared with images manager)
33+
└── blobs/sha256/ (Alpine layers cached)
3434
```
3535

3636
### Versioning Rules
3737

3838
**Snapshots require exact matches:**
3939
```
40-
Standby: kernel v6.12.9, initrd v1.0.0, CH v49.0
41-
Restore: kernel v6.12.9, initrd v1.0.0, CH v49.0 (MUST match)
40+
Standby: kernel ch-6.12.8-kernel-1.2-20251213, CH v49.0
41+
Restore: kernel ch-6.12.8-kernel-1.2-20251213, CH v49.0 (MUST match)
4242
```
4343

4444
**Maintenance upgrades (shutdown → boot):**
@@ -50,8 +50,8 @@ Restore: kernel v6.12.9, initrd v1.0.0, CH v49.0 (MUST match)
5050

5151
**Multi-version support:**
5252
```
53-
Instance A (standby): kernel v6.12.8, initrd v1.0.0
54-
Instance B (running): kernel v6.12.9, initrd v1.0.0
53+
Instance A (standby): kernel ch-6.12.8-kernel-1-202511182
54+
Instance B (running): kernel ch-6.12.8-kernel-1.2-20251213
5555
Both work independently
5656
```
5757

@@ -66,67 +66,36 @@ It replaces the previous shell-based init script with cleaner logic and structur
6666
- ✅ Network configuration (if enabled)
6767
- ✅ Load GPU drivers (if GPU attached)
6868
- ✅ Mount volumes
69-
- ✅ Auto-detect systemd images from CMD
7069
- ✅ Execute container entrypoint (exec mode)
71-
- ✅ Hand off to systemd via pivot_root (systemd mode)
70+
- ✅ Hand off to systemd via chroot + exec (systemd mode)
7271

7372
**Two boot modes:**
74-
- **Exec mode** (default): Init binary is PID 1, runs entrypoint as child process
75-
- **Systemd mode** (auto-detected): Uses pivot_root to hand off to systemd as PID 1
73+
- **Exec mode** (default): Init chroots to container rootfs, runs entrypoint as child process, then waits on guest-agent to keep VM alive
74+
- **Systemd mode** (auto-detected on host): Init chroots to container rootfs, then execs /sbin/init so systemd becomes PID 1
7675

77-
**Systemd detection:** If image CMD is `/sbin/init`, `/lib/systemd/systemd`, or similar,
78-
hypeman automatically uses systemd mode.
76+
**Systemd detection:** Host-side detection in `lib/images/systemd.go` checks if image CMD is
77+
`/sbin/init`, `/lib/systemd/systemd`, or similar. The detected mode is passed to the initrd
78+
via `INIT_MODE` in the config disk.
7979

8080
**Result:** OCI images require **zero modifications** - no `/init` script needed!
8181

82-
## Usage
83-
84-
### Application Startup
85-
86-
```go
87-
// cmd/api/main.go
88-
systemMgr := system.NewManager(dataDir)
89-
90-
// Ensure files exist (download/build if needed)
91-
err := systemMgr.EnsureSystemFiles(ctx)
92-
93-
// Files are ready, instances can be created
94-
```
95-
96-
### Instance Creation
97-
98-
```go
99-
// Instances manager uses system manager automatically
100-
inst, err := instanceManager.CreateInstance(ctx, req)
101-
// Uses default kernel/initrd versions
102-
// Versions stored in instance metadata for restore compatibility
103-
```
104-
105-
### Get File Paths
106-
107-
```go
108-
kernelPath, _ := systemMgr.GetKernelPath(system.KernelV6_12_9)
109-
initrdPath, _ := systemMgr.GetInitrdPath(system.InitrdV1_0_0)
110-
```
111-
11282
## Kernel Sources
11383

114-
Kernels downloaded from Cloud Hypervisor releases:
115-
- https://github.com/cloud-hypervisor/linux/releases
84+
Kernels downloaded from onkernel/linux releases (Cloud Hypervisor-optimized fork):
85+
- https://github.com/onkernel/linux/releases
11686

11787
Example URLs:
118-
- x86_64: `https://github.com/cloud-hypervisor/linux/releases/download/ch-v6.12.9/vmlinux-x86_64`
119-
- aarch64: `https://github.com/cloud-hypervisor/linux/releases/download/ch-v6.12.9/Image-aarch64`
88+
- x86_64: `https://github.com/onkernel/linux/releases/download/ch-6.12.8-kernel-1.2-20251213/vmlinux-x86_64`
89+
- aarch64: `https://github.com/onkernel/linux/releases/download/ch-6.12.8-kernel-1.2-20251213/Image-arm64`
12090

12191
## Initrd Build Process
12292

12393
1. **Pull Alpine base** (using image manager's OCI client)
12494
2. **Add guest-agent binary** (embedded, runs in guest for exec/shell)
125-
3. **Add init binary** (embedded Go binary, runs as PID 1)
126-
4. **Add NVIDIA modules** (optional, for GPU passthrough)
127-
5. **Package as cpio.gz** (initramfs format)
128-
129-
**Build tools required:** `find`, `cpio`, `gzip` (standard Unix tools)
95+
3. **Add init.sh wrapper** (mounts /proc, /sys, /dev before Go runtime)
96+
4. **Add init binary** (embedded Go binary, runs as PID 1)
97+
5. **Add NVIDIA modules** (optional, for GPU passthrough)
98+
6. **Package as cpio** (initramfs format, pure Go - no shell tools required)
13099

131100
## Adding New Versions
132101

@@ -136,19 +105,19 @@ Example URLs:
136105
// lib/system/versions.go
137106

138107
const (
139-
KernelV6_12_10 KernelVersion = "ch-v6.12.10" // Add constant
108+
Kernel_20251220 KernelVersion = "ch-6.12.8-kernel-1.3-20251220" // Add constant
140109
)
141110

142111
var KernelDownloadURLs = map[KernelVersion]map[string]string{
143112
// ... existing ...
144-
KernelV6_12_10: {
145-
"x86_64": "https://github.com/cloud-hypervisor/linux/releases/download/ch-v6.12.10/vmlinux-x86_64",
146-
"aarch64": "https://github.com/cloud-hypervisor/linux/releases/download/ch-v6.12.10/Image-aarch64",
113+
Kernel_20251220: {
114+
"x86_64": "https://github.com/onkernel/linux/releases/download/ch-6.12.8-kernel-1.3-20251220/vmlinux-x86_64",
115+
"aarch64": "https://github.com/onkernel/linux/releases/download/ch-6.12.8-kernel-1.3-20251220/Image-arm64",
147116
},
148117
}
149118

150119
// Update default if needed
151-
var DefaultKernelVersion = KernelV6_12_10
120+
var DefaultKernelVersion = Kernel_20251220
152121
```
153122

154123
### Updating the Init Binary
@@ -188,13 +157,13 @@ Files downloaded/built once per version, reused for all instances using that ver
188157
```
189158
lib/system/init/
190159
main.go # Entry point, orchestrates boot
191-
mount.go # Mount operations (proc, sys, dev, overlay)
160+
init.sh # Shell wrapper (mounts /proc, /sys, /dev before Go runtime)
161+
mount.go # Mount operations (overlay, bind mounts)
192162
config.go # Parse config disk
193163
network.go # Network configuration
194164
drivers.go # GPU driver loading
195165
volumes.go # Volume mounting
196-
mode_exec.go # Exec mode: run entrypoint
197-
mode_systemd.go # Systemd mode: pivot_root + exec init
166+
mode_exec.go # Exec mode: chroot, run entrypoint, wait on guest-agent
167+
mode_systemd.go # Systemd mode: chroot + exec /sbin/init
198168
logger.go # Human-readable logging to hypeman operations log
199169
```
200-

lib/system/init/mode_exec.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,30 @@ import (
1212
// - The init binary remains PID 1
1313
// - Guest-agent runs as a background process
1414
// - The container entrypoint runs as a child process
15-
// - When the entrypoint exits, the VM exits
15+
// - After entrypoint exits, guest-agent keeps VM alive
1616
func runExecMode(log *Logger, cfg *Config) {
1717
const newroot = "/overlay/newroot"
1818

19+
// Change root to the new filesystem using chroot (consistent with systemd mode)
20+
log.Info("exec", "executing chroot")
21+
if err := syscall.Chroot(newroot); err != nil {
22+
log.Error("exec", "chroot failed", err)
23+
dropToShell()
24+
}
25+
26+
// Change to new root directory
27+
if err := os.Chdir("/"); err != nil {
28+
log.Error("exec", "chdir / failed", err)
29+
dropToShell()
30+
}
31+
1932
// Set up environment
2033
os.Setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
2134
os.Setenv("HOME", "/root")
2235

23-
// Start guest-agent in background inside the container namespace
36+
// Start guest-agent in background
2437
log.Info("exec", "starting guest-agent in background")
25-
agentCmd := exec.Command("/usr/sbin/chroot", newroot, "/opt/hypeman/guest-agent")
38+
agentCmd := exec.Command("/opt/hypeman/guest-agent")
2639
agentCmd.Stdout = os.Stdout
2740
agentCmd.Stderr = os.Stderr
2841
if err := agentCmd.Start(); err != nil {
@@ -47,7 +60,7 @@ func runExecMode(log *Logger, cfg *Config) {
4760
log.Info("exec", "launching entrypoint")
4861

4962
// Run the entrypoint
50-
appCmd := exec.Command("/usr/sbin/chroot", newroot, "/bin/sh", "-c", shellCmd)
63+
appCmd := exec.Command("/bin/sh", "-c", shellCmd)
5164
appCmd.Stdin = os.Stdin
5265
appCmd.Stdout = os.Stdout
5366
appCmd.Stderr = os.Stderr

0 commit comments

Comments
 (0)