1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
{
config,
lib,
pkgs,
credentials,
...
}:
let
# qemu 9.1.2 no longer supports strings being passed instead of some
# integer parameters. incus already has the fix, but it hasn't made it
# into a release yet.
# see: https://github.com/lxc/incus/issues/1522
incusPatch = pkgs.fetchpatch {
name = "1531.patch";
url = "https://github.com/lxc/incus/pull/1531.patch";
sha256 = "sha256-tM/+JRH0OwR3bM8gk3yNo9SSAEMqpS2HP+OzooV3DJY=";
};
incus = pkgs.incus.overrideAttrs (attrs: {
patches = (attrs.patches or [ ]) ++ [ incusPatch ];
});
toYAML = lib.generators.toYAML { };
cloudInitConfiguration = {
users = [
(with credentials.mel; {
name = "mel";
groups = "users";
sudo = "ALL=(ALL) NOPASSWD:ALL";
passwd = password;
lock_passwd = false;
ssh_authorized_keys = keys;
})
(with credentials.philip; {
name = "philip";
groups = "users";
sudo = "ALL=(ALL) NOPASSWD:ALL";
passwd = password;
lock_passwd = false;
ssh_authorized_keys = keys;
})
];
# ssh configuration
allow_public_ssh_keys = true;
disable_root = true;
};
in
{
virtualisation.incus = {
enable = true;
package = incus;
preseed = {
networks = [
{
# we don't really need internal ipv6 here, i think.
config = {
"ipv4.address" = "10.0.100.1/24";
"ipv4.nat" = "true";
};
name = "incusbr0";
type = "bridge";
}
];
profiles = [
# this default profile gets applied to all
# new instances without an explicitly set profile.
{
name = "default";
# config applied to new instances,
# this is how we can best control
# vm provisioning semi-declaratively.
# for options, see: https://linuxcontainers.org/incus/docs/main/reference/instance_options/
config = {
# `vendor` is usually for defaults, but it doesn't actually matter here.
# NOTE: cloud-init requires either the incus-agent to be running,
# or that the image is a special cloud image. i.e. `images:ubuntu/22.04/cloud`.
"cloud-init.vendor-data" = ''
#cloud-config
${toYAML cloudInitConfiguration}
'';
};
devices = {
# this is the internal vm network,
# not the hosts.
eth0 = {
name = "eth0";
network = "incusbr0";
type = "nic";
};
root = {
path = "/";
pool = "default";
size = "5GiB";
type = "disk";
};
};
}
];
storage_pools = [
{
config = {
source = "/var/lib/incus/storage-pools/default";
};
driver = "dir";
name = "default";
}
];
};
};
# `incus-admin` essentially gives you root access anyway,
# let users in `wheel` use it freely.
users.groups."incus-admin".members = config.users.groups."wheel".members;
}
|