Added a package and module for Plex Media Server, an application for managing media collections across multiple devices.wip/yesman
parent
d8cd5d34ae
commit
079da8cdcd
@ -0,0 +1,87 @@ |
||||
{ config, pkgs, lib, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.plex; |
||||
plex = pkgs.plex; |
||||
in |
||||
{ |
||||
options = { |
||||
services.plex = { |
||||
enable = mkEnableOption "Enable Plex Media Server"; |
||||
|
||||
# FIXME: In order for this config option to work, symlinks in the Plex |
||||
# package in the Nix store have to be changed to point to this directory. |
||||
dataDir = mkOption { |
||||
type = types.str; |
||||
default = "/var/lib/plex"; |
||||
description = "The directory where Plex stores its data files."; |
||||
}; |
||||
|
||||
user = mkOption { |
||||
type = types.str; |
||||
default = "plex"; |
||||
description = "User account under which Plex runs."; |
||||
}; |
||||
|
||||
group = mkOption { |
||||
type = types.str; |
||||
default = "plex"; |
||||
description = "Group under which Plex runs."; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf cfg.enable { |
||||
# Most of this is just copied from the RPM package's systemd service file. |
||||
systemd.services.plex = { |
||||
description = "Plex Media Server"; |
||||
after = [ "network.target" ]; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
preStart = '' |
||||
test -d "${cfg.dataDir}" || { |
||||
echo "Creating initial Plex data directory in \"${cfg.dataDir}\"." |
||||
mkdir -p "${cfg.dataDir}" |
||||
chown -R ${cfg.user}:${cfg.group} "${cfg.dataDir}" |
||||
} |
||||
# Copy the database skeleton files to /var/lib/plex/.skeleton |
||||
test -d "${cfg.dataDir}/.skeleton" || mkdir "${cfg.dataDir}/.skeleton" |
||||
for db in "com.plexapp.plugins.library.db"; do |
||||
cp "${plex}/usr/lib/plexmediaserver/Resources/base_$db" "${cfg.dataDir}/.skeleton/$db" |
||||
chmod u+w "${cfg.dataDir}/.skeleton/$db" |
||||
chown ${cfg.user}:${cfg.group} "${cfg.dataDir}/.skeleton/$db" |
||||
done |
||||
''; |
||||
serviceConfig = { |
||||
Type = "simple"; |
||||
User = cfg.user; |
||||
Group = cfg.group; |
||||
PermissionsStartOnly = "true"; |
||||
ExecStart = "/bin/sh -c '${plex}/usr/lib/plexmediaserver/Plex\\ Media\\ Server'"; |
||||
}; |
||||
environment = { |
||||
PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=cfg.dataDir; |
||||
PLEX_MEDIA_SERVER_HOME="${plex}/usr/lib/plexmediaserver"; |
||||
PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6"; |
||||
PLEX_MEDIA_SERVER_TMPDIR="/tmp"; |
||||
LD_LIBRARY_PATH="${plex}/usr/lib/plexmediaserver"; |
||||
LC_ALL="en_US.UTF-8"; |
||||
LANG="en_US.UTF-8"; |
||||
}; |
||||
}; |
||||
|
||||
users.extraUsers = mkIf (cfg.user == "plex") { |
||||
plex = { |
||||
group = cfg.group; |
||||
uid = config.ids.uids.plex; |
||||
}; |
||||
}; |
||||
|
||||
users.extraGroups = mkIf (cfg.group == "plex") { |
||||
plex = { |
||||
gid = config.ids.gids.plex; |
||||
}; |
||||
}; |
||||
}; |
||||
} |
@ -0,0 +1,65 @@ |
||||
{ stdenv, fetchurl, rpmextract, glibc |
||||
, dataDir ? "/var/lib/plex" # Plex's data directory must be baked into the package due to symlinks. |
||||
}: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
name = "plex-${version}"; |
||||
version = "0.9.11.16.958"; |
||||
vsnHash = "80f1748"; |
||||
|
||||
src = fetchurl { |
||||
url = "https://downloads.plex.tv/plex-media-server/${version}-${vsnHash}/plexmediaserver-${version}-${vsnHash}.x86_64.rpm"; |
||||
sha256 = "1wrl654nk10i9p01cgy9fqiqalxyl718qhp4kjnxvcwafayxkp26"; |
||||
}; |
||||
|
||||
buildInputs = [ rpmextract glibc ]; |
||||
|
||||
phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ]; |
||||
|
||||
unpackPhase = '' |
||||
rpmextract $src |
||||
''; |
||||
|
||||
installPhase = '' |
||||
install -d $out/usr/lib |
||||
cp -dr --no-preserve='ownership' usr/lib/plexmediaserver $out/usr/lib/ |
||||
|
||||
# Now we need to patch up the executables and libraries to work on Nix. |
||||
# Side note: PLEASE don't put spaces in your binary names. This is stupid. |
||||
for bin in "Plex Media Server" "Plex DLNA Server" "Plex Media Scanner"; do |
||||
patchelf --set-interpreter "${glibc}/lib/ld-linux-x86-64.so.2" "$out/usr/lib/plexmediaserver/$bin" |
||||
patchelf --set-rpath "$out/usr/lib/plexmediaserver" "$out/usr/lib/plexmediaserver/$bin" |
||||
done |
||||
|
||||
find $out/usr/lib/plexmediaserver/Resources -type f -a -perm +0100 \ |
||||
-print -exec patchelf --set-interpreter "${glibc}/lib/ld-linux-x86-64.so.2" '{}' \; |
||||
|
||||
|
||||
# Our next problem is the "Resources" directory in /usr/lib/plexmediaserver. |
||||
# This is ostensibly a skeleton directory, which contains files that Plex |
||||
# copies into its folder in /var. Unfortunately, there are some SQLite |
||||
# databases in the directory that are opened at startup. Since these |
||||
# database files are read-only, SQLite chokes and Plex fails to start. To |
||||
# solve this, we keep the resources directory in the Nix store, but we |
||||
# rename the database files and replace the originals with symlinks to |
||||
# /var/lib/plex. Then, in the systemd unit, the base database files are |
||||
# copied to /var/lib/plex before starting Plex. |
||||
RSC=$out/usr/lib/plexmediaserver/Resources |
||||
for db in "com.plexapp.plugins.library.db"; do |
||||
mv $RSC/$db $RSC/base_$db |
||||
ln -s ${dataDir}/.skeleton/$db $RSC/$db |
||||
done |
||||
''; |
||||
|
||||
meta = with stdenv.lib; { |
||||
homepage = http://plex.tv/; |
||||
license = licenses.unfree; |
||||
platforms = platforms.linux; |
||||
maintainers = with stdenv.lib.maintainers; [ forkk ]; |
||||
description = "Media / DLNA server"; |
||||
longDescription = '' |
||||
Plex is a media server which allows you to store your media and play it |
||||
back across many different devices. |
||||
''; |
||||
}; |
||||
} |
Loading…
Reference in new issue