feat: add systemd install script for daemon-only deployment
The daemon already handles bidirectional sync (SVN→Git polling and Git→SVN push), so a single systemd service is sufficient. The script creates a venv, generates svn-mirror.service, and enables it for a given user (default: gitea). README updated accordingly. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -235,14 +235,57 @@ it fetches the new commits from Gitea and runs `sync_git_to_svn`.
|
|||||||
- Secret: same as `webhook_secret` in config
|
- Secret: same as `webhook_secret` in config
|
||||||
- Events: "Push"
|
- Events: "Push"
|
||||||
|
|
||||||
### Mode C: Both (recommended)
|
### Mode C: systemd service (recommended)
|
||||||
|
|
||||||
Run daemon AND webhook. The daemon handles SVN→Git polling; the webhook
|
The daemon handles **bidirectional** sync: SVN→Git polling AND Git→SVN push
|
||||||
handles instant Git→SVN on developer push.
|
on each cycle. One service is all you need.
|
||||||
|
|
||||||
|
#### Quick install via script
|
||||||
|
|
||||||
|
Use the provided install script to generate and enable the systemd service
|
||||||
|
running as a given user (e.g. `gitea`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
screen -dmS daemon python3.11 -m svn_mirror daemon --config /etc/svn-mirror/config.yml
|
sudo ./deploy/install.sh --install-dir /opt/svn-git-server --user gitea
|
||||||
screen -dmS webhook python3.11 -m svn_mirror webhook --config /etc/svn-mirror/config.yml
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Create a Python virtualenv at `<install-dir>/.venv` and install deps
|
||||||
|
- Generate `svn-mirror.service`
|
||||||
|
- Enable the service (auto-start on boot)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
| Option | Default | Description |
|
||||||
|
|--------|---------|-------------|
|
||||||
|
| `--install-dir DIR` | *(required)* | Where the code is installed |
|
||||||
|
| `--user USER` | `gitea` | System user to run the service as |
|
||||||
|
| `--config FILE` | `<install-dir>/config.yml` | Config file path |
|
||||||
|
| `--venv DIR` | `<install-dir>/.venv` | Virtualenv path |
|
||||||
|
| `--uninstall` | — | Remove service instead of installing |
|
||||||
|
|
||||||
|
After install, start the service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl start svn-mirror
|
||||||
|
```
|
||||||
|
|
||||||
|
Check logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u svn-mirror -f
|
||||||
|
```
|
||||||
|
|
||||||
|
To uninstall:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./deploy/install.sh --uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Manual setup (screen/tmux)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
screen -dmS svn-mirror python3.11 -m svn_mirror daemon --config /etc/svn-mirror/config.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mode D: Gitea post-receive hook (filesystem)
|
### Mode D: Gitea post-receive hook (filesystem)
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
#!/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: <install-dir>/config.yml)
|
||||||
|
# --venv DIR Virtualenv path (default: <install-dir>/.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" <<EOF
|
||||||
|
# Generated by svn-git-server deploy/install.sh
|
||||||
|
# Do not edit by hand — re-run install.sh to change settings.
|
||||||
|
[Unit]
|
||||||
|
Description=gitea-svn-mirror daemon (bidirectional SVN<->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"
|
||||||
Reference in New Issue
Block a user