forked from c3d2/nix-config
119 lines
3.3 KiB
Nix
119 lines
3.3 KiB
Nix
{ zentralwerk, options, config, lib, pkgs, ... }:
|
|
let
|
|
inherit (config.c3d2.deployment) server;
|
|
serverFQDN = "${server}.cluster.zentralwerk.org";
|
|
serverConfig = zentralwerk.lib.config.site.hosts.${config.c3d2.deployment.server};
|
|
serverBridges = builtins.attrNames (
|
|
lib.filterAttrs (_: { type, ... }: type == "bridge")
|
|
serverConfig.interfaces
|
|
);
|
|
in
|
|
{
|
|
options.c3d2.deployment = with lib; {
|
|
server = mkOption {
|
|
type = types.enum [ "server10" ];
|
|
description = "Server that is supposed to host this MicroVM.";
|
|
};
|
|
|
|
interfaces = mkOption {
|
|
description = "Network interfaces";
|
|
type = types.listOf (types.submodule {
|
|
options = {
|
|
net = mkOption {
|
|
description = "Network to hook up to";
|
|
type = types.enum serverBridges;
|
|
};
|
|
mac = mkOption {
|
|
description = "Ethernet MAC address";
|
|
type = types.str;
|
|
};
|
|
};
|
|
});
|
|
};
|
|
|
|
mounts = mkOption {
|
|
description = "Persistent filesystems to create, without leading /.";
|
|
type = with types; listOf str;
|
|
default = [ "etc" ];
|
|
};
|
|
};
|
|
|
|
config.system.build = with pkgs; {
|
|
copyToServer = writeScript "copy-to-${server}" ''
|
|
#! ${runtimeShell} -e
|
|
|
|
nix copy --to ssh://root@${serverFQDN} $@
|
|
'';
|
|
|
|
runOnServer = writeScript "run-on-${server}" ''
|
|
#! ${runtimeShell} -e
|
|
|
|
ssh root@${serverFQDN} -- $@
|
|
'';
|
|
};
|
|
|
|
config = {
|
|
microvm = {
|
|
hypervisor = lib.mkDefault "cloud-hypervisor";
|
|
mem = lib.mkDefault 512;
|
|
|
|
interfaces = map ({ net, mac }: {
|
|
type = "tap";
|
|
id = builtins.substring 0 15 "${net}-${config.networking.hostName}";
|
|
inherit mac;
|
|
}) config.c3d2.deployment.interfaces;
|
|
|
|
shares = [ {
|
|
source = "/nix/store";
|
|
mountPoint = "/nix/.ro-store";
|
|
tag = "store";
|
|
proto = "virtiofs";
|
|
socket = "store.socket";
|
|
} ]
|
|
++ map (dir:
|
|
if lib.hasPrefix "/" dir
|
|
then throw "${dir} starts with a leading /. Just don't!"
|
|
else let
|
|
tag = builtins.replaceStrings ["/"] ["_"] dir;
|
|
in {
|
|
source = "/var/lib/microvms/${config.networking.hostName}/${dir}";
|
|
mountPoint = "/${dir}";
|
|
inherit tag;
|
|
proto = "virtiofs";
|
|
socket = "${tag}.socket";
|
|
}) config.c3d2.deployment.mounts;
|
|
};
|
|
|
|
systemd.services."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";
|
|
};
|
|
scriptArgs = "%i";
|
|
script = ''
|
|
zfsExists() {
|
|
zfs list $1 >/dev/null 2>/dev/null
|
|
}
|
|
|
|
NAME="$1"
|
|
BASE=$(hostname)/vm/$NAME
|
|
zfsExists $BASE || \
|
|
zfs create $BASE
|
|
for d in current/share/microvm/virtiofs/*; do
|
|
SOURCE=$(cat $d/source)
|
|
MNT=$(pwd)/$SOURCE
|
|
zfsExists $BASE/$d || \
|
|
zfs create -o mountpoint=$MNT $BASE/$d
|
|
done
|
|
'';
|
|
};
|
|
};
|
|
}
|