diff --git a/pkg/kube/statuswait.go b/pkg/kube/statuswait.go index b1c39948c..bb92ae74e 100644 --- a/pkg/kube/statuswait.go +++ b/pkg/kube/statuswait.go @@ -75,6 +75,7 @@ func (w *statusWaiter) waitForDelete(ctx context.Context, resourceList ResourceL } eventCh := w.sw.Watch(cancelCtx, resources, watcher.Options{}) statusCollector := collector.NewResourceStatusCollector(resources) + go logResource(ctx, resources, statusCollector, status.NotFoundStatus, w.log) done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.NotFoundStatus)) <-done @@ -127,6 +128,7 @@ func (w *statusWaiter) wait(ctx context.Context, resourceList ResourceList, wait } eventCh := w.sw.Watch(cancelCtx, resources, watcher.Options{}) statusCollector := collector.NewResourceStatusCollector(resources) + go logResource(cancelCtx, resources, statusCollector, status.CurrentStatus, w.log) done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.CurrentStatus)) <-done @@ -165,3 +167,23 @@ func statusObserver(cancel context.CancelFunc, desired status.Status) collector. } } } + +func logResource(ctx context.Context, resources []object.ObjMetadata, sc *collector.ResourceStatusCollector, desiredStatus status.Status, log func(string, ...interface{})) { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + for _, id := range resources { + rs := sc.ResourceStatuses[id] + if rs.Status != desiredStatus { + log("waiting for resource, name: %s, kind: %s, desired status: %s, actual status: %s\n", rs.Identifier.Name, rs.Identifier.GroupKind.Kind, desiredStatus, rs.Status) + // only log one resource to not overwhelm the logs + break + } + } + } + } +} diff --git a/pkg/kube/statuswait_test.go b/pkg/kube/statuswait_test.go index 0084606cf..0d635ad79 100644 --- a/pkg/kube/statuswait_test.go +++ b/pkg/kube/statuswait_test.go @@ -19,6 +19,7 @@ package kube // import "helm.sh/helm/v3/pkg/kube" import ( "context" "errors" + "fmt" "testing" "time" @@ -114,6 +115,9 @@ func getGVR(t *testing.T, mapper meta.RESTMapper, obj *unstructured.Unstructured require.NoError(t, err) return mapping.Resource } +func testLogger(message string, args ...interface{}) { + fmt.Printf(message, args...) +} func TestStatusWaitForDelete(t *testing.T) { t.Parallel() @@ -151,7 +155,7 @@ func TestStatusWaitForDelete(t *testing.T) { statusWatcher := watcher.NewDefaultStatusWatcher(fakeClient, fakeMapper) statusWaiter := statusWaiter{ sw: statusWatcher, - log: t.Logf, + log: testLogger, } createdObjs := []runtime.Object{} for _, objYaml := range tt.objToCreate { @@ -248,7 +252,7 @@ func TestStatusWait(t *testing.T) { statusWatcher := watcher.NewDefaultStatusWatcher(fakeClient, fakeMapper) statusWaiter := statusWaiter{ sw: statusWatcher, - log: t.Logf, + log: testLogger, } objs := []runtime.Object{}