Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not overwrite kapp deploy status during delete #1460

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -181,6 +182,11 @@ func (a *App) updateLastDeploy(result exec.CmdRunResult) exec.CmdRunResult {
return result
}

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

usedGKs := []metav1.GroupKind{}
for _, gk := range a.metadata.UsedGKs {
usedGKs = append(usedGKs, metav1.GroupKind{
Expand Down
96 changes: 96 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,98 @@ 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
name: configmap
namespace: %s
data:
key: value
template:
- ytt: {}
deploy:
- kapp:
delete:
rawOptions: ["--wait-timeout=2s"]`, 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() {
// Deleting the namespace directly could delete the service account, so let's delete the App first
_, err := kubectl.RunWithOpts([]string{"delete", "app", name, "-n", nsName1, "--timeout=10s"}, e2e.RunOpts{AllowError: true, NoNamespace: true})
require.Error(t, err, "Expected to timeout")

// 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, "--timeout=10s"}, e2e.RunOpts{AllowError: true, NoNamespace: 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", nsName1}, e2e.RunOpts{NoNamespace: true})

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

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