diff options
-rw-r--r-- | nixos/modules/services/audio/slimserver.nix | 2 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/slimserver.nix | 47 | ||||
-rw-r--r-- | pkgs/applications/audio/squeezelite/default.nix | 6 | ||||
-rw-r--r-- | pkgs/servers/slimserver/default.nix | 112 | ||||
-rw-r--r-- | pkgs/top-level/perl-packages.nix | 66 |
6 files changed, 227 insertions, 7 deletions
diff --git a/nixos/modules/services/audio/slimserver.nix b/nixos/modules/services/audio/slimserver.nix index 9fbc68b71364e..cdd9d551c501f 100644 --- a/nixos/modules/services/audio/slimserver.nix +++ b/nixos/modules/services/audio/slimserver.nix @@ -54,7 +54,7 @@ in { serviceConfig = { User = "slimserver"; # Issue 40589: Disable broken image/video support (audio still works!) - ExecStart = "${cfg.package}/slimserver.pl --logdir ${cfg.dataDir}/logs --prefsdir ${cfg.dataDir}/prefs --cachedir ${cfg.dataDir}/cache --noimage --novideo"; + ExecStart = "${lib.getExe cfg.package} --logdir ${cfg.dataDir}/logs --prefsdir ${cfg.dataDir}/prefs --cachedir ${cfg.dataDir}/cache --noimage --novideo"; }; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 6c127efa4cea2..272fe6933d633 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -750,6 +750,7 @@ in { signal-desktop = handleTest ./signal-desktop.nix {}; simple = handleTest ./simple.nix {}; sing-box = handleTest ./sing-box.nix {}; + slimserver = handleTest ./slimserver.nix {}; slurm = handleTest ./slurm.nix {}; smokeping = handleTest ./smokeping.nix {}; snapcast = handleTest ./snapcast.nix {}; diff --git a/nixos/tests/slimserver.nix b/nixos/tests/slimserver.nix new file mode 100644 index 0000000000000..c3f7b6fde4de0 --- /dev/null +++ b/nixos/tests/slimserver.nix @@ -0,0 +1,47 @@ +import ./make-test-python.nix ({ pkgs, ...} : { + name = "slimserver"; + meta.maintainers = with pkgs.lib.maintainers; [ adamcstephens ]; + + nodes.machine = { ... }: { + services.slimserver.enable = true; + services.squeezelite = { + enable = true; + extraArguments = "-s 127.0.0.1 -d slimproto=info"; + }; + sound.enable = true; + boot.initrd.kernelModules = ["snd-dummy"]; + }; + + testScript = + '' + import json + rpc_get_player = { + "id": 1, + "method": "slim.request", + "params":[0,["player", "id", "0", "?"]] + } + + with subtest("slimserver is started"): + machine.wait_for_unit("slimserver.service") + # give slimserver a moment to report errors + machine.sleep(2) + + with subtest('slimserver module errors are not reported'): + machine.fail("journalctl -u slimserver.service | grep 'throw_exception'") + machine.fail("journalctl -u slimserver.service | grep 'not installed'") + machine.fail("journalctl -u slimserver.service | grep 'not found'") + machine.fail("journalctl -u slimserver.service | grep 'The following CPAN modules were found but cannot work with Logitech Media Server'") + machine.fail("journalctl -u slimserver.service | grep 'please use the buildme.sh'") + + with subtest('slimserver is ready'): + machine.wait_for_open_port(9000) + machine.wait_until_succeeds("journalctl -u slimserver.service | grep 'Completed dbOptimize Scan'") + + with subtest("squeezelite player successfully connects to slimserver"): + machine.wait_for_unit("squeezelite.service") + machine.wait_until_succeeds("journalctl -u squeezelite.service | grep 'slimproto:937 connected'") + player_mac = machine.wait_until_succeeds("journalctl -eu squeezelite.service | grep 'sendHELO:148 mac:'").strip().split(" ")[-1] + player_id = machine.succeed(f"curl http://localhost:9000/jsonrpc.js -g -X POST -d '{json.dumps(rpc_get_player)}'") + assert player_mac == json.loads(player_id)["result"]["_id"], "squeezelite player not found" + ''; +}) diff --git a/pkgs/applications/audio/squeezelite/default.nix b/pkgs/applications/audio/squeezelite/default.nix index da126de3fc436..0f3b8be11c08b 100644 --- a/pkgs/applications/audio/squeezelite/default.nix +++ b/pkgs/applications/audio/squeezelite/default.nix @@ -22,6 +22,7 @@ , openssl , portaudioSupport ? stdenv.isDarwin , portaudio +, slimserver , AudioToolbox , AudioUnit , Carbon @@ -95,7 +96,10 @@ stdenv.mkDerivation { runHook postInstall ''; - passthru.updateScript = ./update.sh; + passthru = { + inherit (slimserver) tests; + updateScript = ./update.sh; + }; meta = with lib; { description = "Lightweight headless squeezebox client emulator"; diff --git a/pkgs/servers/slimserver/default.nix b/pkgs/servers/slimserver/default.nix index f561eec0bac8f..08d9dbe97e6f7 100644 --- a/pkgs/servers/slimserver/default.nix +++ b/pkgs/servers/slimserver/default.nix @@ -5,13 +5,18 @@ , lib , makeWrapper , monkeysAudio -, perlPackages +, nixosTests +, perl538Packages , sox , stdenv , wavpack , zlib +, enableUnfreeFirmware ? false }: +let + perlPackages = perl538Packages; +in perlPackages.buildPerlPackage rec { pname = "slimserver"; version = "8.3.1"; @@ -25,10 +30,99 @@ perlPackages.buildPerlPackage rec { nativeBuildInputs = [ makeWrapper ]; - buildInputs = [ perlPackages.CryptOpenSSLRSA perlPackages.IOSocketSSL ]; + buildInputs = with perlPackages; [ + AnyEvent + ArchiveZip + AsyncUtil + AudioScan + CarpClan + CGI + ClassAccessor + ClassAccessorChained + ClassC3 + # ClassC3Componentised # Error: DBIx::Class::Row::throw_exception(): DBIx::Class::Relationship::BelongsTo::belongs_to(): Can't infer join condition for track + ClassDataInheritable + ClassInspector + ClassISA + ClassMember + ClassSingleton + ClassVirtual + ClassXSAccessor + CompressRawZlib + CryptOpenSSLRSA + DataDump + DataPage + DataURIEncode + DBDSQLite + DBI + # DBIxClass # https://github.com/Logitech/slimserver/issues/138 + DigestSHA1 + EncodeDetect + EV + ExporterLite + FileBOM + FileCopyRecursive + FileNext + FileReadBackwards + FileSlurp + FileWhich + HTMLParser + HTTPCookies + HTTPDaemon + HTTPMessage + ImageScale + IOAIO + IOInterface + IOSocketSSL + IOString + JSONXS + JSONXSVersionOneAndTwo + # LogLog4perl # Internal error: Root Logger not initialized. + LWP + LWPProtocolHttps + MP3CutGapless + NetHTTP + NetHTTPSNB + PathClass + ProcBackground + # SQLAbstract # DBI Exception: DBD::SQLite::db prepare_cached failed: no such function: ARRAY + SQLAbstractLimit + SubName + TemplateToolkit + TextUnidecode + TieCacheLRU + TieCacheLRUExpires + TieRegexpHash + TimeDate + URI + URIFind + UUIDTiny + XMLParser + XMLSimple + YAMLLibYAML + ] + # ++ (lib.optional stdenv.isDarwin perlPackages.MacFSEvents) + ++ (lib.optional stdenv.isLinux perlPackages.LinuxInotify2); prePatch = '' + # remove vendored binaries rm -rf Bin + + # remove most vendored modules, keeping necessary ones + mkdir -p CPAN_used/Class/C3/ CPAN_used/SQL + rm -r CPAN/SQL/Abstract/Limit.pm + cp -rv CPAN/Class/C3/Componentised.pm CPAN_used/Class/C3/ + cp -rv CPAN/DBIx CPAN_used/ + cp -rv CPAN/Log CPAN_used/ + cp -rv CPAN/SQL/* CPAN_used/SQL/ + rm -r CPAN + mv CPAN_used CPAN + + ${lib.optionalString (!enableUnfreeFirmware) '' + # remove unfree firmware + rm -rf Firmware + ''} + touch Makefile.PL ''; @@ -38,18 +132,26 @@ perlPackages.buildPerlPackage rec { cp -r . $out wrapProgram $out/slimserver.pl \ --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ zlib stdenv.cc.cc.lib ]}" \ - --prefix PATH : "${lib.makeBinPath [ lame flac faad2 sox monkeysAudio wavpack ]}" + --prefix PATH : "${lib.makeBinPath ([ lame flac faad2 sox wavpack ] ++ (lib.optional stdenv.isLinux monkeysAudio))}" + mkdir $out/bin + ln -s $out/slimserver.pl $out/bin/slimserver ''; outputs = [ "out" ]; + passthru.tests = { + inherit (nixosTests) slimserver; + }; + meta = with lib; { homepage = "https://github.com/Logitech/slimserver"; description = "Server for Logitech Squeezebox players. This server is also called Logitech Media Server"; - # the firmware is not under a free license! + # the firmware is not under a free license, but not included in the default package # https://github.com/Logitech/slimserver/blob/public/8.3/License.txt - license = licenses.unfree; + license = if enableUnfreeFirmware then licenses.unfree else licenses.gpl2Only; + mainProgram = "slimserver"; maintainers = with maintainers; [ adamcstephens jecaro ]; platforms = platforms.unix; + broken = stdenv.isDarwin; }; } diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index a884bcd346188..47484eaf80f59 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -1169,6 +1169,20 @@ with self; { }; }; + AsyncUtil = buildPerlPackage { + pname = "Async-Util"; + version = "0.01"; + src = fetchurl { + url = "mirror://cpan/authors/id/W/WH/WHITNEY/Async-Util-0.01.tar.gz"; + hash = "sha256-jzKxHKvFD2Xjh79W8mWBV6IsNah5Nmbhtfis/hMQkQY="; + }; + buildInputs = [ AnyEvent ListMoreUtils ]; + meta = { + description = "Utilities for doing common async operations"; + license = with lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + ArchiveCpio = buildPerlPackage { pname = "Archive-Cpio"; version = "0.10"; @@ -1253,6 +1267,18 @@ with self; { }; }; + AudioCuefileParser = buildPerlPackage { + pname = "Audio-Cuefile-Parser"; + version = "0.02"; + src = fetchurl { + url = "mirror://cpan/authors/id/M/MA/MATTK/Audio-Cuefile-Parser-0.02.tar.gz"; + hash = "sha256-ulbQcMhz2WxoatmoH99P6JuETkPrSd/gAL+c70PFtmk="; + }; + meta = { + license = with lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + AudioFLACHeader = buildPerlPackage { pname = "Audio-FLAC-Header"; version = "2.4"; @@ -3602,6 +3628,19 @@ with self; { }; }; + ClassMember = buildPerlPackage { + pname = "Class-Member"; + version = "1.6"; + src = fetchurl { + url = "mirror://cpan/authors/id/O/OP/OPI/Class-Member-1.6.tar.gz"; + hash = "sha256-p1KK8in6OhIF3NJakd59dKxvp9lSgbmTtV6Lb0+HuZE="; + }; + meta = { + description = "A set of modules to make the module developement easier"; + license = with lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + ClassMethodMaker = buildPerlPackage { pname = "Class-MethodMaker"; version = "2.24"; @@ -12712,6 +12751,19 @@ with self; { }; }; + IOInterface = buildPerlModule { + pname = "IO-Interface"; + version = "1.09"; + src = fetchurl { + url = "mirror://cpan/authors/id/L/LD/LDS/IO-Interface-1.09.tar.gz"; + hash = "sha256-5j6BxS6x4OYOwtmD9VUtJJPhFxeZJclnV/I8S9n6cTo="; + }; + meta = { + description = "Access and modify network interface card configuration"; + license = with lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + IOInteractive = buildPerlPackage { pname = "IO-Interactive"; version = "1.025"; @@ -17933,6 +17985,20 @@ with self; { }; }; + MP3CutGapless = buildPerlPackage { + pname = "MP3-Cut-Gapless"; + version = "0.03"; + src = fetchurl { + url = "mirror://cpan/authors/id/A/AG/AGRUNDMA/MP3-Cut-Gapless-0.03.tar.gz"; + hash = "sha256-PoS3OdHx4902FvhR3GV14WXTKEZ/AySGB5UOWVH+pPM="; + }; + propagatedBuildInputs = [ AudioCuefileParser ]; + meta = { + description = "Split an MP3 file without gaps (based on pcutmp3)"; + license = with lib.licenses; [ artistic1 ]; + }; + }; + MP3Info = buildPerlPackage { pname = "MP3-Info"; version = "1.26"; |