diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/from_md/release-notes/rl-2211.section.xml | 7 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2211.section.md | 2 | ||||
-rw-r--r-- | nixos/lib/make-options-doc/options-to-docbook.xsl | 4 | ||||
-rw-r--r-- | nixos/lib/testing-python.nix | 10 | ||||
-rw-r--r-- | nixos/lib/testing/nodes.nix | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/karma.nix | 128 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/vmagent.nix | 100 | ||||
-rw-r--r-- | nixos/modules/services/printing/cupsd.nix | 14 | ||||
-rw-r--r-- | nixos/modules/services/system/cachix-watch-store.nix | 87 | ||||
-rw-r--r-- | nixos/modules/virtualisation/oci-containers.nix | 7 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/karma.nix | 84 | ||||
-rw-r--r-- | nixos/tests/make-test-python.nix | 4 | ||||
-rw-r--r-- | nixos/tests/printing.nix | 1 |
15 files changed, 440 insertions, 13 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 6906f46e7fe09..a88a8c0a015ae 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -265,6 +265,13 @@ </listitem> <listitem> <para> + <link xlink:href="https://github.com/prymitive/karma">karma</link>, + an alert dashboard for Prometheus Alertmanager. Available as + <link xlink:href="options.html#opt-services.karma.enable">services.karma</link> + </para> + </listitem> + <listitem> + <para> <link xlink:href="https://languagetool.org/">languagetool</link>, a multilingual grammar, style, and spell checker. Available as <link xlink:href="options.html#opt-services.languagetool.enable">services.languagetool</link>. diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 6e7592cc63010..8f0d4f74810c8 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -93,6 +93,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [kanata](https://github.com/jtroo/kanata), a tool to improve keyboard comfort and usability with advanced customization. Available as [services.kanata](options.html#opt-services.kanata.enable). +- [karma](https://github.com/prymitive/karma), an alert dashboard for Prometheus Alertmanager. Available as [services.karma](options.html#opt-services.karma.enable) + - [languagetool](https://languagetool.org/), a multilingual grammar, style, and spell checker. Available as [services.languagetool](options.html#opt-services.languagetool.enable). diff --git a/nixos/lib/make-options-doc/options-to-docbook.xsl b/nixos/lib/make-options-doc/options-to-docbook.xsl index d5b921b1dedb3..0fe14a6d2d169 100644 --- a/nixos/lib/make-options-doc/options-to-docbook.xsl +++ b/nixos/lib/make-options-doc/options-to-docbook.xsl @@ -40,8 +40,8 @@ concat($optionIdPrefix, translate( attr[@name = 'name']/string/@value, - '*< >[]:', - '_______' + '*< >[]:"', + '________' ))" /> <varlistentry> <term xlink:href="#{$id}"> diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index f63b6c78f6da3..d7204a2bc1434 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -29,7 +29,9 @@ rec { }; }; - # Make a full-blown test + # Make a full-blown test (legacy) + # For an official public interface to the tests, see + # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests makeTest = { machine ? null , nodes ? {} @@ -48,7 +50,8 @@ rec { else builtins.unsafeGetAttrPos "testScript" t) , extraPythonPackages ? (_ : []) , interactive ? {} - } @ t: + } @ t: let + testConfig = (evalTest { imports = [ { _file = "makeTest parameters"; config = t; } @@ -60,6 +63,9 @@ rec { } ]; }).config; + in + testConfig.test # For nix-build + // testConfig; # For all-tests.nix simpleTest = as: (makeTest as).test; diff --git a/nixos/lib/testing/nodes.nix b/nixos/lib/testing/nodes.nix index 0395238cbaae7..8e620c96b3bb1 100644 --- a/nixos/lib/testing/nodes.nix +++ b/nixos/lib/testing/nodes.nix @@ -101,7 +101,7 @@ in nodesCompat = mapAttrs (name: config: config // { - config = lib.warn + config = lib.warnIf (lib.isInOldestRelease 2211) "Module argument `nodes.${name}.config` is deprecated. Use `nodes.${name}` instead." config; }) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c400fadef3a2a..33d27796b2965 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -684,6 +684,7 @@ ./services/monitoring/heapster.nix ./services/monitoring/incron.nix ./services/monitoring/kapacitor.nix + ./services/monitoring/karma.nix ./services/monitoring/kthxbye.nix ./services/monitoring/loki.nix ./services/monitoring/longview.nix @@ -714,6 +715,7 @@ ./services/monitoring/unifi-poller.nix ./services/monitoring/ups.nix ./services/monitoring/uptime.nix + ./services/monitoring/vmagent.nix ./services/monitoring/vnstat.nix ./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-proxy.nix diff --git a/nixos/modules/services/monitoring/karma.nix b/nixos/modules/services/monitoring/karma.nix new file mode 100644 index 0000000000000..85dbc81f443f0 --- /dev/null +++ b/nixos/modules/services/monitoring/karma.nix @@ -0,0 +1,128 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.services.karma; + yaml = pkgs.formats.yaml { }; +in +{ + options.services.karma = { + enable = mkEnableOption (mdDoc "the Karma dashboard service"); + + package = mkOption { + type = types.package; + default = pkgs.karma; + defaultText = literalExpression "pkgs.karma"; + description = mdDoc '' + The Karma package that should be used. + ''; + }; + + configFile = mkOption { + type = types.path; + default = yaml.generate "karma.yaml" cfg.settings; + defaultText = "A configuration file generated from the provided nix attributes settings option."; + description = mdDoc '' + A YAML config file which can be used to configure karma instead of the nix-generated file. + ''; + example = "/etc/karma/karma.conf"; + }; + + environment = mkOption { + type = with types; attrsOf str; + default = {}; + description = mdDoc '' + Additional environment variables to provide to karma. + ''; + example = { + ALERTMANAGER_URI = "https://alertmanager.example.com"; + ALERTMANAGER_NAME= "single"; + }; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Whether to open ports in the firewall needed for karma to function. + ''; + }; + + extraOptions = mkOption { + type = with types; listOf str; + default = []; + description = mdDoc '' + Extra command line options. + ''; + example = [ + "--alertmanager.timeout 10s" + ]; + }; + + settings = mkOption { + type = types.submodule { + freeformType = yaml.type; + + options.listen = { + address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = mdDoc '' + Hostname or IP to listen on. + ''; + example = "[::]"; + }; + + port = mkOption { + type = types.port; + default = 8080; + description = mdDoc '' + HTTP port to listen on. + ''; + example = 8182; + }; + }; + }; + default = { + listen = { + address = "127.0.0.1"; + }; + }; + description = mdDoc '' + Karma dashboard configuration as nix attributes. + + Reference: <https://github.com/prymitive/karma/blob/main/docs/CONFIGURATION.md> + ''; + example = { + listen = { + address = "192.168.1.4"; + port = "8000"; + prefix = "/dashboard"; + }; + alertmanager = { + interval = "15s"; + servers = [ + { + name = "prod"; + uri = "http://alertmanager.example.com"; + } + ]; + }; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.karma = { + description = "Alert dashboard for Prometheus Alertmanager"; + wantedBy = [ "multi-user.target" ]; + environment = cfg.environment; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + Restart = "on-failure"; + ExecStart = "${pkgs.karma}/bin/karma --config.file ${cfg.configFile} ${concatStringsSep " " cfg.extraOptions}"; + }; + }; + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.listen.port ]; + }; +} diff --git a/nixos/modules/services/monitoring/vmagent.nix b/nixos/modules/services/monitoring/vmagent.nix new file mode 100644 index 0000000000000..c793bb073199c --- /dev/null +++ b/nixos/modules/services/monitoring/vmagent.nix @@ -0,0 +1,100 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.services.vmagent; + settingsFormat = pkgs.formats.json { }; +in { + options.services.vmagent = { + enable = mkEnableOption (lib.mdDoc "vmagent"); + + user = mkOption { + default = "vmagent"; + type = types.str; + description = lib.mdDoc '' + User account under which vmagent runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "vmagent"; + description = lib.mdDoc '' + Group under which vmagent runs. + ''; + }; + + package = mkOption { + default = pkgs.vmagent; + defaultText = lib.literalMD "pkgs.vmagent"; + type = types.package; + description = lib.mdDoc '' + vmagent package to use. + ''; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/vmagent"; + description = lib.mdDoc '' + The directory where vmagent stores its data files. + ''; + }; + + remoteWriteUrl = mkOption { + default = "http://localhost:8428/api/v1/write"; + type = types.str; + description = lib.mdDoc '' + The storage endpoint such as VictoriaMetrics + ''; + }; + + prometheusConfig = mkOption { + type = lib.types.submodule { freeformType = settingsFormat.type; }; + description = lib.mdDoc '' + Config for prometheus style metrics + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Whether to open the firewall for the default ports. + ''; + }; + }; + + config = mkIf cfg.enable { + users.groups = mkIf (cfg.group == "vmagent") { vmagent = { }; }; + + users.users = mkIf (cfg.user == "vmagent") { + vmagent = { + group = cfg.group; + description = "vmagent daemon user"; + home = cfg.dataDir; + isSystemUser = true; + }; + }; + + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 8429 ]; + + systemd.services.vmagent = let + prometheusConfig = settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig; + in { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "vmagent system service"; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Type = "simple"; + Restart = "on-failure"; + WorkingDirectory = cfg.dataDir; + ExecStart = "${cfg.package}/bin/vmagent -remoteWrite.url=${cfg.remoteWriteUrl} -promscrape.config=${prometheusConfig}"; + }; + }; + + systemd.tmpfiles.rules = + [ "d '${cfg.dataDir}' 0755 ${cfg.user} ${cfg.group} -" ]; + }; +} diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix index fea7ffb673ca0..ae59dcc226de8 100644 --- a/nixos/modules/services/printing/cupsd.nix +++ b/nixos/modules/services/printing/cupsd.nix @@ -134,6 +134,15 @@ in ''; }; + stateless = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + If set, all state directories relating to CUPS will be removed on + startup of the service. + ''; + }; + startWhenNeeded = mkOption { type = types.bool; default = true; @@ -343,8 +352,9 @@ in path = [ cups.out ]; - preStart = - '' + preStart = lib.optionalString cfg.stateless '' + rm -rf /var/cache/cups /var/lib/cups /var/spool/cups + '' + '' mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/spool/cups mkdir -m 0755 -p ${cfg.tempDir} diff --git a/nixos/modules/services/system/cachix-watch-store.nix b/nixos/modules/services/system/cachix-watch-store.nix new file mode 100644 index 0000000000000..ec73c0bcdcfe5 --- /dev/null +++ b/nixos/modules/services/system/cachix-watch-store.nix @@ -0,0 +1,87 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.cachix-watch-store; +in +{ + meta.maintainers = [ lib.maintainers.jfroche lib.maintainers.domenkozar ]; + + options.services.cachix-watch-store = { + enable = mkEnableOption (lib.mdDoc "Cachix Watch Store: https://docs.cachix.org"); + + cacheName = mkOption { + type = types.str; + description = lib.mdDoc "Cachix binary cache name"; + }; + + cachixTokenFile = mkOption { + type = types.path; + description = lib.mdDoc '' + Required file that needs to contain the cachix auth token. + ''; + }; + + compressionLevel = mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "The compression level for XZ compression (between 0 and 9)"; + default = null; + }; + + jobs = mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "Number of threads used for pushing store paths"; + default = null; + }; + + host = mkOption { + type = types.nullOr types.str; + default = null; + description = lib.mdDoc "Cachix host to connect to"; + }; + + verbose = mkOption { + type = types.bool; + description = lib.mdDoc "Enable verbose output"; + default = false; + }; + + package = mkOption { + type = types.package; + default = pkgs.cachix; + defaultText = literalExpression "pkgs.cachix"; + description = lib.mdDoc "Cachix Client package to use."; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.cachix-watch-store-agent = { + description = "Cachix watch store Agent"; + after = [ "network-online.target" ]; + path = [ config.nix.package ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + # we don't want to kill children processes as those are deployments + KillMode = "process"; + Restart = "on-failure"; + DynamicUser = true; + LoadCredential = [ + "cachix-token:${toString cfg.cachixTokenFile}" + ]; + }; + script = + let + command = [ "${cfg.package}/bin/cachix" ] + ++ (lib.optional cfg.verbose "--verbose") ++ (lib.optionals (cfg.host != null) [ "--host" cfg.host ]) + ++ [ "watch-store" ] ++ (lib.optionals (cfg.compressionLevel != null) [ "--compression-level" (toString cfg.compressionLevel) ]) + ++ (lib.optionals (cfg.jobs != null) [ "--jobs" (toString cfg.jobs) ]) ++ [ cfg.cacheName ]; + in + '' + export CACHIX_AUTH_TOKEN="$(<"$CREDENTIALS_DIRECTORY/cachix-token")" + ${lib.escapeShellArgs command} + ''; + }; + }; +} diff --git a/nixos/modules/virtualisation/oci-containers.nix b/nixos/modules/virtualisation/oci-containers.nix index 36a28efc6ce44..61066c3cbd758 100644 --- a/nixos/modules/virtualisation/oci-containers.nix +++ b/nixos/modules/virtualisation/oci-containers.nix @@ -304,12 +304,13 @@ let # ExecReload = ...; ### - Environment=if cfg.backend == "podman" then "PODMAN_SYSTEMD_UNIT=podman-${name}.service" else {}; - Type=if cfg.backend == "podman" then "notify" else {}; - NotifyAccess=if cfg.backend == "podman" then "all" else {}; TimeoutStartSec = 0; TimeoutStopSec = 120; Restart = "always"; + } // optionalAttrs (cfg.backend == "podman") { + Environment="PODMAN_SYSTEMD_UNIT=podman-${name}.service"; + Type="notify"; + NotifyAccess="all"; }; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index b6fffd8de838d..9dfa83a907deb 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -299,6 +299,7 @@ in { k3s = handleTest ./k3s {}; kafka = handleTest ./kafka.nix {}; kanidm = handleTest ./kanidm.nix {}; + karma = handleTest ./karma.nix {}; kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {}; kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {}; kea = handleTest ./kea.nix {}; diff --git a/nixos/tests/karma.nix b/nixos/tests/karma.nix new file mode 100644 index 0000000000000..5ac2983b8aa3e --- /dev/null +++ b/nixos/tests/karma.nix @@ -0,0 +1,84 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "karma"; + nodes = { + server = { ... }: { + services.prometheus.alertmanager = { + enable = true; + logLevel = "debug"; + port = 9093; + openFirewall = true; + configuration = { + global = { + resolve_timeout = "1m"; + }; + route = { + # Root route node + receiver = "test"; + group_by = ["..."]; + continue = false; + group_wait = "1s"; + group_interval="15s"; + repeat_interval = "24h"; + }; + receivers = [ + { + name = "test"; + webhook_configs = [ + { + url = "http://localhost:1234"; + send_resolved = true; + max_alerts = 0; + } + ]; + } + ]; + }; + }; + services.karma = { + enable = true; + openFirewall = true; + settings = { + listen = { + address = "0.0.0.0"; + port = 8081; + }; + alertmanager = { + servers = [ + { + name = "alertmanager"; + uri = "https://127.0.0.1:9093"; + } + ]; + }; + karma.name = "test-dashboard"; + log.config = true; + log.requests = true; + log.timestamp = true; + }; + }; + }; + }; + + testScript = '' + start_all() + + with subtest("Wait for server to come up"): + + server.wait_for_unit("alertmanager.service") + server.wait_for_unit("karma.service") + + server.sleep(5) # wait for both services to settle + + server.wait_for_open_port(9093) + server.wait_for_open_port(8081) + + with subtest("Test alertmanager readiness"): + server.succeed("curl -s http://127.0.0.1:9093/-/ready") + + # Karma only starts serving the dashboard once it has established connectivity to all alertmanagers in its config + # Therefore, this will fail if karma isn't able to reach alertmanager + server.succeed("curl -s http://127.0.0.1:8081") + + server.shutdown() + ''; +}) diff --git a/nixos/tests/make-test-python.nix b/nixos/tests/make-test-python.nix index c3bbd67423726..7a96f538d8d7a 100644 --- a/nixos/tests/make-test-python.nix +++ b/nixos/tests/make-test-python.nix @@ -6,6 +6,4 @@ f: { with import ../lib/testing-python.nix { inherit system pkgs; }; -let testConfig = makeTest (if pkgs.lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f); -in testConfig.test # For nix-build - // testConfig # For all-tests.nix +makeTest (if pkgs.lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f) diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix index 6338fd8d8ac10..cfebe232d92a0 100644 --- a/nixos/tests/printing.nix +++ b/nixos/tests/printing.nix @@ -4,6 +4,7 @@ import ./make-test-python.nix ({pkgs, ... }: let printingServer = startWhenNeeded: { services.printing.enable = true; + services.printing.stateless = true; services.printing.startWhenNeeded = startWhenNeeded; services.printing.listenAddresses = [ "*:631" ]; services.printing.defaultShared = true; |