diff --git a/Gopkg.lock b/Gopkg.lock index f1b8b8c66e..e1ab82cfa1 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -433,14 +433,14 @@ [[projects]] branch = "master" - digest = "1:8529a8c8976002e4732532e8e7acfb666bdc456f5c2075fd933132f79fd8be57" + digest = "1:9928e3f53e8ae5e280f275d0f39cdfd948169d91e8bdd23e2c6e07715321c858" name = "github.com/openshift/cluster-version-operator" packages = [ "lib/resourceapply", "lib/resourcemerge", ] pruneopts = "NUT" - revision = "b0250fa556f60c8f2fe093925ff45c2c659a0a12" + revision = "08cac1c02538c279d9aac094d42cf8788dc4e45c" [[projects]] branch = "master" @@ -1275,6 +1275,7 @@ "github.com/stretchr/testify/assert", "k8s.io/api/apps/v1", "k8s.io/api/core/v1", + "k8s.io/apimachinery/pkg/api/equality", "k8s.io/apimachinery/pkg/api/errors", "k8s.io/apimachinery/pkg/api/resource", "k8s.io/apimachinery/pkg/apis/meta/v1", diff --git a/pkg/operator/operator_test.go b/pkg/operator/operator_test.go index f7737c1ec7..cf5ac8ccf1 100644 --- a/pkg/operator/operator_test.go +++ b/pkg/operator/operator_test.go @@ -249,3 +249,61 @@ func TestOperatorSyncClusterAPIControllerHealthCheckController(t *testing.T) { } } } + +func TestEnableDisableOperatorSyncClusterAPIControllerHealthCheckController(t *testing.T) { + infra := &v1.Infrastructure{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster", + }, + Status: v1.InfrastructureStatus{ + Platform: v1.AWSPlatformType, + }, + } + stopCh := make(chan struct{}) + defer close(stopCh) + + optr := newFakeOperator(nil, []runtime.Object{newFeatureGate(v1.TechPreviewNoUpgrade), infra}, stopCh) + go optr.Run(2, stopCh) + + if err := wait.PollImmediate(1*time.Second, 5*time.Second, func() (bool, error) { + d, err := optr.deployLister.Deployments(targetNamespace).Get(deploymentName) + if err != nil { + t.Logf("Failed to get %q deployment: %v", deploymentName, err) + return false, nil + } + if !deploymentHasContainer(d, hcControllerName) { + t.Logf("Failed to verify that deployment %q has container %q", deploymentName, hcControllerName) + return false, nil + } + return true, nil + }); err != nil { + t.Fatalf("Failed to verify that deployment %q has container %q", deploymentName, hcControllerName) + } + + t.Logf("Found %q container in %q deployment", hcControllerName, deploymentName) + + hcFeatureGate, err := optr.osClient.ConfigV1().FeatureGates().Get(MachineAPIFeatureGateName, metav1.GetOptions{}) + if err != nil { + t.Fatalf("Unable to get %q feature gate: %v", MachineAPIFeatureGateName, err) + } + hcFeatureGate.Spec.FeatureSet = v1.Default + if _, err := optr.osClient.ConfigV1().FeatureGates().Update(hcFeatureGate); err != nil { + t.Fatalf("Unable to update %q feature gate and set default feature set: %v", MachineAPIFeatureGateName, err) + } + + if err := wait.PollImmediate(1*time.Second, 15*time.Second, func() (bool, error) { + d, err := optr.deployLister.Deployments(targetNamespace).Get(deploymentName) + if err != nil { + t.Logf("Failed to get %q deployment: %v", deploymentName, err) + return false, nil + } + if deploymentHasContainer(d, hcControllerName) { + t.Logf("Failed to verify that deployment %q has no container with name %q", deploymentName, hcControllerName) + return false, nil + } + return true, nil + }); err != nil { + t.Errorf("Failed to verify that deployment %q has no container with name %q ", deploymentName, hcControllerName) + } + +} diff --git a/vendor/github.com/openshift/cluster-version-operator/lib/resourcemerge/core.go b/vendor/github.com/openshift/cluster-version-operator/lib/resourcemerge/core.go index f8bec55837..0c77b3c33c 100644 --- a/vendor/github.com/openshift/cluster-version-operator/lib/resourcemerge/core.go +++ b/vendor/github.com/openshift/cluster-version-operator/lib/resourcemerge/core.go @@ -24,38 +24,8 @@ func ensurePodTemplateSpec(modified *bool, existing *corev1.PodTemplateSpec, req } func ensurePodSpec(modified *bool, existing *corev1.PodSpec, required corev1.PodSpec) { - // any container we specify, we require. - for _, required := range required.InitContainers { - var existingCurr *corev1.Container - for j, curr := range existing.InitContainers { - if curr.Name == required.Name { - existingCurr = &existing.InitContainers[j] - break - } - } - if existingCurr == nil { - *modified = true - existing.Containers = append(existing.InitContainers, corev1.Container{}) - existingCurr = &existing.InitContainers[len(existing.InitContainers)-1] - } - ensureContainer(modified, existingCurr, required) - } - - for _, required := range required.Containers { - var existingCurr *corev1.Container - for j, curr := range existing.Containers { - if curr.Name == required.Name { - existingCurr = &existing.Containers[j] - break - } - } - if existingCurr == nil { - *modified = true - existing.Containers = append(existing.Containers, corev1.Container{}) - existingCurr = &existing.Containers[len(existing.Containers)-1] - } - ensureContainer(modified, existingCurr, required) - } + ensureContainers(modified, &existing.InitContainers, required.InitContainers) + ensureContainers(modified, &existing.Containers, required.Containers) // any volume we specify, we require. for _, required := range required.Volumes { @@ -91,6 +61,37 @@ func ensurePodSpec(modified *bool, existing *corev1.PodSpec, required corev1.Pod setInt32Ptr(modified, &existing.Priority, required.Priority) } +func ensureContainers(modified *bool, existing *[]corev1.Container, required []corev1.Container) { + for i, existingContainer := range *existing { + var existingCurr *corev1.Container + for _, requiredContainer := range required { + if existingContainer.Name == requiredContainer.Name { + existingCurr = &(*existing)[i] + ensureContainer(modified, existingCurr, requiredContainer) + break + } + } + if existingCurr == nil { + *modified = true + *existing = append((*existing)[:i], (*existing)[i+1:]...) + } + } + + for _, requiredContainer := range required { + match := false + for _, existingContainer := range *existing { + if existingContainer.Name == requiredContainer.Name { + match = true + break + } + } + if !match { + *modified = true + *existing = append(*existing, requiredContainer) + } + } +} + func ensureContainer(modified *bool, existing *corev1.Container, required corev1.Container) { setStringIfSet(modified, &existing.Name, required.Name) setStringIfSet(modified, &existing.Image, required.Image)