nix-config/modules/microvm-host.nix

119 lines
3.8 KiB
Nix

{ self, config, lib, pkgs, ... }:
{
options = with lib; {
c3d2.deployment.microvmBaseZfsDataset = mkOption {
type = types.str;
description = "Base ZFS dataset whereunder to create shares for MicroVMs.";
};
};
config = {
# just all the microvms from this flake that are supposed to run on the server
microvm.autostart =
builtins.filter (name:
(self.nixosConfigurations.${name}.config.c3d2.deployment.server or null) == config.networking.hostName
) (builtins.attrNames self.nixosConfigurations);
systemd.services = {
"microvm-virtiofsd@" = {
requires = [ "microvm-zfs-datasets@%i.service" ];
};
"microvm-zfs-datasets@" = {
description = "Create ZFS datasets for MicroVM '%i'";
before = [ "microvm-virtiofsd@%i.service" ];
after = [ "local-fs.target" ];
partOf = [ "microvm@%i.service" ];
unitConfig.ConditionPathExists = "/var/lib/microvms/%i/current/share/microvm/virtiofs";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
WorkingDirectory = "/var/lib/microvms/%i";
SyslogIdentifier = "microvm-zfs-datasets@%i";
};
path = with pkgs; [ zfs ];
scriptArgs = "%i";
script = ''
zfsExists() {
zfs list $1 >/dev/null 2>/dev/null
}
NAME="$1"
BASE="${config.c3d2.deployment.microvmBaseZfsDataset}"
zfsExists $BASE || \
zfs create $BASE
zfsExists $BASE/$NAME || \
zfs create $BASE/$NAME
for d in current/share/microvm/virtiofs/*; do
SOURCE=$(cat $d/source)
TAG=$(basename $d)
MNT=$SOURCE
if [[ "$MNT" == /var/lib/microvms/$NAME/* ]]; then
zfsExists $BASE/$NAME/$TAG || \
zfs create -o mountpoint=$MNT $BASE/$NAME/$TAG
fi
done
'';
};
};
nix.settings = {
min-free = 128000000;
max-free = 1000000000;
# fetch github-prebuilt microvm-kernels
substituters = [ "https://microvm.cachix.org" ];
trusted-public-keys = [ "microvm.cachix.org-1:oXnBc6hRE3eX5rSYdRyMYXnfzcCxC7yKPTbZXALsqys=" ];
};
environment.systemPackages = [ (
# 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 /var/lib/microvms/$NAME
if [ "$(cat flake)" = "git+https://gitea.c3d2.de/c3d2/nix-config?ref=flake-update" ]; then
NEW=$(curl -sLH "Accept: application/json" https://hydra.hq.c3d2.de/job/c3d2/nix-config/$NAME/latest | ${pkgs.jq}/bin/jq -er .buildoutputs.out.path)
nix copy --from https://nix-serve.hq.c3d2.de $NEW
if [ -e booted ]; then
nix store diff-closures $(readlink booted) $NEW
elif [ -e current ]; then
echo "NOT BOOTED! Diffing to old current:"
nix store diff-closures $(readlink current) $NEW
else
echo "NOT BOOTED?"
fi
CHANGED=no
if ! [ -e current ]; then
ln -s $NEW current
CHANGED=yes
elif [ "$(readlink current)" != $NEW ]; then
rm -f old
cp --no-dereference current old
rm -f current
ln -s $NEW current
CHANGED=yes
fi
fi
if [ "$CHANGED" = "yes" ]; then
echo Run at your own peril:
echo systemctl restart microvm@$NAME
fi
echo
done
''
) ];
};
}