nix-config/modules/microvm-host.nix

131 lines
4.0 KiB
Nix

{ self, config, lib, options, pkgs, ... }:
{
options = with lib; {
c3d2.deployment.microvmBaseZfsDataset = mkOption {
type = types.str;
description = "Base ZFS dataset whereunder to create shares for MicroVMs.";
};
};
config = {
assertions = [
# {
# assertion = config.skyflake.storage.ceph.package != 17;
# message = "Please pin ceph to major version 17!";
# }
];
microvm = {
# just all the microvms from this flake that are supposed to run on the server
autostart =
builtins.filter (name:
(self.nixosConfigurations.${name}.config.c3d2.deployment.server or null) == config.networking.hostName
) (builtins.attrNames self.nixosConfigurations);
# don't enable microvm host options in live iso's
host.enable = if (options?isoImage) then false else true;
};
# allow microvm access to zvol
users.users.microvm.extraGroups = [ "disk" ];
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 = /* bash */ ''
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;
};
environment.systemPackages = [ (
# Provide a manual updating script that fetches the latest
# updated+built system from Hydra
pkgs.writeScriptBin "update-microvm" /* bash */ ''
#! ${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-cache.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
''
) ];
};
}