From 73e6bb7285712162581c72a466e9a2128c27ea62 Mon Sep 17 00:00:00 2001 From: Peter van Arkel Date: Wed, 20 May 2026 01:27:08 +0200 Subject: [PATCH] (ops) Install pobsync-manage for native management commands Add a pobsync-manage wrapper that loads the native environment file before running Django management commands, so production commands use the same database and runtime settings as the systemd services. Install the wrapper from the systemd installer, use it for migrations, static collection, SSH key setup, and superuser creation, and document it in the README for operational commands. --- README.md | 11 ++++++++++- deploy/bin/pobsync-manage | 19 +++++++++++++++++++ scripts/install-systemd | 24 ++++++++++++++++++------ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 deploy/bin/pobsync-manage diff --git a/README.md b/README.md index 8a31590..325739d 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ The installer will, by default: - copy the checkout to `/opt/pobsync/app` - create `/opt/pobsync/venv` - write `/etc/pobsync/pobsync.env` if it does not exist +- install `pobsync-manage`, a Django management wrapper that loads `/etc/pobsync/pobsync.env` - create `/var/lib/pobsync`, `/var/log/pobsync`, and the backup root - install Python dependencies - run migrations and collect static files @@ -127,7 +128,15 @@ http://127.0.0.1:8010/ Create a superuser if needed: ``` -sudo -u pobsync /opt/pobsync/venv/bin/python /opt/pobsync/app/manage.py createsuperuser +sudo -u pobsync pobsync-manage createsuperuser +``` + +For other Django management commands on native installs, use `pobsync-manage` so the production environment file is +loaded before Django starts: + +``` +sudo -u pobsync pobsync-manage showmigrations pobsync_backend +sudo -u pobsync pobsync-manage check ``` The UI includes: diff --git a/deploy/bin/pobsync-manage b/deploy/bin/pobsync-manage new file mode 100644 index 0000000..f55c96a --- /dev/null +++ b/deploy/bin/pobsync-manage @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +APP_DIR="@POBSYNC_APP_DIR@" +VENV_DIR="@POBSYNC_VENV_DIR@" +ENV_FILE="@POBSYNC_ENV_FILE@" + +if [ ! -f "$ENV_FILE" ]; then + echo "pobsync environment file not found: $ENV_FILE" >&2 + exit 1 +fi + +set -a +# shellcheck disable=SC1090 +. "$ENV_FILE" +set +a + +cd "$APP_DIR" +exec "$VENV_DIR/bin/python" "$APP_DIR/manage.py" "$@" diff --git a/scripts/install-systemd b/scripts/install-systemd index 938d947..05cbc23 100755 --- a/scripts/install-systemd +++ b/scripts/install-systemd @@ -504,10 +504,21 @@ install_units() { run_step "Install systemd units" install_units +install_manage_wrapper() { + sed \ + -e "s|@POBSYNC_APP_DIR@|$APP_DIR|g" \ + -e "s|@POBSYNC_VENV_DIR@|$VENV_DIR|g" \ + -e "s|@POBSYNC_ENV_FILE@|$ENV_FILE|g" \ + "$APP_DIR/deploy/bin/pobsync-manage" > /usr/local/bin/pobsync-manage + chmod 0755 /usr/local/bin/pobsync-manage +} + +run_step "Install manage wrapper" install_manage_wrapper + run_step "Reload systemd" systemctl daemon-reload -run_step "Run database migrations" "$VENV_DIR/bin/python" "$APP_DIR/manage.py" migrate --noinput -run_step "Ensure default SSH key" "$VENV_DIR/bin/python" "$APP_DIR/manage.py" ensure_pobsync_ssh_key --name default --set-global-default -run_step "Collect static files" "$VENV_DIR/bin/python" "$APP_DIR/manage.py" collectstatic --noinput --clear +run_step "Run database migrations" /usr/local/bin/pobsync-manage migrate --noinput +run_step "Ensure default SSH key" /usr/local/bin/pobsync-manage ensure_pobsync_ssh_key --name default --set-global-default +run_step "Collect static files" /usr/local/bin/pobsync-manage collectstatic --noinput --clear run_step "Finalize state permissions" chown -R "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync superuser_exists=$("$VENV_DIR/bin/python" -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pobsync_server.settings'); import django; django.setup(); from django.contrib.auth import get_user_model; print('yes' if get_user_model().objects.filter(is_superuser=True).exists() else 'no')") @@ -519,17 +530,17 @@ if [ "$CREATE_SUPERUSER" -eq 1 ]; then DJANGO_SUPERUSER_USERNAME="$SUPERUSER_USERNAME" \ DJANGO_SUPERUSER_EMAIL="$SUPERUSER_EMAIL" \ DJANGO_SUPERUSER_PASSWORD="$SUPERUSER_PASSWORD" \ - "$VENV_DIR/bin/python" "$APP_DIR/manage.py" createsuperuser --noinput + /usr/local/bin/pobsync-manage createsuperuser --noinput run_step "Finalize superuser permissions" chown -R "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync else note_step "Create Django superuser" "SKIPPED" echo "No superuser password was provided; create one later with:" - echo " sudo -u $SERVICE_USER $VENV_DIR/bin/python $APP_DIR/manage.py createsuperuser" + echo " sudo -u $SERVICE_USER pobsync-manage createsuperuser" fi elif [ "$superuser_exists" != "yes" ]; then note_step "Create Django superuser" "SKIPPED" echo "No Django superuser exists yet. Create one with:" - echo " sudo -u $SERVICE_USER $VENV_DIR/bin/python $APP_DIR/manage.py createsuperuser" + echo " sudo -u $SERVICE_USER pobsync-manage createsuperuser" else note_step "Create Django superuser" "SKIPPED" fi @@ -574,3 +585,4 @@ echo echo "Useful commands:" echo " systemctl status pobsync-web pobsync-worker pobsync-scheduler" echo " journalctl -u pobsync-worker -f" +echo " sudo -u $SERVICE_USER pobsync-manage check"