b46be5c076
Hop-State: A_06FPC0CGS3F7SJG3BGW0YF0 Hop-Proposal: R_06FPC0BK6YEV7XASNM7C908 Hop-Task: T_06FPAWA3279RBMJAR0BHM10 Hop-Attempt: AT_06FPBZWSBFTB9B5YH9JY9QR
127 lines
4.6 KiB
Bash
Executable File
127 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
APP_DIR="${APP_DIR:-/opt/synapsis}"
|
|
DATA_DIR="${DATA_DIR:-/var/lib/synapsis}"
|
|
ENV_FILE="${ENV_FILE:-/etc/synapsis.env}"
|
|
BRANCH="${BRANCH:-main}"
|
|
DEPLOYED_COMMIT_FILE="$DATA_DIR/deployed-commit"
|
|
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
echo "Run this updater as root." >&2
|
|
exit 1
|
|
fi
|
|
|
|
[[ -d "$APP_DIR/.git" ]] || { echo "No Synapsis checkout found at $APP_DIR" >&2; exit 1; }
|
|
[[ -f "$ENV_FILE" ]] || { echo "Missing $ENV_FILE" >&2; exit 1; }
|
|
|
|
set -a
|
|
source "$ENV_FILE"
|
|
set +a
|
|
|
|
# Existing installations predate encrypted-message recovery. Enroll them with
|
|
# a distinct stable secret before migrations/builds make E2EE available.
|
|
if [[ -z "${E2EE_RECOVERY_SECRET:-}" ]]; then
|
|
command -v openssl >/dev/null || { echo "Missing required command: openssl" >&2; exit 1; }
|
|
E2EE_RECOVERY_SECRET="$(openssl rand -base64 48 | tr -d '\n')"
|
|
printf '\nE2EE_RECOVERY_SECRET=%s\n' "$E2EE_RECOVERY_SECRET" >> "$ENV_FILE"
|
|
export E2EE_RECOVERY_SECRET
|
|
echo "Added E2EE_RECOVERY_SECRET to $ENV_FILE. Back it up separately from the database."
|
|
fi
|
|
|
|
install_update_units() {
|
|
units_changed=0
|
|
for unit in synapsis.service synapsis-maintenance.service synapsis-update.service synapsis-update.timer; do
|
|
if ! cmp -s "$APP_DIR/deploy/$unit" "/etc/systemd/system/$unit"; then
|
|
install -m 0644 "$APP_DIR/deploy/$unit" "/etc/systemd/system/$unit"
|
|
units_changed=1
|
|
fi
|
|
done
|
|
|
|
if [[ "$units_changed" == "1" ]]; then
|
|
systemctl daemon-reload
|
|
fi
|
|
if ! systemctl is-enabled --quiet synapsis-update.timer; then
|
|
systemctl enable synapsis-update.timer
|
|
fi
|
|
if ! systemctl is-active --quiet synapsis-update.timer; then
|
|
systemctl start synapsis-update.timer
|
|
fi
|
|
}
|
|
|
|
if [[ "${SYNAPSIS_APPLY_UPDATE:-0}" != "1" ]]; then
|
|
runuser -u synapsis -- git -C "$APP_DIR" fetch --prune origin "+refs/heads/$BRANCH:refs/remotes/origin/$BRANCH"
|
|
|
|
current_commit="$(runuser -u synapsis -- git -C "$APP_DIR" rev-parse HEAD)"
|
|
target_commit="$(runuser -u synapsis -- git -C "$APP_DIR" rev-parse "origin/$BRANCH")"
|
|
deployed_commit=""
|
|
if [[ -f "$DEPLOYED_COMMIT_FILE" ]]; then
|
|
deployed_commit="$(tr -d '[:space:]' < "$DEPLOYED_COMMIT_FILE")"
|
|
fi
|
|
|
|
if [[ -n "$deployed_commit" && "$deployed_commit" == "$target_commit" ]]; then
|
|
install_update_units
|
|
echo "Synapsis is already current at ${target_commit:0:7}."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "$current_commit" != "$target_commit" ]]; then
|
|
if ! runuser -u synapsis -- git -C "$APP_DIR" merge-base --is-ancestor "$current_commit" "$target_commit"; then
|
|
echo "Cannot auto-update: local checkout has diverged from origin/$BRANCH." >&2
|
|
exit 1
|
|
fi
|
|
runuser -u synapsis -- git -C "$APP_DIR" merge --ff-only "origin/$BRANCH"
|
|
fi
|
|
|
|
exec env SYNAPSIS_APPLY_UPDATE=1 APP_DIR="$APP_DIR" DATA_DIR="$DATA_DIR" ENV_FILE="$ENV_FILE" BRANCH="$BRANCH" bash "$APP_DIR/deploy/update.sh"
|
|
fi
|
|
|
|
install_update_units
|
|
if ! runuser -u synapsis -- env \
|
|
PORT="${PORT:-43821}" \
|
|
MAINTENANCE_APP_DIR="$APP_DIR" \
|
|
MAINTENANCE_DATA_DIR="$DATA_DIR" \
|
|
node "$APP_DIR/deploy/maintenance-server.mjs" --capture-branding; then
|
|
echo "Warning: could not refresh maintenance-page branding; using the last captured branding." >&2
|
|
fi
|
|
systemctl stop synapsis
|
|
systemctl start synapsis-maintenance
|
|
|
|
restore_service() {
|
|
systemctl stop synapsis-maintenance 2>/dev/null || true
|
|
systemctl start synapsis
|
|
}
|
|
trap restore_service EXIT
|
|
|
|
if [[ -f "${DATABASE_PATH:-$DATA_DIR/synapsis.db}" ]]; then
|
|
database_file="${DATABASE_PATH:-$DATA_DIR/synapsis.db}"
|
|
backup_root="$DATA_DIR/backups"
|
|
backup_staging="$backup_root/.latest.$$"
|
|
backup_dir="$backup_root/latest"
|
|
install -d -o synapsis -g synapsis -m 0750 "$backup_root"
|
|
rm -rf "$backup_staging"
|
|
install -d -o synapsis -g synapsis -m 0750 "$backup_staging"
|
|
cp "$database_file" "$backup_staging/synapsis.db"
|
|
for suffix in -wal -shm; do
|
|
if [[ -f "${database_file}${suffix}" ]]; then
|
|
cp "${database_file}${suffix}" "$backup_staging/synapsis.db${suffix}"
|
|
fi
|
|
done
|
|
chown -R synapsis:synapsis "$backup_staging"
|
|
rm -rf "$backup_dir"
|
|
mv "$backup_staging" "$backup_dir"
|
|
find "$backup_root" -mindepth 1 -maxdepth 1 ! -name latest -exec rm -rf {} +
|
|
fi
|
|
|
|
runuser -u synapsis -- npm --prefix "$APP_DIR" ci
|
|
runuser -u synapsis -- npm --prefix "$APP_DIR" run db:migrate
|
|
runuser -u synapsis -- npm --prefix "$APP_DIR" run build
|
|
|
|
deployed_commit="$(runuser -u synapsis -- git -C "$APP_DIR" rev-parse HEAD)"
|
|
printf '%s\n' "$deployed_commit" | install -m 0644 -o synapsis -g synapsis /dev/stdin "$DEPLOYED_COMMIT_FILE"
|
|
install_update_units
|
|
systemctl stop synapsis-maintenance
|
|
systemctl start synapsis
|
|
trap - EXIT
|
|
echo "Synapsis updated successfully to ${deployed_commit:0:7}."
|