1{ config, lib, pkgs, ... }:
2
3let
4 cfg = config.virtualisation.lxd.agent;
5
6 # the lxd agent is provided by the lxd daemon through a virtiofs or 9p mount
7 # this is a port of the distrobuilder lxd-agent generator
8 # https://github.com/lxc/distrobuilder/blob/f77300bf7d7d5707b08eaf8a434d647d1ba81b5d/generators/lxd-agent.go#L18-L55
9 preStartScript = ''
10 PREFIX="/run/lxd_agent"
11
12 mount_virtiofs() {
13 mount -t virtiofs config "$PREFIX/.mnt" >/dev/null 2>&1
14 }
15
16 mount_9p() {
17 modprobe 9pnet_virtio >/dev/null 2>&1 || true
18 mount -t 9p config "$PREFIX/.mnt" -o access=0,trans=virtio,size=1048576 >/dev/null 2>&1
19 }
20
21 fail() {
22 umount -l "$PREFIX" >/dev/null 2>&1 || true
23 rmdir "$PREFIX" >/dev/null 2>&1 || true
24 echo "$1"
25 exit 1
26 }
27
28 # Setup the mount target.
29 umount -l "$PREFIX" >/dev/null 2>&1 || true
30 mkdir -p "$PREFIX"
31 mount -t tmpfs tmpfs "$PREFIX" -o mode=0700,size=50M
32 mkdir -p "$PREFIX/.mnt"
33
34 # Try virtiofs first.
35 mount_virtiofs || mount_9p || fail "Couldn't mount virtiofs or 9p, failing."
36
37 # Copy the data.
38 cp -Ra "$PREFIX/.mnt/"* "$PREFIX"
39
40 # Unmount the temporary mount.
41 umount "$PREFIX/.mnt"
42 rmdir "$PREFIX/.mnt"
43
44 # Fix up permissions.
45 chown -R root:root "$PREFIX"
46 '';
47in {
48 meta.maintainers = with lib.maintainers; [ adamcstephens ];
49
50 options = {
51 virtualisation.lxd.agent.enable = lib.mkEnableOption (lib.mdDoc "Enable LXD agent");
52 };
53
54 config = lib.mkIf cfg.enable {
55 # https://github.com/lxc/distrobuilder/blob/f77300bf7d7d5707b08eaf8a434d647d1ba81b5d/generators/lxd-agent.go#L108-L125
56 systemd.services.lxd-agent = {
57 enable = true;
58 wantedBy = [ "multi-user.target" ];
59 path = [ pkgs.kmod pkgs.util-linux ];
60
61 preStart = preStartScript;
62
63 # avoid killing nixos-rebuild switch when executed through lxc exec
64 stopIfChanged = false;
65
66 unitConfig = {
67 Description = "LXD - agent";
68 Documentation = "https://documentation.ubuntu.com/lxd/en/latest";
69 ConditionPathExists = "/dev/virtio-ports/org.linuxcontainers.lxd";
70 Before = lib.optionals config.services.cloud-init.enable [ "cloud-init.target" "cloud-init.service" "cloud-init-local.service" ];
71 DefaultDependencies = "no";
72 StartLimitInterval = "60";
73 StartLimitBurst = "10";
74 };
75
76 serviceConfig = {
77 Type = "notify";
78 WorkingDirectory = "-/run/lxd_agent";
79 ExecStart = "/run/lxd_agent/lxd-agent";
80 Restart = "on-failure";
81 RestartSec = "5s";
82 };
83 };
84
85 systemd.paths.lxd-agent = {
86 enable = true;
87 wantedBy = [ "multi-user.target" ];
88 pathConfig.PathExists = "/dev/virtio-ports/org.linuxcontainers.lxd";
89 };
90 };
91}