(refactor) Quiet native installer output by default
Add step-based installer logging that reports pobsync actions as OK, FAILED, or SKIPPED while suppressing noisy apt, pip, Django, and systemd output during successful runs. Show the captured output for the failed step when something breaks, and add a --verbose flag to restore full command output for debugging. Document the quieter installer behavior and verbose mode in the README and development notes.
This commit is contained in:
@@ -60,7 +60,8 @@ sudo scripts/install-systemd \
|
|||||||
|
|
||||||
Use `--no-install-os-packages` if you want to manage system packages yourself. Use `--force-env` only when you want the
|
Use `--no-install-os-packages` if you want to manage system packages yourself. Use `--force-env` only when you want the
|
||||||
installer to rewrite an existing `/etc/pobsync/pobsync.env`.
|
installer to rewrite an existing `/etc/pobsync/pobsync.env`.
|
||||||
Use `--non-interactive` for scripted installs.
|
Use `--non-interactive` for scripted installs. Use `--verbose` when you want to see the underlying apt, pip, Django, and
|
||||||
|
systemd output.
|
||||||
|
|
||||||
For MariaDB support, add:
|
For MariaDB support, add:
|
||||||
|
|
||||||
|
|||||||
@@ -72,11 +72,13 @@ Useful modes:
|
|||||||
```
|
```
|
||||||
sudo scripts/install-systemd
|
sudo scripts/install-systemd
|
||||||
sudo scripts/install-systemd --non-interactive
|
sudo scripts/install-systemd --non-interactive
|
||||||
|
sudo scripts/install-systemd --verbose
|
||||||
sudo scripts/install-systemd --create-superuser --superuser-username admin
|
sudo scripts/install-systemd --create-superuser --superuser-username admin
|
||||||
```
|
```
|
||||||
|
|
||||||
The installer should print a short completion summary with the control panel URL, Self Check reminder, and service log
|
The installer should print a short completion summary with the control panel URL, Self Check reminder, and service log
|
||||||
commands. Keep that output user-facing rather than developer-facing.
|
commands. Keep normal output user-facing: pobsync step names with OK, FAILED, or SKIPPED. Full apt, pip, Django, and
|
||||||
|
systemd output belongs behind `--verbose` or in the failed step output.
|
||||||
|
|
||||||
## Migration Helpers
|
## Migration Helpers
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ WEB_BIND=${POBSYNC_WEB_BIND:-127.0.0.1:8010}
|
|||||||
FORCE_ENV=0
|
FORCE_ENV=0
|
||||||
INSTALL_OS_PACKAGES=1
|
INSTALL_OS_PACKAGES=1
|
||||||
WITH_NGINX=0
|
WITH_NGINX=0
|
||||||
|
VERBOSE=0
|
||||||
INTERACTIVE=0
|
INTERACTIVE=0
|
||||||
CREATE_SUPERUSER=ask
|
CREATE_SUPERUSER=ask
|
||||||
SUPERUSER_USERNAME=${POBSYNC_SUPERUSER_USERNAME:-}
|
SUPERUSER_USERNAME=${POBSYNC_SUPERUSER_USERNAME:-}
|
||||||
@@ -72,6 +73,10 @@ while [ "$#" -gt 0 ]; do
|
|||||||
FORCE_ENV=1
|
FORCE_ENV=1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--verbose)
|
||||||
|
VERBOSE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--interactive)
|
--interactive)
|
||||||
INTERACTIVE=1
|
INTERACTIVE=1
|
||||||
shift
|
shift
|
||||||
@@ -128,6 +133,39 @@ if [ "$(id -u)" -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
run_step() {
|
||||||
|
label=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ "$VERBOSE" -eq 1 ]; then
|
||||||
|
echo "==> $label"
|
||||||
|
"$@"
|
||||||
|
echo "OK: $label"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%-48s' "$label"
|
||||||
|
log_file=$(mktemp)
|
||||||
|
if "$@" >"$log_file" 2>&1; then
|
||||||
|
rm -f "$log_file"
|
||||||
|
echo "OK"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "FAILED"
|
||||||
|
echo
|
||||||
|
echo "Output from failed step '$label':" >&2
|
||||||
|
cat "$log_file" >&2
|
||||||
|
rm -f "$log_file"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
note_step() {
|
||||||
|
label=$1
|
||||||
|
status=$2
|
||||||
|
printf '%-48s%s\n' "$label" "$status"
|
||||||
|
}
|
||||||
|
|
||||||
prompt_value() {
|
prompt_value() {
|
||||||
prompt=$1
|
prompt=$1
|
||||||
default=$2
|
default=$2
|
||||||
@@ -252,6 +290,7 @@ fi
|
|||||||
|
|
||||||
install_os_packages() {
|
install_os_packages() {
|
||||||
if [ "$INSTALL_OS_PACKAGES" -ne 1 ]; then
|
if [ "$INSTALL_OS_PACKAGES" -ne 1 ]; then
|
||||||
|
note_step "Install OS packages" "SKIPPED"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -263,8 +302,7 @@ install_os_packages() {
|
|||||||
if [ "$INSTALL_EXTRAS" = "mariadb" ] || [ "$INSTALL_EXTRAS" = "[mariadb]" ] || [ "$INSTALL_EXTRAS" = ".[mariadb]" ]; then
|
if [ "$INSTALL_EXTRAS" = "mariadb" ] || [ "$INSTALL_EXTRAS" = "[mariadb]" ] || [ "$INSTALL_EXTRAS" = ".[mariadb]" ]; then
|
||||||
packages="$packages default-libmysqlclient-dev build-essential pkg-config"
|
packages="$packages default-libmysqlclient-dev build-essential pkg-config"
|
||||||
fi
|
fi
|
||||||
apt-get update
|
run_step "Install OS packages" sh -c "apt-get update && apt-get install -y --no-install-recommends $packages"
|
||||||
apt-get install -y --no-install-recommends $packages
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -294,19 +332,23 @@ if [ ! -f "$SOURCE_DIR/manage.py" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! getent group "$SERVICE_GROUP" >/dev/null 2>&1; then
|
if ! getent group "$SERVICE_GROUP" >/dev/null 2>&1; then
|
||||||
groupadd --system "$SERVICE_GROUP"
|
run_step "Create service group" groupadd --system "$SERVICE_GROUP"
|
||||||
|
else
|
||||||
|
note_step "Create service group" "OK"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
|
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
|
||||||
useradd --system --home /var/lib/pobsync --shell /usr/sbin/nologin --gid "$SERVICE_GROUP" "$SERVICE_USER"
|
run_step "Create service user" useradd --system --home /var/lib/pobsync --shell /usr/sbin/nologin --gid "$SERVICE_GROUP" "$SERVICE_USER"
|
||||||
|
else
|
||||||
|
note_step "Create service user" "OK"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /etc/pobsync /var/lib/pobsync /var/log/pobsync "$(dirname "$VENV_DIR")" "$APP_DIR" "$BACKUP_ROOT"
|
run_step "Prepare directories" mkdir -p /etc/pobsync /var/lib/pobsync /var/log/pobsync "$(dirname "$VENV_DIR")" "$APP_DIR" "$BACKUP_ROOT"
|
||||||
chown "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync
|
run_step "Set state directory permissions" chown "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync
|
||||||
chmod 0750 /var/lib/pobsync /var/log/pobsync
|
run_step "Set private directory modes" chmod 0750 /var/lib/pobsync /var/log/pobsync
|
||||||
|
|
||||||
if [ "$SOURCE_DIR" != "$APP_DIR" ]; then
|
if [ "$SOURCE_DIR" != "$APP_DIR" ]; then
|
||||||
rsync -a --delete \
|
run_step "Sync application files" rsync -a --delete \
|
||||||
--exclude .git \
|
--exclude .git \
|
||||||
--exclude .venv \
|
--exclude .venv \
|
||||||
--exclude __pycache__ \
|
--exclude __pycache__ \
|
||||||
@@ -314,10 +356,12 @@ if [ "$SOURCE_DIR" != "$APP_DIR" ]; then
|
|||||||
--exclude .mypy_cache \
|
--exclude .mypy_cache \
|
||||||
--exclude var \
|
--exclude var \
|
||||||
"$SOURCE_DIR"/ "$APP_DIR"/
|
"$SOURCE_DIR"/ "$APP_DIR"/
|
||||||
|
else
|
||||||
|
note_step "Sync application files" "SKIPPED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
python3 -m venv "$VENV_DIR"
|
run_step "Create Python virtualenv" python3 -m venv "$VENV_DIR"
|
||||||
"$VENV_DIR/bin/python" -m pip install --upgrade pip
|
run_step "Upgrade pip" "$VENV_DIR/bin/python" -m pip install --upgrade pip
|
||||||
case "$INSTALL_EXTRAS" in
|
case "$INSTALL_EXTRAS" in
|
||||||
"")
|
"")
|
||||||
pip_target=$APP_DIR
|
pip_target=$APP_DIR
|
||||||
@@ -336,7 +380,7 @@ case "$INSTALL_EXTRAS" in
|
|||||||
exit 2
|
exit 2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
"$VENV_DIR/bin/python" -m pip install -e "$pip_target"
|
run_step "Install Python package" "$VENV_DIR/bin/python" -m pip install -e "$pip_target"
|
||||||
|
|
||||||
if [ ! -f "$ENV_FILE" ] || [ "$FORCE_ENV" -eq 1 ]; then
|
if [ ! -f "$ENV_FILE" ] || [ "$FORCE_ENV" -eq 1 ]; then
|
||||||
secret=$("$VENV_DIR/bin/python" -c "import secrets; print(secrets.token_urlsafe(48))")
|
secret=$("$VENV_DIR/bin/python" -c "import secrets; print(secrets.token_urlsafe(48))")
|
||||||
@@ -359,8 +403,9 @@ POBSYNC_SCHEDULER_INTERVAL=60
|
|||||||
EOF
|
EOF
|
||||||
chmod 0640 "$ENV_FILE"
|
chmod 0640 "$ENV_FILE"
|
||||||
chown "root:$SERVICE_GROUP" "$ENV_FILE"
|
chown "root:$SERVICE_GROUP" "$ENV_FILE"
|
||||||
echo "Wrote $ENV_FILE."
|
note_step "Write environment file" "OK"
|
||||||
else
|
else
|
||||||
|
note_step "Write environment file" "SKIPPED"
|
||||||
echo "Keeping existing $ENV_FILE. Use --force-env to rewrite it."
|
echo "Keeping existing $ENV_FILE. Use --force-env to rewrite it."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -382,49 +427,63 @@ install_unit() {
|
|||||||
chmod 0644 "$dest"
|
chmod 0644 "$dest"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_units() {
|
||||||
install_unit "$APP_DIR/deploy/systemd/pobsync-web.service" /etc/systemd/system/pobsync-web.service
|
install_unit "$APP_DIR/deploy/systemd/pobsync-web.service" /etc/systemd/system/pobsync-web.service
|
||||||
install_unit "$APP_DIR/deploy/systemd/pobsync-worker.service" /etc/systemd/system/pobsync-worker.service
|
install_unit "$APP_DIR/deploy/systemd/pobsync-worker.service" /etc/systemd/system/pobsync-worker.service
|
||||||
install_unit "$APP_DIR/deploy/systemd/pobsync-scheduler.service" /etc/systemd/system/pobsync-scheduler.service
|
install_unit "$APP_DIR/deploy/systemd/pobsync-scheduler.service" /etc/systemd/system/pobsync-scheduler.service
|
||||||
|
}
|
||||||
|
|
||||||
systemctl daemon-reload
|
run_step "Install systemd units" install_units
|
||||||
"$VENV_DIR/bin/python" "$APP_DIR/manage.py" migrate --noinput
|
|
||||||
"$VENV_DIR/bin/python" "$APP_DIR/manage.py" collectstatic --noinput --clear
|
run_step "Reload systemd" systemctl daemon-reload
|
||||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync
|
run_step "Run database migrations" "$VENV_DIR/bin/python" "$APP_DIR/manage.py" migrate --noinput
|
||||||
|
run_step "Collect static files" "$VENV_DIR/bin/python" "$APP_DIR/manage.py" 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')")
|
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')")
|
||||||
if [ "$CREATE_SUPERUSER" -eq 1 ]; then
|
if [ "$CREATE_SUPERUSER" -eq 1 ]; then
|
||||||
if [ "$superuser_exists" = "yes" ]; then
|
if [ "$superuser_exists" = "yes" ]; then
|
||||||
echo "A Django superuser already exists; skipping superuser creation."
|
note_step "Create Django superuser" "SKIPPED"
|
||||||
elif [ -n "$SUPERUSER_USERNAME" ] && [ -n "$SUPERUSER_PASSWORD" ]; then
|
elif [ -n "$SUPERUSER_USERNAME" ] && [ -n "$SUPERUSER_PASSWORD" ]; then
|
||||||
DJANGO_SUPERUSER_USERNAME=$SUPERUSER_USERNAME \
|
run_step "Create Django superuser" env \
|
||||||
DJANGO_SUPERUSER_EMAIL=$SUPERUSER_EMAIL \
|
DJANGO_SUPERUSER_USERNAME="$SUPERUSER_USERNAME" \
|
||||||
DJANGO_SUPERUSER_PASSWORD=$SUPERUSER_PASSWORD \
|
DJANGO_SUPERUSER_EMAIL="$SUPERUSER_EMAIL" \
|
||||||
|
DJANGO_SUPERUSER_PASSWORD="$SUPERUSER_PASSWORD" \
|
||||||
"$VENV_DIR/bin/python" "$APP_DIR/manage.py" createsuperuser --noinput
|
"$VENV_DIR/bin/python" "$APP_DIR/manage.py" createsuperuser --noinput
|
||||||
echo "Created Django superuser '$SUPERUSER_USERNAME'."
|
run_step "Finalize superuser permissions" chown -R "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync
|
||||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" /var/lib/pobsync /var/log/pobsync
|
|
||||||
else
|
else
|
||||||
|
note_step "Create Django superuser" "SKIPPED"
|
||||||
echo "No superuser password was provided; create one later with:"
|
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 $VENV_DIR/bin/python $APP_DIR/manage.py createsuperuser"
|
||||||
fi
|
fi
|
||||||
elif [ "$superuser_exists" != "yes" ]; then
|
elif [ "$superuser_exists" != "yes" ]; then
|
||||||
|
note_step "Create Django superuser" "SKIPPED"
|
||||||
echo "No Django superuser exists yet. Create one with:"
|
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 $VENV_DIR/bin/python $APP_DIR/manage.py createsuperuser"
|
||||||
|
else
|
||||||
|
note_step "Create Django superuser" "SKIPPED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
systemctl enable --now pobsync-web.service pobsync-worker.service pobsync-scheduler.service
|
run_step "Enable and start services" systemctl enable --now pobsync-web.service pobsync-worker.service pobsync-scheduler.service
|
||||||
|
|
||||||
if [ "$WITH_NGINX" -eq 1 ]; then
|
if [ "$WITH_NGINX" -eq 1 ]; then
|
||||||
if ! command -v nginx >/dev/null 2>&1; then
|
if ! command -v nginx >/dev/null 2>&1; then
|
||||||
|
note_step "Install nginx config" "SKIPPED"
|
||||||
echo "nginx is not installed; skipping nginx config." >&2
|
echo "nginx is not installed; skipping nginx config." >&2
|
||||||
else
|
else
|
||||||
sed "s|@POBSYNC_SERVER_NAME@|$SERVER_NAME|g" "$APP_DIR/deploy/nginx/pobsync.conf" > /etc/nginx/sites-available/pobsync.conf
|
sed "s|@POBSYNC_SERVER_NAME@|$SERVER_NAME|g" "$APP_DIR/deploy/nginx/pobsync.conf" > /etc/nginx/sites-available/pobsync.conf
|
||||||
ln -sf /etc/nginx/sites-available/pobsync.conf /etc/nginx/sites-enabled/pobsync.conf
|
ln -sf /etc/nginx/sites-available/pobsync.conf /etc/nginx/sites-enabled/pobsync.conf
|
||||||
nginx -t
|
note_step "Install nginx config" "OK"
|
||||||
systemctl reload nginx
|
run_step "Validate nginx config" nginx -t
|
||||||
|
run_step "Reload nginx" systemctl reload nginx
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
note_step "Install nginx config" "SKIPPED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$VERBOSE" -eq 1 ]; then
|
||||||
systemctl --no-pager --full status pobsync-web.service pobsync-worker.service pobsync-scheduler.service || true
|
systemctl --no-pager --full status pobsync-web.service pobsync-worker.service pobsync-scheduler.service || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "pobsync installation complete."
|
echo "pobsync installation complete."
|
||||||
|
|||||||
Reference in New Issue
Block a user