DockerST/utils/DockerRep.go
2024-06-19 15:22:40 +08:00

198 lines
4.8 KiB
Go

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
}