Skip to content

Commit b163bd4

Browse files
authored
feat/ci VM builds (#60)
1 parent 66bb37a commit b163bd4

File tree

27 files changed

+738
-17
lines changed

27 files changed

+738
-17
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: build-vms-main
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.ref }}
8+
cancel-in-progress: true
9+
10+
jobs:
11+
build-vms-fast:
12+
name: Build NixOS VMs (fast)
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
host: [ virtmark ]
17+
uses: ./.github/workflows/vm-build.yml
18+
with:
19+
host: ${{ matrix.host }}
20+
format: vm
21+
secrets:
22+
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
23+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: build-vms-manual
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
host:
7+
description: NixOS host (flake nixosConfigurations)
8+
required: true
9+
default: virtmark
10+
type: choice
11+
options:
12+
- virtmark
13+
format:
14+
description: VM format to build
15+
required: true
16+
default: vm
17+
type: choice
18+
options:
19+
- vm
20+
- vmWithBootLoader
21+
- vmWithDisko
22+
- iso
23+
- qcow
24+
25+
jobs:
26+
build-vm:
27+
name: Build selected VM
28+
runs-on: ubuntu-latest
29+
permissions:
30+
contents: read
31+
id-token: write
32+
steps:
33+
- uses: actions/checkout@v4
34+
35+
- name: Install Nix
36+
uses: DeterminateSystems/nix-installer-action@main
37+
38+
- name: Enable binary cache
39+
uses: DeterminateSystems/magic-nix-cache-action@v8
40+
41+
- name: Set up Cachix (feltnerm)
42+
uses: cachix/cachix-action@v15
43+
with:
44+
name: feltnerm
45+
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
46+
skipPush: true
47+
48+
49+
- name: Show flake
50+
run: nix flake show
51+
52+
- name: Build VM
53+
run: |
54+
set -euxo pipefail
55+
HOST="${{ github.event.inputs.host }}"
56+
FORMAT="${{ github.event.inputs.format }}"
57+
case "$FORMAT" in
58+
vm|vmWithBootLoader|vmWithDisko)
59+
nix build .#nixosConfigurations."$HOST".config.system.build."$FORMAT"
60+
;;
61+
iso|qcow)
62+
nix build .#nixosConfigurations."$HOST".config.formats."$FORMAT"
63+
;;
64+
*)
65+
echo "Unsupported format: $FORMAT" >&2
66+
exit 1
67+
;;
68+
esac
69+

.github/workflows/build-vms-pr.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: build-vms-pr
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
types: [ opened, synchronize, reopened ]
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
9+
cancel-in-progress: true
10+
11+
jobs:
12+
build-vm-fast:
13+
name: Build NixOS VM (fast)
14+
uses: ./.github/workflows/vm-build.yml
15+
with:
16+
host: virtmark
17+
format: vm
18+
secrets:
19+
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
20+

.github/workflows/vm-build.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: vm-build
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
host:
7+
description: NixOS host (flake nixosConfigurations)
8+
required: true
9+
type: string
10+
format:
11+
description: VM format to build
12+
required: true
13+
type: string
14+
secrets:
15+
CACHIX_AUTH_TOKEN:
16+
required: false
17+
18+
jobs:
19+
build-vm:
20+
name: Build VM
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
id-token: write
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Install Nix
29+
uses: DeterminateSystems/nix-installer-action@main
30+
31+
- name: Enable binary cache
32+
uses: DeterminateSystems/magic-nix-cache-action@v8
33+
34+
- name: Set up Cachix (feltnerm)
35+
if: secrets.CACHIX_AUTH_TOKEN != ''
36+
uses: cachix/cachix-action@v15
37+
with:
38+
name: feltnerm
39+
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
40+
41+
- name: Show flake
42+
run: nix flake show
43+
44+
- name: Build VM
45+
run: |
46+
set -euxo pipefail
47+
HOST="${{ inputs.host }}"
48+
FORMAT="${{ inputs.format }}"
49+
case "$FORMAT" in
50+
vm|vmWithBootLoader|vmWithDisko)
51+
nix build .#nixosConfigurations."$HOST".config.system.build."$FORMAT"
52+
;;
53+
iso|qcow)
54+
nix build .#nixosConfigurations."$HOST".config.formats."$FORMAT"
55+
;;
56+
*)
57+
echo "Unsupported format: $FORMAT" >&2
58+
exit 1
59+
;;
60+
esac

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
result
2+
seed.iso

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# feltnerm nix-config
22

3+
[![Build VMs (main)](https://github.com/feltnerm/nix-config/actions/workflows/build-vms-main.yml/badge.svg)](https://github.com/feltnerm/nix-config/actions/workflows/build-vms-main.yml)
4+
35
Personal NixOS, nix-darwin, and Home Manager setup using flake-parts and a small `feltnerm` module to define hosts and users.
46

57
## Quick Start
@@ -45,9 +47,33 @@ nix build .#<pkg> && ./result/bin/<pkg>
4547

4648
## Extras
4749

48-
- VM images: `nixosConfigurations.<host>.config.formats.<format>`
49-
- Topology diagrams: build outputs under `flake.topology`
50-
- TODO Secrets: use ragenix/agenix (`age.secrets.*`, store files outside git)
50+
### VM Development
51+
- Devshell: `nix develop .#vm`
52+
- Build: `build-vm <host> <output>`
53+
- Examples: `build-vm virtmark vmWithBootLoader`, `build-vm virtmark-gui qcow`, `build-vm codemonkey iso`
54+
- Run: `run-vm ./result --memory 4096 --cpus 2`
55+
- Seed SSH keys: `seed-cloud-init mark ~/.ssh/id_ed25519.pub seed.iso`
56+
57+
Notes
58+
- Artifacts appear at `./result` (symlink)
59+
- SSH forwarding: `ssh -p 2222 mark@localhost`
60+
- Acceleration: macOS (HVF) and Linux (KVM) auto-enabled when available
61+
- Default user: `mark` (see `configs/nixos/*/user/mark.nix`)
62+
63+
Direct Nix builds (reference)
64+
- `nix build .#nixosConfigurations.<host>.config.system.build.vmWithBootLoader`
65+
- `nix build .#nixosConfigurations.<host>.config.system.build.vm`
66+
- `nix build .#nixosConfigurations.<host>.config.formats.{iso,qcow}`
67+
68+
Cloud-init (optional)
69+
- Quick helper: `scripts/cloud-init-seed.sh mark ~/.ssh/id_ed25519.pub seed.iso`
70+
- Manual:
71+
- Create `user-data` and `meta-data`, then `cloud-localds seed.iso user-data meta-data`
72+
- Boot with VM image + `seed.iso`, then `ssh -p 2222 mark@localhost`
73+
74+
Other
75+
- Topology: `flake.topology` outputs
76+
- Secrets: ragenix/agenix (`age.secrets.*`, store files outside git)
5177

5278
## Inspiration
5379

configs/home/mark/default.nix

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
inputs,
33
lib,
4-
config,
54
...
65
}:
76
{
@@ -13,7 +12,9 @@
1312
config = {
1413
feltnerm = {
1514
enable = true;
16-
theme = lib.mkDefault config.feltnerm.theme;
15+
# theme default now comes from flake-level feltnerm.theme via extraSpecialArgs
16+
# remove or override here only if you need per-home differences
17+
# theme = lib.mkDefault "catppuccin-mocha";
1718
developer = {
1819
enable = true;
1920
ai.enable = true;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
pkgs,
3+
...
4+
}:
5+
{
6+
imports = [
7+
./hardware.nix
8+
../../../modules/nixos/vm-base.nix
9+
];
10+
11+
config = {
12+
boot.loader.systemd-boot.enable = true;
13+
boot.loader.efi.canTouchEfiVariables = true;
14+
15+
system.stateVersion = "25.05";
16+
nixpkgs.hostPlatform = "x86_64-linux";
17+
18+
nix.settings.trusted-users = [ "mark" ];
19+
20+
networking.networkmanager.enable = true;
21+
networking.firewall.enable = false;
22+
23+
users.users.mark.shell = pkgs.zsh;
24+
25+
services.openssh.enable = true;
26+
27+
# Allow cloud-init to inject SSH keys/users on first boot
28+
services.cloud-init.enable = true;
29+
30+
# GUI setup: greetd + Hyprland
31+
services.greetd.enable = true;
32+
programs.hyprland.enable = true;
33+
programs.hyprlock.enable = true;
34+
security.pam.services.hyprlock = { };
35+
36+
environment.systemPackages = with pkgs; [
37+
kitty
38+
firefox
39+
];
40+
41+
services.qemuGuest.enable = true;
42+
};
43+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{ lib, modulesPath, ... }:
2+
{
3+
imports = [
4+
(modulesPath + "/profiles/qemu-guest.nix")
5+
];
6+
7+
config = {
8+
networking.hostId = "12345679";
9+
10+
boot.initrd.availableKernelModules = [
11+
"ata_piix"
12+
"uhci_hcd"
13+
"virtio_pci"
14+
"virtio_scsi"
15+
"sd_mod"
16+
"sr_mod"
17+
];
18+
boot.initrd.kernelModules = [ ];
19+
boot.kernelModules = [ ];
20+
boot.extraModulePackages = [ ];
21+
22+
fileSystems."/" = {
23+
device = "/dev/disk/by-label/nixos";
24+
fsType = "ext4";
25+
};
26+
27+
fileSystems."/boot" = {
28+
device = "/dev/disk/by-label/boot";
29+
fsType = "vfat";
30+
};
31+
32+
swapDevices = [
33+
{
34+
device = "/dev/disk/by-label/swap";
35+
}
36+
];
37+
38+
boot.kernel.sysctl = {
39+
"vm.swappiness" = lib.mkDefault 10;
40+
};
41+
};
42+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* home-manager GUI config for virtmark-gui
3+
*/
4+
_: {
5+
wayland.windowManager.hyprland.enable = true;
6+
programs.firefox.enable = true;
7+
stylix.targets.firefox.profileNames = [ "mark" ];
8+
programs.ghostty.enable = true;
9+
}

0 commit comments

Comments
 (0)