diff --git a/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go b/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go index dfa21157906..d15b15b4435 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go @@ -715,6 +715,10 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio listVal.Set(reflect.Append(listVal, reflect.ValueOf(elem.Object).Elem())) } } + if listVal.IsNil() { + // Ensure that we never return a nil Items pointer in the result for consistency. + listVal.Set(reflect.MakeSlice(listVal.Type(), 0, 0)) + } span.AddEvent("Filtered items", attribute.Int("count", listVal.Len())) if c.versioner != nil { if err := c.versioner.UpdateList(listObj, readResourceVersion, "", nil); err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go index 51e5b9012b9..463a84d7b91 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -782,6 +782,10 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption options = append(options, clientv3.WithRev(withRev)) } } + if v.IsNil() { + // Ensure that we never return a nil Items pointer in the result for consistency. + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } // instruct the client to begin querying from immediately after the last key we returned // we never return a key that the client wouldn't be allowed to see diff --git a/staging/src/k8s.io/apiserver/pkg/storage/testing/store_tests.go b/staging/src/k8s.io/apiserver/pkg/storage/testing/store_tests.go index f68a7df4fa5..075bd0d6748 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/testing/store_tests.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/testing/store_tests.go @@ -1088,13 +1088,13 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage name: "existing key, resourceVersion=0", key: key, pred: storage.Everything, - expectedAlternatives: [][]example.Pod{nil, {*storedObj}}, + expectedAlternatives: [][]example.Pod{{}, {*storedObj}}, rv: "0", }, { name: "existing key, resourceVersion=0, resourceVersionMatch=notOlderThan", key: key, pred: storage.Everything, - expectedAlternatives: [][]example.Pod{nil, {*storedObj}}, + expectedAlternatives: [][]example.Pod{{}, {*storedObj}}, rv: "0", rvMatch: metav1.ResourceVersionMatchNotOlderThan, }, { @@ -1142,7 +1142,7 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage name: "non-existing key", key: "/non-existing", pred: storage.Everything, - expectedOut: nil, + expectedOut: []example.Pod{}, }, { name: "with matching pod name", key: "/non-existing", @@ -1154,7 +1154,7 @@ func RunTestGetListNonRecursive(ctx context.Context, t *testing.T, store storage return nil, fields.Set{"metadata.name": pod.Name}, nil }, }, - expectedOut: nil, + expectedOut: []example.Pod{}, }} for _, tt := range tests {