Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions .github/workflows/lima-guest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
with:
persist-credentials: false

- uses: ./.github/actions/setup-nix

- uses: lima-vm/lima-actions/setup@55627e31b78637bf254a8b2a14da8ea7d12564e5 # v1
id: lima-setup
with:
Expand All @@ -48,10 +50,18 @@ jobs:
restore-keys: |
lima-${{ steps.lima-setup.outputs.version }}-

- name: Create Lima Instance from standard template
- name: Generate homeless templates
run: |
nix build .#lima-custom-templates
# Remove potential read-only symlink from cache
rm -rf ~/.lima/_templates
mkdir -p ~/.lima/_templates
cp result/share/lima/templates/homeless-*.yaml ~/.lima/_templates/

- name: Create Lima Instance from custom template
run: |
limactl delete -f docker-nix || true
limactl create --yes --name=docker-nix template:docker
limactl delete -f homeless-docker-nix || true
limactl create --yes --name=homeless-docker-nix template:homeless-docker

test-provisioning:
needs: prepare-image
Expand All @@ -76,25 +86,25 @@ jobs:
restore-keys: |
lima-${{ steps.lima-setup.outputs.version }}-

- name: Start docker-nix
run: limactl start --name=docker-nix --tty=false
- name: Start homeless-docker-nix
run: limactl start --name=homeless-docker-nix --tty=false

- name: Install and configure Nix in Guest
env:
REV: ${{ github.head_ref || github.ref_name }}
run: |
# Use the same pipe-based command as in README, passing the current branch.
curl -fsSL "https://raw.githubusercontent.com/kachick/dotfiles/${REV}/scripts/install-nix.bash" | limactl shell docker-nix bash -s -- "${REV}"
curl -fsSL "https://raw.githubusercontent.com/kachick/dotfiles/${REV}/scripts/install-nix.bash" | limactl shell homeless-docker-nix bash -s -- "${REV}"

- name: Verify Nix installation in Guest
run: limactl shell docker-nix nix --version
run: limactl shell homeless-docker-nix nix --version

- name: Show Binary Cache effectiveness in Guest
env:
REV: ${{ github.head_ref || github.ref_name }}
run: |
FLAKE_URI="github:kachick/dotfiles/${REV}"
limactl shell docker-nix nix run --accept-flake-config "${FLAKE_URI}#la" -- --version
limactl shell homeless-docker-nix nix run --accept-flake-config "${FLAKE_URI}#la" -- --version

- name: Show Docker works in Guest
run: limactl shell docker-nix docker run --rm hello-world
run: limactl shell homeless-docker-nix docker run --rm hello-world
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,29 +194,29 @@ However I should keep the minimum environment for now.

## Lima

1. Start a standard Docker guest with Lima:
1. Start a custom Docker guest with Lima:

```bash
limactl start --name=docker-nix template:docker
limactl start --name=homeless-docker-nix template:homeless-docker
```

1. Install and configure Nix in the guest:

```bash
REV=main; \
curl -fsSL "https://raw.githubusercontent.com/kachick/dotfiles/$REV/scripts/install-nix.bash" | limactl shell docker-nix bash -s -- "$REV"
curl -fsSL "https://raw.githubusercontent.com/kachick/dotfiles/$REV/scripts/install-nix.bash" | limactl shell homeless-docker-nix bash -s -- "$REV"
```

1. Apply home-manager:

```bash
limactl shell docker-nix nix run --accept-flake-config "github:kachick/dotfiles#home-manager" -- switch -b backup --flake "github:kachick/dotfiles#user@lima"
limactl shell homeless-docker-nix nix run --accept-flake-config "github:kachick/dotfiles#home-manager" -- switch -b backup --flake "github:kachick/dotfiles#user@lima"
```

1. Run containers:

```bash
limactl shell docker-nix docker run --rm hello-world
limactl shell homeless-docker-nix docker run --rm hello-world
```

## How to setup secrets
Expand Down
5 changes: 4 additions & 1 deletion config/lima/_config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ mounts:
# TODO: Disable default mounting host home to keep secure even if it is not writable
# - location: '~' # Just comment out still respects template default. And setting mountPoint as false handles the false as string...
- location: '~/repos' # See git.nix in this repo
mountPoint: '{{.Home}}/repos' # Keep same behavior for ghq and the wrapped scripts
# Avoid hardcoding '{{.Home}}/repos' to ensure 'limactl shell' can
# synchronize the working directory by matching the host's absolute path.
# Also, consider and test compatibility with ghq and wrapped scripts (e.g., cdrepo).
# mountPoint: '{{.Home}}/repos'
writable: true # For developing purpose, writable should be reasonable. And my system does not directly include these files

# https://github.com/lima-vm/lima/issues/1015#issuecomment-4092839880
Expand Down
16 changes: 15 additions & 1 deletion home-manager/lima-guest.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
{ config, ... }:
{ config, lib, ... }:

{
# https://github.com/lima-vm/lima/blame/0d058b0eaa2d1bafc867298503a9239e89c202a8/templates/default.yaml#L295-L296
home.homeDirectory = "/home/${config.home.username}.linux";

# Restore access from the guest home to the host-path mounts.
# This allows 'limactl shell' to sync CWD (via absolute host paths) while keeping
# compatibility with tools expecting '~/repos' such as ghq and cdrepo.
home.activation.setupHostReposSymlink = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
for d in /home/*; do
# 1. Skip if it's the current guest home (e.g., /home/user.linux)
# 2. Check if 'repos' directory exists inside it (the host mount point)
if [ "$d" != "$HOME" ] && [ -d "$d/repos" ]; then
$DRY_RUN_CMD ln -sfn "$d/repos" "$HOME/repos"
break
fi
done
'';
}
5 changes: 5 additions & 0 deletions home-manager/lima-host.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ in
# See https://github.com/lima-vm/lima/blob/v1.0.1/templates/default.yaml#L536-L574 for detail
file.".lima/_config/default.yaml".source = ../config/lima/_config/default.yaml;

file.".lima/_templates" = {
source = "${pkgs.local.lima-custom-templates}/share/lima/templates";
recursive = true;
};

shellAliases = {
"lc" = "limactl";
};
Expand Down
101 changes: 101 additions & 0 deletions pkgs/local/lima-custom-templates/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
lib,
stdenvNoCC,
yq-go,
gnugrep,
writableTmpDirAsHomeHook,
pkgs,
}:

let
lima = pkgs.local.lima;
in
stdenvNoCC.mkDerivation {
pname = "lima-custom-templates";
version = lima.version;

dontUnpack = true;

nativeBuildInputs = [
# Use yq-go instead of `limactl template yq` because the latter fills in
# default values and resolves external references before evaluation,
# which would result in large, static YAML files rather than templates
# that inherit from bases.
yq-go
gnugrep
];

buildPhase = ''
runHook preBuild

for template_path in ${lima}/share/lima/templates/*.yaml; do
template_name=$(basename "$template_path")
# Skip default.yaml as it has a special configuration and isn't intended to be a standalone homeless template.
if [ "$template_name" = "default.yaml" ]; then
continue
fi
if yq '.base[] | select(. == "template:_default/mounts")' "$template_path" | grep -q .; then
yq 'del(.base[] | select(. == "template:_default/mounts"))' "$template_path" > "homeless-$template_name"
fi
done

runHook postBuild
'';

doCheck = true;

checkPhase = ''
runHook preCheck

# Verify that the deletion actually happened for a representative template.
if [ "$(yq -o=json -I=0 '.' ${lima}/share/lima/templates/docker.yaml)" = "$(yq -o=json -I=0 '.' homeless-docker.yaml)" ]; then
echo "Error: The template was not modified. The target string might not exist anymore." >&2
exit 1
fi

runHook postCheck
'';

installPhase = ''
runHook preInstall

mkdir -p $out/share/lima/templates
cp homeless-*.yaml $out/share/lima/templates/

runHook postInstall
'';

doInstallCheck = true;

nativeInstallCheckInputs = [
lima
# Workaround for: "panic: $HOME is not defined" in limactl
writableTmpDirAsHomeHook
];

installCheckPhase = ''
runHook preInstallCheck

for template in $out/share/lima/templates/*.yaml; do
limactl validate "$template"
done

runHook postInstallCheck
'';

preInstallCheck = ''
export USER=nix
'';

meta = {
description = "Custom Lima templates with the default home mount removed";
longDescription = ''
Most standard Lima templates (except for a few like k3s) inherit `template:_default/mounts`, which cannot be excluded via `default.yaml`.
To improve security, this package creates templates with those mounts removed by default.
While Lima 2.1+ supports avoiding default mounts via CLI flags such as `--mount-only` or `--mount-none`, it is safer to have them disabled by default in the template.
Revisit once https://github.com/lima-vm/lima/discussions/4372 is resolved.
'';
inherit (lima.meta) platforms;
maintainers = with lib.maintainers; [ kachick ];
};
}
Loading