package op import ( "agent-wdd/config" "agent-wdd/log" "agent-wdd/utils" "encoding/json" "fmt" "io" "net/http" "strings" "time" ) type PackageOperator struct { installPrefix []string // 安装前缀 removePrefix []string // 移除前缀 upgradePrefix []string // 升级前缀 initCommand []string } var ( AgentPackOperator = &PackageOperator{} aptPackageOperator = &PackageOperator{ installPrefix: []string{ "apt-get", "install", "--allow-downgrades", "-y", }, removePrefix: []string{ "apt", "remove", "-y", }, upgradePrefix: []string{}, initCommand: []string{ "apt-get", "update", }, } yumPackageOperator = &PackageOperator{ installPrefix: []string{ "yum", "install", "-y", }, removePrefix: []string{ "yum", "remove", "-y", }, upgradePrefix: []string{}, initCommand: []string{ "yum", "makecache", }, } ) func (op *PackageOperator) Install(tools []string) bool { // 判定本机的包管理Operator ok := generatePackageOperator() if !ok { log.Error("PackageOperator init failed! 无法执行安装操作 %s", tools) return false } // install seperately for _, tool := range tools { ok, result := SingleLineCommandExecutor(append(AgentPackOperator.installPrefix, tool)) if !ok { log.Error("[install] failed! => %s", tool) utils.BeautifulPrint(result) } } return true } // PackageInit 初始化包管理器, 同样会判定主机是否可以联网,如果本机是ubuntu或者debian, 则使用apt, 否则使用yum func (op *PackageOperator) PackageInit() bool { log.Info("PackageInit !") // 判定本机的包管理Operator ok := generatePackageOperator() if !ok { return false } // package init os := config.ConfigCache.Agent.OS osFamily := strings.ToLower(os.OsFamily) if strings.Contains(osFamily, "ubuntu") || strings.Contains(osFamily, "debian") { ok, resultLog := SingleLineCommandExecutor(aptPackageOperator.initCommand) if !ok { log.Error("APT init failed! please check !") utils.BeautifulPrint(resultLog) } } return true } func (op *PackageOperator) Remove(tools []string) { // 判定本机的包管理Operator generatePackageOperator() // install seperately for _, tool := range tools { ok, result := SingleLineCommandExecutor(append(AgentPackOperator.removePrefix, tool)) if !ok { log.Error("[remove] failed! => %s", tool) utils.BeautifulPrint(result) } } } func generatePackageOperator() bool { // cache return if AgentPackOperator.initCommand != nil { return true } // 检查是否可以连接互联网 if config.CanConnectInternet() <= 1 { log.Error("服务器无法连接互联网,无法初始化包管理器") return false } // 检查本机是否存在OS的信息 os := config.ConfigCache.Agent.OS if os.Hostname == "" { os.Gather() os.SaveConfig() } if os.IsUbuntuType { AgentPackOperator = aptPackageOperator } else { AgentPackOperator = yumPackageOperator } return true } // GetLatestGithubReleaseVersion 获取GitHub仓库的最新版本 func GetLatestGithubReleaseVersion(repoOwner, repoName string) (string, error) { // 检查是否可以连接互联网 if config.CanConnectInternet() <= 1 { return "", fmt.Errorf("服务器无法连接互联网,无法获取GitHub最新版本") } // 设置超时时间为10秒的HTTP客户端 client := &http.Client{ Timeout: 10 * time.Second, } // 构建GitHub API URL apiURL := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", repoOwner, repoName) // 发送GET请求 resp, err := client.Get(apiURL) if err != nil { return "", fmt.Errorf("请求GitHub API失败: %v", err) } defer resp.Body.Close() // 检查响应状态码 if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("GitHub API返回非200状态码: %d", resp.StatusCode) } // 读取响应体 body, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("读取响应内容失败: %v", err) } // 解析JSON响应 var release struct { TagName string `json:"tag_name"` } if err := json.Unmarshal(body, &release); err != nil { return "", fmt.Errorf("解析JSON响应失败: %v", err) } return release.TagName, nil } // CommandExists 判定命令是否存在 func CommandExists(command string) bool { ok, _ := SingleLineCommandExecutor([]string{"command", "-v", command}) return ok } func CommandExistsByPath(command string) bool { // 查询 /usr/bin /usr/local/bin中是否有可执行文件 ok, _ := SingleLineCommandExecutor([]string{"find", "/usr/bin", "/usr/local/bin", "-name", command}) return ok }