From 810c08e6542aa58fe52ba187d99be5bb5a7eb3ce Mon Sep 17 00:00:00 2001 From: Roberto Bonafiglia Date: Wed, 31 Jul 2024 17:59:21 +0200 Subject: [PATCH] Fixed hns clean only in case of reboot Signed-off-by: Roberto Bonafiglia --- pkg/windows/calico.go | 51 +++++++++++++++++++++++++++++++++++++++++-- pkg/windows/utils.go | 6 +++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/pkg/windows/calico.go b/pkg/windows/calico.go index 4892320fef..40a74c8711 100644 --- a/pkg/windows/calico.go +++ b/pkg/windows/calico.go @@ -21,6 +21,7 @@ import ( "github.com/rancher/rke2/pkg/logging" "github.com/sirupsen/logrus" opv1 "github.com/tigera/operator/api/v1" + "golang.org/x/sys/windows" authv1 "k8s.io/api/authentication/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -302,8 +303,14 @@ func (c *Calico) Start(ctx context.Context) error { // generateCalicoNetworks creates the overlay networks for internode networking func (c *Calico) generateCalicoNetworks() error { - if err := deleteAllNetworks(); err != nil { - return errors.Wrapf(err, "failed to delete all networks before bootstrapping calico") + nodeRebooted, err := c.isNodeRebooted() + if err != nil { + return errors.Wrapf(err, "failed to check last node reboot time") + } + if nodeRebooted { + if err = deleteAllNetworks(); err != nil { + return errors.Wrapf(err, "failed to delete all networks before bootstrapping calico") + } } // There are four ways to select the vxlan interface. In order of priority: @@ -528,3 +535,43 @@ func (c *Calico) ReserveSourceVip(ctx context.Context) (string, error) { return vip, nil } + +//Get latest stored reboot +func (c *Calico) getStoredLastBootTime() (string, error) { + lastRebootPath := filepath.Join(c.CNICfg.ConfigPath, "lastBootTime.txt") + lastStoredBoot, err := os.ReadFile(lastRebootPath) + if err != nil { + if os.IsNotExist(err) { + return "", nil + } else { + return "", err + } + } + return string(lastStoredBoot), nil +} + +//Set last boot time on the registry +func (c *Calico) setStoredLastBootTime(lastBootTime string) error { + lastRebootPath := filepath.Join(c.CNICfg.ConfigPath, "lastBootTime.txt") + err := os.WriteFile(lastRebootPath, []byte(lastBootTime), 0644) + if err != nil { + return err + } + return nil +} + +// Check if the node was rebooted +func (c *Calico) isNodeRebooted() (bool, error) { + tickCountSinceBoot := windows.DurationSinceBoot() + bootTime := time.Now().Add(-tickCountSinceBoot) + lastReboot := bootTime.Format(time.UnixDate) + prevLastReboot, err := c.getStoredLastBootTime() + if err != nil { + return true, err + } + if lastReboot == prevLastReboot { + return false, nil + } + err = c.setStoredLastBootTime(lastReboot) + return true, err +} diff --git a/pkg/windows/utils.go b/pkg/windows/utils.go index 772de9f3f1..7721d9c302 100644 --- a/pkg/windows/utils.go +++ b/pkg/windows/utils.go @@ -34,6 +34,12 @@ var ( // createHnsNetwork creates the network that will connect nodes and returns its managementIP func createHnsNetwork(backend string, networkAdapter string) (string, error) { var network hcsshim.HNSNetwork + // Check if the interface already exists + hcsnetwork, err := hcsshim.GetHNSNetworkByName(CalicoHnsNetworkName) + if err == nil { + return hcsnetwork.ManagementIP, nil + } + if backend == "vxlan" { // Ignoring the return because both true and false without an error represent that the firewall rule was created or already exists if _, err := wapi.FirewallRuleAdd("OverlayTraffic4789UDP", "Overlay network traffic UDP", "", "4789", wapi.NET_FW_IP_PROTOCOL_UDP, wapi.NET_FW_PROFILE2_ALL); err != nil {