优化探针卸载&服务端删除探针自动卸载自身

This commit is contained in:
dushixiang committed 2025-12-25 19:24:59 +08:00
1 parent 7944fb09dc
commit 502de9d816
6 files changed
+98 -20

No files matched your search

+2 -16
View File
@@ -237,23 +237,9 @@ func installService(cmd *cobra.Command, args []string) {
// uninstallService 卸载服务
func uninstallService(cmd *cobra.Command, args []string) {
// 加载配置
cfg, err := config.Load(configPath)
if err != nil {
log.Fatalf("❌ 加载配置失败: %v", err)
if err := service.UninstallAgent(configPath); err != nil {
log.Fatalf("❌ 卸载失败: %v", err)
}
// 创建服务管理器
mgr, err := service.NewServiceManager(cfg)
if err != nil {
log.Fatalf("❌ 创建服务管理器失败: %v", err)
}
// 卸载服务
if err := mgr.Uninstall(); err != nil {
log.Fatalf("❌ 卸载服务失败: %v", err)
}
log.Println("✅ 服务卸载成功")
}
+22 -1
View File
@@ -713,8 +713,29 @@ func (h *AgentHandler) Delete(c echo.Context) error {
return err
}
// 如果探针在线,先断开连接
// 如果探针在线,先发送卸载指令,然后断开连接
if client, exists := h.wsManager.GetClient(agentID); exists {
// 构建卸载消息
uninstallMsg, err := json.Marshal(protocol.OutboundMessage{
Type: protocol.MessageTypeUninstall,
Data: struct{}{}, // 空数据,卸载指令不需要额外参数
})
if err == nil {
// 发送卸载指令(忽略发送错误,继续删除流程)
if err := h.wsManager.SendToClient(agentID, uninstallMsg); err != nil {
h.logger.Warn("发送卸载指令失败",
zap.String("agentID", agentID),
zap.Error(err))
} else {
h.logger.Info("已向探针发送卸载指令",
zap.String("agentID", agentID),
zap.String("name", agent.Name))
// 等待一小段时间让探针处理卸载消息
time.Sleep(500 * time.Millisecond)
}
}
// 断开连接
client.Conn.Close()
}
+1
View File
@@ -52,6 +52,7 @@ const (
MessageTypeHeartbeat MessageType = "heartbeat"
MessageTypeCommand MessageType = "command"
MessageTypeCommandResp MessageType = "command_response"
MessageTypeUninstall MessageType = "uninstall"
// 指标消息
MessageTypeMetrics MessageType = "metrics"
MessageTypeMonitorConfig MessageType = "monitor_config"
+3 -3
View File
@@ -18,12 +18,12 @@ type Manager struct {
// NewManager 创建 ID 管理器
func NewManager() *Manager {
return &Manager{
idFilePath: getIDFilePath(),
idFilePath: GetIDFilePath(),
}
}
// getIDFilePath 获取 ID 文件路径
func getIDFilePath() string {
// GetIDFilePath 获取 ID 文件路径
func GetIDFilePath() string {
// 获取用户主目录
var homeDir = utils.GetSafeHomeDir()
// 统一使用 ~/.pika/agent.id
+26
View File
@@ -296,6 +296,8 @@ func (a *Agent) readLoop(conn *websocket.Conn, done chan struct{}) error {
go a.handleTamperProtect(msg.Data)
case protocol.MessageTypeDDNSConfig:
go a.handleDDNSConfig(msg.Data)
case protocol.MessageTypeUninstall:
go a.handleUninstall()
default:
// 忽略其他类型
}
@@ -829,3 +831,27 @@ func (a *Agent) getIPAddress(manager *collector.Manager, method, value string, i
return "", fmt.Errorf("不支持的 IP 获取方式: %s", method)
}
}
// handleUninstall 处理服务端发送的卸载指令
func (a *Agent) handleUninstall() {
log.Println("📥 收到服务端卸载指令,开始执行卸载...")
// 获取配置文件路径
cfgPath := a.cfg.Path
if cfgPath == "" {
cfgPath = config.GetDefaultConfigPath()
}
// 执行卸载操作
if err := UninstallAgent(cfgPath); err != nil {
log.Printf("❌ 卸载失败: %v", err)
return
}
log.Println("✅ 探针卸载成功,即将退出...")
// 卸载成功后,触发停止信号
if a.cancel != nil {
a.cancel()
}
}
+44
View File
@@ -9,6 +9,7 @@ import (
"syscall"
"github.com/dushixiang/pika/pkg/agent/config"
"github.com/dushixiang/pika/pkg/agent/id"
"github.com/dushixiang/pika/pkg/agent/sysutil"
"github.com/dushixiang/pika/pkg/agent/updater"
"github.com/kardianos/service"
@@ -235,3 +236,46 @@ func (m *ServiceManager) Run() error {
return nil
}
// UninstallAgent 执行探针卸载操作(可被复用)
func UninstallAgent(cfgPath string) error {
// 加载配置
cfg, err := config.Load(cfgPath)
if err != nil {
return fmt.Errorf("加载配置失败: %w", err)
}
// 创建服务管理器
mgr, err := NewServiceManager(cfg)
if err != nil {
return fmt.Errorf("创建服务管理器失败: %w", err)
}
// 检查服务状态,如果在运行则停止
status, err := mgr.Status()
if err != nil {
log.Printf("⚠️ 获取服务状态失败: %v", err)
} else if status != "已停止 (Stopped)" {
if err := mgr.Stop(); err != nil {
return fmt.Errorf("停止服务失败: %w", err)
}
}
// 卸载服务
if err := mgr.Uninstall(); err != nil {
return fmt.Errorf("卸载服务失败: %w", err)
}
// 删除配置文件
if err := os.Remove(cfgPath); err != nil {
log.Printf("⚠️ 删除配置文件失败: %v", err)
}
// 删除探针 ID 文件
idPath := id.GetIDFilePath()
if err := os.Remove(idPath); err != nil {
log.Printf("⚠️ 删除探针 ID 文件失败: %v", err)
}
return nil
}