diff options
Diffstat (limited to 'nixos/modules/services')
-rw-r--r-- | nixos/modules/services/desktops/accountsservice.nix | 10 | ||||
-rw-r--r-- | nixos/modules/services/desktops/geoclue2.nix | 39 | ||||
-rw-r--r-- | nixos/modules/services/desktops/zeitgeist.nix | 26 | ||||
-rw-r--r-- | nixos/modules/services/logging/syslog-ng.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/misc/synergy.nix | 12 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/datadog-agent.nix | 236 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/dd-agent/dd-agent.nix | 80 | ||||
-rw-r--r-- | nixos/modules/services/network-filesystems/samba.nix | 10 | ||||
-rw-r--r-- | nixos/modules/services/networking/dhcpcd.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/system/localtime.nix | 10 | ||||
-rw-r--r-- | nixos/modules/services/web-servers/hydron.nix | 12 | ||||
-rw-r--r-- | nixos/modules/services/x11/desktop-managers/gnome3.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/x11/display-managers/lightdm.nix | 7 | ||||
-rw-r--r-- | nixos/modules/services/x11/redshift.nix | 3 |
14 files changed, 376 insertions, 75 deletions
diff --git a/nixos/modules/services/desktops/accountsservice.nix b/nixos/modules/services/desktops/accountsservice.nix index 2a7450669ea0..933b9da2c83c 100644 --- a/nixos/modules/services/desktops/accountsservice.nix +++ b/nixos/modules/services/desktops/accountsservice.nix @@ -32,15 +32,21 @@ with lib; environment.systemPackages = [ pkgs.accountsservice ]; + # Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice + environment.pathsToLink = [ "/share/accountsservice" ]; + services.dbus.packages = [ pkgs.accountsservice ]; systemd.packages = [ pkgs.accountsservice ]; - systemd.services.accounts-daemon= { + systemd.services.accounts-daemon = { wantedBy = [ "graphical.target" ]; - } // (mkIf (!config.users.mutableUsers) { + # Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice + environment.XDG_DATA_DIRS = "${config.system.path}/share"; + + } // (optionalAttrs (!config.users.mutableUsers) { environment.NIXOS_USERS_PURE = "true"; }); }; diff --git a/nixos/modules/services/desktops/geoclue2.nix b/nixos/modules/services/desktops/geoclue2.nix index c5a000d5c6a7..dafb0af20756 100644 --- a/nixos/modules/services/desktops/geoclue2.nix +++ b/nixos/modules/services/desktops/geoclue2.nix @@ -4,6 +4,10 @@ with lib; +let + # the demo agent isn't built by default, but we need it here + package = pkgs.geoclue2.override { withDemoAgent = config.services.geoclue2.enableDemoAgent; }; +in { ###### interface @@ -21,21 +25,42 @@ with lib; ''; }; + enableDemoAgent = mkOption { + type = types.bool; + default = true; + description = '' + Whether to use the GeoClue demo agent. This should be + overridden by desktop environments that provide their own + agent. + ''; + }; + }; }; ###### implementation - config = mkIf config.services.geoclue2.enable { - environment.systemPackages = [ pkgs.geoclue2 ]; - - services.dbus.packages = [ pkgs.geoclue2 ]; - - systemd.packages = [ pkgs.geoclue2 ]; - + environment.systemPackages = [ package ]; + + services.dbus.packages = [ package ]; + + systemd.packages = [ package ]; + + # this needs to run as a user service, since it's associated with the + # user who is making the requests + systemd.user.services = mkIf config.services.geoclue2.enableDemoAgent { + "geoclue-agent" = { + description = "Geoclue agent"; + script = "${package}/libexec/geoclue-2.0/demos/agent"; + # this should really be `partOf = [ "geoclue.service" ]`, but + # we can't be part of a system service, and the agent should + # be okay with the main service coming and going + wantedBy = [ "default.target" ]; + }; + }; }; } diff --git a/nixos/modules/services/desktops/zeitgeist.nix b/nixos/modules/services/desktops/zeitgeist.nix new file mode 100644 index 000000000000..20c82ccdd56c --- /dev/null +++ b/nixos/modules/services/desktops/zeitgeist.nix @@ -0,0 +1,26 @@ +# Zeitgeist + +{ config, lib, pkgs, ... }: + +with lib; + +{ + ###### interface + + options = { + services.zeitgeist = { + enable = mkEnableOption "zeitgeist"; + }; + }; + + ###### implementation + + config = mkIf config.services.zeitgeist.enable { + + environment.systemPackages = [ pkgs.zeitgeist ]; + + services.dbus.packages = [ pkgs.zeitgeist ]; + + systemd.packages = [ pkgs.zeitgeist ]; + }; +} diff --git a/nixos/modules/services/logging/syslog-ng.nix b/nixos/modules/services/logging/syslog-ng.nix index 21be286a6e98..65e103ac2ba5 100644 --- a/nixos/modules/services/logging/syslog-ng.nix +++ b/nixos/modules/services/logging/syslog-ng.nix @@ -85,9 +85,11 @@ in { after = [ "multi-user.target" ]; # makes sure hostname etc is set serviceConfig = { Type = "notify"; + PIDFile = pidFile; StandardOutput = "null"; Restart = "on-failure"; ExecStart = "${cfg.package}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; }; }; }; diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix index 7e8eadbe5f37..b89cb41ac3ad 100644 --- a/nixos/modules/services/misc/synergy.nix +++ b/nixos/modules/services/misc/synergy.nix @@ -83,20 +83,20 @@ in config = mkMerge [ (mkIf cfgC.enable { - systemd.services."synergy-client" = { - after = [ "network.target" ]; + systemd.user.services."synergy-client" = { + after = [ "network.target" "graphical-session.target" ]; description = "Synergy client"; - wantedBy = optional cfgC.autoStart "multi-user.target"; + wantedBy = optional cfgC.autoStart "graphical-session.target"; path = [ pkgs.synergy ]; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}''; serviceConfig.Restart = "on-failure"; }; }) (mkIf cfgS.enable { - systemd.services."synergy-server" = { - after = [ "network.target" ]; + systemd.user.services."synergy-server" = { + after = [ "network.target" "graphical-session.target" ]; description = "Synergy server"; - wantedBy = optional cfgS.autoStart "multi-user.target"; + wantedBy = optional cfgS.autoStart "graphical-session.target"; path = [ pkgs.synergy ]; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }''; serviceConfig.Restart = "on-failure"; diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix new file mode 100644 index 000000000000..f8ee34ebdf88 --- /dev/null +++ b/nixos/modules/services/monitoring/datadog-agent.nix @@ -0,0 +1,236 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.datadog-agent; + + ddConf = { + dd_url = "https://app.datadoghq.com"; + skip_ssl_validation = "no"; + api_key = ""; + confd_path = "/etc/datadog-agent/conf.d"; + additional_checksd = "/etc/datadog-agent/checks.d"; + use_dogstatsd = "yes"; + } + // optionalAttrs (cfg.logLevel != null) { log_level = cfg.logLevel; } + // optionalAttrs (cfg.hostname != null) { inherit (cfg) hostname; } + // optionalAttrs (cfg.tags != null ) { tags = concatStringsSep ", " cfg.tags; } + // cfg.extraConfig; + + # Generate Datadog configuration files for each configured checks. + # This works because check configurations have predictable paths, + # and because JSON is a valid subset of YAML. + makeCheckConfigs = entries: mapAttrsToList (name: conf: { + source = pkgs.writeText "${name}-check-conf.yaml" (builtins.toJSON conf); + target = "datadog-agent/conf.d/${name}.d/conf.yaml"; + }) entries; + + defaultChecks = { + disk = cfg.diskCheck; + network = cfg.networkCheck; + }; + + # Assemble all check configurations and the top-level agent + # configuration. + etcfiles = with pkgs; with builtins; [{ + source = writeText "datadog.yaml" (toJSON ddConf); + target = "datadog-agent/datadog.yaml"; + }] ++ makeCheckConfigs (cfg.checks // defaultChecks); + + # Apply the configured extraIntegrations to the provided agent + # package. See the documentation of `dd-agent/integrations-core.nix` + # for detailed information on this. + datadogPkg = cfg.package.overrideAttrs(_: { + python = (pkgs.datadog-integrations-core cfg.extraIntegrations).python; + }); +in { + options.services.datadog-agent = { + enable = mkOption { + description = '' + Whether to enable the datadog-agent v6 monitoring service + ''; + default = false; + type = types.bool; + }; + + package = mkOption { + default = pkgs.datadog-agent; + defaultText = "pkgs.datadog-agent"; + description = '' + Which DataDog v6 agent package to use. Note that the provided + package is expected to have an overridable `python`-attribute + which configures the Python environment with the Datadog + checks. + ''; + type = types.package; + }; + + apiKeyFile = mkOption { + description = '' + Path to a file containing the Datadog API key to associate the + agent with your account. + ''; + example = "/run/keys/datadog_api_key"; + type = types.path; + }; + + tags = mkOption { + description = "The tags to mark this Datadog agent"; + example = [ "test" "service" ]; + default = null; + type = types.nullOr (types.listOf types.str); + }; + + hostname = mkOption { + description = "The hostname to show in the Datadog dashboard (optional)"; + default = null; + example = "mymachine.mydomain"; + type = types.uniq (types.nullOr types.string); + }; + + logLevel = mkOption { + description = "Logging verbosity."; + default = null; + type = types.nullOr (types.enum ["DEBUG" "INFO" "WARN" "ERROR"]); + }; + + extraIntegrations = mkOption { + default = {}; + type = types.attrs; + + description = '' + Extra integrations from the Datadog core-integrations + repository that should be built and included. + + By default the included integrations are disk, mongo, network, + nginx and postgres. + + To include additional integrations the name of the derivation + and a function to filter its dependencies from the Python + package set must be provided. + ''; + + example = { + ntp = (pythonPackages: [ pythonPackages.ntplib ]); + }; + }; + + extraConfig = mkOption { + default = {}; + type = types.attrs; + description = '' + Extra configuration options that will be merged into the + main config file <filename>datadog.yaml</filename>. + ''; + }; + + checks = mkOption { + description = '' + Configuration for all Datadog checks. Keys of this attribute + set will be used as the name of the check to create the + appropriate configuration in `conf.d/$check.d/conf.yaml`. + + The configuration is converted into JSON from the plain Nix + language configuration, meaning that you should write + configuration adhering to Datadog's documentation - but in Nix + language. + + Refer to the implementation of this module (specifically the + definition of `defaultChecks`) for an example. + + Note: The 'disk' and 'network' check are configured in + separate options because they exist by default. Attempting to + override their configuration here will have no effect. + ''; + + example = { + http_check = { + init_config = null; # sic! + instances = [ + { + name = "some-service"; + url = "http://localhost:1337/healthz"; + tags = [ "some-service" ]; + } + ]; + }; + }; + + default = {}; + + # sic! The structure of the values is up to the check, so we can + # not usefully constrain the type further. + type = with types; attrsOf attrs; + }; + + diskCheck = mkOption { + description = "Disk check config"; + type = types.attrs; + default = { + init_config = {}; + instances = [ { use-mount = "no"; } ]; + }; + }; + + networkCheck = mkOption { + description = "Network check config"; + type = types.attrs; + default = { + init_config = {}; + # Network check only supports one configured instance + instances = [ { collect_connection_state = false; + excluded_interfaces = [ "lo" "lo0" ]; } ]; + }; + }; + }; + config = mkIf cfg.enable { + environment.systemPackages = [ datadogPkg pkgs.sysstat pkgs.procps ]; + + users.extraUsers.datadog = { + description = "Datadog Agent User"; + uid = config.ids.uids.datadog; + group = "datadog"; + home = "/var/log/datadog/"; + createHome = true; + }; + + users.extraGroups.datadog.gid = config.ids.gids.datadog; + + systemd.services = let + makeService = attrs: recursiveUpdate { + path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "datadog"; + Group = "datadog"; + Restart = "always"; + RestartSec = 2; + PrivateTmp = true; + }; + restartTriggers = [ datadogPkg ] ++ map (etc: etc.source) etcfiles; + } attrs; + in { + datadog-agent = makeService { + description = "Datadog agent monitor"; + preStart = '' + chown -R datadog: /etc/datadog-agent + rm -f /etc/datadog-agent/auth_token + ''; + script = '' + export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) + exec ${datadogPkg}/bin/agent start -c /etc/datadog-agent/datadog.yaml + ''; + serviceConfig.PermissionsStartOnly = true; + }; + + dd-jmxfetch = lib.mkIf (lib.hasAttr "jmx" cfg.checks) (makeService { + description = "Datadog JMX Fetcher"; + path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ]; + serviceConfig.ExecStart = "${datadogPkg}/bin/dd-jmxfetch"; + }); + }; + + environment.etc = etcfiles; + }; +} diff --git a/nixos/modules/services/monitoring/dd-agent/dd-agent.nix b/nixos/modules/services/monitoring/dd-agent/dd-agent.nix index cf65b6c28cf2..abc8d65d58f2 100644 --- a/nixos/modules/services/monitoring/dd-agent/dd-agent.nix +++ b/nixos/modules/services/monitoring/dd-agent/dd-agent.nix @@ -114,13 +114,22 @@ let in { options.services.dd-agent = { enable = mkOption { - description = "Whether to enable the dd-agent montioring service"; + description = '' + Whether to enable the dd-agent v5 monitoring service. + For datadog-agent v6, see <option>services.datadog-agent.enable</option>. + ''; default = false; type = types.bool; }; api_key = mkOption { - description = "The Datadog API key to associate the agent with your account"; + description = '' + The Datadog API key to associate the agent with your account. + + Warning: this key is stored in cleartext within the world-readable + Nix store! Consider using the new v6 + <option>services.datadog-agent</option> module instead. + ''; example = "ae0aa6a8f08efa988ba0a17578f009ab"; type = types.str; }; @@ -188,48 +197,41 @@ in { users.groups.datadog.gid = config.ids.gids.datadog; - systemd.services.dd-agent = { - description = "Datadog agent monitor"; - path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps pkgs.gohai ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground"; - User = "datadog"; - Group = "datadog"; - Restart = "always"; - RestartSec = 2; + systemd.services = let + makeService = attrs: recursiveUpdate { + path = [ pkgs.dd-agent pkgs.python pkgs.sysstat pkgs.procps pkgs.gohai ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "datadog"; + Group = "datadog"; + Restart = "always"; + RestartSec = 2; + PrivateTmp = true; + }; + restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ]; + } attrs; + in { + dd-agent = makeService { + description = "Datadog agent monitor"; + serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground"; }; - restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ]; - }; - systemd.services.dogstatsd = { - description = "Datadog statsd"; - path = [ pkgs."dd-agent" pkgs.python pkgs.procps ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${pkgs.dd-agent}/bin/dogstatsd start"; - User = "datadog"; - Group = "datadog"; - Type = "forking"; - PIDFile = "/tmp/dogstatsd.pid"; - Restart = "always"; - RestartSec = 2; + dogstatsd = makeService { + description = "Datadog statsd"; + environment.TMPDIR = "/run/dogstatsd"; + serviceConfig = { + ExecStart = "${pkgs.dd-agent}/bin/dogstatsd start"; + Type = "forking"; + PIDFile = "/run/dogstatsd/dogstatsd.pid"; + RuntimeDirectory = "dogstatsd"; + }; }; - restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ]; - }; - systemd.services.dd-jmxfetch = lib.mkIf (cfg.jmxConfig != null) { - description = "Datadog JMX Fetcher"; - path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${pkgs.dd-agent}/bin/dd-jmxfetch"; - User = "datadog"; - Group = "datadog"; - Restart = "always"; - RestartSec = 2; + dd-jmxfetch = lib.mkIf (cfg.jmxConfig != null) { + description = "Datadog JMX Fetcher"; + path = [ pkgs.dd-agent pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ]; + serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-jmxfetch"; }; - restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig ]; }; environment.etc = etcfiles; diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index b23266e8d43a..10dc58311212 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -214,12 +214,10 @@ in } ]; # Always provide a smb.conf to shut up programs like smbclient and smbspool. - environment.etc = singleton - { source = - if cfg.enable then configFile - else pkgs.writeText "smb-dummy.conf" "# Samba is disabled."; - target = "samba/smb.conf"; - }; + environment.etc."samba/smb.conf".source = mkOptionDefault ( + if cfg.enable then configFile + else pkgs.writeText "smb-dummy.conf" "# Samba is disabled." + ); } (mkIf cfg.enable { diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index de0aa1a2c2c3..019c8fd9ec48 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -161,8 +161,8 @@ in { description = "DHCP Client"; wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target"; - after = [ "network.target" ]; wants = [ "network.target" ]; + before = [ "network.target" ]; # Stopping dhcpcd during a reconfiguration is undesirable # because it brings down the network interfaces configured by diff --git a/nixos/modules/services/system/localtime.nix b/nixos/modules/services/system/localtime.nix index b9355bbb9441..c7e897c96448 100644 --- a/nixos/modules/services/system/localtime.nix +++ b/nixos/modules/services/system/localtime.nix @@ -22,14 +22,8 @@ in { config = mkIf cfg.enable { services.geoclue2.enable = true; - security.polkit.extraConfig = '' - polkit.addRule(function(action, subject) { - if (action.id == "org.freedesktop.timedate1.set-timezone" - && subject.user == "localtimed") { - return polkit.Result.YES; - } - }); - ''; + # so polkit will pick up the rules + environment.systemPackages = [ pkgs.localtime ]; users.users = [{ name = "localtimed"; diff --git a/nixos/modules/services/web-servers/hydron.nix b/nixos/modules/services/web-servers/hydron.nix index c49efaede160..ed63230bc784 100644 --- a/nixos/modules/services/web-servers/hydron.nix +++ b/nixos/modules/services/web-servers/hydron.nix @@ -16,10 +16,10 @@ in with lib; { interval = mkOption { type = types.str; - default = "hourly"; + default = "weekly"; example = "06:00"; description = '' - How often we run hydron import and possibly fetch tags. Runs by default every hour. + How often we run hydron import and possibly fetch tags. Runs by default every week. The format is described in <citerefentry><refentrytitle>systemd.time</refentrytitle> @@ -137,9 +137,13 @@ in with lib; { systemd.timers.hydron-fetch = { description = "Automatically import paths into hydron and possibly fetch tags"; - after = [ "network.target" ]; + after = [ "network.target" "hydron.service" ]; wantedBy = [ "timers.target" ]; - timerConfig.OnCalendar = cfg.interval; + + timerConfig = { + Persistent = true; + OnCalendar = cfg.interval; + }; }; users = { diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index ee9b11928ae1..c339d24b098a 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -97,6 +97,8 @@ in { services.udisks2.enable = true; services.accounts-daemon.enable = true; services.geoclue2.enable = mkDefault true; + # GNOME should have its own geoclue agent + services.geoclue2.enableDemoAgent = false; services.dleyna-renderer.enable = mkDefault true; services.dleyna-server.enable = mkDefault true; services.gnome3.at-spi2-core.enable = true; diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index 6be15d8cdf46..dc82f7086c82 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -15,7 +15,7 @@ let inherit (pkgs) lightdm writeScript writeText; - # lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup + # lightdm runs with clearenv(), but we need a few things in the environment for X to startup xserverWrapper = writeScript "xserver-wrapper" '' #! ${pkgs.bash}/bin/bash @@ -209,9 +209,12 @@ in services.dbus.enable = true; services.dbus.packages = [ lightdm ]; - # lightdm uses the accounts daemon to rember language/window-manager per user + # lightdm uses the accounts daemon to remember language/window-manager per user services.accounts-daemon.enable = true; + # Enable the accounts daemon to find lightdm's dbus interface + environment.systemPackages = [ lightdm ]; + security.pam.services.lightdm = { allowNullPassword = true; startSession = true; diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix index 30d853841ea4..b7dd7debcb63 100644 --- a/nixos/modules/services/x11/redshift.nix +++ b/nixos/modules/services/x11/redshift.nix @@ -116,6 +116,9 @@ in { } ]; + # needed so that .desktop files are installed, which geoclue cares about + environment.systemPackages = [ cfg.package ]; + services.geoclue2.enable = mkIf (cfg.provider == "geoclue2") true; systemd.user.services.redshift = |