lol

Merge: nixos/vmalert: support multiple instances (#410856)

authored by

Maximilian Bosch and committed by
GitHub
d92e7102 435b64d2

+156 -106
+3
doc/release-notes/rl-2511.section.md
··· 24 24 25 25 - Added `rewriteURL` attribute to the nixpkgs `config`, to allow for rewriting the URLs downloaded by `fetchurl`. 26 26 27 + - `vmalert` now supports multiple instances with the option `services.vmalert.instances."".enable` 28 + et al.. 29 + 27 30 ## Nixpkgs Library {#sec-nixpkgs-release-25.11-lib} 28 31 29 32 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+1 -1
nixos/doc/manual/release-notes/rl-2305.section.md
··· 105 105 106 106 - [ivpn](https://www.ivpn.net/), a secure, private VPN with fast WireGuard connections. Available as [services.ivpn](#opt-services.ivpn.enable). 107 107 108 - - [vmalert](https://victoriametrics.com/), an alerting engine for VictoriaMetrics. Available as [services.vmalert](#opt-services.vmalert.enable). 108 + - [vmalert](https://victoriametrics.com/), an alerting engine for VictoriaMetrics. Available as [services.vmalert.instances](#opt-services.vmalert.instances._name_.enable). 109 109 110 110 - [jellyseerr](https://github.com/Fallenbagel/jellyseerr), a web-based requests manager for Jellyfin, forked from Overseerr. Available as [services.jellyseerr](#opt-services.jellyseerr.enable). 111 111
+151 -104
nixos/modules/services/monitoring/vmalert.nix
··· 10 10 11 11 format = pkgs.formats.yaml { }; 12 12 13 - confOpts = concatStringsSep " \\\n" ( 14 - mapAttrsToList mkLine (filterAttrs (_: v: v != false) cfg.settings) 15 - ); 13 + mkConfOpts = 14 + settings: 15 + concatStringsSep " \\\n" (mapAttrsToList mkLine (filterAttrs (_: v: v != false) settings)); 16 16 confType = 17 17 with types; 18 18 let ··· 33 33 concatMapStringsSep " " (v: "-${key}=${escapeShellArg (toString v)}") value 34 34 else 35 35 "-${key}=${escapeShellArg (toString value)}"; 36 + 37 + vmalertName = name: "vmalert" + lib.optionalString (name != "") ("-" + name); 38 + enabledInstances = lib.filterAttrs (name: conf: conf.enable) config.services.vmalert.instances; 36 39 in 37 40 { 41 + imports = [ 42 + (lib.mkRenamedOptionModule 43 + [ "services" "vmalert" "enable" ] 44 + [ "services" "vmalert" "instances" "" "enable" ] 45 + ) 46 + (lib.mkRenamedOptionModule 47 + [ "services" "vmalert" "rules" ] 48 + [ "services" "vmalert" "instances" "" "rules" ] 49 + ) 50 + (lib.mkRenamedOptionModule 51 + [ "services" "vmalert" "settings" ] 52 + [ "services" "vmalert" "instances" "" "settings" ] 53 + ) 54 + ]; 55 + 38 56 # interface 39 - options.services.vmalert = { 40 - enable = lib.mkOption { 41 - type = lib.types.bool; 42 - default = false; 43 - description = '' 44 - Wether to enable VictoriaMetrics's `vmalert`. 57 + options.services.vmalert.package = mkPackageOption pkgs "victoriametrics" { }; 45 58 46 - `vmalert` evaluates alerting and recording rules against a data source, sends notifications via Alertmanager. 47 - ''; 48 - }; 59 + options.services.vmalert.instances = mkOption { 60 + default = { }; 49 61 50 - package = mkPackageOption pkgs "victoriametrics" { }; 62 + description = '' 63 + Define multiple instances of vmalert. 64 + ''; 51 65 52 - settings = mkOption { 53 - type = types.submodule { 54 - freeformType = confType; 55 - options = { 66 + type = types.attrsOf ( 67 + types.submodule ( 68 + { name, config, ... }: 69 + { 70 + options = { 71 + enable = lib.mkOption { 72 + type = lib.types.bool; 73 + default = false; 74 + description = '' 75 + Wether to enable VictoriaMetrics's `vmalert`. 56 76 57 - "datasource.url" = mkOption { 58 - type = types.nonEmptyStr; 59 - example = "http://localhost:8428"; 60 - description = '' 61 - Datasource compatible with Prometheus HTTP API. 62 - ''; 63 - }; 77 + `vmalert` evaluates alerting and recording rules against a data source, sends notifications via Alertmanager. 78 + ''; 79 + }; 64 80 65 - "notifier.url" = mkOption { 66 - type = with types; listOf nonEmptyStr; 67 - default = [ ]; 68 - example = [ "http://127.0.0.1:9093" ]; 69 - description = '' 70 - Prometheus Alertmanager URL. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability. 71 - ''; 72 - }; 81 + settings = mkOption { 82 + type = types.submodule { 83 + freeformType = confType; 84 + options = { 73 85 74 - "rule" = mkOption { 75 - type = with types; listOf path; 76 - description = '' 77 - Path to the files with alerting and/or recording rules. 86 + "datasource.url" = mkOption { 87 + type = types.nonEmptyStr; 88 + example = "http://localhost:8428"; 89 + description = '' 90 + Datasource compatible with Prometheus HTTP API. 91 + ''; 92 + }; 93 + 94 + "notifier.url" = mkOption { 95 + type = with types; listOf nonEmptyStr; 96 + default = [ ]; 97 + example = [ "http://127.0.0.1:9093" ]; 98 + description = '' 99 + Prometheus Alertmanager URL. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability. 100 + ''; 101 + }; 78 102 79 - ::: {.note} 80 - Consider using the {option}`services.vmalert.rules` option as a convenient alternative for declaring rules 81 - directly in the `nix` language. 82 - ::: 83 - ''; 103 + "rule" = mkOption { 104 + type = with types; listOf path; 105 + description = '' 106 + Path to the files with alerting and/or recording rules. 107 + 108 + ::: {.note} 109 + Consider using the {option}`services.vmalert.instances.<name>.rules` option as a convenient alternative for declaring rules 110 + directly in the `nix` language. 111 + ::: 112 + ''; 113 + }; 114 + 115 + }; 116 + }; 117 + default = { }; 118 + example = { 119 + "datasource.url" = "http://localhost:8428"; 120 + "datasource.disableKeepAlive" = true; 121 + "datasource.showURL" = false; 122 + "rule" = [ 123 + "http://<some-server-addr>/path/to/rules" 124 + "dir/*.yaml" 125 + ]; 126 + }; 127 + description = '' 128 + `vmalert` configuration, passed via command line flags. Refer to 129 + <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#configuration> 130 + for details on supported values. 131 + ''; 132 + }; 133 + 134 + rules = mkOption { 135 + type = format.type; 136 + default = { }; 137 + example = { 138 + group = [ 139 + { 140 + name = "TestGroup"; 141 + rules = [ 142 + { 143 + alert = "ExampleAlertAlwaysFiring"; 144 + expr = '' 145 + sum by(job) 146 + (up == 1) 147 + ''; 148 + } 149 + ]; 150 + } 151 + ]; 152 + }; 153 + description = '' 154 + A list of the given alerting or recording rules against configured `"datasource.url"` compatible with 155 + Prometheus HTTP API for `vmalert` to execute. Refer to 156 + <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#rules> 157 + for details on supported values. 158 + ''; 159 + }; 84 160 }; 85 161 86 - }; 87 - }; 88 - default = { }; 89 - example = { 90 - "datasource.url" = "http://localhost:8428"; 91 - "datasource.disableKeepAlive" = true; 92 - "datasource.showURL" = false; 93 - "rule" = [ 94 - "http://<some-server-addr>/path/to/rules" 95 - "dir/*.yaml" 96 - ]; 97 - }; 98 - description = '' 99 - `vmalert` configuration, passed via command line flags. Refer to 100 - <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#configuration> 101 - for details on supported values. 102 - ''; 103 - }; 104 - 105 - rules = mkOption { 106 - type = format.type; 107 - default = { }; 108 - example = { 109 - group = [ 110 - { 111 - name = "TestGroup"; 112 - rules = [ 113 - { 114 - alert = "ExampleAlertAlwaysFiring"; 115 - expr = '' 116 - sum by(job) 117 - (up == 1) 118 - ''; 119 - } 162 + config = { 163 + settings.rule = [ 164 + "/etc/${vmalertName name}/rules.yml" 120 165 ]; 121 - } 122 - ]; 123 - }; 124 - description = '' 125 - A list of the given alerting or recording rules against configured `"datasource.url"` compatible with 126 - Prometheus HTTP API for `vmalert` to execute. Refer to 127 - <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#rules> 128 - for details on supported values. 129 - ''; 130 - }; 166 + }; 167 + } 168 + ) 169 + ); 131 170 }; 132 171 133 172 # implementation 134 - config = mkIf cfg.enable { 173 + config = mkIf (enabledInstances != { }) { 174 + environment.etc = lib.mapAttrs' ( 175 + name: 176 + { rules, ... }: 177 + lib.nameValuePair "${vmalertName name}/rules.yml" { 178 + source = format.generate "rules.yml" rules; 179 + } 180 + ) enabledInstances; 135 181 136 - environment.etc."vmalert/rules.yml".source = format.generate "rules.yml" cfg.rules; 182 + systemd.services = lib.mapAttrs' ( 183 + name: 184 + { settings, ... }: 185 + let 186 + name' = vmalertName name; 187 + in 188 + lib.nameValuePair name' { 189 + description = "vmalert service"; 190 + wantedBy = [ "multi-user.target" ]; 191 + after = [ "network.target" ]; 192 + reloadTriggers = [ config.environment.etc."${name'}/rules.yml".source ]; 137 193 138 - services.vmalert.settings.rule = [ 139 - "/etc/vmalert/rules.yml" 140 - ]; 141 - 142 - systemd.services.vmalert = { 143 - description = "vmalert service"; 144 - wantedBy = [ "multi-user.target" ]; 145 - after = [ "network.target" ]; 146 - reloadTriggers = [ config.environment.etc."vmalert/rules.yml".source ]; 147 - 148 - serviceConfig = { 149 - DynamicUser = true; 150 - Restart = "on-failure"; 151 - ExecStart = "${cfg.package}/bin/vmalert ${confOpts}"; 152 - ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"''; 153 - }; 154 - }; 194 + serviceConfig = { 195 + DynamicUser = true; 196 + Restart = "on-failure"; 197 + ExecStart = "${cfg.package}/bin/vmalert ${mkConfOpts settings}"; 198 + ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"''; 199 + }; 200 + } 201 + ) enabledInstances; 155 202 }; 156 203 }
+1 -1
nixos/tests/victoriametrics/vmalert.nix
··· 55 55 }; 56 56 }; 57 57 58 - services.vmalert = { 58 + services.vmalert.instances."" = { 59 59 enable = true; 60 60 settings = { 61 61 "datasource.url" = "http://localhost:8428"; # victoriametrics' api