#!/usr/bin/env bash set -euo pipefail SERVICE_NAME="vmess-domain-rotator" APP_DIR="/opt/vmess-domain-rotator" RUN_USER="vmessrotator" RUN_GROUP="vmessrotator" APP_DIR_SET="0" RUN_USER_SET="0" RUN_GROUP_SET="0" INTERVAL="12h" INSTALL_DEPS="1" OVERWRITE_CONFIG="0" usage() { cat <<'EOF' Usage: sudo bash scripts/install_debian.sh [options] Default behavior: - If current source dir is a git repo and --app-dir is not set, install in-place (service runs directly from this repo so auto-commit works on your real git repo). - If --app-dir is set, files are copied into that directory. Options: --app-dir Install directory (default: /opt/vmess-domain-rotator) --user Service user (default: vmessrotator) --group Service group (default: vmessrotator) --interval Timer interval, e.g. 12h/10min (default: 12h) --no-install-deps Skip apt dependency install --overwrite-config Overwrite existing config.json in app dir -h, --help Show help Examples: sudo bash scripts/install_debian.sh sudo bash scripts/install_debian.sh --app-dir /opt/vmess-domain-rotator sudo bash scripts/install_debian.sh --user root --group root --interval 10min EOF } while [[ $# -gt 0 ]]; do case "$1" in --app-dir) APP_DIR="$2" APP_DIR_SET="1" shift 2 ;; --user) RUN_USER="$2" RUN_USER_SET="1" shift 2 ;; --group) RUN_GROUP="$2" RUN_GROUP_SET="1" shift 2 ;; --interval) INTERVAL="$2" shift 2 ;; --no-install-deps) INSTALL_DEPS="0" shift ;; --overwrite-config) OVERWRITE_CONFIG="1" shift ;; -h|--help) usage exit 0 ;; *) echo "Unknown option: $1" >&2 usage exit 1 ;; esac done if [[ "$(id -u)" -ne 0 ]]; then echo "Please run as root (use sudo)." >&2 exit 1 fi SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DEPLOY_MODE="copy" if [[ "$APP_DIR_SET" != "1" ]] && git -C "$SOURCE_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then APP_DIR="$SOURCE_DIR" DEPLOY_MODE="in-place" if [[ -n "${SUDO_USER:-}" ]] && [[ "$RUN_USER_SET" != "1" ]]; then RUN_USER="$SUDO_USER" fi if [[ -n "${SUDO_USER:-}" ]] && [[ "$RUN_GROUP_SET" != "1" ]]; then RUN_GROUP="$(id -gn "$SUDO_USER")" fi fi if [[ "$INSTALL_DEPS" == "1" ]]; then export DEBIAN_FRONTEND=noninteractive apt-get update -y apt-get install -y python3 ca-certificates git fi if [[ "$RUN_USER" != "root" ]]; then if ! getent group "$RUN_GROUP" >/dev/null 2>&1; then groupadd --system "$RUN_GROUP" fi if ! id -u "$RUN_USER" >/dev/null 2>&1; then useradd --system --home-dir "$APP_DIR" --create-home --shell /usr/sbin/nologin --gid "$RUN_GROUP" "$RUN_USER" fi fi mkdir -p "$APP_DIR" if [[ "$DEPLOY_MODE" == "copy" ]]; then CONFIG_BACKUP="" if [[ "$OVERWRITE_CONFIG" != "1" && -f "$APP_DIR/config.json" ]]; then CONFIG_BACKUP="$(mktemp)" cp "$APP_DIR/config.json" "$CONFIG_BACKUP" fi tar -C "$SOURCE_DIR" \ --exclude='.git' \ --exclude='.DS_Store' \ --exclude='__pycache__' \ -cf - . | tar -C "$APP_DIR" -xf - if [[ -n "$CONFIG_BACKUP" ]]; then cp "$CONFIG_BACKUP" "$APP_DIR/config.json" rm -f "$CONFIG_BACKUP" fi fi mkdir -p "$APP_DIR/runtime" chmod +x "$APP_DIR/scripts/run_update_and_commit.sh" "$APP_DIR/scripts/install_debian.sh" "$APP_DIR/scripts/uninstall_debian.sh" || true if [[ "$RUN_USER" != "root" ]]; then if [[ "$DEPLOY_MODE" == "in-place" ]]; then chown -R "$RUN_USER:$RUN_GROUP" "$APP_DIR/runtime" else chown -R "$RUN_USER:$RUN_GROUP" "$APP_DIR" fi fi if [[ "$DEPLOY_MODE" == "copy" ]] && ! git -C "$APP_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then git -C "$APP_DIR" init fi cat >"/etc/systemd/system/${SERVICE_NAME}.service" <"/etc/systemd/system/${SERVICE_NAME}.timer" <