133 lines
3.7 KiB
Bash
Executable File
133 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
function run() {
|
|
# we're not root. Run as who we are.
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
eval "$@"
|
|
else
|
|
gosu pypiserver "$@"
|
|
fi
|
|
}
|
|
|
|
if [[ "$EUID" -ne 0 && "$EUID" -ne $(id -u pypiserver) ]]; then
|
|
USER_ID="$EUID"
|
|
WARN=(
|
|
"The pypiserver container was run as a non-root, non-pypiserver user."
|
|
"Pypiserver will be run as this user if possible, but this is not"
|
|
"officially supported."
|
|
)
|
|
echo "" 1>&2
|
|
echo "${WARN[@]}" 1>&2
|
|
echo "" 1>&2
|
|
else
|
|
USER_ID=$(id -u pypiserver)
|
|
fi
|
|
|
|
|
|
function print_permissions_help() {
|
|
MSG1=(
|
|
"If you are mounting a volume at /data or /data/packages and are running the"
|
|
"container on a linux system, you may need to add add a pypiserver"
|
|
"group to the host and give it permission to access the directories."
|
|
"Please see https://github.com/pypiserver/pypiserver/issues/256 for more"
|
|
"details."
|
|
)
|
|
MSG2=(
|
|
"Please see https://github.com/pypiserver/pypiserver/issues/256 for more"
|
|
"details."
|
|
)
|
|
echo "" 1>&2
|
|
echo "${MSG1[@]}" 1>&2
|
|
echo "" 1>&2
|
|
echo "${MSG2[@]}" 1>&2
|
|
}
|
|
|
|
|
|
# the user must have read and execute access to the /data directory
|
|
# (execute to be able to cd into directory and list content metadata)
|
|
if ! run test -r /data -a -x /data; then
|
|
|
|
chown -R "$USER_ID:pypiserver" /data || true
|
|
|
|
if ! run test -r /data -a -x /data; then
|
|
FAIL_MSG=(
|
|
"Cannot start pypiserver:"
|
|
"pypiserver user (UID $USER_ID)"
|
|
"or pypiserver group (GID $(id -g pypiserver))"
|
|
"must have read/execute access to /data"
|
|
)
|
|
echo "${FAIL_MSG[@]}" 1>&2
|
|
echo "" 1>&2
|
|
print_permissions_help
|
|
exit 1
|
|
fi
|
|
|
|
fi
|
|
|
|
# The /data/packages directory must exist
|
|
# It not existing is very unlikely, possibly impossible, because the VOLUME
|
|
# specification in the Dockerfile leads to its being created even if someone is
|
|
# mounting a volume at /data that does not contain a /packages subdirectory
|
|
if [[ ! -d "/data/packages" ]]; then
|
|
if ! run test -w /data; then
|
|
FAIL_MSG=(
|
|
"Cannot start pypiserver:"
|
|
"/data/packages does not exist and"
|
|
"pypiserver user (UID $USER_ID)"
|
|
"or pypiserver group (GID $(id -g pypiserver))"
|
|
"does not have write access to /data to create it"
|
|
)
|
|
echo "" 1>&2
|
|
echo "${FAIL_MSG[@]}" 1>&2
|
|
print_permissions_help
|
|
exit 1
|
|
fi
|
|
run mkdir /data/packages
|
|
fi
|
|
|
|
# The pypiserver user needs read/write/execute access to the packages directory
|
|
if ! run \
|
|
test -w /data/packages \
|
|
-a -r /data/packages \
|
|
-a -x /data/packages; then
|
|
|
|
# We'll try to chown as a last resort.
|
|
# Don't complain if it fails, since we'll bomb on the next check anyway.
|
|
chown -R "$USER_ID:pypiserver" /data/packages || true
|
|
|
|
if ! run \
|
|
test -w /data/packages \
|
|
-a -r /data/packages \
|
|
-a -x /data/packages; then
|
|
FAIL_MSG=(
|
|
"Cannot start pypiserver:"
|
|
"pypiserver user (UID $USER_ID)"
|
|
"or pypiserver group (GID $(id -g pypiserver))"
|
|
"must have read/write/execute access to /data/packages"
|
|
)
|
|
echo "" 1>&2
|
|
echo "${FAIL_MSG[@]}" 1>&2
|
|
print_permissions_help
|
|
exit 1
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
if [[ "$*" == "" ]]; then
|
|
# Use the gunicorn server by default, since it's more performant than
|
|
# bottle's default server
|
|
CMD=("run" "-p" "${PYPISERVER_PORT:-$PORT}" "--server" "gunicorn")
|
|
else
|
|
# this reassigns the array to the CMD variable
|
|
CMD=( "${@}" )
|
|
fi
|
|
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
exec pypi-server "${CMD[@]}"
|
|
else
|
|
exec gosu pypiserver pypi-server "${CMD[@]}"
|
|
fi
|