at 23.11-beta 29 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 inherit (lib) 5 collect 6 concatLists 7 concatStringsSep 8 flip 9 getAttrFromPath 10 hasPrefix 11 isList 12 length 13 literalExpression 14 literalMD 15 mapAttrsRecursiveCond 16 mapAttrsToList 17 mdDoc 18 mkEnableOption 19 mkIf 20 mkMerge 21 mkOption 22 mkPackageOptionMD 23 optional 24 optionalAttrs 25 optionalString 26 types 27 ; 28 29 cfg = config.services.thanos; 30 31 nullOpt = type: description: mkOption { 32 type = types.nullOr type; 33 default = null; 34 description = mdDoc description; 35 }; 36 37 optionToArgs = opt: v : optional (v != null) ''--${opt}="${toString v}"''; 38 flagToArgs = opt: v : optional v "--${opt}"; 39 listToArgs = opt: vs : map (v: ''--${opt}="${v}"'') vs; 40 attrsToArgs = opt: kvs: mapAttrsToList (k: v: ''--${opt}=${k}=\"${v}\"'') kvs; 41 42 mkParamDef = type: default: description: mkParam type (description + '' 43 44 Defaults to `${toString default}` in Thanos 45 when set to `null`. 46 ''); 47 48 mkParam = type: description: { 49 toArgs = optionToArgs; 50 option = nullOpt type description; 51 }; 52 53 mkFlagParam = description: { 54 toArgs = flagToArgs; 55 option = mkOption { 56 type = types.bool; 57 default = false; 58 description = mdDoc description; 59 }; 60 }; 61 62 mkListParam = opt: description: { 63 toArgs = _opt: listToArgs opt; 64 option = mkOption { 65 type = types.listOf types.str; 66 default = []; 67 description = mdDoc description; 68 }; 69 }; 70 71 mkAttrsParam = opt: description: { 72 toArgs = _opt: attrsToArgs opt; 73 option = mkOption { 74 type = types.attrsOf types.str; 75 default = {}; 76 description = mdDoc description; 77 }; 78 }; 79 80 mkStateDirParam = opt: default: description: { 81 toArgs = _opt: stateDir: optionToArgs opt "/var/lib/${stateDir}"; 82 option = mkOption { 83 type = types.str; 84 inherit default; 85 description = mdDoc description; 86 }; 87 }; 88 89 toYAML = name: attrs: pkgs.runCommand name { 90 preferLocalBuild = true; 91 json = builtins.toFile "${name}.json" (builtins.toJSON attrs); 92 nativeBuildInputs = [ pkgs.remarshal ]; 93 } "json2yaml -i $json -o $out"; 94 95 thanos = cmd: "${cfg.package}/bin/thanos ${cmd}" + 96 (let args = cfg.${cmd}.arguments; 97 in optionalString (length args != 0) (" \\\n " + 98 concatStringsSep " \\\n " args)); 99 100 argumentsOf = cmd: concatLists (collect isList 101 (flip mapParamsRecursive params.${cmd} (path: param: 102 let opt = concatStringsSep "." path; 103 v = getAttrFromPath path cfg.${cmd}; 104 in param.toArgs opt v))); 105 106 mkArgumentsOption = cmd: mkOption { 107 type = types.listOf types.str; 108 default = argumentsOf cmd; 109 defaultText = literalMD '' 110 calculated from `config.services.thanos.${cmd}` 111 ''; 112 description = mdDoc '' 113 Arguments to the `thanos ${cmd}` command. 114 115 Defaults to a list of arguments formed by converting the structured 116 options of {option}`services.thanos.${cmd}` to a list of arguments. 117 118 Overriding this option will cause none of the structured options to have 119 any effect. So only set this if you know what you're doing! 120 ''; 121 }; 122 123 mapParamsRecursive = 124 let noParam = attr: !(attr ? toArgs && attr ? option); 125 in mapAttrsRecursiveCond noParam; 126 127 paramsToOptions = mapParamsRecursive (_path: param: param.option); 128 129 params = { 130 131 log = { 132 133 log.level = mkParamDef (types.enum ["debug" "info" "warn" "error" "fatal"]) "info" '' 134 Log filtering level. 135 ''; 136 137 log.format = mkParam types.str '' 138 Log format to use. 139 ''; 140 }; 141 142 tracing = cfg: { 143 tracing.config-file = { 144 toArgs = _opt: path: optionToArgs "tracing.config-file" path; 145 option = mkOption { 146 type = with types; nullOr str; 147 default = if cfg.tracing.config == null then null 148 else toString (toYAML "tracing.yaml" cfg.tracing.config); 149 defaultText = literalExpression '' 150 if config.services.thanos.<cmd>.tracing.config == null then null 151 else toString (toYAML "tracing.yaml" config.services.thanos.<cmd>.tracing.config); 152 ''; 153 description = mdDoc '' 154 Path to YAML file that contains tracing configuration. 155 156 See format details: <https://thanos.io/tip/thanos/tracing.md/#configuration> 157 ''; 158 }; 159 }; 160 161 tracing.config = 162 { 163 toArgs = _opt: _attrs: []; 164 option = nullOpt types.attrs '' 165 Tracing configuration. 166 167 When not `null` the attribute set gets converted to 168 a YAML file and stored in the Nix store. The option 169 {option}`tracing.config-file` will default to its path. 170 171 If {option}`tracing.config-file` is set this option has no effect. 172 173 See format details: <https://thanos.io/tip/thanos/tracing.md/#configuration> 174 ''; 175 }; 176 }; 177 178 common = cfg: params.log // params.tracing cfg // { 179 180 http-address = mkParamDef types.str "0.0.0.0:10902" '' 181 Listen `host:port` for HTTP endpoints. 182 ''; 183 184 grpc-address = mkParamDef types.str "0.0.0.0:10901" '' 185 Listen `ip:port` address for gRPC endpoints (StoreAPI). 186 187 Make sure this address is routable from other components. 188 ''; 189 190 grpc-server-tls-cert = mkParam types.str '' 191 TLS Certificate for gRPC server, leave blank to disable TLS 192 ''; 193 194 grpc-server-tls-key = mkParam types.str '' 195 TLS Key for the gRPC server, leave blank to disable TLS 196 ''; 197 198 grpc-server-tls-client-ca = mkParam types.str '' 199 TLS CA to verify clients against. 200 201 If no client CA is specified, there is no client verification on server side. 202 (tls.NoClientCert) 203 ''; 204 }; 205 206 objstore = cfg: { 207 208 objstore.config-file = { 209 toArgs = _opt: path: optionToArgs "objstore.config-file" path; 210 option = mkOption { 211 type = with types; nullOr str; 212 default = if cfg.objstore.config == null then null 213 else toString (toYAML "objstore.yaml" cfg.objstore.config); 214 defaultText = literalExpression '' 215 if config.services.thanos.<cmd>.objstore.config == null then null 216 else toString (toYAML "objstore.yaml" config.services.thanos.<cmd>.objstore.config); 217 ''; 218 description = mdDoc '' 219 Path to YAML file that contains object store configuration. 220 221 See format details: <https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage> 222 ''; 223 }; 224 }; 225 226 objstore.config = 227 { 228 toArgs = _opt: _attrs: []; 229 option = nullOpt types.attrs '' 230 Object store configuration. 231 232 When not `null` the attribute set gets converted to 233 a YAML file and stored in the Nix store. The option 234 {option}`objstore.config-file` will default to its path. 235 236 If {option}`objstore.config-file` is set this option has no effect. 237 238 See format details: <https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage> 239 ''; 240 }; 241 }; 242 243 sidecar = params.common cfg.sidecar // params.objstore cfg.sidecar // { 244 245 prometheus.url = mkParamDef types.str "http://localhost:9090" '' 246 URL at which to reach Prometheus's API. 247 248 For better performance use local network. 249 ''; 250 251 tsdb.path = { 252 toArgs = optionToArgs; 253 option = mkOption { 254 type = types.str; 255 default = "/var/lib/${config.services.prometheus.stateDir}/data"; 256 defaultText = literalExpression ''"/var/lib/''${config.services.prometheus.stateDir}/data"''; 257 description = mdDoc '' 258 Data directory of TSDB. 259 ''; 260 }; 261 }; 262 263 reloader.config-file = mkParam types.str '' 264 Config file watched by the reloader. 265 ''; 266 267 reloader.config-envsubst-file = mkParam types.str '' 268 Output file for environment variable substituted config file. 269 ''; 270 271 reloader.rule-dirs = mkListParam "reloader.rule-dir" '' 272 Rule directories for the reloader to refresh. 273 ''; 274 275 }; 276 277 store = params.common cfg.store // params.objstore cfg.store // { 278 279 stateDir = mkStateDirParam "data-dir" "thanos-store" '' 280 Data directory relative to `/var/lib` 281 in which to cache remote blocks. 282 ''; 283 284 index-cache-size = mkParamDef types.str "250MB" '' 285 Maximum size of items held in the index cache. 286 ''; 287 288 chunk-pool-size = mkParamDef types.str "2GB" '' 289 Maximum size of concurrently allocatable bytes for chunks. 290 ''; 291 292 store.limits.request-samples = mkParamDef types.int 0 '' 293 The maximum samples allowed for a single Series request. 294 The Series call fails if this limit is exceeded. 295 296 `0` means no limit. 297 298 NOTE: For efficiency the limit is internally implemented as 'chunks limit' 299 considering each chunk contains a maximum of 120 samples. 300 ''; 301 302 store.grpc.series-max-concurrency = mkParamDef types.int 20 '' 303 Maximum number of concurrent Series calls. 304 ''; 305 306 sync-block-duration = mkParamDef types.str "3m" '' 307 Repeat interval for syncing the blocks between local and remote view. 308 ''; 309 310 block-sync-concurrency = mkParamDef types.int 20 '' 311 Number of goroutines to use when syncing blocks from object storage. 312 ''; 313 314 min-time = mkParamDef types.str "0000-01-01T00:00:00Z" '' 315 Start of time range limit to serve. 316 317 Thanos Store serves only metrics, which happened later than this 318 value. Option can be a constant time in RFC3339 format or time duration 319 relative to current time, such as -1d or 2h45m. Valid duration units are 320 ms, s, m, h, d, w, y. 321 ''; 322 323 max-time = mkParamDef types.str "9999-12-31T23:59:59Z" '' 324 End of time range limit to serve. 325 326 Thanos Store serves only blocks, which happened earlier than this 327 value. Option can be a constant time in RFC3339 format or time duration 328 relative to current time, such as -1d or 2h45m. Valid duration units are 329 ms, s, m, h, d, w, y. 330 ''; 331 }; 332 333 query = params.common cfg.query // { 334 335 grpc-client-tls-secure = mkFlagParam '' 336 Use TLS when talking to the gRPC server 337 ''; 338 339 grpc-client-tls-cert = mkParam types.str '' 340 TLS Certificates to use to identify this client to the server 341 ''; 342 343 grpc-client-tls-key = mkParam types.str '' 344 TLS Key for the client's certificate 345 ''; 346 347 grpc-client-tls-ca = mkParam types.str '' 348 TLS CA Certificates to use to verify gRPC servers 349 ''; 350 351 grpc-client-server-name = mkParam types.str '' 352 Server name to verify the hostname on the returned gRPC certificates. 353 See <https://tools.ietf.org/html/rfc4366#section-3.1> 354 ''; 355 356 web.route-prefix = mkParam types.str '' 357 Prefix for API and UI endpoints. 358 359 This allows thanos UI to be served on a sub-path. This option is 360 analogous to {option}`web.route-prefix` of Promethus. 361 ''; 362 363 web.external-prefix = mkParam types.str '' 364 Static prefix for all HTML links and redirect URLs in the UI query web 365 interface. 366 367 Actual endpoints are still served on / or the 368 {option}`web.route-prefix`. This allows thanos UI to be served 369 behind a reverse proxy that strips a URL sub-path. 370 ''; 371 372 web.prefix-header = mkParam types.str '' 373 Name of HTTP request header used for dynamic prefixing of UI links and 374 redirects. 375 376 This option is ignored if the option 377 `web.external-prefix` is set. 378 379 Security risk: enable this option only if a reverse proxy in front of 380 thanos is resetting the header. 381 382 The setting `web.prefix-header="X-Forwarded-Prefix"` 383 can be useful, for example, if Thanos UI is served via Traefik reverse 384 proxy with `PathPrefixStrip` option enabled, which 385 sends the stripped prefix value in `X-Forwarded-Prefix` 386 header. This allows thanos UI to be served on a sub-path. 387 ''; 388 389 query.timeout = mkParamDef types.str "2m" '' 390 Maximum time to process query by query node. 391 ''; 392 393 query.max-concurrent = mkParamDef types.int 20 '' 394 Maximum number of queries processed concurrently by query node. 395 ''; 396 397 query.replica-labels = mkAttrsParam "query.replica-label" '' 398 Labels to treat as a replica indicator along which data is 399 400 deduplicated. 401 402 Still you will be able to query without deduplication using 403 'dedup=false' parameter. Data includes time series, recording 404 rules, and alerting rules. 405 ''; 406 407 selector-labels = mkAttrsParam "selector-label" '' 408 Query selector labels that will be exposed in info endpoint. 409 ''; 410 411 endpoints = mkListParam "endpoint" '' 412 Addresses of statically configured Thanos API servers (repeatable). 413 414 The scheme may be prefixed with 'dns+' or 'dnssrv+' to detect 415 Thanos API servers through respective DNS lookups. 416 ''; 417 418 store.sd-files = mkListParam "store.sd-files" '' 419 Path to files that contain addresses of store API servers. The path 420 can be a glob pattern. 421 ''; 422 423 store.sd-interval = mkParamDef types.str "5m" '' 424 Refresh interval to re-read file SD files. It is used as a resync fallback. 425 ''; 426 427 store.sd-dns-interval = mkParamDef types.str "30s" '' 428 Interval between DNS resolutions. 429 ''; 430 431 store.unhealthy-timeout = mkParamDef types.str "5m" '' 432 Timeout before an unhealthy store is cleaned from the store UI page. 433 ''; 434 435 query.auto-downsampling = mkFlagParam '' 436 Enable automatic adjustment (step / 5) to what source of data should 437 be used in store gateways if no 438 `max_source_resolution` param is specified. 439 ''; 440 441 query.partial-response = mkFlagParam '' 442 Enable partial response for queries if no 443 `partial_response` param is specified. 444 ''; 445 446 query.default-evaluation-interval = mkParamDef types.str "1m" '' 447 Set default evaluation interval for sub queries. 448 ''; 449 450 store.response-timeout = mkParamDef types.str "0ms" '' 451 If a Store doesn't send any data in this specified duration then a 452 Store will be ignored and partial data will be returned if it's 453 enabled. `0` disables timeout. 454 ''; 455 }; 456 457 query-frontend = params.common cfg.query-frontend // { 458 query-frontend.downstream-url = mkParamDef types.str "http://localhost:9090" '' 459 URL of downstream Prometheus Query compatible API. 460 ''; 461 }; 462 463 rule = params.common cfg.rule // params.objstore cfg.rule // { 464 465 labels = mkAttrsParam "label" '' 466 Labels to be applied to all generated metrics. 467 468 Similar to external labels for Prometheus, 469 used to identify ruler and its blocks as unique source. 470 ''; 471 472 stateDir = mkStateDirParam "data-dir" "thanos-rule" '' 473 Data directory relative to `/var/lib`. 474 ''; 475 476 rule-files = mkListParam "rule-file" '' 477 Rule files that should be used by rule manager. Can be in glob format. 478 ''; 479 480 eval-interval = mkParamDef types.str "1m" '' 481 The default evaluation interval to use. 482 ''; 483 484 tsdb.block-duration = mkParamDef types.str "2h" '' 485 Block duration for TSDB block. 486 ''; 487 488 tsdb.retention = mkParamDef types.str "48h" '' 489 Block retention time on local disk. 490 ''; 491 492 alertmanagers.urls = mkListParam "alertmanagers.url" '' 493 Alertmanager replica URLs to push firing alerts. 494 495 Ruler claims success if push to at least one alertmanager from 496 discovered succeeds. The scheme may be prefixed with 497 `dns+` or `dnssrv+` to detect 498 Alertmanager IPs through respective DNS lookups. The port defaults to 499 `9093` or the SRV record's value. The URL path is 500 used as a prefix for the regular Alertmanager API path. 501 ''; 502 503 alertmanagers.send-timeout = mkParamDef types.str "10s" '' 504 Timeout for sending alerts to alertmanager. 505 ''; 506 507 alert.query-url = mkParam types.str '' 508 The external Thanos Query URL that would be set in all alerts 'Source' field. 509 ''; 510 511 alert.label-drop = mkListParam "alert.label-drop" '' 512 Labels by name to drop before sending to alertmanager. 513 514 This allows alert to be deduplicated on replica label. 515 516 Similar Prometheus alert relabelling 517 ''; 518 519 web.route-prefix = mkParam types.str '' 520 Prefix for API and UI endpoints. 521 522 This allows thanos UI to be served on a sub-path. 523 524 This option is analogous to `--web.route-prefix` of Promethus. 525 ''; 526 527 web.external-prefix = mkParam types.str '' 528 Static prefix for all HTML links and redirect URLs in the UI query web 529 interface. 530 531 Actual endpoints are still served on / or the 532 {option}`web.route-prefix`. This allows thanos UI to be served 533 behind a reverse proxy that strips a URL sub-path. 534 ''; 535 536 web.prefix-header = mkParam types.str '' 537 Name of HTTP request header used for dynamic prefixing of UI links and 538 redirects. 539 540 This option is ignored if the option 541 {option}`web.external-prefix` is set. 542 543 Security risk: enable this option only if a reverse proxy in front of 544 thanos is resetting the header. 545 546 The header `X-Forwarded-Prefix` can be useful, for 547 example, if Thanos UI is served via Traefik reverse proxy with 548 `PathPrefixStrip` option enabled, which sends the 549 stripped prefix value in `X-Forwarded-Prefix` 550 header. This allows thanos UI to be served on a sub-path. 551 ''; 552 553 query.addresses = mkListParam "query" '' 554 Addresses of statically configured query API servers. 555 556 The scheme may be prefixed with `dns+` or 557 `dnssrv+` to detect query API servers through 558 respective DNS lookups. 559 ''; 560 561 query.sd-files = mkListParam "query.sd-files" '' 562 Path to file that contain addresses of query peers. 563 The path can be a glob pattern. 564 ''; 565 566 query.sd-interval = mkParamDef types.str "5m" '' 567 Refresh interval to re-read file SD files. (used as a fallback) 568 ''; 569 570 query.sd-dns-interval = mkParamDef types.str "30s" '' 571 Interval between DNS resolutions. 572 ''; 573 }; 574 575 compact = params.log // params.tracing cfg.compact // params.objstore cfg.compact // { 576 577 http-address = mkParamDef types.str "0.0.0.0:10902" '' 578 Listen `host:port` for HTTP endpoints. 579 ''; 580 581 stateDir = mkStateDirParam "data-dir" "thanos-compact" '' 582 Data directory relative to `/var/lib` 583 in which to cache blocks and process compactions. 584 ''; 585 586 consistency-delay = mkParamDef types.str "30m" '' 587 Minimum age of fresh (non-compacted) blocks before they are being 588 processed. Malformed blocks older than the maximum of consistency-delay 589 and 30m0s will be removed. 590 ''; 591 592 retention.resolution-raw = mkParamDef types.str "0d" '' 593 How long to retain raw samples in bucket. 594 595 `0d` - disables this retention 596 ''; 597 598 retention.resolution-5m = mkParamDef types.str "0d" '' 599 How long to retain samples of resolution 1 (5 minutes) in bucket. 600 601 `0d` - disables this retention 602 ''; 603 604 retention.resolution-1h = mkParamDef types.str "0d" '' 605 How long to retain samples of resolution 2 (1 hour) in bucket. 606 607 `0d` - disables this retention 608 ''; 609 610 startAt = { 611 toArgs = _opt: startAt: flagToArgs "wait" (startAt == null); 612 option = nullOpt types.str '' 613 When this option is set to a `systemd.time` 614 specification the Thanos compactor will run at the specified period. 615 616 When this option is `null` the Thanos compactor service 617 will run continuously. So it will not exit after all compactions have 618 been processed but wait for new work. 619 ''; 620 }; 621 622 downsampling.disable = mkFlagParam '' 623 Disables downsampling. 624 625 This is not recommended as querying long time ranges without 626 non-downsampled data is not efficient and useful e.g it is not possible 627 to render all samples for a human eye anyway 628 ''; 629 630 compact.concurrency = mkParamDef types.int 1 '' 631 Number of goroutines to use when compacting groups. 632 ''; 633 }; 634 635 downsample = params.log // params.tracing cfg.downsample // params.objstore cfg.downsample // { 636 637 stateDir = mkStateDirParam "data-dir" "thanos-downsample" '' 638 Data directory relative to `/var/lib` 639 in which to cache blocks and process downsamplings. 640 ''; 641 642 }; 643 644 receive = params.common cfg.receive // params.objstore cfg.receive // { 645 646 remote-write.address = mkParamDef types.str "0.0.0.0:19291" '' 647 Address to listen on for remote write requests. 648 ''; 649 650 stateDir = mkStateDirParam "tsdb.path" "thanos-receive" '' 651 Data directory relative to `/var/lib` of TSDB. 652 ''; 653 654 labels = mkAttrsParam "label" '' 655 External labels to announce. 656 657 This flag will be removed in the future when handling multiple tsdb 658 instances is added. 659 ''; 660 661 tsdb.retention = mkParamDef types.str "15d" '' 662 How long to retain raw samples on local storage. 663 664 `0d` - disables this retention 665 ''; 666 }; 667 668 }; 669 670 assertRelativeStateDir = cmd: { 671 assertions = [ 672 { 673 assertion = !hasPrefix "/" cfg.${cmd}.stateDir; 674 message = 675 "The option services.thanos.${cmd}.stateDir should not be an absolute directory." + 676 " It should be a directory relative to /var/lib."; 677 } 678 ]; 679 }; 680 681in { 682 683 options.services.thanos = { 684 685 package = mkPackageOptionMD pkgs "thanos" {}; 686 687 sidecar = paramsToOptions params.sidecar // { 688 enable = mkEnableOption 689 (mdDoc "the Thanos sidecar for Prometheus server"); 690 arguments = mkArgumentsOption "sidecar"; 691 }; 692 693 store = paramsToOptions params.store // { 694 enable = mkEnableOption 695 (mdDoc "the Thanos store node giving access to blocks in a bucket provider."); 696 arguments = mkArgumentsOption "store"; 697 }; 698 699 query = paramsToOptions params.query // { 700 enable = mkEnableOption 701 (mdDoc ("the Thanos query node exposing PromQL enabled Query API " + 702 "with data retrieved from multiple store nodes")); 703 arguments = mkArgumentsOption "query"; 704 }; 705 706 query-frontend = paramsToOptions params.query-frontend // { 707 enable = mkEnableOption 708 (mdDoc ("the Thanos query frontend implements a service deployed in front of queriers to 709 improve query parallelization and caching.")); 710 arguments = mkArgumentsOption "query-frontend"; 711 }; 712 713 rule = paramsToOptions params.rule // { 714 enable = mkEnableOption 715 (mdDoc ("the Thanos ruler service which evaluates Prometheus rules against" + 716 " given Query nodes, exposing Store API and storing old blocks in bucket")); 717 arguments = mkArgumentsOption "rule"; 718 }; 719 720 compact = paramsToOptions params.compact // { 721 enable = mkEnableOption 722 (mdDoc "the Thanos compactor which continuously compacts blocks in an object store bucket"); 723 arguments = mkArgumentsOption "compact"; 724 }; 725 726 downsample = paramsToOptions params.downsample // { 727 enable = mkEnableOption 728 (mdDoc "the Thanos downsampler which continuously downsamples blocks in an object store bucket"); 729 arguments = mkArgumentsOption "downsample"; 730 }; 731 732 receive = paramsToOptions params.receive // { 733 enable = mkEnableOption 734 (mdDoc ("the Thanos receiver which accept Prometheus remote write API requests and write to local tsdb")); 735 arguments = mkArgumentsOption "receive"; 736 }; 737 }; 738 739 config = mkMerge [ 740 741 (mkIf cfg.sidecar.enable { 742 assertions = [ 743 { 744 assertion = config.services.prometheus.enable; 745 message = 746 "Please enable services.prometheus when enabling services.thanos.sidecar."; 747 } 748 { 749 assertion = !(config.services.prometheus.globalConfig.external_labels == null || 750 config.services.prometheus.globalConfig.external_labels == {}); 751 message = 752 "services.thanos.sidecar requires uniquely identifying external labels " + 753 "to be configured in the Prometheus server. " + 754 "Please set services.prometheus.globalConfig.external_labels."; 755 } 756 ]; 757 systemd.services.thanos-sidecar = { 758 wantedBy = [ "multi-user.target" ]; 759 after = [ "network.target" "prometheus.service" ]; 760 serviceConfig = { 761 User = "prometheus"; 762 Restart = "always"; 763 ExecStart = thanos "sidecar"; 764 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 765 }; 766 }; 767 }) 768 769 (mkIf cfg.store.enable (mkMerge [ 770 (assertRelativeStateDir "store") 771 { 772 systemd.services.thanos-store = { 773 wantedBy = [ "multi-user.target" ]; 774 after = [ "network.target" ]; 775 serviceConfig = { 776 DynamicUser = true; 777 StateDirectory = cfg.store.stateDir; 778 Restart = "always"; 779 ExecStart = thanos "store"; 780 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 781 }; 782 }; 783 } 784 ])) 785 786 (mkIf cfg.query.enable { 787 systemd.services.thanos-query = { 788 wantedBy = [ "multi-user.target" ]; 789 after = [ "network.target" ]; 790 serviceConfig = { 791 DynamicUser = true; 792 Restart = "always"; 793 ExecStart = thanos "query"; 794 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 795 }; 796 }; 797 }) 798 799 (mkIf cfg.query-frontend.enable { 800 systemd.services.thanos-query-frontend = { 801 wantedBy = [ "multi-user.target" ]; 802 after = [ "network.target" ]; 803 serviceConfig = { 804 DynamicUser = true; 805 Restart = "always"; 806 ExecStart = thanos "query-frontend"; 807 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 808 }; 809 }; 810 }) 811 812 (mkIf cfg.rule.enable (mkMerge [ 813 (assertRelativeStateDir "rule") 814 { 815 systemd.services.thanos-rule = { 816 wantedBy = [ "multi-user.target" ]; 817 after = [ "network.target" ]; 818 serviceConfig = { 819 DynamicUser = true; 820 StateDirectory = cfg.rule.stateDir; 821 Restart = "always"; 822 ExecStart = thanos "rule"; 823 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 824 }; 825 }; 826 } 827 ])) 828 829 (mkIf cfg.compact.enable (mkMerge [ 830 (assertRelativeStateDir "compact") 831 { 832 systemd.services.thanos-compact = 833 let wait = cfg.compact.startAt == null; in { 834 wantedBy = [ "multi-user.target" ]; 835 after = [ "network.target" ]; 836 serviceConfig = { 837 Type = if wait then "simple" else "oneshot"; 838 Restart = if wait then "always" else "no"; 839 DynamicUser = true; 840 StateDirectory = cfg.compact.stateDir; 841 ExecStart = thanos "compact"; 842 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 843 }; 844 } // optionalAttrs (!wait) { inherit (cfg.compact) startAt; }; 845 } 846 ])) 847 848 (mkIf cfg.downsample.enable (mkMerge [ 849 (assertRelativeStateDir "downsample") 850 { 851 systemd.services.thanos-downsample = { 852 wantedBy = [ "multi-user.target" ]; 853 after = [ "network.target" ]; 854 serviceConfig = { 855 DynamicUser = true; 856 StateDirectory = cfg.downsample.stateDir; 857 Restart = "always"; 858 ExecStart = thanos "downsample"; 859 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 860 }; 861 }; 862 } 863 ])) 864 865 (mkIf cfg.receive.enable (mkMerge [ 866 (assertRelativeStateDir "receive") 867 { 868 systemd.services.thanos-receive = { 869 wantedBy = [ "multi-user.target" ]; 870 after = [ "network.target" ]; 871 serviceConfig = { 872 DynamicUser = true; 873 StateDirectory = cfg.receive.stateDir; 874 Restart = "always"; 875 ExecStart = thanos "receive"; 876 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 877 }; 878 }; 879 } 880 ])) 881 882 ]; 883}