From 573708fd479ea551a83c54d120f22b9ca5ae6496 Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Tue, 4 Nov 2025 15:02:49 -0600 Subject: [PATCH] moved storage option draft to its own folder --- modules/nixos-modules/default.nix | 1 + modules/nixos-modules/impermanence.nix | 140 ------------------ modules/nixos-modules/storage/default.nix | 12 ++ .../nixos-modules/storage/impermanence.nix | 31 ++++ .../storage/submodules/dataset.nix | 3 + .../submodules/impermanenceDataset.nix | 46 ++++++ modules/nixos-modules/storage/zfs.nix | 67 +++++++++ 7 files changed, 160 insertions(+), 140 deletions(-) create mode 100644 modules/nixos-modules/storage/default.nix create mode 100644 modules/nixos-modules/storage/impermanence.nix create mode 100644 modules/nixos-modules/storage/submodules/dataset.nix create mode 100644 modules/nixos-modules/storage/submodules/impermanenceDataset.nix create mode 100644 modules/nixos-modules/storage/zfs.nix diff --git a/modules/nixos-modules/default.nix b/modules/nixos-modules/default.nix index 2ba1a58..77bfe93 100644 --- a/modules/nixos-modules/default.nix +++ b/modules/nixos-modules/default.nix @@ -16,6 +16,7 @@ ./tailscale.nix ./steam.nix ./server + ./storage ]; nixpkgs.config.permittedInsecurePackages = [ diff --git a/modules/nixos-modules/impermanence.nix b/modules/nixos-modules/impermanence.nix index 5b1bbd2..4cdcd00 100644 --- a/modules/nixos-modules/impermanence.nix +++ b/modules/nixos-modules/impermanence.nix @@ -3,146 +3,6 @@ lib, ... }: { - options.storage = let - datasetSubmodule = {name, ...}: { - # TODO: we need to figure out what options a dataset can have in zfs - }; - - impermanenceDatasetSubmodules = [ - datasetSubmodule - ({...}: let - pathPermissions = { - read = lib.mkEnableOption "should the path have read permissions"; - write = lib.mkEnableOption "should the path have read permissions"; - execute = lib.mkEnableOption "should the path have read permissions"; - }; - pathTypeSubmodule = {name, ...}: { - options = { - enable = lib.mkOption { - type = lib.types.bool; - default = true; - }; - owner = { - user = lib.mkOption { - type = lib.types.str; - default = "nouser"; - }; - permissions = pathPermissions; - }; - group = { - group = lib.mkOption { - type = lib.types.str; - default = "nogroup"; - }; - permissions = pathPermissions; - }; - other = { - permissions = pathPermissions; - }; - }; - }; - in { - options = { - files = lib.types.mkOption { - type = lib.types.attrsOf (lib.types.submodule pathTypeSubmodule); - default = {}; - }; - directories = { - type = lib.types.attrsOf (lib.types.submodule pathTypeSubmodule); - default = {}; - }; - }; - }) - ]; - in { - zfs = { - # TODO: enable option implementation - enable = lib.mkEnableOption "Should zfs be enabled on this system."; - - notifications = { - enable = lib.mkEnableOption "are notifications enabled"; - host = lib.mkOption { - type = lib.types.str; - description = "what is the host that we are going to send the email to"; - }; - port = lib.mkOption { - type = lib.types.port; - description = "what port is the host using to receive mail on"; - }; - to = lib.mkOption { - type = lib.types.str; - description = "what account is the email going to be sent to"; - }; - user = lib.mkOption { - type = lib.types.str; - description = "what user is the email going to be set from"; - }; - tokenFile = lib.mkOption { - type = lib.types.str; - description = "file containing the password to be used by msmtp for notifications"; - }; - }; - - # TODO: we need options to configure zfs pools - # we should have warnings when the configured pool is missing drives after activation - # TODO: implementation of this - # TODO: validations that we have at least one boot drive - pool = let - deviceType = - lib.types.coercedTo lib.types.str (device: { - device = device; - boot = false; - }) { - device = lib.mkOption { - type = lib.types.str; - }; - boot = lib.mkEnableOption "should this device be a boot device"; - }; - in { - encryption = lib.mkEnableOption "Should encryption be enabled on this pool."; - vdevs = lib.mkOption { - type = lib.types.listOf deviceType; - default = []; - }; - cache = lib.mkOption { - type = lib.types.attrsOf deviceType; - }; - }; - - # TODO:create the root dataset automatically - # TODO: dataset option that is a submodule that adds datasets to the system - # warnings for when a dataset was created in the past on a system but it is now missing some of the options defined for it - datasets = lib.types.attrsOf (lib.types.submodule datasetSubmodule); - }; - - impermanence = { - enable = lib.mkEnableOption "should impermanence be enabled for this system"; - # TODO: enable option implementation - - # TODO: assertion that zfs needs to be enabled when impermanence is enabled - - # TODO: datasets option that is a submodule that will be used to define what datasets to add to the storage system - # We should by default create the `local`, `local/system/nix`, `local/system/root`, `persist` `persist/system/root`, and `persist/system/var/log` datasets - # We should also create datasets for systemd modules that have have impermanence enabled for them - - datasets = lib.types.attrsOf (lib.types.submodule impermanenceDatasetSubmodules); - - # TODO: this should just live under home-manager.users..storage.impermanence - home-manager = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - enable = lib.mkEnableOption "should impermanence be enabled for this user"; - - # We should by default create the `local/home/${name}`, and `persist/home/${name}` datasets - datasets = lib.types.attrsOf (lib.types.submodule impermanenceDatasetSubmodules); - })); - }; - - # TODO: we should have an impermanence module for home manager that proxies its values namespaced to the user down here that matches the same interface - - # TODO: we should have a way of enabling impermanence for a systemd config - # these should have an option to put their folder into their own dataset (this needs to support private vs non private) - # options for features that can be added to the dataset - }; - options.host.impermanence.enable = lib.mkEnableOption "are we going to use impermanence on this device"; config = lib.mkMerge [ diff --git a/modules/nixos-modules/storage/default.nix b/modules/nixos-modules/storage/default.nix new file mode 100644 index 0000000..02f7fb9 --- /dev/null +++ b/modules/nixos-modules/storage/default.nix @@ -0,0 +1,12 @@ +{...}: { + # TODO: we should have an impermanence module for home manager that proxies its values namespaced to the user down here that matches the same interface + + # TODO: we should have a way of enabling impermanence for a systemd config + # these should have an option to put their folder into their own dataset (this needs to support private vs non private) + # options for features that can be added to the dataset + + imports = [ + ./impermanence.nix + ./zfs.nix + ]; +} diff --git a/modules/nixos-modules/storage/impermanence.nix b/modules/nixos-modules/storage/impermanence.nix new file mode 100644 index 0000000..c51e35f --- /dev/null +++ b/modules/nixos-modules/storage/impermanence.nix @@ -0,0 +1,31 @@ +args @ {lib, ...}: let + impermanenceDatasetSubmodules = (import ./submodules/impermanenceDataset.nix) args; +in { + options.storage = { + impermanence = { + enable = lib.mkEnableOption "should impermanence be enabled for this system"; + # TODO: enable option implementation + + # TODO: assertion that zfs needs to be enabled when impermanence is enabled + + # TODO: datasets option that is a submodule that will be used to define what datasets to add to the storage system + # We should by default create the `local`, `local/system/nix`, `local/system/root`, `persist` `persist/system/root`, and `persist/system/var/log` datasets + # We should also create datasets for systemd modules that have have impermanence enabled for them + + datasets = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule impermanenceDatasetSubmodules); + }; + + # TODO: this should just live under home-manager.users..storage.impermanence + home-manager = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { + enable = lib.mkEnableOption "should impermanence be enabled for this user"; + # We should by default create the `local/home/${name}`, and `persist/home/${name}` datasets + datasets = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule impermanenceDatasetSubmodules); + }; + })); + }; + }; + }; +} diff --git a/modules/nixos-modules/storage/submodules/dataset.nix b/modules/nixos-modules/storage/submodules/dataset.nix new file mode 100644 index 0000000..a6cc3e6 --- /dev/null +++ b/modules/nixos-modules/storage/submodules/dataset.nix @@ -0,0 +1,3 @@ +{name, ...}: { + # TODO: we need to figure out what options a dataset can have in zfs +} diff --git a/modules/nixos-modules/storage/submodules/impermanenceDataset.nix b/modules/nixos-modules/storage/submodules/impermanenceDataset.nix new file mode 100644 index 0000000..f9a4df6 --- /dev/null +++ b/modules/nixos-modules/storage/submodules/impermanenceDataset.nix @@ -0,0 +1,46 @@ +{lib, ...}: let + pathPermissions = { + read = lib.mkEnableOption "should the path have read permissions"; + write = lib.mkEnableOption "should the path have read permissions"; + execute = lib.mkEnableOption "should the path have read permissions"; + }; + pathTypeSubmodule = {name, ...}: { + options = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + }; + owner = { + user = lib.mkOption { + type = lib.types.str; + default = "nouser"; + }; + permissions = pathPermissions; + }; + group = { + group = lib.mkOption { + type = lib.types.str; + default = "nogroup"; + }; + permissions = pathPermissions; + }; + other = { + permissions = pathPermissions; + }; + }; + }; +in { + imports = [ + ./dataset.nix + ]; + options = { + files = lib.types.mkOption { + type = lib.types.attrsOf (lib.types.submodule pathTypeSubmodule); + default = {}; + }; + directories = { + type = lib.types.attrsOf (lib.types.submodule pathTypeSubmodule); + default = {}; + }; + }; +} diff --git a/modules/nixos-modules/storage/zfs.nix b/modules/nixos-modules/storage/zfs.nix new file mode 100644 index 0000000..c5dd412 --- /dev/null +++ b/modules/nixos-modules/storage/zfs.nix @@ -0,0 +1,67 @@ +args @ {lib, ...}: let + datasetSubmodule = (import ./submodules/dataset.nix) args; +in { + options.storage = { + zfs = { + # TODO: enable option implementation + enable = lib.mkEnableOption "Should zfs be enabled on this system."; + + notifications = { + enable = lib.mkEnableOption "are notifications enabled"; + host = lib.mkOption { + type = lib.types.str; + description = "what is the host that we are going to send the email to"; + }; + port = lib.mkOption { + type = lib.types.port; + description = "what port is the host using to receive mail on"; + }; + to = lib.mkOption { + type = lib.types.str; + description = "what account is the email going to be sent to"; + }; + user = lib.mkOption { + type = lib.types.str; + description = "what user is the email going to be set from"; + }; + tokenFile = lib.mkOption { + type = lib.types.str; + description = "file containing the password to be used by msmtp for notifications"; + }; + }; + + # TODO: we need options to configure zfs pools + # we should have warnings when the configured pool is missing drives after activation + # TODO: implementation of this + # TODO: validations that we have at least one boot drive + pool = let + deviceType = + lib.types.coercedTo lib.types.str (device: { + device = device; + boot = false; + }) { + device = lib.mkOption { + type = lib.types.str; + }; + boot = lib.mkEnableOption "should this device be a boot device"; + }; + in { + encryption = lib.mkEnableOption "Should encryption be enabled on this pool."; + vdevs = lib.mkOption { + type = lib.types.listOf deviceType; + default = []; + }; + cache = lib.mkOption { + type = lib.types.attrsOf deviceType; + }; + }; + + # TODO:create the root dataset automatically + # TODO: dataset option that is a submodule that adds datasets to the system + # warnings for when a dataset was created in the past on a system but it is now missing some of the options defined for it + datasets = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule datasetSubmodule); + }; + }; + }; +}