diff --git a/system/ids.nix b/system/ids.nix
index 3838f7138f22..a950ec84db12 100644
--- a/system/ids.nix
+++ b/system/ids.nix
@@ -19,6 +19,7 @@
dovecot = 15;
tomcat = 16;
gnunetd = 17;
+ pulseaudio = 22; # must match `pulseaudio' GID
nixbld = 30000; # start of range of uids
nobody = 65534;
@@ -45,6 +46,7 @@
uucp = 19;
lp = 20;
tomcat = 21;
+ pulseaudio = 22; # must match `pulseaudio' UID
users = 100;
nixbld = 30000;
diff --git a/system/options.nix b/system/options.nix
index d1748f16f7f5..6b0f725ab2ff 100644
--- a/system/options.nix
+++ b/system/options.nix
@@ -2248,6 +2248,7 @@ in
(import ../upstart-jobs/manual.nix)
(import ../upstart-jobs/rogue.nix)
(import ../upstart-jobs/guest-users.nix)
+ (import ../upstart-jobs/pulseaudio.nix)
# fonts
(import ../system/fonts.nix)
diff --git a/upstart-jobs/pulseaudio.nix b/upstart-jobs/pulseaudio.nix
new file mode 100644
index 000000000000..b8497ce12e78
--- /dev/null
+++ b/upstart-jobs/pulseaudio.nix
@@ -0,0 +1,94 @@
+{pkgs, config, ...}:
+
+###### interface
+let
+ inherit (pkgs.lib) mkOption;
+
+ uid = (import ../system/ids.nix).uids.pulseaudio;
+ gid = (import ../system/ids.nix).gids.pulseaudio;
+
+ 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.
+ '';
+ };
+ };
+ };
+ };
+in
+
+###### implementation
+
+# For some reason, PulseAudio wants UID == GID.
+assert uid == gid;
+
+{
+ require = [
+ options
+ ];
+
+ environment = {
+
+ extraPackages =
+ pkgs.lib.optional
+ (!config.environment.cleanStart)
+ pkgs.pulseaudio;
+ };
+
+ users = {
+ extraUsers = [
+ { name = "pulse";
+ inherit uid;
+ group = "pulse";
+ description = "PulseAudio system-wide daemon";
+ home = "/var/run/pulse";
+ }
+ ];
+
+ extraGroups = [
+ { name = "pulse";
+ inherit gid;
+ }
+ ];
+ };
+
+ services = {
+ extraJobs = [{
+ name = "pulseaudio";
+
+ job = ''
+ description "PulseAudio system-wide server"
+
+ start on startup
+ stop on shutdown
+
+ start script
+ test -d /var/run/pulse || \
+ ( mkdir -p --mode 755 /var/run/pulse && \
+ chown pulse:pulse /var/run/pulse )
+ end script
+
+ respawn ${pkgs.pulseaudio}/bin/pulseaudio \
+ --system --daemonize \
+ --log-level="${config.services.pulseaudio.logLevel}"
+ '';
+ }];
+ };
+}