319 lines
9.8 KiB
Bash
Executable File
319 lines
9.8 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ============================================
|
||
# LinkMaster 节点端一键卸载脚本
|
||
# 使用方法: curl -fsSL https://gitee.nas.cpolar.cn/yoyo/linkmaster-node/raw/branch/main/uninstall.sh | bash
|
||
# 或: ./uninstall.sh
|
||
# ============================================
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# 配置
|
||
BINARY_NAME="linkmaster-node"
|
||
INSTALL_DIR="/usr/local/bin"
|
||
SERVICE_NAME="linkmaster-node"
|
||
SOURCE_DIR="/opt/linkmaster-node"
|
||
CONFIG_FILE="${SOURCE_DIR}/config.yaml"
|
||
LOG_FILE="${SOURCE_DIR}/node.log"
|
||
PID_FILE="${SOURCE_DIR}/node.pid"
|
||
|
||
# 检查是否已安装
|
||
check_installed() {
|
||
local installed=false
|
||
|
||
# 检查服务文件是否存在
|
||
if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then
|
||
installed=true
|
||
fi
|
||
|
||
# 检查二进制文件是否存在
|
||
if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then
|
||
installed=true
|
||
fi
|
||
|
||
# 检查源码目录是否存在
|
||
if [ -d "$SOURCE_DIR" ]; then
|
||
installed=true
|
||
fi
|
||
|
||
if [ "$installed" = false ]; then
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
# 停止服务
|
||
stop_service() {
|
||
echo -e "${BLUE}停止服务...${NC}"
|
||
|
||
# 停止 systemd 服务
|
||
if systemctl is-active --quiet ${SERVICE_NAME} 2>/dev/null; then
|
||
echo -e "${BLUE} 正在停止 systemd 服务...${NC}"
|
||
sudo systemctl stop ${SERVICE_NAME} 2>/dev/null || true
|
||
sleep 2
|
||
fi
|
||
|
||
# 清理残留进程
|
||
if pgrep -f "$BINARY_NAME" > /dev/null 2>&1; then
|
||
echo -e "${BLUE} 清理残留进程...${NC}"
|
||
sudo pkill -f "$BINARY_NAME" 2>/dev/null || true
|
||
sleep 1
|
||
|
||
# 再次检查,如果还有进程则强制杀死
|
||
if pgrep -f "$BINARY_NAME" > /dev/null 2>&1; then
|
||
echo -e "${YELLOW} 强制清理残留进程...${NC}"
|
||
sudo pkill -9 -f "$BINARY_NAME" 2>/dev/null || true
|
||
sleep 1
|
||
fi
|
||
fi
|
||
|
||
# 如果使用 run.sh 启动的进程(通过 PID 文件)
|
||
if [ -f "$PID_FILE" ]; then
|
||
local pid=$(cat "$PID_FILE" 2>/dev/null || echo "")
|
||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||
echo -e "${BLUE} 停止通过 run.sh 启动的进程 (PID: $pid)...${NC}"
|
||
kill "$pid" 2>/dev/null || true
|
||
sleep 1
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
kill -9 "$pid" 2>/dev/null || true
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
echo -e "${GREEN}✓ 服务已停止${NC}"
|
||
}
|
||
|
||
# 禁用服务
|
||
disable_service() {
|
||
echo -e "${BLUE}禁用服务...${NC}"
|
||
|
||
if systemctl is-enabled --quiet ${SERVICE_NAME} 2>/dev/null; then
|
||
sudo systemctl disable ${SERVICE_NAME} 2>/dev/null || true
|
||
echo -e "${GREEN}✓ 服务已禁用${NC}"
|
||
else
|
||
echo -e "${BLUE} 服务未启用,跳过${NC}"
|
||
fi
|
||
}
|
||
|
||
# 删除服务文件
|
||
remove_service_files() {
|
||
echo -e "${BLUE}删除服务文件...${NC}"
|
||
|
||
local removed=false
|
||
|
||
# 删除 systemd 服务文件
|
||
if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then
|
||
sudo rm -f /etc/systemd/system/${SERVICE_NAME}.service
|
||
echo -e "${GREEN}✓ 已删除服务文件: /etc/systemd/system/${SERVICE_NAME}.service${NC}"
|
||
removed=true
|
||
fi
|
||
|
||
# 删除可能的 override 配置目录
|
||
if [ -d "/etc/systemd/system/${SERVICE_NAME}.service.d" ]; then
|
||
sudo rm -rf /etc/systemd/system/${SERVICE_NAME}.service.d
|
||
echo -e "${GREEN}✓ 已删除服务配置目录: /etc/systemd/system/${SERVICE_NAME}.service.d${NC}"
|
||
removed=true
|
||
fi
|
||
|
||
if [ "$removed" = true ]; then
|
||
# 重新加载 systemd daemon
|
||
sudo systemctl daemon-reload
|
||
echo -e "${GREEN}✓ systemd daemon 已重新加载${NC}"
|
||
else
|
||
echo -e "${BLUE} 未找到服务文件,跳过${NC}"
|
||
fi
|
||
}
|
||
|
||
# 删除二进制文件
|
||
remove_binary() {
|
||
echo -e "${BLUE}删除二进制文件...${NC}"
|
||
|
||
if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then
|
||
sudo rm -f "$INSTALL_DIR/$BINARY_NAME"
|
||
echo -e "${GREEN}✓ 已删除二进制文件: $INSTALL_DIR/$BINARY_NAME${NC}"
|
||
else
|
||
echo -e "${BLUE} 未找到二进制文件,跳过${NC}"
|
||
fi
|
||
}
|
||
|
||
# 删除源码目录和配置文件
|
||
remove_source_directory() {
|
||
echo -e "${BLUE}删除源码目录和配置文件...${NC}"
|
||
|
||
if [ -d "$SOURCE_DIR" ]; then
|
||
# 显示将要删除的内容
|
||
echo -e "${BLUE} 源码目录: $SOURCE_DIR${NC}"
|
||
|
||
# 删除整个源码目录
|
||
sudo rm -rf "$SOURCE_DIR"
|
||
echo -e "${GREEN}✓ 已删除源码目录: $SOURCE_DIR${NC}"
|
||
else
|
||
echo -e "${BLUE} 未找到源码目录,跳过${NC}"
|
||
fi
|
||
|
||
# 额外检查配置文件(如果单独存在)
|
||
if [ -f "$CONFIG_FILE" ]; then
|
||
sudo rm -f "$CONFIG_FILE"
|
||
echo -e "${GREEN}✓ 已删除配置文件: $CONFIG_FILE${NC}"
|
||
fi
|
||
}
|
||
|
||
# 清理防火墙规则(可选,默认不删除)
|
||
remove_firewall_rules() {
|
||
local remove_firewall="${1:-false}"
|
||
|
||
if [ "$remove_firewall" != "true" ]; then
|
||
echo -e "${BLUE}跳过防火墙规则清理(默认保留)${NC}"
|
||
echo -e "${YELLOW} 如需删除防火墙规则,请使用: ./uninstall.sh --remove-firewall${NC}"
|
||
return
|
||
fi
|
||
|
||
echo -e "${BLUE}清理防火墙规则(开放2200端口)...${NC}"
|
||
|
||
PORT=2200
|
||
FIREWALL_REMOVED=false
|
||
|
||
# 检测 firewalld (CentOS/RHEL 7+, Fedora)
|
||
if command -v firewall-cmd > /dev/null 2>&1; then
|
||
if sudo systemctl is-active --quiet firewalld 2>/dev/null; then
|
||
echo -e "${BLUE} 从 firewalld 删除端口规则...${NC}"
|
||
if sudo firewall-cmd --permanent --remove-port=${PORT}/tcp > /dev/null 2>&1; then
|
||
sudo firewall-cmd --reload > /dev/null 2>&1
|
||
echo -e "${GREEN}✓ firewalld 规则已删除${NC}"
|
||
FIREWALL_REMOVED=true
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# 检测 ufw (Ubuntu/Debian)
|
||
if command -v ufw > /dev/null 2>&1; then
|
||
if sudo ufw status > /dev/null 2>&1; then
|
||
echo -e "${BLUE} 从 ufw 删除端口规则...${NC}"
|
||
if sudo ufw delete allow ${PORT}/tcp > /dev/null 2>&1; then
|
||
echo -e "${GREEN}✓ ufw 规则已删除${NC}"
|
||
FIREWALL_REMOVED=true
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# 检测 iptables(较老的系统)
|
||
if command -v iptables > /dev/null 2>&1 && [ "$FIREWALL_REMOVED" = false ]; then
|
||
if sudo iptables -C INPUT -p tcp --dport ${PORT} -j ACCEPT > /dev/null 2>&1; then
|
||
echo -e "${BLUE} 从 iptables 删除端口规则...${NC}"
|
||
if sudo iptables -D INPUT -p tcp --dport ${PORT} -j ACCEPT > /dev/null 2>&1; then
|
||
echo -e "${GREEN}✓ iptables 规则已删除${NC}"
|
||
# 尝试保存规则
|
||
if command -v iptables-save > /dev/null 2>&1; then
|
||
if [ -f /etc/redhat-release ]; then
|
||
sudo iptables-save > /etc/sysconfig/iptables 2>/dev/null || true
|
||
elif [ -f /etc/debian_version ]; then
|
||
sudo iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
|
||
fi
|
||
fi
|
||
FIREWALL_REMOVED=true
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ "$FIREWALL_REMOVED" = false ]; then
|
||
echo -e "${YELLOW}⚠ 未找到防火墙规则或防火墙未启用${NC}"
|
||
fi
|
||
}
|
||
|
||
# 显示卸载摘要
|
||
show_summary() {
|
||
echo ""
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo -e "${GREEN} 卸载完成!${NC}"
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo ""
|
||
echo -e "${BLUE}已删除的内容:${NC}"
|
||
echo " - systemd 服务文件"
|
||
echo " - 二进制文件: $INSTALL_DIR/$BINARY_NAME"
|
||
echo " - 源码目录: $SOURCE_DIR"
|
||
echo ""
|
||
echo -e "${YELLOW}注意:${NC}"
|
||
echo " - 防火墙规则已保留(如需删除请使用 --remove-firewall 参数)"
|
||
echo " - 如果手动修改过系统配置,请手动清理"
|
||
echo ""
|
||
}
|
||
|
||
# 主卸载流程
|
||
main() {
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo -e "${GREEN} LinkMaster 节点端卸载程序${NC}"
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo ""
|
||
|
||
# 检查是否已安装
|
||
if ! check_installed; then
|
||
echo -e "${YELLOW}未检测到已安装的 LinkMaster 节点端${NC}"
|
||
echo -e "${YELLOW}无需卸载${NC}"
|
||
exit 0
|
||
fi
|
||
|
||
# 检查是否需要删除防火墙规则
|
||
REMOVE_FIREWALL=false
|
||
if [ "$1" = "--remove-firewall" ]; then
|
||
REMOVE_FIREWALL=true
|
||
fi
|
||
|
||
# 确认卸载
|
||
echo -e "${YELLOW}即将卸载 LinkMaster 节点端,此操作将:${NC}"
|
||
echo " - 停止并禁用服务"
|
||
echo " - 删除 systemd 服务文件"
|
||
echo " - 删除二进制文件"
|
||
echo " - 删除源码目录和配置文件"
|
||
echo ""
|
||
|
||
# 如果在非交互式环境中,自动确认
|
||
if [ -t 0 ]; then
|
||
read -p "是否继续?(y/N): " -n 1 -r
|
||
echo ""
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
echo -e "${YELLOW}已取消卸载${NC}"
|
||
exit 0
|
||
fi
|
||
else
|
||
echo -e "${BLUE}非交互式环境,自动确认卸载${NC}"
|
||
fi
|
||
|
||
echo ""
|
||
|
||
# 执行卸载步骤
|
||
stop_service
|
||
disable_service
|
||
remove_service_files
|
||
remove_binary
|
||
remove_source_directory
|
||
remove_firewall_rules "$REMOVE_FIREWALL"
|
||
|
||
# 最终检查
|
||
echo ""
|
||
echo -e "${BLUE}最终检查...${NC}"
|
||
|
||
local still_installed=false
|
||
if check_installed; then
|
||
still_installed=true
|
||
fi
|
||
|
||
if [ "$still_installed" = false ]; then
|
||
show_summary
|
||
exit 0
|
||
else
|
||
echo -e "${YELLOW}⚠ 部分文件可能未完全删除,请手动检查${NC}"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 执行卸载
|
||
main "$@"
|
||
|