From b29a1b8320c80d709f56f47c05bd48be9889fda6 Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 20 Dec 2024 20:31:10 +0000 Subject: [PATCH] Support nonroot operation --- README.md | 10 ++++ readme-vars.yml | 4 ++ .../s6-overlay/s6-rc.d/init-plex-chown/run | 56 +++++++++--------- .../s6-rc.d/init-plex-gid-video/run | 58 ++++++++++--------- root/etc/s6-overlay/s6-rc.d/svc-plex/run | 13 ++++- 5 files changed, 84 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index ae167750..d3a72b4c 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,15 @@ This image can be run with a read-only container filesystem. For details please * Runtime update of Plex (and thus Plexpass builds) is not supported. * Transcode directory must be mounted to a host path or tmpfs. +## Non-Root Operation + +This image can be run with a non-root user. For details please [read the docs](https://docs.linuxserver.io/misc/non-root/). + +### Caveats + +* Runtime update of Plex (and thus Plexpass builds) is not supported. +* Transcode directory must be mounted to a host path or tmpfs. + ### Hardware Acceleration Many desktop applications need access to a GPU to function properly and even some Desktop Environments have compositor effects that will not function without a GPU. However this is not a hard requirement and all base images will function without a video device mounted into the container. @@ -174,6 +183,7 @@ Containers are configured using parameters passed at runtime (such as those abov | `-v /tv` | Media goes here. Add as many as needed e.g. `/movies`, `/tv`, etc. | | `-v /movies` | Media goes here. Add as many as needed e.g. `/movies`, `/tv`, etc. | | `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). | +| `--user=1000:1000` | Run container with a non-root user. Please [read the docs](https://docs.linuxserver.io/misc/non-root/). | ## Environment variables from files (Docker secrets) diff --git a/readme-vars.yml b/readme-vars.yml index 86979f67..4e109a1a 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -75,6 +75,10 @@ readonly_supported: true readonly_message: | * Runtime update of Plex (and thus Plexpass builds) is not supported. * Transcode directory must be mounted to a host path or tmpfs. +nonroot_supported: true +nonroot_message: | + * Runtime update of Plex (and thus Plexpass builds) is not supported. + * Transcode directory must be mounted to a host path or tmpfs. # init diagram init_diagram: | "plex:latest": { diff --git a/root/etc/s6-overlay/s6-rc.d/init-plex-chown/run b/root/etc/s6-overlay/s6-rc.d/init-plex-chown/run index 6c2d74c8..f98e6699 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-plex-chown/run +++ b/root/etc/s6-overlay/s6-rc.d/init-plex-chown/run @@ -6,16 +6,9 @@ mkdir -p /run/plex-temp # create folders if [[ ! -d "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" ]]; then mkdir -p "${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}" - lsiown -R abc:abc /config -fi - -# check Library permissions -PUID=${PUID:-911} -if [[ ! "$(stat -c %u /config/Library)" == "${PUID}" ]]; then - echo "Change in ownership detected, please be patient while we chown existing files" - echo "This could take some time" - lsiown -R abc:abc \ - /config/Library + if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + lsiown -R abc:abc /config + fi fi # remove plex pid after unclean stop @@ -23,20 +16,31 @@ if [[ -f "/config/Library/Application Support/Plex Media Server/plexmediaserver. rm -f "/config/Library/Application Support/Plex Media Server/plexmediaserver.pid" fi -# set permissions on Plex Transcoder Temp Directory -PLEX_MEDIA_SERVER_PREFERENCES="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}/Plex Media Server/Preferences.xml" -if [[ -f "${PLEX_MEDIA_SERVER_PREFERENCES}" ]]; then - TranscoderTempDirectory='\bTranscoderTempDirectory="([^"]+)"' - while IFS= read -r line; do - if [[ ${line} =~ ${TranscoderTempDirectory} ]] && [[ -d "${BASH_REMATCH[1]}" ]]; then - echo "Setting permissions on ${BASH_REMATCH[1]}" - lsiown -R abc:abc "${BASH_REMATCH[1]}" - fi - done <"${PLEX_MEDIA_SERVER_PREFERENCES}" -fi +if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + # check Library permissions + PUID=${PUID:-911} + if [[ ! "$(stat -c %u /config/Library)" == "${PUID}" ]]; then + echo "Change in ownership detected, please be patient while we chown existing files" + echo "This could take some time" + lsiown -R abc:abc \ + /config/Library + fi -# permissions (non-recursive) on config root and folders -lsiown abc:abc \ - /run/plex-temp \ - /config \ - /config/* + # set permissions on Plex Transcoder Temp Directory + PLEX_MEDIA_SERVER_PREFERENCES="${PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR}/Plex Media Server/Preferences.xml" + if [[ -f "${PLEX_MEDIA_SERVER_PREFERENCES}" ]]; then + TranscoderTempDirectory='\bTranscoderTempDirectory="([^"]+)"' + while IFS= read -r line; do + if [[ ${line} =~ ${TranscoderTempDirectory} ]] && [[ -d "${BASH_REMATCH[1]}" ]]; then + echo "Setting permissions on ${BASH_REMATCH[1]}" + lsiown -R abc:abc "${BASH_REMATCH[1]}" + fi + done <"${PLEX_MEDIA_SERVER_PREFERENCES}" + fi + + # permissions (non-recursive) on config root and folders + lsiown abc:abc \ + /run/plex-temp \ + /config \ + /config/* +fi diff --git a/root/etc/s6-overlay/s6-rc.d/init-plex-gid-video/run b/root/etc/s6-overlay/s6-rc.d/init-plex-gid-video/run index cd01d814..083570fd 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-plex-gid-video/run +++ b/root/etc/s6-overlay/s6-rc.d/init-plex-gid-video/run @@ -1,35 +1,37 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash -FILES=$(find /dev/dri /dev/dvb -type c -print 2>/dev/null) +if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + FILES=$(find /dev/dri /dev/dvb -type c -print 2>/dev/null) -for i in ${FILES}; do - VIDEO_GID=$(stat -c '%g' "${i}") - VIDEO_UID=$(stat -c '%u' "${i}") - # check if user matches device - if id -u abc | grep -qw "${VIDEO_UID}"; then - echo "**** permissions for ${i} are good ****" - else - # check if group matches and that device has group rw - if id -G abc | grep -qw "${VIDEO_GID}" && [[ $(stat -c '%A' "${i}" | cut -b 5,6) == "rw" ]]; then + for i in ${FILES}; do + VIDEO_GID=$(stat -c '%g' "${i}") + VIDEO_UID=$(stat -c '%u' "${i}") + # check if user matches device + if id -u abc | grep -qw "${VIDEO_UID}"; then echo "**** permissions for ${i} are good ****" - # check if device needs to be added to video group - elif ! id -G abc | grep -qw "${VIDEO_GID}"; then - # check if video group needs to be created - VIDEO_NAME=$(getent group "${VIDEO_GID}" | awk -F: '{print $1}') - if [[ -z "${VIDEO_NAME}" ]]; then - VIDEO_NAME="video$(head /dev/urandom | tr -dc 'a-z0-9' | head -c4)" - groupadd "${VIDEO_NAME}" - groupmod -g "${VIDEO_GID}" "${VIDEO_NAME}" - echo "**** creating video group ${VIDEO_NAME} with id ${VIDEO_GID} ****" + else + # check if group matches and that device has group rw + if id -G abc | grep -qw "${VIDEO_GID}" && [[ $(stat -c '%A' "${i}" | cut -b 5,6) == "rw" ]]; then + echo "**** permissions for ${i} are good ****" + # check if device needs to be added to video group + elif ! id -G abc | grep -qw "${VIDEO_GID}"; then + # check if video group needs to be created + VIDEO_NAME=$(getent group "${VIDEO_GID}" | awk -F: '{print $1}') + if [[ -z "${VIDEO_NAME}" ]]; then + VIDEO_NAME="video$(head /dev/urandom | tr -dc 'a-z0-9' | head -c4)" + groupadd "${VIDEO_NAME}" + groupmod -g "${VIDEO_GID}" "${VIDEO_NAME}" + echo "**** creating video group ${VIDEO_NAME} with id ${VIDEO_GID} ****" + fi + echo "**** adding ${i} to video group ${VIDEO_NAME} with id ${VIDEO_GID} ****" + usermod -a -G "${VIDEO_NAME}" abc + fi + # check if device has group rw + if [[ $(stat -c '%A' "${i}" | cut -b 5,6) != "rw" ]]; then + echo -e "**** The device ${i} does not have group read/write permissions, attempting to fix inside the container. ****" + chmod g+rw "${i}" fi - echo "**** adding ${i} to video group ${VIDEO_NAME} with id ${VIDEO_GID} ****" - usermod -a -G "${VIDEO_NAME}" abc - fi - # check if device has group rw - if [[ $(stat -c '%A' "${i}" | cut -b 5,6) != "rw" ]]; then - echo -e "**** The device ${i} does not have group read/write permissions, attempting to fix inside the container. ****" - chmod g+rw "${i}" fi - fi -done + done +fi diff --git a/root/etc/s6-overlay/s6-rc.d/svc-plex/run b/root/etc/s6-overlay/s6-rc.d/svc-plex/run index 09fe8dff..bb607461 100755 --- a/root/etc/s6-overlay/s6-rc.d/svc-plex/run +++ b/root/etc/s6-overlay/s6-rc.d/svc-plex/run @@ -6,6 +6,13 @@ PLEX_MEDIA_SERVER_INFO_MODEL=$(uname -m) export PLEX_MEDIA_SERVER_INFO_MODEL PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION=$(uname -r) export PLEX_MEDIA_SERVER_INFO_PLATFORM_VERSION -exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 32400" \ - s6-setuidgid abc "/usr/lib/plexmediaserver/Plex Media Server" + +if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 32400" \ + s6-setuidgid abc "/usr/lib/plexmediaserver/Plex Media Server" +else + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 32400" \ + "/usr/lib/plexmediaserver/Plex Media Server" +fi