98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
package system
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"strings"
|
||
)
|
||
|
||
// SetHostname 设置系统主机名
|
||
// 参数: hostname - 目标主机名
|
||
// 返回: error - 如果设置失败返回错误信息
|
||
func SetHostname(hostname string) error {
|
||
if hostname == "" {
|
||
return nil // 空值跳过,不报错
|
||
}
|
||
|
||
// 检查是否已有相同主机名
|
||
current, err := os.Hostname()
|
||
if err == nil && current == hostname {
|
||
return nil // 已经设置正确,无需修改
|
||
}
|
||
|
||
// 使用 hostnamectl 设置主机名(适用于 systemd 系统)
|
||
if _, err := exec.LookPath("hostnamectl"); err == nil {
|
||
cmd := exec.Command("hostnamectl", "set-hostname", hostname)
|
||
cmd.Stdout = os.Stdout
|
||
cmd.Stderr = os.Stderr
|
||
if err := cmd.Run(); err != nil {
|
||
return fmt.Errorf("hostnamectl 设置主机名失败: %v", err)
|
||
}
|
||
} else {
|
||
// 传统方法:直接修改 /etc/hostname
|
||
if err := os.WriteFile("/etc/hostname", []byte(hostname+"\n"), 0644); err != nil {
|
||
return fmt.Errorf("写入 /etc/hostname 失败: %v", err)
|
||
}
|
||
|
||
// 立即生效(需要内核支持)
|
||
cmd := exec.Command("sysctl", "kernel.hostname="+hostname)
|
||
cmd.Stdout = os.Stdout
|
||
cmd.Stderr = os.Stderr
|
||
if err := cmd.Run(); err != nil {
|
||
// 不返回错误,因为重启后会生效
|
||
fmt.Printf("警告: 主机名将在重启后完全生效\n")
|
||
}
|
||
}
|
||
|
||
// 更新 /etc/hosts,确保本机解析正确
|
||
if err := updateHostsFile(hostname); err != nil {
|
||
fmt.Printf("警告: 更新 /etc/hosts 失败: %v\n", err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// updateHostsFile 更新 /etc/hosts 文件中的本机映射
|
||
func updateHostsFile(hostname string) error {
|
||
content, err := os.ReadFile("/etc/hosts")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
lines := strings.Split(string(content), "\n")
|
||
newLines := make([]string, 0, len(lines))
|
||
hostnameSet := false
|
||
|
||
for _, line := range lines {
|
||
// 跳过空行和注释
|
||
if line == "" || strings.HasPrefix(line, "#") {
|
||
newLines = append(newLines, line)
|
||
continue
|
||
}
|
||
|
||
fields := strings.Fields(line)
|
||
if len(fields) >= 2 && fields[0] == "127.0.1.1" {
|
||
// 替换 Ubuntu/Debian 风格的本地主机名
|
||
newLines = append(newLines, "127.0.1.1\t"+hostname)
|
||
hostnameSet = true
|
||
} else if len(fields) >= 2 && fields[0] == "127.0.0.1" {
|
||
// 保留原行,但检查是否包含主机名
|
||
if !strings.Contains(line, hostname) {
|
||
line = line + " " + hostname
|
||
}
|
||
newLines = append(newLines, line)
|
||
hostnameSet = true
|
||
} else {
|
||
newLines = append(newLines, line)
|
||
}
|
||
}
|
||
|
||
// 如果没有找到合适的位置,添加一行
|
||
if !hostnameSet {
|
||
newLines = append(newLines, "127.0.1.1\t"+hostname)
|
||
}
|
||
|
||
return os.WriteFile("/etc/hosts", []byte(strings.Join(newLines, "\n")), 0644)
|
||
}
|