diff --git a/docs/gitbook/usage/how-it-works.md b/docs/gitbook/usage/how-it-works.md index e534f24a..4fa93086 100644 --- a/docs/gitbook/usage/how-it-works.md +++ b/docs/gitbook/usage/how-it-works.md @@ -264,6 +264,7 @@ The recommended approach to disable canary analysis would be utilization of the attribute, which limits the need for resource reconciliation. Utilizing the `revertOnDeletion` attribute should be enabled when you no longer plan to rely on Flagger for deployment management. +**Note** When this feature is enabled expect a delay in the delete action due to the reconciliation. ### Canary analysis diff --git a/pkg/canary/daemonset_controller.go b/pkg/canary/daemonset_controller.go index d52f5d34..2bbcf57a 100644 --- a/pkg/canary/daemonset_controller.go +++ b/pkg/canary/daemonset_controller.go @@ -297,6 +297,11 @@ func (c *DaemonSetController) HaveDependenciesChanged(cd *flaggerv1.Canary) (boo return c.configTracker.HasConfigChanged(cd) } +//Finalize scale the reference instance from zero func (c *DaemonSetController) Finalize(cd *flaggerv1.Canary) error { + + if err := c.ScaleFromZero(cd); err != nil { + return err + } return nil } diff --git a/pkg/canary/daemonset_controller_test.go b/pkg/canary/daemonset_controller_test.go index 0222a710..3899b163 100644 --- a/pkg/canary/daemonset_controller_test.go +++ b/pkg/canary/daemonset_controller_test.go @@ -194,3 +194,19 @@ func TestDaemonSetController_Scale(t *testing.T) { } }) } + +func TestDaemonSetController_Finalize(t *testing.T) { + mocks := newDaemonSetFixture() + err := mocks.controller.Initialize(mocks.canary, true) + require.NoError(t, err) + + err = mocks.controller.Finalize(mocks.canary) + require.NoError(t, err) + + dep, err := mocks.kubeClient.AppsV1().DaemonSets("default").Get("podinfo", metav1.GetOptions{}) + require.NoError(t, err) + + _, ok := dep.Spec.Template.Spec.NodeSelector["flagger.app/scale-to-zero"] + + assert.False(t, ok) +} diff --git a/pkg/canary/deployment_controller_test.go b/pkg/canary/deployment_controller_test.go index 9ef5e312..ed0aee50 100644 --- a/pkg/canary/deployment_controller_test.go +++ b/pkg/canary/deployment_controller_test.go @@ -189,7 +189,7 @@ func TestDeploymentController_HasTargetChanged(t *testing.T) { assert.True(t, isNew) } -func TestCanaryDeployer_Finalize(t *testing.T) { +func TestDeploymentController_Finalize(t *testing.T) { mocks := newDeploymentFixture() diff --git a/pkg/controller/finalizer.go b/pkg/controller/finalizer.go index d3f76bf4..3c631026 100644 --- a/pkg/controller/finalizer.go +++ b/pkg/controller/finalizer.go @@ -23,6 +23,13 @@ func (c *Controller) finalize(old interface{}) error { return nil } + _, err := c.flaggerClient.FlaggerV1beta1().Canaries(r.Namespace).Get(r.Name, metav1.GetOptions{}) + if err != nil { + c.logger.With("canary", fmt.Sprintf("%s.%s", r.Name, r.Namespace)). + Errorf("Canary %s.%s not found nothing to finalize", r.Name, r.Namespace) + return nil + } + //Retrieve a controller canaryController := c.canaryFactory.Controller(r.Spec.TargetRef.Kind) @@ -36,7 +43,7 @@ func (c *Controller) finalize(old interface{}) error { c.recordEventInfof(r, "Terminating canary %s.%s", r.Name, r.Namespace) } - err := c.revertTargetRef(canaryController, r) + err = c.revertTargetRef(canaryController, r) if err != nil { if errors.IsNotFound(err) { //No reason to wait not found diff --git a/test/e2e-kubernetes-tests-daemonset.sh b/test/e2e-kubernetes-tests-daemonset.sh index 443f4dfb..e5ab93c3 100755 --- a/test/e2e-kubernetes-tests-daemonset.sh +++ b/test/e2e-kubernetes-tests-daemonset.sh @@ -108,4 +108,92 @@ done echo '✔ Canary promotion test passed' + +cat <>> Waiting for finalizers to be present' +retries=50 +count=0 +ok=false +until ${ok}; do + kubectl get canary podinfo -n test -o jsonpath='{.metadata.finalizers}' | grep "finalizer.flagger.app" && ok=true || ok=false + sleep 10 + count=$(($count + 1)) + if [[ ${count} -eq ${retries} ]]; then + kubectl -n test describe canary/podinfo + echo "No more retries left" + exit 1 + fi +done + +kubectl delete canary podinfo -n test + +echo '>>> Waiting for primary to revert' +retries=50 +count=0 +ok=false +until ${ok}; do + kubectl get daemonset podinfo -n test -o jsonpath='{.status.numberReady}' | grep 1 && ok=true || ok=false + sleep 10 + kubectl -n flagger-system logs deployment/flagger --tail 1 + count=$(($count + 1)) + if [[ ${count} -eq ${retries} ]]; then + kubectl -n test describe canary/podinfo + echo "No more retries left" + exit 1 + fi +done + +echo '✔ Canary finalize passed' + kubectl -n flagger-system logs deployment/flagger