diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix index 3e969991f8fd..80ff6c1aabf7 100644 --- a/nixos/modules/config/pulseaudio.nix +++ b/nixos/modules/config/pulseaudio.nix @@ -102,7 +102,7 @@ in { each user that tries to use the sound system. The server runs with user privileges. If true, one system-wide PulseAudio server is launched on boot, running as the user "pulse", and - only users in the "audio" group will have access to the server. + only users in the "pulse-access" group will have access to the server. Please read the PulseAudio documentation for more details. Don't enable this option unless you know what you are doing. @@ -310,6 +310,7 @@ in { }; users.groups.pulse.gid = gid; + users.groups.pulse-access = {}; systemd.services.pulseaudio = { description = "PulseAudio System-Wide Server"; diff --git a/nixos/tests/pulseaudio.nix b/nixos/tests/pulseaudio.nix index cfdc61bc6c2b..dc8e33ccd559 100644 --- a/nixos/tests/pulseaudio.nix +++ b/nixos/tests/pulseaudio.nix @@ -1,10 +1,10 @@ let - mkTest = { systemWide ? false }: + mkTest = { systemWide ? false , fullVersion ? false }: import ./make-test-python.nix ({ pkgs, lib, ... }: let testFile = pkgs.fetchurl { url = - "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"; + "https://file-examples.com/storage/fe5947fd2362fc197a3c2df/2017/11/file_example_MP3_700KB.mp3"; hash = "sha256-+iggJW8s0/LfA/okfXsB550/55Q0Sq3OoIzuBrzOPJQ="; }; @@ -22,7 +22,7 @@ let testPlay32 = { inherit (pkgs.pkgsi686Linux) sox alsa-utils; }; }; in { - name = "pulseaudio${lib.optionalString systemWide "-systemWide"}"; + name = "pulseaudio${lib.optionalString fullVersion "Full"}${lib.optionalString systemWide "-systemWide"}"; meta = with pkgs.lib.maintainers; { maintainers = [ synthetica ] ++ pkgs.pulseaudio.meta.maintainers; }; @@ -35,12 +35,14 @@ let enable = true; support32Bit = true; inherit systemWide; + } // lib.optionalAttrs fullVersion { + package = pkgs.pulseaudioFull; }; environment.systemPackages = [ testers.testPlay pkgs.pavucontrol ] ++ lib.optional pkgs.stdenv.isx86_64 testers.testPlay32; } // lib.optionalAttrs systemWide { - users.users.alice.extraGroups = [ "audio" ]; + users.users.alice.extraGroups = [ "pulse-access" ]; systemd.services.pulseaudio.wantedBy = [ "multi-user.target" ]; }; @@ -58,14 +60,21 @@ let ''} machine.screenshot("testPlay") + ${lib.optionalString (!systemWide) '' + machine.send_chars("pacmd info && touch /tmp/pacmd_success\n") + machine.wait_for_file("/tmp/pacmd_success") + ''} + # Pavucontrol only loads when Pulseaudio is running. If it isn't, the - # text "Playback" (one of the tabs) will never show. + # text "Dummy Output" (sound device name) will never show. machine.send_chars("pavucontrol\n") - machine.wait_for_text("Playback") + machine.wait_for_text("Dummy Output") machine.screenshot("Pavucontrol") ''; }); in builtins.mapAttrs (key: val: mkTest val) { - user = { systemWide = false; }; - system = { systemWide = true; }; + user = { systemWide = false; fullVersion = false; }; + system = { systemWide = true; fullVersion = false; }; + userFull = { systemWide = false; fullVersion = true; }; + systemFull = { systemWide = true; fullVersion = true; }; } diff --git a/pkgs/servers/pulseaudio/default.nix b/pkgs/servers/pulseaudio/default.nix index 5084bd720514..2639ad8b80e2 100644 --- a/pkgs/servers/pulseaudio/default.nix +++ b/pkgs/servers/pulseaudio/default.nix @@ -116,6 +116,11 @@ stdenv.mkDerivation rec { "-Dsysconfdir=/etc" "-Dsysconfdir_install=${placeholder "out"}/etc" "-Dudevrulesdir=${placeholder "out"}/lib/udev/rules.d" + + # pulseaudio complains if its binary is moved after installation; + # this is needed so that wrapGApp can operate *without* + # renaming the unwrapped binaries (see below) + "--bindir=${placeholder "out"}/.bin-unwrapped" ] ++ lib.optional (stdenv.isLinux && useSystemd) "-Dsystemduserunitdir=${placeholder "out"}/lib/systemd/user" ++ lib.optionals stdenv.isDarwin [ @@ -133,11 +138,11 @@ stdenv.mkDerivation rec { postInstall = lib.optionalString libOnly '' find $out/share -maxdepth 1 -mindepth 1 ! -name "vala" -prune -exec rm -r {} \; find $out/share/vala -maxdepth 1 -mindepth 1 ! -name "vapi" -prune -exec rm -r {} \; - rm -r $out/{bin,etc,lib/pulse-*} + rm -r $out/{.bin-unwrapped,etc,lib/pulse-*} '' + '' moveToOutput lib/cmake "$dev" - rm -f $out/bin/qpaeq # this is packaged by the "qpaeq" package now, because of missing deps + rm -f $out/.bin-unwrapped/qpaeq # this is packaged by the "qpaeq" package now, because of missing deps ''; preFixup = lib.optionalString (stdenv.isLinux && (stdenv.hostPlatform == stdenv.buildPlatform)) '' @@ -151,6 +156,15 @@ stdenv.mkDerivation rec { ln -s "''$file" "''${file%.dylib}.so" ln -s "''$file" "$out/lib/pulseaudio/''$(basename ''$file .dylib).so" done + '' + # put symlinks to binaries in `$prefix/bin`; + # then wrapGApp will *rename these symlinks* instead of + # the original binaries in `$prefix/.bin-unwrapped` (see above); + # when pulseaudio is looking for its own binary (it does!), + # it will be happy to find it in its original installation location + + lib.optionalString (!libOnly) '' + mkdir -p $out/bin + ln -st $out/bin $out/.bin-unwrapped/* ''; meta = {