[优化] 部署脚本优化

This commit is contained in:
ryan
2026-06-06 11:06:45 +08:00
parent 3cfefb4367
commit 2662c65f57
6 changed files with 577 additions and 228 deletions
+358 -23
View File
@@ -15,6 +15,252 @@ AGENT_TOKEN=""
CREATE_SERVICE="true"
SERVICE_NAME="openflare-agent"
OPENRESTY_PATH=""
INSTALL_METHOD=""
CURRENT_DIR="$(pwd)"
LOG_FILE="${CURRENT_DIR}/install.log"
# Translation text variables
TXT_DOCKER_RESTARTED="Docker 已启动/重启并运行中"
TXT_LOW_DOCKER_VERSION="Docker 版本较低,建议升级到 20.10 及以上版本"
TXT_INSTALL_DOCKER_CONFIRM="未检测到 Docker,是否现在安装?(y/n) [y]: "
TXT_DOCKER_INSTALL_ONLINE="开始在线安装 Docker..."
TXT_INSTALL_DOCKER_ONLINE="使用 opkg 在线安装 Docker..."
TXT_CHOOSE_LOWEST_LATENCY_SOURCE="选择延迟最低的镜像源:"
TXT_CHOOSE_LOWEST_LATENCY_DELAY="延迟为:"
TXT_TRY_NEXT_LINK="尝试使用链接:"
TXT_DOWNLOAD_DOCKER_SCRIPT="下载 Docker 安装脚本..."
TXT_DOWNLOAD_DOCKER_SCRIPT_SUCCESS="下载成功:"
TXT_SUCCESSFULLY_MESSAGE="开始执行安装..."
TXT_DOWNLOAD_FAIELD="下载失败:"
TXT_ALL_DOWNLOAD_ATTEMPTS_FAILED="所有 Docker 下载尝试均失败,请手动安装 Docker"
TXT_DOCKER_INSTALL_FAIL="Docker 安装失败"
TXT_DOCKER_INSTALL_SUCCESS="Docker 安装成功"
TXT_CANNOT_SELECT_SOURCE="无法选择合适的镜像源"
TXT_REGIONS_OTHER_THAN_CHINA="检测到非中国大陆地区,使用官方源安装 Docker..."
TXT_DOCKER_START_NOTICE="正在启动 Docker 服务..."
TXT_CANCEL_INSTALL_DOCKER="已取消 Docker 安装"
TXT_INVALID_YN_INPUT="无效的输入,请输入 y 或 n"
log() {
echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
configure_accelerator() {
log "配置 Docker 国内镜像加速源..."
local docker_config_folder="/etc/docker"
if [[ ! -d "$docker_config_folder" ]]; then
mkdir -p "$docker_config_folder"
fi
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
if command -v systemctl &>/dev/null; then
systemctl daemon-reload
systemctl restart docker
else
service dockerd restart
fi
}
function Install_Docker(){
if which docker >/dev/null 2>&1; then
docker_version=$(docker --version | grep -oE '[0-9]+\.[0-9]+' | head -n 1)
major_version=${docker_version%%.*}
minor_version=${docker_version##*.}
local service_cmd="service dockerd start && service dockerd status"
if command -v systemctl &>/dev/null; then
service_cmd="systemctl start docker && systemctl status docker"
fi
set +e
local service_status=$($service_cmd 2>&1)
set -e
if [[ $service_status == *running* ]]; then
log "$TXT_DOCKER_RESTARTED"
else
if [[ $major_version -lt 20 ]]; then
log "$TXT_LOW_DOCKER_VERSION"
fi
set +e
local country_code=$(curl -s --max-time 5 ipinfo.io/country)
set -e
if [[ "$country_code" == "CN" ]]; then
configure_accelerator
fi
fi
else
while true; do
read -p "$TXT_INSTALL_DOCKER_CONFIRM" install_docker_choice
install_docker_choice=${install_docker_choice:-y}
case "$install_docker_choice" in
[yY])
log "$TXT_DOCKER_INSTALL_ONLINE"
if command -v opkg &>/dev/null; then
log "$TXT_INSTALL_DOCKER_ONLINE"
opkg update
opkg install luci-i18n-dockerman-zh-cn
opkg install zoneinfo-asia
service system restart
set +e
local country_code=$(curl -s --max-time 5 ipinfo.io/country)
set -e
if [[ "$country_code" == "CN" ]]; then
configure_accelerator
fi
else
set +e
local country_code=$(curl -s --max-time 5 ipinfo.io/country)
set -e
if [[ "$country_code" == "CN" ]]; then
sources=(
"https://mirrors.aliyun.com/docker-ce"
"https://mirrors.tencent.com/docker-ce"
"https://mirrors.163.com/docker-ce"
"https://mirrors.cernet.edu.cn/docker-ce"
)
docker_install_scripts=(
"https://get.docker.com"
"https://testingcf.jsdelivr.net/gh/docker/docker-install@master/install.sh"
"https://cdn.jsdelivr.net/gh/docker/docker-install@master/install.sh"
"https://fastly.jsdelivr.net/gh/docker/docker-install@master/install.sh"
"https://gcore.jsdelivr.net/gh/docker/docker-install@master/install.sh"
"https://raw.githubusercontent.com/docker/docker-install/master/install.sh"
)
get_average_delay() {
local source=$1
local total_delay=0
local iterations=2
local timeout=2
for ((i = 0; i < iterations; i++)); do
delay=$(curl -o /dev/null -s -m $timeout -w "%{time_total}\n" "$source")
if [ $? -ne 0 ]; then
delay=$timeout
fi
total_delay=$(awk "BEGIN {print $total_delay + $delay}")
done
average_delay=$(awk "BEGIN {print $total_delay / $iterations}")
echo "$average_delay"
}
min_delay=99999999
selected_source=""
for source in "${sources[@]}"; do
average_delay=$(get_average_delay "$source" &)
if (( $(awk 'BEGIN { print '"$average_delay"' < '"$min_delay"' }') )); then
min_delay=$average_delay
selected_source=$source
fi
done
wait
if [ -n "$selected_source" ]; then
log "$TXT_CHOOSE_LOWEST_LATENCY_SOURCE $selected_source,$TXT_CHOOSE_LOWEST_LATENCY_DELAY $min_delay"
export DOWNLOAD_URL="$selected_source"
for alt_source in "${docker_install_scripts[@]}"; do
log "$TXT_TRY_NEXT_LINK $alt_source $TXT_DOWNLOAD_DOCKER_SCRIPT"
if curl -fsSL --retry 2 --retry-delay 3 --connect-timeout 5 --max-time 10 "$alt_source" -o get-docker.sh; then
log "$TXT_DOWNLOAD_DOCKER_SCRIPT_SUCCESS $alt_source $TXT_SUCCESSFULLY_MESSAGE"
break
else
log "$TXT_DOWNLOAD_FAIELD $alt_source $TXT_TRY_NEXT_LINK"
fi
done
if [ ! -f "get-docker.sh" ]; then
log "$TXT_ALL_DOWNLOAD_ATTEMPTS_FAILED"
log "bash <(curl -sSL https://linuxmirrors.cn/docker.sh)"
exit 1
fi
sh get-docker.sh 2>&1 | tee -a "${CURRENT_DIR}/install.log"
docker_config_folder="/etc/docker"
if [[ ! -d "$docker_config_folder" ]]; then
mkdir -p "$docker_config_folder"
fi
set +e
docker version >/dev/null 2>&1
local docker_ver_res=$?
set -e
if [[ $docker_ver_res -ne 0 ]]; then
log "$TXT_DOCKER_INSTALL_FAIL"
exit 1
else
log "$TXT_DOCKER_INSTALL_SUCCESS"
if command -v systemctl &>/dev/null; then
systemctl enable docker 2>&1 | tee -a "${LOG_FILE}"
fi
configure_accelerator
fi
else
log "$TXT_CANNOT_SELECT_SOURCE"
exit 1
fi
else
log "$TXT_REGIONS_OTHER_THAN_CHINA"
export DOWNLOAD_URL="https://download.docker.com"
curl -fsSL "https://get.docker.com" -o get-docker.sh
sh get-docker.sh 2>&1 | tee -a "${LOG_FILE}"
log "$TXT_DOCKER_START_NOTICE"
if command -v systemctl &>/dev/null; then
systemctl enable docker; systemctl daemon-reload; systemctl start docker 2>&1 | tee -a "${LOG_FILE}"
else
service dockerd start 2>&1 | tee -a "${LOG_FILE}"
sleep 1
fi
docker_config_folder="/etc/docker"
if [[ ! -d "$docker_config_folder" ]]; then
mkdir -p "$docker_config_folder"
fi
set +e
docker version >/dev/null 2>&1
local docker_ver_res=$?
set -e
if [[ $docker_ver_res -ne 0 ]]; then
log "$TXT_DOCKER_INSTALL_FAIL"
exit 1
else
log "$TXT_DOCKER_INSTALL_SUCCESS"
fi
fi
fi
break
;;
[nN])
echo "$TXT_CANCEL_INSTALL_DOCKER"
exit 1
;;
*)
log "$TXT_INVALID_YN_INPUT"
continue
;;
esac
done
fi
}
usage() {
cat <<EOF
@@ -24,29 +270,35 @@ Usage:
install-agent.sh [OPTIONS]
Options:
--server-url URL Server URL (required)
--server-url URL Server URL
--discovery-token TOKEN Discovery token for auto-registration
--agent-token TOKEN Node-specific agent token
--install-dir DIR Installation directory (default: /opt/openflare-agent)
--openresty-path PATH OpenResty binary path (default: auto-detect from PATH)
--repo REPO GitHub repository (default: Rain-kl/OpenFlare)
--no-service Do not create systemd service
--docker Install via Docker container
--method METHOD Installation method: 'local' or 'docker' (default: local)
-h, --help Show this help message
Examples:
# Install with discovery token (auto-register)
# Interactive installation (prompts for options)
install-agent.sh
# Automated local installation
install-agent.sh --server-url http://10.0.0.1:3000 --discovery-token abc123
# Install with node-specific token
install-agent.sh --server-url http://10.0.0.1:3000 --agent-token node-token-xyz
Notes:
Reinstall will remove the entire install directory before installing again,
including the old agent.json, local state, cached data, and downloaded binary.
# Automated Docker installation
install-agent.sh --server-url http://10.0.0.1:3000 --discovery-token abc123 --docker
EOF
exit 0
}
HAS_ARGS="false"
if [[ $# -gt 0 ]]; then
HAS_ARGS="true"
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--server-url) SERVER_URL="$2"; shift 2 ;;
@@ -56,19 +308,111 @@ while [[ $# -gt 0 ]]; do
--openresty-path) OPENRESTY_PATH="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--no-service) CREATE_SERVICE="false"; shift ;;
--docker) INSTALL_METHOD="docker"; shift ;;
--method) INSTALL_METHOD="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
if [[ -z "$SERVER_URL" ]]; then
echo "Error: --server-url is required"
exit 1
if [[ "$HAS_ARGS" == "false" ]]; then
echo "=================================================="
echo "欢迎使用 OpenFlare Agent 安装脚本"
echo "Welcome to the OpenFlare Agent Installer"
echo "=================================================="
echo "请选择安装方式 / Please choose installation method:"
echo " 1) Local (本地安装: 下载二进制运行,需要本地有 OpenResty)"
echo " 2) Docker (容器安装: 运行内置 OpenResty 的 Agent 容器)"
read -p "请输入序号 [1-2] (默认 1): " method_choice
method_choice=${method_choice:-1}
case "$method_choice" in
2) INSTALL_METHOD="docker" ;;
*) INSTALL_METHOD="local" ;;
esac
if [[ "$INSTALL_METHOD" == "docker" ]]; then
Install_Docker
fi
# Prompt for Server URL
while [[ -z "$SERVER_URL" ]]; do
read -p "请输入 OpenFlare Server 地址 (例如 http://127.0.0.1:3000): " SERVER_URL
done
# Prompt for Token
while [[ -z "$DISCOVERY_TOKEN" && -z "$AGENT_TOKEN" ]]; do
echo "请选择认证 Token 类型 / Please choose token type:"
echo " 1) Discovery Token (自动注册凭证 - 适合新节点上线)"
echo " 2) Agent Token (专属接入凭证 - 适合预创建节点)"
read -p "请输入序号 [1-2] (默认 1): " token_type_choice
token_type_choice=${token_type_choice:-1}
if [[ "$token_type_choice" == "2" ]]; then
read -p "请输入 Agent Token: " AGENT_TOKEN
else
read -p "请输入 Discovery Token: " DISCOVERY_TOKEN
fi
done
else
# Non-interactive mode validation
if [[ -z "$INSTALL_METHOD" ]]; then
INSTALL_METHOD="local"
fi
if [[ -z "$SERVER_URL" ]]; then
echo "Error: --server-url is required"
exit 1
fi
if [[ -z "$DISCOVERY_TOKEN" && -z "$AGENT_TOKEN" ]]; then
echo "Error: either --discovery-token or --agent-token is required"
exit 1
fi
fi
if [[ -z "$DISCOVERY_TOKEN" && -z "$AGENT_TOKEN" ]]; then
echo "Error: either --discovery-token or --agent-token is required"
exit 1
# Run Docker container installation if Docker method selected
if [[ "$INSTALL_METHOD" == "docker" ]]; then
echo "拉取最新的 OpenFlare Agent 镜像..."
docker pull ghcr.io/rain-kl/openflare-agent:latest
echo "停止并移除旧的 openflare-agent 容器 (如果存在)..."
docker rm -f openflare-agent 2>/dev/null || true
echo "启动 openflare-agent 容器..."
if [[ -n "$AGENT_TOKEN" ]]; then
docker run -d --name openflare-agent --restart unless-stopped \
-p 80:80 -p 443:443/tcp -p 443:443/udp \
-e OPENFLARE_SERVER_URL="${SERVER_URL}" \
-e OPENFLARE_AGENT_TOKEN="${AGENT_TOKEN}" \
ghcr.io/rain-kl/openflare-agent:latest
else
docker run -d --name openflare-agent --restart unless-stopped \
-p 80:80 -p 443:443/tcp -p 443:443/udp \
-e OPENFLARE_SERVER_URL="${SERVER_URL}" \
-e OPENFLARE_DISCOVERY_TOKEN="${DISCOVERY_TOKEN}" \
ghcr.io/rain-kl/openflare-agent:latest
fi
echo ""
echo "OpenFlare Agent (Docker) 安装成功!"
echo "您可以执行以下命令查看运行日志:"
echo " docker logs -f openflare-agent"
exit 0
fi
# Local installation starts below
if [[ -z "$OPENRESTY_PATH" ]]; then
if command -v openresty >/dev/null 2>&1; then
OPENRESTY_PATH="$(command -v openresty)"
elif [[ "$HAS_ARGS" == "false" ]]; then
read -p "未在 PATH 中检测到 openresty,请输入 OpenResty 二进制路径: " OPENRESTY_PATH
if [[ -z "$OPENRESTY_PATH" ]]; then
echo "Error: OpenResty binary path is required for local installation."
exit 1
fi
else
echo "Error: openresty was not found in PATH. Install OpenResty first or pass --openresty-path."
exit 1
fi
fi
# Detect platform
@@ -85,15 +429,6 @@ if [[ "$OS" != "linux" && "$OS" != "darwin" ]]; then
exit 1
fi
if [[ -z "$OPENRESTY_PATH" ]]; then
if command -v openresty >/dev/null 2>&1; then
OPENRESTY_PATH="$(command -v openresty)"
else
echo "Error: openresty was not found in PATH. Install OpenResty first or pass --openresty-path."
exit 1
fi
fi
if [[ ! -x "$OPENRESTY_PATH" ]]; then
echo "Error: OpenResty binary is not executable: ${OPENRESTY_PATH}"
exit 1
-192
View File
@@ -1,192 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
INSTALL_DIR="/opt/openflare-agent"
SERVICE_NAME="openflare-agent"
usage() {
cat <<EOF
OpenFlare Agent Uninstaller
Usage:
uninstall-agent.sh [OPTIONS]
Options:
--install-dir DIR Installation directory (default: /opt/openflare-agent)
--service-name NAME systemd service name (default: openflare-agent)
-h, --help Show this help message
Behavior:
1. Stop the agent service/process and remove the entire installation directory
2. Remove the systemd service definition when present
3. Check the saved agent config to identify the OpenResty mode
4. If Docker mode was used, remove the OpenResty container and try to remove its image
5. If local openresty_path mode was used, do not modify the local OpenResty install
Examples:
uninstall-agent.sh
uninstall-agent.sh --install-dir /srv/openflare-agent
EOF
exit 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
--install-dir) INSTALL_DIR="$2"; shift 2 ;;
--service-name) SERVICE_NAME="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
if [[ -z "$INSTALL_DIR" || "$INSTALL_DIR" == "/" || "$INSTALL_DIR" == "." ]]; then
echo "Refusing to remove unsafe install directory: '${INSTALL_DIR}'"
exit 1
fi
json_get_string() {
local file="$1"
local key="$2"
local match
match=$(grep -o "\"${key}\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" "$file" 2>/dev/null | head -n 1 || true)
if [[ -z "$match" ]]; then
return 0
fi
printf '%s\n' "$match" | sed -E 's/.*:[[:space:]]*"([^"]*)"/\1/'
}
AGENT_BINARY="${INSTALL_DIR}/openflare-agent"
CONFIG_FILE="${INSTALL_DIR}/agent.json"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
OPENRESTY_PATH=""
OPENRESTY_CONTAINER_NAME="openflare-openresty"
OPENRESTY_DOCKER_IMAGE="openresty/openresty:alpine"
DOCKER_BINARY="docker"
OPENRESTY_MODE="unknown"
if [[ -f "$CONFIG_FILE" ]]; then
OPENRESTY_PATH="$(json_get_string "$CONFIG_FILE" "openresty_path")"
OPENRESTY_CONTAINER_NAME="$(json_get_string "$CONFIG_FILE" "openresty_container_name")"
OPENRESTY_DOCKER_IMAGE="$(json_get_string "$CONFIG_FILE" "openresty_docker_image")"
DOCKER_BINARY="$(json_get_string "$CONFIG_FILE" "docker_binary")"
if [[ -z "$OPENRESTY_CONTAINER_NAME" ]]; then
OPENRESTY_CONTAINER_NAME="openflare-openresty"
fi
if [[ -z "$OPENRESTY_DOCKER_IMAGE" ]]; then
OPENRESTY_DOCKER_IMAGE="openresty/openresty:alpine"
fi
if [[ -z "$DOCKER_BINARY" ]]; then
DOCKER_BINARY="docker"
fi
if [[ -n "$OPENRESTY_PATH" ]]; then
OPENRESTY_MODE="local"
else
OPENRESTY_MODE="docker"
fi
fi
SYSTEMCTL_AVAILABLE="false"
if command -v systemctl >/dev/null 2>&1; then
SYSTEMCTL_AVAILABLE="true"
fi
echo "Uninstalling OpenFlare Agent from ${INSTALL_DIR}..."
if [[ "$SYSTEMCTL_AVAILABLE" == "true" ]]; then
if systemctl is-active --quiet "$SERVICE_NAME"; then
echo "Stopping service: ${SERVICE_NAME}"
systemctl stop "$SERVICE_NAME"
fi
if systemctl is-enabled --quiet "$SERVICE_NAME" >/dev/null 2>&1; then
echo "Disabling service: ${SERVICE_NAME}"
systemctl disable "$SERVICE_NAME" >/dev/null 2>&1 || true
fi
fi
if command -v pgrep >/dev/null 2>&1; then
mapfile -t agent_pids < <(pgrep -f "$AGENT_BINARY" || true)
if (( ${#agent_pids[@]} > 0 )); then
echo "Stopping agent process: ${agent_pids[*]}"
kill "${agent_pids[@]}" || true
sleep 1
mapfile -t remaining_agent_pids < <(pgrep -f "$AGENT_BINARY" || true)
if (( ${#remaining_agent_pids[@]} > 0 )); then
echo "Force stopping remaining agent process: ${remaining_agent_pids[*]}"
kill -9 "${remaining_agent_pids[@]}" || true
fi
fi
fi
if [[ -f "$SERVICE_FILE" ]]; then
echo "Removing service file: ${SERVICE_FILE}"
rm -f "$SERVICE_FILE"
fi
if [[ "$SYSTEMCTL_AVAILABLE" == "true" ]]; then
systemctl daemon-reload || true
systemctl reset-failed "$SERVICE_NAME" >/dev/null 2>&1 || true
fi
if [[ -d "$INSTALL_DIR" ]]; then
echo "Removing installation directory: ${INSTALL_DIR}"
rm -rf "$INSTALL_DIR"
else
echo "Installation directory not found, skipping: ${INSTALL_DIR}"
fi
echo "Agent uninstall complete."
echo ""
echo "Checking OpenResty installation mode..."
if [[ "$OPENRESTY_MODE" == "docker" ]]; then
echo "Detected Docker OpenResty mode."
if ! command -v "$DOCKER_BINARY" >/dev/null 2>&1; then
echo "Docker binary '${DOCKER_BINARY}' was not found."
echo "Please remove container '${OPENRESTY_CONTAINER_NAME}' and image '${OPENRESTY_DOCKER_IMAGE}' manually."
exit 0
fi
if "$DOCKER_BINARY" inspect "$OPENRESTY_CONTAINER_NAME" >/dev/null 2>&1; then
if [[ -z "$OPENRESTY_DOCKER_IMAGE" ]]; then
OPENRESTY_DOCKER_IMAGE="$("$DOCKER_BINARY" inspect -f '{{.Config.Image}}' "$OPENRESTY_CONTAINER_NAME" 2>/dev/null || true)"
fi
echo "Removing Docker container: ${OPENRESTY_CONTAINER_NAME}"
"$DOCKER_BINARY" rm -f "$OPENRESTY_CONTAINER_NAME"
else
echo "Docker container not found, skipping: ${OPENRESTY_CONTAINER_NAME}"
fi
if [[ -n "$OPENRESTY_DOCKER_IMAGE" ]] && "$DOCKER_BINARY" image inspect "$OPENRESTY_DOCKER_IMAGE" >/dev/null 2>&1; then
other_container_ids="$("$DOCKER_BINARY" ps -a --filter "ancestor=${OPENRESTY_DOCKER_IMAGE}" --format '{{.ID}}' 2>/dev/null || true)"
if [[ -z "$other_container_ids" ]]; then
echo "Removing Docker image: ${OPENRESTY_DOCKER_IMAGE}"
if ! "$DOCKER_BINARY" image rm "$OPENRESTY_DOCKER_IMAGE"; then
echo "Image removal skipped because Docker reported it is still in use."
fi
else
echo "Docker image is still used by other containers, skipping image removal: ${OPENRESTY_DOCKER_IMAGE}"
fi
fi
echo "Docker OpenResty cleanup complete."
elif [[ "$OPENRESTY_MODE" == "local" ]]; then
echo "Detected local OpenResty mode via openresty_path:"
echo " ${OPENRESTY_PATH}"
echo "Agent has been removed, but the local OpenResty installation was not modified."
echo "Please uninstall the local OpenResty manually if you no longer need it."
else
echo "OpenResty mode could not be determined because ${CONFIG_FILE} was not found before uninstall."
echo "If you were using Docker OpenResty, please remove its container and image manually if needed."
fi
echo ""
echo "OpenFlare Agent uninstall finished."
+76 -2
View File
@@ -3,6 +3,7 @@ set -euo pipefail
INSTALL_DIR="/opt/openflare-agent"
SERVICE_NAME="openflare-agent"
INSTALL_METHOD=""
usage() {
cat <<EOF
@@ -14,29 +15,102 @@ Usage:
Options:
--install-dir DIR Installation directory (default: /opt/openflare-agent)
--service-name NAME systemd service name (default: openflare-agent)
--docker Uninstall Docker container agent
--method METHOD Uninstall method: 'local' or 'docker' (default: local)
-h, --help Show this help message
Behavior:
1. Stop the agent service/process and remove the entire installation directory
2. Remove the systemd service definition when present
3. Leave the local OpenResty installation untouched
3. Uninstall Docker container when --docker is specified
4. Leave the local OpenResty installation untouched
Examples:
# Interactive uninstall (prompts for options)
uninstall-agent.sh
uninstall-agent.sh --install-dir /srv/openflare-agent
# Automated local uninstall
uninstall-agent.sh --install-dir /opt/openflare-agent
# Automated Docker uninstall
uninstall-agent.sh --docker
EOF
exit 0
}
HAS_ARGS="false"
if [[ $# -gt 0 ]]; then
HAS_ARGS="true"
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--install-dir) INSTALL_DIR="$2"; shift 2 ;;
--service-name) SERVICE_NAME="$2"; shift 2 ;;
--docker) INSTALL_METHOD="docker"; shift ;;
--method) INSTALL_METHOD="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
if [[ "$HAS_ARGS" == "false" ]]; then
echo "=================================================="
echo "欢迎使用 OpenFlare Agent 卸载脚本"
echo "Welcome to the OpenFlare Agent Uninstaller"
echo "=================================================="
echo "请选择卸载方式 / Please choose uninstall method:"
echo " 1) Local (本地卸载: 停止服务并删除二进制及配置)"
echo " 2) Docker (容器卸载: 停止并删除 Docker 容器)"
read -p "请输入序号 [1-2] (默认 1): " method_choice
method_choice=${method_choice:-1}
case "$method_choice" in
2) INSTALL_METHOD="docker" ;;
*) INSTALL_METHOD="local" ;;
esac
else
if [[ -z "$INSTALL_METHOD" ]]; then
INSTALL_METHOD="local"
fi
fi
if [[ "$INSTALL_METHOD" == "docker" ]]; then
echo "正在卸载 OpenFlare Agent (Docker)..."
# Check if container exists
if command -v docker >/dev/null 2>&1; then
if docker ps -a --format '{{.Names}}' | grep -Eq "^openflare-agent$"; then
echo "停止并移除 openflare-agent 容器..."
docker stop openflare-agent || true
docker rm -f openflare-agent || true
echo "已成功移除 openflare-agent 容器。"
else
echo "未检测到 openflare-agent 容器。"
fi
# In interactive mode, ask if user wants to remove docker image
if [[ "$HAS_ARGS" == "false" ]]; then
read -p "是否删除 OpenFlare Agent 镜像 (ghcr.io/rain-kl/openflare-agent:latest)? (y/n) [n]: " remove_image_choice
remove_image_choice=${remove_image_choice:-n}
case "$remove_image_choice" in
[yY])
echo "正在删除 Docker 镜像..."
docker rmi ghcr.io/rain-kl/openflare-agent:latest || true
;;
*)
echo "保留 Docker 镜像。"
;;
esac
fi
else
echo "Error: 未检测到 Docker 运行环境,无法进行 Docker 方式的卸载。"
exit 1
fi
echo "OpenFlare Agent (Docker) 卸载完成。"
exit 0
fi
if [[ -z "$INSTALL_DIR" || "$INSTALL_DIR" == "/" || "$INSTALL_DIR" == "." ]]; then
echo "Refusing to remove unsafe install directory: '${INSTALL_DIR}'"
exit 1