diff --git a/machines/deedee/configuration.nix b/machines/deedee/configuration.nix index c0a2a78..43dbcf2 100644 --- a/machines/deedee/configuration.nix +++ b/machines/deedee/configuration.nix @@ -141,6 +141,23 @@ rec { rootless = false; }; + incus = { + enable = true; + enableUI = true; + initializeBaseNixOSVM = true; + defaultStoragePool = { + config = { + source = "tank/vms"; + }; + driver = "zfs"; + }; + defaultNIC = { + nictype = "bridged"; + parent = "br0"; + type = "nic"; + }; + }; + letsencrypt = { enable = true; useProduction = true; diff --git a/machines/deedee/secrets.sops.yaml b/machines/deedee/secrets.sops.yaml index d7f99e0..4e98cb4 100644 --- a/machines/deedee/secrets.sops.yaml +++ b/machines/deedee/secrets.sops.yaml @@ -71,6 +71,9 @@ system: DB_PASSWORD: ENC[AES256_GCM,data:mbC7eRSCB99A5VkhCK7BL4oQh5T8k+wbQZPcsReKtHjQtO/4PIanww==,iv:Bhp2whhp7MWBgPwbVWG/79S/ZA7UOCtwNFYhqTbfImQ=,tag:nNoNloIEe6lUKt7Fh2aUPA==,type:str] OIDC_SECRET_ENCRYPTED: ENC[AES256_GCM,data:HNwOGx5f6g7NTFi7Xk7lRWFpPgqH+2sAZXE4wGPsTdOXZtl/EsQFFP6x5kG/L0UvC+WcpmqP9M2RrN70pvNfpR5DZtAx91owYYgnhQ9jBvNgCb0cgyEf9IO0n5YWZ5dGlYN7DrwXYPZ5UAbNl4QGMoYq93BSUo6Ob9KYw6r+PJKvmK8=,iv:AiMZO4itdkNCdUlJ2JfruYwzi1viA3xYbmDnC/vcD9c=,tag:pK3UsufBQ3rKUhaMdAM0AA==,type:str] OIDC_SECRET_RAW: ENC[AES256_GCM,data:JMA2jwiSTCtP0bJzXiPawWLfkKtLJMDDIcwJbTBhzKlxiL8YE0NwXz098CRwd2o3sUxoyZa6CrygTUuq3GDUopwHVX7ZsQn2,iv:iU06dfr+g9mK3ZwwvZqkn1NxjbtErG/UQnefTTqJonM=,tag:8msqG8E+rIHFXyLAgWBrQg==,type:str] + incus: + incus-ui.crt: ENC[AES256_GCM,data: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,iv:8ejvEJO+k1pFjojcc5ioWX+eiEF5tpD3WeARxUJIUpE=,tag:+h3EGO6DUGyTjWdbc5suyA==,type:str] + incus-ui.key: ENC[AES256_GCM,data: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,iv:7EbV1YgviKWp99vE2mknF6SLa6xzpvkDRXX1Glcoc4w=,tag:Pf5owB2TvjIxsECWzRFBFg==,type:str] jellyfin: env: OIDC_SECRET_ENCRYPTED: ENC[AES256_GCM,data:hRAudzG+gyAW5he21z2aY191Qon56UQxOdQanjWc9qC7ToPTqoVQQUsSwN6T8n4hCLSwfOEXZF6jQUFFQocnvMHfz/IjZGrhl2uGR/wOm8bADYU9UUuyJCB1mdq8wBWbi22hv+V1unl0uWDz/6GMLv4VVouwN6y7fqk7FLpwbQkeT1g=,iv:Ck3iV8ySo9t8MYjqZeTC0Kpe+srolUjg5FabKMBM5+k=,tag:C/d3sFzmeBJDS2iMryQ9zA==,type:str] @@ -171,8 +174,8 @@ sops: c3FoaFNzbjJubzlBckdDb2lNOUZtOGMKRbHxa1B3QAdredBMTd7W7g3kRz6l8uyV bBclsA8Gm7p+6ndV39sN+Daqm5MyggY1Prwv/Ukdd5Q+1C+XsEW6OQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-11-02T14:27:10Z" - mac: ENC[AES256_GCM,data:Yc/OB/IBUxCRLQYCckjmSrpLHBeHw+r8ZZ5BfzPwyg9Khrk2cdWSoTOcssYQjJpwdyelnTLFPXujmJRzOoqf6PteoL7d6yn6YxyzVEvYKo5UPNaTb5fjnAH4TszxXXderjhZUw8D70ogMIHHNqD+OlEpM5JVj1ZK57acaH3rhbw=,iv:jhre5EViny+uaqP5xpwWIOnDiVl0YUgJtFzTRH3Ekys=,tag:Uy4fG2oNXiqg9KE+qB60FA==,type:str] + lastmodified: "2024-11-03T19:20:18Z" + mac: ENC[AES256_GCM,data:1nM8NWF8vD9J+1zuGxp3LRO1uZh8fPVPegogrYrWobHNv7i0VwT7suCTFBnkRmkPwIVRC63inEiFCSO/Ojz/QvDfSGr2P8w8SAdWs+xe9hMnuuFDPuGi9Hq0eV8O0YiuOxkmRgmexZqYp+SUPvtPQ4ztvYFcTi7tZNKlaJkHseU=,iv:fuAdNDFW2aZFlsV8ctMbxc3waeAaHnPdNK0wOGZmtYc=,tag:lhLSPHqzaiqin97k7o4JKw==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 diff --git a/modules/system/apps/default.nix b/modules/system/apps/default.nix index db5a6d2..a055f17 100644 --- a/modules/system/apps/default.nix +++ b/modules/system/apps/default.nix @@ -4,6 +4,7 @@ _: { ./adguardhome ./docker + ./incus ./letsencrypt ./nginx ./openconnect diff --git a/modules/system/apps/incus/default.nix b/modules/system/apps/incus/default.nix new file mode 100644 index 0000000..123c897 --- /dev/null +++ b/modules/system/apps/incus/default.nix @@ -0,0 +1,170 @@ +{ + config, + lib, + svc, + ... +}: +let + cfg = config.mySystemApps.incus; +in +{ + options.mySystemApps.incus = { + enable = lib.mkEnableOption "incus app"; + dataDir = lib.mkOption { + type = lib.types.str; + description = "Path to directory containing data."; + default = "/var/lib/incus"; + }; + defaultStoragePool = lib.mkOption { + type = lib.types.attrs; + description = "Default storage pool configuration for incus."; + default = { + config = { + source = "${cfg.dataDir}/disks/default.img"; + size = "500GiB"; + }; + driver = "btrfs"; + name = "default"; + }; + }; + defaultNIC = lib.mkOption { + type = lib.types.attrs; + description = "Default NIC for the VM."; + default = { + network = "incusbr0"; + type = "nic"; + }; + example = { + nictype = "bridged"; + parent = "br0"; + type = "nic"; + vlan = 100; + }; + }; + enableUI = lib.mkOption { + type = lib.types.bool; + description = "Enable incus UI"; + default = false; + }; + incusUICrtSopsSecret = lib.mkOption { + type = lib.types.str; + description = '' + Sops secret name containing Incus UI certificate. + Don't use incus UI to generate it, as it generates faulty certificates, not accepted by nginx. + Instead do: + openssl req -newkey rsa:4096 -nodes -keyout incus-ui.key -x509 -days 36500 -out incus-ui.crt + ''; + default = "system/apps/incus/incus-ui.crt"; + }; + incusUIKeySopsSecret = lib.mkOption { + type = lib.types.str; + description = '' + Sops secret name containing Incus UI certificate. + Don't use incus UI to generate it, as it generates faulty certificates, not accepted by nginx. + Instead do: + openssl req -newkey rsa:4096 -nodes -keyout incus-ui.key -x509 -days 36500 -out incus-ui.crt + ''; + default = "system/apps/incus/incus-ui.key"; + }; + initializeBaseNixOSVM = lib.mkOption { + type = lib.types.bool; + description = "If set to true, it will install base image, compatible with nixos-anywhere."; + default = false; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = (!cfg.enableUI) || config.mySystemApps.authelia.enable; + message = "To use incus UI, authelia container needs to be enabled."; + } + ]; + + sops.secrets = { + "${cfg.incusUICrtSopsSecret}" = { + owner = "nginx"; + group = "nginx"; + restartUnits = [ "nginx.service" ]; + }; + "${cfg.incusUIKeySopsSecret}" = { + owner = "nginx"; + group = "nginx"; + restartUnits = [ "nginx.service" ]; + }; + }; + + virtualisation.incus = { + enable = true; + ui.enable = cfg.enableUI; + + preseed = { + profiles = [ + { + name = "default"; + description = "Default profile"; + devices = { + eth0 = lib.recursiveUpdate cfg.defaultNIC { name = "eth0"; }; + root = { + path = "/"; + pool = "default"; + size = "200GiB"; + type = "disk"; + }; + }; + config = { + "boot.autostart" = false; + "limits.cpu" = 4; + "limits.memory" = "8GiB"; + "security.secureboot" = false; + "snapshots.schedule" = "@hourly"; + }; + } + ]; + storage_pools = [ (lib.recursiveUpdate cfg.defaultStoragePool { name = "default"; }) ]; + }; + }; + + users.users."${config.mySystem.primaryUser}".extraGroups = [ "incus-admin" ]; + networking.firewall.trustedInterfaces = + lib.optionals (builtins.hasAttr "network" cfg.defaultNIC) [ cfg.defaultNIC.network ] + ++ lib.optionals (builtins.hasAttr "parent" cfg.defaultNIC) [ cfg.defaultNIC.parent ]; + + environment.persistence."${config.mySystem.impermanence.persistPath}" = + lib.mkIf config.mySystem.impermanence.enable + { directories = [ cfg.dataDir ]; }; + + systemd.services.incus.postStart = lib.mkAfter ( + (lib.optionalString cfg.enableUI '' + ${lib.getExe config.virtualisation.incus.package} config set core.https_address 127.0.0.1:8443 + ${lib.getExe config.virtualisation.incus.package} config trust add-certificate ${ + config.sops.secrets."${cfg.incusUICrtSopsSecret}".path + } || true + '') + + (lib.optionalString cfg.initializeBaseNixOSVM '' + if ! incus image show nixos/base/vm; then + nix run github:deedee-ops/nixlab#build-base-vm + fi + '') + ); + + services.nginx.virtualHosts.incus = lib.mkIf cfg.enableUI ( + svc.mkNginxVHost { + host = "incus"; + proxyPass = "https://127.0.0.1:8443"; + extraConfig = '' + proxy_ssl_certificate ${config.sops.secrets."${cfg.incusUICrtSopsSecret}".path}; + proxy_ssl_certificate_key ${config.sops.secrets."${cfg.incusUIKeySopsSecret}".path}; + ''; + } + ); + + mySystemApps.homepage = lib.mkIf cfg.enableUI { + services.Apps.Incus = svc.mkHomepage "incus" // { + icon = "proxmox.svg"; # @todo + container = null; + description = "Virtual machines manager"; + }; + }; + }; +} diff --git a/modules/system/lib.nix b/modules/system/lib.nix index 0ca0175..3487ee2 100644 --- a/modules/system/lib.nix +++ b/modules/system/lib.nix @@ -19,6 +19,7 @@ useAuthelia ? true, autheliaIgnorePaths ? [ ], customCSP ? null, + extraConfig ? "", }: let # proxy_pass needs to be passed as variable, otherwise resolver won't work as expected @@ -40,7 +41,8 @@ more_set_headers "Content-Security-Policy: ${ lib.trim (builtins.replaceStrings [ "\n" ] [ " " ] customCSP) }"; - ''); + '') + + extraConfig; in { extraConfig =