scope: { lib, pkgs, config, ... }: let cfg = config.services.jellyfin; plugin = name: (scope pkgs)."jellyfin-plugin-${name}".override { jellyfin = cfg.package; }; libs = pkg: fn: lib.lists.foldl (acc: lib: acc ++ lib.toList (fn lib)) [ ] pkg.pluginLibraries; serviceConfig = pkg: let make-rw = pkgs.writeShellScript "make-rw" '' readonly src="${pkg}/''${1}" readonly dst="${cfg.dataDir}/''${1}" mkdir -p "''${dst%/*}" [[ -f "''${dst}" ]] || cp "''${src}" "''${dst}" ''; in { BindReadOnlyPaths = map (name: "${pkg}/${name}:${cfg.dataDir}/plugins/${pkg.name}/${name}") pkg.jellyfinPluginFiles; BindPaths = [ "${cfg.dataDir}/plugins/${pkg.name}/meta.json" ]; }; type.plugin = lib.types.addCheck lib.types.package (builtins.hasAttr "jellyfinPluginFiles"); in { options.services.jellyfin.plugins = lib.mkOption { type = lib.types.listOf (lib.types.coercedTo lib.types.nonEmptyStr plugin type.plugin); default = [ ]; }; config.systemd = lib.mkIf (cfg.plugins != { }) { services.jellyfin.serviceConfig = lib.mkMerge ( [ { BindPaths = [ "${cfg.dataDir}/plugins" ]; } { BindPaths = [ "${cfg.dataDir}/plugins/configurations/" ]; } ] ++ builtins.map serviceConfig cfg.plugins ); tmpfiles.settings = lib.lists.foldl ( acc: pkg: acc // { ${pkg.name}."${cfg.dataDir}/plugins/${pkg.name}/meta.json".C = { group = cfg.group; user = cfg.user; mode = "0700"; argument = "${pkg}/meta.json"; }; } ) { } cfg.plugins; }; }