This commit is contained in:
Jermeiah S 2025-07-10 01:25:45 -04:00
commit dc5069e9b2
No known key found for this signature in database
7 changed files with 323 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.img
*.qcow2

71
configuration.nix Normal file
View file

@ -0,0 +1,71 @@
{
config,
lib,
pkgs,
...
}:
let
indexHtml = pkgs.writeText "index.html" ''
hello mofo
'';
in
{
imports = [
./microvm.nix
./vm-variant.nix
];
networking = {
firewall.enable = false;
useDHCP = lib.mkForce true;
hostName = "demo";
};
services.avahi = {
enable = true;
nssmdns = true;
publish = {
enable = true;
addresses = true;
workstation = true;
};
};
# boot = {
# # loader.grub.device = "nodev";
# kernelParams = [ "console=ttyS0" ];
# };
users.users = {
root = {
password = "";
};
};
# Optional: Make sure DNS is configured
networking = {
nameservers = [
"9.9.9.9"
];
# Enable networking
# networkmanager.enable = true;
};
nix = {
settings.experimental-features = [
"nix-command"
"flakes"
];
};
services.nginx = {
enable = true;
virtualHosts."localhost" = {
root = "${pkgs.runCommand "nginx-root" { } ''
mkdir -p $out
cp ${indexHtml} $out/index.html
''}";
locations."/" = {
index = "index.html";
};
};
};
# users.mutableUsers = false;
system.stateVersion = "25.05";
}

99
flake.lock generated Normal file
View file

@ -0,0 +1,99 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"microvm": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"spectrum": "spectrum"
},
"locked": {
"lastModified": 1752095991,
"narHash": "sha256-+paXzPg6SN3O+YKtQKiU+kQE1EkfsrI1XEYTxI4DSFk=",
"owner": "astro",
"repo": "microvm.nix",
"rev": "f30b1412b73df264dc9cac154d340645add350ff",
"type": "github"
},
"original": {
"owner": "astro",
"repo": "microvm.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1751943650,
"narHash": "sha256-7orTnNqkGGru8Je6Un6mq1T8YVVU/O5kyW4+f9C1mZQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "88983d4b665fb491861005137ce2b11a9f89f203",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"microvm": "microvm",
"nixpkgs": "nixpkgs"
}
},
"spectrum": {
"flake": false,
"locked": {
"lastModified": 1751265943,
"narHash": "sha256-XoHSo6GEElzRUOYAEg/jlh5c8TDsyDESFIux3nU/NMc=",
"ref": "refs/heads/main",
"rev": "37c8663fab86fdb202fece339ef7ac7177ffc201",
"revCount": 904,
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
},
"original": {
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

41
flake.nix Normal file
View file

@ -0,0 +1,41 @@
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
microvm = {
url = "github:astro/microvm.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
microvm,
nixpkgs,
...
}:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
lib = nixpkgs.lib;
run-vm = pkgs.writeShellApplication {
name = "nix-vm";
runtimeInputs = with pkgs; [
jq
gum
];
text = builtins.readFile ./scripts/run-vm.sh;
};
in
{
nixosConfigurations.demo = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
microvm.nixosModules.microvm
./configuration.nix
];
};
apps.x86_64-linux.run-vm = {
type = "app";
program = "${lib.getExe run-vm}";
};
};
}

40
microvm.nix Normal file
View file

@ -0,0 +1,40 @@
_: {
microvm = {
interfaces = [
{
type = "user";
# interface name on the host
id = "vm-a1";
# Ethernet address of the MicroVM's interface, not the host's
#
# Locally administered have one of 2/6/A/E in the second nibble.
mac = "02:00:00:00:00:01";
}
];
volumes = [
{
mountPoint = "/var";
image = "var.img";
size = 256;
}
];
shares = [
{
# use proto = "virtiofs" for MicroVMs that are started by systemd
proto = "9p";
tag = "ro-store";
# a host's /nix/store will be picked up so that no
# squashfs/erofs will be built for it.
source = "/nix/store";
mountPoint = "/nix/.ro-store";
}
];
# "qemu" has 9p built-in!
hypervisor = "qemu";
socket = "control.socket";
};
}

38
scripts/run-vm.sh Normal file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
if ! command -v gum &> /dev/null; then
echo "gum (from charm.sh) is required but not found in PATH."
exit 1
fi
if ! command -v jq &> /dev/null; then
echo "jq is required but not found in PATH."
exit 1
fi
# List flake configs without evaluating them
HOSTS=()
while IFS= read -r line; do
HOSTS+=("$line")
done < <(nix flake show --json | jq -r '.nixosConfigurations | keys[]')
if [ ${#HOSTS[@]} -eq 0 ]; then
echo "No NixOS configurations found in flake."
exit 1
fi
# Prompt user for a config
SELECTED=$(printf "%s\n" "${HOSTS[@]}" | gum choose --header="Select a NixOS VM config:")
if [ -z "$SELECTED" ]; then
echo "No hostname selected. Exiting."
exit 1
fi
echo "Building VM for flake config: $SELECTED"
# Build the VM
nix run ".#nixosConfigurations.$SELECTED.config.system.build.vm"

32
vm-variant.nix Normal file
View file

@ -0,0 +1,32 @@
_: {
virtualisation.vmVariant = {
# virtualisation.diskImage = null;
# Boot with tmpfs as root
fileSystems."/" = {
fsType = "tmpfs";
options = [
"defaults"
"size=1024M"
];
};
virtualisation = {
forwardPorts = [
{
from = "host";
host.port = 8888;
guest.port = 80;
}
];
graphics = false; # disables graphical output
memorySize = 1024;
};
users.users = {
root = {
password = "";
};
};
};
}