feat(system): add systemd service and installation script

- Add gitks systemd service unit file with security sandboxing
- Create environment configuration template for gitks service
- Add logrotate configuration for gitks application logs
- Implement installation script with service user creation
- Set up proper directory permissions and file ownership
- Configure automatic service startup and systemd integration
This commit is contained in:
zhenyi
2026-06-08 21:27:54 +08:00
parent c2487ec0b6
commit eeb4d9f902
5 changed files with 248 additions and 225 deletions
+35
View File
@@ -0,0 +1,35 @@
# GitKS environment configuration
#
# This file is sourced by systemd via EnvironmentFile.
# Uncomment and adjust values as needed.
#
# Location: /etc/gitks/gitks.env
# Permissions: 0640 root:gitks
REPO_PREFIX_PATH=/data/repos
GITKS_HOST=0.0.0.0
GITKS_PORT=50051
# GITKS_ADVERTISE_ADDR=http://node1.example.com:50051
GITKS_METRICS_PORT=9100
GITKS_CLUSTER_PORT=4697
GITKS_CLUSTER_COOKIE=gitks-default-cookie
# GITKS_CLUSTER_HOSTNAME=node1.example.com
GITKS_ETCD_ENDPOINTS=http://localhost:2379
GITKS_ETCD_CONNECT_TIMEOUT=5000
GITKS_LEASE_TTL=15
GITKS_HEALTH_CHECK_INTERVAL=1
GITKS_MAX_HEALTH_FAILURES=10
GITKS_DISK_CACHE_ENABLED=false
GITKS_DISK_CACHE_MAX_AGE=300
GITKS_PACK_CACHE_ENABLED=false
GITKS_PACK_CACHE_BACKPRESSURE=true
GITKS_HOOKS_ENABLED=true
GITKS_HOOK_TIMEOUT=30
GITKS_ALLOW_CUSTOM_HOOKS=true
# GITKS_SERVER_HOOKS_DIR=/etc/gitks/hooks
# GITKS_HOOK_CALLBACK_ADDR=http://localhost:50052
GITKS_RATE_LIMIT_MAX_CONCURRENT=200
# === LOGGING ===
RUST_LOG=info
Executable
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env bash
# GitKS bare-metal installation script
#
# Installs the gitks binary, systemd service, environment config,
# logrotate config, and creates the service user and data directory.
#
# Usage:
# sudo ./install.sh # install from local build
# sudo ./install.sh /path/to/gitks # install from prebuilt binary
# sudo GITKS_USER=custom ./install.sh # use a different service user
set -euo pipefail
GITKS_USER="${GITKS_USER:-gitks}"
GITKS_GROUP="${GITKS_GROUP:-gitks}"
BINARY_SRC="${1:-target/release/gitks}"
INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local}"
DATA_DIR="${DATA_DIR:-/data/repos}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ── Preflight checks ──────────────────────────────────────────────
[[ $EUID -eq 0 ]] || err "This script must be run as root (use sudo)"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
command -v git >/dev/null 2>&1 || {
warn "git not found in PATH. Installing git..."
if command -v apt-get >/dev/null 2>&1; then
apt-get update -qq && apt-get install -y -qq git
elif command -v yum >/dev/null 2>&1; then
yum install -y git
elif command -v dnf >/dev/null 2>&1; then
dnf install -y git
else
err "Cannot install git automatically. Please install git first."
fi
}
# ── Create service user ───────────────────────────────────────────
if id "$GITKS_USER" &>/dev/null; then
log "User '$GITKS_USER' already exists"
else
log "Creating system user '$GITKS_USER'"
useradd --system --user-group --home-dir /var/lib/gitks \
--shell /usr/sbin/nologin --comment "GitKS service" "$GITKS_USER"
fi
# ── Install binary ────────────────────────────────────────────────
BINARY_DST="${INSTALL_PREFIX}/bin/gitks"
if [[ -f "$BINARY_SRC" ]]; then
log "Installing gitks binary: $BINARY_SRC$BINARY_DST"
install -o root -g root -m 0755 "$BINARY_SRC" "$BINARY_DST"
elif [[ -f "$PROJECT_DIR/$BINARY_SRC" ]]; then
log "Installing gitks binary: $PROJECT_DIR/$BINARY_SRC$BINARY_DST"
install -o root -g root -m 0755 "$PROJECT_DIR/$BINARY_SRC" "$BINARY_DST"
else
warn "Binary not found at '$BINARY_SRC'. Skipping binary install."
warn "Build first: cargo build --release"
warn "Or specify path: sudo ./install.sh /path/to/gitks"
fi
# ── Create directories ────────────────────────────────────────────
log "Creating directories..."
install -d -o "$GITKS_USER" -g "$GITKS_GROUP" -m 0750 /var/lib/gitks
install -d -o "$GITKS_USER" -g "$GITKS_GROUP" -m 0750 /var/log/gitks
install -d -o root -g root -m 0755 /etc/gitks
[[ -d "$DATA_DIR" ]] || {
log "Creating repo data directory: $DATA_DIR"
mkdir -p "$DATA_DIR"
chown "$GITKS_USER:$GITKS_GROUP" "$DATA_DIR"
}
# ── Install config ────────────────────────────────────────────────
CONF_SRC="${PROJECT_DIR}/etc/gitks.env"
if [[ -f /etc/gitks/gitks.env ]]; then
warn "/etc/gitks/gitks.env already exists — skipping (preserving existing config)"
else
log "Installing environment config..."
install -o root -g "$GITKS_GROUP" -m 0640 "$CONF_SRC" /etc/gitks/gitks.env
log "Edit /etc/gitks/gitks.env to configure your deployment"
fi
# ── Install systemd service ───────────────────────────────────────
log "Installing systemd service..."
install -o root -g root -m 0644 \
"${PROJECT_DIR}/etc/systemd/gitks.service" \
/etc/systemd/system/gitks.service
# ── Install logrotate config ──────────────────────────────────────
LOG_ROTATE_SRC="${PROJECT_DIR}/etc/logrotate.d/gitks"
if [[ -d /etc/logrotate.d ]]; then
if [[ -f /etc/logrotate.d/gitks ]]; then
warn "/etc/logrotate.d/gitks already exists — skipping"
else
log "Installing logrotate config..."
install -o root -g root -m 0644 "$LOG_ROTATE_SRC" /etc/logrotate.d/gitks
fi
fi
# ── Reload systemd & enable ───────────────────────────────────────
log "Reloading systemd..."
systemctl daemon-reload
log "Enabling gitks to start on boot..."
systemctl enable gitks.service
# ── Done ──────────────────────────────────────────────────────────
echo ""
log "Installation complete!"
echo ""
echo " Next steps:"
echo " 1. Edit config: vim /etc/gitks/gitks.env"
echo " 2. Start service: systemctl start gitks"
echo " 3. Check status: systemctl status gitks"
echo " 4. View logs: journalctl -fu gitks"
echo ""
echo " Cluster setup (multi-node):"
echo " - Set STORAGE_NAME uniquely per node"
echo " - Set GITKS_CLUSTER_HOSTNAME to each node's hostname"
echo " - Set GITKS_ADVERTISE_ADDR to each node's reachable IP:port"
echo " - Point GITKS_ETCD_ENDPOINTS to your etcd cluster"
echo ""
+22
View File
@@ -0,0 +1,22 @@
# GitKS logrotate configuration
#
# Rotates file-based application logs if gitks is configured
# to write logs to a file instead of journald.
#
# Location: /etc/logrotate.d/gitks
# Permissions: 0644 root:root
/var/log/gitks/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 gitks gitks
sharedscripts
postrotate
# Notify gitks to reopen log files if needed
/bin/systemctl kill -s HUP gitks.service 2>/dev/null || true
endscript
}
+59
View File
@@ -0,0 +1,59 @@
[Unit]
Description=GitKS - gRPC Git Bare Repository Operations Service
Documentation=https://github.com/example/gitks
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=gitks
Group=gitks
# Environment
EnvironmentFile=/etc/gitks/gitks.env
# Runtime directories
RuntimeDirectory=gitks
StateDirectory=gitks
WorkingDirectory=/var/lib/gitks
# Executable (assumes installed to /usr/local/bin/gitks)
ExecStart=/usr/local/bin/gitks
# Restart policy
Restart=on-failure
RestartSec=5s
# Graceful shutdown — send SIGTERM, wait, then SIGKILL
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30s
# Sandbox hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/gitks /data/repos
ReadOnlyPaths=/etc/gitks
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictRealtime=yes
RestrictNamespaces=yes
LockPersonality=yes
MemoryDenyWriteExecute=no
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
# Logging to journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=gitks
# Limit file descriptors (git may open many files)
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target