Skip to content

feat: add native Linux mode (vmType=native) — bypass Lima/QEMU on Linux hosts#1565

Open
architectureman wants to merge 3 commits into
abiosoft:mainfrom
vnknowledge2014:feat/native-linux
Open

feat: add native Linux mode (vmType=native) — bypass Lima/QEMU on Linux hosts#1565
architectureman wants to merge 3 commits into
abiosoft:mainfrom
vnknowledge2014:feat/native-linux

Conversation

@architectureman
Copy link
Copy Markdown

@architectureman architectureman commented Apr 30, 2026

Motivation

On Linux hosts, Colima currently creates a full Linux VM via Lima/QEMU even though the host itself is already running Linux. This adds unnecessary overhead in terms of CPU, memory, disk, and startup time. Many Linux users expect container runtimes to run natively — the same way Docker Desktop works on Linux.

This PR introduces vmType: "native" which allows Colima on Linux to use the host's container runtime directly, eliminating the virtualization layer entirely while keeping the same Colima UX (profiles, colima start/stop/status/delete, Docker context management, Kubernetes provisioning, etc.).

What's New

# On Linux — auto-detected, zero config needed
colima start                         # uses native mode by default

# Or explicitly
colima start --vm-type native        # bypass VM, use host Docker/containerd/Incus
colima start --vm-type qemu          # traditional VM mode (still fully supported)

How It Works

A new environment/vm/native/ package implements the environment.VM interface using direct host execution (os/exec) instead of SSH-based Lima commands:

Component VM Mode (existing) Native Mode (new)
Command execution limactl shell ... (SSH) Direct os/exec.Command
File I/O SFTP via Lima os.ReadFile/os.WriteFile
Docker socket ~/.colima/.../docker.sock (forwarded) /var/run/docker.sock
Resource info limautil.Instance() /proc/cpuinfo + syscall.Statfs
Host gateway host.lima.internal ip route show default
Network Lima virtual network Host network (direct)

Safety Guarantees

  • Zero impact on macOS — native mode is Linux-only; all existing VM paths remain untouched
  • Opt-out available — users can still use --vm-type qemu on Linux if they prefer isolation
  • Guard pattern — all limautil.* calls are guarded with conf.VMType != "native" checks
  • colima model — intentionally blocked in native mode for the initial release (GPU passthrough setup differs from krunkit)

Changes Summary

New files (7):

  • util/linux.goLinux() detection helper
  • environment/vm/native/{native,shell,file,config,hostinfo}.go — Full VM interface implementation
  • model/guest.go — Centralized newGuest() factory (replaces 13× hardcoded lima.New())

Modified files (18):

  • environment/vm.goDefaultVMType() returns native on Linux
  • config/config.goDriverLabel() returns "Native"
  • config/configmanager/configmanager.go — Skip VM validations for native
  • app/app.goNewWithVMType() factory + limautil guards
  • cmd/{start,restart,clone,ssh-config,prune,util}.go — CLI integration
  • environment/container/docker/{daemon,context}.go — Socket + gateway fallback
  • environment/container/kubernetes/{k3s,kubeconfig}.go — IP address guards
  • environment/container/incus/incus.go — Disk provisioning guard
  • model/{docker,ramalama,runner}.gonewGuest() migration

Testing

Test Result
Cross-compile GOOS=linux GOARCH=amd64
macOS regression GOOS=darwin GOARCH=arm64
go vet ./...
E2E: start → status → stop → delete (in Colima VM)
E2E Test Output (click to expand)
$ colima-test start --vm-type native -p native-test
INFO[0000] starting colima [profile=native-test]
INFO[0000] runtime: docker
INFO[0000] starting (native mode) ...     context=vm
INFO[0000] provisioning ...               context=docker
> Successfully created context "colima-native-test"
> Current context is now "colima-native-test"
INFO[0014] starting ...                   context=docker
INFO[0014] done

$ colima-test status -p native-test
INFO[0000] colima [profile=native-test] is running using Native
INFO[0000] arch: x86_64
INFO[0000] runtime: docker
INFO[0000] docker socket: unix:///var/run/docker.sock

$ colima-test status -p native-test --json
{"driver":"Native","cpu":2,"memory":2061250560,"disk":19682557952,...}

$ colima-test stop -p native-test
INFO[0000] stopping colima [profile=native-test]
INFO[0010] done

$ colima-test delete -p native-test --force
INFO[0000] deleting colima [profile=native-test]
INFO[0000] done

Use Cases

  1. CI/CD pipelines — Run Colima in GitHub Actions/GitLab CI Linux runners without QEMU overhead
  2. Linux workstations — Developers on Linux get zero-overhead container management with Colima's UX
  3. Server deployments — Unified Colima interface across macOS (VM) and Linux (native) environments
  4. GUI management — Community projects like Colima UI (a Tauri-based desktop app providing visual management for Colima instances) already support this native mode, showing growing ecosystem adoption and enabling Linux users to manage Docker/K8s visually without any VM overhead

Dependencies

  • Linux host with systemd
  • Container runtime pre-installed (Docker, containerd, or Incus)
  • User in the docker group (for Docker runtime)

Future Work

  • colima model support in native mode (NVIDIA Container Toolkit integration)
  • Native mode for WSL2 (Windows Subsystem for Linux)
  • Unit tests for environment/vm/native/ package

…ux hosts

Add vmType 'native' that runs container runtimes (Docker, containerd, Incus, K3s)
directly on the Linux host without any virtualization layer.

Key changes:
- New environment/vm/native/ package: VM interface via direct host execution
- Config validation: native type auto-detected on Linux, skips VM-specific checks
- App factory: NewWithVMType() solves config-before-VM-creation ordering
- model/guest.go: centralized newGuest() replaces 13x hardcoded lima.New()
- Command guards: skip limautil calls when in native mode
- Docker daemon: fallback from host.lima.internal to ip route for gateway IP
- Docker context: use /var/run/docker.sock directly in native mode
- K3s/Kubeconfig: use host IP and primary interface
- Incus: guard DiskProvisioned/MountPoint for native
- colima model: blocked in native mode (GPU passthrough requires krunkit VM)

Tested:
- Cross-compiled GOOS=linux GOARCH=amd64: OK
- macOS regression GOOS=darwin GOARCH=arm64: OK
- go vet: OK
- E2E in Colima VM: start → status → stop → delete lifecycle verified
architectureman added 2 commits April 30, 2026 10:56
- Add NativeInstances() to scan state files directly from filesystem
- Modify Instances() to merge Lima + native instances with dedup
- Gracefully handle missing limactl (return nil instead of error)
- Fix currentRuntime() to fallback to config for native mode
- Fix Teardown() to clean up state directory on delete
- Add isSystemdActive() and getNativeIPAddress() helpers

All 7 E2E tests pass on Ubuntu 24.04 VM:
  1. List (empty) ✓
  2. Start (native docker) ✓
  3. List (running) ✓
  4. Status ✓
  5. JSON output ✓
  6. Delete ✓
  7. List (after delete) ✓
Ensures Linux users running VM-mode (Lima/QEMU) still see proper
error messages if limactl encounters issues. Only suppresses the
'executable not found' case for native-only setups.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant