Skip to content

feat(firecracker): implement AttachVolume, DetachVolume, ResizeInstance, and real TAP networking - #701

Merged
poyrazK merged 10 commits into
mainfrom
feature/firecracker-volume-resize-network
Jun 13, 2026
Merged

feat(firecracker): implement AttachVolume, DetachVolume, ResizeInstance, and real TAP networking#701
poyrazK merged 10 commits into
mainfrom
feature/firecracker-volume-resize-network

Conversation

@poyrazK

@poyrazK poyrazK commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

Implements remaining Firecracker gaps identified in PR #691:

Features Added

Feature Implementation
AttachVolume Stop VM → rebuild config with extra drive → restart (cold attach)
DetachVolume Stop VM → rebuild config without specified drive → restart
ResizeInstance Stop VM → update CPU/memory → restart (cold resize)
CreateNetwork Real TAP device via ip tuntap add with MAC from generateMAC()
DeleteNetwork Real TAP device deletion via ip tuntap del

Technical Details

  • All VM-modifying operations (Attach/Detach/Resize) cause brief downtime — Firecracker has no hot-attach API
  • TAP device operations require root/CAP_NET_ADMIN
  • GetInstanceIP still returns 0.0.0.0 (would need instance→TAP mapping tracking)
  • Exec remains NotImplemented — Firecracker has no guest agent mechanism

Files Changed

  • internal/repositories/firecracker/adapter.go — main implementation

Testing

  • Build passes ✅
  • Unit tests pass ✅
  • E2E tests pass (in mock mode) ✅

Copilot AI review requested due to automatic review settings June 9, 2026 16:28
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@poyrazK, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 56 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f9bb49b2-23eb-4d53-bf54-627a9e239aa0

📥 Commits

Reviewing files that changed from the base of the PR and between 9bfeb83 and ffaaa6e.

📒 Files selected for processing (3)
  • internal/repositories/firecracker/adapter.go
  • internal/repositories/firecracker/adapter_test.go
  • tests/firecracker_e2e_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/firecracker-volume-resize-network

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes remaining feature gaps in the Firecracker compute backend by adding cold (stop/recreate/start) support for volume attach/detach and instance resizing, and by switching network creation/deletion to real TAP devices via ip tuntap.

Changes:

  • Implement cold AttachVolume/DetachVolume by rebuilding the Firecracker machine config and restarting the VM.
  • Implement cold ResizeInstance by updating vCPU/memory in the machine config and restarting the VM.
  • Implement real TAP-based CreateNetwork/DeleteNetwork using ip commands and deterministic MAC generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/repositories/firecracker/adapter.go Outdated
Comment on lines +422 to +425
tapName := "fc-" + name[:8]
if len(tapName) > 14 {
tapName = tapName[:14]
}
Comment on lines +429 to +432
if err := exec.CommandContext(ctx, "ip", "tuntap", "add", "dev", tapName, "mode", "tap").Run(); err != nil {
a.logger.Warn("failed to create TAP device", "tap", tapName, "error", err)
return "", fmt.Errorf("failed to create TAP device: %w", err)
}
a.attachedVolumes[id] = append(a.attachedVolumes[id], volumePath)
a.mu.Unlock()

return "/dev/vdb", "", nil
Comment on lines +471 to +483
a.mu.Lock()
cfg, ok := a.machineConfigs[id]
m, okMachine := a.machines[id]
if !ok || !okMachine {
a.mu.Unlock()
return "", "", fmt.Errorf("instance %s not found", id)
}

// Stop VM gracefully
if err := m.Shutdown(ctx); err != nil {
a.mu.Unlock()
return "", "", fmt.Errorf("failed to stop VM for volume attach: %w", err)
}
Comment on lines +527 to +539
a.mu.Lock()
cfg, ok := a.machineConfigs[id]
m, okMachine := a.machines[id]
if !ok || !okMachine {
a.mu.Unlock()
return "", fmt.Errorf("instance %s not found", id)
}

// Stop VM gracefully
if err := m.Shutdown(ctx); err != nil {
a.mu.Unlock()
return "", fmt.Errorf("failed to stop VM for volume detach: %w", err)
}
Comment on lines +616 to +620
// Update machine config with new CPU and memory
newCfg := cfg
newCfg.MachineCfg.VcpuCount = firecracker.Int64(cpu)
newCfg.MachineCfg.MemSizeMib = firecracker.Int64(memory / 1024 / 1024)

Comment on lines +598 to +600
if a.cfg.MockMode {
return fmt.Errorf("resize not implemented in mock mode")
}
Comment on lines +602 to +614
a.mu.Lock()
cfg, ok := a.machineConfigs[id]
m, okMachine := a.machines[id]
if !ok || !okMachine {
a.mu.Unlock()
return fmt.Errorf("instance %s not found", id)
}

// Stop VM gracefully
if err := m.Shutdown(ctx); err != nil {
a.mu.Unlock()
return fmt.Errorf("failed to stop VM for resize: %w", err)
}
poyrazK added 10 commits June 13, 2026 16:42
Also implement real TAP device creation in CreateNetwork with MAC address.
Wire generateMAC to CreateNetwork for proper TAP device configuration.

Features implemented:
- AttachVolume: stop VM → add drive to config → restart → track volume
- DetachVolume: stop VM → remove drive from config → restart
- ResizeInstance: stop VM → update CPU/memory → restart
- CreateNetwork: real TAP device via ip tuntap with MAC from generateMAC
- DeleteNetwork: real TAP device deletion via ip tuntap del

Note: All VM-modifying operations cause brief downtime (cold restart).
Requires root/CAP_NET_ADMIN for TAP device management.
The delete(a.instanceNetworks, id) line in DeleteInstance referenced a field
that was never declared in the FirecrackerAdapter struct. This caused a
compile error on Linux (GOOS=linux) while being invisible on macOS due to
the //go:build linux build tag.
…ack, dead code

- Fix TAP device name collision: use UUID instead of name truncation
- Add rebuildFromConfig() helper for rollback on failed rebuilds
- Apply rollback to AttachVolume, DetachVolume, ResizeInstance
- Remove dead attachedVolumes map (written but never read)
- Add unit tests for rebuild logic (RebuildSuccess, Rollback, NotFound)
- Format adapter.go with gofmt
- Change Start mock from .Once() to .Maybe() since Start is called
  twice per test (once in LaunchInstanceWithOptions, once in rebuild)
Tests were asserting error messages that don't match actual code:
- ResizeInstance MockMode: 'resize not supported' → 'resize not implemented in mock mode'
- ResizeInstance RealMode NotFound: 'resize not supported' → 'not found'
- AttachVolume RealMode NotFound: 'not implemented' → 'not found'
Test was setting newMachineFn to fail BEFORE launch, but launch also needs
a working machine. Now properly:
1. Launch with working machine
2. Replace newMachineFn to fail
3. Call AttachVolume which fails on new machine creation
Use _ = to explicitly ignore error return values from cleanup
exec calls in CreateNetwork error handlers (errcheck lint)
In CI, FIRECRACKER_MOCK_MODE=true so adapter returns 'not implemented'
instead of 'not found'. Tests now accept either error message.
CreateNetwork/DeleteNetwork require root/CAP_NET_ADMIN privileges.
Skip tests gracefully instead of failing when privileges are missing.
Extract CreateAndDeleteNetwork and DeleteNetwork_Twice into a
separate TestFirecrackerBackend_E2E_Network function to reduce
cyclomatic complexity of TestFirecrackerBackend_E2E below 30.
@poyrazK
poyrazK force-pushed the feature/firecracker-volume-resize-network branch from 1baf6d5 to ffaaa6e Compare June 13, 2026 13:42

@poyrazK poyrazK left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's okay to merge

@poyrazK
poyrazK merged commit 4dec69b into main Jun 13, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants