diff --git a/cmd/machine-config-controller/start.go b/cmd/machine-config-controller/start.go index 4a357385ed..6999ebf2e9 100644 --- a/cmd/machine-config-controller/start.go +++ b/cmd/machine-config-controller/start.go @@ -179,6 +179,8 @@ func createControllers(ctx *ctrlcommon.ControllerContext) []ctrlcommon.Controlle ctx.InformerFactory.Machineconfiguration().V1().MachineConfigPools(), ctx.InformerFactory.Machineconfiguration().V1().MachineConfigs(), ctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(), + ctx.InformerFactory.Machineconfiguration().V1().ContainerRuntimeConfigs(), + ctx.InformerFactory.Machineconfiguration().V1().KubeletConfigs(), ctx.ClientBuilder.KubeClientOrDie("render-controller"), ctx.ClientBuilder.MachineConfigClientOrDie("render-controller"), ), diff --git a/pkg/apis/machineconfiguration.openshift.io/v1/helpers.go b/pkg/apis/machineconfiguration.openshift.io/v1/helpers.go index 77fc8db011..168f77ede6 100644 --- a/pkg/apis/machineconfiguration.openshift.io/v1/helpers.go +++ b/pkg/apis/machineconfiguration.openshift.io/v1/helpers.go @@ -5,6 +5,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "k8s.io/apimachinery/pkg/labels" ) // NewMachineConfigPoolCondition creates a new MachineConfigPool condition. @@ -199,3 +201,40 @@ func IsControllerConfigCompleted(ccName string, ccGetter func(string) (*Controll } return fmt.Errorf("ControllerConfig has not completed: completed(%v) running(%v) failing(%v)", completed, running, failing) } + +// AreMCGeneratingSubControllersCompleted checks whether all MC producing sub-controllers are completed +func AreMCGeneratingSubControllersCompleted(crcLister func(labels.Selector) ([]*ContainerRuntimeConfig, error), mckLister func(labels.Selector) ([]*KubeletConfig, error), selector labels.Selector) error { + + containerConfigs, err := crcLister(selector) + if err != nil { + return err + } + for _, crc := range containerConfigs { + if crc.Generation != crc.Status.ObservedGeneration { + return fmt.Errorf("status for ContainerRuntimeConfig %s is being reported for %d, expecting it for %d", crc.ObjectMeta.Name, crc.Status.ObservedGeneration, crc.Generation) + } + + for _, condition := range crc.Status.Conditions { + if condition.Type != ContainerRuntimeConfigSuccess { + return fmt.Errorf("ContainerRuntimeConfig has not completed") + } + } + } + + kubeletConfigs, err := mckLister(selector) + if err != nil { + return err + } + for _, mck := range kubeletConfigs { + if mck.Generation != mck.Status.ObservedGeneration { + return fmt.Errorf("status for KubeletConfig %s is being reported for %d, expecting it for %d", mck.ObjectMeta.Name, mck.Status.ObservedGeneration, mck.Generation) + } + + for _, condition := range mck.Status.Conditions { + if condition.Type != KubeletConfigSuccess { + return fmt.Errorf("KubeletConfig has not completed") + } + } + } + return nil +} diff --git a/pkg/controller/render/render_controller.go b/pkg/controller/render/render_controller.go index a5d568b1f3..bf04328c1f 100644 --- a/pkg/controller/render/render_controller.go +++ b/pkg/controller/render/render_controller.go @@ -68,6 +68,12 @@ type Controller struct { ccLister mcfglistersv1.ControllerConfigLister ccListerSynced cache.InformerSynced + crcLister mcfglistersv1.ContainerRuntimeConfigLister + crcListerSynced cache.InformerSynced + + mckLister mcfglistersv1.KubeletConfigLister + mckListerSynced cache.InformerSynced + queue workqueue.RateLimitingInterface } @@ -76,6 +82,8 @@ func New( mcpInformer mcfginformersv1.MachineConfigPoolInformer, mcInformer mcfginformersv1.MachineConfigInformer, ccInformer mcfginformersv1.ControllerConfigInformer, + crcInformer mcfginformersv1.ContainerRuntimeConfigInformer, + mckInformer mcfginformersv1.KubeletConfigInformer, kubeClient clientset.Interface, mcfgClient mcfgclientset.Interface, ) *Controller { @@ -109,6 +117,10 @@ func New( ctrl.mcListerSynced = mcInformer.Informer().HasSynced ctrl.ccLister = ccInformer.Lister() ctrl.ccListerSynced = ccInformer.Informer().HasSynced + ctrl.crcLister = crcInformer.Lister() + ctrl.crcListerSynced = crcInformer.Informer().HasSynced + ctrl.mckLister = mckInformer.Lister() + ctrl.mckListerSynced = mckInformer.Informer().HasSynced return ctrl } @@ -427,6 +439,10 @@ func (ctrl *Controller) syncMachineConfigPool(key string) error { return err } + if err := mcfgv1.AreMCGeneratingSubControllersCompleted(ctrl.crcLister.List, ctrl.mckLister.List, selector); err != nil { + return err + } + mcs, err := ctrl.mcLister.List(selector) if err != nil { return err diff --git a/pkg/controller/render/render_controller_test.go b/pkg/controller/render/render_controller_test.go index 235a3fd320..537c9c72a7 100644 --- a/pkg/controller/render/render_controller_test.go +++ b/pkg/controller/render/render_controller_test.go @@ -46,6 +46,8 @@ type fixture struct { mcpLister []*mcfgv1.MachineConfigPool mcLister []*mcfgv1.MachineConfig ccLister []*mcfgv1.ControllerConfig + crcLister []*mcfgv1.ContainerRuntimeConfig + mckLister []*mcfgv1.KubeletConfig actions []core.Action @@ -65,11 +67,13 @@ func (f *fixture) newController() *Controller { i := informers.NewSharedInformerFactory(f.client, noResyncPeriodFunc()) c := New(i.Machineconfiguration().V1().MachineConfigPools(), i.Machineconfiguration().V1().MachineConfigs(), - i.Machineconfiguration().V1().ControllerConfigs(), k8sfake.NewSimpleClientset(), f.client) + i.Machineconfiguration().V1().ControllerConfigs(), i.Machineconfiguration().V1().ContainerRuntimeConfigs(), i.Machineconfiguration().V1().KubeletConfigs(), k8sfake.NewSimpleClientset(), f.client) c.mcpListerSynced = alwaysReady c.mcListerSynced = alwaysReady c.ccListerSynced = alwaysReady + c.crcListerSynced = alwaysReady + c.mckListerSynced = alwaysReady c.eventRecorder = ctrlcommon.NamespacedEventRecorder(&record.FakeRecorder{}) stopCh := make(chan struct{}) @@ -91,6 +95,14 @@ func (f *fixture) newController() *Controller { i.Machineconfiguration().V1().ControllerConfigs().Informer().GetIndexer().Add(m) } + for _, m := range f.crcLister { + i.Machineconfiguration().V1().ContainerRuntimeConfigs().Informer().GetIndexer().Add(m) + } + + for _, m := range f.mckLister { + i.Machineconfiguration().V1().KubeletConfigs().Informer().GetIndexer().Add(m) + } + return c } @@ -184,7 +196,11 @@ func filterInformerActions(actions []core.Action) []core.Action { action.Matches("list", "controllerconfigs") || action.Matches("watch", "controllerconfigs") || action.Matches("list", "machineconfigs") || - action.Matches("watch", "machineconfigs")) { + action.Matches("watch", "machineconfigs") || + action.Matches("list", "kubeletconfigs") || + action.Matches("watch", "kubeletconfigs") || + action.Matches("list", "containerruntimeconfigs") || + action.Matches("watch", "containerruntimeconfigs")) { continue } ret = append(ret, action) @@ -261,8 +277,12 @@ func TestCreatesGeneratedMachineConfig(t *testing.T) { helpers.NewMachineConfig("05-extra-master", map[string]string{"node-role/master": ""}, "dummy://1", []ign3types.File{files[1]}), } cc := newControllerConfig(ctrlcommon.ControllerConfigName) + crc := &mcfgv1.ContainerRuntimeConfig{} + mck := &mcfgv1.KubeletConfig{} f.ccLister = append(f.ccLister, cc) + f.crcLister = append(f.crcLister, crc) + f.mckLister = append(f.mckLister, mck) f.mcpLister = append(f.mcpLister, mcp) f.objects = append(f.objects, mcp) f.mcLister = append(f.mcLister, mcs...) @@ -342,8 +362,12 @@ func TestUpdatesGeneratedMachineConfig(t *testing.T) { mcp.Spec.Configuration.Name = gmc.Name mcp.Status.Configuration.Name = gmc.Name - f.ccLister = append(f.ccLister, cc) + crc := &mcfgv1.ContainerRuntimeConfig{} + mck := &mcfgv1.KubeletConfig{} + f.ccLister = append(f.ccLister, cc) + f.crcLister = append(f.crcLister, crc) + f.mckLister = append(f.mckLister, mck) f.mcpLister = append(f.mcpLister, mcp) f.objects = append(f.objects, mcp) f.mcLister = append(f.mcLister, mcs...) @@ -449,8 +473,12 @@ func TestDoNothing(t *testing.T) { mcp.Spec.Configuration.Name = gmc.Name mcp.Status.Configuration.Name = gmc.Name - f.ccLister = append(f.ccLister, cc) + crc := &mcfgv1.ContainerRuntimeConfig{} + mck := &mcfgv1.KubeletConfig{} + f.ccLister = append(f.ccLister, cc) + f.crcLister = append(f.crcLister, crc) + f.mckLister = append(f.mckLister, mck) f.mcpLister = append(f.mcpLister, mcp) f.objects = append(f.objects, mcp) f.mcLister = append(f.mcLister, mcs...) diff --git a/test/e2e-bootstrap/bootstrap_test.go b/test/e2e-bootstrap/bootstrap_test.go index 28db91c001..0fcbedc7bb 100644 --- a/test/e2e-bootstrap/bootstrap_test.go +++ b/test/e2e-bootstrap/bootstrap_test.go @@ -499,6 +499,8 @@ func createControllers(ctx *ctrlcommon.ControllerContext) []ctrlcommon.Controlle ctx.InformerFactory.Machineconfiguration().V1().MachineConfigPools(), ctx.InformerFactory.Machineconfiguration().V1().MachineConfigs(), ctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(), + ctx.InformerFactory.Machineconfiguration().V1().ContainerRuntimeConfigs(), + ctx.InformerFactory.Machineconfiguration().V1().KubeletConfigs(), ctx.ClientBuilder.KubeClientOrDie("render-controller"), ctx.ClientBuilder.MachineConfigClientOrDie("render-controller"), ),