Last active
July 10, 2020 10:12
-
-
Save beekhof/a0312eed54ac03cca9e33ed4f38b980c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go | |
index 773246cb..4dfd9325 100644 | |
--- a/pkg/daemon/update.go | |
+++ b/pkg/daemon/update.go | |
@@ -17,6 +17,8 @@ import ( | |
"syscall" | |
"time" | |
+ "github.com/openshift/machine-config-operator/pkg/daemon/pivot/reboot" | |
+ | |
ign "github.com/coreos/ignition/config/v2_2" | |
igntypes "github.com/coreos/ignition/config/v2_2/types" | |
"github.com/golang/glog" | |
@@ -24,7 +26,6 @@ import ( | |
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" | |
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common" | |
"github.com/openshift/machine-config-operator/pkg/daemon/constants" | |
- "github.com/openshift/machine-config-operator/pkg/daemon/pivot/reboot" | |
pivotutils "github.com/openshift/machine-config-operator/pkg/daemon/pivot/utils" | |
errors "github.com/pkg/errors" | |
"github.com/vincent-petithory/dataurl" | |
@@ -280,6 +281,129 @@ func (dn *Daemon) compareMachineConfig(oldConfig, newConfig *mcfgv1.MachineConfi | |
return true, nil | |
} | |
+type actionResult interface { | |
+ Describe(dn *Daemon) string | |
+ Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error | |
+} | |
+ | |
+type NoOpPostAction struct { | |
+ actionResult | |
+} | |
+ | |
+func (a NoOpPostAction)Describe(dn *Daemon) string { | |
+ return "No action needed to apply update" | |
+} | |
+ | |
+func (a NoOpPostAction)Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error { | |
+ return nil | |
+} | |
+ | |
+type RebootPostAction struct { | |
+ actionResult | |
+ | |
+ Reason string | |
+} | |
+ | |
+func (a RebootPostAction)Describe(dn *Daemon) string { | |
+ return fmt.Sprintf("Rebooting node %v: %v", dn.node.GetName(), a.Reason) | |
+} | |
+ | |
+func (a RebootPostAction)Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error { | |
+ return dn.drainAndReboot(newConfig) | |
+} | |
+ | |
+type DrainPostAction struct { | |
+ actionResult | |
+} | |
+ | |
+func (a DrainPostAction)Describe(dn *Daemon) string { | |
+ return fmt.Sprintf("Draining node %v", dn.node.GetName()) | |
+} | |
+ | |
+func (a DrainPostAction)Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error { | |
+ return dn.drain() | |
+} | |
+ | |
+type ServicePostAction struct { | |
+ actionResult | |
+ | |
+ Reason string | |
+ | |
+ ServiceName string | |
+ ServiceAction string | |
+} | |
+ | |
+ | |
+func (a ServicePostAction)Describe(dn *Daemon) string { | |
+ return fmt.Sprintf("Restarting service %v", a.Reason) | |
+} | |
+ | |
+func (a ServicePostAction)Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error { | |
+ return nil | |
+} | |
+ | |
+ | |
+type SchedulablePostAction struct { | |
+ actionResult | |
+} | |
+ | |
+func (a SchedulablePostAction)Describe(dn *Daemon) string { | |
+ return fmt.Sprintf("Uncordoning node %v", dn.node.GetName()) | |
+} | |
+ | |
+func (a SchedulablePostAction)Execute(dn *Daemon, newConfig *mcfgv1.MachineConfig) error { | |
+ return drain.RunCordonOrUncordon(dn.drainer, dn.node, false) | |
+} | |
+ | |
+func calculateActions(oldIgnConfig, newIgnConfig igntypes.Config, diff *MachineConfigDiff) []actionResult { | |
+ if diff.osUpdate || diff.kargs || diff.fips || diff.kernelType { | |
+ return []actionResult{RebootPostAction{Reason: "OS/Kernel changed"}} | |
+ } | |
+ if !reflect.DeepEqual(oldIgnConfig.Ignition, newIgnConfig.Ignition) { | |
+ return []actionResult{RebootPostAction{Reason: "Ignition changed"}} | |
+ } | |
+ if !reflect.DeepEqual(oldIgnConfig.Networkd, newIgnConfig.Networkd) { | |
+ return []actionResult{RebootPostAction{Reason: "Network changed"}} | |
+ } | |
+ if !reflect.DeepEqual(oldIgnConfig.Passwd, newIgnConfig.Passwd) { | |
+ return []actionResult{RebootPostAction{Reason: "Passwords changed"}} | |
+ } | |
+ if !reflect.DeepEqual(oldIgnConfig.Systemd, newIgnConfig.Systemd) { | |
+ return []actionResult{RebootPostAction{Reason: "Systemd changed"}} | |
+ } | |
+ if !reflect.DeepEqual(oldIgnConfig.Storage, newIgnConfig.Storage) { | |
+ actions = []actionResult{} | |
+ | |
+ icspRegex := regexp.MustCompile(".*/registry.conf") | |
+ | |
+ fileChanges = reboot.getFilesChanges(oldIgnConfig.Storage.Files, newIgnConfig.Storage.Files) | |
+ for _, change := range fileChanges { | |
+ matched, err := icspRegex.MatchString(change.name) | |
+ if err != nil { | |
+ return []actionResult{RebootPostAction{Reason: "Error processing storage changes"}} | |
+ } | |
+ if !matched { | |
+ return []actionResult{RebootPostAction{Reason: "Storage changed"}} | |
+ } | |
+ | |
+ if len(actions) == 0 { | |
+ actions = append(actions, DrainPostAction{}) | |
+ } | |
+ actions = append(actions, ServicePostAction{ | |
+ Reason: fmt.Sprintf("change to %v", change.name), | |
+ ServiceName: "crio.service", ServiceAction: "restart"}) | |
+ } | |
+ | |
+ if len(actions) > 0 { | |
+ actions = append(actions, SchedulablePostAction{}) | |
+ return actions | |
+ } | |
+ } | |
+ | |
+ return []actionResult{NoOpPostAction{}} | |
+} | |
+ | |
+ | |
// update the node to the provided node configuration. | |
func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr error) { | |
oldConfig = canonicalizeEmptyMC(oldConfig) | |
@@ -334,18 +458,20 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err | |
} | |
dn.logSystem("Starting update from %s to %s: %+v", oldConfigName, newConfigName, diff) | |
- rebootRequired := diff.osUpdate || diff.kargs || diff.fips || diff.kernelType | |
- rebootFilter := reboot.NewFilter(oldIgnConfig, newIgnConfig) | |
- drainRequired := rebootFilter.IsRebootRequired || rebootFilter.IsDrainRequired | |
+ actions := dn.calculateActions(oldIgnConfig, newIgnConfig, diff) | |
- if drainRequired { | |
- if err := dn.drain(); err != nil { | |
- return err | |
+ for _, action := range actions { | |
+ switch action.(type) { | |
+ case DrainPostAction: | |
+ glog.Infof("Performing %v", action.Describe(dn)) | |
+ if err := action.Execute(dn, newConfig); err != nil { | |
+ glog.Errorf("Uncordoning node failed, node will reboot: %v", err) | |
+ return dn.finalizeAndReboot(newConfig) | |
+ } | |
+ default: | |
+ continue | |
} | |
- } else { | |
- glog.Info("Draining node skipped as it is not required") | |
- } | |
// update files on disk that need updating | |
if err := dn.updateFiles(oldConfig, newConfig); err != nil { | |
@@ -416,10 +542,20 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err | |
if err := dn.updateOS(newConfig); err != nil { | |
return err | |
} | |
- if rebootRequired || rebootFilter.RunPostUpdateActions() { | |
- return dn.drainAndReboot(newConfig) | |
+ | |
+ for _, action := range actions { | |
+ switch action.(type) { | |
+ case DrainPostAction: | |
+ continue | |
+ default: | |
+ glog.Infof("Performing %v", action.Describe(dn)) | |
+ if err := action.Execute(dn, newConfig); err != nil { | |
+ glog.Errorf("Uncordoning node failed, node will reboot: %v", err) | |
+ return dn.finalizeAndReboot(newConfig) | |
+ } | |
+ } | |
} | |
- glog.Info("Reboot skipped as it is not required") | |
+ | |
if err := dn.nodeWriter.SetDone( | |
dn.kubeClient.CoreV1().Nodes(), | |
dn.nodeLister, | |
@@ -429,13 +565,6 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig) (retErr err | |
glog.Errorf("Setting node's state to Done failed, node will reboot: %v", err) | |
return dn.drainAndReboot(newConfig) | |
} | |
- if drainRequired { | |
- glog.Infof("Starting uncordoning node %v", dn.node.GetName()) | |
- if err := drain.RunCordonOrUncordon(dn.drainer, dn.node, false); err != nil { | |
- glog.Errorf("Uncordoning node failed, node will reboot: %v", err) | |
- return dn.finalizeAndReboot(newConfig) | |
- } | |
- } | |
glog.Infof("In desired config %s", newConfigName) | |
MCDUpdateState.WithLabelValues(newConfigName, "").SetToCurrentTime() | |
return nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment