From 4ca86ff6484c897398724cab86074994512fd585 Mon Sep 17 00:00:00 2001 From: Ashvin Deodhar Date: Wed, 19 Dec 2018 17:21:58 -0800 Subject: [PATCH] Detect reboot for windows and cleanup network config --- ipam/manager.go | 1 + network/manager.go | 15 ++++++++ platform/os_linux.go | 6 ++++ platform/os_windows.go | 77 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/ipam/manager.go b/ipam/manager.go index 385e33498e..a87fcc544e 100644 --- a/ipam/manager.go +++ b/ipam/manager.go @@ -110,6 +110,7 @@ func (am *addressManager) restore() error { log.Printf("[ipam] reboot time %v store mod time %v", rebootTime, modTime) if err == nil && rebootTime.After(modTime) { + log.Printf("[ipam] Detected Reboot") rebooted = true } } diff --git a/network/manager.go b/network/manager.go index 3a6e9e5974..2c41971b00 100644 --- a/network/manager.go +++ b/network/manager.go @@ -121,7 +121,22 @@ func (nm *networkManager) restore() error { rebootTime, err := platform.GetLastRebootTime() log.Printf("[net] reboot time %v store mod time %v", rebootTime, modTime) if err == nil && rebootTime.After(modTime) { + log.Printf("[net] Detected Reboot") rebooted = true + if clearNwConfig, err := platform.ClearNetworkConfiguration(); clearNwConfig { + if err != nil { + log.Printf("[net] Failed to clear network configuration, err:%v\n", err) + return err + } + + // Clear networkManager contents + nm.TimeStamp = time.Time{} + for extIfName := range nm.ExternalInterfaces { + delete(nm.ExternalInterfaces, extIfName) + } + + return nil + } } } diff --git a/platform/os_linux.go b/platform/os_linux.go index ebf4239bb6..0243b5aaa9 100644 --- a/platform/os_linux.go +++ b/platform/os_linux.go @@ -88,3 +88,9 @@ func SetOutboundSNAT(subnet string) error { } return nil } + +// ClearNetworkConfiguration clears the azure-vnet.json contents. +// This will be called only when reboot is detected - This is windows specific +func ClearNetworkConfiguration() (bool, error) { + return false, nil +} diff --git a/platform/os_windows.go b/platform/os_windows.go index 00e1d97d1e..f0467b89c8 100644 --- a/platform/os_windows.go +++ b/platform/os_windows.go @@ -4,7 +4,13 @@ package platform import ( + "fmt" + "os/exec" + "strconv" + "strings" "time" + + "github.com/Azure/azure-container-networking/log" ) const ( @@ -32,8 +38,60 @@ func GetOSInfo() string { // GetLastRebootTime returns the last time the system rebooted. func GetLastRebootTime() (time.Time, error) { - var rebootTime time.Time - return rebootTime, nil + var systemBootTime string + out, err := exec.Command("cmd", "/c", "systeminfo").Output() + if err != nil { + log.Printf("Failed to query systeminfo, err: %v", err) + return time.Time{}.UTC(), err + } + + systemInfo := strings.Split(string(out), "\n") + for _, systemProperty := range systemInfo { + if strings.Contains(systemProperty, "Boot Time") { + systemBootTime = strings.TrimSpace(strings.Split(systemProperty, "System Boot Time:")[1]) + } + } + + if len(strings.TrimSpace(systemBootTime)) == 0 { + log.Printf("Failed to retrieve boot time from systeminfo") + return time.Time{}.UTC(), fmt.Errorf("Failed to retrieve boot time from systeminfo") + } + + log.Printf("Boot time: %s", systemBootTime) + // The System Boot Time is in the following format "01/02/2006, 03:04:05 PM" + // Formulate the Boot Time in the format: "2006-01-02 15:04:05" + bootDate := strings.Split(systemBootTime, " ")[0] + bootTime := strings.Split(systemBootTime, " ")[1] + bootPM := strings.Contains(strings.Split(systemBootTime, " ")[2], "PM") + + month := strings.Split(bootDate, "/")[0] + day := strings.Split(bootDate, "/")[1] + year := strings.Split(bootDate, "/")[2] + year = strings.Trim(year, ",") + hour := strings.Split(bootTime, ":")[0] + hourInt, _ := strconv.Atoi(hour) + min := strings.Split(bootTime, ":")[1] + sec := strings.Split(bootTime, ":")[2] + + if bootPM && hourInt < 12 { + hourInt += 12 + } else if !bootPM && hourInt == 12 { + hourInt = 0 + } + + hour = strconv.Itoa(hourInt) + systemBootTime = year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + log.Printf("Formatted Boot time: %s", systemBootTime) + + // Parse the boot time. + layout := "2006-01-02 15:04:05" + rebootTime, err := time.ParseInLocation(layout, systemBootTime, time.Local) + if err != nil { + log.Printf("Failed to parse boot time, err:%v", err) + return time.Time{}.UTC(), err + } + + return rebootTime.UTC(), nil } func ExecuteCommand(command string) (string, error) { @@ -43,3 +101,18 @@ func ExecuteCommand(command string) (string, error) { func SetOutboundSNAT(subnet string) error { return nil } + +// ClearNetworkConfiguration clears the azure-vnet.json contents. +// This will be called only when reboot is detected - This is windows specific +func ClearNetworkConfiguration() (bool, error) { + jsonStore := CNIRuntimePath + "azure-vnet.json" + log.Printf("Deleting the json store %s", jsonStore) + cmd := exec.Command("cmd", "/c", "del", jsonStore) + + if err := cmd.Run(); err != nil { + log.Printf("Error deleting the json store %s", jsonStore) + return true, err + } + + return true, nil +}