at master 3.8 kB view raw
1{ pkgs, lib, ... }: 2let 3 track = pkgs.fetchurl { 4 # Sourced from http://freemusicarchive.org/music/Blue_Wave_Theory/Surf_Music_Month_Challenge/Skyhawk_Beach_fade_in 5 6 name = "Blue_Wave_Theory-Skyhawk_Beach.mp3"; 7 url = "https://freemusicarchive.org/file/music/ccCommunity/Blue_Wave_Theory/Surf_Music_Month_Challenge/Blue_Wave_Theory_-_04_-_Skyhawk_Beach.mp3"; 8 hash = "sha256-91VDWwrcP6Cw4rk72VHvZ8RGfRBrpRE8xo/02dcJhHc="; 9 meta.license = lib.licenses.cc-by-sa-40; 10 }; 11 12 defaultCfg = rec { 13 user = "mpd"; 14 group = "mpd"; 15 dataDir = "/var/lib/mpd"; 16 musicDirectory = "${dataDir}/music"; 17 }; 18 19 defaultMpdCfg = { 20 inherit (defaultCfg) 21 dataDir 22 musicDirectory 23 user 24 group 25 ; 26 enable = true; 27 }; 28 29 musicService = 30 { 31 user, 32 group, 33 musicDirectory, 34 }: 35 { 36 description = "Sets up the music file(s) for MPD to use."; 37 requires = [ "mpd.service" ]; 38 after = [ "mpd.service" ]; 39 wantedBy = [ "default.target" ]; 40 script = '' 41 cp ${track} ${musicDirectory} 42 ''; 43 serviceConfig = { 44 User = user; 45 Group = group; 46 }; 47 }; 48 49 mkServer = 50 { mpd, musicService }: 51 { 52 boot.kernelModules = [ "snd-dummy" ]; 53 services.mpd = mpd; 54 systemd.services.musicService = musicService; 55 }; 56in 57{ 58 name = "mpd"; 59 meta = { 60 maintainers = with lib.maintainers; [ emmanuelrosa ]; 61 }; 62 63 nodes = { 64 client = { ... }: { }; 65 66 serverALSA = 67 { ... }: 68 lib.mkMerge [ 69 (mkServer { 70 mpd = defaultMpdCfg // { 71 network.listenAddress = "any"; 72 extraConfig = '' 73 audio_output { 74 type "alsa" 75 name "ALSA" 76 mixer_type "null" 77 } 78 ''; 79 }; 80 musicService = musicService { inherit (defaultMpdCfg) user group musicDirectory; }; 81 }) 82 { networking.firewall.allowedTCPPorts = [ 6600 ]; } 83 ]; 84 85 serverPulseAudio = 86 { ... }: 87 lib.mkMerge [ 88 (mkServer { 89 mpd = defaultMpdCfg // { 90 extraConfig = '' 91 audio_output { 92 type "pulse" 93 name "The Pulse" 94 } 95 ''; 96 }; 97 98 musicService = musicService { inherit (defaultMpdCfg) user group musicDirectory; }; 99 }) 100 { 101 services.pulseaudio = { 102 enable = true; 103 systemWide = true; 104 tcp.enable = true; 105 tcp.anonymousClients.allowAll = true; 106 }; 107 systemd.services.mpd.environment.PULSE_SERVER = "localhost"; 108 } 109 ]; 110 }; 111 112 testScript = '' 113 mpc = "${lib.getExe pkgs.mpc} --wait" 114 115 # Connects to the given server and attempts to play a tune. 116 def play_some_music(server): 117 server.wait_for_unit("mpd.service") 118 server.succeed(f"{mpc} update") 119 _, tracks = server.execute(f"{mpc} ls") 120 121 for track in tracks.splitlines(): 122 server.succeed(f"{mpc} add {track}") 123 124 _, added_tracks = server.execute(f"{mpc} playlist") 125 126 # Check we succeeded adding audio tracks to the playlist 127 assert len(added_tracks.splitlines()) > 0 128 129 server.succeed(f"{mpc} play") 130 131 _, output = server.execute(f"{mpc} status") 132 # Assure audio track is playing 133 assert "playing" in output 134 135 server.succeed(f"{mpc} stop") 136 137 138 play_some_music(serverALSA) 139 play_some_music(serverPulseAudio) 140 141 client.wait_for_unit("multi-user.target") 142 client.succeed(f"{mpc} -h serverALSA status") 143 144 # The PulseAudio-based server is configured not to accept external client connections 145 # to perform the following test: 146 client.fail(f"{mpc} -h serverPulseAudio status") 147 ''; 148}