#!/usr/bin/env bash # Packet Station launcher on a VM. The native counterpart of docker/entrypoint.sh. # The systemd units and ps-run start every packetstation command through it. # # Usage: ps-launch.sh app | worker | migrate | doctor [...] | job run | version | healthcheck app|worker | ... # # It runs from a release folder, /opt/packetstation//deploy/vm/ps-launch.sh, and uses that # release's venv and built frontend. systemd has already loaded /etc/packetstation/packetstation.env. # # Secrets: each unit hands its own secrets to the service as systemd credentials (LoadCredential=), # so the app never sees the VISUAL or M-Files password. When $CREDENTIALS_DIRECTORY holds a known # secret, the matching *_FILE setting is pointed at it. MFilesKit reads its password from the # environment only, so MFILES_PASSWORD is exported from MFILES_PASSWORD_FILE, as the entrypoint does. # No value is ever printed. # # Set here, over the env file: STATIC_DIR and PS_BUILD (from the release), WORKER_BEAT_FILE, TZ, LANG. set -euo pipefail self="$(readlink -f -- "${BASH_SOURCE[0]}")" release="$(cd -- "$(dirname -- "$self")/../.." && pwd -P)" venv="${PS_VENV:-$release/venv}" # secret name (the credential id and the file name in /etc/packetstation/secrets) and its setting cred_map='postgres_app_password PG_APP_PASSWORD_FILE postgres_migrate_password PG_MIGRATE_PASSWORD_FILE visualkit_password VISUAL_PASSWORD_FILE mfileskit_password MFILES_PASSWORD_FILE ldap_bind_password LDAP_PASSWORD_FILE session_key SESSION_KEY_FILE seal_key SEAL_KEY_FILE' if [[ -n "${CREDENTIALS_DIRECTORY:-}" ]]; then while read -r name var; do if [[ -r "$CREDENTIALS_DIRECTORY/$name" ]]; then export "$var=$CREDENTIALS_DIRECTORY/$name" fi done <<< "$cred_map" fi unset cred_map name var mfiles_secret="${MFILES_PASSWORD_FILE:-}" if [[ -n "$mfiles_secret" && -r "$mfiles_secret" ]]; then MFILES_PASSWORD="$(<"$mfiles_secret")" # Drop a trailing carriage return left by an editor on Windows. MFILES_PASSWORD="${MFILES_PASSWORD%$'\r'}" export MFILES_PASSWORD fi unset mfiles_secret build="dev" if [[ -r "$release/BUILD" ]]; then build="$(head -n 1 -- "$release/BUILD")" build="${build%$'\r'}" fi export PATH="$venv/bin:/usr/local/bin:/usr/bin:/bin" export STATIC_DIR="$release/static" export PS_BUILD="$build" # The worker unit makes /run/packetstation (RuntimeDirectory=). The heartbeat lives there so # `ps-run healthcheck worker` reads the same file the worker writes. export WORKER_BEAT_FILE=/run/packetstation/worker.beat # The same as the containers: UTC process clock, UTF-8, unbuffered logs to the journal. export TZ=UTC export LANG=C.UTF-8 export PYTHONUNBUFFERED=1 export PYTHONDONTWRITEBYTECODE=1 unset build self if [[ $# -eq 0 ]]; then set -- app fi exec "$venv/bin/packetstation" "$@"