Since the 1.0.0 update announcement and the UI changes for the website, it is much more difficult to copy a link to the download so I can paste it into my terminal session for linux. I have no GUI on my Linux box that I use for my server.
Please reconsider the UI changes for choosing what to download for the media server or add a repository for plexpass.
if (yourDistro == “Debian 64 bit”) then $distroSpecificStringVariable = “amd64.deb”;
if (yourDistro == “CentOS 64 bit”) then $distroSpecificStringVariable = “x86_64.rpm”;
Lateley, I’ve been copying the link from the update banner in the Web UI. That’s the only time I notice that an update is available, and I’m able to download without issue on a headless Debian server by simply passing the tokenized URL to lynx.
edit: @bmerkley’s answer is solid, but if anybody’s looking to just copy and paste a URL, it should work just fine.
I don’t mind copy/paste the banner link. It has my token in it so I can download the plexpass version. The @bmerkley method would d/l the public release, wouldn’t it?
@fecaleagle What utility are you using? I can make wget download it but it ends up with a name like “1?channel…”. I can’t get curl to d/l it at all. If you care to share your syntax, I would appreciate it.
So if you want to use curl to download it you have to resolve the redirect with -O -L (–remote-name --location). In recent versions of curl, you can grab the remote header name and save the file with the proper remote filename under some conditions, which of course, the filename header here does not meet. If you don’t care about losing the filename or keeping the file, you can do an update with curl and dpkg in one shot like this:
If you want to do this via a script, you can get a little clever and pull the location header using curl, then save the file using the resolved remote filename. Here’s a lazy script that demonstrates my lack of knowledge about curl by pushing and popping a working directory, rather, than downloading it to the specified path:
#!/usr/bin/env bash
ProvidedURL="$1"
PlexDebPath="/home/william/downloads/plex/"
# resolve location header for remote url
LatestVersionRemotePath=$(curl -sI "$ProvidedURL" | grep -oP 'Location: \K.*')
# clean any non-printing characters
LatestVersionRemotePath=$(tr -dc '[[:print:]]' <<< "$LatestVersionRemotePath")
# extract the filename
LatestFileName="$(basename "$LatestVersionRemotePath")"
# push the working directory
pushd "$PlexDebPath"
# download via the provided URL rather than the RemotePath
curl -o "$LatestFileName" -O -L "$ProvidedURL"
# install the deb
sudo dpkg -i "$LatestFileName"
# delete the deb or keep it?
# rm "$LatestFileName"
# pop the working directory
popd
I love it! Thanks.
I’ve been using wget then just renaming the file. I always kept one version prior in case I felt the need to downgrade. With almost zero scripting knowledge, your syntax is a great primer for me.
@welbo said:
I love it! Thanks.
I’ve been using wget then just renaming the file. I always kept one version prior in case I felt the need to downgrade. With almost zero scripting knowledge, your syntax is a great primer for me.
It honestly never occurred to me to look at the URLs. I’ve always just done it manually, because I can afford to spend two minutes a week manually downloading and installing it. If the access token and URL is always the same, you could just check the latest release filename nightly via a cron job, and if the file hasn’t already been downloaded, download and install it without any interaction whatsoever. Because this extracts the Location: header and doesn’t redirect to it when resolving the LatestVersionRemotePath, you can check whether a new version is available without downloading the file. I’ll provide an updated script later to accomplish this and hold onto however many old versions you want.
@welbo, here’s a cleaner version of the script that is usable for automation.
Anyway, ensure that you execute it with sudo or as a root cron job (for dpkg -i). For future readers, this should be mostly usable out of the box, but it does depend on stat and perl-compatible grep, as well as assuming debian-based packaging and using dpkg-query for checking the installed version and dpkg --compare-versions for version comparison, but it could be easily modified for other package availability and package managers. It will not delete ANY previously downloaded server package files unless you uncomment the VersionNumbersToKeep variable.
This has now been tested and is confirmed to be working via root cron by reverting to an older version and letting it run on a schedule.
Last Update: 2018/05/09 02:55 PM EST
#!/usr/bin/env bash
# specify custom path to locate dpkg dependencies when running via root (or user) cron
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
# specify plex token and url containing channel, build, and distribution
PlexToken="[Your Plex Token Here]"
PlexURL="https://plex.tv/downloads/latest/1?channel=8&build=linux-ubuntu-x86_64&distro=ubuntu&X-Plex-Token=$PlexToken"
# specify path to plex downloads
PlexDownloadPath="[Your Plex Downloads Location Here]"
# trim the trailing slash if one is given...
PlexDownloadPath="${PlexDownloadPath%/}"
# specify plex download user (the user to own the download)
PlexDownloadUser=[Your Linux Username]
# optional: specify how many versions to keep (0 for never keep after install)
#VersionsToKeep=5
# get the installed plex version
InstalledVersion="$(dpkg-query --showformat='${Version}' --show plexmediaserver)"
# resolve the 'Location' header to yield the direct URL, and clean non-printable characters
LatestVersionDirectURL="$(tr -dc '[[:print:]]' <<< "$(curl -sI "$PlexURL" | grep -oP 'Location: \K.*')")"
# extract the filename from the URL
LatestFileName="$(basename "$LatestVersionDirectURL")"
# extract the version from the filename
LatestFileVersion="$(echo "$LatestFileName" | sed 's/plexmediaserver_\(.*\)_.*/\1/')"
# proposed filepath
LatestFilePath="$PlexDownloadPath/$LatestFileName"
echo
echo "Installed Version Info"
echo "----------------------"
echo "Version: $InstalledVersion"
echo
echo "Latest Version Info"
echo "----------------------"
echo "URL: $LatestVersionDirectURL"
echo "Name: $LatestFileName"
echo "Version: $LatestFileVersion"
echo
# if we were able to extract the latest file version, then
# assume that the directURL was resolved correctly.
if [ -n "$LatestFileVersion" ] && [ -e "$PlexDownloadPath" ]; then
# if the latest version is greater than the installed version,
# then proceed.
if $(dpkg --compare-versions "$LatestFileVersion" "gt" "$InstalledVersion"); then
# if the file does not yet exist or if it's too small to be a complete download,
# download it!
if [ ! -e "$LatestFilePath" ] || [ $(( $( stat -c '%s' "$LatestFilePath" ) / 1024 / 1024 )) -lt 50 ]; then
echo "Downloading $LatestFileName..."
# silently download $PlexURL to $LatestFilePath (still show errors)
curl -s -S -o "$LatestFilePath" -O -L "$PlexURL"
# if curl did not exit cleanly or the $LatestFilePath does not exist, abort!
if [ $? -ne 0 ] || [ ! -e "$LatestFilePath" ]; then
echo "Failed to download $LatestFileName."
echo
# exit the script with a failure
exit 1
else
if [ "$USER" != "$PlexDownloadUser" ]; then
chown $PlexDownloadUser:$PlexDownloadUser "$LatestFilePath" &>/dev/null
fi
echo "done."
echo
fi
else
echo "The file is already present and the file size appears sane. Installing existing file."
echo
fi
echo "Installing Plex Media Server $LatestFileVersion..."
echo
# uncomment this for dry run
#echo "dpkg -i \"$LatestFilePath\""
# comment this for dry run
dpkg -i "$LatestFilePath"
else
echo "The installed version is greater than or equal to the latest version."
echo
# exit the script without a failure
exit 0
fi
else
echo "Unable to extract the latest file url."
echo
# exit the script with a failure
exit 1
fi
# if $VersionsToKeep is set, and $PlexDownloadPath Exists, then
# clean up old versions, preserving $VersionsToKeep...
if [ -n "$VersionsToKeep" ] && [ -e "$PlexDownloadPath" ]; then
# this is a bit gnarly; start by counting the number of the server package files
#in $PlexDownloadPath.
ServerVersionCount=$(ls -p "$PlexDownloadPath" | grep -P 'plexmediaserver_.*\.deb' | wc -l)
# if the number of server files is greater than the number of versions to keep...
echo
echo "Cleaning up old server downloads, preserving the last $VersionsToKeep versions..."
if [ $ServerVersionCount -gt $VersionsToKeep ]; then
# list the server package files, sort by name, grab the first X files, where X is the number of files minus the versions to keep,
# then pass to xargs to remove each of the top X files.
ls -p "$PlexDownloadPath" | grep -P 'plexmediaserver_.*\.deb' | sort -V | head -n +$(( $ServerVersionCount - $VersionsToKeep )) | xargs -I {} rm -- "$PlexDownloadPath/"{}
else
echo "...only $ServerVersionCount versions present."
fi
fi
echo
Well I must say that is a nice bit of programming. Like you, I didn’t mind going to the terminal and spending a few minutes checking things out and doing an upgrade. However this script is so cool, I want to implement it just for fun.
I’m on Centos 6 so I’ll use yum and rpm for package management. I’ll make the substitutions and make sure the syntax is good and post that version here for redhat users.
@welbo, it occurred to me after posting that you may be on Centos or Fedora and using yum or dnf. Feel free to post your update, and I’ll incorporate it into the main script, so that you only have to specify the package manager, build, distribution, token, username, and download path to get it up and running on any distribution/architecture. If you run into any trouble, dnf and yum both provide the ability to lookup an installed package version, so I should be able to swing a working script without the ability to test. I’m a fairly dedicated Debian user, so I rarely deal with anything other than apt and dpkg.
Fortunately, sort -V handles PMS version numbers, so I can replace all the package manager usages except those that pull the installed version and perform the installation for more portability.
I noticed an issue today with the latest server version and the iOS app not playing nice together, so I’ve added a provision to my local version of the script for holding on a desired version.
I will update the published version to include this functionality, along with support other package managers when I get the opportunity to do so.
@fecaleagle said:
I noticed an issue today with the latest server version and the iOS app not playing nice together, so I’ve added a provision to my local version of the script for holding on a desired version.
I will update the published version to include this functionality, along with support other package managers when I get the opportunity to do so.
I still intend to modify and implement your script for use in redhat and will post the changes here.
When you mentioned putting a “hold back” variable into the script, the first thought that came to my mind was controls and reports for the update process through a channel plugin. That’s pretty far over my head but might be a fun project to learn about channel programming on for me.
I’ve been using my iOS app away from my server today without issue. What is your issue?
Edit: My issue appears to have been only tangentially related to that one at best. Switching back to latest (and cycling the service in the process) restored order.
Still, I think the point stands that occasionally you need to hang back on a version other than latest. While I’d guess this could be done via a plugin in straight Python, I don’t believe you could automate it, since plugins (afaik) can’t run in the background. I could be wrong about that, but I’ve only written one channel/plugin, and I wouldn’t be interested in putting the management functionality into the client UI via that mechanism.
Edit Edit: I stand corrected; Sub-Zero runs a scheduler message loop on a background thread, so it could certainly be done. It’d still be a project for someone into plugin development (i.e., not me).
Edit Edit Edit: You’d still need to be able to elevate privilege for the package manager. It could be done by having the Plugin call a script with sudo, but then you’d be in the business of needing to add the script file to sudoers NOPWD for the Plex user, which would be ugly enough as is, but would also partially offset the convenience offered by a packaged plugin-based solution.