@@ -60,7 +60,8 @@ const (
6060 // 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
6161 maxRetries = 15
6262
63- builtInLabelKey = "machineconfiguration.openshift.io/mco-built-in"
63+ builtInLabelKey = "machineconfiguration.openshift.io/mco-built-in"
64+ forceSyncOnUpgrade = "force-sync-on-upgrade"
6465)
6566
6667var (
@@ -79,6 +80,7 @@ type Controller struct {
7980 templatesDir string
8081
8182 client mcfgclientset.Interface
83+ kubeClient clientset.Interface
8284 configClient configclientset.Interface
8385 eventRecorder record.EventRecorder
8486
@@ -148,6 +150,7 @@ func New(
148150 ctrl := & Controller {
149151 templatesDir : templatesDir ,
150152 client : mcfgClient ,
153+ kubeClient : kubeClient ,
151154 configClient : configClient ,
152155 eventRecorder : ctrlcommon .NamespacedEventRecorder (eventBroadcaster .NewRecorder (scheme .Scheme , corev1.EventSource {Component : "machineconfigcontroller-containerruntimeconfigcontroller" })),
153156 queue : workqueue .NewTypedRateLimitingQueueWithConfig (
@@ -213,6 +216,7 @@ func New(
213216
214217 ctrl .clusterVersionLister = clusterVersionInformer .Lister ()
215218 ctrl .clusterVersionListerSynced = clusterVersionInformer .Informer ().HasSynced
219+ ctrl .queue .Add (forceSyncOnUpgrade )
216220
217221 ctrl .fgHandler = fgHandler
218222
@@ -596,6 +600,84 @@ func (ctrl *Controller) addAnnotation(cfg *mcfgv1.ContainerRuntimeConfig, annota
596600 return annotationUpdateErr
597601}
598602
603+ // migrateRuncToCrun performs the upgrade migration from runc to crun as the default container runtime.
604+ // This function checks for the existence of the crio-default-container-runtime ConfigMap. If it exists,
605+ // it updates the MachineConfigs for master and worker pools to use crun instead of runc, then deletes
606+ // the ConfigMap to prevent re-running the migration.
607+ func (ctrl * Controller ) migrateRuncToCrun () error {
608+ // Check if the migration ConfigMap exists
609+ _ , err := ctrl .kubeClient .CoreV1 ().ConfigMaps (ctrlcommon .MCONamespace ).Get (context .TODO (), "crio-default-container-runtime" , metav1.GetOptions {})
610+ if errors .IsNotFound (err ) {
611+ // ConfigMap doesn't exist, no migration needed
612+ return nil
613+ }
614+ if err != nil {
615+ return fmt .Errorf ("error checking for crio-default-container-runtime configmap: %w" , err )
616+ }
617+
618+ klog .Info ("Found crio-default-container-runtime ConfigMap, starting migration from runc to crun" )
619+
620+ // Get all MachineConfigPools
621+ pools , err := ctrl .mcpLister .List (labels .Everything ())
622+ if err != nil {
623+ return fmt .Errorf ("error listing MachineConfigPools: %w" , err )
624+ }
625+
626+ // Only process master and worker pools for the migration
627+ for _ , pool := range pools {
628+ if pool .Name != "master" && pool .Name != "worker" {
629+ continue
630+ }
631+
632+ // Get the MachineConfig name for this pool
633+ mcName := fmt .Sprintf ("00-override-%s-generated-crio-default-container-runtime" , pool .Name )
634+
635+ // Get the existing MachineConfig
636+ mc , err := ctrl .client .MachineconfigurationV1 ().MachineConfigs ().Get (context .TODO (), mcName , metav1.GetOptions {})
637+ if errors .IsNotFound (err ) {
638+ klog .Infof ("MachineConfig %s not found, skipping migration for pool %s" , mcName , pool .Name )
639+ continue
640+ }
641+ if err != nil {
642+ return fmt .Errorf ("error getting MachineConfig %s: %w" , mcName , err )
643+ }
644+
645+ // Create the new crun configuration file
646+ configFileList := createDefaultContainerRuntimeFile ()
647+
648+ // Create the new Ignition config
649+ ctrRuntimeConfigIgn := createNewIgnition (configFileList )
650+ rawCtrRuntimeConfigIgn , err := json .Marshal (ctrRuntimeConfigIgn )
651+ if err != nil {
652+ return fmt .Errorf ("error marshalling container runtime config Ignition: %w" , err )
653+ }
654+
655+ // Update the MachineConfig with the new crun configuration
656+ mc .Spec .Config .Raw = rawCtrRuntimeConfigIgn
657+ mc .SetAnnotations (map [string ]string {
658+ ctrlcommon .GeneratedByControllerVersionAnnotationKey : version .Hash ,
659+ })
660+
661+ // Update the MachineConfig
662+ if err := retry .RetryOnConflict (updateBackoff , func () error {
663+ _ , err = ctrl .client .MachineconfigurationV1 ().MachineConfigs ().Update (context .TODO (), mc , metav1.UpdateOptions {})
664+ return err
665+ }); err != nil {
666+ return fmt .Errorf ("error updating MachineConfig %s: %w" , mcName , err )
667+ }
668+
669+ klog .Infof ("Successfully migrated MachineConfig %s to use crun" , mcName )
670+ }
671+
672+ // Delete the ConfigMap after successful migration
673+ if err := ctrl .kubeClient .CoreV1 ().ConfigMaps (ctrlcommon .MCONamespace ).Delete (context .TODO (), "crio-default-container-runtime" , metav1.DeleteOptions {}); err != nil && ! errors .IsNotFound (err ) {
674+ return fmt .Errorf ("error deleting crio-default-container-runtime configmap: %w" , err )
675+ }
676+
677+ klog .Info ("Successfully completed migration from runc to crun and deleted migration ConfigMap" )
678+ return nil
679+ }
680+
599681// syncContainerRuntimeConfig will sync the ContainerRuntimeconfig with the given key.
600682// This function is not meant to be invoked concurrently with the same key.
601683// nolint: gocyclo
@@ -606,6 +688,17 @@ func (ctrl *Controller) syncContainerRuntimeConfig(key string) error {
606688 klog .V (4 ).Infof ("Finished syncing ContainerRuntimeconfig %q (%v)" , key , time .Since (startTime ))
607689 }()
608690
691+ // OKD only: Run the migration function at the start of sync
692+ if version .IsSCOS () {
693+ if err := ctrl .migrateRuncToCrun (); err != nil {
694+ return fmt .Errorf ("Error during runc to crun migration: %w" , err )
695+ }
696+ }
697+
698+ if key == forceSyncOnUpgrade {
699+ return nil
700+ }
701+
609702 _ , name , err := cache .SplitMetaNamespaceKey (key )
610703 if err != nil {
611704 return err
@@ -709,7 +802,7 @@ func (ctrl *Controller) syncContainerRuntimeConfig(key string) error {
709802 }
710803 _ , ok := cfg .GetAnnotations ()[ctrlcommon .MCNameSuffixAnnotationKey ]
711804 arr := strings .Split (managedKey , "-" )
712- // the first managed key value 99 -poolname-generated-containerruntime does not have a suffix
805+ // the first managed key value 00-override -poolname-generated-containerruntime does not have a suffix
713806 // set "" as suffix annotation to the containerruntime config object
714807 if _ , err := strconv .Atoi (arr [len (arr )- 1 ]); err != nil && ! ok {
715808 if err := ctrl .addAnnotation (cfg , ctrlcommon .MCNameSuffixAnnotationKey , "" ); err != nil {
0 commit comments