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