#!/bin/bash # # Install svn-git-server as a systemd service (daemon). # # The daemon handles bidirectional sync: SVN->Git polling AND Git->SVN push. # # Usage: # sudo ./deploy/install.sh --install-dir /opt/svn-git-server --user gitea # # Options: # --install-dir DIR Path where the code is installed (required) # --user USER System user to run the service as (default: gitea) # --config FILE Config file path (default: /config.yml) # --venv DIR Virtualenv path (default: /.venv) # --uninstall Remove service instead of installing # set -euo pipefail INSTALL_DIR="" SERVICE_USER="gitea" CONFIG_FILE="" VENV_DIR="" UNINSTALL=false # ── Parse args ────────────────────────────────────────────── while [[ $# -gt 0 ]]; do case "$1" in --install-dir) INSTALL_DIR="$2"; shift 2 ;; --user) SERVICE_USER="$2"; shift 2 ;; --config) CONFIG_FILE="$2"; shift 2 ;; --venv) VENV_DIR="$2"; shift 2 ;; --uninstall) UNINSTALL=true; shift ;; -h|--help) grep -E '^#( |$)' "$0" | sed 's/^# \?//' exit 0 ;; *) echo "Unknown option: $1" >&2 exit 1 ;; esac done if [[ "$UNINSTALL" == true ]]; then echo "Removing svn-mirror service..." systemctl disable --now svn-mirror.service 2>/dev/null || true rm -f /etc/systemd/system/svn-mirror.service systemctl daemon-reload echo "Done. Service removed." exit 0 fi if [[ -z "$INSTALL_DIR" ]]; then echo "Error: --install-dir is required" >&2 echo "Usage: sudo $0 --install-dir /opt/svn-git-server --user gitea" >&2 exit 1 fi # Resolve to absolute path INSTALL_DIR="$(cd "$INSTALL_DIR" 2>/dev/null && pwd)" || { echo "Error: install-dir '$INSTALL_DIR' does not exist" >&2 exit 1 } CONFIG_FILE="${CONFIG_FILE:-$INSTALL_DIR/config.yml}" VENV_DIR="${VENV_DIR:-$INSTALL_DIR/.venv}" echo "=== svn-mirror install ===" echo " Install dir: $INSTALL_DIR" echo " User: $SERVICE_USER" echo " Config: $CONFIG_FILE" echo " Venv: $VENV_DIR" echo "" # ── Checks ────────────────────────────────────────────────── if [[ "$EUID" -ne 0 ]]; then echo "Error: must run as root (use sudo)" >&2 exit 1 fi if ! id "$SERVICE_USER" &>/dev/null; then echo "Error: user '$SERVICE_USER' does not exist" >&2 exit 1 fi if [[ ! -f "$CONFIG_FILE" ]]; then echo "Warning: config file '$CONFIG_FILE' not found" echo " You can create it later before starting the service." fi if [[ ! -d "$VENV_DIR" ]]; then echo "Creating virtualenv at $VENV_DIR ..." python3 -m venv "$VENV_DIR" chown -R "$SERVICE_USER":"$SERVICE_USER" "$VENV_DIR" sudo -u "$SERVICE_USER" "$VENV_DIR/bin/pip" install --quiet --upgrade pip sudo -u "$SERVICE_USER" "$VENV_DIR/bin/pip" install --quiet -r "$INSTALL_DIR/requirements.txt" echo " Virtualenv created." else echo "Virtualenv already exists at $VENV_DIR" fi # Make sure the install dir is owned by the service user chown -R "$SERVICE_USER":"$SERVICE_USER" "$INSTALL_DIR" # ── Generate systemd unit ─────────────────────────────────── SERVICE_UNIT="/etc/systemd/system/svn-mirror.service" cat > "$SERVICE_UNIT" <Git sync) After=network-online.target Wants=network-online.target [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_USER WorkingDirectory=$INSTALL_DIR ExecStart=$VENV_DIR/bin/python -m svn_mirror daemon --config $CONFIG_FILE Restart=always RestartSec=10 StandardOutput=journal StandardError=journal # Ensure UTF-8 locale for SVN with non-ASCII filenames Environment=LC_ALL=en_US.UTF-8 Environment=LANG=en_US.UTF-8 [Install] WantedBy=multi-user.target EOF echo "Created service file:" echo " $SERVICE_UNIT" # ── Reload and enable ─────────────────────────────────────── systemctl daemon-reload systemctl enable svn-mirror.service echo "" echo "Service enabled. Start it with:" echo " systemctl start svn-mirror" echo "" echo "Check logs with:" echo " journalctl -u svn-mirror -f" echo "" echo "Status:" echo " systemctl status svn-mirror"