Commit 1699460b authored by K900's avatar K900
Browse files

Merge remote-tracking branch 'origin/master' into staging-next

parents 3f441b1a 9b5e5b0b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -140,6 +140,8 @@

- Added `nixos-init`, a Rust-based bashless initialization system for systemd initrd. This allows to build NixOS systems without any interpreter. Enable via `system.nixos-init.enable = true;`.

- [nvme-rs](https://github.com/liberodark/nvme-rs), NVMe monitoring [services.nvme-rs](#opt-services.nvme-rs.enable).

## Backward Incompatibilities {#sec-release-25.11-incompatibilities}

<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+1 −0
Original line number Diff line number Diff line
@@ -1502,6 +1502,7 @@
  ./services/system/localtimed.nix
  ./services/system/nix-daemon.nix
  ./services/system/nscd.nix
  ./services/system/nvme-rs.nix
  ./services/system/saslauthd.nix
  ./services/system/self-deploy.nix
  ./services/system/swapspace.nix
+1 −1
Original line number Diff line number Diff line
@@ -809,7 +809,7 @@ in
        default = "";
        type = lib.types.lines;
        description = ''
          Entries for the transport map, cf. man-page {manpage}`transport(8)`.
          Entries for the transport map, cf. man-page {manpage}`transport(5)`.
        '';
      };

+8 −2
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ let
in
{
  options.services.loki = {
    enable = mkEnableOption "loki";
    enable = mkEnableOption "Grafana Loki";

    user = mkOption {
      type = types.str;
@@ -49,7 +49,7 @@ in
      type = types.path;
      default = "/var/lib/loki";
      description = ''
        Specify the directory for Loki.
        Specify the data directory for Loki.
      '';
    };

@@ -58,6 +58,10 @@ in
      default = { };
      description = ''
        Specify the configuration for Loki in Nix.

        See [documentation of Grafana Loki](https://grafana.com/docs/loki/latest/configure/) for all available options.

        Cannot be specified together with {option}`services.loki.configFile`.
      '';
    };

@@ -66,6 +70,8 @@ in
      default = null;
      description = ''
        Specify a configuration file that Loki should use.

        Cannot be specified together with {option}`services.loki.configuration`.
      '';
    };

+204 −0
Original line number Diff line number Diff line
{
  config,
  options,
  lib,
  pkgs,
  ...
}:

let
  inherit (lib) types;
  cfg = config.services.nvme-rs;
  opt = options.services.nvme-rs;
  settingsFormat = pkgs.formats.toml { };
in
{
  options.services.nvme-rs = {
    enable = lib.mkEnableOption "nvme-rs, a monitoring service";

    package = lib.mkPackageOption pkgs "nvme-rs" { };

    settings = lib.mkOption {
      type = types.submodule {
        freeformType = settingsFormat.type;
        options = {
          check_interval_secs = lib.mkOption {
            type = types.int;
            default = 3600;
            description = "Check interval in seconds";
            example = 86400;
          };

          thresholds = lib.mkOption {
            type = types.submodule {
              freeformType = settingsFormat.type;
              options = {
                temp_warning = lib.mkOption {
                  type = types.int;
                  default = 55;
                  description = "Temperature warning threshold (°C)";
                };

                temp_critical = lib.mkOption {
                  type = types.int;
                  default = 65;
                  description = "Temperature critical threshold (°C)";
                };

                wear_warning = lib.mkOption {
                  type = types.int;
                  default = 20;
                  description = "Wear warning threshold (%)";
                };

                wear_critical = lib.mkOption {
                  type = types.int;
                  default = 50;
                  description = "Wear critical threshold (%)";
                };

                spare_warning = lib.mkOption {
                  type = types.int;
                  default = 50;
                  description = "Available spare warning threshold (%)";
                };

                error_threshold = lib.mkOption {
                  type = types.int;
                  default = 100;
                  description = "Error count warning threshold";
                };
              };
            };
            default = { };
            description = "Threshold configuration for NVMe monitoring";
          };

          email = lib.mkOption {
            type = types.nullOr (
              types.submodule {
                freeformType = settingsFormat.type;
                options = {
                  smtp_server = lib.mkOption {
                    type = types.str;
                    default = "smtp.gmail.com";
                    description = "SMTP server address";
                    example = "mail.example.com";
                  };

                  smtp_port = lib.mkOption {
                    type = types.port;
                    default = 587;
                    description = "SMTP server port";
                  };

                  smtp_username = lib.mkOption {
                    type = types.str;
                    description = "SMTP username";
                    example = "your-email@gmail.com";
                  };

                  smtp_password_file = lib.mkOption {
                    type = types.path;
                    description = "File containing SMTP password";
                    example = "/run/secrets/smtp-password";
                  };

                  from = lib.mkOption {
                    type = types.str;
                    description = "Sender email address";
                    example = "nvme-monitor@example.com";
                  };

                  to = lib.mkOption {
                    type = types.str;
                    description = "Recipient email address";
                    example = "admin@example.com";
                  };

                  use_tls = lib.mkOption {
                    type = types.bool;
                    default = true;
                    description = "Use TLS for SMTP connection";
                  };
                };
              }
            );
            default = null;
            description = "Email notification configuration";
          };
        };
      };
      default = { };
      description = ''
        Configuration for nvme-rs in TOML format.
        See the config.toml example for all available options.
      '';
    };
  };

  config = lib.mkIf cfg.enable {
    services.nvme-rs.settings = opt.settings.default;

    systemd.services.nvme-rs = {
      description = "NVMe health monitoring service";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      serviceConfig =
        let
          settingsWithoutNull =
            if cfg.settings.email == null then lib.removeAttrs cfg.settings [ "email" ] else cfg.settings;
          configFile = settingsFormat.generate "nvme-rs.toml" settingsWithoutNull;
        in
        {
          ExecStart = lib.escapeShellArgs [
            "${lib.getExe cfg.package}"
            "daemon"
            "--config"
            "${configFile}"
          ];

          DynamicUser = true;
          SupplementaryGroups = [ "disk" ];
          CapabilityBoundingSet = [ "CAP_SYS_ADMIN" ];
          AmbientCapabilities = [ "CAP_SYS_ADMIN" ];
          LimitCORE = 0;
          LimitNOFILE = 65535;
          LockPersonality = true;
          MemorySwapMax = 0;
          MemoryZSwapMax = 0;
          PrivateTmp = true;
          ProcSubset = "pid";
          ProtectClock = true;
          ProtectControlGroups = true;
          ProtectHome = true;
          ProtectHostname = true;
          ProtectKernelLogs = true;
          ProtectKernelModules = true;
          ProtectKernelTunables = true;
          ProtectProc = "invisible";
          ProtectSystem = "strict";
          Restart = "on-failure";
          RestartSec = "10s";
          RestrictAddressFamilies = [
            "AF_INET"
            "AF_INET6"
            "AF_UNIX"
          ];
          RestrictNamespaces = true;
          RestrictRealtime = true;
          SystemCallArchitectures = "native";
          SystemCallFilter = [
            "@system-service"
            "@resources"
            "~@privileged"
          ];
          NoNewPrivileges = true;
          UMask = "0077";
        };
    };

    environment.systemPackages = [ cfg.package ];
  };
}
Loading