Full Code of abiosoft/colima for AI

main 8cb5d3528716 cached
143 files
429.4 KB
126.5k tokens
790 symbols
1 requests
Download .txt
Showing preview only (463K chars total). Download the full file or copy to clipboard to get everything.
Repository: abiosoft/colima
Branch: main
Commit: 8cb5d3528716
Files: 143
Total size: 429.4 KB

Directory structure:
gitextract_xof0cru8/

├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yaml
│   │   └── feature_request.yaml
│   ├── dependabot.yaml
│   └── workflows/
│       ├── go.yml
│       ├── golang-ci.yml
│       └── integration.yml
├── .gitignore
├── .golangci.yml
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── app/
│   └── app.go
├── cli/
│   ├── chain.go
│   └── command.go
├── cmd/
│   ├── clone.go
│   ├── colima/
│   │   └── main.go
│   ├── completion.go
│   ├── daemon/
│   │   ├── cmd.go
│   │   ├── daemon.go
│   │   └── daemon_test.go
│   ├── delete.go
│   ├── kubernetes.go
│   ├── list.go
│   ├── model.go
│   ├── nerdctl.go
│   ├── prune.go
│   ├── restart.go
│   ├── root/
│   │   └── root.go
│   ├── ssh-config.go
│   ├── ssh.go
│   ├── start.go
│   ├── start_test.go
│   ├── status.go
│   ├── stop.go
│   ├── template.go
│   ├── update.go
│   ├── util.go
│   └── version.go
├── colima.nix
├── config/
│   ├── config.go
│   ├── configmanager/
│   │   └── configmanager.go
│   ├── files.go
│   └── profile.go
├── core/
│   └── core.go
├── daemon/
│   ├── daemon.go
│   └── process/
│       ├── inotify/
│       │   ├── events.go
│       │   ├── inotify.go
│       │   ├── volumes.go
│       │   ├── volumes_test.go
│       │   └── watch.go
│       ├── process.go
│       └── vmnet/
│           ├── deps.go
│           └── vmnet.go
├── default.nix
├── docs/
│   ├── CONTRIBUTE.md
│   ├── FAQ.md
│   └── INSTALL.md
├── embedded/
│   ├── defaults/
│   │   ├── abort.yaml
│   │   ├── colima.yaml
│   │   └── template.yaml
│   ├── embed.go
│   ├── images/
│   │   ├── images.txt
│   │   └── images_sha.sh
│   ├── k3s/
│   │   └── flannel.json
│   ├── network/
│   │   └── sudo.txt
│   └── sudoers.go
├── environment/
│   ├── container/
│   │   ├── containerd/
│   │   │   ├── buildkitd.toml
│   │   │   ├── config.toml
│   │   │   └── containerd.go
│   │   ├── docker/
│   │   │   ├── config.toml
│   │   │   ├── containerd.go
│   │   │   ├── context.go
│   │   │   ├── daemon.go
│   │   │   ├── docker.go
│   │   │   └── proxy.go
│   │   ├── incus/
│   │   │   ├── config.yaml
│   │   │   ├── incus.go
│   │   │   └── route.go
│   │   └── kubernetes/
│   │       ├── cni.go
│   │       ├── k3s.go
│   │       ├── kubeconfig.go
│   │       └── kubernetes.go
│   ├── container.go
│   ├── environment.go
│   ├── guest/
│   │   └── systemctl/
│   │       ├── systemctl.go
│   │       └── systemctl_test.go
│   ├── host/
│   │   └── host.go
│   ├── host.go
│   ├── vm/
│   │   └── lima/
│   │       ├── certs.go
│   │       ├── config.go
│   │       ├── daemon.go
│   │       ├── disk.go
│   │       ├── disk.sh
│   │       ├── dns.go
│   │       ├── file.go
│   │       ├── lima.go
│   │       ├── limaconfig/
│   │       │   └── config.go
│   │       ├── limautil/
│   │       │   ├── disk.go
│   │       │   ├── files.go
│   │       │   ├── image.go
│   │       │   ├── instance.go
│   │       │   ├── limautil.go
│   │       │   ├── network.go
│   │       │   └── ssh.go
│   │       ├── network.go
│   │       ├── shell.go
│   │       ├── yaml.go
│   │       └── yaml_test.go
│   └── vm.go
├── flake.nix
├── go.mod
├── go.sum
├── integration/
│   └── Dockerfile
├── model/
│   ├── docker.go
│   ├── ramalama.go
│   ├── runner.go
│   └── runner_test.go
├── scripts/
│   ├── build_vmnet.sh
│   └── integration.sh
├── shell.nix
├── store/
│   └── store.go
└── util/
    ├── debutil/
    │   └── debutil.go
    ├── downloader/
    │   ├── curl.go
    │   ├── download.go
    │   ├── errors.go
    │   ├── http.go
    │   ├── native.go
    │   └── sha.go
    ├── fsutil/
    │   └── fs.go
    ├── macos.go
    ├── macos_test.go
    ├── osutil/
    │   └── os.go
    ├── qemu.go
    ├── shautil/
    │   └── sha.go
    ├── template.go
    ├── terminal/
    │   ├── output.go
    │   └── terminal.go
    ├── util.go
    └── yamlutil/
        ├── yaml.go
        └── yaml_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
[*.go]
indent_style = tab

================================================
FILE: .github/FUNDING.yml
================================================
github: abiosoft
custom:
  - "https://buymeacoffee.com/abiosoft"
patreon: colima


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yaml
================================================
name: Bug report
description: Report a bug or issue
body:
  - type: textarea
    attributes:
      label: Description
      description: A clear and concise description of what the issue is.
  - type: textarea
    attributes:
      label: Version
      description: Please show the output of `colima version && limactl --version && qemu-img --version`.
  - type: checkboxes
    attributes:
      label: Operating System
      description: Which Operating System/Architecture does this issue happen on? Check all that apply.
      options:
        - label: macOS Intel <= 13 (Ventura)
          required: false
        - label: macOS Intel >= 14 (Sonoma)
          required: false
        - label: Apple Silicon <= 13 (Ventura)
          required: false
        - label: Apple Silicon >= 14 (Sonoma)
          required: false
        - label: Linux
          required: false
  - type: textarea
    attributes:
      label: Output of `colima status`
      description: The output of `colima status` or `colima status -p <profilename>` tells us what vm-type and mount type, etc.
      value:
  - type: textarea
    attributes:
      label: Reproduction Steps
      description: Kindly walk us through the steps to reproduce this behaviour.
      value: |
        1.
        2.
        3.
  - type: textarea
    attributes:
      label: Expected behaviour
      description: A clear and concise description of what you expected to happen.
  - type: textarea
    attributes:
      label: Additional context
      description: Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yaml
================================================
name: Feature request
description: Request a missing feature
body:
  - type: textarea
    attributes:
      label: Description


================================================
FILE: .github/dependabot.yaml
================================================
version: 2
updates:
- package-ecosystem: "gomod"
  directory: "/"
  schedule:
    interval: "daily"
  open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
  directory: "/"
  schedule:
    interval: "weekly"

================================================
FILE: .github/workflows/go.yml
================================================
name: Go

on:
  push:
    tags: ["v*"]
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"
  pull_request:
    branches: [main]
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"

permissions: write-all

jobs:
  build-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Build
        run: go build -v ./...

      - name: Test
        run: go test -v ./...

  build-macos:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Build
        run: go build -v ./...

      - name: Test
        run: go test -v ./...

  binaries-linux:
    needs: "build-linux"
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: install gcc-aarch64-linux-gnu
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu

      - name: generate binaries
        run: |
          OS=Linux ARCH=x86_64 make
          OS=Linux ARCH=aarch64 make

      - name: upload artifacts
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: artifacts-linux
          path: _output/binaries/

  binaries-macos:
    needs: "build-macos"
    runs-on: macos-15-intel

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: generate binaries
        run: |
          CGO_ENABLED=1 OS=Darwin ARCH=x86_64 make
          CGO_ENABLED=1 OS=Darwin ARCH=arm64 make

      - name: upload artifacts
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: artifacts-macos
          path: _output/binaries/


  release:
    needs: ["binaries-linux", "binaries-macos"]
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
        with:
          name: artifacts-linux
          path: _output/binaries/
      - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
        with:
          name: artifacts-macos
          path: _output/binaries/
      - name: create release
        if: github.event_name != 'pull_request'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: >
          tag="${GITHUB_REF##*/}"

          gh release create "${tag}" --draft --title "${tag}"
          _output/binaries/colima-Darwin-x86_64
          _output/binaries/colima-Darwin-x86_64.sha256sum
          _output/binaries/colima-Darwin-arm64
          _output/binaries/colima-Darwin-arm64.sha256sum
          _output/binaries/colima-Linux-x86_64
          _output/binaries/colima-Linux-x86_64.sha256sum
          _output/binaries/colima-Linux-aarch64
          _output/binaries/colima-Linux-aarch64.sha256sum


================================================
FILE: .github/workflows/golang-ci.yml
================================================
name: golangci-lint
on:
  push:
    tags: [v*]
    branches: [main]
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"
  pull_request:
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"
jobs:
  golangci:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"
      - name: golangci-lint
        uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
        with:
          version: v2.11.3
          args: --timeout 3m0s


================================================
FILE: .github/workflows/integration.yml
================================================
name: Integration

on:
  push:
    tags: ["v*"]
    branches: [main]
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"
  pull_request:
    branches: [main]
    paths-ignore:
      - "**/*.md"
      - "**/*.nix"
      - "**/*.lock"
  workflow_dispatch:
    inputs:
      debug_enabled:
        description: 'Debug with tmate set "debug_enabled"'
        required: false
        default: "false"

jobs:
  kubernetes-docker:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Install CLI deps
        run: brew install kubectl docker coreutils lima

      - name: Build and Install
        run: make && sudo make install

      - name: tmate debugging session
        uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
        with:
          limit-access-to-actor: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

      - name: Start Colima
        run: colima start --runtime docker --kubernetes

      - name: Delay
        run: sleep 20

      - name: Validate Kubernetes
        run: kubectl cluster-info && kubectl version && kubectl get nodes -o wide

      - name: Teardown
        run: colima delete -f

  kubernetes-containerd:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Install CLI deps
        run: brew install kubectl docker coreutils lima

      - name: Build and Install
        run: make && sudo make install

      - name: tmate debugging session
        uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
        with:
          limit-access-to-actor: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

      - name: Start
        run: colima start --runtime containerd --kubernetes

      - name: Delay
        run: sleep 20

      - name: Validate Kubernetes
        run: kubectl cluster-info && kubectl version && kubectl get nodes -o wide

      - name: Teardown
        run: colima delete -f

  docker:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Install CLI deps
        run: brew install kubectl docker coreutils lima

      - name: Build and Install
        run: make && sudo make install

      - name: tmate debugging session
        uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
        with:
          limit-access-to-actor: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

      - name: Start Colima
        run: colima start --runtime docker

      - name: Delay
        run: sleep 10

      - name: Validate Docker
        run: docker ps && docker info

      - name: Validate DNS
        run: colima ssh -- sh -c "sudo apt-get update -y -qq && sudo apt-get install -qq dnsutils && nslookup host.docker.internal"

      - name: Build Image
        run: docker build integration

      - name: Run Image arm64
        run: docker run --rm --platform=linux/arm64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Run Image amd64
        run: docker run --rm --platform=linux/amd64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Stop
        run: colima stop

      - name: Temp Delete
        run: colima delete -f

      - name: Restart
        run: colima start --runtime docker

      - name: Assert runtime disk arm64
        run: docker run --pull=never --rm --platform=linux/arm64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Assert runtime disk amd64
        run: docker run --pull=never --rm --platform=linux/amd64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Teardown
        run: colima delete --data -f

  containerd:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Install CLI deps
        run: brew install kubectl docker coreutils lima

      - name: Build and Install
        run: make && sudo make install

      - name: tmate debugging session
        uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
        with:
          limit-access-to-actor: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

      - name: Start Colima
        run: colima start --runtime containerd

      - name: Delay
        run: sleep 10

      - name: Validate Containerd
        run: colima nerdctl ps && colima nerdctl info

      - name: Validate DNS
        run: colima ssh -- sh -c "sudo apt-get update -y -qq && sudo apt-get install -qq dnsutils && nslookup host.docker.internal"

      - name: Build Image
        run: colima nerdctl -- build integration

      - name: Run Image arm64
        run: colima nerdctl -- run --rm --platform=linux/arm64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Run Image amd64
        run: colima nerdctl -- run --rm --platform=linux/amd64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Stop
        run: colima stop

      - name: Temp Delete
        run: colima delete -f

      - name: Restart
        run: colima start --runtime containerd

      - name: Assert runtime disk arm64
        run: colima nerdctl -- run --pull=never --rm --platform=linux/arm64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Assert runtime disk amd64
        run: colima nerdctl -- run --pull=never --rm --platform=linux/amd64 ghcr.io/linuxcontainers/alpine:latest uname -a

      - name: Teardown
        run: colima delete --data -f

  incus:
    runs-on: macos-15-intel
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
        with:
          go-version: "1.26.1"

      - name: Install CLI deps
        run: brew install kubectl docker coreutils lima incus

      - name: Build and Install
        run: make && sudo make install

      - name: tmate debugging session
        uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
        with:
          limit-access-to-actor: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

      - name: Start Colima
        run: colima start --runtime incus

      - name: Delay
        run: sleep 10

      - name: Validate Incus
        run: incus version && incus list

      - name: Launch Instance
        run: incus launch images:alpine/edge test-instance

      - name: Delay for instance
        run: sleep 5

      - name: Validate Instance
        run: incus exec test-instance -- cat /etc/os-release

      - name: Validate DNS
        run: colima ssh -- sh -c "sudo apt-get update -y -qq && sudo apt-get install -qq dnsutils && nslookup host.docker.internal"

      - name: Stop
        run: colima stop

      - name: Temp Delete
        run: colima delete -f

      - name: Restart
        run: colima start --runtime incus

      - name: Delay for restart
        run: sleep 10

      - name: Assert instance restored
        run: incus exec test-instance -- cat /etc/os-release

      - name: Teardown
        run: colima delete --data -f


================================================
FILE: .gitignore
================================================
.idea/
.fleet/
.vscode/
_output/
_build/
bin/
result


================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
  enable:
    - gocritic


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 Abiola Ibrahim

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================

OS ?= $(shell uname)
ARCH ?= $(shell uname -m)

GOOS ?= $(shell echo "$(OS)" | tr '[:upper:]' '[:lower:]')
GOARCH_x86_64 = amd64
GOARCH_aarch64 = arm64
GOARCH_arm64 = arm64
GOARCH ?= $(shell echo "$(GOARCH_$(ARCH))")

VERSION := $(shell git describe --tags --always)
REVISION := $(shell git rev-parse HEAD)
PACKAGE := github.com/abiosoft/colima/config
VERSION_VARIABLES := -X $(PACKAGE).appVersion=$(VERSION) -X $(PACKAGE).revision=$(REVISION)

OUTPUT_DIR := _output/binaries
OUTPUT_BIN := colima-$(OS)-$(ARCH)
INSTALL_DIR := /usr/local/bin
BIN_NAME := colima

LDFLAGS := $(VERSION_VARIABLES)

.PHONY: all
all: build

.PHONY: clean
clean:
	rm -rf _output _build

.PHONY: gopath
gopath:
	go get -v ./cmd/colima

.PHONY: fmt
fmt:
	go fmt ./...
	goimports -w .

.PHONY: build
build:
	GOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags="$(LDFLAGS)" -o $(OUTPUT_DIR)/$(OUTPUT_BIN) ./cmd/colima
ifeq ($(GOOS),darwin)
	codesign -s - $(OUTPUT_DIR)/$(OUTPUT_BIN)
endif
	cd $(OUTPUT_DIR) && openssl sha256 -r -out $(OUTPUT_BIN).sha256sum $(OUTPUT_BIN)

.PHONY: test
test:
	go test -v -ldflags="$(LD_FLAGS)" ./...

.PHONY: vmnet
vmnet:
	sh scripts/build_vmnet.sh

.PHONY: install
install:
	mkdir -p $(INSTALL_DIR)
	rm -f $(INSTALL_DIR)/$(BIN_NAME)
	cp $(OUTPUT_DIR)/colima-$(OS)-$(ARCH) $(INSTALL_DIR)/$(BIN_NAME)
	chmod +x $(INSTALL_DIR)/$(BIN_NAME)

.PHONY: lint
lint: ## Assumes that golangci-lint is installed and in the path.  To install: https://golangci-lint.run/usage/install/
	golangci-lint --timeout 3m run

.PHONY: print-binary-name
print-binary-name:
	@echo $(OUTPUT_DIR)/$(OUTPUT_BIN)

.PHONY: nix-derivation-shell
nix-derivation-shell:
	$(eval DERIVATION=$(shell nix-build))
	echo $(DERIVATION) | grep ^/nix
	nix-shell -p $(DERIVATION)

.PHONY: integration
integration: build
	GOARCH=$(GOARCH) COLIMA_BINARY=$(OUTPUT_DIR)/$(OUTPUT_BIN) scripts/integration.sh

.PHONY: images-sha
images-sha:
	bash embedded/images/images_sha.sh


================================================
FILE: README.md
================================================
![colima-logo](colima.png)

## Colima - container runtimes on macOS (and Linux) with minimal setup.

[![Go](https://github.com/abiosoft/colima/actions/workflows/go.yml/badge.svg)](https://github.com/abiosoft/colima/actions/workflows/go.yml)
[![Integration](https://github.com/abiosoft/colima/actions/workflows/integration.yml/badge.svg)](https://github.com/abiosoft/colima/actions/workflows/integration.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/abiosoft/colima)](https://goreportcard.com/report/github.com/abiosoft/colima)

![Demonstration](colima.gif)

**Website & Documentation:** [colima.run](https://colima.run) | [colima.run/docs](https://colima.run/docs/)

## Features

Support for Intel and Apple Silicon macOS, and Linux

- Simple CLI interface with sensible defaults
- Automatic Port Forwarding
- Volume mounts
- Multiple instances
- Support for multiple container runtimes
  - [Docker](https://docker.com) (with optional Kubernetes)
  - [Containerd](https://containerd.io) (with optional Kubernetes)
  - [Incus](https://linuxcontainers.org/incus) (containers and virtual machines)
- GPU accelerated containers for AI workloads

## Getting Started

### Installation

Colima is available on Homebrew, MacPorts, Nix and [Mise](http://github.com/jdx/mise). Check [here](docs/INSTALL.md) for other installation options.

```sh
# Homebrew
brew install colima

# MacPorts
sudo port install colima

# Nix
nix-env -iA nixpkgs.colima

# Mise
mise use -g colima@latest

```

Or stay on the bleeding edge (only Homebrew)

```
brew install --HEAD colima
```

## Usage

Start Colima with defaults

```
colima start
```

For more usage options

```
colima --help
colima start --help
```

Or use a config file

```
colima start --edit
```

## Runtimes

On initial startup, Colima initiates with a user specified runtime that defaults to Docker.

### Docker

Docker client is required for Docker runtime. Installable with `brew install docker`.

```
colima start
docker run hello-world
docker ps
```

You can use the `docker` client on macOS after `colima start` with no additional setup.

### Containerd

`colima start --runtime containerd` starts and setup Containerd. You can use `colima nerdctl` to interact with
Containerd using [nerdctl](https://github.com/containerd/nerdctl).

```
colima start --runtime containerd
nerdctl run hello-world
nerdctl ps
```

It is recommended to run `colima nerdctl install` to install `nerdctl` alias script in $PATH.

### Kubernetes

kubectl is required for Kubernetes. Installable with `brew install kubectl`.

To enable Kubernetes, start Colima with `--kubernetes` flag.

```
colima start --kubernetes
kubectl run caddy --image=caddy
kubectl get pods
```

#### Interacting with Image Registry

For Docker runtime, images built or pulled with Docker are accessible to Kubernetes.

For Containerd runtime, images built or pulled in the `k8s.io` namespace are accessible to Kubernetes.

### Incus

<small>**Requires v0.7.0**</small>


Incus client is required for Incus runtime. Installable with brew `brew install incus`.

`colima start --runtime incus` starts and setup Incus.

```
colima start --runtime incus
incus launch images:alpine/edge
incus list
```

You can use the `incus` client on macOS after `colima start` with no additional setup.

**Note:** Running virtual machines on Incus is only supported on m3 or newer Apple Silicon devices.

### AI Models (GPU Accelerated)

<small>**Requires v0.10.0, Apple Silicon and macOS 13+**</small>

Colima supports GPU accelerated containers for AI workloads using the `krunkit` VM type.

**Note:** To use krunkit with colima, ensure it is installed.

```
brew tap slp/krunkit
brew install krunkit
```

Setup and use a model.

```
colima start --runtime docker --vm-type krunkit
colima model run gemma3
```

Colima supports two model runner backends:

- **Docker Model Runner** (default) — supports [Docker AI Registry](https://hub.docker.com/u/ai) and [HuggingFace](https://huggingface.co).
- **Ramalama** — supports [HuggingFace](https://huggingface.co) and [Ollama](https://ollama.com) registries.

The default registry is the Docker AI Registry. Models can be run by name without a prefix:

```sh
colima model run gemma3
colima model run llama3.2
# HuggingFace (Docker Model Runner)
colima model run hf.co/microsoft/Phi-3-mini-4k-instruct-gguf
# Ollama (requires ramalama runner)
colima model run ollama://gemma3 --runner ramalama
```

See the [AI Workloads documentation](https://colima.run/docs/ai/) for more details.

### Customizing the VM

The default VM created by Colima has 2 CPUs, 2GiB memory and 100GiB storage.

The VM can be customized either by passing additional flags to `colima start`.
e.g. `--cpu`, `--memory`, `--disk`, `--runtime`.
Or by editing the config file with `colima start --edit`.

**NOTE**: Disk size can be increased after the VM is created.

#### Customization Examples

- create VM with 1CPU, 2GiB memory and 10GiB storage.

  ```
  colima start --cpu 1 --memory 2 --disk 10
  ```

- modify an existing VM to 4CPUs and 8GiB memory.

  ```
  colima stop
  colima start --cpu 4 --memory 8
  ```

- create VM with Rosetta 2 emulation. Requires v0.5.3 and macOS >= 13 (Ventura) on Apple Silicon.

  ```
  colima start --vm-type=vz --vz-rosetta
  ```

## Project Goal

To provide container runtimes on macOS with minimal setup.

## What is with the name?

Colima means Containers on [Lima](https://github.com/lima-vm/lima).

Since Lima is aka Linux Machines. By transitivity, Colima can also mean Containers on Linux Machines.

## And the Logo?

The logo was contributed by [Daniel Hodvogner](https://github.com/dhodvogner). Check [this issue](https://github.com/abiosoft/colima/issues/781) for more.

## Troubleshooting and FAQs

Check [here](docs/FAQ.md) for Frequently Asked Questions, or visit the [online FAQ](https://colima.run/docs/faq/) for a searchable version.

## How to Contribute?

Check [here](docs/CONTRIBUTE.md) for the instructions on contributing to the project.

## Community
- [GitHub Discussions](https://github.com/abiosoft/colima/discussions)
- [GitHub Issues](https://github.com/abiosoft/colima/issues)
- [Announcements](https://colima.run/announcements/)
- `#colima` channel in the CNCF Slack
  - New account: <https://slack.cncf.io/>
  - Login: <https://cloud-native.slack.com/>

## License

MIT


## Sponsoring the Project

If you (or your company) are benefiting from the project and would like to support the contributors, kindly sponsor.

- [Github Sponsors](https://github.com/sponsors/abiosoft)
- [Buy me a coffee](https://www.buymeacoffee.com/abiosoft)
- [Patreon](https://patreon.com/colima)

---

[<img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" style="max-height: 150px"/>](https://macstadium.com)




================================================
FILE: SECURITY.md
================================================
Thanks for helping make Colima safe for everyone.

## Security

We take the security of Colima seriously.

We will ensure that your finding gets passed along to the appropriate maintainers for remediation. 

## Reporting Security Issues

If you believe you have found a security vulnerability in this repository, please report it to us through coordinated disclosure.

**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**

Instead, please send an email to git[@]abiosoft.com.

Please include as much of the information listed below as you can to help us better understand and resolve the issue:

  * The type of issue (e.g., buffer overflow, SQL injection, or cross-site scripting)
  * Full paths of source file(s) related to the manifestation of the issue
  * The location of the affected source code (tag/branch/commit or direct URL)
  * Any special configuration required to reproduce the issue
  * Step-by-step instructions to reproduce the issue
  * Proof-of-concept or exploit code (if possible)
  * Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly.


================================================
FILE: app/app.go
================================================
package app

import (
	"bufio"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/config/configmanager"
	"github.com/abiosoft/colima/environment"
	"github.com/abiosoft/colima/environment/container/containerd"
	"github.com/abiosoft/colima/environment/container/docker"
	"github.com/abiosoft/colima/environment/container/incus"
	"github.com/abiosoft/colima/environment/container/kubernetes"
	"github.com/abiosoft/colima/environment/host"
	"github.com/abiosoft/colima/environment/vm/lima"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/abiosoft/colima/store"
	"github.com/abiosoft/colima/util"
	"github.com/docker/go-units"
	log "github.com/sirupsen/logrus"
)

type App interface {
	Active() bool
	Start(config.Config) error
	Stop(force bool) error
	Delete(data, force bool) error
	SSH(args ...string) error
	Status(extended bool, json bool) error
	Version() error
	Runtime() (string, error)
	Update() error
	Kubernetes() (environment.Container, error)
}

var _ App = (*colimaApp)(nil)

// New creates a new app.
func New() (App, error) {
	guest := lima.New(host.New())
	if err := host.IsInstalled(guest); err != nil {
		return nil, fmt.Errorf("dependency check failed for VM: %w", err)
	}

	return &colimaApp{
		guest: guest,
	}, nil
}

type colimaApp struct {
	guest environment.VM
}

func (c colimaApp) startWithRuntime(conf config.Config) ([]environment.Container, error) {
	kubernetesEnabled := conf.Kubernetes.Enabled

	// Kubernetes can only be enabled for docker and containerd
	switch conf.Runtime {
	case docker.Name, containerd.Name:
	default:
		kubernetesEnabled = false
	}

	var containers []environment.Container

	{
		runtime := conf.Runtime
		if kubernetesEnabled {
			runtime += "+k3s"
		}
		log.Println("runtime:", runtime)
	}

	// runtime
	{
		env, err := c.containerEnvironment(conf.Runtime)
		if err != nil {
			return nil, err
		}
		containers = append(containers, env)
	}

	// kubernetes should come after required runtime
	if kubernetesEnabled {
		env, err := c.containerEnvironment(kubernetes.Name)
		if err != nil {
			return nil, err
		}
		containers = append(containers, env)
	}

	return containers, nil
}

func (c colimaApp) Start(conf config.Config) error {
	ctx := context.WithValue(context.Background(), config.CtxKey(), conf)

	log.Println("starting", config.CurrentProfile().DisplayName)
	// print the full path of current profile being used
	log.Tracef("starting with config file: %s\n", config.CurrentProfile().File())

	var containers []environment.Container
	if !environment.IsNoneRuntime(conf.Runtime) {
		cs, err := c.startWithRuntime(conf)
		if err != nil {
			return err
		}
		containers = cs
	}

	// the order for start is:
	//   vm start -> container runtime provision -> container runtime start

	// start vm
	if err := c.guest.Start(ctx, conf); err != nil {
		return fmt.Errorf("error starting vm: %w", err)
	}

	// run after-boot provision scripts
	c.runProvisionScripts(conf, config.ProvisionModeAfterBoot)

	// provision and start container runtimes
	for _, cont := range containers {
		log := log.WithField("context", cont.Name())
		log.Println("provisioning ...")
		if err := cont.Provision(ctx); err != nil {
			return fmt.Errorf("error provisioning %s: %w", cont.Name(), err)
		}
		log.Println("starting ...")
		if err := cont.Start(ctx); err != nil {
			return fmt.Errorf("error starting %s: %w", cont.Name(), err)
		}
	}

	// run ready provision scripts
	c.runProvisionScripts(conf, config.ProvisionModeReady)

	// persist the current runtime
	if err := c.setRuntime(conf.Runtime); err != nil {
		log.Error(fmt.Errorf("error persisting runtime settings: %w", err))
	}

	// persist the kubernetes config
	if err := c.setKubernetes(conf.Kubernetes); err != nil {
		log.Error(fmt.Errorf("error persisting kubernetes settings: %w", err))
	}

	log.Println("done")

	if err := generateSSHConfig(conf.SSHConfig); err != nil {
		log.Trace("error generating ssh_config: %w", err)
	}
	return nil
}

func (c colimaApp) runProvisionScripts(conf config.Config, mode string) {
	var failed bool
	for _, s := range conf.Provision {
		if s.Mode != mode {
			continue
		}
		if err := c.guest.Run("sh", "-c", s.Script); err != nil {
			failed = true
		}
	}
	if failed {
		log.Warnln(fmt.Errorf("error running %s provision script(s)", mode))
	}
}

func (c colimaApp) Stop(force bool) error {
	ctx := context.Background()
	log.Println("stopping", config.CurrentProfile().DisplayName)

	// the order for stop is:
	//   container stop -> vm stop

	// stop container runtimes
	if c.guest.Running(ctx) {
		containers, err := c.currentContainerEnvironments(ctx)
		if err != nil {
			log.Warnln(fmt.Errorf("error retrieving runtimes: %w", err))
		}

		// stop happens in reverse of start
		for i := len(containers) - 1; i >= 0; i-- {
			cont := containers[i]

			log := log.WithField("context", cont.Name())
			log.Println("stopping ...")

			if err := cont.Stop(ctx, force); err != nil {
				// failure to stop a container runtime is not fatal
				// it is only meant for graceful shutdown.
				// the VM will shut down anyways.
				log.Warnln(fmt.Errorf("error stopping %s: %w", cont.Name(), err))
			}
		}
	}

	// stop vm
	// no need to check running status, it may be in a state that requires stopping.
	if err := c.guest.Stop(ctx, force); err != nil {
		return fmt.Errorf("error stopping vm: %w", err)
	}

	log.Println("done")

	if err := generateSSHConfig(false); err != nil {
		log.Trace("error generating ssh_config: %w", err)
	}
	return nil
}

func (c colimaApp) Delete(data, force bool) error {
	confirmContainerDestruction := func() bool {
		return cli.Prompt("\033[31m\033[1mthis will delete ALL container data. Are you sure you want to continue")
	}

	s, _ := store.Load()
	diskInUse := s.DiskFormatted

	if !force {
		y := cli.Prompt("are you sure you want to delete " + config.CurrentProfile().DisplayName + " and all settings")
		if !y {
			return nil
		}

		// runtime disk not in use or data deletion is requested,
		// deletion deletes all data, warn accordingly.
		if !diskInUse || data {
			if y := confirmContainerDestruction(); !y {
				return nil
			}
		}
	}

	ctx := context.Background()
	log.Println("deleting", config.CurrentProfile().DisplayName)

	// the order for teardown is:
	//   container teardown -> vm teardown

	// vm teardown would've sufficed but container provision
	// may have created configurations on the host.
	// it is thereby necessary to teardown containers as well.

	// teardown container runtimes
	if c.guest.Running(ctx) {
		containers, err := c.currentContainerEnvironments(ctx)
		if err != nil {
			log.Warnln(fmt.Errorf("error retrieving runtimes: %w", err))
		}
		for _, cont := range containers {
			log := log.WithField("context", cont.Name())
			log.Println("deleting ...")

			if err := cont.Teardown(ctx); err != nil {
				// failure here is not fatal
				log.Warnln(fmt.Errorf("error during teardown of %s: %w", cont.Name(), err))
			}
		}
	}

	// teardown vm
	if err := c.guest.Teardown(ctx); err != nil {
		return fmt.Errorf("error during teardown of vm: %w", err)
	}

	// delete configs
	if err := configmanager.Teardown(); err != nil {
		return fmt.Errorf("error deleting configs: %w", err)
	}

	// delete runtime disk if disk in use and data deletion is requested
	if diskInUse && data {
		log.Println("deleting container data")
		if err := limautil.DeleteDisk(); err != nil {
			return fmt.Errorf("error deleting container data: %w", err)
		}

		if err := store.Reset(); err != nil {
			log.Trace("error resetting store: %w", err)
		}
	}

	log.Println("done")

	if err := generateSSHConfig(false); err != nil {
		log.Trace("error generating ssh_config: %w", err)
	}
	return nil
}

func (c colimaApp) SSH(args ...string) error {
	ctx := context.Background()
	if !c.guest.Running(ctx) {
		return fmt.Errorf("%s not running", config.CurrentProfile().DisplayName)
	}

	workDir, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("error retrieving current working directory: %w", err)
	}
	// peek the current directory to see if it is mounted to prevent `cd` errors
	// with limactl ssh
	if err := func() error {
		conf, err := configmanager.LoadInstance()
		if err != nil {
			return err
		}
		pwd, err := util.CleanPath(workDir)
		if err != nil {
			return err
		}
		for _, m := range conf.MountsOrDefault() {
			location := m.MountPoint
			if location == "" {
				location = m.Location
			}
			location, err := util.CleanPath(location)
			if err != nil {
				log.Trace(err)
				continue
			}
			if strings.HasPrefix(pwd, location) {
				return nil
			}
		}
		return fmt.Errorf("not a mounted directory: %s", workDir)
	}(); err != nil {
		// the errors returned here is not critical and thereby silenced.
		// the goal is to prevent unnecessary warning message from Lima.
		log.Trace(fmt.Errorf("error checking if PWD is mounted: %w", err))
		workDir = ""
	}

	guest := lima.New(host.New())
	return guest.SSH(workDir, args...)
}

type statusInfo struct {
	DisplayName      string `json:"display_name"`
	Driver           string `json:"driver"`
	Arch             string `json:"arch"`
	Runtime          string `json:"runtime"`
	MountType        string `json:"mount_type"`
	IPAddress        string `json:"ip_address,omitempty"`
	DockerSocket     string `json:"docker_socket,omitempty"`
	ContainerdSocket string `json:"containerd_socket,omitempty"`
	BuildkitdSocket  string `json:"buildkitd_socket,omitempty"`
	IncusSocket      string `json:"incus_socket,omitempty"`
	Kubernetes       bool   `json:"kubernetes"`
	CPU              int    `json:"cpu"`
	Memory           int64  `json:"memory"`
	Disk             int64  `json:"disk"`
}

func (c colimaApp) getStatus() (status statusInfo, err error) {
	ctx := context.Background()
	if !c.guest.Running(ctx) {
		return status, fmt.Errorf("%s is not running", config.CurrentProfile().DisplayName)
	}

	currentRuntime, err := c.currentRuntime(ctx)
	if err != nil {
		return status, err
	}

	status.DisplayName = config.CurrentProfile().DisplayName
	status.Driver = "QEMU"
	conf, _ := configmanager.LoadInstance()
	if !conf.Empty() {
		status.Driver = conf.DriverLabel()
	}
	status.Arch = string(c.guest.Arch())
	status.Runtime = currentRuntime
	status.MountType = conf.MountType
	ipAddress := limautil.IPAddress(config.CurrentProfile().ID)
	if ipAddress != "127.0.0.1" {
		status.IPAddress = ipAddress
	}
	if currentRuntime == docker.Name {
		status.DockerSocket = "unix://" + docker.HostSocketFile()
		status.ContainerdSocket = "unix://" + containerd.HostSocketFiles().Containerd
	}
	if currentRuntime == containerd.Name {
		status.ContainerdSocket = "unix://" + containerd.HostSocketFiles().Containerd
		status.BuildkitdSocket = "unix://" + containerd.HostSocketFiles().Buildkitd
	}
	if currentRuntime == incus.Name {
		status.IncusSocket = "unix://" + incus.HostSocketFile()
	}
	if k, err := c.Kubernetes(); err == nil && k.Running(ctx) {
		status.Kubernetes = true
	}
	if inst, err := limautil.Instance(); err == nil {
		status.CPU = inst.CPU
		status.Memory = inst.Memory
		status.Disk = inst.Disk
	}
	return status, nil
}

func (c colimaApp) Status(extended bool, jsonOutput bool) error {
	status, err := c.getStatus()
	if err != nil {
		return err
	}

	if jsonOutput {
		if err := json.NewEncoder(os.Stdout).Encode(status); err != nil {
			return fmt.Errorf("error encoding status as json: %w", err)
		}
	} else {
		log.Println(config.CurrentProfile().DisplayName, "is running using", status.Driver)
		log.Println("arch:", status.Arch)
		log.Println("runtime:", status.Runtime)
		if status.MountType != "" {
			log.Println("mountType:", status.MountType)
		}

		// ip address
		if status.IPAddress != "" {
			log.Println("address:", status.IPAddress)
		}

		// docker socket
		if status.DockerSocket != "" {
			log.Println("docker socket:", status.DockerSocket)
		}
		if status.ContainerdSocket != "" {
			log.Println("containerd socket:", status.ContainerdSocket)
		}
		if status.BuildkitdSocket != "" {
			log.Println("buildkitd socket:", status.BuildkitdSocket)
		}
		if status.IncusSocket != "" {
			log.Println("incus socket:", status.IncusSocket)
		}

		// kubernetes
		if status.Kubernetes {
			log.Println("kubernetes: enabled")
		}

		// additional details
		if extended {
			if status.CPU > 0 {
				log.Println("cpu:", status.CPU)
			}
			if status.Memory > 0 {
				log.Println("mem:", units.BytesSize(float64(status.Memory)))
			}
			if status.Disk > 0 {
				log.Println("disk:", units.BytesSize(float64(status.Disk)))
			}
		}
	}
	return nil
}

func (c colimaApp) Version() error {
	ctx := context.Background()
	if !c.guest.Running(ctx) {
		return nil
	}

	containerRuntimes, err := c.currentContainerEnvironments(ctx)
	if err != nil {
		return err
	}

	var kube environment.Container
	for _, cont := range containerRuntimes {
		if cont.Name() == kubernetes.Name {
			kube = cont
			continue
		}

		fmt.Println()
		fmt.Println("runtime:", cont.Name())
		fmt.Println("arch:", c.guest.Arch())
		fmt.Println(cont.Version(ctx))
	}

	if kube != nil && kube.Version(ctx) != "" {
		fmt.Println()
		fmt.Println(kubernetes.Name)
		fmt.Println(kube.Version(ctx))
	}

	return nil
}

func (c colimaApp) currentRuntime(ctx context.Context) (string, error) {
	if !c.guest.Running(ctx) {
		return "", fmt.Errorf("%s is not running", config.CurrentProfile().DisplayName)
	}

	r := c.guest.Get(environment.ContainerRuntimeKey)
	if r == "" {
		return "", fmt.Errorf("error retrieving current runtime: empty value")
	}

	return r, nil
}

func (c colimaApp) setRuntime(runtime string) error {
	err := store.Set(func(s *store.Store) {
		// update runtime if runtime disk is in use
		if s.DiskFormatted {
			s.DiskRuntime = runtime
		}
	})

	if err != nil {
		log.Traceln(fmt.Errorf("error persisting store: %w", err))
	}

	return c.guest.Set(environment.ContainerRuntimeKey, runtime)
}

func (c colimaApp) setKubernetes(conf config.Kubernetes) error {
	b, err := json.Marshal(conf)
	if err != nil {
		return err
	}

	return c.guest.Set(kubernetes.ConfigKey, string(b))
}

func (c colimaApp) currentContainerEnvironments(ctx context.Context) ([]environment.Container, error) {
	var containers []environment.Container
	// runtime
	{
		runtime, err := c.currentRuntime(ctx)
		if err != nil {
			return nil, err
		}

		if environment.IsNoneRuntime(runtime) {
			return nil, nil
		}

		env, err := c.containerEnvironment(runtime)
		if err != nil {
			return nil, err
		}
		containers = append(containers, env)
	}

	// detect and add kubernetes
	if k, err := c.containerEnvironment(kubernetes.Name); err == nil && k.Running(ctx) {
		containers = append(containers, k)
	}

	return containers, nil
}

func (c colimaApp) containerEnvironment(runtime string) (environment.Container, error) {
	env, err := environment.NewContainer(runtime, c.guest.Host(), c.guest)
	if err != nil {
		return nil, fmt.Errorf("error initiating container runtime: %w", err)
	}
	if err := host.IsInstalled(env); err != nil {
		return nil, fmt.Errorf("dependency check failed for %s: %w", runtime, err)
	}

	return env, nil
}

func (c colimaApp) Runtime() (string, error) {
	return c.currentRuntime(context.Background())
}

func (c colimaApp) Kubernetes() (environment.Container, error) {
	return c.containerEnvironment(kubernetes.Name)
}

func (c colimaApp) Active() bool {
	return c.guest.Running(context.Background())
}

func (c *colimaApp) Update() error {
	ctx := context.Background()
	if !c.guest.Running(ctx) {
		return fmt.Errorf("runtime cannot be updated, %s is not running", config.CurrentProfile().DisplayName)
	}

	runtime, err := c.currentRuntime(ctx)
	if err != nil {
		return err
	}

	container, err := c.containerEnvironment(runtime)
	if err != nil {
		return err
	}

	oldVersion := container.Version(ctx)

	updated, err := container.Update(ctx)
	if err != nil {
		return err
	}

	if updated {
		fmt.Println()
		fmt.Println("Previous")
		fmt.Println(oldVersion)
		fmt.Println()
		fmt.Println("Current")
		fmt.Println(container.Version(ctx))
	}

	return nil
}

func generateSSHConfig(modifySSHConfig bool) error {
	instances, err := limautil.Instances()
	if err != nil {
		return fmt.Errorf("error retrieving instances: %w", err)
	}
	var buf bytes.Buffer

	for _, i := range instances {
		if !i.Running() {
			continue
		}

		profile := config.ProfileFromName(i.Name)
		resp, err := limautil.ShowSSH(profile.ID)
		if err != nil {
			log.Trace(fmt.Errorf("error retrieving SSH config for '%s': %w", i.Name, err))
			continue
		}

		fmt.Fprintln(&buf, resp.Output)
	}

	sshFileColima := config.SSHConfigFile()
	if err := os.WriteFile(sshFileColima, buf.Bytes(), 0644); err != nil {
		return fmt.Errorf("error writing ssh_config file: %w", err)
	}

	if !modifySSHConfig {
		// ~/.ssh/config modification disabled
		return nil
	}

	includeLine := "Include " + sshFileColima

	sshFileSystem := filepath.Join(util.HomeDir(), ".ssh", "config")

	// include the SSH config file if not included
	// if ssh file missing, the only content will be the include
	if _, err := os.Stat(sshFileSystem); err != nil {
		if err := os.MkdirAll(filepath.Dir(sshFileSystem), 0700); err != nil {
			return fmt.Errorf("error creating ssh directory: %w", err)
		}

		if err := os.WriteFile(sshFileSystem, []byte(includeLine), 0644); err != nil {
			return fmt.Errorf("error modifying %s: %w", sshFileSystem, err)
		}

		return nil
	}

	sshContent, err := os.ReadFile(sshFileSystem)
	if err != nil {
		return fmt.Errorf("error reading ssh config: %w", err)
	}

	scanner := bufio.NewScanner(bytes.NewReader(sshContent))
	for scanner.Scan() {
		words := strings.Fields(scanner.Text())

		// empty line
		if len(words) == 0 {
			continue
		}

		// comment
		if strings.HasPrefix(words[0], "#") {
			continue
		}

		// not an include line
		if len(words) < 2 {
			continue
		}

		if words[0] == "Include" {
			sshConfig := words[1]
			sshConfig = strings.Replace(sshConfig, "~/", "$HOME/", 1)
			sshConfig = os.ExpandEnv(sshConfig)
			if sshConfig == sshFileColima {
				// already present
				return nil
			}
		}
	}

	// not found, prepend file
	if err := os.WriteFile(sshFileSystem, []byte(includeLine+"\n\n"+string(sshContent)), 0644); err != nil {
		return fmt.Errorf("error modifying %s: %w", sshFileSystem, err)
	}
	return nil
}


================================================
FILE: cli/chain.go
================================================
package cli

import (
	"context"
	"fmt"
	"io"
	"time"

	log "github.com/sirupsen/logrus"
)

// CtxKeyQuiet is the context key to mute the chain.
var CtxKeyQuiet = struct{ key string }{key: "quiet"}

// errNonFatal is a non fatal error
type errNonFatal struct {
	err error
}

// Error implements error
func (e errNonFatal) Error() string { return e.err.Error() }

// ErrNonFatal creates a non-fatal error for a command chain.
// A warning would be printed instead of terminating the chain.
func ErrNonFatal(err error) error {
	return errNonFatal{err}
}

// New creates a new runner instance.
func New(name string) CommandChain {
	return &namedCommandChain{
		name: name,
	}
}

type cFunc struct {
	f func() error
	s string
}

// CommandChain is a chain of commands.
// commands are executed in order.
type CommandChain interface {
	// Init initiates a new runner using the current instance.
	Init(ctx context.Context) *ActiveCommandChain
	// Logger returns the instance logger.
	Logger(ctx context.Context) *log.Entry
}

var _ CommandChain = (*namedCommandChain)(nil)

type namedCommandChain struct {
	name string
	log  *log.Entry
}

func (n *namedCommandChain) Logger(ctx context.Context) *log.Entry {
	if quiet, _ := ctx.Value(CtxKeyQuiet).(bool); quiet {
		l := log.New()
		l.SetOutput(io.Discard)
		return l.WithContext(ctx)
	}
	if n.log == nil {
		n.log = log.WithField("context", n.name).WithContext(ctx)
	}
	return n.log
}

func (n *namedCommandChain) Init(ctx context.Context) *ActiveCommandChain {
	return &ActiveCommandChain{
		log: n.Logger(ctx),
	}
}

// ActiveCommandChain is an active command chain.
type ActiveCommandChain struct {
	funcs     []cFunc
	lastStage string
	log       *log.Entry

	executing bool
}

// Logger returns the logger for the command chain.
func (a *ActiveCommandChain) Logger() *log.Entry { return a.log }

// Add adds a new function to the runner.
func (a *ActiveCommandChain) Add(f func() error) {
	a.funcs = append(a.funcs, cFunc{f: f})
}

// Stage sets the current stage of the runner.
func (a *ActiveCommandChain) Stage(s string) {
	if a.executing {
		a.log.Println(s, "...")
		return
	}
	a.funcs = append(a.funcs, cFunc{s: s})
}

// Stagef is like stage with string format.
func (a *ActiveCommandChain) Stagef(format string, s ...any) {
	f := fmt.Sprintf(format, s...)
	a.Stage(f)
}

// Exec executes the command chain.
// The first errored function terminates the chain and the
// error is returned. Otherwise, returns nil.
func (a *ActiveCommandChain) Exec() error {
	a.executing = true
	defer func() { a.executing = false }()

	for _, f := range a.funcs {
		if f.f == nil {
			if f.s != "" {
				a.log.Println(f.s, "...")
				a.lastStage = f.s
			}
			continue
		}

		// success
		err := f.f()
		if err == nil {
			continue
		}

		// warning
		if _, ok := err.(errNonFatal); ok {
			if a.lastStage == "" {
				a.log.Warnln(err)
			} else {
				a.log.Warnln(fmt.Errorf("error at '%s': %w", a.lastStage, err))
			}
			continue
		}

		// error
		if a.lastStage == "" {
			return err
		}
		return fmt.Errorf("error at '%s': %w", a.lastStage, err)
	}
	return nil
}

// Retry retries `f` up to `count` times at interval.
// If after `count` attempts there is an error, the command chain is terminated with the final error.
// retryCount starts from 1.
func (a *ActiveCommandChain) Retry(stage string, interval time.Duration, count int, f func(retryCount int) error) {
	a.Add(func() (err error) {
		var i int
		for err = f(i + 1); i < count && err != nil; i, err = i+1, f(i+1) {
			if stage != "" {
				a.log.Println(stage, "...")
			}
			time.Sleep(interval)
		}
		return err
	})
}


================================================
FILE: cli/command.go
================================================
package cli

import (
	"fmt"
	"os"
	"os/exec"
	"strconv"

	log "github.com/sirupsen/logrus"
)

var runner commandRunner = &defaultCommandRunner{}

// Settings is global cli settings
var Settings = struct {
	// Verbose toggles verbose output for commands.
	Verbose bool
}{}

// Command creates a new command.
func Command(command string, args ...string) *exec.Cmd { return runner.Command(command, args...) }

// CommandInteractive creates a new interactive command.
func CommandInteractive(command string, args ...string) *exec.Cmd {
	return runner.CommandInteractive(command, args...)
}

type commandRunner interface {
	Command(command string, args ...string) *exec.Cmd
	CommandInteractive(command string, args ...string) *exec.Cmd
}

var _ commandRunner = (*defaultCommandRunner)(nil)

type defaultCommandRunner struct{}

func (d defaultCommandRunner) Command(command string, args ...string) *exec.Cmd {
	cmd := exec.Command(command, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	log.Trace("cmd ", quotedArgs(cmd.Args))

	return cmd
}

func (d defaultCommandRunner) CommandInteractive(command string, args ...string) *exec.Cmd {
	cmd := exec.Command(command, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	log.Trace("cmd int ", quotedArgs(cmd.Args))

	return cmd
}

func quotedArgs(args []string) string {
	var q []string
	for _, s := range args {
		q = append(q, strconv.Quote(s))
	}
	return fmt.Sprintf("%v", q)
}

// Prompt prompts for input with a question. It returns true only if answer is y or Y.
func Prompt(question string) bool {
	fmt.Print(question)
	fmt.Print("? [y/N] ")
	fmt.Print("\033[0m") // reset all formatting modes (if any) used by the question string

	var answer string
	_, _ = fmt.Scanln(&answer)

	if answer == "" {
		return false
	}

	return answer[0] == 'Y' || answer[0] == 'y'
}


================================================
FILE: cmd/clone.go
================================================
package cmd

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// stopCmd represents the stop command
var cloneCmd = &cobra.Command{
	Use:   "clone <profile> <new-profile>",
	Short: "clone Colima profile",
	Long:  `Clone the Colima profile.`,
	Args:  cobra.ExactArgs(2),
	RunE: func(cmd *cobra.Command, args []string) error {
		from := config.ProfileFromName(args[0])
		to := config.ProfileFromName(args[1])

		logrus.Infof("preparing to clone %s...", from.DisplayName)
		{
			// verify source profile exists
			if stat, err := os.Stat(from.LimaInstanceDir()); err != nil || !stat.IsDir() {
				return fmt.Errorf("colima profile '%s' does not exist", from.ShortName)
			}

			// verify destination profile does not exists
			if stat, err := os.Stat(to.LimaInstanceDir()); err == nil && stat.IsDir() {
				return fmt.Errorf("colima profile '%s' already exists, delete with `colima delete %s` and try again", to.ShortName, to.ShortName)
			}

			// copy source to destination
			logrus.Info("cloning virtual machine...")
			if err := cli.Command("mkdir", "-p", to.LimaInstanceDir()).Run(); err != nil {
				return fmt.Errorf("error preparing to copy VM: %w", err)
			}

			if err := cli.Command("cp",
				filepath.Join(from.LimaInstanceDir(), "basedisk"),
				filepath.Join(from.LimaInstanceDir(), "diffdisk"),
				filepath.Join(from.LimaInstanceDir(), "cidata.iso"),
				filepath.Join(from.LimaInstanceDir(), "lima.yaml"),
				to.LimaInstanceDir(),
			).Run(); err != nil {
				return fmt.Errorf("error copying VM: %w", err)
			}
		}

		{
			logrus.Info("copying config...")
			// verify source config exists
			if _, err := os.Stat(from.LimaInstanceDir()); err != nil {
				return fmt.Errorf("config missing for colima profile '%s': %w", from.ShortName, err)
			}

			// ensure destination config directory
			if err := cli.Command("mkdir", "-p", filepath.Dir(to.LimaInstanceDir())).Run(); err != nil {
				return fmt.Errorf("cannot copy config to new profile '%s': %w", to.ShortName, err)
			}

			if err := cli.Command("cp", from.LimaInstanceDir(), to.LimaInstanceDir()).Run(); err != nil {
				return fmt.Errorf("error copying VM config: %w", err)
			}
		}

		logrus.Info("clone successful")
		logrus.Infof("run `colima start %s` to start the newly cloned profile", to.ShortName)
		return nil
	},
}

func init() {
	root.Cmd().AddCommand(cloneCmd)
	cloneCmd.Hidden = true

}


================================================
FILE: cmd/colima/main.go
================================================
package main

import (
	_ "github.com/abiosoft/colima/cmd"        // for other commands
	_ "github.com/abiosoft/colima/cmd/daemon" // for vmnet daemon
	_ "github.com/abiosoft/colima/embedded"   // for embedded assets

	"github.com/abiosoft/colima/cmd/root"
)

func main() {
	root.Execute()
}


================================================
FILE: cmd/completion.go
================================================
package cmd

import (
	"os"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

// completionCmd represents the completion command
func completionCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "completion [bash|zsh|fish|powershell]",
		Short: "Generate completion script",
		Long: `To load completions:
Bash:

  $ source <(colima completion bash)

  # To load completions for each session, execute once:
  # Linux:
  $ colima completion bash > /etc/bash_completion.d/colima
  # macOS:
  $ colima completion bash > /usr/local/etc/bash_completion.d/colima

Zsh:

  # If shell completion is not already enabled in your environment,
  # you will need to enable it.  You can execute the following once:

  $ echo "autoload -U compinit; compinit" >> ~/.zshrc

  # To load completions for each session, execute once:
  $ colima completion zsh > "${fpath[1]}/_colima"

  # You will need to start a new shell for this setup to take effect.

fish:

  $ colima completion fish | source

  # To load completions for each session, execute once:
  $ colima completion fish > ~/.config/fish/completions/colima.fish

PowerShell:

  PS> colima completion powershell | Out-String | Invoke-Expression

  # To load completions for every new session, run:
  PS> colima completion powershell > colima.ps1
  # and source this file from your PowerShell profile.
`,
		DisableFlagsInUseLine: true,
		ValidArgs:             []string{"bash", "zsh", "fish", "powershell"},
		Args:                  cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
		Run: func(cmd *cobra.Command, args []string) {
			switch args[0] {
			case "bash":
				_ = cmd.Root().GenBashCompletion(os.Stdout)
			case "zsh":
				_ = cmd.Root().GenZshCompletion(os.Stdout)
			case "fish":
				_ = cmd.Root().GenFishCompletion(os.Stdout, true)
			case "powershell":
				_ = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
			}
		},
	}
	return cmd
}

func init() {
	root.Cmd().AddCommand(completionCmd())
}


================================================
FILE: cmd/daemon/cmd.go
================================================
package daemon

import (
	"context"
	"time"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/daemon/process/inotify"
	"github.com/abiosoft/colima/daemon/process/vmnet"
	"github.com/abiosoft/colima/environment/host"
	"github.com/abiosoft/colima/environment/vm/lima"
	"github.com/spf13/cobra"
)

var daemonCmd = &cobra.Command{
	Use:    "daemon",
	Short:  "daemon",
	Long:   `runner for background daemons.`,
	Hidden: true,
}

var startCmd = &cobra.Command{
	Use:   "start [profile]",
	Short: "start daemon",
	Long:  `start the daemon`,
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		config.SetProfile(args[0])
		ctx := cmd.Context()

		var processes []process.Process
		if daemonArgs.vmnet.enabled {
			processes = append(processes, vmnet.New(daemonArgs.vmnet.mode, daemonArgs.vmnet.netInterface))
		}
		if daemonArgs.inotify.enabled {
			processes = append(processes, inotify.New())
			guest := lima.New(host.New())
			args := inotify.Args{
				GuestActions: guest,
				Runtime:      daemonArgs.inotify.runtime,
				Dirs:         daemonArgs.inotify.dirs,
			}
			ctx = context.WithValue(ctx, inotify.CtxKeyArgs(), args)
		}

		return start(ctx, processes)
	},
}

var stopCmd = &cobra.Command{
	Use:   "stop [profile]",
	Short: "stop daemon",
	Long:  `stop the daemon`,
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		config.SetProfile(args[0])

		// wait for 60 seconds
		timeout := time.Second * 60
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		defer cancel()

		return stop(ctx)
	},
}

var statusCmd = &cobra.Command{
	Use:   "status",
	Short: "status of the daemon",
	Long:  `status of the daemon`,
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		config.SetProfile(args[0])

		return status()
	},
}

var daemonArgs struct {
	vmnet struct {
		enabled      bool
		mode         string
		netInterface string
	}
	inotify struct {
		enabled bool
		dirs    []string
		runtime string
	}

	verbose bool
}

func init() {
	root.Cmd().AddCommand(daemonCmd)

	daemonCmd.AddCommand(startCmd)
	daemonCmd.AddCommand(stopCmd)
	daemonCmd.AddCommand(statusCmd)

	startCmd.Flags().BoolVar(&daemonArgs.vmnet.enabled, "vmnet", false, "start vmnet")
	startCmd.Flags().StringVar(&daemonArgs.vmnet.mode, "vmnet-mode", "shared", "vmnet mode (shared, bridged)")
	startCmd.Flags().StringVar(&daemonArgs.vmnet.netInterface, "vmnet-interface", "en0", "vmnet interface for bridged mode")
	startCmd.Flags().BoolVar(&daemonArgs.inotify.enabled, "inotify", false, "start inotify")
	startCmd.Flags().StringSliceVar(&daemonArgs.inotify.dirs, "inotify-dir", nil, "set inotify directories")
	startCmd.Flags().StringVar(&daemonArgs.inotify.runtime, "inotify-runtime", "docker", "set runtime")
}


================================================
FILE: cmd/daemon/daemon.go
================================================
package daemon

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"sync"
	"syscall"
	"time"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/util/fsutil"
	godaemon "github.com/sevlyar/go-daemon"
	"github.com/sirupsen/logrus"
)

var dir = process.Dir

// daemonize creates the daemon and returns if this is a child process
func daemonize() (ctx *godaemon.Context, child bool, err error) {
	dir := dir()
	if err := fsutil.MkdirAll(dir, 0755); err != nil {
		return nil, false, fmt.Errorf("cannot make dir: %w", err)
	}

	info := Info()

	ctx = &godaemon.Context{
		PidFileName: info.PidFile,
		PidFilePerm: 0644,
		LogFileName: info.LogFile,
		LogFilePerm: 0644,
	}

	d, err := ctx.Reborn()
	if err != nil {
		return ctx, false, fmt.Errorf("error starting daemon: %w", err)
	}
	if d != nil {
		return ctx, false, nil
	}

	logrus.Info("- - - - - - - - - - - - - - -")
	logrus.Info("daemon started by colima")
	logrus.Infof("Run `/usr/bin/pkill -F %s` to kill the daemon", info.PidFile)

	return ctx, true, nil
}

func start(ctx context.Context, processes []process.Process) error {
	if status() == nil {
		logrus.Info("daemon already running, startup ignored")
		return nil
	}

	{
		ctx, child, err := daemonize()
		if err != nil {
			return err
		}

		if ctx != nil {
			defer func() {
				_ = ctx.Release()
			}()
		}

		if !child {
			return nil
		}
	}

	ctx, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	return RunProcesses(ctx, processes...)
}

func stop(ctx context.Context) error {
	if status() != nil {
		// not running
		return nil
	}

	info := Info()

	if err := cli.CommandInteractive("/usr/bin/pkill", "-F", info.PidFile).Run(); err != nil {
		return fmt.Errorf("error sending sigterm to daemon: %w", err)
	}

	logrus.Info("waiting for process to terminate")

	for {
		alive := status() == nil
		if !alive {
			return nil
		}
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
			time.Sleep(time.Second * 1)
		}
	}

}

func status() error {
	info := Info()
	if _, err := os.Stat(info.PidFile); err != nil {
		return fmt.Errorf("pid file not found: %w", err)
	}

	// check if process is actually running
	p, err := os.ReadFile(info.PidFile)
	if err != nil {
		return fmt.Errorf("error reading pid file: %w", err)
	}
	pid, _ := strconv.Atoi(string(p))
	if pid == 0 {
		return fmt.Errorf("invalid pid: %v", string(p))
	}

	process, err := os.FindProcess(pid)
	if err != nil {
		return fmt.Errorf("process not found: %v", err)
	}

	if err := process.Signal(syscall.Signal(0)); err != nil {
		return fmt.Errorf("process signal(0) returned error: %w", err)
	}

	return nil
}

const (
	pidFileName = "daemon.pid"
	logFileName = "daemon.log"
)

func Info() struct {
	PidFile string
	LogFile string
} {
	dir := dir()
	return struct {
		PidFile string
		LogFile string
	}{
		PidFile: filepath.Join(dir, pidFileName),
		LogFile: filepath.Join(dir, logFileName),
	}
}

// Run runs the daemon with background processes.
// NOTE: this must be called from the program entrypoint with minimal intermediary logic
// due to the creation of the daemon.
func RunProcesses(ctx context.Context, processes ...process.Process) error {
	ctx, stop := context.WithCancel(ctx)
	defer stop()

	var wg sync.WaitGroup
	wg.Add(len(processes))

	for _, bg := range processes {
		go func(bg process.Process) {
			err := bg.Start(ctx)
			if err != nil {
				logrus.Error(fmt.Errorf("error starting %s: %w", bg.Name(), err))
				stop()
			}
			wg.Done()
		}(bg)
	}

	<-ctx.Done()
	logrus.Info("terminate signal received")

	wg.Wait()

	return ctx.Err()
}


================================================
FILE: cmd/daemon/daemon_test.go
================================================
package daemon

import (
	"context"
	"os"
	"os/exec"
	"testing"
	"time"

	"github.com/abiosoft/colima/daemon/process"
)

var testDir string

func setDir(t *testing.T) {
	if testDir == "" {
		testDir = t.TempDir()
	}
	dir = func() string { return testDir }
}

func getProcesses() []process.Process {
	var addresses = []string{
		"localhost",
		"127.0.0.1",
	}

	var processes []process.Process
	for _, add := range addresses {
		processes = append(processes, &pinger{address: add})
	}

	return processes
}

func TestStart(t *testing.T) {
	setDir(t)
	info := Info()

	processes := getProcesses()

	t.Log("pidfile", info.PidFile)

	timeout := time.Second * 5
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	// start the processes
	if err := start(ctx, processes); err != nil {
		t.Fatal(err)
	}
	t.Log("start successful")

	{
	loop:
		for {
			select {
			case <-ctx.Done():
				t.Skipf("daemon not supported: %v", ctx.Err())
			default:
				if p, err := os.ReadFile(info.PidFile); err == nil && len(p) > 0 {
					break loop
				} else if err != nil {
					t.Logf("encountered err: %v", err)
				}
				time.Sleep(1 * time.Second)
			}
		}
	}

	// verify the processes are running
	if err := status(); err != nil {
		t.Error(err)
		return
	}

	// stop the processes
	if err := stop(ctx); err != nil {
		t.Error(err)
	}

	// verify the processes are no longer running
	if err := status(); err == nil {
		t.Errorf("process with pidFile %s is still running", info.PidFile)
		return
	}

}

func TestRunProcesses(t *testing.T) {
	processes := getProcesses()

	timeout := time.Second * 5
	ctx, cancel := context.WithTimeout(context.Background(), timeout)

	// start the processes
	done := make(chan error, 1)
	go func() {
		done <- RunProcesses(ctx, processes...)
	}()

	cancel()

	select {
	case <-ctx.Done():
		if err := ctx.Err(); err != context.Canceled {
			t.Error(err)
		}
	case err := <-done:
		t.Error(err)
	}

}

var _ process.Process = (*pinger)(nil)

type pinger struct {
	address string
}

func (p pinger) Alive(ctx context.Context) error {
	return nil
}

// Name implements BgProcess
func (pinger) Name() string { return "pinger" }

// Start implements BgProcess
func (p *pinger) Start(ctx context.Context) error {
	return p.run(ctx, "ping", "-c10", p.address)
}

// Start implements BgProcess
func (p *pinger) Dependencies() ([]process.Dependency, bool) { return nil, false }

func (p *pinger) run(ctx context.Context, command string, args ...string) error {
	cmd := exec.CommandContext(ctx, command, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}


================================================
FILE: cmd/delete.go
================================================
package cmd

import (
	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

var deleteCmdArgs struct {
	force bool
	data  bool
}

// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
	Use:   "delete [profile]",
	Short: "delete and teardown Colima",
	Long: `Delete and teardown Colima and all settings.

Use with caution. This deletes everything and a startup afterwards is like the
initial startup of Colima.`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		return newApp().Delete(deleteCmdArgs.data, deleteCmdArgs.force)
	},
}

func init() {
	root.Cmd().AddCommand(deleteCmd)

	deleteCmd.Flags().BoolVarP(&deleteCmdArgs.force, "force", "f", false, "do not prompt for yes/no")
	deleteCmd.Flags().BoolVarP(&deleteCmdArgs.data, "data", "d", false, "delete container runtime data")
}


================================================
FILE: cmd/kubernetes.go
================================================
package cmd

import (
	"context"
	"fmt"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/environment/container/kubernetes"

	"github.com/spf13/cobra"
)

// kubernetesCmd represents the kubernetes command
var kubernetesCmd = &cobra.Command{
	Use:     "kubernetes",
	Aliases: []string{"kube", "k8s", "k3s", "k"},
	Short:   "manage Kubernetes cluster",
	Long:    `Manage the Kubernetes cluster`,
	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
		// cobra overrides PersistentPreRunE when redeclared.
		// re-run rootCmd's.
		if err := root.Cmd().PersistentPreRunE(cmd, args); err != nil {
			return err
		}
		if !newApp().Active() {
			return fmt.Errorf("%s is not running", config.CurrentProfile().DisplayName)
		}
		return nil
	},
}

// kubernetesStartCmd represents the kubernetes start command
var kubernetesStartCmd = &cobra.Command{
	Use:   "start",
	Short: "start the Kubernetes cluster",
	Long:  `Start the Kubernetes cluster.`,
	Args:  cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		app := newApp()
		k, err := app.Kubernetes()
		if err != nil {
			return err
		}

		if err := k.Provision(context.Background()); err != nil {
			return err
		}

		return k.Start(context.Background())
	},
}

// kubernetesStopCmd represents the kubernetes stop command
var kubernetesStopCmd = &cobra.Command{
	Use:   "stop",
	Short: "stop the Kubernetes cluster",
	Long:  `Stop the Kubernetes cluster.`,
	Args:  cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := cmd.Context()
		app := newApp()
		k, err := app.Kubernetes()
		if err != nil {
			return err
		}
		if !k.Running(ctx) {
			return fmt.Errorf("%s is not enabled", kubernetes.Name)
		}

		return k.Stop(ctx, false)
	},
}

// kubernetesDeleteCmd represents the kubernetes delete command
var kubernetesDeleteCmd = &cobra.Command{
	Use:   "delete",
	Short: "delete the Kubernetes cluster",
	Long:  `Delete the Kubernetes cluster.`,
	Args:  cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := cmd.Context()
		app := newApp()
		k, err := app.Kubernetes()
		if err != nil {
			return err
		}
		if !k.Running(ctx) {
			return fmt.Errorf("%s is not enabled", kubernetes.Name)
		}

		return k.Teardown(ctx)
	},
}

// kubernetesResetCmd represents the kubernetes reset command
var kubernetesResetCmd = &cobra.Command{
	Use:   "reset",
	Short: "reset the Kubernetes cluster",
	Long: `Reset the Kubernetes cluster.

This resets the Kubernetes cluster and all Kubernetes objects
will be deleted.

The Kubernetes images are cached making the startup (after reset) much faster.`,
	Args: cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		app := newApp()
		k, err := app.Kubernetes()
		if err != nil {
			return err
		}

		if err := k.Teardown(context.Background()); err != nil {
			return fmt.Errorf("error deleting %s: %w", kubernetes.Name, err)
		}

		ctx := context.Background()
		if err := k.Provision(ctx); err != nil {
			return err
		}

		if err := k.Start(ctx); err != nil {
			return fmt.Errorf("error starting %s: %w", kubernetes.Name, err)
		}

		return nil
	},
}

func init() {
	root.Cmd().AddCommand(kubernetesCmd)
	kubernetesCmd.AddCommand(kubernetesStartCmd)
	kubernetesCmd.AddCommand(kubernetesStopCmd)
	kubernetesCmd.AddCommand(kubernetesDeleteCmd)
	kubernetesCmd.AddCommand(kubernetesResetCmd)
}


================================================
FILE: cmd/list.go
================================================
package cmd

import (
	"encoding/json"
	"fmt"
	"text/tabwriter"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/docker/go-units"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var listCmdArgs struct {
	json bool
}

// listCmd represents the version command
var listCmd = &cobra.Command{
	Use:     "list",
	Aliases: []string{"ls"},
	Short:   "list instances",
	Long: `List all created instances.

A new instance can be created during 'colima start' by specifying the '--profile' flag.`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		profile := config.CurrentProfile()
		profileArgs := []string{}

		if profile.Changed {
			profileArgs = append(profileArgs, profile.ID)
		}

		instances, err := limautil.Instances(profileArgs...)
		if err != nil {
			return err
		}

		if listCmdArgs.json {
			encoder := json.NewEncoder(cmd.OutOrStdout())
			// print instance per line to conform with Lima's output
			for _, instance := range instances {
				// dir should be hidden from the output
				instance.Dir = ""
				if err := encoder.Encode(instance); err != nil {
					return err
				}
			}
			return nil
		}

		w := tabwriter.NewWriter(cmd.OutOrStdout(), 4, 8, 4, ' ', 0)
		_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESS")

		if len(instances) == 0 {
			logrus.Warn("No instance found. Run `colima start` to create an instance.")
		}

		for _, inst := range instances {
			_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\n",
				inst.Name,
				inst.Status,
				inst.Arch,
				inst.CPU,
				units.BytesSize(float64(inst.Memory)),
				units.BytesSize(float64(inst.Disk)),
				inst.Runtime,
				inst.IPAddress,
			)
		}

		return w.Flush()
	},
}

func init() {
	root.Cmd().AddCommand(listCmd)

	listCmd.Flags().BoolVarP(&listCmdArgs.json, "json", "j", false, "print json output")
}


================================================
FILE: cmd/model.go
================================================
package cmd

import (
	"fmt"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config/configmanager"
	"github.com/abiosoft/colima/model"
	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/terminal"
	"github.com/spf13/cobra"
)

// modelCmdArgs holds command-line flags for the model command.
var modelCmdArgs struct {
	Runner    string
	ServePort int
}

// modelCmd represents the model command
var modelCmd = &cobra.Command{
	Use:   "model",
	Short: "manage AI models (requires docker runtime and krunkit VM type)",
	Long: `Manage AI models inside the VM.
This requires docker runtime and krunkit VM type for GPU access.

Use --runner to select the model runner:
  - docker: Docker Model Runner (default)
  - ramalama: Ramalama

All arguments are passed to the selected AI model runner.
Specifying '--' will pass arguments to the underlying tool.

Examples:
  colima model list
  colima model pull ai/smollm2
  colima model run ai/smollm2
  colima model serve
  colima model serve ai/smollm2 --port 8080

Multiple registries are supported.
`,
	PreRunE: func(cmd *cobra.Command, args []string) error {
		runner, err := getModelRunner()
		if err != nil {
			return err
		}
		return runner.ValidatePrerequisites(newApp())
	},
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) == 0 {
			return cmd.Help()
		}

		runner, err := getModelRunner()
		if err != nil {
			return err
		}

		a := newApp()

		if err := runner.EnsureProvisioned(); err != nil {
			return err
		}

		runnerArgs, err := runner.BuildArgs(args)
		if err != nil {
			return err
		}
		return a.SSH(runnerArgs...)
	},
}

// modelSetupCmd reinstalls the model runner in the VM.
var modelSetupCmd = &cobra.Command{
	Use:     "setup",
	Short:   "install or update AI model runner in the VM",
	Long:    `Install or update AI model runner and its dependencies in the VM.`,
	Aliases: []string{"update"},
	PreRunE: func(cmd *cobra.Command, args []string) error {
		runner, err := getModelRunner()
		if err != nil {
			return err
		}
		return runner.ValidatePrerequisites(newApp())
	},
	RunE: func(cmd *cobra.Command, args []string) error {
		runner, err := getModelRunner()
		if err != nil {
			return err
		}

		// Check if setup is needed (on primary screen)
		status, err := runner.CheckSetup()
		if err != nil {
			return err
		}

		// Print version info on primary screen
		fmt.Println(runner.DisplayName())
		if status.CurrentVersion != "" {
			fmt.Printf("current: %s\n", status.CurrentVersion)
		}
		if status.LatestVersion != "" {
			fmt.Printf("latest:  %s\n", status.LatestVersion)
		}

		if !status.NeedsSetup {
			fmt.Println()
			fmt.Println("Already up to date")
			return nil
		}

		// Build header for alternate screen
		separator := "────────────────────────────────────────"
		header := fmt.Sprintf("Colima - %s Setup\n%s", runner.DisplayName(), separator)

		// Run setup in alternate screen
		if err := terminal.WithAltScreen(func() error {
			return runner.Setup()
		}, header); err != nil {
			return err
		}

		// Print new version on primary screen after update
		if newVersion := runner.GetCurrentVersion(); newVersion != "" {
			fmt.Printf("updated: %s\n", newVersion)
		}

		return nil
	},
}

// modelServeCmd serves a model API.
var modelServeCmd = &cobra.Command{
	Use:   "serve [model]",
	Short: "serve a model API",
	Long: `Serve a model API.

This starts a model server providing:
  - OpenAI-compatible API at http://localhost:<port>/v1
  - Web UI for chat at http://localhost:<port>

Press Ctrl-C to stop the server.
`,
	Args: cobra.MaximumNArgs(1),
	PreRunE: func(cmd *cobra.Command, args []string) error {
		runner, err := getModelRunner()
		if err != nil {
			return err
		}
		return runner.ValidatePrerequisites(newApp())
	},
	RunE: func(cmd *cobra.Command, args []string) error {
		runner, err := getModelRunner()
		if err != nil {
			return err
		}

		// Determine the model to serve
		var modelName string
		if len(args) > 0 {
			modelName = args[0]
		} else if runner.Name() == model.RunnerDocker {
			// For docker runner, get the first available model
			firstModel, err := model.GetFirstModel()
			if err != nil {
				return err
			}
			if firstModel == "" {
				return fmt.Errorf("no models available\nPull a model first: colima model pull ai/smollm2")
			}
			modelName = firstModel
		} else {
			return fmt.Errorf("model name is required for ramalama runner\nUsage: colima model serve <model>")
		}

		if err := runner.EnsureProvisioned(); err != nil {
			return err
		}

		// Ensure the model is available (pull if necessary) - this happens outside alternate screen
		normalizedModel, err := runner.EnsureModel(modelName)
		if err != nil {
			return err
		}

		// Determine the port to use
		port := modelCmdArgs.ServePort
		portExplicitlySet := cmd.Flags().Changed("port")

		// If port was not explicitly set, find an available port starting from the default
		const maxPortAttempts = 20
		if !portExplicitlySet {
			availablePort, found := util.FindAvailablePort(port, maxPortAttempts)
			if !found {
				return fmt.Errorf("no available port found in range %d-%d", port, port+maxPortAttempts-1)
			}
			if availablePort != port {
				fmt.Printf("Port %d is in use, using port %d instead\n", port, availablePort)
			}
			port = availablePort
		} else {
			// User explicitly set the port, check if it's available
			if _, found := util.FindAvailablePort(port, 1); !found {
				return fmt.Errorf("port %d is already in use", port)
			}
		}

		// Build header for alternate screen
		separator := "────────────────────────────────────────"
		header := fmt.Sprintf("Colima - Model Server (Ctrl-C to stop)\nWeb UI & API at http://localhost:%d\n%s", port, separator)

		// Run in alternate screen with header
		return terminal.WithAltScreen(func() error {
			return runner.Serve(normalizedModel, port)
		}, header)
	},
}

func init() {
	root.Cmd().AddCommand(modelCmd)
	modelCmd.AddCommand(modelSetupCmd)
	modelCmd.AddCommand(modelServeCmd)

	// Add --runner flag with default from config or ramalama
	modelCmd.PersistentFlags().StringVar(&modelCmdArgs.Runner, "runner", "", "AI model runner (docker, ramalama)")

	// Add --port flag for serve command
	modelServeCmd.Flags().IntVar(&modelCmdArgs.ServePort, "port", 8080, "port for the web UI")
}

// getModelRunner returns the appropriate runner based on flag or config.
func getModelRunner() (model.Runner, error) {
	runnerType := modelCmdArgs.Runner

	// If not specified via flag, check instance config
	if runnerType == "" {
		if conf, err := configmanager.LoadInstance(); err == nil && conf.ModelRunner != "" {
			runnerType = conf.ModelRunner
		}
	}

	// Default to docker
	if runnerType == "" {
		runnerType = string(model.RunnerDocker)
	}

	return model.GetRunner(model.RunnerType(runnerType))
}


================================================
FILE: cmd/nerdctl.go
================================================
package cmd

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/environment/container/containerd"
	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/fsutil"
	"github.com/abiosoft/colima/util/osutil"
	"github.com/spf13/cobra"
)

var nerdctlCmdArgs struct {
	force           bool
	path            string
	usrBinWriteable bool
	isColimaScript  bool
}

// nerdctlCmd represents the nerdctl command
var nerdctlCmd = &cobra.Command{
	Use:     "nerdctl",
	Aliases: []string{"nerd", "n"},
	Short:   "run nerdctl (requires containerd runtime)",
	Long: `Run nerdctl to interact with containerd.
This requires containerd runtime.

It is recommended to specify '--' to differentiate from Colima flags.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		app := newApp()
		r, err := app.Runtime()
		if err != nil {
			return err
		}
		if r != containerd.Name {
			return fmt.Errorf("nerdctl only supports %s runtime", containerd.Name)
		}

		// collect CONTAINERD_* and NERDCTL_* environment variables from the host
		var envVars []string
		for _, env := range os.Environ() {
			if strings.HasPrefix(env, "CONTAINERD_") || strings.HasPrefix(env, "NERDCTL_") {
				envVars = append(envVars, env)
			}
		}

		var nerdctlArgs []string
		if len(envVars) > 0 {
			// use 'sudo env VAR=value ... nerdctl' to pass environment variables
			nerdctlArgs = append([]string{"sudo", "env"}, envVars...)
			nerdctlArgs = append(nerdctlArgs, "nerdctl")
		} else {
			nerdctlArgs = []string{"sudo", "nerdctl"}
		}
		nerdctlArgs = append(nerdctlArgs, args...)

		return app.SSH(nerdctlArgs...)
	},
}

// nerdctlLinkFunc represents the nerdctl command
var nerdctlLinkFunc = func() *cobra.Command {
	return &cobra.Command{
		Use:   "install",
		Short: "install nerdctl alias script on the host",
		Long:  `Install nerdctl alias script on the host. The script will be installed at ` + nerdctlDefaultInstallPath + `.`,
		Args:  cobra.NoArgs,
		PreRun: func(cmd *cobra.Command, args []string) {
			// check if /usr/local/bin is writeable and no need for sudo

			// if the path is user-specified, ignore.
			if nerdctlCmdArgs.path != nerdctlDefaultInstallPath {
				return
			}

			// attempt writing to the /usr/local/bin
			tmpFile := filepath.Join(filepath.Dir(nerdctlDefaultInstallPath), "colima.tmp")
			if err := os.WriteFile(tmpFile, []byte("tmp"), 0777); err == nil {
				nerdctlCmdArgs.usrBinWriteable = true
				_ = os.Remove(tmpFile)
			}

			// check if the current file (if exists) is generated by colima
			// in such case no need for confirmation before overwrite
			// TODO: this is too basic, should be better
			if b, err := os.ReadFile(nerdctlCmdArgs.path); err == nil {
				if strings.Contains(string(b), "colima nerdctl ") {
					nerdctlCmdArgs.isColimaScript = true
				}
			}
		},

		RunE: func(cmd *cobra.Command, args []string) error {
			exists := false
			if _, err := os.Stat(nerdctlCmdArgs.path); err == nil && !nerdctlCmdArgs.force && !nerdctlCmdArgs.isColimaScript {
				return fmt.Errorf("%s exists, use --force to replace", nerdctlCmdArgs.path)
			} else if err == nil {
				exists = true
			}

			var values = struct {
				ColimaApp string
				Profile   string
			}{
				ColimaApp: osutil.Executable(),
				Profile:   config.CurrentProfile().ShortName,
			}
			buf, err := util.ParseTemplate(nerdctlScript, values)
			if err != nil {
				return fmt.Errorf("error applying nerdctl script template: %w", err)
			}

			// /usr/local/bin writeable i.e. sudo not needed
			// or user-specified install path, we assume user specified path is writeable
			if nerdctlCmdArgs.usrBinWriteable || nerdctlCmdArgs.path != nerdctlDefaultInstallPath {
				if exists {
					if err := os.Rename(nerdctlCmdArgs.path, nerdctlCmdArgs.path+".moved"); err != nil {
						return fmt.Errorf("error backing up existing file: %w", err)
					}
				}
				if err := fsutil.MkdirAll("/usr/local/bin", 0755); err != nil {
					return nil
				}
				return os.WriteFile(nerdctlCmdArgs.path, buf, 0755)
			}

			// sudo is needed for the default path
			log.Println("/usr/local/bin not writable, sudo password required to install nerdctl binary")
			if exists && !nerdctlCmdArgs.isColimaScript {
				c := cli.CommandInteractive("sudo", "mv", nerdctlCmdArgs.path, nerdctlCmdArgs.path+".moved")
				if err := c.Run(); err != nil {
					return fmt.Errorf("error backing up existing file: %w", err)
				}
			}
			// prepare dir
			{
				c := cli.CommandInteractive("sudo", "mkdir", "-p", "/usr/local/bin")
				if err := c.Run(); err != nil {
					return err
				}
			}
			// install script
			{
				c := cli.CommandInteractive("sudo", "sh", "-c", "cat > "+nerdctlCmdArgs.path)
				c.Stdin = bytes.NewReader(buf)
				if err := c.Run(); err != nil {
					return err
				}
			}
			// ensure it is executable
			if err := cli.Command("sudo", "chmod", "+x", nerdctlCmdArgs.path).Run(); err != nil {
				return err
			}

			return nil
		},
	}
}

const nerdctlDefaultInstallPath = "/usr/local/bin/nerdctl"

const nerdctlScript = `#!/usr/bin/env sh

{{.ColimaApp}} nerdctl --profile {{.Profile}} -- "$@"
`

func init() {
	root.Cmd().AddCommand(nerdctlCmd)

	nerdctlLink := nerdctlLinkFunc()
	nerdctlCmd.AddCommand(nerdctlLink)
	nerdctlLink.Flags().BoolVarP(&nerdctlCmdArgs.force, "force", "f", false, "replace "+nerdctlDefaultInstallPath+" (if exists)")
	nerdctlLink.Flags().StringVar(&nerdctlCmdArgs.path, "path", nerdctlDefaultInstallPath, "path to install nerdctl binary")
}


================================================
FILE: cmd/prune.go
================================================
package cmd

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var pruneCmdArgs struct {
	force bool
	all   bool
}

// pruneCmd represents the prune command
var pruneCmd = &cobra.Command{
	Use:   "prune",
	Short: "prune cached downloaded assets",
	Long:  `Prune cached downloaded assets`,
	Args:  cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		colimaCacheDir := config.CacheDir()
		limaCacheDir := filepath.Join(filepath.Dir(colimaCacheDir), "lima")
		if !pruneCmdArgs.force {
			msg := "'" + colimaCacheDir + "' will be emptied, are you sure"
			if pruneCmdArgs.all {
				msg = "'" + colimaCacheDir + "' and '" + limaCacheDir + "' will be emptied, are you sure"
			}
			if y := cli.Prompt(msg); !y {
				return nil
			}
		}
		logrus.Info("Pruning ", strconv.Quote(config.CacheDir()))
		if err := os.RemoveAll(config.CacheDir()); err != nil {
			return fmt.Errorf("error during prune: %w", err)
		}

		if pruneCmdArgs.all {
			cmd := limautil.Limactl("prune")
			if err := cmd.Run(); err != nil {
				return fmt.Errorf("error during Lima prune: %w", err)
			}
		}

		return nil
	},
}

func init() {
	root.Cmd().AddCommand(pruneCmd)

	pruneCmd.Flags().BoolVarP(&pruneCmdArgs.force, "force", "f", false, "do not prompt for yes/no")
	pruneCmd.Flags().BoolVarP(&pruneCmdArgs.all, "all", "a", false, "include Lima assets")
}


================================================
FILE: cmd/restart.go
================================================
package cmd

import (
	"time"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config/configmanager"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/spf13/cobra"
)

var restartCmdArgs struct {
	force bool
}

// restartCmd represents the restart command
var restartCmd = &cobra.Command{
	Use:   "restart [profile]",
	Short: "restart Colima",
	Long: `Stop and then starts Colima.

The state of the VM is persisted at stop. A start afterwards
should return it back to its previous state.`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		// validate if the instance was previously created
		if _, err := limautil.Instance(); err != nil {
			return err
		}

		app := newApp()

		if err := app.Stop(restartCmdArgs.force); err != nil {
			return err
		}

		// delay a bit before starting
		time.Sleep(time.Second * 3)

		config, err := configmanager.Load()
		if err != nil {
			return err
		}

		return app.Start(config)
	},
}

func init() {
	root.Cmd().AddCommand(restartCmd)

	restartCmd.Flags().BoolVarP(&restartCmdArgs.force, "force", "f", false, "during restart, do stop without graceful shutdown")
}


================================================
FILE: cmd/root/root.go
================================================
package root

import (
	"log"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/config"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var versionInfo = config.AppVersion()

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:     "colima",
	Short:   "container runtimes on macOS with minimal setup",
	Long:    `Colima provides container runtimes on macOS with minimal setup.`,
	Version: versionInfo.Version,
	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
		// use profile from environment variable if set
		profile := config.EnvProfile()

		switch cmd.Name() {

		// special case handling for commands directly interacting with the VM
		// start, stop, restart, delete, status, version, update, ssh-config
		case "start",
			"stop",
			"restart",
			"delete",
			"status",
			"list",
			"version",
			"update",
			"ssh-config":

			// if an arg is passed, assume it to be the profile (provided --profile is unset)
			// i.e. colima start docker == colima start --profile=docker
			// takes precedence over the environment variable
			if len(args) > 0 && !cmd.Flag("profile").Changed {
				profile = args[0]
			}
		}

		// if profile is set via flag, use it
		// takes precedence over the environment variable and arg
		if cmd.Flag("profile").Changed {
			profile = rootCmdArgs.Profile
		}

		if profile != "" {
			config.SetProfile(profile)
		}

		initLog()

		cmd.SilenceUsage = true
		cmd.SilenceErrors = true
		return nil
	},
}

// Cmd returns the root command.
func Cmd() *cobra.Command {
	return rootCmd
}

// rootCmdArgs holds all flags configured in root Cmd
var rootCmdArgs struct {
	Profile     string
	Verbose     bool
	VeryVerbose bool
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		logrus.Fatal(err)
	}
}

func init() {
	rootCmd.PersistentFlags().BoolVarP(&rootCmdArgs.Verbose, "verbose", "v", rootCmdArgs.Verbose, "enable verbose log")
	rootCmd.PersistentFlags().BoolVar(&rootCmdArgs.VeryVerbose, "very-verbose", rootCmdArgs.VeryVerbose, "enable more verbose log")
	rootCmd.PersistentFlags().StringVarP(&rootCmdArgs.Profile, "profile", "p", "default", "profile name, for multiple instances")
}

func initLog() {
	if rootCmdArgs.Verbose {
		cli.Settings.Verbose = true
		logrus.SetLevel(logrus.DebugLevel)
	}
	if rootCmdArgs.VeryVerbose {
		cli.Settings.Verbose = true
		logrus.SetLevel(logrus.TraceLevel)
	}

	// general log output
	log.SetOutput(logrus.StandardLogger().Writer())
	log.SetFlags(0)
}


================================================
FILE: cmd/ssh-config.go
================================================
package cmd

import (
	"fmt"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/spf13/cobra"
)

// statusCmd represents the status command
var sshConfigCmd = &cobra.Command{
	Use:   "ssh-config [profile]",
	Short: "show SSH connection config",
	Long:  `Show configuration of the SSH connection to the VM.`,
	Args:  cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		resp, err := limautil.ShowSSH(config.CurrentProfile().ID)
		if err == nil {
			fmt.Println(resp.Output)
		}
		return err
	},
}

func init() {
	root.Cmd().AddCommand(sshConfigCmd)
}


================================================
FILE: cmd/ssh.go
================================================
package cmd

import (
	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

// sshCmd represents the ssh command
var sshCmd = &cobra.Command{
	Use:     "ssh",
	Aliases: []string{"exec", "x"},
	Short:   "SSH into the VM",
	Long: `SSH into the VM.

Appending additional command runs the command instead.
e.g. 'colima ssh -- htop' will run htop.

It is recommended to specify '--' to differentiate from colima flags.`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return newApp().SSH(args...)
	},
}

func init() {
	root.Cmd().AddCommand(sshCmd)
}


================================================
FILE: cmd/start.go
================================================
package cmd

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"github.com/abiosoft/colima/app"
	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/config/configmanager"
	"github.com/abiosoft/colima/core"
	"github.com/abiosoft/colima/embedded"
	"github.com/abiosoft/colima/environment"
	"github.com/abiosoft/colima/environment/container/docker"
	"github.com/abiosoft/colima/environment/container/incus"
	"github.com/abiosoft/colima/environment/container/kubernetes"
	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/downloader"
	"github.com/abiosoft/colima/util/osutil"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// startCmd represents the start command
var startCmd = &cobra.Command{
	Use:   "start [profile]",
	Short: "start Colima",
	Long: `Start Colima with the specified container runtime and optional kubernetes.

Colima can also be configured with a YAML file.
Run 'colima template' to set the default configurations or 'colima start --edit' to customize before startup.
`,
	Example: "  colima start\n" +
		"  colima start --edit\n" +
		"  colima start --foreground\n" +
		"  colima start --runtime containerd\n" +
		"  colima start --kubernetes\n" +
		"  colima start --runtime containerd --kubernetes\n" +
		"  colima start --cpu 4 --memory 8 --disk 100\n" +
		"  colima start --arch aarch64\n" +
		"  colima start --dns 1.1.1.1 --dns 8.8.8.8\n" +
		"  colima start --dns-host example.com=1.2.3.4\n" +
		"  colima start --gateway-address 192.168.6.2\n" +
		"  colima start --kubernetes --k3s-arg='\"--disable=coredns,servicelb,traefik,local-storage,metrics-server\"'",
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		app := newApp()
		conf := startCmdArgs.Config

		if !startCmdArgs.Flags.Edit {
			if app.Active() {
				log.Warnln("already running, ignoring")
				return nil
			}
			return start(app, conf)
		}

		// edit flag is specified
		conf, err := editConfigFile()
		if err != nil {
			return err
		}

		// validate config
		if err := configmanager.ValidateConfig(conf); err != nil {
			return fmt.Errorf("error in config file: %w", err)
		}

		if app.Active() {
			if !cli.Prompt("colima is currently running, restart to apply changes") {
				return nil
			}
			if err := app.Stop(false); err != nil {
				return fmt.Errorf("error stopping :%w", err)
			}
			// pause before startup to prevent race condition
			time.Sleep(time.Second * 3)
		}

		return start(app, conf)
	},
	PreRunE: func(cmd *cobra.Command, args []string) error {
		// validate Lima version
		if err := core.LimaVersionSupported(); err != nil {
			return fmt.Errorf("lima compatibility error: %w", err)
		}

		// combine args and current config file(if any)
		prepareConfig(cmd)

		// validate config
		if err := configmanager.ValidateConfig(startCmdArgs.Config); err != nil {
			return fmt.Errorf("error in config: %w", err)
		}

		// persist in preparation for application start
		if startCmdArgs.Flags.SaveConfig {
			if err := configmanager.Save(startCmdArgs.Config); err != nil {
				return fmt.Errorf("error preparing config file: %w", err)
			}
		}

		// validate and set downloader if flag is specified (takes precedence over env var)
		if cmd.Flag("downloader").Changed {
			normalized, err := downloader.ValidateDownloader(startCmdArgs.Flags.Downloader)
			if err != nil {
				return err
			}
			downloader.SetDownloader(normalized)
		}

		return nil
	},
}

const (
	defaultCPU               = 2
	defaultMemory            = 2
	defaultDisk              = 100
	defaultRootDisk          = 20
	defaultKubernetesVersion = kubernetes.DefaultVersion

	defaultMountTypeQEMU = "sshfs"
	defaultMountTypeVZ   = "virtiofs"
)

var (
	defaultVMType  = "qemu"
	defaultK3sArgs = []string{"--disable=traefik"}
	envSaveConfig  = osutil.EnvVar("COLIMA_SAVE_CONFIG")
)

var startCmdArgs struct {
	config.Config

	Flags struct {
		Mounts                  []string
		LegacyKubernetes        bool // for backward compatibility
		LegacyKubernetesDisable []string
		Edit                    bool
		Editor                  string
		ActivateRuntime         bool
		Binfmt                  bool
		DNSHosts                []string
		Foreground              bool
		SaveConfig              bool
		LegacyCPU               int // for backward compatibility
		Template                bool
		Downloader              string // downloader to use (native, curl)
	}
}

func init() {
	runtimes := strings.Join(environment.ContainerRuntimes(), ", ")
	defaultArch := string(environment.HostArch())
	defaultVMType = environment.DefaultVMType()

	defaultMountType := defaultMountTypeQEMU
	if defaultVMType == "vz" {
		defaultMountType = defaultMountTypeVZ
	}

	mounts := strings.Join([]string{defaultMountTypeQEMU, "9p", "virtiofs"}, ", ")

	vmTypes := []string{"qemu", "vz"}
	if util.MacOS13OrNewerOnArm() {
		vmTypes = append(vmTypes, "krunkit")
	}
	types := strings.Join(vmTypes, ", ")

	saveConfigDefault := true
	if envSaveConfig.Exists() {
		saveConfigDefault = envSaveConfig.Bool()
	}

	root.Cmd().AddCommand(startCmd)
	startCmd.Flags().StringVarP(&startCmdArgs.Runtime, "runtime", "r", docker.Name, "container runtime ("+runtimes+")")
	startCmd.Flags().BoolVar(&startCmdArgs.Flags.ActivateRuntime, "activate", true, "set as active Docker/Kubernetes/Incus context on startup")
	startCmd.Flags().IntVarP(&startCmdArgs.CPU, "cpus", "c", defaultCPU, "number of CPUs")
	startCmd.Flags().StringVar(&startCmdArgs.CPUType, "cpu-type", "", "the CPU type, options can be checked with 'qemu-system-"+defaultArch+" -cpu help'")
	startCmd.Flags().Float32VarP(&startCmdArgs.Memory, "memory", "m", defaultMemory, "memory in GiB")
	startCmd.Flags().IntVarP(&startCmdArgs.Disk, "disk", "d", defaultDisk, "disk size in GiB")
	startCmd.Flags().IntVar(&startCmdArgs.RootDisk, "root-disk", defaultRootDisk, "disk size in GiB for the root filesystem")
	startCmd.Flags().StringVarP(&startCmdArgs.Arch, "arch", "a", defaultArch, "architecture (aarch64, x86_64)")
	startCmd.Flags().BoolVarP(&startCmdArgs.Flags.Foreground, "foreground", "f", false, "Keep colima in the foreground")
	startCmd.Flags().StringVar(&startCmdArgs.Hostname, "hostname", "", "custom hostname for the virtual machine")
	startCmd.Flags().StringVarP(&startCmdArgs.DiskImage, "disk-image", "i", "", "file path to a custom disk image")
	startCmd.Flags().BoolVar(&startCmdArgs.Flags.Template, "template", true, "use the template file for initial configuration")

	// port forwarder
	startCmd.Flags().StringVar(&startCmdArgs.PortForwarder, "port-forwarder", "ssh", "port forwarder to use (ssh, grpc, none)")

	// retain cpu flag for backward compatibility
	startCmd.Flags().IntVar(&startCmdArgs.Flags.LegacyCPU, "cpu", defaultCPU, "number of CPUs")
	startCmd.Flag("cpu").Hidden = true

	// host IP addresses
	startCmd.Flags().BoolVar(&startCmdArgs.Network.HostAddresses, "network-host-addresses", false, "support port forwarding to specific host IP addresses")

	binfmtDesc := "use binfmt for foreign architecture emulation"

	if util.MacOS() {
		// network address
		startCmd.Flags().BoolVar(&startCmdArgs.Network.Address, "network-address", false, "assign reachable IP address to the VM")
		startCmd.Flags().StringVar(&startCmdArgs.Network.Mode, "network-mode", "shared", "network mode (shared, bridged)")
		startCmd.Flags().StringVar(&startCmdArgs.Network.BridgeInterface, "network-interface", "en0", "host network interface to use for bridged mode")
		startCmd.Flags().BoolVar(&startCmdArgs.Network.PreferredRoute, "network-preferred-route", false, "use the assigned IP address as the preferred route for the VM (implies --network-address)")

		// vm type
		if util.MacOS13OrNewer() {
			startCmd.Flags().StringVarP(&startCmdArgs.VMType, "vm-type", "t", defaultVMType, "virtual machine type ("+types+")")
			if util.MacOS13OrNewerOnArm() {
				startCmd.Flags().BoolVar(&startCmdArgs.VZRosetta, "vz-rosetta", false, "enable Rosetta for amd64 emulation")
				startCmd.Flags().StringVar(&startCmdArgs.ModelRunner, "model-runner", "docker", "AI model runner (docker, ramalama)")
				binfmtDesc += " (no-op if Rosetta is enabled)"
			}
		}

		// nested virtualization
		if util.MacOSNestedVirtualizationSupported() {
			startCmd.Flags().BoolVarP(&startCmdArgs.NestedVirtualization, "nested-virtualization", "z", false, "enable nested virtualization")
		}
	}

	// Gateway Address
	startCmd.Flags().IPVar(&startCmdArgs.Network.GatewayAddress, "gateway-address", net.ParseIP("192.168.5.2"), "gateway address")

	// binfmt
	startCmd.Flags().BoolVar(&startCmdArgs.Flags.Binfmt, "binfmt", true, binfmtDesc)

	// config
	startCmd.Flags().BoolVarP(&startCmdArgs.Flags.Edit, "edit", "e", false, "edit the configuration file before starting")
	startCmd.Flags().StringVar(&startCmdArgs.Flags.Editor, "editor", "", `editor to use for edit e.g. vim, nano, code (default "$EDITOR" env var)`)
	startCmd.Flags().BoolVar(&startCmdArgs.Flags.SaveConfig, "save-config", saveConfigDefault, "persist and overwrite config file with (newly) specified flags")

	// mounts
	startCmd.Flags().StringSliceVarP(&startCmdArgs.Flags.Mounts, "mount", "V", nil, "directories to mount, suffix ':w' for writable, disable with 'none'")
	startCmd.Flags().StringVar(&startCmdArgs.MountType, "mount-type", defaultMountType, "volume driver for the mount ("+mounts+")")
	startCmd.Flags().BoolVar(&startCmdArgs.MountINotify, "mount-inotify", true, "propagate inotify file events to the VM")

	// ssh
	startCmd.Flags().BoolVarP(&startCmdArgs.ForwardAgent, "ssh-agent", "s", false, "forward SSH agent to the VM")
	startCmd.Flags().BoolVar(&startCmdArgs.SSHConfig, "ssh-config", true, "generate SSH config in ~/.ssh/config")
	startCmd.Flags().IntVar(&startCmdArgs.SSHPort, "ssh-port", 0, "SSH server port")

	// k8s
	startCmd.Flags().BoolVarP(&startCmdArgs.Kubernetes.Enabled, "kubernetes", "k", false, "start with Kubernetes")
	startCmd.Flags().BoolVar(&startCmdArgs.Flags.LegacyKubernetes, "with-kubernetes", false, "start with Kubernetes")
	startCmd.Flags().StringVar(&startCmdArgs.Kubernetes.Version, "kubernetes-version", defaultKubernetesVersion, "must match a k3s version https://github.com/k3s-io/k3s/releases")
	startCmd.Flags().StringSliceVar(&startCmdArgs.Flags.LegacyKubernetesDisable, "kubernetes-disable", nil, "components to disable for k3s e.g. traefik,servicelb")
	startCmd.Flags().StringSliceVar(&startCmdArgs.Kubernetes.K3sArgs, "k3s-arg", defaultK3sArgs, "additional args to pass to k3s")
	startCmd.Flags().IntVar(&startCmdArgs.Kubernetes.Port, "k3s-listen-port", 0, "k3s server listen port")
	startCmd.Flag("with-kubernetes").Hidden = true
	startCmd.Flag("kubernetes-disable").Hidden = true

	// env
	startCmd.Flags().StringToStringVar(&startCmdArgs.Env, "env", nil, "environment variables for the VM")

	// dns
	startCmd.Flags().IPSliceVarP(&startCmdArgs.Network.DNSResolvers, "dns", "n", nil, "DNS resolvers for the VM")
	startCmd.Flags().StringSliceVar(&startCmdArgs.Flags.DNSHosts, "dns-host", nil, "custom DNS names to provide to resolver")

	// download options
	startCmd.Flags().StringVar(&startCmdArgs.Flags.Downloader, "downloader", downloader.DownloaderNative, "downloader to use (native, curl)")
}

func dnsHostsFromFlag(hosts []string) map[string]string {
	mapping := make(map[string]string)

	for _, h := range hosts {
		str := strings.SplitN(h, "=", 2)
		if len(str) != 2 {
			log.Warnf("unable to parse custom dns host: %v, skipping\n", h)
			continue
		}
		src := str[0]
		target := str[1]

		mapping[src] = target
	}
	return mapping
}

// mountsFromFlag converts mounts from cli flag format to config file format
func mountsFromFlag(mounts []string) []config.Mount {
	mnts := make([]config.Mount, len(mounts))
	for i, mount := range mounts {

		// if one of the parameters is none, treat as none.
		if strings.ToLower(mount) == "none" {
			return nil
		}

		str := strings.SplitN(mount, ":", 3)
		mnt := config.Mount{Location: str[0]}

		if len(str) > 1 {
			if filepath.IsAbs(str[1]) {
				mnt.MountPoint = str[1]
			} else if str[1] == "w" {
				mnt.Writable = true
			}
		}
		if len(str) > 2 && str[2] == "w" {
			mnt.Writable = true
		}

		mnts[i] = mnt
	}
	return mnts
}

func setFlagDefaults(cmd *cobra.Command) {
	if startCmdArgs.VMType == "" {
		startCmdArgs.VMType = defaultVMType
	}

	if util.MacOS13OrNewer() {
		// changing to vz implies changing mount type to virtiofs
		if cmd.Flag("vm-type").Changed && startCmdArgs.VMType == "vz" && !cmd.Flag("mount-type").Changed {
			startCmdArgs.MountType = "virtiofs"
			cmd.Flag("mount-type").Changed = true
		}
	}

	// mount type
	{
		// convert mount type for qemu
		if startCmdArgs.VMType != "vz" && startCmdArgs.VMType != "krunkit" && startCmdArgs.MountType == defaultMountTypeVZ {
			startCmdArgs.MountType = defaultMountTypeQEMU
			if cmd.Flag("mount-type").Changed {
				log.Warnf("%s is only available for 'vz' vmType, using %s", defaultMountTypeVZ, defaultMountTypeQEMU)
			}
		}
		// convert mount type for vz
		if startCmdArgs.VMType == "vz" && startCmdArgs.MountType == "9p" {
			startCmdArgs.MountType = "virtiofs"
			if cmd.Flag("mount-type").Changed {
				log.Warnf("9p is only available for 'qemu' vmType, using %s", defaultMountTypeVZ)
			}
		}
	}

	// always enable nested virtualization for incus, if supported and not explicitly disabled.
	if util.MacOSNestedVirtualizationSupported() {
		if !cmd.Flag("nested-virtualization").Changed {
			if startCmdArgs.Runtime == incus.Name && (startCmdArgs.VMType == "vz" || startCmdArgs.VMType == "krunkit") {
				startCmdArgs.NestedVirtualization = true
			}
		}
	}

	// always enable network address for incus, if supported and not explicitly disabled
	if util.MacOS13OrNewer() {
		if !cmd.Flag("network-address").Changed {
			if startCmdArgs.Runtime == incus.Name && startCmdArgs.VMType == "vz" {
				startCmdArgs.Network.Address = true
			}
		}
	}
}

func setConfigDefaults(conf *config.Config) {
	// handle macOS virtualization.framework transition
	if conf.VMType == "" {
		conf.VMType = defaultVMType
		// if on macOS with no qemu, use vz
		if err := util.AssertQemuImg(); err != nil && util.MacOS13OrNewer() {
			conf.VMType = "vz"
		}
	}

	if conf.MountType == "" {
		conf.MountType = defaultMountTypeQEMU
		if util.MacOS13OrNewer() && conf.VMType == "vz" {
			conf.MountType = defaultMountTypeVZ
		}
	}

	if conf.Hostname == "" {
		conf.Hostname = config.CurrentProfile().ID
	}

	if conf.PortForwarder == "" {
		conf.PortForwarder = "ssh"
	}
}

func setFixedConfigs(conf *config.Config) {
	fixedConf, err := configmanager.LoadFrom(config.CurrentProfile().StateFile())
	if err != nil {
		return
	}

	warnIfNotEqual := func(name, newVal, fixedVal string) {
		if newVal != fixedVal {
			log.Warnln(fmt.Errorf("'%s' cannot be updated after initial setup, discarded", name))
		}
	}

	// override the fixed configs
	// arch, vmType, mountType, runtime are fixed and cannot be changed
	if fixedConf.Arch != "" {
		warnIfNotEqual("architecture", conf.Arch, fixedConf.Arch)
		conf.Arch = fixedConf.Arch
	}
	if fixedConf.VMType != "" {
		warnIfNotEqual("virtual machine type", conf.VMType, fixedConf.VMType)
		conf.VMType = fixedConf.VMType
	}
	if fixedConf.Runtime != "" {
		warnIfNotEqual("runtime", conf.Runtime, fixedConf.Runtime)
		conf.Runtime = fixedConf.Runtime
	}
	if fixedConf.MountType != "" {
		warnIfNotEqual("volume mount type", conf.MountType, fixedConf.MountType)
		conf.MountType = fixedConf.MountType
	}
	if fixedConf.Network.Address && !conf.Network.Address {
		log.Warnln("network address cannot be disabled once enabled")
		conf.Network.Address = true
	}
	if fixedConf.Network.Mode != "" {
		warnIfNotEqual("network mode", conf.Network.Mode, fixedConf.Network.Mode)
		conf.Network.Mode = fixedConf.Network.Mode
	}
}

func prepareConfig(cmd *cobra.Command) {
	current, err := configmanager.Load()
	if err != nil {
		// not fatal, will proceed with defaults
		log.Warnln(fmt.Errorf("config load failed: %w", err))
		log.Warnln("reverting to default settings")
	}

	// handle legacy kubernetes flag
	if cmd.Flag("with-kubernetes").Changed {
		startCmdArgs.Kubernetes.Enabled = startCmdArgs.Flags.LegacyKubernetes
		cmd.Flag("kubernetes").Changed = true
	}

	// handle legacy cpu flag
	if cmd.Flag("cpu").Changed && !cmd.Flag("cpus").Changed {
		startCmdArgs.CPU = startCmdArgs.Flags.LegacyCPU
		cmd.Flag("cpus").Changed = true
	}

	// convert cli to config file format
	startCmdArgs.Mounts = mountsFromFlag(startCmdArgs.Flags.Mounts)
	startCmdArgs.Network.DNSHosts = dnsHostsFromFlag(startCmdArgs.Flags.DNSHosts)
	startCmdArgs.ActivateRuntime = &startCmdArgs.Flags.ActivateRuntime
	startCmdArgs.Binfmt = &startCmdArgs.Flags.Binfmt

	// handle legacy kubernetes-disable
	for _, disable := range startCmdArgs.Flags.LegacyKubernetesDisable {
		startCmdArgs.Kubernetes.K3sArgs = append(startCmdArgs.Kubernetes.K3sArgs, "--disable="+disable)
	}

	// set relevant missing default values
	setFlagDefaults(cmd)

	// if there is no existing settings
	if current.Empty() {
		templateUsed := false

		// attempt template if enabled
		if startCmdArgs.Flags.Template {
			template, err := configmanager.LoadFrom(templateFile())
			if err == nil {
				current = template
				templateUsed = true
			}
		}

		if !templateUsed {
			// use default config if there is no template or template is disabled
			return
		}
	}

	// set missing defaults in the current config
	setConfigDefaults(&current)

	// docker can only be set in config file
	startCmdArgs.Docker = current.Docker
	// provision scripts can only be set in config file
	startCmdArgs.Provision = current.Provision

	// use current settings for unchanged configs
	// otherwise may be reverted to their default values.
	if !cmd.Flag("arch").Changed {
		startCmdArgs.Arch = current.Arch
	}
	if !cmd.Flag("disk").Changed {
		startCmdArgs.Disk = current.Disk
	}
	if !cmd.Flag("root-disk").Changed {
		if current.RootDisk > 0 {
			startCmdArgs.RootDisk = current.RootDisk
		}
	}
	if !cmd.Flag("kubernetes").Changed {
		startCmdArgs.Kubernetes.Enabled = current.Kubernetes.Enabled
	}
	if !cmd.Flag("kubernetes-version").Changed && current.Kubernetes.Version != "" {
		startCmdArgs.Kubernetes.Version = current.Kubernetes.Version
	}
	if !cmd.Flag("k3s-arg").Changed && current.Kubernetes.K3sArgs != nil {
		startCmdArgs.Kubernetes.K3sArgs = current.Kubernetes.K3sArgs
	}
	if !cmd.Flag("k3s-listen-port").Changed && current.Kubernetes.Port > 0 {
		startCmdArgs.Kubernetes.Port = current.Kubernetes.Port
	}
	if !cmd.Flag("runtime").Changed {
		startCmdArgs.Runtime = current.Runtime
	}
	if util.MacOS13OrNewerOnArm() {
		if !cmd.Flag("model-runner").Changed {
			startCmdArgs.ModelRunner = current.ModelRunner
		}
	}
	if !cmd.Flag("cpus").Changed {
		startCmdArgs.CPU = current.CPU
	}
	if !cmd.Flag("cpu-type").Changed {
		startCmdArgs.CPUType = current.CPUType
	}
	if !cmd.Flag("memory").Changed {
		startCmdArgs.Memory = current.Memory
	}
	if !cmd.Flag("mount").Changed {
		startCmdArgs.Mounts = current.Mounts
	}
	if !cmd.Flag("mount-type").Changed {
		startCmdArgs.MountType = current.MountType
	}
	if !cmd.Flag("mount-inotify").Changed {
		startCmdArgs.MountINotify = current.MountINotify
	}
	if !cmd.Flag("ssh-agent").Changed {
		startCmdArgs.ForwardAgent = current.ForwardAgent
	}
	if !cmd.Flag("ssh-config").Changed {
		startCmdArgs.SSHConfig = current.SSHConfig
	}
	if !cmd.Flag("ssh-port").Changed {
		startCmdArgs.SSHPort = current.SSHPort
	}
	if !cmd.Flag("port-forwarder").Changed {
		startCmdArgs.PortForwarder = current.PortForwarder
	}
	if !cmd.Flag("dns").Changed {
		startCmdArgs.Network.DNSResolvers = current.Network.DNSResolvers
	}
	if !cmd.Flag("dns-host").Changed {
		startCmdArgs.Network.DNSHosts = current.Network.DNSHosts
	}
	if !cmd.Flag("gateway-address").Changed {
		startCmdArgs.Network.GatewayAddress = current.Network.GatewayAddress
	}
	if !cmd.Flag("env").Changed {
		startCmdArgs.Env = current.Env
	}
	if !cmd.Flag("hostname").Changed {
		startCmdArgs.Hostname = current.Hostname
	}
	if !cmd.Flag("activate").Changed {
		if current.ActivateRuntime != nil { // backward compatibility for `activate`
			startCmdArgs.ActivateRuntime = current.ActivateRuntime
		}
	}
	if !cmd.Flag("binfmt").Changed {
		if current.Binfmt != nil {
			startCmdArgs.Binfmt = current.Binfmt
		}
	}
	if !cmd.Flag("network-host-addresses").Changed {
		startCmdArgs.Network.HostAddresses = current.Network.HostAddresses
	}
	if util.MacOS() {
		if !cmd.Flag("network-address").Changed {
			startCmdArgs.Network.Address = current.Network.Address
		}
		if !cmd.Flag("network-mode").Changed {
			startCmdArgs.Network.Mode = current.Network.Mode
		}
		if !cmd.Flag("network-interface").Changed {
			startCmdArgs.Network.BridgeInterface = current.Network.BridgeInterface
		}
		if !cmd.Flag("network-preferred-route").Changed {
			startCmdArgs.Network.PreferredRoute = current.Network.PreferredRoute
		}
		if util.MacOS13OrNewer() {
			if !cmd.Flag("vm-type").Changed {
				startCmdArgs.VMType = current.VMType
			}
		}
		if util.MacOS13OrNewerOnArm() {
			if !cmd.Flag("vz-rosetta").Changed {
				startCmdArgs.VZRosetta = current.VZRosetta
			}
		}
		if util.MacOSNestedVirtualizationSupported() {
			if !cmd.Flag("nested-virtualization").Changed {
				startCmdArgs.NestedVirtualization = current.NestedVirtualization
			}
		}
	}

	setFixedConfigs(&startCmdArgs.Config)
}

// editConfigFile launches an editor to edit the config file.
func editConfigFile() (config.Config, error) {
	var c config.Config

	// preserve the current file in case the user terminates
	currentFile, err := os.ReadFile(config.CurrentProfile().File())
	if err != nil {
		return c, fmt.Errorf("error reading config file: %w", err)
	}

	// prepend the config file with termination instruction
	abort, err := embedded.ReadString("defaults/abort.yaml")
	if err != nil {
		log.Warnln(fmt.Errorf("unable to read embedded file: %w", err))
	}

	tmpFile, err := waitForUserEdit(startCmdArgs.Flags.Editor, []byte(abort+"\n"+string(currentFile)))
	if err != nil {
		return c, fmt.Errorf("error editing config file: %w", err)
	}

	// if file is empty, abort
	if tmpFile == "" {
		return c, fmt.Errorf("empty file, startup aborted")
	}

	defer func() {
		_ = os.Remove(tmpFile)
	}()
	if startCmdArgs.Flags.SaveConfig {
		if err := configmanager.SaveFromFile(tmpFile); err != nil {
			return c, err
		}
	}
	return configmanager.LoadFrom(tmpFile)
}

func start(app app.App, conf config.Config) error {
	if err := app.Start(conf); err != nil {
		return err
	}
	if startCmdArgs.Flags.Foreground {
		return awaitForInterruption(app)
	}
	return nil
}

func awaitForInterruption(app app.App) error {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	log.Println("keeping Colima in the foreground, press ctrl+c to exit...")

	sig := <-c
	log.Infof("interrupted by: %v", sig)

	if err := app.Stop(false); err != nil {
		log.Errorf("error stopping: %v", err)
		return err
	}

	return nil
}


================================================
FILE: cmd/start_test.go
================================================
package cmd

import (
	"reflect"
	"strconv"
	"testing"

	"github.com/abiosoft/colima/config"
)

func Test_mountsFromFlag(t *testing.T) {
	tests := []struct {
		mounts []string
		want   []config.Mount
	}{
		{
			mounts: []string{
				"~:w",
			},
			want: []config.Mount{
				{Location: "~", Writable: true},
			},
		},
		{
			mounts: []string{
				"~",
			},
			want: []config.Mount{
				{Location: "~"},
			},
		},
		{
			mounts: []string{
				"/home/users", "/home/another:w", "/tmp",
			},
			want: []config.Mount{
				{Location: "/home/users"},
				{Location: "/home/another", Writable: true},
				{Location: "/tmp"},
			},
		},
		{
			mounts: []string{
				"/home/users:/home/users", "/home/another:w", "/tmp:/users/tmp", "/tmp:/users/tmp:w",
			},
			want: []config.Mount{
				{Location: "/home/users", MountPoint: "/home/users"},
				{Location: "/home/another", Writable: true},
				{Location: "/tmp", MountPoint: "/users/tmp"},
				{Location: "/tmp", MountPoint: "/users/tmp", Writable: true},
			},
		},
		{
			mounts: []string{
				"none",
			},
			want: nil,
		},
	}
	for i, tt := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			if got := mountsFromFlag(tt.mounts); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("mountsFromFlag() = %+v, want %+v", got, tt.want)
			}
		})
	}
}


================================================
FILE: cmd/status.go
================================================
package cmd

import (
	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

var statusCmdArgs struct {
	extended bool
	json     bool
}

// statusCmd represents the status command
var statusCmd = &cobra.Command{
	Use:   "status [profile]",
	Short: "show the status of Colima",
	Long:  `Show the status of Colima`,
	Args:  cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		return newApp().Status(statusCmdArgs.extended, statusCmdArgs.json)
	},
}

func init() {
	root.Cmd().AddCommand(statusCmd)

	statusCmd.Flags().BoolVarP(&statusCmdArgs.extended, "extended", "e", false, "include additional details")
	statusCmd.Flags().BoolVarP(&statusCmdArgs.json, "json", "j", false, "print json output")
}


================================================
FILE: cmd/stop.go
================================================
package cmd

import (
	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

var stopCmdArgs struct {
	force bool
}

// stopCmd represents the stop command
var stopCmd = &cobra.Command{
	Use:   "stop [profile]",
	Short: "stop Colima",
	Long: `Stop Colima to free up resources.

The state of the VM is persisted at stop. A start afterwards
should return it back to its previous state.`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		return newApp().Stop(stopCmdArgs.force)
	},
}

func init() {
	root.Cmd().AddCommand(stopCmd)

	stopCmd.Flags().BoolVarP(&stopCmdArgs.force, "force", "f", false, "stop without graceful shutdown")
}


================================================
FILE: cmd/template.go
================================================
package cmd

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/config/configmanager"
	"github.com/abiosoft/colima/embedded"
	"github.com/spf13/cobra"
)

// templateCmd represents the template command
var templateCmd = &cobra.Command{
	Use:     "template",
	Aliases: []string{"tmpl", "tpl", "t"},
	Short:   "edit the template for default configurations",
	Long: `Edit the template for default configurations of new instances.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if templateCmdArgs.Print {
			fmt.Println(templateFile())
			return nil
		}
		// there are unwarranted []byte to string overheads.
		// not a big deal in this case

		abort, err := embedded.ReadString("defaults/abort.yaml")
		if err != nil {
			return fmt.Errorf("error reading embedded file: %w", err)
		}
		info, err := embedded.ReadString("defaults/template.yaml")
		if err != nil {
			return fmt.Errorf("error reading embedded file: %w", err)
		}
		template, err := templateFileOrDefault()
		if err != nil {
			return fmt.Errorf("error reading template file: %w", err)
		}

		tmpFile, err := waitForUserEdit(templateCmdArgs.Editor, []byte(abort+"\n"+info+"\n"+template))
		if err != nil {
			return fmt.Errorf("error editing template file: %w", err)
		}
		if tmpFile == "" {
			return fmt.Errorf("empty file, template edit aborted")
		}
		defer func() {
			_ = os.Remove(tmpFile)
		}()

		// load and resave template to ensure the format is correct
		cf, err := configmanager.LoadFrom(tmpFile)
		if err != nil {
			return fmt.Errorf("error in template: %w", err)
		}
		if err := configmanager.SaveToFile(cf, templateFile()); err != nil {
			return fmt.Errorf("error saving template: %w", err)
		}

		log.Println("configurations template saved")

		return nil
	},
}

func templateFile() string { return filepath.Join(config.TemplatesDir(), "default.yaml") }

func templateFileOrDefault() (string, error) {
	tFile := templateFile()
	if _, err := os.Stat(tFile); err == nil {
		b, err := os.ReadFile(tFile)
		if err == nil {
			return string(b), nil
		}
	}

	return embedded.ReadString("defaults/colima.yaml")
}

var templateCmdArgs struct {
	Editor string
	Print  bool
}

func init() {
	root.Cmd().AddCommand(templateCmd)

	templateCmd.Flags().StringVar(&templateCmdArgs.Editor, "editor", "", `editor to use for edit e.g. vim, nano, code (default "$EDITOR" env var)`)
	templateCmd.Flags().BoolVar(&templateCmdArgs.Print, "print", false, `print out the configuration file path, without editing`)
}


================================================
FILE: cmd/update.go
================================================
package cmd

import (
	"github.com/abiosoft/colima/cmd/root"
	"github.com/spf13/cobra"
)

// statusCmd represents the status command
var updateCmd = &cobra.Command{
	Use:     "update [profile]",
	Aliases: []string{"u", "up"},
	Short:   "update the container runtime",
	Long:    `Update the current container runtime.`,
	Args:    cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		return newApp().Update()
	},
}

func init() {
	root.Cmd().AddCommand(updateCmd)
}


================================================
FILE: cmd/util.go
================================================
package cmd

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"github.com/abiosoft/colima/app"
	"github.com/abiosoft/colima/cli"
	"github.com/sirupsen/logrus"
)

func newApp() app.App {
	colimaApp, err := app.New()
	if err != nil {
		logrus.Fatal("Error: ", err)
	}
	return colimaApp
}

// waitForUserEdit launches a temporary file with content using editor,
// and waits for the user to close the editor.
// It returns the filename (if saved), empty file name (if aborted), and an error (if any).
func waitForUserEdit(editor string, content []byte) (string, error) {
	tmp, err := os.CreateTemp("", "colima-*.yaml")
	if err != nil {
		return "", fmt.Errorf("error creating temporary file: %w", err)
	}
	if _, err := tmp.Write(content); err != nil {
		return "", fmt.Errorf("error writing temporary file: %w", err)
	}
	if err := tmp.Close(); err != nil {
		return "", fmt.Errorf("error closing temporary file: %w", err)
	}

	if err := launchEditor(editor, tmp.Name()); err != nil {
		return "", err
	}

	// aborted
	if f, err := os.ReadFile(tmp.Name()); err == nil && len(bytes.TrimSpace(f)) == 0 {
		return "", nil
	}

	return tmp.Name(), nil
}

var editors = []string{
	"vim",
	"code --wait --new-window",
	"nano",
}

func launchEditor(editor string, file string) error {
	if editor != "" {
		log.Println("editing in", editor)
	}
	// if not specified, prefer vscode if this a vscode terminal
	if editor == "" {
		if os.Getenv("TERM_PROGRAM") == "vscode" {
			log.Println("vscode detected, editing in vscode")
			editor = "code --wait"
		}
	}

	// if not found, check the EDITOR env var
	if editor == "" {
		if e := os.Getenv("EDITOR"); e != "" {
			log.Println("editing in", e, "from", "$EDITOR environment variable")
			editor = e
		}
	}

	// if not found, check the preferred editors
	if editor == "" {
		for _, e := range editors {
			s := strings.Fields(e)
			if _, err := exec.LookPath(s[0]); err == nil {
				editor = e
				log.Println("editing in", e)
				break
			}
		}
	}

	// if still not found, abort
	if editor == "" {
		return fmt.Errorf("no editor found in $PATH, kindly set $EDITOR environment variable and try again")
	}

	// some editors need the wait flag, let us add it if the user has not.
	switch editor {
	case "code", "code-insiders", "code-oss", "codium", "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code":
		editor = strconv.Quote(editor) + " --wait --new-window"
	case "mate", "/Applications/TextMate 2.app/Contents/MacOS/mate", "/Applications/TextMate 2.app/Contents/MacOS/TextMate":
		editor = strconv.Quote(editor) + " --wait"
	}

	return cli.CommandInteractive("sh", "-c", editor+" "+file).Run()
}


================================================
FILE: cmd/version.go
================================================
package cmd

import (
	"fmt"

	"github.com/abiosoft/colima/app"
	"github.com/abiosoft/colima/cmd/root"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/model"
	"github.com/abiosoft/colima/store"
	"github.com/spf13/cobra"
)

// versionCmd represents the version command
var versionCmd = &cobra.Command{
	Use:   "version [profile]",
	Short: "print the version of Colima",
	Long:  `Print the version of Colima`,
	Args:  cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		version := config.AppVersion()
		fmt.Println(config.AppName, "version", version.Version)
		fmt.Println("git commit:", version.Revision)

		if colimaApp, err := app.New(); err == nil {
			_ = colimaApp.Version()

			// Show AI model runner version if provisioned
			s, _ := store.Load()
			if s.RamalamaProvisioned {
				if modelVersion := model.GetRamalamaVersion(); modelVersion != "" {
					fmt.Println()
					fmt.Println("AI model runner")
					fmt.Println("version:", modelVersion)
				}
			}
		}
	},
}

func init() {
	root.Cmd().AddCommand(versionCmd)
}


================================================
FILE: colima.nix
================================================
{ pkgs ? import <nixpkgs> }:

with pkgs;

buildGo123Module {
  name = "colima";
  pname = "colima";
  src = ./.;
  nativeBuildInputs = [ installShellFiles makeWrapper git ];
  vendorHash = "sha256-ZwgzKCOEhgKK2LNRLjnWP6qHI4f6OGORvt3CREJf55I=";
  CGO_ENABLED = 1;

  subPackages = [ "cmd/colima" ];

  # `nix-build` has .git folder but `nix build` does not, this caters for both cases
  preConfigure = ''
    export VERSION="$(git describe --tags --always || echo nix-build-at-"$(date +%s)")"
    export REVISION="$(git rev-parse HEAD || echo nix-unknown)"
    ldflags="-X github.com/abiosoft/colima/config.appVersion=$VERSION
              -X github.com/abiosoft/colima/config.revision=$REVISION"
  '';

  postInstall = ''
    wrapProgram $out/bin/colima \
      --prefix PATH : ${lib.makeBinPath [ qemu lima ]}
    installShellCompletion --cmd colima \
      --bash <($out/bin/colima completion bash) \
      --fish <($out/bin/colima completion fish) \
      --zsh <($out/bin/colima completion zsh)
  '';
}



================================================
FILE: config/config.go
================================================
package config

import (
	"fmt"
	"net"

	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/osutil"
)

const (
	AppName    = "colima"
	envProfile = "COLIMA_PROFILE" // environment variable for profile name
)

// VersionInfo is the application version info.
type VersionInfo struct {
	Version  string
	Revision string
}

func AppVersion() VersionInfo { return VersionInfo{Version: appVersion, Revision: revision} }
func EnvProfile() string      { return osutil.EnvVar(envProfile).Val() }

var (
	appVersion = "development"
	revision   = "unknown"
)

// Config is the application config.
type Config struct {
	CPU      int               `yaml:"cpu,omitempty"`
	Disk     int               `yaml:"disk,omitempty"`
	RootDisk int               `yaml:"rootDisk,omitempty"`
	Memory   float32           `yaml:"memory,omitempty"`
	Arch     string            `yaml:"arch,omitempty"`
	CPUType  string            `yaml:"cpuType,omitempty"`
	Network  Network           `yaml:"network,omitempty"`
	Env      map[string]string `yaml:"env,omitempty"` // environment variables
	Hostname string            `yaml:"hostname"`

	// SSH
	SSHPort      int  `yaml:"sshPort,omitempty"`
	ForwardAgent bool `yaml:"forwardAgent,omitempty"`
	SSHConfig    bool `yaml:"sshConfig,omitempty"` // config generation

	// VM
	VMType               string `yaml:"vmType,omitempty"`
	VZRosetta            bool   `yaml:"rosetta,omitempty"`
	Binfmt               *bool  `yaml:"binfmt,omitempty"`
	NestedVirtualization bool   `yaml:"nestedVirtualization,omitempty"`
	DiskImage            string `yaml:"diskImage,omitempty"`
	PortForwarder        string `yaml:"portForwarder,omitempty"` // "ssh", "grpc"

	// volume mounts
	Mounts       []Mount `yaml:"mounts,omitempty"`
	MountType    string  `yaml:"mountType,omitempty"`
	MountINotify bool    `yaml:"mountInotify,omitempty"`

	// Runtime is one of docker, containerd.
	Runtime         string `yaml:"runtime,omitempty"`
	ActivateRuntime *bool  `yaml:"autoActivate,omitempty"`

	// ModelRunner is the AI model runner (docker, ramalama).
	ModelRunner string `yaml:"modelRunner,omitempty"`

	// Kubernetes configuration
	Kubernetes Kubernetes `yaml:"kubernetes,omitempty"`

	// Docker configuration
	Docker map[string]any `yaml:"docker,omitempty"`

	// provision scripts
	Provision []Provision `yaml:"provision,omitempty"`
}

// Kubernetes is kubernetes configuration
type Kubernetes struct {
	Enabled bool     `yaml:"enabled"`
	Version string   `yaml:"version"`
	K3sArgs []string `yaml:"k3sArgs"`
	Port    int      `yaml:"port,omitempty"`
}

// Network is VM network configuration
type Network struct {
	Address         bool              `yaml:"address"`
	DNSResolvers    []net.IP          `yaml:"dns"`
	DNSHosts        map[string]string `yaml:"dnsHosts"`
	HostAddresses   bool              `yaml:"hostAddresses"`
	Mode            string            `yaml:"mode"` // shared, bridged
	BridgeInterface string            `yaml:"interface"`
	PreferredRoute  bool              `yaml:"preferredRoute"`
	GatewayAddress  net.IP            `yaml:"gatewayAddress"`
}

// Mount is volume mount
type Mount struct {
	Location   string `yaml:"location"`
	MountPoint string `yaml:"mountPoint,omitempty"`
	Writable   bool   `yaml:"writable"`
}

// Provision modes managed by Colima (not passed to Lima).
const (
	ProvisionModeAfterBoot = "after-boot"
	ProvisionModeReady     = "ready"
)

type Provision struct {
	Mode   string `yaml:"mode"`
	Script string `yaml:"script"`
}

// IsColimaMode returns true if the provision script is managed by Colima
// rather than being passed to Lima.
func (p Provision) IsColimaMode() bool {
	return p.Mode == ProvisionModeAfterBoot || p.Mode == ProvisionModeReady
}

func (c Config) MountsOrDefault() []Mount {
	// explicit empty list means mount home directory (matches yaml.go)
	if c.Mounts != nil && len(c.Mounts) == 0 {
		return []Mount{
			{Location: util.HomeDir(), Writable: true},
		}
	}

	// nil means no mounts, non-empty means user-specified mounts
	return c.Mounts
}

// AutoActivate returns if auto-activation of host client config is enabled.
func (c Config) AutoActivate() bool {
	if c.ActivateRuntime == nil {
		return true
	}
	return *c.ActivateRuntime
}

// Empty checks if the configuration is empty.
func (c Config) Empty() bool { return c.Runtime == "" } // this may be better but not really needed.

func (c Config) DriverLabel() string {
	if util.MacOS13OrNewer() && c.VMType == "vz" {
		return "macOS Virtualization.Framework"
	} else if util.MacOS13OrNewerOnArm() && c.VMType == "krunkit" {
		return "Krunkit"
	}
	return "QEMU"
}

// Disk is an instance disk size
type Disk int

// GiB returns the string represent of the disk in GiB.
func (d Disk) GiB() string { return fmt.Sprintf("%dGiB", d) }

// Int returns the disk size in bytes.
func (d Disk) Int() int64 { return 1024 * 1024 * 1024 * int64(d) }

// CtxKey returns the context key for config.
func CtxKey() any {
	return struct{ name string }{name: "colima_config"}
}


================================================
FILE: config/configmanager/configmanager.go
================================================
package configmanager

import (
	"fmt"
	"net"
	"os"
	"strings"

	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/yamlutil"
	"gopkg.in/yaml.v3"
)

// Save saves the config.
func Save(c config.Config) error {
	return yamlutil.Save(c, config.CurrentProfile().File())
}

// SaveFromFile loads configuration from file and save as config.
func SaveFromFile(file string) error {
	c, err := LoadFrom(file)
	if err != nil {
		return err
	}
	return Save(c)
}

// SaveToFile saves configuration to file.
func SaveToFile(c config.Config, file string) error {
	return yamlutil.Save(c, file)
}

// LoadFrom loads config from file.
func LoadFrom(file string) (config.Config, error) {
	var c config.Config
	b, err := os.ReadFile(file)
	if err != nil {
		return c, fmt.Errorf("could not load config from file: %w", err)
	}

	err = yaml.Unmarshal(b, &c)
	if err != nil {
		return c, fmt.Errorf("could not load config from file: %w", err)
	}

	return c, nil
}

// ValidateConfig validates config before we use it
func ValidateConfig(c config.Config) error {
	validMountTypes := map[string]bool{"9p": true, "sshfs": true}
	validPortForwarders := map[string]bool{"grpc": true, "ssh": true, "none": true}

	if util.MacOS13OrNewer() {
		validMountTypes["virtiofs"] = true
	}
	if _, ok := validMountTypes[c.MountType]; !ok {
		return fmt.Errorf("invalid mountType: '%s'", c.MountType)
	}
	validVMTypes := map[string]bool{"qemu": true}
	if util.MacOS13OrNewer() {
		validVMTypes["vz"] = true
	}
	if util.MacOS13OrNewerOnArm() {
		validVMTypes["krunkit"] = true
	}
	if c.VMType == "krunkit" && !util.MacOS13OrNewerOnArm() {
		return fmt.Errorf("vmType 'krunkit' is only available on macOS with Apple Silicon")
	}
	if _, ok := validVMTypes[c.VMType]; !ok {
		return fmt.Errorf("invalid vmType: '%s'", c.VMType)
	}
	if c.VMType == "qemu" {
		if err := util.AssertQemuImg(); err != nil {
			return fmt.Errorf("cannot use vmType: '%s', error: %w", c.VMType, err)
		}
	}
	if c.VMType == "krunkit" {
		if err := util.AssertKrunkit(); err != nil {
			return fmt.Errorf("cannot use vmType: '%s', error: %w", c.VMType, err)
		}
	}

	if c.DiskImage != "" {
		if strings.HasPrefix(c.DiskImage, "http://") || strings.HasPrefix(c.DiskImage, "https://") {
			return fmt.Errorf("cannot use diskImage: remote URLs not supported, only local files can be specified")
		}
	}

	if _, ok := validPortForwarders[c.PortForwarder]; !ok {
		return fmt.Errorf("invalid port forwarder: '%s'", c.PortForwarder)
	}

	if c.Network.GatewayAddress != nil {
		if err := validateGatewayAddress(c.Network.GatewayAddress); err != nil {
			return err
		}
	}

	return nil
}

// Load loads the config.
// Error is only returned if the config file exists but could not be loaded.
// No error is returned if the config file does not exist.
func Load() (c config.Config, err error) {
	f := config.CurrentProfile().File()
	if _, err := os.Stat(f); err != nil {
		return c, nil
	}

	return LoadFrom(f)
}

// LoadInstance is like Load but returns the config of the currently running instance.
func LoadInstance() (config.Config, error) {
	return LoadFrom(config.CurrentProfile().StateFile())
}

// Teardown deletes the config.
func Teardown() error {
	dir := config.CurrentProfile().ConfigDir()
	if _, err := os.Stat(dir); err == nil {
		return os.RemoveAll(dir)
	}
	return nil
}

// Validates that gateway is a valid IPv4 address and that the last octet is “2”.
// Lima uses the last octet as 2 for gateways.
func validateGatewayAddress(gateway net.IP) error {
	ip4 := gateway.To4()
	if ip4 == nil {
		return fmt.Errorf("gateway %q is not IPv4", gateway)
	}

	// Check last octet
	if ip4[3] != 2 {
		return fmt.Errorf("the last octet of gateway %q is not 2", gateway)
	}

	return nil
}


================================================
FILE: config/files.go
================================================
package config

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/fsutil"
	"github.com/sirupsen/logrus"
)

// requiredDir is a directory that must exist on the filesystem
type requiredDir struct {
	once sync.Once

	// dir is a func to enable deferring the value of the directory
	// until execution time.
	// if dir() returns an error, a fatal error is triggered.
	dir func() (string, error)

	computedDir *string
}

// Dir returns the directory path.
// It ensures the directory is created on the filesystem by calling
// `mkdir` prior to returning the directory path.
func (r *requiredDir) Dir() string {
	if r.computedDir != nil {
		return *r.computedDir
	}

	dir, err := r.dir()
	if err != nil {
		logrus.Fatal(fmt.Errorf("cannot fetch required directory: %w", err))
	}

	r.once.Do(func() {
		if err := fsutil.MkdirAll(dir, 0755); err != nil {
			logrus.Fatal(fmt.Errorf("cannot make required directory: %w", err))
		}
	})

	r.computedDir = &dir
	return dir
}

var (
	configBaseDir = requiredDir{
		dir: func() (string, error) {
			// colima home explicit config
			dir := os.Getenv("COLIMA_HOME")
			if _, err := os.Stat(dir); err == nil {
				return dir, nil
			}

			// user home directory
			homeDir, err := os.UserHomeDir()
			if err != nil {
				return "", err
			}
			// colima's config directory based on home directory
			dir = filepath.Join(homeDir, ".colima")
			// validate existence of colima's config directory
			_, err = os.Stat(dir)

			// extra xdg config directory
			xdgDir, xdg := os.LookupEnv("XDG_CONFIG_HOME")

			if err == nil {
				// ~/.colima is found but xdg dir is set
				if xdg {
					logrus.Warnln("found ~/.colima, ignoring $XDG_CONFIG_HOME...")
					logrus.Warnln("delete ~/.colima to use $XDG_CONFIG_HOME as config directory")
					logrus.Warnf("or run `mv ~/.colima \"%s\"`", filepath.Join(xdgDir, "colima"))
				}
				return dir, nil
			} else {
				// ~/.colima is missing and xdg dir is set
				if xdg {
					return filepath.Join(xdgDir, "colima"), nil
				}
			}

			// macOS users are accustomed to ~/.colima
			if util.MacOS() {
				return dir, nil
			}

			// other environments fall back to user config directory
			dir, err = os.UserConfigDir()
			if err != nil {
				return "", err
			}

			return filepath.Join(dir, "colima"), nil
		},
	}

	cacheDir = requiredDir{
		dir: func() (string, error) {
			if dir := os.Getenv("COLIMA_CACHE_HOME"); dir != "" {
				return dir, nil
			}

			if dir := os.Getenv("XDG_CACHE_HOME"); dir != "" {
				return filepath.Join(dir, "colima"), nil
			}
			// else
			dir, err := os.UserCacheDir()
			if err != nil {
				return "", err
			}
			return filepath.Join(dir, "colima"), nil
		},
	}

	templatesDir = requiredDir{
		dir: func() (string, error) {
			dir, err := configBaseDir.dir()
			if err != nil {
				return "", err
			}
			return filepath.Join(dir, "_templates"), nil
		},
	}

	limaDir = requiredDir{
		dir: func() (string, error) {
			// if LIMA_HOME env var is set, obey it.
			if dir := os.Getenv("LIMA_HOME"); dir != "" {
				return dir, nil
			}

			dir, err := configBaseDir.dir()
			if err != nil {
				return "", err
			}
			return filepath.Join(dir, "_lima"), nil
		},
	}

	storeDir = requiredDir{
		dir: func() (string, error) {
			dir, err := configBaseDir.dir()
			if err != nil {
				return "", err
			}
			return filepath.Join(dir, "_store"), nil
		},
	}
)

// CacheDir returns the cache directory.
func CacheDir() string { return cacheDir.Dir() }

// TemplatesDir returns the templates' directory.
func TemplatesDir() string { return templatesDir.Dir() }

// LimaDir returns Lima directory.
func LimaDir() string { return limaDir.Dir() }

const configFileName = "colima.yaml"

// SSHConfigFile returns the path to generated ssh config.
func SSHConfigFile() string { return filepath.Join(configBaseDir.Dir(), "ssh_config") }


================================================
FILE: config/profile.go
================================================
package config

import (
	"path/filepath"
	"strings"
)

var profile = &Profile{ID: AppName, DisplayName: AppName, ShortName: "default"}

// SetProfile sets the profile name for the application.
// This is an avenue to test Colima without breaking an existing stable setup.
// Not perfect, but good enough for testing.
func SetProfile(profileName string) {
	profile = ProfileFromName(profileName)
	profile.Changed = true
}

// ProfileFromName retrieves profile given name.
func ProfileFromName(name string) *Profile {
	var i Profile

	switch name {
	case "", AppName, "default":
		i.ID = AppName
		i.DisplayName = AppName
		i.ShortName = "default"
		return &i
	}

	// sanitize
	name = strings.TrimPrefix(name, "colima-")

	// if custom profile is specified,
	// use a prefix to prevent possible name clashes
	i.ID = "colima-" + name
	i.DisplayName = "colima [profile=" + name + "]"
	i.ShortName = name
	return &i
}

// CurrentProfile returns the current running profile.
func CurrentProfile() *Profile { return profile }

// Profile is colima profile.
type Profile struct {
	ID          string
	DisplayName string
	ShortName   string

	Changed bool // indicates if the profile has been changed

	configDir *requiredDir
}

// ConfigDir returns the configuration directory.
func (p *Profile) ConfigDir() string {
	if p.configDir == nil {
		p.configDir = &requiredDir{
			dir: func() (string, error) {
				return filepath.Join(configBaseDir.Dir(), p.ShortName), nil
			},
		}
	}
	return p.configDir.Dir()
}

// LimaInstanceDir returns the directory for the Lima instance.
func (p *Profile) LimaInstanceDir() string {
	return filepath.Join(limaDir.Dir(), p.ID)
}

// File returns the path to the config file.
func (p *Profile) File() string {
	return filepath.Join(p.ConfigDir(), configFileName)
}

// LimaFile returns the path to the lima config file.
func (p *Profile) LimaFile() string {
	return filepath.Join(p.LimaInstanceDir(), "lima.yaml")
}

// StateFile returns the path to the state file.
func (p *Profile) StateFile() string {
	return filepath.Join(p.LimaInstanceDir(), configFileName)
}

func (p *Profile) StoreFile() string {
	return filepath.Join(storeDir.Dir(), p.ID+".json")
}

var _ ProfileInfo = (*Profile)(nil)

// ProfileInfo is the information about a profile.
type ProfileInfo interface {
	// ConfigDir returns the configuration directory.
	ConfigDir() string

	// LimaInstanceDir returns the directory for the Lima instance.
	LimaInstanceDir() string

	// File returns the path to the config file.
	File() string

	// LimaFile returns the path to the lima config file.
	LimaFile() string

	// StateFile returns the path to the state file.
	StateFile() string

	// StoreFile returns the path to the store file.
	StoreFile() string
}


================================================
FILE: core/core.go
================================================
package core

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/sirupsen/logrus"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/environment"
	"github.com/coreos/go-semver/semver"
)

const limaVersion = "v0.18.0" // minimum Lima version supported

type (
	hostActions  = environment.HostActions
	guestActions = environment.GuestActions
)

// SetupBinfmt downloads and install binfmt
func SetupBinfmt(host hostActions, guest guestActions, arch environment.Arch) error {
	qemuArch := environment.AARCH64
	if arch.Value().GoArch() == "arm64" {
		qemuArch = environment.X8664
	}

	install := func() error {
		if err := guest.Run("sh", "-c", "sudo QEMU_PRESERVE_ARGV0=1 /usr/bin/binfmt --install 386,"+qemuArch.GoArch()); err != nil {
			return fmt.Errorf("error installing binfmt: %w", err)
		}
		return nil
	}

	// validate binfmt
	if err := guest.RunQuiet("command", "-v", "binfmt"); err != nil {
		return fmt.Errorf("binfmt not found: %w", err)
	}

	return install()
}

// LimaVersionSupported checks if the currently installed Lima version is supported.
func LimaVersionSupported() error {
	var values struct {
		Version string `json:"version"`
	}
	var buf bytes.Buffer
	cmd := cli.Command("limactl", "info")
	cmd.Stdout = &buf

	if err := cmd.Run(); err != nil {
		return fmt.Errorf("error checking Lima version: %w", err)
	}

	if err := json.NewDecoder(&buf).Decode(&values); err != nil {
		return fmt.Errorf("error decoding 'limactl info' json: %w", err)
	}
	// remove pre-release hyphen
	parts := strings.SplitN(values.Version, "-", 2)
	if len(parts) > 0 {
		values.Version = parts[0]
	}

	if parts[0] == "HEAD" {
		logrus.Warnf("to avoid compatibility issues, ensure lima development version (%s) in use is not lower than %s", values.Version, limaVersion)
		return nil
	}

	min := semver.New(strings.TrimPrefix(limaVersion, "v"))
	current, err := semver.NewVersion(strings.TrimPrefix(values.Version, "v"))
	if err != nil {
		return fmt.Errorf("invalid semver version for Lima: %w", err)
	}

	if min.Compare(*current) > 0 {
		return fmt.Errorf("minimum Lima version supported is %s, current version is %s", limaVersion, values.Version)
	}

	return nil
}


================================================
FILE: daemon/daemon.go
================================================
package daemon

import (
	"context"
	"fmt"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/daemon/process/inotify"
	"github.com/abiosoft/colima/daemon/process/vmnet"
	"github.com/abiosoft/colima/environment"
	"github.com/abiosoft/colima/util"
	"github.com/abiosoft/colima/util/fsutil"
	"github.com/abiosoft/colima/util/osutil"
)

// Manager handles running background processes.
type Manager interface {
	Start(context.Context, config.Config) error
	Stop(context.Context, config.Config) error
	Running(context.Context, config.Config) (Status, error)
	Dependency(ctx context.Context, conf config.Config, name string) (deps process.Dependency, root bool)
}

type Status struct {
	// Parent process
	Running bool
	// Subprocesses
	Processes []processStatus
}
type processStatus struct {
	Name    string
	Running bool
	Error   error
}

// NewManager creates a new process manager.
func NewManager(host environment.HostActions) Manager {
	return &processManager{
		host: host,
	}
}

func CtxKey(s string) any { return struct{ key string }{key: s} }

var _ Manager = (*processManager)(nil)

type processManager struct {
	host environment.HostActions
}

func (l processManager) Dependency(ctx context.Context, conf config.Config, name string) (deps process.Dependency, root bool) {
	processes := processesFromConfig(conf)

	for _, p := range processes {
		if p.Name() == name {
			return process.Dependencies(p)
		}
	}

	return process.Dependencies()
}

func (l processManager) init() error {
	// dependencies for network
	if err := fsutil.MkdirAll(process.Dir(), 0755); err != nil {
		return fmt.Errorf("error preparing vmnet: %w", err)
	}
	return nil
}

func (l processManager) Running(ctx context.Context, conf config.Config) (s Status, err error) {
	err = l.host.RunQuiet(osutil.Executable(), "daemon", "status", config.CurrentProfile().ShortName)
	if err != nil {
		return
	}
	s.Running = true

	ctx = context.WithValue(ctx, process.CtxKeyDaemon(), s.Running)

	for _, p := range processesFromConfig(conf) {
		pErr := p.Alive(ctx)
		s.Processes = append(s.Processes, processStatus{
			Name:    p.Name(),
			Running: pErr == nil,
			Error:   pErr,
		})
	}
	return
}

func (l processManager) Start(ctx context.Context, conf config.Config) error {
	_ = l.Stop(ctx, conf) // this is safe, nothing is done when not running

	if err := l.init(); err != nil {
		return fmt.Errorf("error preparing daemon directory: %w", err)
	}

	args := []string{osutil.Executable(), "daemon", "start", config.CurrentProfile().ShortName}

	if conf.Network.Address {
		args = append(args, "--vmnet")
		args = append(args, "--vmnet-mode", conf.Network.Mode)
		args = append(args, "--vmnet-interface", conf.Network.BridgeInterface)
	}
	if conf.MountINotify {
		args = append(args, "--inotify")
		args = append(args, "--inotify-runtime", conf.Runtime)
		for _, mount := range conf.MountsOrDefault() {
			p, err := util.CleanPath(mount.Location)
			if err != nil {
				return fmt.Errorf("error sanitising mount path for inotify: %w", err)
			}
			args = append(args, "--inotify-dir", p)
		}
	}

	if cli.Settings.Verbose {
		args = append(args, "--very-verbose")
	}

	host := l.host.WithDir(util.HomeDir())
	return host.RunQuiet(args...)
}
func (l processManager) Stop(ctx context.Context, conf config.Config) error {
	if s, err := l.Running(ctx, conf); err != nil || !s.Running {
		return nil
	}
	return l.host.RunQuiet(osutil.Executable(), "daemon", "stop", config.CurrentProfile().ShortName)
}

func processesFromConfig(conf config.Config) []process.Process {
	var processes []process.Process

	if conf.Network.Address {
		processes = append(processes, vmnet.New(conf.Network.Mode, conf.Network.BridgeInterface))
	}
	if conf.MountINotify {
		processes = append(processes, inotify.New())
	}

	return processes
}


================================================
FILE: daemon/process/inotify/events.go
================================================
package inotify

import (
	"context"
	"fmt"
	"io/fs"
	"time"
)

type modEvent struct {
	path string // filename
	fs.FileMode
}

func (m modEvent) Mode() string { return fmt.Sprintf("%o", m.FileMode) }

func (f *inotifyProcess) handleEvents(ctx context.Context, watcher dirWatcher) error {
	log := f.log
	log.Trace("begin inotify event handler")

	mod := make(chan modEvent)
	vols := make(chan []string)

	if err := f.monitorContainerVolumes(ctx, vols); err != nil {
		return fmt.Errorf("error watching container volumes: %w", err)
	}

	var last time.Time
	var cancelWatch context.CancelFunc
	var currentVols []string

	volsChanged := func(vols []string) bool {
		if len(currentVols) != len(vols) {
			return true
		}
		for i := range vols {
			if vols[i] != currentVols[i] {
				return true
			}
		}
		return false
	}

	cache := map[string]struct{}{}

	for {
		select {

		// exit signal
		case <-ctx.Done():
			close(mod)
			return ctx.Err()

		// watch only container volumes
		case vols := <-vols:
			if !volsChanged(vols) {
				continue
			}
			log.Tracef("volumes changed from: %+v, to: %+v", currentVols, vols)

			currentVols = vols

			if cancel := cancelWatch; cancel != nil {
				// delay a bit to avoid zero downtime
				time.AfterFunc(time.Second*1, cancel)
			}

			ctx, cancel := context.WithCancel(ctx)
			cancelWatch = cancel

			go func(ctx context.Context, vols []string, mod chan<- modEvent) {
				if err := watcher.Watch(ctx, vols, mod); err != nil {
					log.Error(fmt.Errorf("error running watcher: %w", err))
				}
			}(ctx, vols, mod)

		// handle modification events
		case ev := <-mod:
			now := time.Now()

			// rate limit, handle at most 50 unique items every 500 ms
			if now.Sub(last) < time.Millisecond*500 {
				if _, ok := cache[ev.path]; ok {
					continue // handled, ignore
				}
				if len(cache) > 50 {
					continue
				}
			} else {
				last = now
				cache = map[string]struct{}{} // >500ms, reset unique cache
			}

			// cache current event
			cache[ev.path] = struct{}{}

			// validate that file exists
			if err := f.guest.RunQuiet("stat", ev.path); err != nil {
				log.Trace(fmt.Errorf("cannot stat '%s': %w", ev.path, err))
				continue
			}

			log.Infof("syncing inotify event for %s ", ev.path)
			if err := f.guest.RunQuiet("sudo", "/bin/chmod", ev.Mode(), ev.path); err != nil {
				log.Trace(fmt.Errorf("error syncing inotify event: %w", err))
			}
		}
	}
}


================================================
FILE: daemon/process/inotify/inotify.go
================================================
package inotify

import (
	"context"
	"fmt"
	"time"

	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/environment"
	"github.com/abiosoft/colima/environment/vm/lima/limautil"
	"github.com/sirupsen/logrus"
)

const Name = "inotify"
const volumesInterval = 5 * time.Second

type Args struct {
	environment.GuestActions
	Dirs    []string
	Runtime string
}

func CtxKeyArgs() any { return struct{ name string }{name: "inotify_args"} }

// New returns inotify process.
func New() process.Process {
	return &inotifyProcess{
		log: logrus.WithField("context", "inotify"),
	}
}

var _ process.Process = (*inotifyProcess)(nil)

type inotifyProcess struct {
	vmVols  []string
	guest   environment.GuestActions
	runtime string

	log *logrus.Entry
}

// Alive implements process.Process
func (f *inotifyProcess) Alive(ctx context.Context) error {
	daemonRunning, _ := ctx.Value(process.CtxKeyDaemon()).(bool)

	// if the parent is active, we can assume inotify is active.
	if daemonRunning {
		return nil
	}
	return fmt.Errorf("inotify not running")
}

// Dependencies implements process.Process
func (*inotifyProcess) Dependencies() (deps []process.Dependency, root bool) {
	return nil, false
}

// Name implements process.Process
func (*inotifyProcess) Name() string {
	return Name
}

// Start implements process.Process
func (f *inotifyProcess) Start(ctx context.Context) error {
	args, ok := ctx.Value(CtxKeyArgs()).(Args)
	if !ok {
		return fmt.Errorf("args missing in context")
	}
	f.vmVols = omitChildrenDirectories(args.Dirs)

	f.guest = args.GuestActions
	f.runtime = args.Runtime
	log := f.log

	log.Info("waiting for VM to start")
	f.waitForLima(ctx)
	log.Info("VM started")

	watcher := &defaultWatcher{log: log}

	return f.handleEvents(ctx, watcher)
}

// waitForLima waits until lima starts and sets the directory to watch.
func (f *inotifyProcess) waitForLima(ctx context.Context) {
	log := f.log

	// wait for Lima to finish starting
	for {
		log.Info("waiting 5 secs for VM")

		// 5 second interval
		after := time.After(time.Second * 5)

		select {
		case <-ctx.Done():
			return
		case <-after:
			i, err := limautil.Instance()
			if err != nil || !i.Running() {
				continue
			}
			if err := f.guest.RunQuiet("uname", "-a"); err == nil {
				return
			}
		}
	}
}


================================================
FILE: daemon/process/inotify/volumes.go
================================================
package inotify

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"sort"
	"strings"
	"time"

	"github.com/abiosoft/colima/environment/container/containerd"
	"github.com/abiosoft/colima/environment/container/docker"
)

func (f *inotifyProcess) monitorContainerVolumes(ctx context.Context, c chan<- []string) error {
	log := f.log

	if f.runtime == "" {
		return fmt.Errorf("empty runtime")
	}

	fetch := func() ([]string, error) {
		var vols []string

		switch f.runtime {

		case docker.Name:
			vols, err := f.fetchVolumes(docker.Name)
			if err != nil {
				return nil, fmt.Errorf("error fetching docker volumes: %w", err)
			}
			return vols, nil

		case containerd.Name:
			var namespaces []string
			out, err := f.guest.RunOutput("sudo", "nerdctl", "namespace", "list", "-q")
			if err != nil {
				return nil, fmt.Errorf("error retrieving containerd namespaces: %w", err)
			}
			if out != "" {
				namespaces = strings.Fields(out)
			}

			for _, ns := range namespaces {
				v, err := f.fetchVolumes("sudo", "nerdctl", "--namespace", ns)
				if err != nil {
					return nil, fmt.Errorf("error retrieving containerd volumes: %w", err)
				}
				if len(v) > 0 {
					vols = append(vols, v...)
				}
			}

			return vols, nil
		}

		return nil, nil
	}

	go func() {
		for {
			select {
			case <-ctx.Done():
				log.Trace("stop signal received")
				err := ctx.Err()
				if err != nil {
					log.Trace(fmt.Errorf("error during stop: %w", err))
				}
			case <-time.After(volumesInterval):
				if vols, err := fetch(); err != nil {
					log.Error(err)
				} else {
					c <- vols
				}
			}
		}
	}()

	return nil
}

func (f *inotifyProcess) fetchVolumes(cmdArgs ...string) ([]string, error) {
	log := f.log

	// fetch all containers
	var containers []string
	{
		args := append([]string{}, cmdArgs...)
		args = append(args, "ps", "-q")
		out, err := f.guest.RunOutput(args...)
		if err != nil {
			return nil, fmt.Errorf("error listing containers: %w", err)
		}
		containers = strings.Fields(out)
		if len(containers) == 0 {
			return nil, nil
		}
	}

	log.Tracef("found containers %+v", containers)

	// fetch volumes
	var resp []struct {
		Mounts []struct {
			Source string `json:"Source"`
		} `json:"Mounts"`
	}
	{
		args := append([]string{}, cmdArgs...)
		args = append(args, "inspect")
		args = append(args, containers...)

		var buf bytes.Buffer
		if err := f.guest.RunWith(nil, &buf, args...); err != nil {
			return nil, fmt.Errorf("error inspecting containers: %w", err)
		}
		if err := json.NewDecoder(&buf).Decode(&resp); err != nil {
			return nil, fmt.Errorf("error decoding docker response")
		}
	}

	// process and discard redundant volumes
	vols := []string{}
	{
		shouldMount := func(child string) bool {
			// ignore all invalid directories.
			// i.e. directories not within the mounted VM directories
			for _, parent := range f.vmVols {
				if strings.HasPrefix(child, parent) {
					return true
				}
			}
			return false
		}

		for _, r := range resp {
			for _, mount := range r.Mounts {
				if shouldMount(mount.Source) {
					vols = append(vols, mount.Source)
				}
			}
		}

		vols = omitChildrenDirectories(vols)
		log.Tracef("found volumes %+v", vols)
	}

	return vols, nil
}

func omitChildrenDirectories(dirs []string) []string {
	sort.Strings(dirs) // sort to put the parent directories first

	// keep track for uniqueness
	set := map[string]struct{}{}

	var newVols []string

	omitted := map[int]struct{}{}
	for i := 0; i < len(dirs); i++ {
		// if the index is omitted, skip
		if _, ok := omitted[i]; ok {
			continue
		}

		parent := dirs[i]
		if _, ok := set[parent]; !ok {
			newVols = append(newVols, parent)
			set[parent] = struct{}{}
		}

		for j := i + 1; j < len(dirs); j++ {
			child := dirs[j]
			if strings.HasPrefix(child, strings.TrimSuffix(parent, "/")+"/") {
				omitted[j] = struct{}{}
			}
		}
	}

	return newVols
}


================================================
FILE: daemon/process/inotify/volumes_test.go
================================================
package inotify

import (
	"reflect"
	"strconv"
	"testing"
)

func Test_omitChildrenDirectories(t *testing.T) {
	tests := []struct {
		args []string
		want []string
	}{
		{
			args: []string{"/", "/user", "/user/someone", "/a", "/a/ee", "/a/bb"},
			want: []string{"/"},
		},
		{
			args: []string{"/someone", "/user", "/user/someone", "/a", "/a/ee", "/a/bb", "/a"},
			want: []string{"/a", "/someone", "/user"},
		},
		{
			args: []string{"/someone", "/user/colima/projects/myworks", "/user/colima/projects", "/user/colima/projects/myworks", "/user/colima/projects", "/someone"},
			want: []string{"/someone", "/user/colima/projects"},
		},
		{
			args: []string{"/someone", "/user/colima/projects/myworks", "/user/colima/projects"},
			want: []string{"/someone", "/user/colima/projects"},
		},
		{
			args: []string{"/user/colima/projects"},
			want: []string{"/user/colima/projects"},
		},
	}
	for i, tt := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			if got := omitChildrenDirectories(tt.args); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("omitChildrenDirectories() = %v, want %v", got, tt.want)
			}
		})
	}
}


================================================
FILE: daemon/process/inotify/watch.go
================================================
package inotify

import (
	"context"
	"fmt"
	"os"

	"github.com/abiosoft/colima/util"
	"github.com/rjeczalik/notify"
	"github.com/sirupsen/logrus"
)

type dirWatcher interface {
	// Watch watches directories recursively for changes and sends message via c on
	// modifications to files within the watched directories.
	//
	// Watch returns immediately and runs the watcher in the background.
	// An error is returned when the watcher can not be started in background.
	//
	// The watcher terminates on fatal error or when ctx is done.
	Watch(ctx context.Context, dirs []string, c chan<- modEvent) error
}

type defaultWatcher struct {
	log *logrus.Entry
}

// Watch implements dirWatcher
func (d *defaultWatcher) Watch(ctx context.Context, dirs []string, mod chan<- modEvent) error {
	log := d.log
	c := make(chan notify.EventInfo, 1)

	for _, dir := range dirs {
		dir, err := util.CleanPath(dir)
		if err != nil {
			return fmt.Errorf("invalid directory: %w", err)
		}
		err = notify.Watch(dir+"...", c, notify.Write)
		if err != nil {
			return fmt.Errorf("error watching directory recursively '%s': %w", dir, err)
		}
	}

	go func(ctx context.Context, c chan notify.EventInfo, mod chan<- modEvent) {
		for {
			select {

			case <-ctx.Done():
				notify.Stop(c)
				log.Trace("stopping watcher")
				if err := ctx.Err(); err != nil {
					log.Trace(fmt.Errorf("error found in ctx: %w", err))
					return
				}

			case e := <-c:
				path := e.Path()

				log.Tracef("received event %s for %s", e.Event().String(), path)

				stat, err := os.Stat(path)
				if err != nil {
					log.Trace(fmt.Errorf("unable to stat inotify file '%s': %w", path, err))
					continue
				}

				if stat.IsDir() {
					log.Tracef("'%s' is directory, ignoring.", path)
					continue
				}

				// send modification event
				mod <- modEvent{path: path, FileMode: stat.Mode()}
			}
		}
	}(ctx, c, mod)

	return nil
}

var _ dirWatcher = (*defaultWatcher)(nil)


================================================
FILE: daemon/process/process.go
================================================
package process

import (
	"context"
	"fmt"
	"path/filepath"

	"github.com/abiosoft/colima/config"

	"github.com/abiosoft/colima/environment"
)

func CtxKeyDaemon() any { return struct{ key string }{key: "colima_daemon"} }

// Process is a background process managed by the daemon.
type Process interface {
	// Name for the background process
	Name() string
	// Start starts the background process.
	// The process is expected to terminate when ctx is done.
	Start(ctx context.Context) error
	// Alive checks if the process is the alive.
	Alive(ctx context.Context) error
	// Dependencies are requirements for start to succeed.
	// root should be true if root access is required for
	// installing any of the dependencies.
	Dependencies() (deps []Dependency, root bool)
}

// Dir is the directory for daemon files.
func Dir() string { return filepath.Join(config.CurrentProfile().ConfigDir(), "daemon") }

// Dependency is a requirement to be fulfilled before a process can be started.
type Dependency interface {
	Installed() bool
	Install(environment.HostActions) error
}

// Dependencies returns the dependencies for the processes.
// root returns if root access is required
func Dependencies(processes ...Process) (deps Dependency, root bool) {
	// check rootful for user info message
	rootful := false
	for _, p := range processes {
		deps, root := p.Dependencies()
		for _, dep := range deps {
			if !dep.Installed() && root {
				rootful = true
				break
			}
		}
	}

	return processDeps(processes), rootful
}

type processDeps []Process

func (p processDeps) Installed() bool {
	for _, process := range p {
		deps, _ := process.Dependencies()
		for _, d := range deps {
			if !d.Installed() {
				return false
			}
		}
	}

	return true
}

func (p processDeps) Install(host environment.HostActions) error {
	for _, process := range p {
		deps, _ := process.Dependencies()
		for _, d := range deps {
			if !d.Installed() {
				if err := d.Install(host); err != nil {
					return fmt.Errorf("error occurred installing dependencies for '%s': %w", process.Name(), err)
				}
			}
		}
	}

	return nil
}


================================================
FILE: daemon/process/vmnet/deps.go
================================================
package vmnet

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"

	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/embedded"
	"github.com/abiosoft/colima/environment"
)

var _ process.Dependency = sudoerFile{}

type sudoerFile struct{}

// Installed implements Dependency
func (s sudoerFile) Installed() bool { return embedded.SudoersInstalled() }

// Install implements Dependency
func (s sudoerFile) Install(host environment.HostActions) error {
	return embedded.InstallSudoers(host)
}

var _ process.Dependency = vmnetFile{}

const BinaryPath = "/opt/colima/bin/socket_vmnet"
const ClientBinaryPath = "/opt/colima/bin/socket_vmnet_client"

type vmnetFile struct{}

// Installed implements Dependency
func (v vmnetFile) Installed() bool {
	for _, bin := range v.bins() {
		if _, err := os.Stat(bin); err != nil {
			return false
		}
	}
	return true
}

func (v vmnetFile) bins() []string {
	return []string{BinaryPath, ClientBinaryPath}
}
func (v vmnetFile) Install(host environment.HostActions) error {
	arch := "x86_64"
	if runtime.GOARCH != "amd64" {
		arch = "arm64"
	}

	// read the embedded file
	gz, err := embedded.Read("network/vmnet_" + arch + ".tar.gz")
	if err != nil {
		return fmt.Errorf("error retrieving embedded vmnet file: %w", err)
	}

	// write tar to tmp directory
	f, err := os.CreateTemp("", "vmnet.tar.gz")
	if err != nil {
		return fmt.Errorf("error creating temp file: %w", err)
	}
	if _, err := f.Write(gz); err != nil {
		return fmt.Errorf("error writing temp file: %w", err)
	}
	_ = f.Close() // not a fatal error

	defer func() {
		_ = os.Remove(f.Name())
	}()

	// extract tar to desired location
	dir := optDir
	if err := host.RunInteractive("sudo", "mkdir", "-p", dir); err != nil {
		return fmt.Errorf("error preparing colima privileged dir: %w", err)
	}
	if err := host.RunInteractive("sudo", "sh", "-c", fmt.Sprintf("cd %s && tar xfz %s 2>/dev/null", dir, f.Name())); err != nil {
		return fmt.Errorf("error extracting vmnet archive: %w", err)
	}

	return nil
}

var _ process.Dependency = vmnetRunDir{}

type vmnetRunDir struct{}

// Install implements Dependency
func (v vmnetRunDir) Install(host environment.HostActions) error {
	return host.RunInteractive("sudo", "mkdir", "-p", runDir())
}

// Installed implements Dependency
func (v vmnetRunDir) Installed() bool {
	stat, err := os.Stat(runDir())
	return err == nil && stat.IsDir()
}

const optDir = "/opt/colima"

// runDir is the directory to the rootful daemon run related files. e.g. pid files
func runDir() string { return filepath.Join(optDir, "run") }


================================================
FILE: daemon/process/vmnet/vmnet.go
================================================
package vmnet

import (
	"context"
	"fmt"
	"net"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/abiosoft/colima/cli"
	"github.com/abiosoft/colima/config"
	"github.com/abiosoft/colima/daemon/process"
	"github.com/abiosoft/colima/util/osutil"
	"github.com/sirupsen/logrus"
)

const Name = "vmnet"

const (
	SubProcessEnvVar = "COLIMA_VMNET"

	NetGateway = "192.168.106.1"
	NetDHCPEnd = "192.168.106.254"
)

var _ process.Process = (*vmnetProcess)(nil)

func New(mode, netInterface string) process.Process {
	return &vmnetProcess{
		mode:         mode,
		netInterface: netInterface,
	}
}

type vmnetProcess struct {
	mode         string
	netInterface string
}

func (*vmnetProcess) Alive(ctx context.Context) error {
	info := Info()
	pidFile := info.PidFile
	socketFile := info.Socket.File()

	if _, err := os.Stat(pidFile); err == nil {
		cmd := exec.CommandContext(ctx, "sudo", "/usr/bin/pkill", "-0", "-F", pidFile)
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("error checking vmnet process: %w", err)
		}
	}

	if _, err := os.Stat(socketFile); err != nil {
		return fmt.Errorf("vmnet socket file not found error: %w", err)
	}
	if n, err := net.Dial("unix", socketFile); err != nil {
		return fmt.Errorf("vmnet socket file error: %w", err)
	} else {
		if err := n.Close(); err != nil {
			logrus.Debugln(fmt.Errorf("error closing ping socket connection: %w", err))
		}
	}

	return nil
}

// Name implements process.BgProcess
func (*vmnetProcess) Name() string { return Name }

// Start implements process.BgProcess
func (v *vmnetProcess) Start(ctx context.Context) error {
	info := Info()
	socket := info.Socket.File()
	pid := info.PidFile

	// delete existing sockets if exist
	// errors ignored on purpose
	_ = forceDeleteFileIfExists(socket)

	done := make(chan error, 1)

	go func() {
		// rootfully start the vmnet daemon
		var command *exec.Cmd

		if v.mode == "bridged" {
			command = cli.CommandInteractive("sudo", BinaryPath,
				"--vmnet-mode", "bridged",
				"--socket-group", "staff",
				"--vmnet-interface", v.netInterface,
				"--pidfile", pid,
				socket,
			)
		} else {
			command = cli.CommandInteractive("sudo", BinaryPath,
				"--vmnet-mode", "shared",
				"--socket-group", "staff",
				"--vmnet-gateway", NetGateway,
				"--vmnet-dhcp-end", NetDHCPEnd,
				"--pidfile", pid,
				socket,
			)
		}

		if cli.Settings.Verbose {
			command.Env = append(command.Env, os.Environ()...)
			command.Env = append(command.Env, "DEBUG=1")
		}

		done <- command.Run()
	}()

	select {
	case <-ctx.Done():
		if err := stop(pid); err != nil {
			return fmt.Errorf("error stopping vmnet: %w", err)
		}
	case err := <-done:
		if err != nil {
			return fmt.Errorf("error running vmnet: %w", err)
		}
	}

	return nil
}

func (vmnetProcess) Dependencies() (deps []process.Dependency, root bool) {
	return []process.Dependency{
		sudoerFile{},
		vmnetFile{},
		vmnetRunDir{},
	}, true
}

func stop(pidFile string) error {
	// rootfully kill the vmnet process.
	// process is only assumed alive if the pidfile exists
	if _, err := os.Stat(pidFile); err == nil {
		if err := cli.CommandInteractive("sudo", "/usr/bin/pkill", "-F", pidFile).Run(); err != nil {
			return fmt.Errorf("error killing vmnet process: %w", err)
		}
	}

	return nil
}

func forceDeleteFileIfExists(name string) error {
	if stat, err := os.Stat(name); err == nil && !stat.IsDir() {
		return os.Remove(name)
	}
	return nil
}

func Info() struct {
	PidFile string
	Socket  osutil.Socket
} {
	return struct {
		PidFile string
		Socket  osutil.Socket
	}{
		PidFile: filepath.Join(runDir(), "vmnet-"+config.CurrentProfile().ShortName+".pid"),
		Socket:  osutil.Socket(filepath.Join(process.Dir(), "vmnet.sock")),
	}
}


================================================
FILE: default.nix
================================================
with import <nixpkgs> { };
callPackage (import ./colima.nix) { }


================================================
FILE: docs/CONTRIBUTE.md
================================================
# Contributing to Colima

Thank you for your interest in contributing to Colima!

## Getting Started

Colima is a Go project. To contribute, you will need Go installed (see the [Go installation guide](https://golang.org/doc/install)).

### 1. Fork the Repository

First, fork the Colima repository on GitHub. Then, clone your fork locally:

```sh
git clone https://github.com/<your-username>/colima.git
cd colima
```

### 2. Create a New Branch

Create a new branch for your changes:

```sh
git checkout -b my-feature-branch
```

### 3. Commit Your Changes

Commit your changes with a DCO signoff and the required commit message format. Each commit must include a signoff line:

```
Signed-off-by: Your Name <your.email@example.com>
```

You can add this automatically with:

```sh
git commit -s -m "component: <message>"
# Example:
git commit -s -m "cli: add my-command to colima start"
```

### 4. Push Your Branch

Push your branch to your fork:

```sh
git push origin my-feature-branch
```

### 5. Open a Pull Request

Open a Pull Request against the main Colima repository.

## 6. DCO Signoff

Colima requires all commits to be signed off using the [Developer Certificate of Origin (DCO)](https://developercertificate.org/). This is a simple statement that you, as a contributor, have the right to submit your changes.

## Contribution Guidelines

### Major Contributions
Major contributions (new features, significant changes) should be preceded by a GitHub issue discussing the proposed change.

### Minor Contributions
Minor contributions (small fixes, documentation e.t.c.) do not require a prior issue.

### LLM Usage Disclosure
If you use a Large Language Model (LLM) to generate code, you must fully disclose its usage in your pull request, including which parts were generated and to what extent.

### LLM Reviewability
Large code contributions generated by LLMs that are not easily reviewable or understandable will be rejected.

## Reviewing and Merging

All PRs are subject to review.

Kindly ensure that your PR passes all CI checks. You are also obliged to respond to review comments and update your PR as needed.

## Need Help?

If you have questions, open an [issue](https://github.com/abiosoft/colima/issues) or start a [discussion](https://github.com/abiosoft/colima/discussions) in the repository.

---

Thank you for helping to improve Colima!


================================================
FILE: docs/FAQ.md
================================================
# FAQs

- [FAQs](#faqs)
  - [How does Colima compare to Lima?](#how-does-colima-compare-to-lima)
  - [Are Apple Silicon Macs supported?](#are-apple-silicon-macs-supported)
  - [Are AI workloads supported?](#are-ai-workloads-supported)
  - [Are older macOS versions supported?](#are-older-macos-versions-supported)
  - [Does Colima support autostart?](#does-colima-support-autostart)
  - [Can config file be used instead of cli flags?](#can-config-file-be-used-instead-of-cli-flags)
    - [Specifying the config location](#specifying-the-config-location)
    - [Editing the config](#editing-the-config)
    - [Setting the default config](#setting-the-default-config)
    - [Specifying the config editor](#specifying-the-config-editor)
  - [How do I change where Colima files are stored?](#how-do-i-change-where-colima-files-are-stored)
  - [How do I pass custom environment variables into the VM?](#how-do-i-pass-custom-environment-variables-into-the-vm)
  - [Docker](#docker)
    - [Can it run alongside Docker for Mac?](#can-it-run-alongside-docker-for-mac)
    - [Docker socket location](#docker-socket-location)
      - [v0.3.4 or older](#v034-or-older)
      - [v0.4.0 or newer](#v040-or-newer)
      - [Listing Docker contexts](#listing-docker-contexts)
      - [Changing the active Docker context](#changing-the-active-docker-context)
    - [Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?](#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running)
    - [How to customize Docker config (e.g., adding insecure registries or registry mirrors)?](#how-to-customize-docker-config-eg-adding-insecure-registries-or-registry-mirrors)
    - [Docker buildx plugin is missing](#docker-buildx-plugin-is-missing)
      - [Installing Buildx](#installing-buildx)
  - [Containerd](#containerd)
    - [How to customize Containerd config?](#how-to-customize-containerd-config)
      - [Per-profile overrides](#per-profile-overrides)
  - [How does Colima compare to minikube, Kind, K3d?](#how-does-colima-compare-to-minikube-kind-k3d)
    - [For Kubernetes](#for-kubernetes)
    - [For Docker](#for-docker)
  - [Is another Distro supported?](#is-another-distro-supported)
    - [Version v0.5.6 and lower](#version-v056-and-lower)
      - [Enabling Ubuntu layer](#enabling-ubuntu-layer)
      - [Accessing the underlying Virtual Machine](#accessing-the-underlying-virtual-machine)
    - [Version v0.6.0 and newer](#version-v060-and-newer)
  - [The Virtual Machine's IP is not reachable](#the-virtual-machines-ip-is-not-reachable)
    - [Enable reachable IP address](#enable-reachable-ip-address)
  - [Incus instances are not reachable from the host](#incus-instances-are-not-reachable-from-the-host)
  - [How can disk space be recovered?](#how-can-disk-space-be-recovered)
    - [Automatic](#automatic)
    - [Manual](#manual)
  - [How can disk size be increased?](#how-can-disk-size-be-increased)
  - [Are Lima overrides supported?](#are-lima-overrides-supported)
    - [Example: Adding provision scripts](#example-adding-provision-scripts)
  - [How can the VM and its tools be updated?](#how-can-the-vm-and-its-tools-be-updated)
    - [Updating Colima](#updating-colima)
    - [Updating the container runtime](#updating-the-container-runtime)
    - [Accessing the Virtual Machine](#accessing-the-virtual-machine)
  - [Troubleshooting](#troubleshooting)
    - [Colima not starting](#colima-not-starting)
      - [Broken status](#broken-status)
      - [FATA\[0000\] error starting vm: error at 'starting': exit status 1](#fata0000-error-starting-vm-error-at-starting-exit-status-1)
    - [Issues after an upgrade](#issues-after-an-upgrade)
    - [Colima cannot access the internet.](#colima-cannot-access-the-internet)
    - [Docker Compose and Buildx showing runc error](#docker-compose-and-buildx-showing-runc-error)
      - [Version v0.5.6 or lower](#version-v056-or-lower)
    - [Issue with Docker bind mount showing empty](#issue-with-docker-bind-mount-showing-empty)
  - [How can Docker version be updated?](#how-can-docker-version-be-updated)
  - [How can I delete container data](#how-can-i-delete-container-data)

## How does Colima compare to Lima?

Colima is basically a higher level usage of Lima and utilises Lima to provide Docker, Containerd and/or Kubernetes.

## Are Apple Silicon Macs supported?

Colima supports and works on both Intel and Apple Silicon Macs.

Feedbacks would be appreciated.

## Are AI workloads supported?

Yes, Colima supports GPU accelerated containers for AI workloads on Apple Silicon Macs running macOS 13 or newer.

To get started, start Colima with Docker runtime and krunkit VM type:

```sh
colima start --runtime docker --vm-type krunkit
```

Then setup and run AI models:

```sh
colima model setup
colima model run gemma3
```

Multiple model registries are supported including HuggingFace (default) and Ollama:

```sh
colima model run hf://tinyllama
colima model run ollama://tinyllama
```

For more options, run `colima model --help`.

## Are older macOS versions supported?

Colima is supported and regularly tested on the latest macOS version. However, Colima requires macOS 13 or newer.

You may be able to build Colima and it's dependencies from source on older macOS version. Colima requires [Lima](https://github.com/lima-vm/lima) and [Qemu](https://www.qemu.org/).
## Does Colima support autostart?

Since v0.5.6 Colima supports foreground mode via the `--foreground` flag. i.e. `colima start --foreground`.

If Colima has been installed using brew, the easiest way to autostart Colima is to use brew services.

```sh
brew services start colima
```

## Can config file be used instead of cli flags?

Yes, from v0.4.0, Colima support YAML configuration file.

### Specifying the config location

Set the `$COLIMA_HOME` environment variable, otherwise it defaults to `$HOME/.colima`.

### Editing the config

```
colima start --edit
```

For manual edit, the config file is located at `$HOME/.colima/default/colima.yaml`.

For other profiles, `$HOME/.colima/<profile-name>/colima.yaml`

### Setting the default config

```
colima template
```

For manual edit, the template file is located at `$HOME/.colima/_templates/default.yaml`.

### Specifying the config editor

Set the `$EDITOR` environment variable or use the `--editor` flag.

```sh
colima start --edit --editor code # one-off config
colima template --editor code # default config
```

## How do I change where Colima files are stored?

Colima supports these environment variables, set on your host machine:

| Variable | Description |
|----------|-------------|
| `COLIMA_HOME` | Colima configuration directory (default: `$HOME/.colima`) |
| `COLIMA_CACHE_HOME` | Colima cache directory (default is host-specific, see [os.UserCacheDir()](https://pkg.go.dev/os#UserCacheDir)) |
| `COLIMA_PROFILE` | Active profile name (default: `default`) |
| `DOCKER_CONFIG` | Path to Docker client configuration directory (default: `~/.docker`) |

## How do I pass custom environment variables into the VM?

Pass environment variables into the VM at startup using the YAML configuration file:

```yaml
env:
  MY_VAR: value
```

You can also use command-line flags:

```bash session
# On your host machine...
$ colima start --env MY_VAR=value

# Then, within the VM...
$ colima ssh
user@colima:~$ env | grep MY_VAR
MY_VAR=value
```

## Docker

### Can it run alongside Docker for Mac?

Yes, from version v0.3.0 Colima leverages Docker contexts and can thereby run alongside Docker for Mac.

Colima makes itself the default Docker context on startup and should work straight away.

### Docker socket location

#### v0.3.4 or older

Docker socket is located at `$HOME/.colima/docker.sock`

#### v0.4.0 or newer

Docker socket is located at `$HOME/.colima/default/docker.sock`

It can also be retrieved by checking status

```
colima status
```

#### Listing Docker contexts

```
docker context list
```

#### Changing the active Docker context

```
docker context use <context-name>
```
### Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Colima uses Docker contexts to allow co-existence with other Docker servers and sets itself as the default Docker context on startup.

However, some applications are not aware of Docker contexts and may lead to the error.

This can be fixed by any of the following approaches. Ensure the Docker socket path by checking the [socket location](#docker-socket-location).

1. Setting application specific Docker socket path if supported by the application. e.g. JetBrains IDEs.

2. Setting the `DOCKER_HOST` environment variable to point to Colima socket.

   ```sh
   export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
   ```
3. Linking the Colima socket to the default socket path. **Note** that this may break other Docker servers.

   ```sh
   sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
   ```


### How to customize Docker config (e.g., adding insecure registries or registry mirrors)?

* v0.3.4 or lower

  On first startup, Colima generates Docker daemon.json file at `$HOME/.colima/docker/daemon.json`.
  Modify the daemon.json file accordingly and restart Colima.

* v0.4.0 or newer

  Start Colima with `--edit` flag.

  ```sh
  colima start --edit
  ```

  Add the Docker config to the `docker` section.

  ```diff
  - docker: {}
  + docker:
  +   insecure-registries:
  +     - myregistry.com:5000
  +     - host.docker.internal:5000
  ```
**Note:** In order for the Docker client to respect (at least some) configuration value changes, modification of the host ~/.docker/daemon.json file may also be required.

For example, if adding registry mirrors, modifications are needed as follows:

First, colima:

```sh
colima start --edit
```

```diff
- docker: {}
+ docker:
+   registry-mirrors:
+     - https://my.dockerhub.mirror.something
+     - https://my.quayio.mirror.something
```

As an alternative approach to the **colima start --edit**, make the changes via the **template** command (affecting the configuration for any new instances):

```sh
colima template
```

Then, the Docker ~/.docker/daemon.json file (as compared to the default):

```diff
- "experimental": false,
+ "experimental": false,
+ "registry-mirrors": [
+   "https://my.dockerhub.mirror.something",
+   "https://my.quayio.mirror.something"
+ ]
```

### Docker buildx plugin is missing

`buildx` can be installed as a Docker plugin

#### Installing Buildx

Using homebrew
```sh
brew install docker-buildx
# Follow the caveats mentioned in the install instructions:
# mkdir -p ~/.docker/cli-plugins
# ln -sfn $(which docker-buildx) ~/.docker/cli-plugins/docker-buildx
docker buildx version # verify installation
```
Alternatively
```sh
ARCH=amd64 # change to 'arm64' for m1
VERSION=v0.11.2
curl -LO https://github.com/docker/buildx/releases/download/${VERSION}/buildx-${VERSION}.darwin-${ARCH}
mkdir -p ~/.docker/cli-plugins
mv buildx-${VERSION}.darwin-${ARCH} ~/.docker/cli-plugins/docker-buildx
chmod +x ~/.docker/cli-plugins/docker-buildx
docker buildx version # verify installation
```

## Containerd

### How to customize Containerd config?

On first startup with the containerd runtime, Colima generates default config files at the standard user config locations:

| File | Location |
|------|----------|
| Containerd config | `~/.config/containerd/config.toml` |
| BuildKit config | `~/.config/buildkit/buildkitd.toml` |

These follow the standard rootless containerd/buildkit config paths and are shared across all Colima profiles.

Modify the files accordingly and restart Colima for changes to take effect.

```sh
# edit the containerd config
$EDITOR ~/.config/containerd/config.toml

# restart colima
colima stop && colima start --runtime containerd
```

#### Per-profile overrides

To use a different config for a specific profile, place the config file at `$HOME/.colima/<profile-name>/containerd/config.toml` (or `buildkitd.toml`). Per-profile configs take priority over the central config.

The resolution order is:

1. `~/.colima/<profile>/containerd/<file>` (per-profile override)
2. `~/.config/containerd/<file>` or `~/.config/buildkit/<file>` (central)
3. Embedded default

**Note:** `$XDG_CONFIG_HOME` is respected for the central config location if set.

## How does Colima compare to minikube, Kind, K3d?

### For Kubernetes

Yes, you can create a Kubernetes cluster with minikube (with Docker driver), Kind or K3d instead of enabling Kubernetes
in Colima.

Those are better options if you need multiple clusters, or do not need Docker and Kubernetes to share the same images and runtime.

Colima with Docker runtime is fully compatible with Minikube (with Docker driver), Kind and K3d.

### For Docker

Minikube with Docker runtime can expose the cluster's Docker with `minikube docker-env`. But there are some caveats.

- Kubernetes is not optional, even if you only need Docker.

- All of minikube's free drivers for macOS fall-short in one of performance, port forwarding or volumes. While  port-forwarding and volumes are non-issue for Kubernetes, they can be a deal breaker for Docker-only use.

## Is another Distro supported?

### Version v0.5.6 and lower

Colima uses a lightweight Alpine image with bundled dependencies.
Therefore, user interaction with the Virtual Machine is expected to be minimal (if any).

However, Colima optionally provides Ubuntu container as a layer.


#### Enabling Ubuntu layer

* CLI
  ```
  colima start --layer=true
  ```

* Config
  ```diff
  - layer: false
  + layer: true
  ```

#### Accessing the underlying Virtual Machine

When the layer is enabled, the underlying Virtual Machine is abstracted and both the `ssh` and `ssh-config` commands routes to the layer.

The underlying Virtual Machine is still accessible by specifying `--layer=false` to the `ssh` and `ssh-config` commands, or by running `colima` in the SSH session.

### Version v0.6.0 and newer

Colima uses Ubuntu as the underlying image. Other distros are not supported.

## The Virtual Machine's IP is not reachable

Reachable IP address is not enabled by default due to root privilege and slower startup time.

### Enable reachable IP address

**NOTE:** this is only supported on macOS

* CLI
  ```
  colima start --network-address
  ```
* Config
  ```diff
  network:
  -  address: false
  +  address: true
  ```

## Incus instances are not reachable from the host

<small>**Requires v0.10.0**</small>

Incus containers and virtual machines are not reachable from the host by default. This is because network address is not enabled by default.

To fix this, stop Colima and restart with network address enabled:

```sh
colima stop
colima start --network-address
```

Or enable it in the config file:

```sh
colima start --edit
```

```diff
network:
-  address: false
+  address: true
```

## How can disk space be recovered?

Disk space can be freed in the VM by removing containers or running `docker system prune`.
However, it will not reflect on the host on Colima versions v0.4.x or lower.

### Automatic

For Colima v0.5.0 and above, unused disk space in the VM is released on startup. A restart would suffice.

### Manual

For Colima v0.5.0 and above, user can manually recover the disk space by running `sudo fstrim -a` in the VM.

```sh
# '-v' may be added for verbose output
colima ssh -- sudo fstrim -a
```

## How can disk size be increased?

Disk size is automatically increased on start up based on configuration in `colima.yaml`

```diff
- disk: 150
+ disk: 250
```

__Note:__ This feature is available from Version 0.5.3.


## Are Lima overrides supported?

Yes, however this should only be done by advanced users.

Lima supports `override.yaml` and `default.yaml` files that can modify the VM configuration.

The override file is located at `$HOME/.colima/_lima/_config/override.yaml` (or `$LIMA_HOME/_config/override.yaml` if `LIMA_HOME` is set).

Settings in `override.yaml` are applied **before** the instance config, while settings in `default.yaml` are applied **after** (as fallback defaults).

**Note:** Overriding the image is not supported as Colima's image includes bundled dependencies that would be missing in a user-specified image.

### Example: Adding provision scripts

Provision scripts can be added via Lima overrides to run commands during VM boot.

```yaml
# $HOME/.colima/_lima/_config/override.yaml
provision:
  - mode: system
    script: |
      #!/bin/bash
      set -eux -o pipefail
      # install additional packages
      apt-get update && apt-get install -y curl
```

Alternatively, provision scripts can be specified directly in `colima.yaml`:

```sh
colima start --edit
```

```diff
- provision: []
+ provision:
+   - mode: system
+     script: |
+       #!/bin/bash
+       set -eux -o pipefail
+       apt-get update && apt-get install -y curl
```

## How can the VM and its tools be updated?

### Updating Colima

```sh
brew upgrade colima
```

After upgrading, delete and recreate the instance to use the latest VM image:

```sh
colima delete
colima start
```

To test the upgrade without affecting the existing setup, use a separate profile:

```sh
colima start debug
```

### Updating the container runtime

From v0.7.6, the container runtime (Docker, containerd) can be updated independently:

```sh
colima update
```

This updates Docker (or containerd) to the latest version without needing to update Colima itself.

### Accessing the Virtual Machine

SSH into the VM to inspect or modify it directly:

```sh
colima ssh
```

Run a single command without an interactive session:

```sh
colima ssh -- uname -a
```

## Troubleshooting

These are some common issues reported by users and how to troubleshoot them.

### Colima not starting

There are multiple reasons that could cause Colima to fail to start.

#### Broken status

This is the case when the output of `colima list` shows a broken status. This can happen due to macOS restart.

```
colima list
PROFILE    STATUS     ARCH       CPUS    MEMORY    DISK     RUNTIME    ADDRESS
default    Broken     aarch64    2       2GiB      60GiB
```
This can be fixed by forcefully stopping Colima. The state will be changed to `Stopped` and it should start up normally afterwards.

```
colima stop --force
```

#### FATA[0000] error starting vm: error at 'starting': exit status 1

This indicates that a fatal error is preventing Colima from starting, you can enable the debug log with `--verbose` flag to get more info.

If the log output includes `exiting, status={Running:false Degraded:false Exiting:true Errors:[] SSHLocalPort:0}` then it is most certainly due to one of the following.

1. Running on a device without virtualization support.
2. Running an x86_64 version of homebrew (and Colima) on an M1 device.

### Issues after an upgrade

The recommended way to troubleshoot after an upgrade is to test with a separate profile.

```sh
# start with a profile named 'debug'
colima start debug
```
If the separate profile starts successfully without issues, then the issue would be resolved by resetting the default profile.

```
colima delete
colima start
```

### Colima cannot access the internet.

Failure for Colima to access the internet is usually down to DNS.

Try custom DNS server(s)

```sh
colima start --dns 8.8.8.8 --dns 1.1.1.1
```

Ping an internet address from within the VM to ascertain

```
colima ssh -- ping -c4 google.com
PING google.com (216.58.223.238): 56 data bytes
64 bytes from 216.58.223.238: seq=0 ttl=42 time=0.082 ms
64 bytes from 216.58.223.238: seq=1 ttl=42 time=0.557 ms
64 bytes from 216.58.223.238: seq=2 ttl=42 time=0.465 ms
64 bytes from 216.58.223.238: seq=3 ttl=42 time=0.457 ms

--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.082/0.390/0.557 ms
```

### Docker Compose and Buildx showing runc error

#### Version v0.5.6 or lower

Recent versions of Buildkit may show the following error.

```console
runc run failed: unable to start container process: error during container init: error mounting "cgroup" to rootfs at "/sys/fs/cgroup": mount cgroup:/sys/fs/cgroup/openrc (via /proc/self/fd/6), flags: 0xf, data: openrc: invalid argument
```

From v0.5.6, start Colima with `--cgroups-v2` flag as a workaround.

**This is fixed in v0.6.0.**

### Issue with Docker bind mount showing empty

When using docker to bind mount a volume (e.g. using `-v` or `--mount`) from the host where the volume is not contained within `/Users/$USER`, the container will start without raising any errors but the mapped mountpoint on the container will be empty.

This is rectified by mounting the volume on the VM, and only then can docker map the volume or any subdirectory. Edit `$HOME/.colima/default/colima.yaml` and add to the `mounts` section (examples are provided within the yaml file), and then run `colima restart`. Start the container again with the desired bind mount and it should show up correctly.

## How can Docker version be updated?

Each Colima release includes the latest Docker version at the time of release.

From v0.7.6, there is a new `colima update` command to update the container runtime without needing to update Colima or to wait for the next Colima release.

## How can I delete container data

From v0.9.0, Colima utilises a different disk for the container runtime data. This guards against accidental data loss after deletion and the container data should be reinstated on `colima start`.

To clear all data, `colima delete --data`  should be run instead. The `--data` flag ensures that the container data is also deleted.


================================================
FILE: docs/INSTALL.md
================================================
# Installation Options

## Homebrew

Stable Version

```
brew install colima
```

Development Version

```
brew install --HEAD colima
```

## MacPorts

Stable version

```
sudo port install colima
```

## Nix

Only stable Version

```
nix-env -i colima
```

Or using solely in a `nix-shell`

```
nix-shell -p colima
```

## Arch

Install dependencies
```
sudo pacman -S qemu-full go docker
```
Install Lima and Colima from Aur
```
yay -S lima-bin colima-bin
```


## Binary

Binaries are available with every release on the [releases page](https://github.com/abiosoft/colima/releases).

```sh
# download binary
curl -LO https://github.com/abiosoft/colima/releases/latest/download/colima-$(uname)-$(uname -m)

# install in $PATH
sudo install colima-$(uname)-$(uname -m) /usr/local/bin/colima
```

## Building from Source

Requires [Go](https://golang.org).

```sh
# clone repo and cd into it
git clone https://github.com/abiosoft/colima
cd colima
make
sudo make install
```


================================================
FILE: embedded/defaults/abort.yaml
================================================
# ============================================================================================ #
# To abort, delete the contents of this file including the comments and save as an empty file
# ============================================================================================ #


================================================
FILE: embedded/defaults/colima.yaml
================================================
# Number of CPUs to be allocated to the virtual machine.
# Default: 2
cpu: 2

# Size of the disk in GiB to be allocated to the virtual machine for container data.
# NOTE: value can only be increased after virtual machine has been created.
#
# Default: 100
disk: 100

# Size of the memory in GiB to be allocated to the virtual machine.
# Default: 2
memory: 2

# Architecture of the virtual machine (x86_64, aarch64, host).
#
# NOTE: value cannot be changed after virtual machine is created.
# Default: host
arch: host

# Container runtime to be used (docker, containerd).
#
# NOTE: value cannot be changed after virtual machine is created.
# Default: docker
runtime: docker

# AI model runner (docker, ramalama).
# Both require krunkit VM type for GPU access.
# docker: Uses Docker Model Runner.
# ramalama: Uses Ramalama.
#
# Default: docker
modelRunner: docker

# Set custom hostname for the virtual machine.
# Default: colima
#          colima-profile_name for other profiles
hostname: null

# Kubernetes configuration for the virtual machine.
kubernetes:
  # Enable kubernetes.
  # Default: false
  enabled: false

  # Kubernetes version to use.
  # This needs to exactly match a k3s version https://github.com/k3s-io/k3s/releases
  # Default: latest stable release
  version: v1.35.0+k3s1

  # Additional args to pass to k3s https://docs.k3s.io/cli/server
  # Default: traefik is disabled
  k3sArgs: [--disable=traefik]

  # Kubernetes port to listen on
  # A common port is 6443, though left unbound to ensure no port conflicts
  # Default: pick random unbound port
  port: 0

# Auto-activate on the Host for client access.
# Setting to true does the following on startup
#  - sets as active Docker context (for Docker runtime).
#  - sets as active Kubernetes context (if Kubernetes is enabled).
#  - sets as active Incus remote (for Incus runtime).
# Default: true
autoActivate: true

# Network configurations for the virtual machine.
network:
  # Assign reachable IP address to the virtual machine.
  # NOTE: this is currently macOS only and ignored on Linux.
  # Default: false
  address: false

  # Network mode for the virtual machine (shared, bridged).
  # NOTE: this is currently macOS only and ignored on Linux.
  # Default: shared
  mode: shared

  # Network interface to use for bridged mode.
  # This is only used when mode is set to bridged.
  # NOTE: this is currently macOS only and ignored on Linux.
  # Default: en0
  interface: en0

  # Use the assigned IP address as the preferred route for the VM.
  # Note: this only has an effect when `address` is set 
Download .txt
gitextract_xof0cru8/

├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yaml
│   │   └── feature_request.yaml
│   ├── dependabot.yaml
│   └── workflows/
│       ├── go.yml
│       ├── golang-ci.yml
│       └── integration.yml
├── .gitignore
├── .golangci.yml
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── app/
│   └── app.go
├── cli/
│   ├── chain.go
│   └── command.go
├── cmd/
│   ├── clone.go
│   ├── colima/
│   │   └── main.go
│   ├── completion.go
│   ├── daemon/
│   │   ├── cmd.go
│   │   ├── daemon.go
│   │   └── daemon_test.go
│   ├── delete.go
│   ├── kubernetes.go
│   ├── list.go
│   ├── model.go
│   ├── nerdctl.go
│   ├── prune.go
│   ├── restart.go
│   ├── root/
│   │   └── root.go
│   ├── ssh-config.go
│   ├── ssh.go
│   ├── start.go
│   ├── start_test.go
│   ├── status.go
│   ├── stop.go
│   ├── template.go
│   ├── update.go
│   ├── util.go
│   └── version.go
├── colima.nix
├── config/
│   ├── config.go
│   ├── configmanager/
│   │   └── configmanager.go
│   ├── files.go
│   └── profile.go
├── core/
│   └── core.go
├── daemon/
│   ├── daemon.go
│   └── process/
│       ├── inotify/
│       │   ├── events.go
│       │   ├── inotify.go
│       │   ├── volumes.go
│       │   ├── volumes_test.go
│       │   └── watch.go
│       ├── process.go
│       └── vmnet/
│           ├── deps.go
│           └── vmnet.go
├── default.nix
├── docs/
│   ├── CONTRIBUTE.md
│   ├── FAQ.md
│   └── INSTALL.md
├── embedded/
│   ├── defaults/
│   │   ├── abort.yaml
│   │   ├── colima.yaml
│   │   └── template.yaml
│   ├── embed.go
│   ├── images/
│   │   ├── images.txt
│   │   └── images_sha.sh
│   ├── k3s/
│   │   └── flannel.json
│   ├── network/
│   │   └── sudo.txt
│   └── sudoers.go
├── environment/
│   ├── container/
│   │   ├── containerd/
│   │   │   ├── buildkitd.toml
│   │   │   ├── config.toml
│   │   │   └── containerd.go
│   │   ├── docker/
│   │   │   ├── config.toml
│   │   │   ├── containerd.go
│   │   │   ├── context.go
│   │   │   ├── daemon.go
│   │   │   ├── docker.go
│   │   │   └── proxy.go
│   │   ├── incus/
│   │   │   ├── config.yaml
│   │   │   ├── incus.go
│   │   │   └── route.go
│   │   └── kubernetes/
│   │       ├── cni.go
│   │       ├── k3s.go
│   │       ├── kubeconfig.go
│   │       └── kubernetes.go
│   ├── container.go
│   ├── environment.go
│   ├── guest/
│   │   └── systemctl/
│   │       ├── systemctl.go
│   │       └── systemctl_test.go
│   ├── host/
│   │   └── host.go
│   ├── host.go
│   ├── vm/
│   │   └── lima/
│   │       ├── certs.go
│   │       ├── config.go
│   │       ├── daemon.go
│   │       ├── disk.go
│   │       ├── disk.sh
│   │       ├── dns.go
│   │       ├── file.go
│   │       ├── lima.go
│   │       ├── limaconfig/
│   │       │   └── config.go
│   │       ├── limautil/
│   │       │   ├── disk.go
│   │       │   ├── files.go
│   │       │   ├── image.go
│   │       │   ├── instance.go
│   │       │   ├── limautil.go
│   │       │   ├── network.go
│   │       │   └── ssh.go
│   │       ├── network.go
│   │       ├── shell.go
│   │       ├── yaml.go
│   │       └── yaml_test.go
│   └── vm.go
├── flake.nix
├── go.mod
├── go.sum
├── integration/
│   └── Dockerfile
├── model/
│   ├── docker.go
│   ├── ramalama.go
│   ├── runner.go
│   └── runner_test.go
├── scripts/
│   ├── build_vmnet.sh
│   └── integration.sh
├── shell.nix
├── store/
│   └── store.go
└── util/
    ├── debutil/
    │   └── debutil.go
    ├── downloader/
    │   ├── curl.go
    │   ├── download.go
    │   ├── errors.go
    │   ├── http.go
    │   ├── native.go
    │   └── sha.go
    ├── fsutil/
    │   └── fs.go
    ├── macos.go
    ├── macos_test.go
    ├── osutil/
    │   └── os.go
    ├── qemu.go
    ├── shautil/
    │   └── sha.go
    ├── template.go
    ├── terminal/
    │   ├── output.go
    │   └── terminal.go
    ├── util.go
    └── yamlutil/
        ├── yaml.go
        └── yaml_test.go
Download .txt
SYMBOL INDEX (790 symbols across 105 files)

FILE: app/app.go
  type App (line 30) | type App interface
  function New (line 46) | func New() (App, error) {
  type colimaApp (line 57) | type colimaApp struct
    method startWithRuntime (line 61) | func (c colimaApp) startWithRuntime(conf config.Config) ([]environment...
    method Start (line 102) | func (c colimaApp) Start(conf config.Config) error {
    method runProvisionScripts (line 163) | func (c colimaApp) runProvisionScripts(conf config.Config, mode string) {
    method Stop (line 178) | func (c colimaApp) Stop(force bool) error {
    method Delete (line 222) | func (c colimaApp) Delete(data, force bool) error {
    method SSH (line 302) | func (c colimaApp) SSH(args ...string) error {
    method getStatus (line 366) | func (c colimaApp) getStatus() (status statusInfo, err error) {
    method Status (line 412) | func (c colimaApp) Status(extended bool, jsonOutput bool) error {
    method Version (line 470) | func (c colimaApp) Version() error {
    method currentRuntime (line 503) | func (c colimaApp) currentRuntime(ctx context.Context) (string, error) {
    method setRuntime (line 516) | func (c colimaApp) setRuntime(runtime string) error {
    method setKubernetes (line 531) | func (c colimaApp) setKubernetes(conf config.Kubernetes) error {
    method currentContainerEnvironments (line 540) | func (c colimaApp) currentContainerEnvironments(ctx context.Context) (...
    method containerEnvironment (line 568) | func (c colimaApp) containerEnvironment(runtime string) (environment.C...
    method Runtime (line 580) | func (c colimaApp) Runtime() (string, error) {
    method Kubernetes (line 584) | func (c colimaApp) Kubernetes() (environment.Container, error) {
    method Active (line 588) | func (c colimaApp) Active() bool {
    method Update (line 592) | func (c *colimaApp) Update() error {
  type statusInfo (line 349) | type statusInfo struct
  function generateSSHConfig (line 627) | func generateSSHConfig(modifySSHConfig bool) error {

FILE: cli/chain.go
  type errNonFatal (line 16) | type errNonFatal struct
    method Error (line 21) | func (e errNonFatal) Error() string { return e.err.Error() }
  function ErrNonFatal (line 25) | func ErrNonFatal(err error) error {
  function New (line 30) | func New(name string) CommandChain {
  type cFunc (line 36) | type cFunc struct
  type CommandChain (line 43) | type CommandChain interface
  type namedCommandChain (line 52) | type namedCommandChain struct
    method Logger (line 57) | func (n *namedCommandChain) Logger(ctx context.Context) *log.Entry {
    method Init (line 69) | func (n *namedCommandChain) Init(ctx context.Context) *ActiveCommandCh...
  type ActiveCommandChain (line 76) | type ActiveCommandChain struct
    method Logger (line 85) | func (a *ActiveCommandChain) Logger() *log.Entry { return a.log }
    method Add (line 88) | func (a *ActiveCommandChain) Add(f func() error) {
    method Stage (line 93) | func (a *ActiveCommandChain) Stage(s string) {
    method Stagef (line 102) | func (a *ActiveCommandChain) Stagef(format string, s ...any) {
    method Exec (line 110) | func (a *ActiveCommandChain) Exec() error {
    method Retry (line 151) | func (a *ActiveCommandChain) Retry(stage string, interval time.Duratio...

FILE: cli/command.go
  function Command (line 21) | func Command(command string, args ...string) *exec.Cmd { return runner.C...
  function CommandInteractive (line 24) | func CommandInteractive(command string, args ...string) *exec.Cmd {
  type commandRunner (line 28) | type commandRunner interface
  type defaultCommandRunner (line 35) | type defaultCommandRunner struct
    method Command (line 37) | func (d defaultCommandRunner) Command(command string, args ...string) ...
    method CommandInteractive (line 47) | func (d defaultCommandRunner) CommandInteractive(command string, args ...
  function quotedArgs (line 58) | func quotedArgs(args []string) string {
  function Prompt (line 67) | func Prompt(question string) bool {

FILE: cmd/clone.go
  function init (line 77) | func init() {

FILE: cmd/colima/main.go
  function main (line 11) | func main() {

FILE: cmd/completion.go
  function completionCmd (line 11) | func completionCmd() *cobra.Command {
  function init (line 72) | func init() {

FILE: cmd/daemon/cmd.go
  function init (line 96) | func init() {

FILE: cmd/daemon/daemon.go
  function daemonize (line 24) | func daemonize() (ctx *godaemon.Context, child bool, err error) {
  function start (line 54) | func start(ctx context.Context, processes []process.Process) error {
  function stop (line 83) | func stop(ctx context.Context) error {
  function status (line 112) | func status() error {
  constant pidFileName (line 141) | pidFileName = "daemon.pid"
  constant logFileName (line 142) | logFileName = "daemon.log"
  function Info (line 145) | func Info() struct {
  function RunProcesses (line 162) | func RunProcesses(ctx context.Context, processes ...process.Process) err...

FILE: cmd/daemon/daemon_test.go
  function setDir (line 15) | func setDir(t *testing.T) {
  function getProcesses (line 22) | func getProcesses() []process.Process {
  function TestStart (line 36) | func TestStart(t *testing.T) {
  function TestRunProcesses (line 90) | func TestRunProcesses(t *testing.T) {
  type pinger (line 117) | type pinger struct
    method Alive (line 121) | func (p pinger) Alive(ctx context.Context) error {
    method Name (line 126) | func (pinger) Name() string { return "pinger" }
    method Start (line 129) | func (p *pinger) Start(ctx context.Context) error {
    method Dependencies (line 134) | func (p *pinger) Dependencies() ([]process.Dependency, bool) { return ...
    method run (line 136) | func (p *pinger) run(ctx context.Context, command string, args ...stri...

FILE: cmd/delete.go
  function init (line 27) | func init() {

FILE: cmd/kubernetes.go
  function init (line 131) | func init() {

FILE: cmd/list.go
  function init (line 79) | func init() {

FILE: cmd/model.go
  function init (line 221) | func init() {
  function getModelRunner (line 234) | func getModelRunner() (model.Runner, error) {

FILE: cmd/nerdctl.go
  constant nerdctlDefaultInstallPath (line 169) | nerdctlDefaultInstallPath = "/usr/local/bin/nerdctl"
  constant nerdctlScript (line 171) | nerdctlScript = `#!/usr/bin/env sh
  function init (line 176) | func init() {

FILE: cmd/prune.go
  function init (line 56) | func init() {

FILE: cmd/restart.go
  function init (line 49) | func init() {

FILE: cmd/root/root.go
  function Cmd (line 65) | func Cmd() *cobra.Command {
  function Execute (line 78) | func Execute() {
  function init (line 84) | func init() {
  function initLog (line 90) | func initLog() {

FILE: cmd/ssh-config.go
  function init (line 27) | func init() {

FILE: cmd/ssh.go
  function init (line 24) | func init() {

FILE: cmd/start.go
  constant defaultCPU (line 124) | defaultCPU               = 2
  constant defaultMemory (line 125) | defaultMemory            = 2
  constant defaultDisk (line 126) | defaultDisk              = 100
  constant defaultRootDisk (line 127) | defaultRootDisk          = 20
  constant defaultKubernetesVersion (line 128) | defaultKubernetesVersion = kubernetes.DefaultVersion
  constant defaultMountTypeQEMU (line 130) | defaultMountTypeQEMU = "sshfs"
  constant defaultMountTypeVZ (line 131) | defaultMountTypeVZ   = "virtiofs"
  function init (line 160) | func init() {
  function dnsHostsFromFlag (line 274) | func dnsHostsFromFlag(hosts []string) map[string]string {
  function mountsFromFlag (line 292) | func mountsFromFlag(mounts []string) []config.Mount {
  function setFlagDefaults (line 320) | func setFlagDefaults(cmd *cobra.Command) {
  function setConfigDefaults (line 370) | func setConfigDefaults(conf *config.Config) {
  function setFixedConfigs (line 396) | func setFixedConfigs(conf *config.Config) {
  function prepareConfig (line 436) | func prepareConfig(cmd *cobra.Command) {
  function editConfigFile (line 622) | func editConfigFile() (config.Config, error) {
  function start (line 658) | func start(app app.App, conf config.Config) error {
  function awaitForInterruption (line 668) | func awaitForInterruption(app app.App) error {

FILE: cmd/start_test.go
  function Test_mountsFromFlag (line 11) | func Test_mountsFromFlag(t *testing.T) {

FILE: cmd/status.go
  function init (line 24) | func init() {

FILE: cmd/stop.go
  function init (line 26) | func init() {

FILE: cmd/template.go
  function templateFile (line 70) | func templateFile() string { return filepath.Join(config.TemplatesDir(),...
  function templateFileOrDefault (line 72) | func templateFileOrDefault() (string, error) {
  function init (line 89) | func init() {

FILE: cmd/update.go
  function init (line 20) | func init() {

FILE: cmd/util.go
  function newApp (line 17) | func newApp() app.App {
  function waitForUserEdit (line 28) | func waitForUserEdit(editor string, content []byte) (string, error) {
  function launchEditor (line 58) | func launchEditor(editor string, file string) error {

FILE: cmd/version.go
  function init (line 41) | func init() {

FILE: config/config.go
  constant AppName (line 12) | AppName    = "colima"
  constant envProfile (line 13) | envProfile = "COLIMA_PROFILE"
  type VersionInfo (line 17) | type VersionInfo struct
  function AppVersion (line 22) | func AppVersion() VersionInfo { return VersionInfo{Version: appVersion, ...
  function EnvProfile (line 23) | func EnvProfile() string      { return osutil.EnvVar(envProfile).Val() }
  type Config (line 31) | type Config struct
    method MountsOrDefault (line 121) | func (c Config) MountsOrDefault() []Mount {
    method AutoActivate (line 134) | func (c Config) AutoActivate() bool {
    method Empty (line 142) | func (c Config) Empty() bool { return c.Runtime == "" }
    method DriverLabel (line 144) | func (c Config) DriverLabel() string {
  type Kubernetes (line 78) | type Kubernetes struct
  type Network (line 86) | type Network struct
  type Mount (line 98) | type Mount struct
  constant ProvisionModeAfterBoot (line 106) | ProvisionModeAfterBoot = "after-boot"
  constant ProvisionModeReady (line 107) | ProvisionModeReady     = "ready"
  type Provision (line 110) | type Provision struct
    method IsColimaMode (line 117) | func (p Provision) IsColimaMode() bool {
  type Disk (line 154) | type Disk
    method GiB (line 157) | func (d Disk) GiB() string { return fmt.Sprintf("%dGiB", d) }
    method Int (line 160) | func (d Disk) Int() int64 { return 1024 * 1024 * 1024 * int64(d) }
  function CtxKey (line 163) | func CtxKey() any {

FILE: config/configmanager/configmanager.go
  function Save (line 16) | func Save(c config.Config) error {
  function SaveFromFile (line 21) | func SaveFromFile(file string) error {
  function SaveToFile (line 30) | func SaveToFile(c config.Config, file string) error {
  function LoadFrom (line 35) | func LoadFrom(file string) (config.Config, error) {
  function ValidateConfig (line 51) | func ValidateConfig(c config.Config) error {
  function Load (line 107) | func Load() (c config.Config, err error) {
  function LoadInstance (line 117) | func LoadInstance() (config.Config, error) {
  function Teardown (line 122) | func Teardown() error {
  function validateGatewayAddress (line 132) | func validateGatewayAddress(gateway net.IP) error {

FILE: config/files.go
  type requiredDir (line 15) | type requiredDir struct
    method Dir (line 29) | func (r *requiredDir) Dir() string {
  function CacheDir (line 156) | func CacheDir() string { return cacheDir.Dir() }
  function TemplatesDir (line 159) | func TemplatesDir() string { return templatesDir.Dir() }
  function LimaDir (line 162) | func LimaDir() string { return limaDir.Dir() }
  constant configFileName (line 164) | configFileName = "colima.yaml"
  function SSHConfigFile (line 167) | func SSHConfigFile() string { return filepath.Join(configBaseDir.Dir(), ...

FILE: config/profile.go
  function SetProfile (line 13) | func SetProfile(profileName string) {
  function ProfileFromName (line 19) | func ProfileFromName(name string) *Profile {
  function CurrentProfile (line 42) | func CurrentProfile() *Profile { return profile }
  type Profile (line 45) | type Profile struct
    method ConfigDir (line 56) | func (p *Profile) ConfigDir() string {
    method LimaInstanceDir (line 68) | func (p *Profile) LimaInstanceDir() string {
    method File (line 73) | func (p *Profile) File() string {
    method LimaFile (line 78) | func (p *Profile) LimaFile() string {
    method StateFile (line 83) | func (p *Profile) StateFile() string {
    method StoreFile (line 87) | func (p *Profile) StoreFile() string {
  type ProfileInfo (line 94) | type ProfileInfo interface

FILE: core/core.go
  constant limaVersion (line 16) | limaVersion = "v0.18.0"
  function SetupBinfmt (line 24) | func SetupBinfmt(host hostActions, guest guestActions, arch environment....
  function LimaVersionSupported (line 46) | func LimaVersionSupported() error {

FILE: daemon/daemon.go
  type Manager (line 19) | type Manager interface
  type Status (line 26) | type Status struct
  type processStatus (line 32) | type processStatus struct
  function NewManager (line 39) | func NewManager(host environment.HostActions) Manager {
  function CtxKey (line 45) | func CtxKey(s string) any { return struct{ key string }{key: s} }
  type processManager (line 49) | type processManager struct
    method Dependency (line 53) | func (l processManager) Dependency(ctx context.Context, conf config.Co...
    method init (line 65) | func (l processManager) init() error {
    method Running (line 73) | func (l processManager) Running(ctx context.Context, conf config.Confi...
    method Start (line 93) | func (l processManager) Start(ctx context.Context, conf config.Config)...
    method Stop (line 126) | func (l processManager) Stop(ctx context.Context, conf config.Config) ...
  function processesFromConfig (line 133) | func processesFromConfig(conf config.Config) []process.Process {

FILE: daemon/process/inotify/events.go
  type modEvent (line 10) | type modEvent struct
    method Mode (line 15) | func (m modEvent) Mode() string { return fmt.Sprintf("%o", m.FileMode) }
  method handleEvents (line 17) | func (f *inotifyProcess) handleEvents(ctx context.Context, watcher dirWa...

FILE: daemon/process/inotify/inotify.go
  constant Name (line 14) | Name = "inotify"
  constant volumesInterval (line 15) | volumesInterval = 5 * time.Second
  type Args (line 17) | type Args struct
  function CtxKeyArgs (line 23) | func CtxKeyArgs() any { return struct{ name string }{name: "inotify_args...
  function New (line 26) | func New() process.Process {
  type inotifyProcess (line 34) | type inotifyProcess struct
    method Alive (line 43) | func (f *inotifyProcess) Alive(ctx context.Context) error {
    method Dependencies (line 54) | func (*inotifyProcess) Dependencies() (deps []process.Dependency, root...
    method Name (line 59) | func (*inotifyProcess) Name() string {
    method Start (line 64) | func (f *inotifyProcess) Start(ctx context.Context) error {
    method waitForLima (line 85) | func (f *inotifyProcess) waitForLima(ctx context.Context) {

FILE: daemon/process/inotify/volumes.go
  method monitorContainerVolumes (line 16) | func (f *inotifyProcess) monitorContainerVolumes(ctx context.Context, c ...
  method fetchVolumes (line 83) | func (f *inotifyProcess) fetchVolumes(cmdArgs ...string) ([]string, erro...
  function omitChildrenDirectories (line 152) | func omitChildrenDirectories(dirs []string) []string {

FILE: daemon/process/inotify/volumes_test.go
  function Test_omitChildrenDirectories (line 9) | func Test_omitChildrenDirectories(t *testing.T) {

FILE: daemon/process/inotify/watch.go
  type dirWatcher (line 13) | type dirWatcher interface
  type defaultWatcher (line 24) | type defaultWatcher struct
    method Watch (line 29) | func (d *defaultWatcher) Watch(ctx context.Context, dirs []string, mod...

FILE: daemon/process/process.go
  function CtxKeyDaemon (line 13) | func CtxKeyDaemon() any { return struct{ key string }{key: "colima_daemo...
  type Process (line 16) | type Process interface
  function Dir (line 31) | func Dir() string { return filepath.Join(config.CurrentProfile().ConfigD...
  type Dependency (line 34) | type Dependency interface
  function Dependencies (line 41) | func Dependencies(processes ...Process) (deps Dependency, root bool) {
  type processDeps (line 57) | type processDeps
    method Installed (line 59) | func (p processDeps) Installed() bool {
    method Install (line 72) | func (p processDeps) Install(host environment.HostActions) error {

FILE: daemon/process/vmnet/deps.go
  type sudoerFile (line 16) | type sudoerFile struct
    method Installed (line 19) | func (s sudoerFile) Installed() bool { return embedded.SudoersInstalle...
    method Install (line 22) | func (s sudoerFile) Install(host environment.HostActions) error {
  constant BinaryPath (line 28) | BinaryPath = "/opt/colima/bin/socket_vmnet"
  constant ClientBinaryPath (line 29) | ClientBinaryPath = "/opt/colima/bin/socket_vmnet_client"
  type vmnetFile (line 31) | type vmnetFile struct
    method Installed (line 34) | func (v vmnetFile) Installed() bool {
    method bins (line 43) | func (v vmnetFile) bins() []string {
    method Install (line 46) | func (v vmnetFile) Install(host environment.HostActions) error {
  type vmnetRunDir (line 86) | type vmnetRunDir struct
    method Install (line 89) | func (v vmnetRunDir) Install(host environment.HostActions) error {
    method Installed (line 94) | func (v vmnetRunDir) Installed() bool {
  constant optDir (line 99) | optDir = "/opt/colima"
  function runDir (line 102) | func runDir() string { return filepath.Join(optDir, "run") }

FILE: daemon/process/vmnet/vmnet.go
  constant Name (line 18) | Name = "vmnet"
  constant SubProcessEnvVar (line 21) | SubProcessEnvVar = "COLIMA_VMNET"
  constant NetGateway (line 23) | NetGateway = "192.168.106.1"
  constant NetDHCPEnd (line 24) | NetDHCPEnd = "192.168.106.254"
  function New (line 29) | func New(mode, netInterface string) process.Process {
  type vmnetProcess (line 36) | type vmnetProcess struct
    method Alive (line 41) | func (*vmnetProcess) Alive(ctx context.Context) error {
    method Name (line 68) | func (*vmnetProcess) Name() string { return Name }
    method Start (line 71) | func (v *vmnetProcess) Start(ctx context.Context) error {
    method Dependencies (line 127) | func (vmnetProcess) Dependencies() (deps []process.Dependency, root bo...
  function stop (line 135) | func stop(pidFile string) error {
  function forceDeleteFileIfExists (line 147) | func forceDeleteFileIfExists(name string) error {
  function Info (line 154) | func Info() struct {

FILE: embedded/embed.go
  function FS (line 11) | func FS() embed.FS { return fs }
  function read (line 13) | func read(file string) ([]byte, error) { return fs.ReadFile(file) }
  function Read (line 16) | func Read(file string) ([]byte, error) { return read(file) }
  function ReadString (line 19) | func ReadString(file string) (string, error) {

FILE: embedded/sudoers.go
  constant sudoersPath (line 14) | sudoersPath = "/etc/sudoers.d/colima"
  constant sudoersEmbeddedPath (line 15) | sudoersEmbeddedPath = "network/sudo.txt"
  type SudoersInstaller (line 19) | type SudoersInstaller interface
  function SudoersInstalled (line 25) | func SudoersInstalled() bool {
  function InstallSudoers (line 39) | func InstallSudoers(host SudoersInstaller) error {

FILE: environment/container.go
  function IsNoneRuntime (line 10) | func IsNoneRuntime(runtime string) bool { return runtime == "none" }
  type Container (line 13) | type Container interface
  function NewContainer (line 37) | func NewContainer(runtime string, host HostActions, guest GuestActions) ...
  type NewContainerFunc (line 46) | type NewContainerFunc
  type containerRuntimeFunc (line 50) | type containerRuntimeFunc struct
  function RegisterContainer (line 57) | func RegisterContainer(name string, f NewContainerFunc, hidden bool) {
  function ContainerRuntimes (line 65) | func ContainerRuntimes() (names []string) {
  type DataDisk (line 76) | type DataDisk struct
  type DiskDir (line 83) | type DiskDir struct

FILE: environment/container/containerd/containerd.go
  constant Name (line 18) | Name = "containerd"
  function HostSocketFiles (line 23) | func HostSocketFiles() (files struct {
  constant containerdConfFile (line 43) | containerdConfFile = "/etc/containerd/config.toml"
  constant buildKitConfFile (line 44) | buildKitConfFile = "/etc/buildkit/buildkitd.toml"
  function newRuntime (line 46) | func newRuntime(host environment.HostActions, guest environment.GuestAct...
  function init (line 55) | func init() {
  type containerdRuntime (line 61) | type containerdRuntime struct
    method Name (line 68) | func (c containerdRuntime) Name() string {
    method Provision (line 72) | func (c containerdRuntime) Provision(ctx context.Context) error {
    method provisionConfig (line 114) | func (c containerdRuntime) provisionConfig(profilePath, centralPath, g...
    method Start (line 137) | func (c containerdRuntime) Start(ctx context.Context) error {
    method Running (line 156) | func (c containerdRuntime) Running(ctx context.Context) bool {
    method Stop (line 160) | func (c containerdRuntime) Stop(ctx context.Context, force bool) error {
    method Teardown (line 168) | func (c containerdRuntime) Teardown(context.Context) error {
    method Dependencies (line 173) | func (c containerdRuntime) Dependencies() []string {
    method Version (line 178) | func (c containerdRuntime) Version(ctx context.Context) string {
    method Update (line 183) | func (c *containerdRuntime) Update(ctx context.Context) (bool, error) {
  function userConfigDir (line 95) | func userConfigDir() string {
  function DataDisk (line 188) | func DataDisk() environment.DataDisk {

FILE: environment/container/docker/containerd.go
  constant containerdConfFile (line 9) | containerdConfFile = "/etc/containerd/config.toml"
  constant containerdConfFileBackup (line 10) | containerdConfFileBackup = "/etc/containerd/config.colima.bak.toml"
  method provisionContainerd (line 15) | func (d dockerRuntime) provisionContainerd(ctx context.Context) error {

FILE: environment/container/docker/context.go
  function HostSocketFile (line 12) | func HostSocketFile() string { return filepath.Join(configDir(), "docker...
  function LegacyDefaultHostSocketFile (line 13) | func LegacyDefaultHostSocketFile() string {
  method contextCreated (line 17) | func (d dockerRuntime) contextCreated() bool {
  method setupContext (line 21) | func (d dockerRuntime) setupContext() error {
  method useContext (line 34) | func (d dockerRuntime) useContext() error {
  method teardownContext (line 38) | func (d dockerRuntime) teardownContext() error {

FILE: environment/container/docker/daemon.go
  constant daemonFile (line 10) | daemonFile = "/etc/docker/daemon.json"
  constant hostGatewayIPKey (line 11) | hostGatewayIPKey = "host-gateway-ip"
  function getHostGatewayIp (line 13) | func getHostGatewayIp(d dockerRuntime, conf map[string]any) (string, err...
  function resolveHostProxy (line 32) | func resolveHostProxy(hostProxy, hostGateway string) string {
  method createDaemonFile (line 55) | func (d dockerRuntime) createDaemonFile(conf map[string]any, env map[str...
  method addHostGateway (line 105) | func (d dockerRuntime) addHostGateway(conf map[string]any) error {
  method reloadAndRestartSystemdService (line 121) | func (d dockerRuntime) reloadAndRestartSystemdService() error {
  constant systemdUnitFilename (line 131) | systemdUnitFilename = "/etc/systemd/system/docker.service.d/docker.conf"
  constant systemdUnitFileContent (line 132) | systemdUnitFileContent string = `

FILE: environment/container/docker/docker.go
  constant Name (line 18) | Name = "docker"
  function init (line 22) | func init() {
  type dockerRuntime (line 26) | type dockerRuntime struct
    method Name (line 43) | func (d dockerRuntime) Name() string {
    method Provision (line 47) | func (d dockerRuntime) Provision(ctx context.Context) error {
    method Start (line 82) | func (d dockerRuntime) Start(ctx context.Context) error {
    method Running (line 107) | func (d dockerRuntime) Running(ctx context.Context) bool {
    method Stop (line 111) | func (d dockerRuntime) Stop(ctx context.Context, force bool) error {
    method Teardown (line 129) | func (d dockerRuntime) Teardown(ctx context.Context) error {
    method Dependencies (line 138) | func (d dockerRuntime) Dependencies() []string {
    method Version (line 142) | func (d dockerRuntime) Version(ctx context.Context) string {
    method Update (line 147) | func (d *dockerRuntime) Update(ctx context.Context) (bool, error) {
  function newRuntime (line 34) | func newRuntime(host environment.HostActions, guest environment.GuestAct...
  function DataDisk (line 158) | func DataDisk() environment.DataDisk {
  function DockerDir (line 178) | func DockerDir() string {

FILE: environment/container/docker/proxy.go
  type proxyVars (line 8) | type proxyVars struct
    method empty (line 14) | func (p proxyVars) empty() bool {
  type proxyVarKey (line 18) | type proxyVarKey
    method Keys (line 28) | func (p proxyVarKey) Keys() []string {
  method proxyEnvVars (line 32) | func (d dockerRuntime) proxyEnvVars(env map[string]string) proxyVars {

FILE: environment/container/incus/incus.go
  constant incusBridgeInterface (line 21) | incusBridgeInterface = "incusbr0"
  function newRuntime (line 23) | func newRuntime(host environment.HostActions, guest environment.GuestAct...
  function HostSocketFile (line 35) | func HostSocketFile() string { return filepath.Join(configDir(), "incus....
  constant Name (line 38) | Name = "incus"
  constant storageDriver (line 40) | storageDriver = "zfs"
  constant poolName (line 42) | poolName    = "default"
  constant poolMetaDir (line 43) | poolMetaDir = "/var/lib/incus/storage-pools/" + poolName
  constant poolDisksDir (line 45) | poolDisksDir = "/var/lib/incus/disks"
  constant poolDiskFile (line 46) | poolDiskFile = poolDisksDir + "/" + poolName + ".img"
  function init (line 49) | func init() {
  type incusRuntime (line 55) | type incusRuntime struct
    method Dependencies (line 63) | func (c *incusRuntime) Dependencies() []string {
    method Provision (line 68) | func (c *incusRuntime) Provision(ctx context.Context) error {
    method Running (line 144) | func (c *incusRuntime) Running(ctx context.Context) bool {
    method Start (line 149) | func (c *incusRuntime) Start(ctx context.Context) error {
    method Stop (line 212) | func (c *incusRuntime) Stop(ctx context.Context, force bool) error {
    method Teardown (line 230) | func (c *incusRuntime) Teardown(ctx context.Context) error {
    method Version (line 244) | func (c *incusRuntime) Version(ctx context.Context) string {
    method Name (line 249) | func (c incusRuntime) Name() string {
    method setRemote (line 253) | func (c incusRuntime) setRemote(activate bool) error {
    method unsetRemote (line 271) | func (c incusRuntime) unsetRemote() error {
    method hasRemote (line 287) | func (c incusRuntime) hasRemote(name string) bool {
    method fetchRemotes (line 297) | func (c incusRuntime) fetchRemotes() (remoteInfo, error) {
    method isDefaultRemote (line 311) | func (c incusRuntime) isDefaultRemote() bool {
    method addDockerRemote (line 316) | func (c incusRuntime) addDockerRemote() error {
    method findNetwork (line 325) | func (c incusRuntime) findNetwork(interfaceName string) (found bool, i...
    method Update (line 356) | func (c *incusRuntime) Update(ctx context.Context) (bool, error) {
    method poolImported (line 368) | func (c *incusRuntime) poolImported() bool {
    method recoverDisk (line 375) | func (c *incusRuntime) recoverDisk(ctx context.Context) error {
    method wipeDisk (line 415) | func (c *incusRuntime) wipeDisk(size int) error {
  type remoteInfo (line 346) | type remoteInfo
  type networkInfo (line 350) | type networkInfo struct
  function migrationScript (line 434) | func migrationScript() string {
  function DataDisk (line 452) | func DataDisk() environment.DataDisk {

FILE: environment/container/incus/route.go
  constant BridgeSubnet (line 13) | BridgeSubnet = "192.168.100.0/24"
  constant bridgeGateway (line 14) | bridgeGateway = "192.168.100.1/24"
  method addContainerRoute (line 18) | func (c *incusRuntime) addContainerRoute() error {
  method removeContainerRoute (line 48) | func (c *incusRuntime) removeContainerRoute() error {

FILE: environment/container/kubernetes/cni.go
  function installCniConfig (line 13) | func installCniConfig(guest environment.GuestActions, a *cli.ActiveComma...

FILE: environment/container/kubernetes/k3s.go
  constant listenPortKey (line 20) | listenPortKey = "k3s_listen_port"
  function hasK3sArg (line 22) | func hasK3sArg(k3sArgs []string, argName string) bool {
  function installK3s (line 37) | func installK3s(host environment.HostActions,
  function installK3sBinary (line 51) | func installK3sBinary(
  function installK3sCache (line 79) | func installK3sCache(
  function installK3sCluster (line 138) | func installK3sCluster(
  function getPortNumber (line 204) | func getPortNumber(guest environment.GuestActions, k3sListenPort int) (i...

FILE: environment/container/kubernetes/kubeconfig.go
  constant masterAddressKey (line 15) | masterAddressKey = "master_address"
  method provisionKubeconfig (line 17) | func (c kubernetesRuntime) provisionKubeconfig(ctx context.Context) error {
  method unsetKubeconfig (line 123) | func (c kubernetesRuntime) unsetKubeconfig(a *cli.ActiveCommandChain) {
  method teardownKubeconfig (line 143) | func (c kubernetesRuntime) teardownKubeconfig(a *cli.ActiveCommandChain) {

FILE: environment/container/kubernetes/kubernetes.go
  constant Name (line 21) | Name           = "kubernetes"
  constant DefaultVersion (line 22) | DefaultVersion = "v1.35.0+k3s1"
  constant ConfigKey (line 24) | ConfigKey = "kubernetes_config"
  function newRuntime (line 27) | func newRuntime(host environment.HostActions, guest environment.GuestAct...
  function init (line 36) | func init() {
  type kubernetesRuntime (line 42) | type kubernetesRuntime struct
    method Name (line 49) | func (c kubernetesRuntime) Name() string {
    method isInstalled (line 53) | func (c kubernetesRuntime) isInstalled() bool {
    method isVersionInstalled (line 58) | func (c kubernetesRuntime) isVersionInstalled(version string) bool {
    method Running (line 67) | func (c kubernetesRuntime) Running(context.Context) bool {
    method runtime (line 71) | func (c kubernetesRuntime) runtime() string {
    method config (line 75) | func (c kubernetesRuntime) config() config.Kubernetes {
    method setConfig (line 83) | func (c kubernetesRuntime) setConfig(conf config.Kubernetes) error {
    method Provision (line 92) | func (c *kubernetesRuntime) Provision(ctx context.Context) error {
    method Start (line 149) | func (c kubernetesRuntime) Start(ctx context.Context) error {
    method Stop (line 171) | func (c kubernetesRuntime) Stop(ctx context.Context, force bool) error {
    method deleteAllContainers (line 186) | func (c kubernetesRuntime) deleteAllContainers() error {
    method stopAllContainers (line 208) | func (c kubernetesRuntime) stopAllContainers() error {
    method runningContainerIDs (line 230) | func (c kubernetesRuntime) runningContainerIDs() string {
    method Teardown (line 249) | func (c kubernetesRuntime) Teardown(ctx context.Context) error {
    method Dependencies (line 267) | func (c kubernetesRuntime) Dependencies() []string {
    method Version (line 271) | func (c kubernetesRuntime) Version(context.Context) string {
    method Update (line 276) | func (c *kubernetesRuntime) Update(ctx context.Context) (bool, error) {

FILE: environment/environment.go
  type runActions (line 11) | type runActions interface
  type fileActions (line 25) | type fileActions interface
  type HostActions (line 32) | type HostActions interface
  type GuestActions (line 46) | type GuestActions interface
  type Dependencies (line 74) | type Dependencies interface

FILE: environment/guest/systemctl/systemctl.go
  type Runner (line 7) | type Runner interface
  type Systemctl (line 16) | type Systemctl struct
    method Start (line 26) | func (s Systemctl) Start(service string) error {
    method Restart (line 31) | func (s Systemctl) Restart(service string) error {
    method Stop (line 36) | func (s Systemctl) Stop(service string, force bool) error {
    method Active (line 45) | func (s Systemctl) Active(service string) bool {
    method DaemonReload (line 50) | func (s Systemctl) DaemonReload() error {
  function New (line 21) | func New(guest Runner) Systemctl {

FILE: environment/guest/systemctl/systemctl_test.go
  type mockGuest (line 9) | type mockGuest struct
    method Run (line 14) | func (m *mockGuest) Run(args ...string) error      { m.lastArgs = args...
    method RunQuiet (line 15) | func (m *mockGuest) RunQuiet(args ...string) error { m.lastArgs = args...
  function TestStart (line 17) | func TestStart(t *testing.T) {
  function TestRestart (line 28) | func TestRestart(t *testing.T) {
  function TestStop (line 39) | func TestStop(t *testing.T) {
  function TestActive (line 63) | func TestActive(t *testing.T) {
  function TestDaemonReload (line 91) | func TestDaemonReload(t *testing.T) {
  function assertArgs (line 103) | func assertArgs(t *testing.T, got, want []string) {

FILE: environment/host.go
  type Host (line 4) | type Host interface

FILE: environment/host/host.go
  function New (line 20) | func New() environment.Host {
  type hostEnv (line 26) | type hostEnv struct
    method clone (line 31) | func (h hostEnv) clone() hostEnv {
    method WithEnv (line 38) | func (h hostEnv) WithEnv(env ...string) environment.HostActions {
    method WithDir (line 45) | func (h hostEnv) WithDir(dir string) environment.HostActions {
    method Run (line 51) | func (h hostEnv) Run(args ...string) error {
    method RunQuiet (line 77) | func (h hostEnv) RunQuiet(args ...string) error {
    method RunOutput (line 99) | func (h hostEnv) RunOutput(args ...string) (string, error) {
    method RunInteractive (line 132) | func (h hostEnv) RunInteractive(args ...string) error {
    method RunWith (line 144) | func (h hostEnv) RunWith(stdin io.Reader, stdout io.Writer, args ...st...
    method Env (line 167) | func (h hostEnv) Env(s string) string {
    method Read (line 171) | func (h hostEnv) Read(fileName string) (string, error) {
    method Write (line 176) | func (h hostEnv) Write(fileName string, body []byte) error {
    method Stat (line 180) | func (h hostEnv) Stat(fileName string) (os.FileInfo, error) {
  function errCmd (line 122) | func errCmd(args []string, stderr bytes.Buffer, err error) error {
  function IsInstalled (line 185) | func IsInstalled(dependencies environment.Dependencies) error {

FILE: environment/vm.go
  type VM (line 11) | type VM interface
  constant ContainerRuntimeKey (line 21) | ContainerRuntimeKey = "runtime"
  type Arch (line 25) | type Arch
    method GoArch (line 38) | func (a Arch) GoArch() string {
    method Value (line 50) | func (a Arch) Value() Arch {
  constant X8664 (line 28) | X8664   Arch = "x86_64"
  constant AARCH64 (line 29) | AARCH64 Arch = "aarch64"
  function HostArch (line 33) | func HostArch() Arch {
  function DefaultVMType (line 66) | func DefaultVMType() string {

FILE: environment/vm/lima/certs.go
  method copyCerts (line 12) | func (l limaVM) copyCerts() error {

FILE: environment/vm/lima/config.go
  constant configFile (line 10) | configFile = "/etc/colima/colima.json"
  method getConf (line 12) | func (l limaVM) getConf() map[string]string {
  method Get (line 28) | func (l limaVM) Get(key string) string {
  method Set (line 36) | func (l limaVM) Set(key, value string) error {

FILE: environment/vm/lima/daemon.go
  method startDaemon (line 16) | func (l *limaVM) startDaemon(ctx context.Context, conf config.Config) (c...

FILE: environment/vm/lima/disk.go
  method createRuntimeDisk (line 27) | func (l *limaVM) createRuntimeDisk(conf config.Config) error {
  method useRuntimeDisk (line 61) | func (l *limaVM) useRuntimeDisk(conf config.Config) {
  function dataDisk (line 82) | func dataDisk(runtime string) environment.DataDisk {
  function diskMountScript (line 95) | func diskMountScript(format bool) string {
  method mountRuntimeDisk (line 112) | func (l *limaVM) mountRuntimeDisk(conf config.Config, format bool) {
  method downloadDiskImage (line 145) | func (l *limaVM) downloadDiskImage(ctx context.Context, conf config.Conf...
  method setDiskImage (line 186) | func (l *limaVM) setDiskImage() error {
  method syncDiskSize (line 200) | func (l *limaVM) syncDiskSize(ctx context.Context, conf config.Config) c...

FILE: environment/vm/lima/dns.go
  constant localhostAddr (line 12) | localhostAddr         = "127.0.0.1"
  constant defaultGatewayAddress (line 13) | defaultGatewayAddress = "192.168.5.2"
  function hasDnsmasq (line 16) | func hasDnsmasq(l *limaVM) bool {
  method setupDNS (line 21) | func (l *limaVM) setupDNS(conf config.Config) error {

FILE: environment/vm/lima/file.go
  method Read (line 16) | func (l limaVM) Read(fileName string) (string, error) {
  method Write (line 24) | func (l *limaVM) Write(fileName string, body []byte) error {
  method Stat (line 33) | func (l *limaVM) Stat(fileName string) (os.FileInfo, error) {
  type fileInfo (line 39) | type fileInfo struct
    method IsDir (line 78) | func (f fileInfo) IsDir() bool { return f.isDir }
    method ModTime (line 81) | func (f fileInfo) ModTime() time.Time { return f.modTime }
    method Mode (line 84) | func (f fileInfo) Mode() fs.FileMode { return f.mode }
    method Name (line 87) | func (f fileInfo) Name() string { return f.name }
    method Size (line 90) | func (f fileInfo) Size() int64 { return f.size }
    method Sys (line 93) | func (fileInfo) Sys() any { return nil }
  function newFileInfo (line 47) | func newFileInfo(guest environment.GuestActions, filename string) (fileI...
  function statError (line 73) | func statError(filename string, err error) error {

FILE: environment/vm/lima/lima.go
  function New (line 27) | func New(host environment.HostActions) environment.VM {
  constant envLimaInstance (line 48) | envLimaInstance = "LIMA_INSTANCE"
  constant lima (line 49) | lima            = "lima"
  constant limactl (line 50) | limactl         = limautil.LimactlCommand
  type limaVM (line 55) | type limaVM struct
    method Dependencies (line 72) | func (l limaVM) Dependencies() []string {
    method Start (line 78) | func (l *limaVM) Start(ctx context.Context, conf config.Config) error {
    method resume (line 134) | func (l *limaVM) resume(ctx context.Context, conf config.Config) error {
    method Running (line 182) | func (l limaVM) Running(_ context.Context) bool {
    method Stop (line 191) | func (l limaVM) Stop(ctx context.Context, force bool) error {
    method Teardown (line 226) | func (l limaVM) Teardown(ctx context.Context) error {
    method Restart (line 243) | func (l limaVM) Restart(ctx context.Context) error {
    method Host (line 262) | func (l limaVM) Host() environment.HostActions {
    method Env (line 266) | func (l limaVM) Env(s string) (string, error) {
    method Created (line 274) | func (l limaVM) Created() bool {
    method User (line 279) | func (l limaVM) User() (string, error) {
    method Arch (line 283) | func (l limaVM) Arch() environment.Arch {
    method addPostStartActions (line 288) | func (l *limaVM) addPostStartActions(a *cli.ActiveCommandChain, conf c...
    method assertQemu (line 367) | func (l *limaVM) assertQemu() error {
    method prepareHost (line 381) | func (l *limaVM) prepareHost(conf config.Config) {
  constant envLimaSSHPortForwarder (line 379) | envLimaSSHPortForwarder = "LIMA_SSH_PORT_FORWARDER"

FILE: environment/vm/lima/limaconfig/config.go
  type Config (line 12) | type Config struct
  type File (line 35) | type File struct
  type Mount (line 41) | type Mount struct
  type Disk (line 48) | type Disk struct
  type SSH (line 55) | type SSH struct
  type Containerd (line 61) | type Containerd struct
  type Firmware (line 66) | type Firmware struct
  constant TCP (line 79) | TCP Proto = "tcp"
  constant UDP (line 80) | UDP Proto = "udp"
  constant REVSSHFS (line 82) | REVSSHFS MountType = "reverse-sshfs"
  constant NINEP (line 83) | NINEP    MountType = "9p"
  constant VIRTIOFS (line 84) | VIRTIOFS MountType = "virtiofs"
  constant Krunkit (line 86) | Krunkit VMType = "krunkit"
  constant QEMU (line 87) | QEMU    VMType = "qemu"
  constant VZ (line 88) | VZ      VMType = "vz"
  type PortForward (line 91) | type PortForward struct
  type HostResolver (line 105) | type HostResolver struct
  type Network (line 111) | type Network struct
  constant ProvisionModeSystem (line 132) | ProvisionModeSystem     ProvisionMode = "system"
  constant ProvisionModeUser (line 133) | ProvisionModeUser       ProvisionMode = "user"
  constant ProvisionModeBoot (line 134) | ProvisionModeBoot       ProvisionMode = "boot"
  constant ProvisionModeDependency (line 135) | ProvisionModeDependency ProvisionMode = "dependency"
  type Provision (line 138) | type Provision struct
  type NineP (line 144) | type NineP struct
  type VMOpts (line 151) | type VMOpts struct
  type QEMUOpts (line 156) | type QEMUOpts struct
  type VZOpts (line 161) | type VZOpts struct
  type Rosetta (line 165) | type Rosetta struct

FILE: environment/vm/lima/limautil/disk.go
  function HasDisk (line 13) | func HasDisk() bool {
  function CreateDisk (line 37) | func CreateDisk(size int) error {
  function ResizeDisk (line 53) | func ResizeDisk(size int) error {
  function DeleteDisk (line 69) | func DeleteDisk() error {
  function MountPoint (line 85) | func MountPoint() string { return fmt.Sprintf("/mnt/lima-%s", config.Cur...
  function DiskProvisioned (line 88) | func DiskProvisioned(runtime string) bool {

FILE: environment/vm/lima/limautil/files.go
  constant colimaDiffDiskFile (line 9) | colimaDiffDiskFile = "diffdisk"
  function ColimaDiffDisk (line 12) | func ColimaDiffDisk(profileID string) string {
  constant networkFile (line 16) | networkFile = "networks.yaml"
  function NetworkFile (line 19) | func NetworkFile() string {
  function NetworkAssetsDirectory (line 24) | func NetworkAssetsDirectory() string {

FILE: environment/vm/lima/limautil/image.go
  function init (line 20) | func init() {
  function ImageCached (line 28) | func ImageCached(arch environment.Arch, runtime string) (limaconfig.File...
  function findImage (line 42) | func findImage(arch environment.Arch, runtime string) (f limaconfig.File...
  function Image (line 57) | func Image(arch environment.Arch, runtime string) (limaconfig.File, erro...
  function DownloadImage (line 62) | func DownloadImage(arch environment.Arch, runtime string) (f limaconfig....
  type diskImages (line 99) | type diskImages
  function loadImages (line 101) | func loadImages() error {
  function loadImagesFromBytes (line 110) | func loadImagesFromBytes(b []byte) error {
  function downloadImage (line 142) | func downloadImage(host environment.HostActions, file limaconfig.File) (...
  function qcow2ToRaw (line 158) | func qcow2ToRaw(host environment.Host, image diskImageFile) (string, err...
  type diskImageFile (line 174) | type diskImageFile
    method String (line 176) | func (d diskImageFile) String() string { return strings.TrimSuffix(str...
    method Raw (line 177) | func (d diskImageFile) Raw() string    { return d.String() + ".raw" }
    method Generated (line 178) | func (d diskImageFile) Generated() bool {
    method Location (line 184) | func (d diskImageFile) Location() string {

FILE: environment/vm/lima/limautil/instance.go
  function Instance (line 15) | func Instance() (InstanceInfo, error) {
  type InstanceInfo (line 20) | type InstanceInfo struct
    method Running (line 37) | func (i InstanceInfo) Running() bool { return i.Status == limaStatusRu...
    method Config (line 40) | func (i InstanceInfo) Config() (config.Config, error) {
  constant limaStatusRunning (line 46) | limaStatusRunning = "Running"
  function getInstance (line 49) | func getInstance(profileID string) (InstanceInfo, error) {
  function Instances (line 77) | func Instances(ids ...string) ([]InstanceInfo, error) {
  function RunningInstances (line 135) | func RunningInstances() ([]InstanceInfo, error) {
  function getRuntime (line 151) | func getRuntime(conf config.Config) string {

FILE: environment/vm/lima/limautil/limautil.go
  constant EnvLimaHome (line 12) | EnvLimaHome = "LIMA_HOME"
  constant EnvLimaDrivers (line 15) | EnvLimaDrivers = "LIMA_DRIVERS_PATH"
  constant LimactlCommand (line 18) | LimactlCommand = "limactl"
  function Limactl (line 21) | func Limactl(args ...string) *exec.Cmd {

FILE: environment/vm/lima/limautil/network.go
  constant NetInterface (line 10) | NetInterface = "col0"
  constant NetMetric (line 13) | NetMetric uint32 = 300
  constant NetMetricPreferred (line 14) | NetMetricPreferred uint32 = 100
  function IPAddress (line 21) | func IPAddress(profileID string) string {
  function InternalIPAddress (line 40) | func InternalIPAddress(profileID string) string {
  function getIPAddress (line 44) | func getIPAddress(profileID, interfaceName string) string {
  type LimaNetworkConfig (line 56) | type LimaNetworkConfig struct
  type LimaNetwork (line 62) | type LimaNetwork struct

FILE: environment/vm/lima/limautil/ssh.go
  function ShowSSH (line 16) | func ShowSSH(profileID string) (resp struct {
  function replaceSSHConfig (line 35) | func replaceSSHConfig(conf string, profileID string) string {
  constant sshConfigFile (line 53) | sshConfigFile = "ssh.config"
  type sshConfig (line 56) | type sshConfig
    method Contents (line 59) | func (s sshConfig) Contents() (string, error) {
    method File (line 69) | func (s sshConfig) File() string {

FILE: environment/vm/lima/network.go
  method writeNetworkFile (line 30) | func (l *limaVM) writeNetworkFile(conf config.Config) error {
  method replicateHostAddresses (line 61) | func (l *limaVM) replicateHostAddresses(conf config.Config) error {
  method removeHostAddresses (line 72) | func (l *limaVM) removeHostAddresses() {
  method removeIncusContainerRoute (line 83) | func (l *limaVM) removeIncusContainerRoute() {

FILE: environment/vm/lima/shell.go
  method Run (line 10) | func (l limaVM) Run(args ...string) error {
  method SSH (line 22) | func (l limaVM) SSH(workingDir string, args ...string) error {
  method RunInteractive (line 38) | func (l limaVM) RunInteractive(args ...string) error {
  method RunWith (line 50) | func (l limaVM) RunWith(stdin io.Reader, stdout io.Writer, args ...strin...
  method RunOutput (line 62) | func (l limaVM) RunOutput(args ...string) (out string, err error) {
  method RunQuiet (line 76) | func (l limaVM) RunQuiet(args ...string) (err error) {

FILE: environment/vm/lima/yaml.go
  function newConf (line 24) | func newConf(ctx context.Context, conf config.Config) (l limaconfig.Conf...
  function selectPath (line 424) | func selectPath(m config.Mount) (string, error) {
  function checkOverlappingMounts (line 432) | func checkOverlappingMounts(mounts []config.Mount) error {
  function ingressDisabled (line 452) | func ingressDisabled(disableFlags []string) bool {
  constant diskLabelMaxLength (line 475) | diskLabelMaxLength = 16
  function diskByLabelPath (line 477) | func diskByLabelPath(instanceId string) string {

FILE: environment/vm/lima/yaml_test.go
  function Test_checkOverlappingMounts (line 16) | func Test_checkOverlappingMounts(t *testing.T) {
  function Test_config_Mounts (line 48) | func Test_config_Mounts(t *testing.T) {
  function Test_ingressDisabled (line 105) | func Test_ingressDisabled(t *testing.T) {

FILE: model/docker.go
  type DockerModelInfo (line 17) | type DockerModelInfo struct
    method Hash (line 30) | func (m *DockerModelInfo) Hash() string {
  type ociManifest (line 38) | type ociManifest struct
  function findGGUFPath (line 48) | func findGGUFPath(guest environment.VM, modelHash string) (string, error) {
  function InspectDockerModel (line 98) | func InspectDockerModel(modelName string) (*DockerModelInfo, error) {
  function SetupOrUpdateDocker (line 114) | func SetupOrUpdateDocker() error {
  function GetDockerModelVersion (line 137) | func GetDockerModelVersion() string {
  function EnsureDockerModel (line 148) | func EnsureDockerModel(modelName string) (string, error) {
  type DockerModelServeConfig (line 173) | type DockerModelServeConfig struct
  function ServeDockerModel (line 184) | func ServeDockerModel(cfg DockerModelServeConfig) error {
  function ensureDockerModelRunner (line 266) | func ensureDockerModelRunner(guest environment.VM) error {
  function getDockerModelRunnerIP (line 282) | func getDockerModelRunnerIP(guest environment.VM) (string, error) {
  function startSocat (line 298) | func startSocat(guest environment.VM, port int, containerIP string) error {
  function stopSocat (line 305) | func stopSocat(guest environment.VM, port int) {
  function StopDockerModelServe (line 311) | func StopDockerModelServe(port int) error {
  function IsDockerModelServeRunning (line 328) | func IsDockerModelServeRunning(port int) bool {

FILE: model/ramalama.go
  constant ramalamaReleasesURL (line 16) | ramalamaReleasesURL = "https://api.github.com/repos/containers/ramalama/...
  function SetupOrUpdateRamalama (line 20) | func SetupOrUpdateRamalama() error {
  function GetRamalamaVersion (line 26) | func GetRamalamaVersion() string {
  function getLatestRamalamaVersion (line 41) | func getLatestRamalamaVersion() (string, error) {
  type ramalamaModel (line 66) | type ramalamaModel struct
  function listRamalamaModels (line 73) | func listRamalamaModels() ([]ramalamaModel, error) {
  function ramalamaModelExists (line 94) | func ramalamaModelExists(modelName string) bool {
  function normalizeRamalamaModelName (line 115) | func normalizeRamalamaModelName(name string) string {
  function EnsureRamalamaModel (line 128) | func EnsureRamalamaModel(modelName string) error {
  function ProvisionRamalama (line 148) | func ProvisionRamalama() error {

FILE: model/runner.go
  type RunnerType (line 24) | type RunnerType
  constant RunnerDocker (line 27) | RunnerDocker   RunnerType = "docker"
  constant RunnerRamalama (line 28) | RunnerRamalama RunnerType = "ramalama"
  type SetupStatus (line 32) | type SetupStatus struct
  type Runner (line 42) | type Runner interface
  function GetRunner (line 72) | func GetRunner(runnerType RunnerType) (Runner, error) {
  function validateCommonPrerequisites (line 84) | func validateCommonPrerequisites(a app.App) error {
  type dockerRunner (line 119) | type dockerRunner struct
    method Name (line 121) | func (d *dockerRunner) Name() RunnerType {
    method DisplayName (line 125) | func (d *dockerRunner) DisplayName() string {
    method ValidatePrerequisites (line 129) | func (d *dockerRunner) ValidatePrerequisites(a app.App) error {
    method EnsureProvisioned (line 133) | func (d *dockerRunner) EnsureProvisioned() error {
    method BuildArgs (line 138) | func (d *dockerRunner) BuildArgs(args []string) ([]string, error) {
    method EnsureModel (line 145) | func (d *dockerRunner) EnsureModel(modelName string) (string, error) {
    method Serve (line 150) | func (d *dockerRunner) Serve(modelName string, port int) error {
    method CheckSetup (line 283) | func (d *dockerRunner) CheckSetup() (SetupStatus, error) {
    method Setup (line 291) | func (d *dockerRunner) Setup() error {
    method GetCurrentVersion (line 295) | func (d *dockerRunner) GetCurrentVersion() string {
  type dockerModel (line 158) | type dockerModel struct
  function GetFirstModel (line 165) | func GetFirstModel() (string, error) {
  function listDockerModels (line 181) | func listDockerModels() ([]dockerModel, error) {
  function ResolveModelName (line 208) | func ResolveModelName(name string) (string, error) {
  function matchesModel (line 226) | func matchesModel(name, tag string) bool {
  function normalizeModelName (line 273) | func normalizeModelName(name string) string {
  type ramalamaRunner (line 309) | type ramalamaRunner struct
    method Name (line 311) | func (r *ramalamaRunner) Name() RunnerType {
    method DisplayName (line 315) | func (r *ramalamaRunner) DisplayName() string {
    method ValidatePrerequisites (line 319) | func (r *ramalamaRunner) ValidatePrerequisites(a app.App) error {
    method EnsureProvisioned (line 323) | func (r *ramalamaRunner) EnsureProvisioned() error {
    method BuildArgs (line 340) | func (r *ramalamaRunner) BuildArgs(args []string) ([]string, error) {
    method EnsureModel (line 345) | func (r *ramalamaRunner) EnsureModel(modelName string) (string, error) {
    method Serve (line 353) | func (r *ramalamaRunner) Serve(modelName string, port int) error {
    method buildRamalamaArgs (line 365) | func (r *ramalamaRunner) buildRamalamaArgs(args []string) []string {
    method CheckSetup (line 381) | func (r *ramalamaRunner) CheckSetup() (SetupStatus, error) {
    method Setup (line 434) | func (r *ramalamaRunner) Setup() error {
    method GetCurrentVersion (line 438) | func (r *ramalamaRunner) GetCurrentVersion() string {

FILE: model/runner_test.go
  function TestNormalizeModelName (line 7) | func TestNormalizeModelName(t *testing.T) {
  function TestMatchesModel (line 55) | func TestMatchesModel(t *testing.T) {
  function TestResolveModelNameWithMockData (line 199) | func TestResolveModelNameWithMockData(t *testing.T) {

FILE: store/store.go
  type Store (line 13) | type Store struct
  function storeFile (line 22) | func storeFile() string { return config.CurrentProfile().StoreFile() }
  function Load (line 25) | func Load() (s Store, err error) {
  function save (line 39) | func save(s Store) error {
  function Set (line 53) | func Set(f func(*Store)) error {
  function Reset (line 69) | func Reset() error {

FILE: util/debutil/debutil.go
  type packages (line 13) | type packages
    method Upgradable (line 17) | func (p packages) Upgradable() string {
    method Install (line 27) | func (p packages) Install() string {
  function UpdateRuntime (line 31) | func UpdateRuntime(

FILE: util/downloader/curl.go
  constant DownloaderNative (line 15) | DownloaderNative = "native"
  constant DownloaderCurl (line 17) | DownloaderCurl = "curl"
  constant envDownloader (line 19) | envDownloader = "COLIMA_DOWNLOADER"
  function ValidateDownloader (line 24) | func ValidateDownloader(v string) (string, error) {
  type curlDownloader (line 36) | type curlDownloader struct
    method Download (line 39) | func (c *curlDownloader) Download(r Request, destPath string) error {

FILE: util/downloader/download.go
  type Request (line 23) | type Request struct
  type FileDownloader (line 29) | type FileDownloader interface
  function SetDownloader (line 38) | func SetDownloader(v string) {
  function init (line 46) | func init() {
  function DownloadToGuest (line 60) | func DownloadToGuest(host hostActions, guest guestActions, r Request, fi...
  function CopyToGuest (line 75) | func CopyToGuest(host hostActions, src, dest string) error {
  function Download (line 81) | func Download(host hostActions, r Request) (string, error) {
  type downloader (line 93) | type downloader struct
    method cacheDownloadingFileName (line 100) | func (d downloader) cacheDownloadingFileName(url string) string {
    method resumeInfoPath (line 104) | func (d downloader) resumeInfoPath(url string) string {
    method downloadFile (line 108) | func (d downloader) downloadFile(r Request) (err error) {
    method saveResumeInfo (line 138) | func (d downloader) saveResumeInfo(url, etag string, bytesWritten int6...
    method hasCache (line 144) | func (d downloader) hasCache(url string) bool {
  function CacheFilename (line 96) | func CacheFilename(url string) string {

FILE: util/downloader/errors.go
  type NetworkError (line 21) | type NetworkError struct
    method Error (line 27) | func (e *NetworkError) Error() string {
    method Unwrap (line 31) | func (e *NetworkError) Unwrap() error {
    method friendlyMessage (line 35) | func (e *NetworkError) friendlyMessage() string {
  type HTTPStatusError (line 65) | type HTTPStatusError struct
    method Error (line 71) | func (e *HTTPStatusError) Error() string {
    method Unwrap (line 88) | func (e *HTTPStatusError) Unwrap() error {
  type ResumeError (line 93) | type ResumeError struct
    method Error (line 98) | func (e *ResumeError) Error() string {
    method Unwrap (line 102) | func (e *ResumeError) Unwrap() error {
  type SHAValidationError (line 107) | type SHAValidationError struct
    method Error (line 114) | func (e *SHAValidationError) Error() string {
    method Unwrap (line 119) | func (e *SHAValidationError) Unwrap() error {

FILE: util/downloader/http.go
  type HTTPClient (line 20) | type HTTPClient struct
    method GetFinalURL (line 73) | func (h *HTTPClient) GetFinalURL(ctx context.Context, rawURL string) (...
    method Download (line 100) | func (h *HTTPClient) Download(ctx context.Context, opts DownloadOption...
    method Fetch (line 221) | func (h *HTTPClient) Fetch(ctx context.Context, url string) ([]byte, e...
    method createProgressBar (line 247) | func (h *HTTPClient) createProgressBar(totalBytes, startOffset int64) ...
  type DownloadOptions (line 26) | type DownloadOptions struct
  type DownloadResult (line 35) | type DownloadResult struct
  type ResumeInfo (line 43) | type ResumeInfo struct
  function NewHTTPClient (line 49) | func NewHTTPClient() *HTTPClient {
  function parseContentRangeTotal (line 284) | func parseContentRangeTotal(header string) int64 {
  function isTerminal (line 300) | func isTerminal() bool {

FILE: util/downloader/native.go
  type nativeDownloader (line 13) | type nativeDownloader struct
    method Download (line 16) | func (n *nativeDownloader) Download(r Request, destPath string) error {

FILE: util/downloader/sha.go
  type SHA (line 19) | type SHA struct
    method ValidateFile (line 27) | func (s SHA) ValidateFile(host hostActions, file string) error {
    method validateFile (line 32) | func (s SHA) validateFile(file string) error {
    method validateDownload (line 73) | func (s SHA) validateDownload(url string, filename string) error {
  function fetchSHAFromURL (line 98) | func fetchSHAFromURL(shaURL, targetFilename string) (string, error) {
  function parseSHAContent (line 123) | func parseSHAContent(data []byte, targetFilename string) (string, error) {

FILE: util/fsutil/fs.go
  function MkdirAll (line 13) | func MkdirAll(path string, perm os.FileMode) error { return FS.MkdirAll(...
  function Open (line 16) | func Open(name string) (fs.File, error) { return FS.Open(name) }
  type FileSystem (line 19) | type FileSystem interface
  type DefaultFS (line 28) | type DefaultFS struct
    method Open (line 31) | func (DefaultFS) Open(name string) (fs.File, error) { return os.Open(n...
    method MkdirAll (line 34) | func (DefaultFS) MkdirAll(path string, perm fs.FileMode) error { retur...
  type fakeFS (line 41) | type fakeFS struct
    method Open (line 44) | func (fakeFS) Open(name string) (fs.File, error) {
    method MkdirAll (line 51) | func (fakeFS) MkdirAll(path string, perm fs.FileMode) error { return n...

FILE: util/macos.go
  function MacOS (line 19) | func MacOS() bool {
  function MacOS13OrNewerOnArm (line 24) | func MacOS13OrNewerOnArm() bool {
  function MacOS13OrNewer (line 29) | func MacOS13OrNewer() bool { return minMacOSVersion("13.0.0") }
  function MacOS15OrNewer (line 32) | func MacOS15OrNewer() bool { return minMacOSVersion("15.0.0") }
  function MacOSNestedVirtualizationSupported (line 35) | func MacOSNestedVirtualizationSupported() bool {
  function minMacOSVersion (line 39) | func minMacOSVersion(version string) bool {
  function IsMxOrNewer (line 60) | func IsMxOrNewer(min int) bool {
  type chipTypeDetector (line 74) | type chipTypeDetector interface
  type systemProfilerChipDetector (line 80) | type systemProfilerChipDetector struct
    method GetChipType (line 82) | func (d systemProfilerChipDetector) GetChipType() (string, error) {
  function parseMNumber (line 117) | func parseMNumber(s string) (int, bool) {
  function RosettaRunning (line 133) | func RosettaRunning() bool {
  function macOSProductVersion (line 144) | func macOSProductVersion() (*semver.Version, error) {

FILE: util/macos_test.go
  type fakeDetector (line 8) | type fakeDetector struct
    method GetChipType (line 13) | func (f fakeDetector) GetChipType() (string, error) { return f.v, f.e }
  function TestParseMNumber (line 15) | func TestParseMNumber(t *testing.T) {
  function TestIsMxOrNewer (line 39) | func TestIsMxOrNewer(t *testing.T) {

FILE: util/osutil/os.go
  type EnvVar (line 15) | type EnvVar
    method Exists (line 18) | func (e EnvVar) Exists() bool {
    method Bool (line 24) | func (e EnvVar) Bool() bool {
    method Val (line 30) | func (e EnvVar) Val() string {
    method ValOr (line 35) | func (e EnvVar) ValOr(val string) string {
    method WithPath (line 43) | func (e EnvVar) WithPath(p string) string {
  constant EnvColimaBinary (line 50) | EnvColimaBinary = "COLIMA_BINARY"
  function Executable (line 54) | func Executable() string {
  type Socket (line 89) | type Socket
    method Unix (line 92) | func (s Socket) Unix() string { return "unix://" + s.File() }
    method File (line 95) | func (s Socket) File() string { return strings.TrimPrefix(string(s), "...

FILE: util/qemu.go
  function AssertQemuImg (line 9) | func AssertQemuImg() error {
  function AssertKrunkit (line 19) | func AssertKrunkit() error {

FILE: util/shautil/sha.go
  type SHA (line 10) | type SHA interface
  type s1 (line 15) | type s1
    method String (line 17) | func (s s1) String() string { return fmt.Sprintf("%x", s[:]) }
    method Bytes (line 18) | func (s s1) Bytes() []byte  { return s[:] }
  type s256 (line 20) | type s256
    method String (line 22) | func (s s256) String() string { return fmt.Sprintf("%x", s[:]) }
    method Bytes (line 23) | func (s s256) Bytes() []byte  { return s[:] }
  function SHA256 (line 26) | func SHA256(s string) SHA {
  function SHA1 (line 31) | func SHA1(s string) SHA {

FILE: util/template.go
  function WriteTemplate (line 11) | func WriteTemplate(body string, file string, values any) error {
  function ParseTemplate (line 20) | func ParseTemplate(body string, values any) ([]byte, error) {

FILE: util/terminal/output.go
  type verboseWriter (line 19) | type verboseWriter struct
    method Write (line 39) | func (v *verboseWriter) Write(p []byte) (n int, err error) {
    method printLineVerbose (line 62) | func (v *verboseWriter) printLineVerbose() {
    method refresh (line 68) | func (v *verboseWriter) refresh() error {
    method addLine (line 74) | func (v *verboseWriter) addLine() {
    method Close (line 89) | func (v *verboseWriter) Close() error {
    method sanitizeLine (line 103) | func (v *verboseWriter) sanitizeLine(line string) string {
    method printScreen (line 115) | func (v *verboseWriter) printScreen() error {
    method clearScreen (line 135) | func (v *verboseWriter) clearScreen() {
    method updateTerm (line 141) | func (v *verboseWriter) updateTerm() error {
  function NewVerboseWriter (line 35) | func NewVerboseWriter(lineHeight int) io.WriteCloser {

FILE: util/terminal/terminal.go
  function IsTerminal (line 15) | func IsTerminal() bool {
  function ClearLine (line 20) | func ClearLine() {
  function EnterAltScreen (line 31) | func EnterAltScreen() {
  function ExitAltScreen (line 41) | func ExitAltScreen() {
  function WithAltScreen (line 55) | func WithAltScreen(fn func() error, header ...string) error {
  function countLines (line 127) | func countLines(s string, termWidth int) int {

FILE: util/util.go
  function HomeDir (line 16) | func HomeDir() string {
  function RandomAvailablePort (line 26) | func RandomAvailablePort() int {
  function isPortAvailable (line 40) | func isPortAvailable(port int) bool {
  function FindAvailablePort (line 54) | func FindAvailablePort(startPort, maxAttempts int) (int, bool) {
  function HostIPAddresses (line 65) | func HostIPAddresses() []net.IP {
  function SubnetAvailable (line 85) | func SubnetAvailable(subnet string) bool {
  function RouteExists (line 113) | func RouteExists(subnet string) bool {
  function ShellSplit (line 143) | func ShellSplit(cmd string) []string {
  function CleanPath (line 156) | func CleanPath(location string) (string, error) {

FILE: util/yamlutil/yaml.go
  function WriteYAML (line 17) | func WriteYAML(value any, file string) error {
  function Save (line 27) | func Save(c config.Config, file string) error {
  function encodeYAML (line 39) | func encodeYAML(conf config.Config) ([]byte, error) {
  function traverseConfig (line 112) | func traverseConfig(parentKey string, s any, vals map[string]any) {
  function traverseNode (line 140) | func traverseNode(parentKey string, node *yaml.Node, vals map[string]*ya...
  function encode (line 186) | func encode(v any) ([]byte, error) {

FILE: util/yamlutil/yaml_test.go
  function Test_encode_Docker (line 12) | func Test_encode_Docker(t *testing.T) {
Condensed preview — 143 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (487K chars).
[
  {
    "path": ".editorconfig",
    "chars": 25,
    "preview": "[*.go]\nindent_style = tab"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 81,
    "preview": "github: abiosoft\ncustom:\n  - \"https://buymeacoffee.com/abiosoft\"\npatreon: colima\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
    "chars": 1567,
    "preview": "name: Bug report\ndescription: Report a bug or issue\nbody:\n  - type: textarea\n    attributes:\n      label: Description\n  "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yaml",
    "chars": 127,
    "preview": "name: Feature request\ndescription: Request a missing feature\nbody:\n  - type: textarea\n    attributes:\n      label: Descr"
  },
  {
    "path": ".github/dependabot.yaml",
    "chars": 220,
    "preview": "version: 2\nupdates:\n- package-ecosystem: \"gomod\"\n  directory: \"/\"\n  schedule:\n    interval: \"daily\"\n  open-pull-requests"
  },
  {
    "path": ".github/workflows/go.yml",
    "chars": 3675,
    "preview": "name: Go\n\non:\n  push:\n    tags: [\"v*\"]\n    paths-ignore:\n      - \"**/*.md\"\n      - \"**/*.nix\"\n      - \"**/*.lock\"\n  pull"
  },
  {
    "path": ".github/workflows/golang-ci.yml",
    "chars": 730,
    "preview": "name: golangci-lint\non:\n  push:\n    tags: [v*]\n    branches: [main]\n    paths-ignore:\n      - \"**/*.md\"\n      - \"**/*.ni"
  },
  {
    "path": ".github/workflows/integration.yml",
    "chars": 8349,
    "preview": "name: Integration\n\non:\n  push:\n    tags: [\"v*\"]\n    branches: [main]\n    paths-ignore:\n      - \"**/*.md\"\n      - \"**/*.n"
  },
  {
    "path": ".gitignore",
    "chars": 53,
    "preview": ".idea/\n.fleet/\n.vscode/\n_output/\n_build/\nbin/\nresult\n"
  },
  {
    "path": ".golangci.yml",
    "chars": 47,
    "preview": "version: \"2\"\nlinters:\n  enable:\n    - gocritic\n"
  },
  {
    "path": "LICENSE",
    "chars": 1071,
    "preview": "MIT License\n\nCopyright (c) 2021 Abiola Ibrahim\n\nPermission is hereby granted, free of charge, to any person obtaining a "
  },
  {
    "path": "Makefile",
    "chars": 1928,
    "preview": "\nOS ?= $(shell uname)\nARCH ?= $(shell uname -m)\n\nGOOS ?= $(shell echo \"$(OS)\" | tr '[:upper:]' '[:lower:]')\nGOARCH_x86_6"
  },
  {
    "path": "README.md",
    "chars": 6847,
    "preview": "![colima-logo](colima.png)\n\n## Colima - container runtimes on macOS (and Linux) with minimal setup.\n\n[![Go](https://gith"
  },
  {
    "path": "SECURITY.md",
    "chars": 1199,
    "preview": "Thanks for helping make Colima safe for everyone.\n\n## Security\n\nWe take the security of Colima seriously.\n\nWe will ensur"
  },
  {
    "path": "app/app.go",
    "chars": 18369,
    "preview": "package app\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.c"
  },
  {
    "path": "cli/chain.go",
    "chars": 3622,
    "preview": "package cli\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// CtxKeyQuiet is the contex"
  },
  {
    "path": "cli/command.go",
    "chars": 1855,
    "preview": "package cli\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar runner commandRunner "
  },
  {
    "path": "cmd/clone.go",
    "chars": 2536,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/colima/cmd/"
  },
  {
    "path": "cmd/colima/main.go",
    "chars": 292,
    "preview": "package main\n\nimport (\n\t_ \"github.com/abiosoft/colima/cmd\"        // for other commands\n\t_ \"github.com/abiosoft/colima/c"
  },
  {
    "path": "cmd/completion.go",
    "chars": 1985,
    "preview": "package cmd\n\nimport (\n\t\"os\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\n// completionCmd repres"
  },
  {
    "path": "cmd/daemon/cmd.go",
    "chars": 2897,
    "preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft/colima/config\""
  },
  {
    "path": "cmd/daemon/daemon.go",
    "chars": 3663,
    "preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\""
  },
  {
    "path": "cmd/daemon/daemon_test.go",
    "chars": 2620,
    "preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/exec\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/daemon/process\"\n)\n"
  },
  {
    "path": "cmd/delete.go",
    "chars": 857,
    "preview": "package cmd\n\nimport (\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar deleteCmdArgs struct {\n\tfo"
  },
  {
    "path": "cmd/kubernetes.go",
    "chars": 3420,
    "preview": "package cmd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft/colima/config\"\n\t\"g"
  },
  {
    "path": "cmd/list.go",
    "chars": 1970,
    "preview": "package cmd\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"text/tabwriter\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abi"
  },
  {
    "path": "cmd/model.go",
    "chars": 6811,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft/colima/config/configmanager\"\n"
  },
  {
    "path": "cmd/nerdctl.go",
    "chars": 5612,
    "preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"gith"
  },
  {
    "path": "cmd/prune.go",
    "chars": 1582,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/"
  },
  {
    "path": "cmd/restart.go",
    "chars": 1183,
    "preview": "package cmd\n\nimport (\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft/colima/config/configmanager\""
  },
  {
    "path": "cmd/root/root.go",
    "chars": 2701,
    "preview": "package root\n\nimport (\n\t\"log\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/sirup"
  },
  {
    "path": "cmd/ssh-config.go",
    "chars": 674,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/a"
  },
  {
    "path": "cmd/ssh.go",
    "chars": 570,
    "preview": "package cmd\n\nimport (\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\n// sshCmd represents the ssh c"
  },
  {
    "path": "cmd/start.go",
    "chars": 23054,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/abio"
  },
  {
    "path": "cmd/start_test.go",
    "chars": 1305,
    "preview": "package cmd\n\nimport (\n\t\"reflect\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/abiosoft/colima/config\"\n)\n\nfunc Test_mountsFromFlag"
  },
  {
    "path": "cmd/status.go",
    "chars": 737,
    "preview": "package cmd\n\nimport (\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar statusCmdArgs struct {\n\tex"
  },
  {
    "path": "cmd/stop.go",
    "chars": 683,
    "preview": "package cmd\n\nimport (\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar stopCmdArgs struct {\n\tforc"
  },
  {
    "path": "cmd/template.go",
    "chars": 2586,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abiosoft"
  },
  {
    "path": "cmd/update.go",
    "chars": 491,
    "preview": "package cmd\n\nimport (\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/spf13/cobra\"\n)\n\n// statusCmd represents the st"
  },
  {
    "path": "cmd/util.go",
    "chars": 2674,
    "preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/app\"\n\t"
  },
  {
    "path": "cmd/version.go",
    "chars": 1066,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/app\"\n\t\"github.com/abiosoft/colima/cmd/root\"\n\t\"github.com/abio"
  },
  {
    "path": "colima.nix",
    "chars": 1009,
    "preview": "{ pkgs ? import <nixpkgs> }:\n\nwith pkgs;\n\nbuildGo123Module {\n  name = \"colima\";\n  pname = \"colima\";\n  src = ./.;\n  nativ"
  },
  {
    "path": "config/config.go",
    "chars": 4990,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/abiosoft/colima/util\"\n\t\"github.com/abiosoft/colima/util/osutil\"\n)\n\n"
  },
  {
    "path": "config/configmanager/configmanager.go",
    "chars": 3773,
    "preview": "package configmanager\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abioso"
  },
  {
    "path": "config/files.go",
    "chars": 3901,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\n\t\"github.com/abiosoft/colima/util\"\n\t\"github.com/abiosoft"
  },
  {
    "path": "config/profile.go",
    "chars": 2750,
    "preview": "package config\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nvar profile = &Profile{ID: AppName, DisplayName: AppName, ShortN"
  },
  {
    "path": "core/core.go",
    "chars": 2191,
    "preview": "package core\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/sirupsen/logrus\"\n\n\t\"github.com/abiosoft"
  },
  {
    "path": "daemon/daemon.go",
    "chars": 3881,
    "preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/colima/config\"\n\t\"git"
  },
  {
    "path": "daemon/process/inotify/events.go",
    "chars": 2414,
    "preview": "package inotify\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"time\"\n)\n\ntype modEvent struct {\n\tpath string // filename\n\tfs.File"
  },
  {
    "path": "daemon/process/inotify/inotify.go",
    "chars": 2297,
    "preview": "package inotify\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/daemon/process\"\n\t\"github.com/abiosoft/"
  },
  {
    "path": "daemon/process/inotify/volumes.go",
    "chars": 3880,
    "preview": "package inotify\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/"
  },
  {
    "path": "daemon/process/inotify/volumes_test.go",
    "chars": 1137,
    "preview": "package inotify\n\nimport (\n\t\"reflect\"\n\t\"strconv\"\n\t\"testing\"\n)\n\nfunc Test_omitChildrenDirectories(t *testing.T) {\n\ttests :"
  },
  {
    "path": "daemon/process/inotify/watch.go",
    "chars": 1941,
    "preview": "package inotify\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/abiosoft/colima/util\"\n\t\"github.com/rjeczalik/notify\"\n\t\"g"
  },
  {
    "path": "daemon/process/process.go",
    "chars": 2105,
    "preview": "package process\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/config\"\n\n\t\"github.com/abiosof"
  },
  {
    "path": "daemon/process/vmnet/deps.go",
    "chars": 2577,
    "preview": "package vmnet\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\n\t\"github.com/abiosoft/colima/daemon/process\"\n\t\"github."
  },
  {
    "path": "daemon/process/vmnet/vmnet.go",
    "chars": 3699,
    "preview": "package vmnet\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\""
  },
  {
    "path": "default.nix",
    "chars": 65,
    "preview": "with import <nixpkgs> { };\ncallPackage (import ./colima.nix) { }\n"
  },
  {
    "path": "docs/CONTRIBUTE.md",
    "chars": 2368,
    "preview": "# Contributing to Colima\n\nThank you for your interest in contributing to Colima!\n\n## Getting Started\n\nColima is a Go pro"
  },
  {
    "path": "docs/FAQ.md",
    "chars": 21664,
    "preview": "# FAQs\n\n- [FAQs](#faqs)\n  - [How does Colima compare to Lima?](#how-does-colima-compare-to-lima)\n  - [Are Apple Silicon "
  },
  {
    "path": "docs/INSTALL.md",
    "chars": 973,
    "preview": "# Installation Options\n\n## Homebrew\n\nStable Version\n\n```\nbrew install colima\n```\n\nDevelopment Version\n\n```\nbrew install "
  },
  {
    "path": "embedded/defaults/abort.yaml",
    "chars": 288,
    "preview": "# ============================================================================================ #\n# To abort, delete the "
  },
  {
    "path": "embedded/defaults/colima.yaml",
    "chars": 8287,
    "preview": "# Number of CPUs to be allocated to the virtual machine.\n# Default: 2\ncpu: 2\n\n# Size of the disk in GiB to be allocated "
  },
  {
    "path": "embedded/defaults/template.yaml",
    "chars": 67,
    "preview": "# New instances will be created with the following configurations.\n"
  },
  {
    "path": "embedded/embed.go",
    "chars": 476,
    "preview": "package embedded\n\nimport (\n\t\"embed\"\n)\n\n//go:embed network k3s defaults images\nvar fs embed.FS\n\n// FS returns the underly"
  },
  {
    "path": "embedded/images/images.txt",
    "chars": 2462,
    "preview": "arm64 none https://github.com/abiosoft/colima-core/releases/download/v0.10.1/ubuntu-24.04-minimal-cloudimg-arm64-none.qc"
  },
  {
    "path": "embedded/images/images_sha.sh",
    "chars": 550,
    "preview": "#!/usr/bin/env bash\n\nset -eux\n\nBASE_URL=https://github.com/abiosoft/colima-core/releases/download\nBASE_FILENAME=ubuntu-2"
  },
  {
    "path": "embedded/k3s/flannel.json",
    "chars": 413,
    "preview": "{\n    \"name\": \"cbr0\",\n    \"cniVersion\": \"0.3.1\",\n    \"plugins\": [\n        {\n            \"type\": \"flannel\",\n            \""
  },
  {
    "path": "embedded/network/sudo.txt",
    "chars": 793,
    "preview": "# starting vmnet daemon\n%staff ALL=(root:wheel) NOPASSWD:NOSETENV: /opt/colima/bin/socket_vmnet --vmnet-mode shared --so"
  },
  {
    "path": "embedded/sudoers.go",
    "chars": 1622,
    "preview": "package embedded\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n"
  },
  {
    "path": "environment/container/containerd/buildkitd.toml",
    "chars": 84,
    "preview": "[worker.oci]\nenabled = false\n\n[worker.containerd]\nenabled = true\n\n[grpc]\ngid = 1000\n"
  },
  {
    "path": "environment/container/containerd/config.toml",
    "chars": 18,
    "preview": "[grpc]\ngid = 1000\n"
  },
  {
    "path": "environment/container/containerd/containerd.go",
    "chars": 5910,
    "preview": "package containerd\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/c"
  },
  {
    "path": "environment/container/docker/config.toml",
    "chars": 46,
    "preview": "disabled_plugins = [\"cri\"]\n\n[grpc]\ngid = 1000\n"
  },
  {
    "path": "environment/container/docker/containerd.go",
    "chars": 1057,
    "preview": "package docker\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"fmt\"\n)\n\nconst containerdConfFile = \"/etc/containerd/config.toml\"\nconst "
  },
  {
    "path": "environment/container/docker/context.go",
    "chars": 1141,
    "preview": "package docker\n\nimport (\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/config\"\n)\n\nvar configDir = func() string { retur"
  },
  {
    "path": "environment/container/docker/daemon.go",
    "chars": 3711,
    "preview": "package docker\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n)\n\nconst daemonFile = \"/etc/docker/daemon.json\"\nconst"
  },
  {
    "path": "environment/container/docker/docker.go",
    "chars": 4388,
    "preview": "package docker\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abios"
  },
  {
    "path": "environment/container/docker/proxy.go",
    "chars": 939,
    "preview": "package docker\n\nimport (\n\t\"os\"\n\t\"strings\"\n)\n\ntype proxyVars struct {\n\thttp  string\n\thttps string\n\tno    string\n}\n\nfunc ("
  },
  {
    "path": "environment/container/incus/config.yaml",
    "chars": 578,
    "preview": "networks:\n  - config:\n      ipv4.address: {{.BridgeGateway}}\n      ipv4.nat: \"true\"\n      ipv6.address: auto\n    descrip"
  },
  {
    "path": "environment/container/incus/incus.go",
    "chars": 11739,
    "preview": "package incus\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com"
  },
  {
    "path": "environment/container/incus/route.go",
    "chars": 1544,
    "preview": "package incus\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abiosoft/colima/embedded\"\n\t\"github.com"
  },
  {
    "path": "environment/container/kubernetes/cni.go",
    "chars": 736,
    "preview": "package kubernetes\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft"
  },
  {
    "path": "environment/container/kubernetes/k3s.go",
    "chars": 6475,
    "preview": "package kubernetes\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abioso"
  },
  {
    "path": "environment/container/kubernetes/kubeconfig.go",
    "chars": 4038,
    "preview": "package kubernetes\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\""
  },
  {
    "path": "environment/container/kubernetes/kubernetes.go",
    "chars": 6642,
    "preview": "package kubernetes\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\""
  },
  {
    "path": "environment/container.go",
    "chars": 2728,
    "preview": "package environment\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n)\n\n// IsNoneRuntime returns if runtime is none.\nfunc IsNoneRuntim"
  },
  {
    "path": "environment/environment.go",
    "chars": 2422,
    "preview": "package environment\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/abiosoft/colima/config\"\n)\n\ntype runActions interface "
  },
  {
    "path": "environment/guest/systemctl/systemctl.go",
    "chars": 1615,
    "preview": "package systemctl\n\nimport \"github.com/abiosoft/colima/environment\"\n\n// Runner is the subset of environment.GuestActions "
  },
  {
    "path": "environment/guest/systemctl/systemctl_test.go",
    "chars": 2551,
    "preview": "package systemctl\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\n// mockGuest records args passed to Run/RunQuiet and controls whether th"
  },
  {
    "path": "environment/host/host.go",
    "chars": 4193,
    "preview": "package host\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/col"
  },
  {
    "path": "environment/host.go",
    "chars": 91,
    "preview": "package environment\n\n// Host is the host environment.\ntype Host interface {\n\tHostActions\n}\n"
  },
  {
    "path": "environment/vm/lima/certs.go",
    "chars": 1435,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/environment/container/docker\"\n\t\""
  },
  {
    "path": "environment/vm/lima/config.go",
    "chars": 1019,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n)\n\nconst configFile = \"/etc/colima/colima.jso"
  },
  {
    "path": "environment/vm/lima/daemon.go",
    "chars": 3913,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abiosoft/colima/daem"
  },
  {
    "path": "environment/vm/lima/disk.go",
    "chars": 6045,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/"
  },
  {
    "path": "environment/vm/lima/disk.sh",
    "chars": 903,
    "preview": "#!/usr/bin/env sh\n\n# Steps:\n# 1. Check if directory is already mounted, if yes, skip setup\n# 2. Idenify disk e.g. /dev/v"
  },
  {
    "path": "environment/vm/lima/dns.go",
    "chars": 2962,
    "preview": "package lima\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abiosoft/colima/environment/vm"
  },
  {
    "path": "environment/vm/lima/file.go",
    "chars": 2317,
    "preview": "package lima\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abios"
  },
  {
    "path": "environment/vm/lima/lima.go",
    "chars": 9085,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\""
  },
  {
    "path": "environment/vm/lima/limaconfig/config.go",
    "chars": 6819,
    "preview": "package limaconfig\n\nimport (\n\t\"net\"\n\n\t\"github.com/abiosoft/colima/environment\"\n)\n\ntype Arch = environment.Arch\n\n// Confi"
  },
  {
    "path": "environment/vm/lima/limautil/disk.go",
    "chars": 2144,
    "preview": "package limautil\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abiosoft/"
  },
  {
    "path": "environment/vm/lima/limautil/files.go",
    "chars": 692,
    "preview": "package limautil\n\nimport (\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/config\"\n)\n\nconst colimaDiffDiskFile = \"diffdis"
  },
  {
    "path": "environment/vm/lima/limautil/image.go",
    "chars": 4716,
    "preview": "package limautil\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/embedded\"\n\t\"git"
  },
  {
    "path": "environment/vm/lima/limautil/instance.go",
    "chars": 3937,
    "preview": "package limautil\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\""
  },
  {
    "path": "environment/vm/lima/limautil/limautil.go",
    "chars": 668,
    "preview": "package limautil\n\nimport (\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/colima/config\"\n)\n\n/"
  },
  {
    "path": "environment/vm/lima/limautil/network.go",
    "chars": 1598,
    "preview": "package limautil\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"strings\"\n)\n\n// network interface for shared network in the virtual machine."
  },
  {
    "path": "environment/vm/lima/limautil/ssh.go",
    "chars": 1718,
    "preview": "package limautil\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/conf"
  },
  {
    "path": "environment/vm/lima/network.go",
    "chars": 2671,
    "preview": "package lima\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/abiosoft/"
  },
  {
    "path": "environment/vm/lima/shell.go",
    "chars": 1640,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/abiosoft/colima/config\"\n)\n\nfunc (l limaVM) Run(args ...string) err"
  },
  {
    "path": "environment/vm/lima/yaml.go",
    "chars": 13813,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/daemon\"\n\t\"github.com/abio"
  },
  {
    "path": "environment/vm/lima/yaml_test.go",
    "chars": 3531,
    "preview": "package lima\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github"
  },
  {
    "path": "environment/vm.go",
    "chars": 1362,
    "preview": "package environment\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\n\t\"github.com/abiosoft/colima/util\"\n)\n\n// VM is virtual machine.\ntyp"
  },
  {
    "path": "flake.nix",
    "chars": 602,
    "preview": "{\n  description = \"Container runtimes on macOS (and Linux) with minimal setup\";\n\n  # Last revision with go_1_23\n  inputs"
  },
  {
    "path": "go.mod",
    "chars": 905,
    "preview": "module github.com/abiosoft/colima\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/coreos/go-semver v0.3.1\n\tgithub.com/docker/go-units "
  },
  {
    "path": "go.sum",
    "chars": 5145,
    "preview": "github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=\ngithub.com/chengxilo/virtualterm"
  },
  {
    "path": "integration/Dockerfile",
    "chars": 104,
    "preview": "# sample dockerfile to test image building\n# without pulling from docker hub\nFROM scratch\n\nCOPY . /files"
  },
  {
    "path": "model/docker.go",
    "chars": 11267,
    "preview": "package model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/environment\"\n\t\"github.c"
  },
  {
    "path": "model/ramalama.go",
    "chars": 5439,
    "preview": "package model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/abiosoft/colima/environment"
  },
  {
    "path": "model/runner.go",
    "chars": 12908,
    "preview": "package model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/app\"\n\t\"github.com/abiosoft/coli"
  },
  {
    "path": "model/runner_test.go",
    "chars": 6320,
    "preview": "package model\n\nimport (\n\t\"testing\"\n)\n\nfunc TestNormalizeModelName(t *testing.T) {\n\ttests := []struct {\n\t\tname     string"
  },
  {
    "path": "scripts/build_vmnet.sh",
    "chars": 1634,
    "preview": "#!/usr/bin/env sh\n\nset -ex\n\nexport DIR_BUILD=$PWD/_build/network\nexport DIR_VMNET=$DIR_BUILD/socket_vmnet\nexport EMBED_D"
  },
  {
    "path": "scripts/integration.sh",
    "chars": 1595,
    "preview": "#!/usr/bin/env bash\n\nset -ex\n\nalias colima=\"$COLIMA_BINARY\"\nDOCKER_CONTEXT=\"$(docker info -f '{{json .}}' | jq -r '.Clie"
  },
  {
    "path": "shell.nix",
    "chars": 510,
    "preview": "{ pkgs ? import <nixpkgs> { } }:\n\npkgs.mkShell {\n  # nativeBuildInputs is usually what you want -- tools you need to run"
  },
  {
    "path": "store/store.go",
    "chars": 1784,
    "preview": "package store\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"github.com/sirupsen/logrus"
  },
  {
    "path": "util/debutil/debutil.go",
    "chars": 1773,
    "preview": "package debutil\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/cli\"\n\t\"github.com/abiosoft/colima/e"
  },
  {
    "path": "util/downloader/curl.go",
    "chars": 1584,
    "preview": "package downloader\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/util/terminal\"\n)\n\n"
  },
  {
    "path": "util/downloader/download.go",
    "chars": 4188,
    "preview": "package downloader\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/co"
  },
  {
    "path": "util/downloader/errors.go",
    "chars": 3283,
    "preview": "package downloader\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"path\"\n\t\"syscall\"\n)\n\n// Sentinel errors for type checki"
  },
  {
    "path": "util/downloader/http.go",
    "chars": 8222,
    "preview": "package downloader\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.co"
  },
  {
    "path": "util/downloader/native.go",
    "chars": 1632,
    "preview": "package downloader\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"time\"\n)\n\n// nativeDownloader uses Go's n"
  },
  {
    "path": "util/downloader/sha.go",
    "chars": 3666,
    "preview": "package downloader\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"os\"\n\t"
  },
  {
    "path": "util/fsutil/fs.go",
    "chars": 1292,
    "preview": "package fsutil\n\nimport (\n\t\"io/fs\"\n\t\"os\"\n\t\"testing/fstest\"\n)\n\n// FS is the host filesystem implementation.\nvar FS FileSys"
  },
  {
    "path": "util/macos.go",
    "chars": 4093,
    "preview": "package util\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github."
  },
  {
    "path": "util/macos_test.go",
    "chars": 1716,
    "preview": "package util\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\ntype fakeDetector struct {\n\tv string\n\te error\n}\n\nfunc (f fakeDetector) GetCh"
  },
  {
    "path": "util/osutil/os.go",
    "chars": 2158,
    "preview": "package osutil\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/sirupsen/logrus\"\n)"
  },
  {
    "path": "util/qemu.go",
    "chars": 550,
    "preview": "package util\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n)\n\n// AssertQemuImg checks if qemu-img is available.\nfunc AssertQemuImg() error"
  },
  {
    "path": "util/shautil/sha.go",
    "chars": 637,
    "preview": "package shautil\n\nimport (\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n)\n\n// SHA is a sha computation\ntype SHA interface {\n\tSt"
  },
  {
    "path": "util/template.go",
    "chars": 743,
    "preview": "package util\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"text/template\"\n)\n\n// WriteTemplate writes template with body to file afte"
  },
  {
    "path": "util/terminal/output.go",
    "chars": 3187,
    "preview": "package terminal\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/fatih/color\"\n"
  },
  {
    "path": "util/terminal/terminal.go",
    "chars": 3222,
    "preview": "package terminal\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\n\t\"golang.org/x/term\"\n)\n\nvar isTerminal = term.IsTermina"
  },
  {
    "path": "util/util.go",
    "chars": 3991,
    "preview": "package util\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/google/shlex\"\n\t\"github.c"
  },
  {
    "path": "util/yamlutil/yaml.go",
    "chars": 4594,
    "preview": "package yamlutil\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/abiosoft/colima/config\"\n"
  },
  {
    "path": "util/yamlutil/yaml_test.go",
    "chars": 1064,
    "preview": "package yamlutil\n\nimport (\n\t\"net\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/abiosoft/colima/config\"\n\t\"gopkg.in/yaml.v3\"\n)\n\nfun"
  }
]

About this extraction

This page contains the full source code of the abiosoft/colima GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 143 files (429.4 KB), approximately 126.5k tokens, and a symbol index with 790 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!