diff options
| author | Mel <einebeere@gmail.com> | 2024-12-31 17:03:56 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2024-12-31 17:03:56 +0100 |
| commit | 9415facde70c0e02af6ff57c3ebfe2d6b7af385e (patch) | |
| tree | 8a0b96846e8cf7282db2832b3250c3b6ff99bc0e /modules/incus.nix | |
| parent | e73df329fde2e19f3ab3b2b1ffe217d888383086 (diff) | |
| download | declarative-vm.nix-9415facde70c0e02af6ff57c3ebfe2d6b7af385e.tar.zst declarative-vm.nix-9415facde70c0e02af6ff57c3ebfe2d6b7af385e.zip | |
Signed-off-by: Mel <einebeere@gmail.com>
Diffstat (limited to 'modules/incus.nix')
| -rw-r--r-- | modules/incus.nix | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/modules/incus.nix b/modules/incus.nix new file mode 100644 index 0000000..3d64432 --- /dev/null +++ b/modules/incus.nix @@ -0,0 +1,150 @@ +{ + config, + lib, + pkgs, + ... +}: + +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 = [ + { + name = "admin"; + groups = "users"; + sudo = "ALL=(ALL) NOPASSWD:ALL"; + plain_text_passwd = "example"; + lock_passwd = false; + } + ]; + + # ssh configuration + allow_public_ssh_keys = true; + disable_root = true; + packages = [ "openssh-server" ]; + runcmd = [ + [ + "systemctl" + "enable" + "ssh.service" + ] + ]; + }; +in +{ + networking.firewall = { + # needed so that the nixos firewall does not block + # DHCP+DNS requests from incus, and to prevent conflicts + # between the two firewalls. + trustedInterfaces = [ "incusbr0" ]; + allowedTCPPorts = [ 23 ]; + }; + # needed so inscus instances can connect to the proxy. + boot.kernelModules = [ "br_netfilter" ]; + virtualisation.incus = { + enable = true; + package = incus; + preseed = { + networks = [ + { + 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 = { }; + devices = { + eth0 = { + name = "eth0"; + network = "incusbr0"; + type = "nic"; + }; + root = { + path = "/"; + pool = "default"; + size = "35GiB"; + type = "disk"; + }; + }; + } + # this profile is the one we want to apply to an ubuntu example vm. + # it is provisioned with a static ipv4 (for nat-ted proxy) + # and cloud-init configuration + { + name = "vm-1"; + # 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 = { + eth0 = { + name = "eth0"; + network = "incusbr0"; + type = "nic"; + + # this is necessary for our nat proxy configuration. + # see: https://linuxcontainers.org/incus/docs/main/reference/devices_proxy/#nat-mode + "ipv4.address" = "10.0.100.123"; + }; + proxy = { + type = "proxy"; + listen = "tcp:127.0.0.1:2222"; + connect = "tcp:0.0.0.0:22"; + nat = true; + }; + root = { + path = "/"; + pool = "default"; + size = "35GiB"; + 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; +} |
