diff --git a/install/23-2-Sub2API.sh b/install/23-2-Sub2API.sh index 5fe2aad..3819cab 100644 --- a/install/23-2-Sub2API.sh +++ b/install/23-2-Sub2API.sh @@ -24,15 +24,57 @@ detect_compose() { return 0 } -# 前置检查:docker 与 compose 必须先就绪,避免改完配置文件才发现环境缺失 -if ! command -v docker >/dev/null 2>&1; then - echo "未检测到 docker,请先安装 Docker 后再运行本脚本。" >&2 - exit 1 -fi -if ! detect_compose; then - echo "未检测到 docker compose 或 docker-compose,请先安装 Docker Compose。" >&2 - exit 1 -fi +# 卸载当前 Sub2API-2 实例。Docker 镜像可能被其他实例共用,因此不删除镜像。 +uninstall_sub2api() { + echo "即将卸载 Sub2API-2:" + echo " - 停止并删除容器及 Compose 网络" + echo " - 删除自动更新定时任务" + echo " - 可选删除 ufw 端口规则 $port80" + echo " - 永久删除 $install_dir(包括数据库、配置和日志)" + read -r -p "此操作不可恢复。如确需卸载,请输入 UNINSTALL 确认:" uninstall_confirm + if [ "$uninstall_confirm" != "UNINSTALL" ]; then + echo "未确认卸载,已退出。原有安装未修改。" + exit 0 + fi + + if ! command -v docker >/dev/null 2>&1; then + echo "未检测到 Docker,无法确认并停止现有容器,已取消卸载。" >&2 + echo "请先恢复 Docker,或确认容器已不存在后手动清理 $install_dir。" >&2 + exit 1 + fi + if ! detect_compose; then + echo "未检测到 docker compose 或 docker-compose,无法安全停止现有容器,已取消卸载。" >&2 + exit 1 + fi + + if [ -f "$install_dir/docker-compose.yml" ]; then + cd "$install_dir" || { echo "无法进入安装目录 $install_dir" >&2; exit 1; } + "${compose_cmd[@]}" down --remove-orphans + fi + + if command -v crontab >/dev/null 2>&1; then + (crontab -l 2>/dev/null | grep -v -F -- "$update_script" || true) | crontab - + echo "已删除自动更新定时任务。" + fi + + if command -v ufw >/dev/null 2>&1; then + read -r -p "是否同时删除 ufw 端口规则 $port80?[y/N]:" remove_ufw_rule + if [ "$remove_ufw_rule" = "y" ] || [ "$remove_ufw_rule" = "Y" ]; then + if ufw --force delete allow "$port80"; then + echo "已删除 ufw 端口规则 $port80。" + else + echo "未找到或无法删除 ufw 端口规则 $port80,请手动检查。" >&2 + fi + else + echo "已保留 ufw 端口规则 $port80。" + fi + fi + + cd / || { echo "无法切换到根目录,取消删除安装目录。" >&2; exit 1; } + rm -rf -- "$install_dir" + echo "Sub2API-2 已卸载,Docker 镜像已保留。" + exit 0 +} # 交互:已有安装时默认只更新,避免覆盖数据库账号、密码和连接配置 existing_install=0 @@ -44,15 +86,22 @@ echo "请选择操作:" if [ "$existing_install" -eq 1 ]; then echo " 1) 已安装,仅更新 Sub2API app 镜像(默认,安全,不覆盖配置/数据库)" echo " 2) 强制重装 Sub2API(重写 docker-compose.yml,保留 .env 与数据目录)" + echo " 3) 卸载 Sub2API-2(删除容器、配置及全部数据)" + read -r -p "请输入选项 [1/2/3](默认 1):" action_choice else echo " 1) 安装 Sub2API(默认)" echo " 2) 不安装,退出" + read -r -p "请输入选项 [1/2](默认 1):" action_choice fi -read -r -p "请输入选项 [1/2](默认 1):" action_choice action_choice="${action_choice:-1}" -# 严格校验输入,防止误输入落入重装流程 -if [ "$action_choice" != "1" ] && [ "$action_choice" != "2" ]; then +# 严格校验输入,防止误输入落入重装或卸载流程 +if [ "$existing_install" -eq 1 ]; then + if [ "$action_choice" != "1" ] && [ "$action_choice" != "2" ] && [ "$action_choice" != "3" ]; then + echo "无效选项:$action_choice,已退出。未做任何修改。" >&2 + exit 1 + fi +elif [ "$action_choice" != "1" ] && [ "$action_choice" != "2" ]; then echo "无效选项:$action_choice,已退出。未做任何修改。" >&2 exit 1 fi @@ -62,6 +111,20 @@ if [ "$existing_install" -eq 0 ] && [ "$action_choice" = "2" ]; then exit 0 fi +if [ "$existing_install" -eq 1 ] && [ "$action_choice" = "3" ]; then + uninstall_sub2api +fi + +# 安装、更新和重装都要求 Docker 与 Compose 正常可用;卸载在函数内单独检查。 +if ! command -v docker >/dev/null 2>&1; then + echo "未检测到 docker,请先安装 Docker 后再运行本脚本。" >&2 + exit 1 +fi +if ! detect_compose; then + echo "未检测到 docker compose 或 docker-compose,请先安装 Docker Compose。" >&2 + exit 1 +fi + if [ "$existing_install" -eq 1 ] && [ "$action_choice" = "1" ]; then echo "已选择:立即执行 Docker 更新。" if [ -x "$update_script" ]; then