Skip to content

Commit

Permalink
Do not overwrite kapp deploy status during delete
Browse files Browse the repository at this point in the history
Signed-off-by: Praveen Rewar <[email protected]>
  • Loading branch information
praveenrewar committed Jan 23, 2024
1 parent df87efd commit 86734c2
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 7 deletions.
20 changes: 13 additions & 7 deletions pkg/app/app_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,14 @@ func (a *App) updateLastDeploy(result exec.CmdRunResult) exec.CmdRunResult {
result = result.WithFriendlyYAMLStrings()

a.app.Status.Deploy = &v1alpha1.AppStatusDeploy{
Stdout: result.Stdout,
Stderr: result.Stderr,
Finished: result.Finished,
ExitCode: result.ExitCode,
Error: result.ErrorStr(),
StartedAt: a.app.Status.Deploy.StartedAt,
UpdatedAt: metav1.NewTime(time.Now().UTC()),
Stdout: result.Stdout,
Stderr: result.Stderr,
Finished: result.Finished,
ExitCode: result.ExitCode,
Error: result.ErrorStr(),
StartedAt: a.app.Status.Deploy.StartedAt,
UpdatedAt: metav1.NewTime(time.Now().UTC()),
KappDeployStatus: a.app.Status.Deploy.KappDeployStatus,
}

defer a.updateStatus("marking last deploy")
Expand All @@ -188,6 +189,11 @@ func (a *App) updateLastDeploy(result exec.CmdRunResult) exec.CmdRunResult {
})
}

// Do not overwrite kapp deploy status during delete
if len(a.metadata.LastChange.Namespaces) == 0 {
return result
}

a.app.Status.Deploy.KappDeployStatus = &v1alpha1.KappDeployStatus{
AssociatedResources: v1alpha1.AssociatedResources{
Label: fmt.Sprintf("%s=%s", a.metadata.LabelKey, a.metadata.LabelValue),
Expand Down
90 changes: 90 additions & 0 deletions test/e2e/kappcontroller/namespace_deletion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/vmware-tanzu/carvel-kapp-controller/test/e2e"
)

Expand Down Expand Up @@ -292,3 +293,92 @@ spec:
assert.Error(t, err, "Expected to get time out error, but did not")
})
}

func Test_NamespaceDelete_AppWithResourcesInOutOfOrderTerminatingNamespaces(t *testing.T) {
env := e2e.BuildEnv(t)
logger := e2e.Logger{}
kapp := e2e.Kapp{t, env.Namespace, logger}
kubectl := e2e.Kubectl{t, env.Namespace, logger}

nsName1 := "ns-delete-1"
nsName2 := "ns-delete-2"
nsApp := "testnamespaces"
name := "resources-in-different-namespaces"

namespaceTemplate := `---
apiVersion: v1
kind: Namespace
metadata:
name: %v`
namespaceYAML := fmt.Sprintf(namespaceTemplate, nsName1) + "\n" + fmt.Sprintf(namespaceTemplate, nsName2)

appYaml := fmt.Sprintf(`---
apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
name: %s
spec:
serviceAccountName: kappctrl-e2e-ns-sa
fetch:
- inline:
paths:
file.yml: |
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap
namespace: %s
data:
key: value
---
apiVersion: v1
kind: ConfigMap
metadata:
finalizers
- kubernetes // Add finalizer so that it doesn't get deleted until we want
name: configmap
namespace: %s
data:
key: value
template:
- ytt: {}
deploy:
- kapp: {}`, name, nsName1, nsName2) + e2e.ServiceAccounts{nsName1}.ForClusterYAML()

cleanUp := func() {
kapp.Run([]string{"delete", "-a", name})
}

cleanUpTestNamespace := func() {
kapp.Run([]string{"delete", "-a", name})
kapp.Run([]string{"delete", "-a", nsApp})
}

cleanUp()
defer cleanUp()
defer cleanUpTestNamespace()

logger.Section("create namespace and deploy App", func() {
kapp.RunWithOpts([]string{"deploy", "-a", nsApp, "-f", "-"}, e2e.RunOpts{StdinReader: strings.NewReader(namespaceYAML)})
kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", name, "--into-ns", nsName1}, e2e.RunOpts{StdinReader: strings.NewReader(appYaml)})
})

logger.Section("delete namespace", func() {
// Deletion should timeout as test-ns-2 is not being terminated and the cm present in it has a finalizer
_, err := kubectl.RunWithOpts([]string{"delete", "ns", nsName1, nsName2, "--timeout=30s"}, e2e.RunOpts{AllowError: true})
require.Error(t, err, "Expected to timeout")

// At this point the service account should be deleted,
// so removing the finalizer on cm in test-ns-2 wouldn't help
kubectl.RunWithOpts([]string{"patch", "cm", "configmap", "--type=json", "--patch", `[{ "op": "remove", "path": "/metadata/finalizers"}]`,
"-n", nsName2}, e2e.RunOpts{NoNamespace: true})

kubectl.RunWithOpts([]string{"get", "App", name, "-n", "test-ns-1"}, e2e.RunOpts{NoNamespace: true})

// Deleting the second namespace now should do a noop delete for the App
kubectl.RunWithOpts([]string{"delete", "ns", "test-ns-1"}, e2e.RunOpts{NoNamespace: true})

_, err = kubectl.RunWithOpts([]string{"get", "App", name, "-n", "test-ns-1"}, e2e.RunOpts{NoNamespace: true, AllowError: true})
require.Error(t, err, "Expected not found error")
})
}

0 comments on commit 86734c2

Please sign in to comment.