From 7b00c8728263d16c25ccf7b8c4fd491cd379b2ce Mon Sep 17 00:00:00 2001 From: GuanM <1-GuanM@users.noreply.gitlab.54sxh.cn> Date: Wed, 19 Jun 2024 15:22:40 +0800 Subject: [PATCH] =?UTF-8?q?1.0.0=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 --- main.go | 14 ++-- utils/DockerRep.go | 197 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 utils/DockerRep.go diff --git a/README.md b/README.md index 0bd99d3..1fa4446 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,3 @@ Docker官方使用的是CloudFlare的CDN 优选CloudFlare IP后即可实现高 ## 安装本程序 -```bash - -``` - -## 使用代理优选加速(推荐) - -```bash -https://docker.sxh.workers.dev/ -``` - -## 直接加速 - diff --git a/main.go b/main.go index 3f61db8..6891b4b 100644 --- a/main.go +++ b/main.go @@ -38,12 +38,14 @@ func init() { flag.StringVar(&task.IPFile, "f", "ip.txt", "IP段数据文件") flag.StringVar(&task.IPText, "ip", "", "指定IP段数据") flag.StringVar(&utils.Output, "o", "result.csv", "输出结果文件") - flag.BoolVar(&task.IsOff, "om", false, "关闭在线读取列表") + + flag.BoolVar(&task.IsOff, "off", false, "关闭在线读取列表") flag.BoolVar(&task.Disable, "dd", false, "禁用下载测速") flag.BoolVar(&task.TestAll, "allip", false, "测速全部 IP") flag.BoolVar(&printVersion, "v", false, "打印程序版本") - flag.Parse() + flag.StringVar(&utils.DefaultDockerUrl, "docker-url", utils.DefaultDockerUrl, "Docker 地址") + flag.BoolVar(&task.IsOff, "om", false, "关闭在线读取列表") if task.MinSpeed > 0 && time.Duration(maxDelay)*time.Millisecond == utils.InputMaxDelay { fmt.Println("[小提示] 在使用 [-sl] 参数时,建议搭配 [-tl] 参数,以避免因凑不够 [-dn] 数量而一直测速...") @@ -69,15 +71,13 @@ func init() { func main() { task.InitRandSeed() // 置随机数种子 - - fmt.Printf("# XIU2/CloudflareSpeedTest %s \n\n", version) - + fmt.Printf("# sxhoio/DockerST %s \n\n", version) // 开始延迟测速 + 过滤延迟/丢包 pingData := task.NewPing().Run().FilterDelay().FilterLossRate() // 开始下载测速 speedData := task.TestDownloadSpeed(pingData) - utils.ExportCsv(speedData) // 输出文件 - speedData.Print() // 打印结果 + + speedData.DockerSet() // 替换节点 if versionNew != "" { fmt.Printf("\n*** 发现新版本 [%s]!请前往 [https://github.com/sxhoio/DockerST] 更新! ***\n", versionNew) diff --git a/utils/DockerRep.go b/utils/DockerRep.go new file mode 100644 index 0000000..e21c90b --- /dev/null +++ b/utils/DockerRep.go @@ -0,0 +1,197 @@ +package utils + +import ( + "bufio" + "encoding/json" + "fmt" + "os" + "runtime" + "strings" +) + +var ( + DefaultDockerUrl = "http://docker.sxh.workers.dev" +) + +func (s DownloadSpeedSet) DockerSet() { + // 选择最优的节点 + bestIP := s[0].IP + bestSpeed := s[0].DownloadSpeed + // 自动优选节点 最高速度为 0 时,不进行优选 + if bestSpeed == 0 { + fmt.Println("\n[信息] 未找到最优节点,跳过优选节点。") + return + } else { + fmt.Println("\n[信息] 最优节点:", bestIP, " 速度:", bestSpeed, "MB/s") + } + // 输出结果 + fmt.Println("\n[信息] 开始写入 hosts 文件...") + err := WriteHosts(bestIP.String()) + if err != nil { + fmt.Println("\n[错误] 写入 hosts 文件失败:", err) + return + } + + err = SetDockerAccelerator(DefaultDockerUrl) + if err != nil { + fmt.Println("\n[错误] 设置 Docker 加速器失败:", err) + } +} + +func WriteHosts(bestIP string) error { + // 获取当前系统 + system := runtime.GOOS + switch system { + case "windows": + return writeHostsWindows(bestIP) + case "darwin": + return writeHostsMac(bestIP) + case "linux": + return writeHostsLinux(bestIP) + default: + return fmt.Errorf("不支持的操作系统:%s", system) + } +} + +func writeHostsWindows(bestIP string) error { + hostsFilePath := "C:\\Windows\\System32\\drivers\\etc\\hosts" + return writeHostsFile(hostsFilePath, bestIP) +} + +func writeHostsMac(bestIP string) error { + hostsFilePath := "/etc/hosts" + return writeHostsFile(hostsFilePath, bestIP) +} + +func writeHostsLinux(bestIP string) error { + hostsFilePath := "/etc/hosts" + return writeHostsFile(hostsFilePath, bestIP) +} + +func writeHostsFile(hostsFilePath, bestIP string) error { + // 检查文件权限 + file, err := os.OpenFile(hostsFilePath, os.O_RDWR, 0644) + if err != nil { + return fmt.Errorf("无法打开 hosts 文件: %w", err) + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + // 读取文件内容 + var lines []string + scanner := bufio.NewScanner(file) + inBlock := false + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, "# DockerST Start") { + inBlock = true + } + if !inBlock { + lines = append(lines, line) + } + if strings.Contains(line, "# DockerST End") { + inBlock = false + } + } + if err := scanner.Err(); err != nil { + return fmt.Errorf("读取 hosts 文件出错: %w", err) + } + + // 重写文件内容 + file, err = os.Create(hostsFilePath) + if err != nil { + return fmt.Errorf("无法重写 hosts 文件: %w", err) + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + writer := bufio.NewWriter(file) + for _, line := range lines { + _, _ = fmt.Fprintln(writer, line) + } + _, _ = fmt.Fprintln(writer, "# DockerST Start") + domain := strings.Split(strings.Split(DefaultDockerUrl, "//")[1], "/")[0] + _, _ = fmt.Fprintln(writer, bestIP+" "+domain) + _, _ = fmt.Fprintln(writer, "# DockerST End") + + err = writer.Flush() + if err != nil { + return fmt.Errorf("写入 hosts 文件出错: %w", err) + } + + fmt.Println("\n[信息] 成功写入 hosts 文件。") + return nil +} + +func SetDockerAccelerator(dockerUrl string) error { + system := runtime.GOOS + var err error + + switch system { + case "windows": + err = setDockerAcceleratorWindows(dockerUrl) + case "darwin": + err = setDockerAcceleratorMac(dockerUrl) + case "linux": + err = setDockerAcceleratorLinux(dockerUrl) + default: + err = fmt.Errorf("不支持的操作系统:%s", system) + } + + if err != nil { + return fmt.Errorf("设置 Docker 加速器失败: %w", err) + } + fmt.Println("\n[信息] Docker 加速器已设置为:", dockerUrl) + return nil +} + +func setDockerAcceleratorWindows(dockerUrl string) error { + configPath := os.Getenv("USERPROFILE") + "\\.docker\\daemon.json" + return updateDockerConfig(configPath, dockerUrl) +} + +func setDockerAcceleratorMac(dockerUrl string) error { + configPath := os.Getenv("HOME") + "/.docker/daemon.json" + return updateDockerConfig(configPath, dockerUrl) +} + +func setDockerAcceleratorLinux(dockerUrl string) error { + configPath := "/etc/docker/daemon.json" + return updateDockerConfig(configPath, dockerUrl) +} + +func updateDockerConfig(configPath, dockerUrl string) error { + file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return fmt.Errorf("无法打开 Docker 配置文件: %w", err) + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + var config map[string]interface{} + if err := json.NewDecoder(file).Decode(&config); err != nil { + config = make(map[string]interface{}) + } + + config["registry-mirrors"] = []string{dockerUrl} + + file, err = os.Create(configPath) + if err != nil { + return fmt.Errorf("无法重写 Docker 配置文件: %w", err) + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + if err := encoder.Encode(config); err != nil { + return fmt.Errorf("写入 Docker 配置文件出错: %w", err) + } + + fmt.Println("\n[信息] 成功更新 Docker 配置文件。") + return nil +}