diff --git a/README.md b/README.md index 743db103..64fa95e8 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,17 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/inst 安装脚本默认写入 `/opt/openflare-agent`,创建 `openflare-agent.service`,并可重复执行以重装或升级 Agent。 +如需彻底卸载 Agent 并清空本地数据,可执行: + +```bash +curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash +``` + +卸载脚本会先停止并移除 `openflare-agent.service`、删除整个 `/opt/openflare-agent` 目录,然后根据卸载前保存的 `agent.json` 判断 OpenResty 安装方式: + +* Docker 模式:删除对应 OpenResty 容器,并尝试移除镜像 +* 本机 `openresty_path` 模式:不改动本机 OpenResty + ### 3. 发布第一份配置 1. 登录管理端并新增反代规则 diff --git a/docs/deployment.md b/docs/deployment.md index 8e0cb633..fbcb1256 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -237,6 +237,22 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/inst 安装脚本会下载最新 Agent、生成 `agent.json`、创建 `openflare-agent.service` 并启动服务。 +如需彻底卸载 Agent 并清空本地数据,可执行: + +```bash +curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash +``` + +支持参数: + +* `--install-dir` +* `--service-name` + +卸载脚本会先停止 Agent、移除 `openflare-agent.service`、删除整个安装目录,再根据卸载前保存的 `agent.json` 判断 OpenResty 安装方式: + +* Docker 模式:删除对应容器,并尝试移除 OpenResty 镜像 +* 本机 `openresty_path` 模式:不改动本机 OpenResty,仅提示用户手动卸载 + ## 9. 文档维护要求 部署方式、升级方式、接入模式或联调流程变化时,同步更新本文档和 `README.md`。 diff --git a/openflare_server/web/features/proxy-routes/helpers.ts b/openflare_server/web/features/proxy-routes/helpers.ts index dfbbf96d..fb07daec 100644 --- a/openflare_server/web/features/proxy-routes/helpers.ts +++ b/openflare_server/web/features/proxy-routes/helpers.ts @@ -304,8 +304,5 @@ export function getWebsiteStatusBadges(route: ProxyRouteItem) { route.enable_https ? { label: 'HTTPS', variant: 'info' as const } : { label: 'HTTP', variant: 'warning' as const }, - route.cache_enabled - ? { label: '缓存开启', variant: 'success' as const } - : { label: '缓存关闭', variant: 'warning' as const }, ]; } diff --git a/scripts/uninstall-agent.sh b/scripts/uninstall-agent.sh new file mode 100644 index 00000000..0da898d8 --- /dev/null +++ b/scripts/uninstall-agent.sh @@ -0,0 +1,192 @@ +#!/usr/bin/env bash +set -euo pipefail + +INSTALL_DIR="/opt/openflare-agent" +SERVICE_NAME="openflare-agent" + +usage() { + cat </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."