nixos/prometheus: remove prometheus1 module, rename prometheus2

Prometheus 1 is no longer supported, instead 'services.prometheus'
now configures the Prometheus 2 service.
wip/yesman
WilliButz 5 years ago
parent 283d9a0942
commit bb62066225
No known key found for this signature in database
GPG Key ID: 92582A10F1179CB2
  1. 9
      nixos/doc/manual/release-notes/rl-1909.xml
  2. 3
      nixos/modules/rename.nix
  3. 544
      nixos/modules/services/monitoring/prometheus/default.nix
  4. 16
      nixos/modules/services/monitoring/thanos.nix

@ -464,7 +464,14 @@
<literal>packetbeat5</literal>) of the ELK-stack and Elastic beats have been removed.
</para>
</listitem>
<listitem>
<para>
For NixOS 19.03, both Prometheus 1 and 2 were available to allow for
a seamless transition from version 1 to 2 with existing setups.
Because Prometheus 1 is no longer developed, it was removed.
Prometheus 2 is now configured with <literal>services.prometheus</literal>.
</para>
</listitem>
</itemizedlist>
</section>

@ -52,10 +52,11 @@ with lib;
(mkRemovedOptionModule [ "services" "misc" "nzbget" "openFirewall" ] "The port used by nzbget is managed through the web interface so you should adjust your firewall rules accordingly.")
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "user" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a user setting.")
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "group" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a group setting.")
(mkRemovedOptionModule [ "services" "prometheus2" "alertmanagerURL" ] ''
(mkRemovedOptionModule [ "services" "prometheus" "alertmanagerURL" ] ''
Due to incompatibility, the alertmanagerURL option has been removed,
please use 'services.prometheus2.alertmanagers' instead.
'')
(mkRenamedOptionModule [ "services" "prometheus2" ] [ "services" "prometheus" ])
(mkRenamedOptionModule [ "services" "tor" "relay" "portSpec" ] [ "services" "tor" "relay" "port" ])
(mkRenamedOptionModule [ "services" "vmwareGuest" ] [ "virtualisation" "vmware" "guest" ])
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])

@ -4,37 +4,14 @@ with lib;
let
cfg = config.services.prometheus;
cfg2 = config.services.prometheus2;
promUser = "prometheus";
promGroup = "prometheus";
stateDir =
if cfg.stateDir != null
then cfg.stateDir
else
if cfg.dataDir != null
then
# This assumes /var/lib/ is a prefix of cfg.dataDir.
# This is checked as an assertion below.
removePrefix stateDirBase cfg.dataDir
else "prometheus";
stateDirBase = "/var/lib/";
workingDir = stateDirBase + stateDir;
workingDir2 = stateDirBase + cfg2.stateDir;
# a wrapper that verifies that the configuration is valid
promtoolCheck = what: name: file: pkgs.runCommand "${name}-${what}-checked"
{ buildInputs = [ cfg.package ]; } ''
ln -s ${file} $out
promtool ${what} $out
'';
workingDir = "/var/lib/" + cfg.stateDir;
# a wrapper that verifies that the configuration is valid for
# prometheus 2
prom2toolCheck = what: name: file:
# a wrapper that verifies that the configuration is valid
promtoolCheck = what: name: file:
pkgs.runCommand
"${name}-${replaceStrings [" "] [""] what}-checked"
{ buildInputs = [ cfg2.package ]; } ''
{ buildInputs = [ cfg.package ]; } ''
ln -s ${file} $out
promtool ${what} $out
'';
@ -45,61 +22,34 @@ let
echo '${builtins.toJSON x}' | ${pkgs.jq}/bin/jq . > $out
'';
# This becomes the main config file for Prometheus 1
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
# This becomes the main config file for Prometheus
promConfig = {
global = filterValidPrometheus cfg.globalConfig;
rule_files = map (promtoolCheck "check-rules" "rules") (cfg.ruleFiles ++ [
rule_files = map (promtoolCheck "check rules" "rules") (cfg.ruleFiles ++ [
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules))
]);
scrape_configs = filterValidPrometheus cfg.scrapeConfigs;
alerting = {
inherit (cfg) alertmanagers;
};
};
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
prometheusYml = let
yml = if cfg.configText != null then
pkgs.writeText "prometheus.yml" cfg.configText
else generatedPrometheusYml;
in promtoolCheck "check-config" "prometheus.yml" yml;
in promtoolCheck "check config" "prometheus.yml" yml;
cmdlineArgs = cfg.extraFlags ++ [
"-storage.local.path=${workingDir}/metrics"
"-config.file=${prometheusYml}"
"-web.listen-address=${cfg.listenAddress}"
"-alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
"-alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
"--storage.tsdb.path=${workingDir}/data/"
"--config.file=${prometheusYml}"
"--web.listen-address=${cfg.listenAddress}"
"--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
"--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
] ++
optional (cfg.alertmanagerURL != []) "-alertmanager.url=${concatStringsSep "," cfg.alertmanagerURL}" ++
optional (cfg.webExternalUrl != null) "-web.external-url=${cfg.webExternalUrl}";
# This becomes the main config file for Prometheus 2
promConfig2 = {
global = filterValidPrometheus cfg2.globalConfig;
rule_files = map (prom2toolCheck "check rules" "rules") (cfg2.ruleFiles ++ [
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg2.rules))
]);
scrape_configs = filterValidPrometheus cfg2.scrapeConfigs;
alerting = {
inherit (cfg2) alertmanagers;
};
};
generatedPrometheus2Yml = writePrettyJSON "prometheus.yml" promConfig2;
prometheus2Yml = let
yml = if cfg2.configText != null then
pkgs.writeText "prometheus.yml" cfg2.configText
else generatedPrometheus2Yml;
in prom2toolCheck "check config" "prometheus.yml" yml;
cmdlineArgs2 = cfg2.extraFlags ++ [
"--storage.tsdb.path=${workingDir2}/data/"
"--config.file=${prometheus2Yml}"
"--web.listen-address=${cfg2.listenAddress}"
"--alertmanager.notification-queue-capacity=${toString cfg2.alertmanagerNotificationQueueCapacity}"
"--alertmanager.timeout=${toString cfg2.alertmanagerTimeout}s"
] ++
optional (cfg2.webExternalUrl != null) "--web.external-url=${cfg2.webExternalUrl}";
optional (cfg.webExternalUrl != null) "--web.external-url=${cfg.webExternalUrl}";
filterValidPrometheus = filterAttrsListRecursive (n: v: !(n == "_module" || v == null));
filterAttrsListRecursive = pred: x:
@ -514,343 +464,159 @@ let
};
in {
options = {
services.prometheus = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the Prometheus monitoring daemon.
'';
};
package = mkOption {
type = types.package;
default = pkgs.prometheus;
defaultText = "pkgs.prometheus";
description = ''
The prometheus package that should be used.
'';
};
listenAddress = mkOption {
type = types.str;
default = "0.0.0.0:9090";
description = ''
Address to listen on for the web interface, API, and telemetry.
'';
};
dataDir = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Directory to store Prometheus metrics data.
This option is deprecated, please use <option>services.prometheus.stateDir</option>.
'';
};
stateDir = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Directory below <literal>${stateDirBase}</literal> to store Prometheus metrics data.
This directory will be created automatically using systemd's StateDirectory mechanism.
Defaults to <literal>prometheus</literal>.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching Prometheus.
'';
};
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
If non-null, this option defines the text that is written to
prometheus.yml. If null, the contents of prometheus.yml is generated
from the structured config options.
'';
};
globalConfig = mkOption {
type = promTypes.globalConfig;
default = {};
description = ''
Parameters that are valid in all configuration contexts. They
also serve as defaults for other configuration sections
'';
};
rules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Alerting and/or Recording rules to evaluate at runtime.
'';
};
ruleFiles = mkOption {
type = types.listOf types.path;
default = [];
description = ''
Any additional rules files to include in this configuration.
'';
};
options.services.prometheus = {
scrapeConfigs = mkOption {
type = types.listOf promTypes.scrape_config;
default = [];
description = ''
A list of scrape configurations.
'';
};
alertmanagerURL = mkOption {
type = types.listOf types.str;
default = [];
description = ''
List of Alertmanager URLs to send notifications to.
'';
};
alertmanagerNotificationQueueCapacity = mkOption {
type = types.int;
default = 10000;
description = ''
The capacity of the queue for pending alert manager notifications.
'';
};
alertmanagerTimeout = mkOption {
type = types.int;
default = 10;
description = ''
Alert manager HTTP API timeout (in seconds).
'';
};
webExternalUrl = mkOption {
type = types.nullOr types.str;
default = null;
example = "https://example.com/";
description = ''
The URL under which Prometheus is externally reachable (for example,
if Prometheus is served via a reverse proxy).
'';
};
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the Prometheus monitoring daemon.
'';
};
services.prometheus2 = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the Prometheus 2 monitoring daemon.
'';
};
package = mkOption {
type = types.package;
default = pkgs.prometheus;
defaultText = "pkgs.prometheus";
description = ''
The prometheus package that should be used.
'';
};
package = mkOption {
type = types.package;
default = pkgs.prometheus_2;
defaultText = "pkgs.prometheus_2";
description = ''
The prometheus2 package that should be used.
'';
};
listenAddress = mkOption {
type = types.str;
default = "0.0.0.0:9090";
description = ''
Address to listen on for the web interface, API, and telemetry.
'';
};
listenAddress = mkOption {
type = types.str;
default = "0.0.0.0:9090";
description = ''
Address to listen on for the web interface, API, and telemetry.
'';
};
stateDir = mkOption {
type = types.str;
default = "prometheus2";
description = ''
Directory below <literal>/var/lib</literal> to store Prometheus metrics data.
This directory will be created automatically using systemd's StateDirectory mechanism.
'';
};
stateDir = mkOption {
type = types.str;
default = "prometheus2";
description = ''
Directory below <literal>${stateDirBase}</literal> to store Prometheus metrics data.
This directory will be created automatically using systemd's StateDirectory mechanism.
Defaults to <literal>prometheus2</literal>.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching Prometheus.
'';
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Extra commandline options when launching Prometheus 2.
'';
};
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
If non-null, this option defines the text that is written to
prometheus.yml. If null, the contents of prometheus.yml is generated
from the structured config options.
'';
};
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
If non-null, this option defines the text that is written to
prometheus.yml. If null, the contents of prometheus.yml is generated
from the structured config options.
'';
};
globalConfig = mkOption {
type = promTypes.globalConfig;
default = {};
description = ''
Parameters that are valid in all configuration contexts. They
also serve as defaults for other configuration sections
'';
};
globalConfig = mkOption {
type = promTypes.globalConfig;
default = {};
description = ''
Parameters that are valid in all configuration contexts. They
also serve as defaults for other configuration sections
'';
};
rules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Alerting and/or Recording rules to evaluate at runtime.
'';
};
rules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Alerting and/or Recording rules to evaluate at runtime.
'';
};
ruleFiles = mkOption {
type = types.listOf types.path;
default = [];
description = ''
Any additional rules files to include in this configuration.
'';
};
ruleFiles = mkOption {
type = types.listOf types.path;
default = [];
description = ''
Any additional rules files to include in this configuration.
'';
};
scrapeConfigs = mkOption {
type = types.listOf promTypes.scrape_config;
default = [];
description = ''
A list of scrape configurations.
'';
};
scrapeConfigs = mkOption {
type = types.listOf promTypes.scrape_config;
default = [];
description = ''
A list of scrape configurations.
'';
};
alertmanagers = mkOption {
type = types.listOf types.attrs;
example = literalExample ''
[ {
scheme = "https";
path_prefix = "/alertmanager";
static_configs = [ {
targets = [
"prometheus.domain.tld"
];
} ];
} ]
'';
default = [];
description = ''
A list of alertmanagers to send alerts to.
See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config">the official documentation</link> for more information.
'';
};
alertmanagers = mkOption {
type = types.listOf types.attrs;
example = literalExample ''
[ {
scheme = "https";
path_prefix = "/alertmanager";
static_configs = [ {
targets = [
"prometheus.domain.tld"
];
} ];
} ]
'';
default = [];
description = ''
A list of alertmanagers to send alerts to.
See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config">the official documentation</link> for more information.
'';
};
alertmanagerNotificationQueueCapacity = mkOption {
type = types.int;
default = 10000;
description = ''
The capacity of the queue for pending alert manager notifications.
'';
};
alertmanagerNotificationQueueCapacity = mkOption {
type = types.int;
default = 10000;
description = ''
The capacity of the queue for pending alert manager notifications.
'';
};
alertmanagerTimeout = mkOption {
type = types.int;
default = 10;
description = ''
Alert manager HTTP API timeout (in seconds).
'';
};
alertmanagerTimeout = mkOption {
type = types.int;
default = 10;
description = ''
Alert manager HTTP API timeout (in seconds).
'';
};
webExternalUrl = mkOption {
type = types.nullOr types.str;
default = null;
example = "https://example.com/";
description = ''
The URL under which Prometheus is externally reachable (for example,
if Prometheus is served via a reverse proxy).
'';
};
};
webExternalUrl = mkOption {
type = types.nullOr types.str;
default = null;
example = "https://example.com/";
description = ''
The URL under which Prometheus is externally reachable (for example,
if Prometheus is served via a reverse proxy).
'';
};
config = mkIf cfg.enable {
users.groups.prometheus.gid = config.ids.gids.prometheus;
users.users.prometheus = {
description = "Prometheus daemon user";
uid = config.ids.uids.prometheus;
group = "prometheus";
};
};
config = mkMerge [
(mkIf (cfg.enable || cfg2.enable) {
users.groups.${promGroup}.gid = config.ids.gids.prometheus;
users.users.${promUser} = {
description = "Prometheus daemon user";
uid = config.ids.uids.prometheus;
group = promGroup;
systemd.services.prometheus = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/prometheus" +
optionalString (length cmdlineArgs != 0) (" \\\n " +
concatStringsSep " \\\n " cmdlineArgs);
User = "prometheus";
Restart = "always";
WorkingDirectory = workingDir;
StateDirectory = cfg.stateDir;
};
})
(mkIf cfg.enable {
warnings =
optional (cfg.dataDir != null) ''
The option services.prometheus.dataDir is deprecated, please use
services.prometheus.stateDir.
'';
assertions = [
{
assertion = !(cfg.dataDir != null && cfg.stateDir != null);
message =
"The options services.prometheus.dataDir and services.prometheus.stateDir" +
" can't both be set at the same time! It's recommended to only set the latter" +
" since the former is deprecated.";
}
{
assertion = cfg.dataDir != null -> hasPrefix stateDirBase cfg.dataDir;
message =
"The option services.prometheus.dataDir should have ${stateDirBase} as a prefix!";
}
{
assertion = cfg.stateDir != null -> !hasPrefix "/" cfg.stateDir;
message =
"The option services.prometheus.stateDir shouldn't be an absolute directory." +
" It should be a directory relative to ${stateDirBase}.";
}
{
assertion = cfg2.stateDir != null -> !hasPrefix "/" cfg2.stateDir;
message =
"The option services.prometheus2.stateDir shouldn't be an absolute directory." +
" It should be a directory relative to ${stateDirBase}.";
}
];
systemd.services.prometheus = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/prometheus" +
optionalString (length cmdlineArgs != 0) (" \\\n " +
concatStringsSep " \\\n " cmdlineArgs);
User = promUser;
Restart = "always";
WorkingDirectory = workingDir;
StateDirectory = stateDir;
};
};
})
(mkIf cfg2.enable {
systemd.services.prometheus2 = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${cfg2.package}/bin/prometheus" +
optionalString (length cmdlineArgs2 != 0) (" \\\n " +
concatStringsSep " \\\n " cmdlineArgs2);
User = promUser;
Restart = "always";
WorkingDirectory = workingDir2;
StateDirectory = cfg2.stateDir;
};
};
})
];
};
};
}

@ -218,8 +218,8 @@ let
toArgs = optionToArgs;
option = mkOption {
type = types.str;
default = "/var/lib/${config.services.prometheus2.stateDir}/data";
defaultText = "/var/lib/\${config.services.prometheus2.stateDir}/data";
default = "/var/lib/${config.services.prometheus.stateDir}/data";
defaultText = "/var/lib/\${config.services.prometheus.stateDir}/data";
description = ''
Data directory of TSDB.
'';
@ -679,22 +679,22 @@ in {
(mkIf cfg.sidecar.enable {
assertions = [
{
assertion = config.services.prometheus2.enable;
assertion = config.services.prometheus.enable;
message =
"Please enable services.prometheus2 when enabling services.thanos.sidecar.";
"Please enable services.prometheus when enabling services.thanos.sidecar.";
}
{
assertion = !(config.services.prometheus2.globalConfig.external_labels == null ||
config.services.prometheus2.globalConfig.external_labels == {});
assertion = !(config.services.prometheus.globalConfig.external_labels == null ||
config.services.prometheus.globalConfig.external_labels == {});
message =
"services.thanos.sidecar requires uniquely identifying external labels " +
"to be configured in the Prometheus server. " +
"Please set services.prometheus2.globalConfig.external_labels.";
"Please set services.prometheus.globalConfig.external_labels.";
}
];
systemd.services.thanos-sidecar = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "prometheus2.service" ];
after = [ "network.target" "prometheus.service" ];
serviceConfig = {
User = "prometheus";
Restart = "always";

Loading…
Cancel
Save