From 978c3c21d4e94ce74fcae51b2249e05879e21a0a Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 1 Oct 2024 15:42:13 +0200 Subject: [PATCH] Inventory/modules: use explicit roles only --- clanModules/admin/default.nix | 22 +- clanModules/admin/roles/default.nix | 20 ++ clanModules/borgbackup/default.nix | 217 +------------------- clanModules/borgbackup/roles/client.nix | 180 +++++++++++++++- clanModules/disk-id/default.nix | 28 +-- clanModules/disk-id/roles/default.nix | 26 +++ clanModules/iwd/default.nix | 88 +------- clanModules/iwd/roles/default.nix | 86 ++++++++ clanModules/machine-id/default.nix | 47 +---- clanModules/machine-id/roles/default.nix | 45 ++++ clanModules/packages/default.nix | 21 +- clanModules/packages/roles/default.nix | 19 ++ clanModules/single-disk/default.nix | 54 +---- clanModules/single-disk/roles/default.nix | 55 +++++ clanModules/state-version/default.nix | 20 +- clanModules/state-version/roles/default.nix | 18 ++ lib/inventory/build-inventory/default.nix | 2 +- 17 files changed, 468 insertions(+), 480 deletions(-) create mode 100644 clanModules/admin/roles/default.nix create mode 100644 clanModules/disk-id/roles/default.nix create mode 100644 clanModules/iwd/roles/default.nix create mode 100644 clanModules/machine-id/roles/default.nix create mode 100644 clanModules/packages/roles/default.nix create mode 100644 clanModules/single-disk/roles/default.nix create mode 100644 clanModules/state-version/roles/default.nix diff --git a/clanModules/admin/default.nix b/clanModules/admin/default.nix index 32916eed7..ed6af3368 100644 --- a/clanModules/admin/default.nix +++ b/clanModules/admin/default.nix @@ -1,20 +1,6 @@ -{ lib, config, ... }: +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - options.clan.admin = { - allowedKeys = lib.mkOption { - default = { }; - type = lib.types.attrsOf lib.types.str; - description = "The allowed public keys for ssh access to the admin user"; - example = { - "key_1" = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD..."; - }; - }; - }; - imports = [ - ../sshd - ../root-password - ]; - config = { - users.users.root.openssh.authorizedKeys.keys = builtins.attrValues config.clan.admin.allowedKeys; - }; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/admin/roles/default.nix b/clanModules/admin/roles/default.nix new file mode 100644 index 000000000..32916eed7 --- /dev/null +++ b/clanModules/admin/roles/default.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +{ + options.clan.admin = { + allowedKeys = lib.mkOption { + default = { }; + type = lib.types.attrsOf lib.types.str; + description = "The allowed public keys for ssh access to the admin user"; + example = { + "key_1" = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD..."; + }; + }; + }; + imports = [ + ../sshd + ../root-password + ]; + config = { + users.users.root.openssh.authorizedKeys.keys = builtins.attrValues config.clan.admin.allowedKeys; + }; +} diff --git a/clanModules/borgbackup/default.nix b/clanModules/borgbackup/default.nix index 760e1afe8..d4b634d00 100644 --- a/clanModules/borgbackup/default.nix +++ b/clanModules/borgbackup/default.nix @@ -1,215 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - config, - lib, - pkgs, - ... -}: -let - cfg = config.clan.borgbackup; - preBackupScript = '' - declare -A preCommandErrors - - ${lib.concatMapStringsSep "\n" ( - state: - lib.optionalString (state.preBackupCommand != null) '' - echo "Running pre-backup command for ${state.name}" - if ! /run/current-system/sw/bin/${state.preBackupCommand}; then - preCommandErrors["${state.name}"]=1 - fi - '' - ) (lib.attrValues config.clan.core.state)} - - if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then - echo "pre-backup commands failed for the following services:" - for state in "''${!preCommandErrors[@]}"; do - echo " $state" - done - exit 1 - fi - ''; -in -# Each .nix file in the roles directory is a role -# TODO: Helper function to set available roles within module meta. -# roles = -# if builtins.pathExists ./roles then -# lib.pipe ./roles [ -# builtins.readDir -# (lib.filterAttrs (_n: v: v == "regular")) -# lib.attrNames -# (map (fileName: lib.removeSuffix ".nix" fileName)) -# ] -# else -# null; -# TODO: make this an interface of every module -# Maybe load from readme.md -# metaInfoOption = lib.mkOption { -# readOnly = true; -# description = '' -# Meta is used to retrieve information about this module. -# - `availableRoles` is a list of roles that can be assigned via the inventory. -# - `category` is used to group services in the clan marketplace. -# - `description` is a short description of the service for the clan marketplace. -# ''; -# default = { -# description = "Borgbackup is a backup program. Optionally, it supports compression and authenticated encryption."; -# availableRoles = roles; -# category = "backup"; -# }; -# type = lib.types.submodule { -# options = { -# description = lib.mkOption { type = lib.types.str; }; -# availableRoles = lib.mkOption { type = lib.types.nullOr (lib.types.listOf lib.types.str); }; -# category = lib.mkOption { -# description = "A category for the service. This is used to group services in the clan ui"; -# type = lib.types.enum [ -# "backup" -# "network" -# ]; -# }; -# }; -# }; -# }; -{ - - # options.clan.borgbackup.meta = metaInfoOption; - - options.clan.borgbackup.destinations = lib.mkOption { - type = lib.types.attrsOf ( - lib.types.submodule ( - { name, ... }: - { - options = { - name = lib.mkOption { - type = lib.types.strMatching "^[a-zA-Z0-9._-]+$"; - default = name; - description = "the name of the backup job"; - }; - repo = lib.mkOption { - type = lib.types.str; - description = "the borgbackup repository to backup to"; - }; - rsh = lib.mkOption { - type = lib.types.str; - default = "ssh -i ${ - config.clan.core.facts.services.borgbackup.secret."borgbackup.ssh".path - } -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes"; - defaultText = "ssh -i \${config.clan.core.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; - description = "the rsh to use for the backup"; - }; - }; - } - ) - ); - default = { }; - description = '' - destinations where the machine should be backuped to - ''; - }; - - options.clan.borgbackup.exclude = lib.mkOption { - type = lib.types.listOf lib.types.str; - example = [ "*.pyc" ]; - default = [ ]; - description = '' - Directories/Files to exclude from the backup. - Use * as a wildcard. - ''; - }; - - imports = [ - (lib.mkRemovedOptionModule [ - "clan" - "borgbackup" - "enable" - ] "Just define clan.borgbackup.destinations to enable it") - ]; - - config = lib.mkIf (cfg.destinations != { }) { - systemd.services = lib.mapAttrs' ( - _: dest: - lib.nameValuePair "borgbackup-job-${dest.name}" { - # since borgbackup mounts the system read-only, we need to run in a ExecStartPre script, so we can generate additional files. - serviceConfig.ExecStartPre = [ - ''+${pkgs.writeShellScript "borgbackup-job-${dest.name}-pre-backup-commands" preBackupScript}'' - ]; - } - ) cfg.destinations; - - services.borgbackup.jobs = lib.mapAttrs (_: dest: { - paths = lib.unique ( - lib.flatten (map (state: state.folders) (lib.attrValues config.clan.core.state)) - ); - exclude = cfg.exclude; - repo = dest.repo; - environment.BORG_RSH = dest.rsh; - compression = "auto,zstd"; - startAt = "*-*-* 01:00:00"; - persistentTimer = true; - - encryption = { - mode = "repokey"; - passCommand = "cat ${config.clan.core.facts.services.borgbackup.secret."borgbackup.repokey".path}"; - }; - - prune.keep = { - within = "1d"; # Keep all archives from the last day - daily = 7; - weekly = 4; - monthly = 0; - }; - }) cfg.destinations; - - clan.core.facts.services.borgbackup = { - public."borgbackup.ssh.pub" = { }; - secret."borgbackup.ssh" = { }; - secret."borgbackup.repokey" = { }; - generator.path = [ - pkgs.openssh - pkgs.coreutils - pkgs.xkcdpass - ]; - generator.script = '' - ssh-keygen -t ed25519 -N "" -f "$secrets"/borgbackup.ssh - mv "$secrets"/borgbackup.ssh.pub "$facts"/borgbackup.ssh.pub - xkcdpass -n 4 -d - > "$secrets"/borgbackup.repokey - ''; - }; - - environment.systemPackages = [ - (pkgs.writeShellScriptBin "borgbackup-create" '' - set -efu -o pipefail - ${lib.concatMapStringsSep "\n" (dest: '' - systemctl start borgbackup-job-${dest.name} - '') (lib.attrValues cfg.destinations)} - '') - (pkgs.writeShellScriptBin "borgbackup-list" '' - set -efu - (${ - lib.concatMapStringsSep "\n" ( - dest: - # we need yes here to skip the changed url verification - ''yes y | borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.name}::${dest.repo}::" + .name)}]' '' - ) (lib.attrValues cfg.destinations) - }) | ${pkgs.jq}/bin/jq -s 'add' - '') - (pkgs.writeShellScriptBin "borgbackup-restore" '' - set -efux - cd / - IFS=':' read -ra FOLDER <<< "$FOLDERS" - job_name=$(echo "$NAME" | ${pkgs.gawk}/bin/awk -F'::' '{print $1}') - backup_name=''${NAME#"$job_name"::} - if ! command -v borg-job-"$job_name" &> /dev/null; then - echo "borg-job-$job_name not found: Backup name is invalid" >&2 - exit 1 - fi - yes y | borg-job-"$job_name" extract --list "$backup_name" "''${FOLDER[@]}" - '') - ]; - - clan.core.backups.providers.borgbackup = { - list = "borgbackup-list"; - create = "borgbackup-create"; - restore = "borgbackup-restore"; - }; - }; + imports = [ ./roles/client.nix ]; } diff --git a/clanModules/borgbackup/roles/client.nix b/clanModules/borgbackup/roles/client.nix index 84ce41ef7..22a20d77e 100644 --- a/clanModules/borgbackup/roles/client.nix +++ b/clanModules/borgbackup/roles/client.nix @@ -1,4 +1,9 @@ -{ config, lib, ... }: +{ + config, + lib, + pkgs, + ... +}: let instances = config.clan.inventory.services.borgbackup; # roles = { ${role_name} :: { machines :: [string] } } @@ -14,17 +19,170 @@ let ) [ ] instances; inherit (config.clan.core) machineName; + + cfg = config.clan.borgbackup; + preBackupScript = '' + declare -A preCommandErrors + + ${lib.concatMapStringsSep "\n" ( + state: + lib.optionalString (state.preBackupCommand != null) '' + echo "Running pre-backup command for ${state.name}" + if ! /run/current-system/sw/bin/${state.preBackupCommand}; then + preCommandErrors["${state.name}"]=1 + fi + '' + ) (lib.attrValues config.clan.core.state)} + + if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then + echo "pre-backup commands failed for the following services:" + for state in "''${!preCommandErrors[@]}"; do + echo " $state" + done + exit 1 + fi + ''; in { - config.clan.borgbackup.destinations = - let + options.clan.borgbackup.destinations = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + options = { + name = lib.mkOption { + type = lib.types.strMatching "^[a-zA-Z0-9._-]+$"; + default = name; + description = "the name of the backup job"; + }; + repo = lib.mkOption { + type = lib.types.str; + description = "the borgbackup repository to backup to"; + }; + rsh = lib.mkOption { + type = lib.types.str; + default = "ssh -i ${ + config.clan.core.facts.services.borgbackup.secret."borgbackup.ssh".path + } -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes"; + defaultText = "ssh -i \${config.clan.core.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; + description = "the rsh to use for the backup"; + }; + }; + } + ) + ); + default = { }; + description = '' + destinations where the machine should be backuped to + ''; + }; - destinations = builtins.map (serverName: { - name = serverName; - value = { - repo = "borg@${serverName}:/var/lib/borgbackup/${machineName}"; - }; - }) allServers; - in - (builtins.listToAttrs destinations); + options.clan.borgbackup.exclude = lib.mkOption { + type = lib.types.listOf lib.types.str; + example = [ "*.pyc" ]; + default = [ ]; + description = '' + Directories/Files to exclude from the backup. + Use * as a wildcard. + ''; + }; + + config = lib.mkIf (cfg.destinations != { }) { + systemd.services = lib.mapAttrs' ( + _: dest: + lib.nameValuePair "borgbackup-job-${dest.name}" { + # since borgbackup mounts the system read-only, we need to run in a ExecStartPre script, so we can generate additional files. + serviceConfig.ExecStartPre = [ + ''+${pkgs.writeShellScript "borgbackup-job-${dest.name}-pre-backup-commands" preBackupScript}'' + ]; + } + ) cfg.destinations; + + services.borgbackup.jobs = lib.mapAttrs (_: dest: { + paths = lib.unique ( + lib.flatten (map (state: state.folders) (lib.attrValues config.clan.core.state)) + ); + exclude = cfg.exclude; + repo = dest.repo; + environment.BORG_RSH = dest.rsh; + compression = "auto,zstd"; + startAt = "*-*-* 01:00:00"; + persistentTimer = true; + + encryption = { + mode = "repokey"; + passCommand = "cat ${config.clan.core.facts.services.borgbackup.secret."borgbackup.repokey".path}"; + }; + + prune.keep = { + within = "1d"; # Keep all archives from the last day + daily = 7; + weekly = 4; + monthly = 0; + }; + }) cfg.destinations; + + clan.core.facts.services.borgbackup = { + public."borgbackup.ssh.pub" = { }; + secret."borgbackup.ssh" = { }; + secret."borgbackup.repokey" = { }; + generator.path = [ + pkgs.openssh + pkgs.coreutils + pkgs.xkcdpass + ]; + generator.script = '' + ssh-keygen -t ed25519 -N "" -f "$secrets"/borgbackup.ssh + mv "$secrets"/borgbackup.ssh.pub "$facts"/borgbackup.ssh.pub + xkcdpass -n 4 -d - > "$secrets"/borgbackup.repokey + ''; + }; + + environment.systemPackages = [ + (pkgs.writeShellScriptBin "borgbackup-create" '' + set -efu -o pipefail + ${lib.concatMapStringsSep "\n" (dest: '' + systemctl start borgbackup-job-${dest.name} + '') (lib.attrValues cfg.destinations)} + '') + (pkgs.writeShellScriptBin "borgbackup-list" '' + set -efu + (${ + lib.concatMapStringsSep "\n" ( + dest: + # we need yes here to skip the changed url verification + ''yes y | borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.name}::${dest.repo}::" + .name)}]' '' + ) (lib.attrValues cfg.destinations) + }) | ${pkgs.jq}/bin/jq -s 'add' + '') + (pkgs.writeShellScriptBin "borgbackup-restore" '' + set -efux + cd / + IFS=':' read -ra FOLDER <<< "$FOLDERS" + job_name=$(echo "$NAME" | ${pkgs.gawk}/bin/awk -F'::' '{print $1}') + backup_name=''${NAME#"$job_name"::} + if ! command -v borg-job-"$job_name" &> /dev/null; then + echo "borg-job-$job_name not found: Backup name is invalid" >&2 + exit 1 + fi + yes y | borg-job-"$job_name" extract --list "$backup_name" "''${FOLDER[@]}" + '') + ]; + + clan.core.backups.providers.borgbackup = { + list = "borgbackup-list"; + create = "borgbackup-create"; + restore = "borgbackup-restore"; + }; + clan.borgbackup.destinations = + let + destinations = builtins.map (serverName: { + name = serverName; + value = { + repo = "borg@${serverName}:/var/lib/borgbackup/${machineName}"; + }; + }) allServers; + in + (builtins.listToAttrs destinations); + }; } diff --git a/clanModules/disk-id/default.nix b/clanModules/disk-id/default.nix index 870a2a5fd..ed6af3368 100644 --- a/clanModules/disk-id/default.nix +++ b/clanModules/disk-id/default.nix @@ -1,26 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - config, - pkgs, - ... -}: - -{ - - config = { - clan.core.vars.generators.disk-id = { - files.diskId.secret = false; - runtimeInputs = [ - pkgs.coreutils - pkgs.bash - ]; - script = '' - uuid=$(bash ${../uuid4.sh}) - - # Remove the hyphens from the UUID - uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-') - - echo -n "$uuid_no_hyphens" > "$out/diskId" - ''; - }; - }; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/disk-id/roles/default.nix b/clanModules/disk-id/roles/default.nix new file mode 100644 index 000000000..870a2a5fd --- /dev/null +++ b/clanModules/disk-id/roles/default.nix @@ -0,0 +1,26 @@ +{ + config, + pkgs, + ... +}: + +{ + + config = { + clan.core.vars.generators.disk-id = { + files.diskId.secret = false; + runtimeInputs = [ + pkgs.coreutils + pkgs.bash + ]; + script = '' + uuid=$(bash ${../uuid4.sh}) + + # Remove the hyphens from the UUID + uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-') + + echo -n "$uuid_no_hyphens" > "$out/diskId" + ''; + }; + }; +} diff --git a/clanModules/iwd/default.nix b/clanModules/iwd/default.nix index 32158e143..ed6af3368 100644 --- a/clanModules/iwd/default.nix +++ b/clanModules/iwd/default.nix @@ -1,86 +1,6 @@ -{ lib, config, ... }: - -let - cfg = config.clan.iwd; - secret_path = ssid: config.clan.core.facts.services."iwd.${ssid}".secret."iwd.${ssid}".path; - secret_generator = name: value: { - name = "iwd.${value.ssid}"; - value = - let - secret_name = "iwd.${value.ssid}"; - in - { - secret.${secret_name} = { }; - generator.prompt = "Wifi password for '${value.ssid}'"; - generator.script = '' - config=" - [Security] - Passphrase=$prompt_value - " - echo "$config" > $secrets/${secret_name} - ''; - }; - }; -in +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - options.clan.iwd = { - networks = lib.mkOption { - type = lib.types.attrsOf ( - lib.types.submodule ( - { name, ... }: - { - options = { - ssid = lib.mkOption { - type = lib.types.str; - default = name; - description = "The name of the wifi network"; - }; - }; - } - ) - ); - default = { }; - description = "Wifi networks to predefine"; - }; - }; - - imports = [ - (lib.mkRemovedOptionModule [ - "clan" - "iwd" - "enable" - ] "Just define clan.iwd.networks to enable it") - ]; - - config = lib.mkMerge [ - (lib.mkIf (cfg.networks != { }) { - # Systemd tmpfiles rule to create /var/lib/iwd/example.psk file - systemd.tmpfiles.rules = lib.mapAttrsToList ( - _: value: "C /var/lib/iwd/${value.ssid}.psk 0600 root root - ${secret_path value.ssid}" - ) cfg.networks; - - clan.core.facts.services = lib.mapAttrs' secret_generator cfg.networks; - - # TODO: restart the iwd.service if something changes - }) - { - # disable wpa supplicant - networking.wireless.enable = false; - - # Set the network manager backend to iwd - networking.networkmanager.wifi.backend = "iwd"; - - # Use iwd instead of wpa_supplicant. It has a user friendly CLI - networking.wireless.iwd = { - enable = true; - settings = { - Network = { - EnableIPv6 = true; - RoutePriorityOffset = 300; - }; - Settings.AutoConnect = true; - }; - }; - } - ]; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/iwd/roles/default.nix b/clanModules/iwd/roles/default.nix new file mode 100644 index 000000000..32158e143 --- /dev/null +++ b/clanModules/iwd/roles/default.nix @@ -0,0 +1,86 @@ +{ lib, config, ... }: + +let + cfg = config.clan.iwd; + secret_path = ssid: config.clan.core.facts.services."iwd.${ssid}".secret."iwd.${ssid}".path; + secret_generator = name: value: { + name = "iwd.${value.ssid}"; + value = + let + secret_name = "iwd.${value.ssid}"; + in + { + secret.${secret_name} = { }; + generator.prompt = "Wifi password for '${value.ssid}'"; + generator.script = '' + config=" + [Security] + Passphrase=$prompt_value + " + echo "$config" > $secrets/${secret_name} + ''; + }; + }; +in +{ + options.clan.iwd = { + networks = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + options = { + ssid = lib.mkOption { + type = lib.types.str; + default = name; + description = "The name of the wifi network"; + }; + }; + } + ) + ); + default = { }; + description = "Wifi networks to predefine"; + }; + }; + + imports = [ + (lib.mkRemovedOptionModule [ + "clan" + "iwd" + "enable" + ] "Just define clan.iwd.networks to enable it") + ]; + + config = lib.mkMerge [ + (lib.mkIf (cfg.networks != { }) { + # Systemd tmpfiles rule to create /var/lib/iwd/example.psk file + systemd.tmpfiles.rules = lib.mapAttrsToList ( + _: value: "C /var/lib/iwd/${value.ssid}.psk 0600 root root - ${secret_path value.ssid}" + ) cfg.networks; + + clan.core.facts.services = lib.mapAttrs' secret_generator cfg.networks; + + # TODO: restart the iwd.service if something changes + }) + { + # disable wpa supplicant + networking.wireless.enable = false; + + # Set the network manager backend to iwd + networking.networkmanager.wifi.backend = "iwd"; + + # Use iwd instead of wpa_supplicant. It has a user friendly CLI + networking.wireless.iwd = { + enable = true; + settings = { + Network = { + EnableIPv6 = true; + RoutePriorityOffset = 300; + }; + Settings.AutoConnect = true; + }; + }; + } + ]; +} diff --git a/clanModules/machine-id/default.nix b/clanModules/machine-id/default.nix index 8d260c260..ed6af3368 100644 --- a/clanModules/machine-id/default.nix +++ b/clanModules/machine-id/default.nix @@ -1,45 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - config, - pkgs, - lib, - ... -}: - -let - var = config.clan.core.vars.generators.machine-id.files.machineId or { }; -in -{ - config = lib.mkMerge [ - (lib.mkIf ((var.machineId.value or null) != null) { - assertions = [ - { - assertion = lib.stringLength var.machineId.value == 32; - message = "machineId must be exactly 32 characters long."; - } - ]; - boot.kernelParams = [ - ''systemd.machine_id=${var.machineId.value}'' - ]; - environment.etc."machine-id" = { - text = var.machineId.value; - }; - }) - { - clan.core.vars.generators.machine-id = { - files.machineId.secret = false; - runtimeInputs = [ - pkgs.coreutils - pkgs.bash - ]; - script = '' - uuid=$(bash ${../uuid4.sh}) - - # Remove the hyphens from the UUID - uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-') - - echo -n "$uuid_no_hyphens" > "$out/machineId" - ''; - }; - } - ]; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/machine-id/roles/default.nix b/clanModules/machine-id/roles/default.nix new file mode 100644 index 000000000..8d260c260 --- /dev/null +++ b/clanModules/machine-id/roles/default.nix @@ -0,0 +1,45 @@ +{ + config, + pkgs, + lib, + ... +}: + +let + var = config.clan.core.vars.generators.machine-id.files.machineId or { }; +in +{ + config = lib.mkMerge [ + (lib.mkIf ((var.machineId.value or null) != null) { + assertions = [ + { + assertion = lib.stringLength var.machineId.value == 32; + message = "machineId must be exactly 32 characters long."; + } + ]; + boot.kernelParams = [ + ''systemd.machine_id=${var.machineId.value}'' + ]; + environment.etc."machine-id" = { + text = var.machineId.value; + }; + }) + { + clan.core.vars.generators.machine-id = { + files.machineId.secret = false; + runtimeInputs = [ + pkgs.coreutils + pkgs.bash + ]; + script = '' + uuid=$(bash ${../uuid4.sh}) + + # Remove the hyphens from the UUID + uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-') + + echo -n "$uuid_no_hyphens" > "$out/machineId" + ''; + }; + } + ]; +} diff --git a/clanModules/packages/default.nix b/clanModules/packages/default.nix index 1f5c323e8..ed6af3368 100644 --- a/clanModules/packages/default.nix +++ b/clanModules/packages/default.nix @@ -1,19 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - config, - lib, - pkgs, - ... -}: -{ - options.clan.packages = { - packages = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "The packages to install on the machine"; - }; - }; - config = { - environment.systemPackages = map ( - pName: lib.getAttrFromPath (lib.splitString "." pName) pkgs - ) config.clan.packages.packages; - }; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/packages/roles/default.nix b/clanModules/packages/roles/default.nix new file mode 100644 index 000000000..1f5c323e8 --- /dev/null +++ b/clanModules/packages/roles/default.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.clan.packages = { + packages = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "The packages to install on the machine"; + }; + }; + config = { + environment.systemPackages = map ( + pName: lib.getAttrFromPath (lib.splitString "." pName) pkgs + ) config.clan.packages.packages; + }; +} diff --git a/clanModules/single-disk/default.nix b/clanModules/single-disk/default.nix index 64edc68d6..8fdf356eb 100644 --- a/clanModules/single-disk/default.nix +++ b/clanModules/single-disk/default.nix @@ -1,55 +1,3 @@ -{ lib, config, ... }: { - options.clan.single-disk = { - device = lib.mkOption { - default = null; - type = lib.types.nullOr lib.types.str; - description = "The primary disk device to install the system on"; - }; - }; - config = { - warnings = [ - "clanModules.single-disk is deprecated. Please copy the disko config from the module into your machine config." - ]; - - boot.loader.grub.efiSupport = lib.mkDefault true; - boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true; - disko.devices = { - disk = { - main = { - type = "disk"; - # This is set through the UI - device = config.clan.single-disk.device; - - content = { - type = "gpt"; - partitions = { - boot = { - size = "1M"; - type = "EF02"; # for grub MBR - priority = 1; - }; - ESP = { - size = "512M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - root = { - size = "100%"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - }; - }; - }; - }; - }; - }; - }; - }; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/single-disk/roles/default.nix b/clanModules/single-disk/roles/default.nix new file mode 100644 index 000000000..64edc68d6 --- /dev/null +++ b/clanModules/single-disk/roles/default.nix @@ -0,0 +1,55 @@ +{ lib, config, ... }: +{ + options.clan.single-disk = { + device = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = "The primary disk device to install the system on"; + }; + }; + config = { + warnings = [ + "clanModules.single-disk is deprecated. Please copy the disko config from the module into your machine config." + ]; + + boot.loader.grub.efiSupport = lib.mkDefault true; + boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true; + disko.devices = { + disk = { + main = { + type = "disk"; + # This is set through the UI + device = config.clan.single-disk.device; + + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; # for grub MBR + priority = 1; + }; + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/clanModules/state-version/default.nix b/clanModules/state-version/default.nix index 679b750d1..ed6af3368 100644 --- a/clanModules/state-version/default.nix +++ b/clanModules/state-version/default.nix @@ -1,18 +1,6 @@ -{ config, lib, ... }: -let - var = config.clan.core.vars.generators.state-version.files.version or { }; -in +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - system.stateVersion = lib.mkDefault var.value; - - clan.core.vars.generators.state-version = { - files.version = { - secret = false; - value = lib.mkDefault lib.version; - }; - runtimeInputs = [ ]; - script = '' - echo -n ${lib.versions.majorMinor config.system.stateVersion} > $out/version - ''; - }; + imports = [ ./roles/default.nix ]; } diff --git a/clanModules/state-version/roles/default.nix b/clanModules/state-version/roles/default.nix new file mode 100644 index 000000000..679b750d1 --- /dev/null +++ b/clanModules/state-version/roles/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +let + var = config.clan.core.vars.generators.state-version.files.version or { }; +in +{ + system.stateVersion = lib.mkDefault var.value; + + clan.core.vars.generators.state-version = { + files.version = { + secret = false; + value = lib.mkDefault lib.version; + }; + runtimeInputs = [ ]; + script = '' + echo -n ${lib.versions.majorMinor config.system.stateVersion} > $out/version + ''; + }; +} diff --git a/lib/inventory/build-inventory/default.nix b/lib/inventory/build-inventory/default.nix index 8d6e25bcf..008a662a2 100644 --- a/lib/inventory/build-inventory/default.nix +++ b/lib/inventory/build-inventory/default.nix @@ -119,7 +119,7 @@ let acc2 ++ [ { - imports = [ clan-core.clanModules.${serviceName} ] ++ roleModules ++ extraModules; + imports = roleModules ++ extraModules; } (lib.optionalAttrs (globalConfig != { } || machineServiceConfig != { } || roleServiceConfigs != [ ]) {