diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 502b1cd6..d8c081bd 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -372,295 +372,295 @@ }, { "ImportPath": "k8s.io/api/admissionregistration/v1alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/apps/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/apps/v1beta2", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/authentication/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/authentication/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/authorization/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/authorization/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/autoscaling/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/autoscaling/v2alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/batch/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/batch/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/batch/v2alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/certificates/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/core/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/extensions/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/imagepolicy/v1alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/networking/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/policy/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/rbac/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/rbac/v1alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/rbac/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/scheduling/v1alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/settings/v1alpha1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/storage/v1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/api/storage/v1beta1", - "Rev": "21998e7d64f3b177d533268cfb312523e1d53038" + "Rev": "429a9e49c4fef512e68dc11e3ce5da5e79d88ffd" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/equality", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/meta", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/resource", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/apimachinery", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/labels", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/selection", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/types", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/cache", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/clock", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/diff", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/errors", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/framer", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/intstr", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/json", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/net", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/runtime", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/sets", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/wait", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/yaml", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/version", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/pkg/watch", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", - "Rev": "b0b038663fc082407b3c34033ddc9747f701b12e" + "Rev": "429c5e743dc2bf27fc89e2d0c56dec9c3bc03859" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", diff --git a/tools/cache/BUILD b/tools/cache/BUILD index e79cce62..3531eba7 100644 --- a/tools/cache/BUILD +++ b/tools/cache/BUILD @@ -63,6 +63,7 @@ go_library( ], deps = [ "//vendor/github.com/golang/glog:go_default_library", + "//vendor/golang.org/x/net/context:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -79,6 +80,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", + "//vendor/k8s.io/client-go/tools/pager:go_default_library", ], ) diff --git a/tools/cache/listwatch.go b/tools/cache/listwatch.go index 4c976533..cab48ae0 100644 --- a/tools/cache/listwatch.go +++ b/tools/cache/listwatch.go @@ -19,12 +19,15 @@ package cache import ( "time" + "golang.org/x/net/context" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/pager" ) // ListerWatcher is any object that knows how to perform an initial list and start a watch on a resource. @@ -46,8 +49,9 @@ type WatchFunc func(options metav1.ListOptions) (watch.Interface, error) // It is a convenience function for users of NewReflector, etc. // ListFunc and WatchFunc must not be nil type ListWatch struct { - ListFunc ListFunc - WatchFunc WatchFunc + ListFunc ListFunc + WatchFunc WatchFunc + DisablePaging bool } // Getter interface knows how to access Get method from RESTClient. @@ -87,6 +91,9 @@ func timeoutFromListOptions(options metav1.ListOptions) time.Duration { // List a set of apiserver resources func (lw *ListWatch) List(options metav1.ListOptions) (runtime.Object, error) { + if !lw.DisablePaging { + return pager.New(pager.SimplePageFunc(lw.ListFunc)).List(context.TODO(), options) + } return lw.ListFunc(options) } diff --git a/tools/pager/BUILD b/tools/pager/BUILD new file mode 100644 index 00000000..fa07ba8c --- /dev/null +++ b/tools/pager/BUILD @@ -0,0 +1,36 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", +) + +go_library( + name = "go_default_library", + srcs = ["pager.go"], + tags = ["automanaged"], + deps = [ + "//vendor/golang.org/x/net/context:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/tools/pager/pager.go b/tools/pager/pager.go new file mode 100644 index 00000000..a4a04cdc --- /dev/null +++ b/tools/pager/pager.go @@ -0,0 +1,114 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pager + +import ( + "fmt" + + "golang.org/x/net/context" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const defaultPageSize = 500 + +// ListPageFunc returns a list object for the given list options. +type ListPageFunc func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) + +// SimplePageFunc adapts a context-less list function into one that accepts a context. +func SimplePageFunc(fn func(opts metav1.ListOptions) (runtime.Object, error)) ListPageFunc { + return func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + return fn(opts) + } +} + +// ListPager assists client code in breaking large list queries into multiple +// smaller chunks of PageSize or smaller. PageFn is expected to accept a +// metav1.ListOptions that supports paging and return a list. The pager does +// not alter the field or label selectors on the initial options list. +type ListPager struct { + PageSize int64 + PageFn ListPageFunc + + FullListIfExpired bool +} + +// New creates a new pager from the provided pager function using the default +// options. +func New(fn ListPageFunc) *ListPager { + return &ListPager{ + PageSize: defaultPageSize, + PageFn: fn, + FullListIfExpired: true, + } +} + +// List returns a single list object, but attempts to retrieve smaller chunks from the +// server to reduce the impact on the server. If the chunk attempt fails, it will load +// the full list instead. +func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + if options.Limit == 0 { + options.Limit = p.PageSize + } + var list *metainternalversion.List + for { + obj, err := p.PageFn(ctx, options) + if err != nil { + if !errors.IsResourceExpired(err) || !p.FullListIfExpired { + return nil, err + } + // the list expired while we were processing, fall back to a full list + options.Limit = 0 + options.Continue = "" + return p.PageFn(ctx, options) + } + m, err := meta.ListAccessor(obj) + if err != nil { + return nil, fmt.Errorf("returned object must be a list: %v", err) + } + + // exit early and return the object we got if we haven't processed any pages + if len(m.GetContinue()) == 0 && list == nil { + return obj, nil + } + + // initialize the list and fill its contents + if list == nil { + list = &metainternalversion.List{Items: make([]runtime.Object, 0, options.Limit+1)} + list.ResourceVersion = m.GetResourceVersion() + list.SelfLink = m.GetSelfLink() + } + if err := meta.EachListItem(obj, func(obj runtime.Object) error { + list.Items = append(list.Items, obj) + return nil + }); err != nil { + return nil, err + } + + // if we have no more items, return the list + if len(m.GetContinue()) == 0 { + return list, nil + } + + // set the next loop up + options.Continue = m.GetContinue() + } +}