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 = {
49 maintainers = lib.teams.lxc.members;
50 };
51
52 options = {
53 virtualisation.lxd.agent.enable = lib.mkEnableOption "Enable LXD agent";
54 };
55
56 config = lib.mkIf cfg.enable {
57 # https://github.com/lxc/distrobuilder/blob/f77300bf7d7d5707b08eaf8a434d647d1ba81b5d/generators/lxd-agent.go#L108-L125
58 systemd.services.lxd-agent = {
59 enable = true;
60 wantedBy = [ "multi-user.target" ];
61 before = [ "shutdown.target" ] ++ lib.optionals config.services.cloud-init.enable [
62 "cloud-init.target" "cloud-init.service" "cloud-init-local.service"
63 ];
64 conflicts = [ "shutdown.target" ];
65 path = [
66 pkgs.kmod
67 pkgs.util-linux
68
69 # allow `incus exec` to find system binaries
70 "/run/current-system/sw"
71 ];
72
73 preStart = preStartScript;
74
75 # avoid killing nixos-rebuild switch when executed through lxc exec
76 restartIfChanged = false;
77 stopIfChanged = false;
78
79 unitConfig = {
80 Description = "LXD - agent";
81 Documentation = "https://documentation.ubuntu.com/lxd/en/latest";
82 ConditionPathExists = "/dev/virtio-ports/org.linuxcontainers.lxd";
83 DefaultDependencies = "no";
84 StartLimitInterval = "60";
85 StartLimitBurst = "10";
86 };
87
88 serviceConfig = {
89 Type = "notify";
90 WorkingDirectory = "-/run/lxd_agent";
91 ExecStart = "/run/lxd_agent/lxd-agent";
92 Restart = "on-failure";
93 RestartSec = "5s";
94 };
95 };
96
97 systemd.paths.lxd-agent = {
98 enable = true;
99 wantedBy = [ "multi-user.target" ];
100 pathConfig.PathExists = "/dev/virtio-ports/org.linuxcontainers.lxd";
101 };
102 };
103}