mirror of https://github.com/jetkvm/kvm.git
Compare commits
9 Commits
2cf132b62d
...
99faae710f
| Author | SHA1 | Date |
|---|---|---|
|
|
99faae710f | |
|
|
aee1a01cee | |
|
|
ae77887ab2 | |
|
|
aa9d78998f | |
|
|
a3f7b5e937 | |
|
|
ff81768b88 | |
|
|
d02ae062e4 | |
|
|
02382e4632 | |
|
|
775b0f1049 |
80
cmd/main.go
80
cmd/main.go
|
|
@ -16,10 +16,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
envChildID = "JETKVM_CHILD_ID"
|
||||
errorDumpDir = "/userdata/jetkvm/"
|
||||
errorDumpStateFile = ".has_error_dump"
|
||||
errorDumpTemplate = "jetkvm-%s.log"
|
||||
envChildID = "JETKVM_CHILD_ID"
|
||||
errorDumpDir = "/userdata/jetkvm/"
|
||||
errorDumpLastFile = "last-crash.log"
|
||||
errorDumpTemplate = "jetkvm-%s.log"
|
||||
)
|
||||
|
||||
func program() {
|
||||
|
|
@ -117,53 +117,47 @@ func supervise() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func isSymlinkTo(dst, src string) bool {
|
||||
file, err := os.Stat(dst)
|
||||
func isSymlinkTo(oldName, newName string) bool {
|
||||
file, err := os.Stat(newName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if file.Mode()&os.ModeSymlink != os.ModeSymlink {
|
||||
return false
|
||||
}
|
||||
target, err := os.Readlink(dst)
|
||||
target, err := os.Readlink(newName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return target == src
|
||||
return target == oldName
|
||||
}
|
||||
|
||||
func ensureSymlink(dst, src string) error {
|
||||
if isSymlinkTo(dst, src) {
|
||||
func ensureSymlink(oldName, newName string) error {
|
||||
if isSymlinkTo(oldName, newName) {
|
||||
return nil
|
||||
}
|
||||
_ = os.Remove(dst)
|
||||
return os.Symlink(src, dst)
|
||||
_ = os.Remove(newName)
|
||||
return os.Symlink(oldName, newName)
|
||||
}
|
||||
|
||||
func createErrorDump(logFile *os.File) {
|
||||
logFile.Close()
|
||||
func renameFile(f *os.File, newName string) error {
|
||||
_ = f.Close()
|
||||
|
||||
// touch the error dump state file
|
||||
if err := os.WriteFile(filepath.Join(errorDumpDir, errorDumpStateFile), []byte{}, 0644); err != nil {
|
||||
return
|
||||
// try to rename the file first
|
||||
if err := os.Rename(f.Name(), newName); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf(errorDumpTemplate, time.Now().Format("20060102150405"))
|
||||
filePath := filepath.Join(errorDumpDir, fileName)
|
||||
if err := os.Rename(logFile.Name(), filePath); err == nil {
|
||||
fmt.Printf("error dump created: %s\n", filePath)
|
||||
return
|
||||
}
|
||||
|
||||
fnSrc, err := os.Open(logFile.Name())
|
||||
// copy the log file to the error dump directory
|
||||
fnSrc, err := os.Open(f.Name())
|
||||
if err != nil {
|
||||
return
|
||||
return fmt.Errorf("failed to open file: %w", err)
|
||||
}
|
||||
defer fnSrc.Close()
|
||||
|
||||
fnDst, err := os.Create(filePath)
|
||||
fnDst, err := os.Create(newName)
|
||||
if err != nil {
|
||||
return
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
defer fnDst.Close()
|
||||
|
||||
|
|
@ -171,20 +165,42 @@ func createErrorDump(logFile *os.File) {
|
|||
for {
|
||||
n, err := fnSrc.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
return fmt.Errorf("failed to read file: %w", err)
|
||||
}
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if _, err := fnDst.Write(buf[:n]); err != nil {
|
||||
return
|
||||
return fmt.Errorf("failed to write file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("error dump created: %s\n", filePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
_ = ensureSymlink(filePath, filepath.Join(errorDumpDir, "last-crash.log"))
|
||||
func createErrorDump(logFile *os.File) {
|
||||
fmt.Println()
|
||||
|
||||
fileName := fmt.Sprintf(
|
||||
errorDumpTemplate,
|
||||
time.Now().Format("20060102-150405"),
|
||||
)
|
||||
|
||||
filePath := filepath.Join(errorDumpDir, fileName)
|
||||
if err := renameFile(logFile, filePath); err != nil {
|
||||
fmt.Printf("failed to rename file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("error dump copied: %s\n", filePath)
|
||||
|
||||
lastFilePath := filepath.Join(errorDumpDir, errorDumpLastFile)
|
||||
|
||||
if err := ensureSymlink(filePath, lastFilePath); err != nil {
|
||||
fmt.Printf("failed to create symlink: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func doSupervise() {
|
||||
|
|
|
|||
72
config.go
72
config.go
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/jetkvm/kvm/internal/confparser"
|
||||
"github.com/jetkvm/kvm/internal/logging"
|
||||
"github.com/jetkvm/kvm/internal/network/types"
|
||||
"github.com/jetkvm/kvm/internal/usbgadget"
|
||||
|
|
@ -128,41 +129,55 @@ func (c *Config) SetDisplayRotation(rotation string) error {
|
|||
|
||||
const configPath = "/userdata/kvm_config.json"
|
||||
|
||||
var defaultConfig = &Config{
|
||||
CloudURL: "https://api.jetkvm.com",
|
||||
CloudAppURL: "https://app.jetkvm.com",
|
||||
AutoUpdateEnabled: true, // Set a default value
|
||||
ActiveExtension: "",
|
||||
KeyboardMacros: []KeyboardMacro{},
|
||||
DisplayRotation: "270",
|
||||
KeyboardLayout: "en-US",
|
||||
DisplayMaxBrightness: 64,
|
||||
DisplayDimAfterSec: 120, // 2 minutes
|
||||
DisplayOffAfterSec: 1800, // 30 minutes
|
||||
JigglerEnabled: false,
|
||||
// This is the "Standard" jiggler option in the UI
|
||||
JigglerConfig: &JigglerConfig{
|
||||
// it's a temporary solution to avoid sharing the same pointer
|
||||
// we should migrate to a proper config solution in the future
|
||||
var (
|
||||
defaultJigglerConfig = JigglerConfig{
|
||||
InactivityLimitSeconds: 60,
|
||||
JitterPercentage: 25,
|
||||
ScheduleCronTab: "0 * * * * *",
|
||||
Timezone: "UTC",
|
||||
},
|
||||
TLSMode: "",
|
||||
UsbConfig: &usbgadget.Config{
|
||||
}
|
||||
defaultUsbConfig = usbgadget.Config{
|
||||
VendorId: "0x1d6b", //The Linux Foundation
|
||||
ProductId: "0x0104", //Multifunction Composite Gadget
|
||||
SerialNumber: "",
|
||||
Manufacturer: "JetKVM",
|
||||
Product: "USB Emulation Device",
|
||||
},
|
||||
UsbDevices: &usbgadget.Devices{
|
||||
}
|
||||
defaultUsbDevices = usbgadget.Devices{
|
||||
AbsoluteMouse: true,
|
||||
RelativeMouse: true,
|
||||
Keyboard: true,
|
||||
MassStorage: true,
|
||||
},
|
||||
NetworkConfig: &types.NetworkConfig{},
|
||||
DefaultLogLevel: "INFO",
|
||||
}
|
||||
)
|
||||
|
||||
func getDefaultConfig() Config {
|
||||
return Config{
|
||||
CloudURL: "https://api.jetkvm.com",
|
||||
CloudAppURL: "https://app.jetkvm.com",
|
||||
AutoUpdateEnabled: true, // Set a default value
|
||||
ActiveExtension: "",
|
||||
KeyboardMacros: []KeyboardMacro{},
|
||||
DisplayRotation: "270",
|
||||
KeyboardLayout: "en-US",
|
||||
DisplayMaxBrightness: 64,
|
||||
DisplayDimAfterSec: 120, // 2 minutes
|
||||
DisplayOffAfterSec: 1800, // 30 minutes
|
||||
JigglerEnabled: false,
|
||||
// This is the "Standard" jiggler option in the UI
|
||||
JigglerConfig: func() *JigglerConfig { c := defaultJigglerConfig; return &c }(),
|
||||
TLSMode: "",
|
||||
UsbConfig: func() *usbgadget.Config { c := defaultUsbConfig; return &c }(),
|
||||
UsbDevices: func() *usbgadget.Devices { c := defaultUsbDevices; return &c }(),
|
||||
NetworkConfig: func() *types.NetworkConfig {
|
||||
c := &types.NetworkConfig{}
|
||||
_ = confparser.SetDefaultsAndValidate(c)
|
||||
return c
|
||||
}(),
|
||||
DefaultLogLevel: "INFO",
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -195,7 +210,8 @@ func LoadConfig() {
|
|||
}
|
||||
|
||||
// load the default config
|
||||
config = defaultConfig
|
||||
defaultConfig := getDefaultConfig()
|
||||
config = &defaultConfig
|
||||
|
||||
file, err := os.Open(configPath)
|
||||
if err != nil {
|
||||
|
|
@ -207,7 +223,7 @@ func LoadConfig() {
|
|||
defer file.Close()
|
||||
|
||||
// load and merge the default config with the user config
|
||||
loadedConfig := *defaultConfig
|
||||
loadedConfig := defaultConfig
|
||||
if err := json.NewDecoder(file).Decode(&loadedConfig); err != nil {
|
||||
logger.Warn().Err(err).Msg("config file JSON parsing failed")
|
||||
configSuccess.Set(0.0)
|
||||
|
|
@ -216,19 +232,19 @@ func LoadConfig() {
|
|||
|
||||
// merge the user config with the default config
|
||||
if loadedConfig.UsbConfig == nil {
|
||||
loadedConfig.UsbConfig = defaultConfig.UsbConfig
|
||||
loadedConfig.UsbConfig = getDefaultConfig().UsbConfig
|
||||
}
|
||||
|
||||
if loadedConfig.UsbDevices == nil {
|
||||
loadedConfig.UsbDevices = defaultConfig.UsbDevices
|
||||
loadedConfig.UsbDevices = getDefaultConfig().UsbDevices
|
||||
}
|
||||
|
||||
if loadedConfig.NetworkConfig == nil {
|
||||
loadedConfig.NetworkConfig = defaultConfig.NetworkConfig
|
||||
loadedConfig.NetworkConfig = getDefaultConfig().NetworkConfig
|
||||
}
|
||||
|
||||
if loadedConfig.JigglerConfig == nil {
|
||||
loadedConfig.JigglerConfig = defaultConfig.JigglerConfig
|
||||
loadedConfig.JigglerConfig = getDefaultConfig().JigglerConfig
|
||||
}
|
||||
|
||||
// fixup old keyboard layout value
|
||||
|
|
|
|||
|
|
@ -381,28 +381,28 @@ func (f *FieldConfig) validateSingleValue(val string, index int) error {
|
|||
switch validateType {
|
||||
case "int":
|
||||
if _, err := strconv.Atoi(val); err != nil {
|
||||
return fmt.Errorf("field `%s` is not a valid integer: %s", f.Name, val)
|
||||
return fmt.Errorf("field `%s` is not a valid integer: %s", fieldRef, val)
|
||||
}
|
||||
case "ipv6_prefix_length":
|
||||
valInt, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 prefix length: %s", f.Name, val)
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 prefix length: %s", fieldRef, val)
|
||||
}
|
||||
if valInt < 0 || valInt > 128 {
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 prefix length: %s", f.Name, val)
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 prefix length: %s", fieldRef, val)
|
||||
}
|
||||
case "ipv4":
|
||||
if net.ParseIP(val).To4() == nil {
|
||||
return fmt.Errorf("%s is not a valid IPv4 address: %s", fieldRef, val)
|
||||
return fmt.Errorf("field `%s` is not a valid IPv4 address: %s", fieldRef, val)
|
||||
}
|
||||
case "ipv6":
|
||||
if net.ParseIP(val).To16() == nil {
|
||||
return fmt.Errorf("%s is not a valid IPv6 address: %s", fieldRef, val)
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 address: %s", fieldRef, val)
|
||||
}
|
||||
case "ipv6_prefix":
|
||||
if i, _, err := net.ParseCIDR(val); err != nil {
|
||||
if i.To16() == nil {
|
||||
return fmt.Errorf("%s is not a valid IPv6 prefix: %s", fieldRef, val)
|
||||
return fmt.Errorf("field `%s` is not a valid IPv6 prefix: %s", fieldRef, val)
|
||||
}
|
||||
}
|
||||
case "ipv4_or_ipv6":
|
||||
|
|
@ -430,7 +430,7 @@ func (f *FieldConfig) validateSingleValue(val string, index int) error {
|
|||
return fmt.Errorf("%s is not a valid CIDR notation: %s", fieldRef, val)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("field `%s` cannot use validate_type: unsupported validator: %s", f.Name, validateType)
|
||||
return fmt.Errorf("field `%s` cannot use validate_type: unsupported validator: %s", fieldRef, validateType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,14 +146,17 @@ func (m *MDNS) start(allowRestart bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Start starts the mDNS server
|
||||
func (m *MDNS) Start() error {
|
||||
return m.start(false)
|
||||
}
|
||||
|
||||
// Restart restarts the mDNS server
|
||||
func (m *MDNS) Restart() error {
|
||||
return m.start(true)
|
||||
}
|
||||
|
||||
// Stop stops the mDNS server
|
||||
func (m *MDNS) Stop() error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
|
@ -165,26 +168,46 @@ func (m *MDNS) Stop() error {
|
|||
return m.conn.Close()
|
||||
}
|
||||
|
||||
func (m *MDNS) SetLocalNames(localNames []string, always bool) error {
|
||||
if reflect.DeepEqual(m.localNames, localNames) && !always {
|
||||
return nil
|
||||
func (m *MDNS) setLocalNames(localNames []string) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
if reflect.DeepEqual(m.localNames, localNames) {
|
||||
return
|
||||
}
|
||||
|
||||
m.localNames = localNames
|
||||
_ = m.Restart()
|
||||
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MDNS) SetListenOptions(listenOptions *MDNSListenOptions) error {
|
||||
func (m *MDNS) setListenOptions(listenOptions *MDNSListenOptions) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
if m.listenOptions != nil &&
|
||||
m.listenOptions.IPv4 == listenOptions.IPv4 &&
|
||||
m.listenOptions.IPv6 == listenOptions.IPv6 {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
m.listenOptions = listenOptions
|
||||
_ = m.Restart()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetLocalNames sets the local names and restarts the mDNS server
|
||||
func (m *MDNS) SetLocalNames(localNames []string) error {
|
||||
m.setLocalNames(localNames)
|
||||
return m.Restart()
|
||||
}
|
||||
|
||||
// SetListenOptions sets the listen options and restarts the mDNS server
|
||||
func (m *MDNS) SetListenOptions(listenOptions *MDNSListenOptions) error {
|
||||
m.setListenOptions(listenOptions)
|
||||
return m.Restart()
|
||||
}
|
||||
|
||||
// SetOptions sets the local names and listen options and restarts the mDNS server
|
||||
func (m *MDNS) SetOptions(options *MDNSOptions) error {
|
||||
m.setLocalNames(options.LocalNames)
|
||||
m.setListenOptions(options.ListenOptions)
|
||||
return m.Restart()
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -48,6 +48,10 @@ void action_switch_to_reset_config(lv_event_t *e) {
|
|||
loadScreen(SCREEN_ID_RESET_CONFIG_SCREEN);
|
||||
}
|
||||
|
||||
void action_switch_to_dhcpc(lv_event_t *e) {
|
||||
loadScreen(SCREEN_ID_SWITCH_DHCP_CLIENT_SCREEN);
|
||||
}
|
||||
|
||||
void action_switch_to_reboot(lv_event_t *e) {
|
||||
loadScreen(SCREEN_ID_REBOOT_SCREEN);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ extern void action_reset_config(lv_event_t * e);
|
|||
extern void action_reboot(lv_event_t * e);
|
||||
extern void action_switch_to_reboot(lv_event_t * e);
|
||||
extern void action_dhcpc(lv_event_t * e);
|
||||
extern void action_switch_to_dhcpc(lv_event_t * e);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ void create_screen_menu_advanced_screen() {
|
|||
objects.menu_btn_dhcp_client = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, LV_PCT(100), 50);
|
||||
lv_obj_add_event_cb(obj, action_switch_to_reboot, LV_EVENT_PRESSED, (void *)0);
|
||||
lv_obj_add_event_cb(obj, action_switch_to_dhcpc, LV_EVENT_PRESSED, (void *)0);
|
||||
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SNAPPABLE);
|
||||
add_style_menu_button(obj);
|
||||
{
|
||||
|
|
@ -2278,7 +2278,7 @@ void create_screen_switch_dhcp_client_screen() {
|
|||
lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0));
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
add_style_header_link(obj);
|
||||
lv_label_set_text(obj, "Reset Config");
|
||||
lv_label_set_text(obj, "DHCP Client");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -720,7 +720,8 @@ func rpcSetWakeOnLanDevices(params SetWakeOnLanDevicesParams) error {
|
|||
}
|
||||
|
||||
func rpcResetConfig() error {
|
||||
config = defaultConfig
|
||||
defaultConfig := getDefaultConfig()
|
||||
config = &defaultConfig
|
||||
if err := SaveConfig(); err != nil {
|
||||
return fmt.Errorf("failed to reset config: %w", err)
|
||||
}
|
||||
|
|
|
|||
20
mdns.go
20
mdns.go
|
|
@ -1,23 +1,23 @@
|
|||
package kvm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jetkvm/kvm/internal/mdns"
|
||||
)
|
||||
|
||||
var mDNS *mdns.MDNS
|
||||
|
||||
func initMdns() error {
|
||||
options := getMdnsOptions()
|
||||
if options == nil {
|
||||
return fmt.Errorf("failed to get mDNS options")
|
||||
}
|
||||
|
||||
m, err := mdns.NewMDNS(&mdns.MDNSOptions{
|
||||
Logger: logger,
|
||||
LocalNames: []string{
|
||||
"jetkvm", "jetkvm.local",
|
||||
// networkManager.GetHostname(),
|
||||
// networkManager.GetFQDN(),
|
||||
},
|
||||
ListenOptions: &mdns.MDNSListenOptions{
|
||||
IPv4: config.NetworkConfig.MDNSMode.String != "disabled",
|
||||
IPv6: config.NetworkConfig.MDNSMode.String != "disabled",
|
||||
},
|
||||
Logger: logger,
|
||||
LocalNames: options.LocalNames,
|
||||
ListenOptions: options.ListenOptions,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
53
network.go
53
network.go
|
|
@ -32,19 +32,47 @@ func toRpcNetworkSettings(config *types.NetworkConfig) *RpcNetworkSettings {
|
|||
}
|
||||
}
|
||||
|
||||
func getMdnsOptions() *mdns.MDNSOptions {
|
||||
if networkManager == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ipv4, ipv6 bool
|
||||
switch config.NetworkConfig.MDNSMode.String {
|
||||
case "auto":
|
||||
ipv4 = true
|
||||
ipv6 = true
|
||||
case "ipv4_only":
|
||||
ipv4 = true
|
||||
case "ipv6_only":
|
||||
ipv6 = true
|
||||
}
|
||||
|
||||
return &mdns.MDNSOptions{
|
||||
LocalNames: []string{
|
||||
networkManager.Hostname(),
|
||||
networkManager.FQDN(),
|
||||
},
|
||||
ListenOptions: &mdns.MDNSListenOptions{
|
||||
IPv4: ipv4,
|
||||
IPv6: ipv6,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func restartMdns() {
|
||||
if mDNS == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = mDNS.SetListenOptions(&mdns.MDNSListenOptions{
|
||||
IPv4: config.NetworkConfig.MDNSMode.String != "disabled",
|
||||
IPv6: config.NetworkConfig.MDNSMode.String != "disabled",
|
||||
})
|
||||
_ = mDNS.SetLocalNames([]string{
|
||||
networkManager.Hostname(),
|
||||
networkManager.FQDN(),
|
||||
}, true)
|
||||
options := getMdnsOptions()
|
||||
if options == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := mDNS.SetOptions(options); err != nil {
|
||||
networkLogger.Error().Err(err).Msg("failed to restart mDNS")
|
||||
}
|
||||
}
|
||||
|
||||
func triggerTimeSyncOnNetworkStateChange() {
|
||||
|
|
@ -63,9 +91,11 @@ func triggerTimeSyncOnNetworkStateChange() {
|
|||
}
|
||||
|
||||
// sync time
|
||||
if err := timeSync.Sync(); err != nil {
|
||||
networkLogger.Error().Err(err).Msg("failed to sync time after network state change")
|
||||
}
|
||||
go func() {
|
||||
if err := timeSync.Sync(); err != nil {
|
||||
networkLogger.Error().Err(err).Msg("failed to sync time after network state change")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func networkStateChanged(_ string, state types.InterfaceState) {
|
||||
|
|
@ -115,6 +145,7 @@ func initNetwork() error {
|
|||
nc := config.NetworkConfig
|
||||
|
||||
nm := nmlite.NewNetworkManager(context.Background(), networkLogger)
|
||||
networkLogger.Info().Interface("networkConfig", nc).Str("hostname", nc.Hostname.String).Str("domain", nc.Domain.String).Msg("initializing network manager")
|
||||
_ = setHostname(nm, nc.Hostname.String, nc.Domain.String)
|
||||
nm.SetOnInterfaceStateChange(networkStateChanged)
|
||||
if err := nm.AddInterface(NetIfName, nc); err != nil {
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func (hm *ResolvConfManager) getDomain() string {
|
|||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
return "local"
|
||||
}
|
||||
|
||||
func (hm *ResolvConfManager) reconcileHostname() error {
|
||||
|
|
|
|||
|
|
@ -120,12 +120,12 @@ func (im *InterfaceManager) updateInterfaceStateAddresses(nl *link.Link) (bool,
|
|||
}
|
||||
}
|
||||
|
||||
if !compareStringSlices(im.state.IPv4Addresses, ipv4Addresses) {
|
||||
if !sortAndCompareStringSlices(im.state.IPv4Addresses, ipv4Addresses) {
|
||||
im.state.IPv4Addresses = ipv4Addresses
|
||||
stateChanged = true
|
||||
}
|
||||
|
||||
if !compareIPv6AddressSlices(im.state.IPv6Addresses, ipv6Addresses) {
|
||||
if !sortAndCompareIPv6AddressSlices(im.state.IPv6Addresses, ipv6Addresses) {
|
||||
im.state.IPv6Addresses = ipv6Addresses
|
||||
stateChanged = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,10 @@ func (nm *NetworkManager) GetInterfaceState(iface string) (*types.InterfaceState
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return im.GetState(), nil
|
||||
state := im.GetState()
|
||||
state.Hostname = nm.Hostname()
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// GetInterfaceConfig returns the current configuration of a specific interface
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ func lifetimeToTime(lifetime int) *time.Time {
|
|||
return &t
|
||||
}
|
||||
|
||||
func compareStringSlices(a, b []string) bool {
|
||||
func sortAndCompareStringSlices(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ func compareStringSlices(a, b []string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func compareIPv6AddressSlices(a, b []types.IPv6Address) bool {
|
||||
func sortAndCompareIPv6AddressSlices(a, b []types.IPv6Address) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue