summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--configuration/configuration.nix1
-rw-r--r--configuration/vm/default.nix7
-rw-r--r--configuration/vm/incus.nix95
3 files changed, 103 insertions, 0 deletions
diff --git a/configuration/configuration.nix b/configuration/configuration.nix
index e8e20e2..267c219 100644
--- a/configuration/configuration.nix
+++ b/configuration/configuration.nix
@@ -11,6 +11,7 @@
     ./hardware.nix
     ./devices.nix
     ./specimen.nix
+    ./vm
   ];
 
   nix.settings.experimental-features = [
diff --git a/configuration/vm/default.nix b/configuration/vm/default.nix
new file mode 100644
index 0000000..5599639
--- /dev/null
+++ b/configuration/vm/default.nix
@@ -0,0 +1,7 @@
+{ ... }:
+
+{
+  imports = [
+    ./incus.nix
+  ];
+}
diff --git a/configuration/vm/incus.nix b/configuration/vm/incus.nix
new file mode 100644
index 0000000..ab8e6ee
--- /dev/null
+++ b/configuration/vm/incus.nix
@@ -0,0 +1,95 @@
+{
+  config,
+  pkgs,
+  credentials,
+  ...
+}:
+
+let
+  cloudInitConfiguration = {
+    users = [
+      (with credentials.mel; {
+        name = "mel";
+        groups = "users";
+        sudo = "ALL=(ALL) NOPASSWD:ALL";
+        passwd = password;
+        ssh_authorized_keys = keys;
+      })
+      (with credentials.philip; {
+        name = "philip";
+        groups = "users";
+        sudo = "ALL=(ALL) NOPASSWD:ALL";
+        passwd = password;
+        ssh_authorized_keys = keys;
+      })
+    ];
+
+    # ssh configuration
+    allow_public_ssh_keys = true;
+    disable_root = true;
+  };
+in
+{
+  virtualisation.incus = {
+    enable = true;
+    package = pkgs.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" = 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;
+}