mirror of
https://github.com/luckfox-eng29/kvm.git
synced 2026-01-18 03:28:19 +01:00
network enhanecment / refactor (#361)
* chore(network): improve connectivity check * refactor(network): rewrite network and timesync component * feat(display): show cloud connection status * chore: change logging verbosity * chore(websecure): update log message * fix(ota): validate root certificate when downloading update * feat(ui): add network settings tab * fix(display): cloud connecting animation * fix: golintci issues * feat: add network settings tab * feat(timesync): query servers in parallel * refactor(network): move to internal/network package * feat(timesync): add metrics * refactor(log): move log to internal/logging package * refactor(mdms): move mdns to internal/mdns package * feat(developer): add pprof endpoint * feat(logging): add a simple logging streaming endpoint * fix(mdns): do not start mdns until network is up * feat(network): allow users to update network settings from ui * fix(network): handle errors when net.IPAddr is nil * fix(mdns): scopedLogger SIGSEGV * fix(dhcp): watch directory instead of file to catch fsnotify.Create event * refactor(nbd): move platform-specific code to different files * refactor(native): move platform-specific code to different files * chore: fix linter issues * chore(dev_deploy): allow to override PION_LOG_TRACE
This commit is contained in:
137
internal/network/hostname.go
Normal file
137
internal/network/hostname.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
const (
|
||||
hostnamePath = "/etc/hostname"
|
||||
hostsPath = "/etc/hosts"
|
||||
)
|
||||
|
||||
var (
|
||||
hostnameLock sync.Mutex = sync.Mutex{}
|
||||
)
|
||||
|
||||
func updateEtcHosts(hostname string, fqdn string) error {
|
||||
// update /etc/hosts
|
||||
hostsFile, err := os.OpenFile(hostsPath, os.O_RDWR|os.O_SYNC, os.ModeExclusive)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open %s: %w", hostsPath, err)
|
||||
}
|
||||
defer hostsFile.Close()
|
||||
|
||||
// read all lines
|
||||
if _, err := hostsFile.Seek(0, io.SeekStart); err != nil {
|
||||
return fmt.Errorf("failed to seek %s: %w", hostsPath, err)
|
||||
}
|
||||
|
||||
lines, err := io.ReadAll(hostsFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read %s: %w", hostsPath, err)
|
||||
}
|
||||
|
||||
newLines := []string{}
|
||||
hostLine := fmt.Sprintf("127.0.1.1\t%s %s", hostname, fqdn)
|
||||
hostLineExists := false
|
||||
|
||||
for _, line := range strings.Split(string(lines), "\n") {
|
||||
if strings.HasPrefix(line, "127.0.1.1") {
|
||||
hostLineExists = true
|
||||
line = hostLine
|
||||
}
|
||||
newLines = append(newLines, line)
|
||||
}
|
||||
|
||||
if !hostLineExists {
|
||||
newLines = append(newLines, hostLine)
|
||||
}
|
||||
|
||||
if err := hostsFile.Truncate(0); err != nil {
|
||||
return fmt.Errorf("failed to truncate %s: %w", hostsPath, err)
|
||||
}
|
||||
|
||||
if _, err := hostsFile.Seek(0, io.SeekStart); err != nil {
|
||||
return fmt.Errorf("failed to seek %s: %w", hostsPath, err)
|
||||
}
|
||||
|
||||
if _, err := hostsFile.Write([]byte(strings.Join(newLines, "\n"))); err != nil {
|
||||
return fmt.Errorf("failed to write %s: %w", hostsPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ToValidHostname(hostname string) string {
|
||||
ascii, err := idna.Lookup.ToASCII(hostname)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return ascii
|
||||
}
|
||||
|
||||
func SetHostname(hostname string, fqdn string) error {
|
||||
hostnameLock.Lock()
|
||||
defer hostnameLock.Unlock()
|
||||
|
||||
hostname = ToValidHostname(strings.TrimSpace(hostname))
|
||||
fqdn = ToValidHostname(strings.TrimSpace(fqdn))
|
||||
|
||||
if hostname == "" {
|
||||
return fmt.Errorf("invalid hostname: %s", hostname)
|
||||
}
|
||||
|
||||
if fqdn == "" {
|
||||
fqdn = hostname
|
||||
}
|
||||
|
||||
// update /etc/hostname
|
||||
if err := os.WriteFile(hostnamePath, []byte(hostname), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write %s: %w", hostnamePath, err)
|
||||
}
|
||||
|
||||
// update /etc/hosts
|
||||
if err := updateEtcHosts(hostname, fqdn); err != nil {
|
||||
return fmt.Errorf("failed to update /etc/hosts: %w", err)
|
||||
}
|
||||
|
||||
// run hostname
|
||||
if err := exec.Command("hostname", "-F", hostnamePath).Run(); err != nil {
|
||||
return fmt.Errorf("failed to run hostname: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetworkInterfaceState) setHostnameIfNotSame() error {
|
||||
hostname := s.GetHostname()
|
||||
currentHostname, _ := os.Hostname()
|
||||
|
||||
fqdn := fmt.Sprintf("%s.%s", hostname, s.GetDomain())
|
||||
|
||||
if currentHostname == hostname && s.currentFqdn == fqdn && s.currentHostname == hostname {
|
||||
return nil
|
||||
}
|
||||
|
||||
scopedLogger := s.l.With().Str("hostname", hostname).Str("fqdn", fqdn).Logger()
|
||||
|
||||
err := SetHostname(hostname, fqdn)
|
||||
if err != nil {
|
||||
scopedLogger.Error().Err(err).Msg("failed to set hostname")
|
||||
return err
|
||||
}
|
||||
|
||||
s.currentHostname = hostname
|
||||
s.currentFqdn = fqdn
|
||||
|
||||
scopedLogger.Info().Msg("hostname set")
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user