diff --git a/modules/config/pulseaudio.nix b/modules/config/pulseaudio.nix
index 5dffd9d3afba..1043cca2be7e 100644
--- a/modules/config/pulseaudio.nix
+++ b/modules/config/pulseaudio.nix
@@ -1,92 +1,148 @@
{ config, pkgs, ... }:
with pkgs.lib;
+with pkgs;
-let cfg = config.hardware.pulseaudio; in
+let
-{
+ cfg = config.hardware.pulseaudio;
+
+ uid = config.ids.uids.pulseaudio;
+ gid = config.ids.gids.pulseaudio;
+
+ pulseRuntimePath = "/var/run/pulse";
+
+ # Create pulse/client.conf even if PulseAudio is disabled so
+ # that we can disable the autospawn feature in programs that
+ # are built with PulseAudio support (like KDE).
+ clientConf = writeText "client.conf" ''
+ autospawn=${if (cfg.enable && !cfg.systemWide) then "yes" else "no"}
+ ${optionalString (cfg.enable && !cfg.systemWide)
+ "daemon-binary=${cfg.package}/bin/pulseaudio"}
+ '';
+
+ # Write an /etc/asound.conf that causes all ALSA applications to
+ # be re-routed to the PulseAudio server through ALSA's Pulse
+ # plugin.
+ alsaConf = writeText "asound.conf" ''
+ pcm_type.pulse {
+ lib ${alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so
+ }
+ pcm.!default {
+ type pulse
+ hint.description "Default Audio Device (via PulseAudio)"
+ }
+ ctl_type.pulse {
+ lib ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so
+ }
+ ctl.!default {
+ type pulse
+ }
+ '';
+
+in {
options = {
- hardware.pulseaudio.enable = mkOption {
- default = false;
- description = ''
- Whether to enable the PulseAudio sound server.
- '';
- };
+ hardware.pulseaudio = {
+ enable = mkOption {
+ default = false;
+ description = ''
+ Whether to enable the PulseAudio sound server.
+ '';
+ };
- hardware.pulseaudio.package = mkOption {
- default = pkgs.pulseaudio;
- example = "pkgs.pulseaudio.override { jackaudioSupport = true; }";
- description = ''
- The PulseAudio derivation to use. This can be used to enable
- features (such as JACK support) that are not enabled in the
- default PulseAudio in Nixpkgs.
- '';
+ systemWide = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If false, a PulseAudio server is launched automatically for
+ each user that tries to use the sound system. The server runs
+ with user priviliges. This is the recommended and most secure
+ way to use PulseAudio. If true, one system-wide PulseAudio
+ server is launched on boot, running as the user "pulse".
+ Please read the PulseAudio documentation for more details.
+ '';
+ };
+
+ configFile = mkOption {
+ type = types.uniq types.path;
+ default = "${pulseaudio}/etc/pulse/default.pa";
+ description = ''
+ The path to the configuration the PulseAudio server
+ should use. By default, the "default.pa" configuration
+ from the PulseAudio distribution is used.
+ '';
+ };
+
+ package = mkOption {
+ default = pulseaudio;
+ example = "pulseaudio.override { jackaudioSupport = true; }";
+ description = ''
+ The PulseAudio derivation to use. This can be used to enable
+ features (such as JACK support) that are not enabled in the
+ default PulseAudio in Nixpkgs.
+ '';
+ };
};
};
- config = mkMerge
- [ # Create pulse/client.conf even if PulseAudio is disabled so
- # that we can disable the autospawn feature in programs that
- # are built with PulseAudio support (like KDE).
- { environment.etc = singleton
- { target = "pulse/client.conf";
- source = pkgs.writeText "client.conf"
- ''
- autospawn=${if cfg.enable then "yes" else "no"}
- ${optionalString cfg.enable ''
- daemon-binary=${cfg.package}/bin/pulseaudio
- ''}
- '';
- };
- }
+ config = mkMerge [
+ {
+ environment.etc = singleton {
+ target = "pulse/client.conf";
+ source = clientConf;
+ };
+ }
- (mkIf cfg.enable {
+ (mkIf cfg.enable {
+ environment.systemPackages = [ cfg.package ];
- environment.systemPackages = [ cfg.package ];
+ environment.etc = singleton {
+ target = "asound.conf";
+ source = alsaConf;
+ };
- environment.etc =
- [ # Write an /etc/asound.conf that causes all ALSA applications to
- # be re-routed to the PulseAudio server through ALSA's Pulse
- # plugin.
- { target = "asound.conf";
- source = pkgs.writeText "asound.conf"
- ''
- pcm_type.pulse {
- lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so
- }
+ # Allow PulseAudio to get realtime priority using rtkit.
+ security.rtkit.enable = true;
+ })
- pcm.!default {
- type pulse
- hint.description "Default Audio Device (via PulseAudio)"
- }
+ (mkIf (cfg.enable && !cfg.systemWide) {
+ environment.etc = singleton {
+ target = "pulse/default.pa";
+ source = cfg.configFile;
+ };
+ })
- ctl_type.pulse {
- lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so
- }
-
- ctl.!default {
- type pulse
- }
- '';
- }
-
- { target = "pulse/default.pa";
- source = "${cfg.package}/etc/pulse/default.pa";
- }
-
- { target = "pulse/system.pa";
- source = "${cfg.package}/etc/pulse/system.pa";
- }
- ];
-
- # Allow PulseAudio to get realtime priority using rtkit.
- security.rtkit.enable = true;
-
- })
- ];
+ (mkIf (cfg.enable && cfg.systemWide) {
+ users.extraUsers.pulse = {
+ # For some reason, PulseAudio wants UID == GID.
+ uid = assert uid == gid; uid;
+ group = "pulse";
+ extraGroups = [ "audio" ];
+ description = "PulseAudio system service user";
+ home = pulseRuntimePath;
+ };
+
+ users.extraGroups.pulse.gid = gid;
+
+ systemd.services.pulseaudio = {
+ description = "PulseAudio system-wide server";
+ wantedBy = [ "sound.target" ];
+ before = [ "sound.target" ];
+ path = [ pulseaudio ];
+ environment.PULSE_RUNTIME_PATH = pulseRuntimePath;
+ preStart = ''
+ mkdir -p --mode 755 ${pulseRuntimePath}
+ chown -R pulse:pulse ${pulseRuntimePath}
+ '';
+ script = ''
+ exec pulseaudio --system -n --file="${cfg.configFile}"
+ '';
+ };
+ })
+ ];
}
diff --git a/modules/module-list.nix b/modules/module-list.nix
index a899baa6b280..76101dcb7c8c 100644
--- a/modules/module-list.nix
+++ b/modules/module-list.nix
@@ -60,7 +60,6 @@
./services/audio/alsa.nix
./services/audio/fuppes.nix
./services/audio/mpd.nix
- ./services/audio/pulseaudio.nix
./services/backup/mysql-backup.nix
./services/backup/postgresql-backup.nix
./services/backup/sitecopy-backup.nix
diff --git a/modules/services/audio/pulseaudio.nix b/modules/services/audio/pulseaudio.nix
deleted file mode 100644
index 04df2a8e867d..000000000000
--- a/modules/services/audio/pulseaudio.nix
+++ /dev/null
@@ -1,87 +0,0 @@
-{ config, pkgs, ... }:
-
-with pkgs.lib;
-
-let
-
- uid = config.ids.uids.pulseaudio;
- gid = config.ids.gids.pulseaudio;
-
-in
-
-{
-
- ###### interface
-
- options = {
-
- services.pulseaudio = {
-
- enable = mkOption {
- default = false;
- description = ''
- Whether to enable the PulseAudio system-wide audio server.
- Note that the documentation recommends running PulseAudio
- daemons per-user rather than system-wide on desktop machines.
- '';
- };
-
- logLevel = mkOption {
- default = "notice";
- example = "debug";
- description = ''
- A string denoting the log level: one of
- error, warn,
- notice, info,
- or debug.
- '';
- };
-
- };
-
- };
-
-
- ###### implementation
-
- config = mkIf config.services.pulseaudio.enable {
-
- environment.systemPackages = [ pkgs.pulseaudio ];
-
- users.extraUsers = singleton
- { name = "pulse";
- # For some reason, PulseAudio wants UID == GID.
- uid = assert uid == gid; uid;
- group = "pulse";
- description = "PulseAudio system-wide daemon";
- home = "/var/run/pulse";
- };
-
- users.extraGroups = singleton
- { name = "pulse";
- inherit gid;
- };
-
- jobs.pulseaudio =
- { description = "PulseAudio system-wide server";
-
- startOn = "startup";
-
- preStart =
- ''
- test -d /var/run/pulse || \
- ( mkdir -p --mode 755 /var/run/pulse && \
- chown pulse:pulse /var/run/pulse )
- '';
-
- exec =
- ''
- ${pkgs.pulseaudio}/bin/pulseaudio \
- --system --daemonize \
- --log-level="${config.services.pulseaudio.logLevel}"
- '';
- };
-
- };
-
-}