Skip to content

Commit

Permalink
refactor(nixosProfiles.vm): Flatten directory structure [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
Lehmanator committed Jan 28, 2025
1 parent f3f57b2 commit 1f9536f
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 88 deletions.
File renamed without changes.
File renamed without changes.
7 changes: 2 additions & 5 deletions nixos/profiles/vm/libvirt.nix → nixos/profiles/libvirt.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{user, ...}: let
root = true;
root = false;
in {
virtualisation.libvirtd = {
enable = true;
Expand All @@ -23,10 +23,7 @@ in {
};

programs.virt-manager.enable = true;
users.users.${user}.extraGroups =
if root
then ["qemu-libvirtd" "libvirtd"]
else ["libvirtd"];
users.users.${user}.extraGroups = ["libvirtd" "qemu-libvirtd"];

# --- QEMU / KVM ---
# --- User Session ---
Expand Down
63 changes: 37 additions & 26 deletions nixos/profiles/vm/microvm.nix → nixos/profiles/microvm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
user,
...
}: {
#
# https://github.com/astro/microvm.nix
#
imports = [
inputs.microvm.nixosModules.host
inputs.microvm.nixosModules.microvm
Expand All @@ -24,7 +22,7 @@
name = {
autostart = true;
flake = inputs.self; #flake = self;
pkgs = inputs.nixpkgs-unstable {system = "x86_64-linux";};
pkgs = inputs.nixos-stable {system = "x86_64-linux";};
restartIfChanged = true;
specialArgs = {inherit inputs pkgs user;};
updateFlake = "git+file:///etc/nixos"; # Specify from where to let `microvm -u` update later on
Expand All @@ -43,8 +41,9 @@
pivotRoot = "";
extraArgs = [];
};

# PCI / USB devices for host-to-vm passthrough
devices = [
# PCI / USB devices for host-to-vm passthrough
{
bus = "pci";
path = "0000:01:00.0";
Expand All @@ -58,9 +57,10 @@
path = "vendorid=0xabcd,productid=0x0123";
} # QEMU-only !
];

# TCP/UDP port forwarding (QEMU user-networking only)
# from=host|guest, proto=tcp|udp,
forwardPorts = [
# from=host|guest, proto=tcp|udp,
{
from = "host";
host.port = 10022;
Expand Down Expand Up @@ -89,38 +89,48 @@
guest.address = "10.0.2.10";
}
];
# Path of vhost-user socket.
graphics = {
enable = true;
socket = "${config.networking.hostName}-gpu.sock";
}; # Path of vhost-user socket.
};
hugepageMem = false; #
hypervisor = ""; # # Hypervisor to use by default in `microvm.declaredRunner`

# Hypervisor to use by default in `microvm.declaredRunner`
hypervisor = "";

# Network Interfaces
interfaces = [
# # Network Interfaces
{
id = "vm-${vm-name}"; # # Interface name on the host
bridge = ""; # # Attach network interface to host interface for type=macvlan
mac = "02:00:00:00:00:01"; # Eth MAC addr of MicroVM guest's network interface (not the host's)
type = "user"; # # user (qemu-only) | tap (tuntap) | macvtap (attach to host's physical net interface | bridge (attach qemu-created tap interface to a bridge)
macvtap = {
#
link = ""; # Attach network interface to host interface for type=macvlan
mode = ""; # MACVLAN mode to use. (private | vepa | bridge | passthru | source)
};
}
];
kernelParams = [""]; # `boot.kernelParams`, without ending up in `system.build.toplevel`, saving rebuilds

# `boot.kernelParams`, without ending up in `system.build.toplevel`, saving rebuilds
kernelParams = [""];
kernel = config.boot.kernelPackages.kernel;
initrdPath = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
mem = 512; # RAM allocation in MB.

# RAM allocation in MB.
mem = 512;

# Commands to run before starting the hypervisor
preStart = ''
''; # Commands to run before starting the hypervisor
'';
qemu.extraArgs = [""]; # Extra arguments to pass to QEMU.
runner = {};

# Shared filesystem directories (protos: virtiofs | 9p)
# Share directories from host (source/socket) -> VM (mountPoint)
# Pass logs from VM -> host
shares = [
# Shared filesystem directories (protos: virtiofs | 9p)
# Share directories from host (source/socket) -> VM (mountPoint)
# Pass logs from VM -> host
{
proto = "virtiofs";
tag = "journal";
Expand All @@ -146,21 +156,27 @@
mountPoint = "/home/${user}/Public";
}
];
socket = "${config.networking.hostName}.sock"; # Control socket for Hypervisor so MicroVM can be shutdown cleanly.
storeOnDisk = false; # Enables store on boot squashfs even in presence of share with host's /nix/store
# Control socket for Hypervisor so MicroVM can be shutdown cleanly.
socket = "${config.networking.hostName}.sock";

# Enables store on boot squashfs even in presence of share with host's /nix/store
storeOnDisk = false;

vcpu = 4; # Number of virtual CPU cores
vsock.cid = 0; # Virtual Machine address. Setting it enables `AF_VSOCK`. Reserved: 0=hypervisor, 1=loopback, 2=host
# Block device images
volumes = [
{
# Block device images
image = ""; # Path to disk image on the host
mountPoint = "/nix/.rw-store"; # Where to mount the volume inside the container.
size = 1024; # Volume size if created automatically
autoCreate = true; # Create image on host automatically before start?
fsType = "ext4"; # Filesystem for automatic creation & mounting.
}
];
writableStoreOverlay = "/nix/.rw-store"; # Optional string of the path where all writes to /nix/store should go to.

# Optional string of the path where all writes to /nix/store should go to.
writableStoreOverlay = "/nix/.rw-store";
};
};
};
Expand Down Expand Up @@ -188,26 +204,23 @@
hydraHost = "https://hydra.${config.networking.domain}";
binaryCacheHost = "https://nix-cache.${config.networking.domain}";
in [
# Provide a manual updating script that fetches the latest
# updated+built system from Hydra
(
# Provide a manual updating script that fetches the latest
# updated+built system from Hydra
pkgs.writeScriptBin "update-microvm" ''
#! ${pkgs.runtimeShell} -e
if [ $# -lt 1 ]; then
NAMES="$(ls -1 /var/lib/microvms)"
else
NAMES="$@"
fi
for NAME in $NAMES; do
echo MicroVM $NAME
cd ${config.microvms.stateDir}/$NAME
# Is this truly the flake that is being built on Hydra?
if [ "$(cat flake)" = "git+${git.host}/${git.owner}/${git.repo}?ref=${git.ref}" ]; then
NEW=$(curl -sLH "Accept: application/json" ${hydraHost}/job/${git.owner}/${git.repo}/$NAME/latest | ${pkgs.jq}/bin/jq -er .buildoutputs.out.path)
nix copy --from ${binaryCacheHost} $NEW
if [ -e booted ]; then
nix store diff-closures $(readlink booted) $NEW
elif [ -e current ]; then
Expand All @@ -216,7 +229,6 @@
else
echo "NOT BOOTED?"
fi
CHANGED=no
if ! [ -e current ]; then
ln -s $NEW current
Expand All @@ -229,7 +241,6 @@
CHANGED=yes
fi
fi
if [ "$CHANGED" = "yes" ]; then
systemctl restart microvm@$NAME
fi
Expand Down
41 changes: 34 additions & 7 deletions nixos/profiles/vm/qemu-web.nix → nixos/profiles/qemu-web.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{ inputs , config, lib, pkgs , ... }:
{
inputs,
config,
lib,
pkgs,
...
}: {
imports = [
(inputs.self + /nixos/profiles/qemu.nix)
];

# See: https://nixos.wiki/wiki/Libvirt
# QEMU web clients:
# - https://cgit.freedesktop.org/spice/spice-html5/
Expand All @@ -8,15 +17,15 @@
# Since libvirt doesn't support websockets on its own, we'll need to add websockify to your configuration.nix
services.networking.websockify = {
enable = false;
sslCert = "/https-cert.pem";
sslKey = "/https-key.pem";
sslCert = config.sops.secrets.websockify-ssl-cert.path;
sslKey = config.sops.secrets.websockify-ssl-key.path;
portMap = {
"5959" = 5900;
};
};
services.nginx = {
enable = config.services.networking.websockify.enable;
virtualHosts."qemu-web-client.fw.local" = {
virtualHosts."qemu-web-client.${config.networking.hostName}.local" = {
forceSSL = true;
root = "/var/www/";
locations."/spice/" = {
Expand All @@ -30,9 +39,27 @@
proxy_buffering off;
'';
};
sslCertificate = "/https-cert.pem";
sslCertificateKey = "/https-key.pem";
listen = [ { addr = "*"; port = 45000; ssl = true; } ];
sslCertificate = config.sops.secrets.websockify-ssl-cert.path;
sslCertificateKey = config.sops.secrets.websockify-ssl-key.path;
listen = [
{
addr = "*";
port = 45000;
ssl = true;
}
];
};
};

security.acme.certs = {
"websockify.${config.networking.domain}" = {
email = "[email protected]";
webroot = "/var/lib/acme/acme-challenge/";
};
};

sops.secrets = lib.mkIf config.services.networking.websockify.enable {
websockify-ssl-cert = {};
websockify-ssl-key = {};
};
}
21 changes: 21 additions & 0 deletions nixos/profiles/qemu.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
pkgs,
user,
...
}: {
environment.systemPackages = [pkgs.qemu-utils pkgs.quickemu];
users.extraGroups.qemu-libvirtd.members = [user];
# virtualisation.qemu = {
# guestAgent.enable = true;
# diskInterface = "virtio"; # virtio | scsi | ide
# networkingOptions = [
# "-net nic,netdev=user.0,model=virtio"
# "-netdev user,id=user.0,\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
# ];
# options = [ "-vga std" ];
# ovmf = {
# enable = true;
# packages = with pkgs; [ OVMFFull.fd pkgsCross.aarch64-multiplatform.OVMF.fd ];
# };
# };
}
9 changes: 7 additions & 2 deletions nixos/profiles/virt/default.nix → nixos/profiles/virt.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
{ inputs, config, lib, pkgs, ... }:
{
inputs,
config,
lib,
pkgs,
...
}: {
imports = [
(inputs.self + /nixos/profiles/appimage.nix)
(inputs.self + /nixos/profiles/containers)
(inputs.self + /nixos/profiles/vm)
(inputs.self + /nixos/profiles/vm.nix)
(inputs.self + /nixos/profiles/waydroid.nix)
(inputs.self + /nixos/profiles/wine.nix)
];
Expand Down
File renamed without changes.
39 changes: 24 additions & 15 deletions nixos/profiles/vm/host.nix → nixos/profiles/vm-host.nix
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
{ inputs, config, lib, pkgs, ... }:
{
inputs,
config,
lib,
pkgs,
...
}:
#let
# uuid = "6a1eb126-267f-11ee-a91c-075c79e9269a";
#in
{
# https://nixos.wiki/wiki/NixOps/Virtualization
imports = [
#./integration.nix
#./hyperv.nix
#./xen.nix
# ./integration.nix
# ./hyperv.nix
# ./xen.nix
];

# --- Hypervisors ---
# Hyper-V, Xen, KVM
# TODO: Configure Xen
#virtualisation.hypervGuest = {
# enable = true;
# videoMode = "1152x864";
#};
# virtualisation.hypervGuest = {
# enable = true;
# videoMode = "1152x864";
# };

# --- Guest Integration ---
environment.systemPackages = [
Expand All @@ -27,14 +33,17 @@
pkgs.spice
pkgs.spice-protocol
pkgs.spice-gtk

pkgs.python311Packages.guestfs
pkgs.python3Packages.guestfs
];
services.spice-vdagentd.enable = true; # Guest-only?
services.spice-webdavd.enable =
true; # Share files between host & guest via WebDAV
virtualisation.spiceUSBRedirection.enable =
true; # USB device access in guest VM

# Guest-only?
services.spice-vdagentd.enable = true;

# Share files between host & guest via WebDAV
services.spice-webdavd.enable = true;

# USB device access in guest VM
virtualisation.spiceUSBRedirection.enable = true;

#virtualisation.sharedDirectories = { # nixos-rebuild says this option doesnt exist
# windows = { source = "/mnt/share/windows"; target = "C:/host-share/windows"; };
Expand Down
10 changes: 10 additions & 0 deletions nixos/profiles/vm.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{inputs, ...}: {
imports = [
(inputs.self + /nixos/profiles/vm-host.nix)
(inputs.self + /nixos/profiles/libvirt.nix)
(inputs.self + /nixos/profiles/kvm.nix)
(inputs.self + /nixos/profiles/qemu.nix)
(inputs.self + /nixos/profiles/qemu-web.nix)
# (inputs.self + /nixos/profiles/vm-guest-windows.nix)
];
}
11 changes: 0 additions & 11 deletions nixos/profiles/vm/default.nix

This file was deleted.

Loading

0 comments on commit 1f9536f

Please sign in to comment.