diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index f6eb39e92..0b32bd53a 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -20,21 +20,21 @@ set -o pipefail source $(dirname $0)/../vendor/knative.dev/hack/codegen-library.sh -# If we run with -mod=vendor here, then generate-groups.sh looks for vendor files in the wrong place. -export GOFLAGS=-mod= - echo "=== Update Codegen for $MODULE_NAME" group "Kubernetes Codegen" - -# generate the code with: -# --output-base because this script should also be able to run inside the vendor dir of -# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir -# instead of the $GOPATH directly. For normal projects this can be dropped. -${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ - knative.dev/caching/pkg/client knative.dev/caching/pkg/apis \ - "caching:v1alpha1" \ - --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt +source "${CODEGEN_PKG}/kube_codegen.sh" + +kube::codegen::gen_client \ + --boilerplate "${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt" \ + --output-dir "${REPO_ROOT_DIR}/pkg/client" \ + --output-pkg "knative.dev/caching/pkg/client" \ + --with-watch \ + "${REPO_ROOT_DIR}/pkg/apis" + +kube::codegen::gen_helpers \ + --boilerplate "${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt" \ + "${REPO_ROOT_DIR}/pkg" group "Knative Codegen" diff --git a/hack/update-schemas.sh b/hack/update-schemas.sh index 38ae92538..0f131c4b8 100755 --- a/hack/update-schemas.sh +++ b/hack/update-schemas.sh @@ -20,7 +20,7 @@ set -o pipefail REPO_ROOT="$(git rev-parse --show-toplevel)" -go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.17.0 \ +go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.17.1 \ schemapatch:manifests=config/,generateEmbeddedObjectMeta=false \ output:dir=config \ paths=./pkg/apis/... diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 5baab0f63..84a9fc1c6 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -31,8 +31,12 @@ import ( // NewSimpleClientset returns a clientset that will respond with the provided objects. // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, -// without applying any validations and/or defaults. It shouldn't be considered a replacement +// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// DEPRECATED: NewClientset replaces this with support for field management, which significantly improves +// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. +// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { diff --git a/pkg/client/clientset/versioned/typed/caching/v1alpha1/fake/fake_image.go b/pkg/client/clientset/versioned/typed/caching/v1alpha1/fake/fake_image.go index ebdc12080..417e85a88 100644 --- a/pkg/client/clientset/versioned/typed/caching/v1alpha1/fake/fake_image.go +++ b/pkg/client/clientset/versioned/typed/caching/v1alpha1/fake/fake_image.go @@ -41,22 +41,24 @@ var imagesKind = v1alpha1.SchemeGroupVersion.WithKind("Image") // Get takes name of the image, and returns the corresponding image object, and an error if there is any. func (c *FakeImages) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Image, err error) { + emptyResult := &v1alpha1.Image{} obj, err := c.Fake. - Invokes(testing.NewGetAction(imagesResource, c.ns, name), &v1alpha1.Image{}) + Invokes(testing.NewGetActionWithOptions(imagesResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Image), err } // List takes label and field selectors, and returns the list of Images that match those selectors. func (c *FakeImages) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ImageList, err error) { + emptyResult := &v1alpha1.ImageList{} obj, err := c.Fake. - Invokes(testing.NewListAction(imagesResource, imagesKind, c.ns, opts), &v1alpha1.ImageList{}) + Invokes(testing.NewListActionWithOptions(imagesResource, imagesKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -75,40 +77,43 @@ func (c *FakeImages) List(ctx context.Context, opts v1.ListOptions) (result *v1a // Watch returns a watch.Interface that watches the requested images. func (c *FakeImages) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(imagesResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(imagesResource, c.ns, opts)) } // Create takes the representation of a image and creates it. Returns the server's representation of the image, and an error, if there is any. func (c *FakeImages) Create(ctx context.Context, image *v1alpha1.Image, opts v1.CreateOptions) (result *v1alpha1.Image, err error) { + emptyResult := &v1alpha1.Image{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(imagesResource, c.ns, image), &v1alpha1.Image{}) + Invokes(testing.NewCreateActionWithOptions(imagesResource, c.ns, image, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Image), err } // Update takes the representation of a image and updates it. Returns the server's representation of the image, and an error, if there is any. func (c *FakeImages) Update(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (result *v1alpha1.Image, err error) { + emptyResult := &v1alpha1.Image{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(imagesResource, c.ns, image), &v1alpha1.Image{}) + Invokes(testing.NewUpdateActionWithOptions(imagesResource, c.ns, image, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Image), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeImages) UpdateStatus(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (*v1alpha1.Image, error) { +func (c *FakeImages) UpdateStatus(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (result *v1alpha1.Image, err error) { + emptyResult := &v1alpha1.Image{} obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(imagesResource, "status", c.ns, image), &v1alpha1.Image{}) + Invokes(testing.NewUpdateSubresourceActionWithOptions(imagesResource, "status", c.ns, image, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Image), err } @@ -123,7 +128,7 @@ func (c *FakeImages) Delete(ctx context.Context, name string, opts v1.DeleteOpti // DeleteCollection deletes a collection of objects. func (c *FakeImages) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(imagesResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(imagesResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.ImageList{}) return err @@ -131,11 +136,12 @@ func (c *FakeImages) DeleteCollection(ctx context.Context, opts v1.DeleteOptions // Patch applies the patch and returns the patched image. func (c *FakeImages) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Image, err error) { + emptyResult := &v1alpha1.Image{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(imagesResource, c.ns, name, pt, data, subresources...), &v1alpha1.Image{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(imagesResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Image), err } diff --git a/pkg/client/clientset/versioned/typed/caching/v1alpha1/image.go b/pkg/client/clientset/versioned/typed/caching/v1alpha1/image.go index 73ce9c4f3..b3d5f15d8 100644 --- a/pkg/client/clientset/versioned/typed/caching/v1alpha1/image.go +++ b/pkg/client/clientset/versioned/typed/caching/v1alpha1/image.go @@ -20,12 +20,11 @@ package v1alpha1 import ( "context" - "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" v1alpha1 "knative.dev/caching/pkg/apis/caching/v1alpha1" scheme "knative.dev/caching/pkg/client/clientset/versioned/scheme" ) @@ -40,6 +39,7 @@ type ImagesGetter interface { type ImageInterface interface { Create(ctx context.Context, image *v1alpha1.Image, opts v1.CreateOptions) (*v1alpha1.Image, error) Update(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (*v1alpha1.Image, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). UpdateStatus(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (*v1alpha1.Image, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error @@ -52,144 +52,18 @@ type ImageInterface interface { // images implements ImageInterface type images struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.Image, *v1alpha1.ImageList] } // newImages returns a Images func newImages(c *CachingV1alpha1Client, namespace string) *images { return &images{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.Image, *v1alpha1.ImageList]( + "images", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.Image { return &v1alpha1.Image{} }, + func() *v1alpha1.ImageList { return &v1alpha1.ImageList{} }), } } - -// Get takes name of the image, and returns the corresponding image object, and an error if there is any. -func (c *images) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Image, err error) { - result = &v1alpha1.Image{} - err = c.client.Get(). - Namespace(c.ns). - Resource("images"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of Images that match those selectors. -func (c *images) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ImageList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.ImageList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("images"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested images. -func (c *images) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("images"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a image and creates it. Returns the server's representation of the image, and an error, if there is any. -func (c *images) Create(ctx context.Context, image *v1alpha1.Image, opts v1.CreateOptions) (result *v1alpha1.Image, err error) { - result = &v1alpha1.Image{} - err = c.client.Post(). - Namespace(c.ns). - Resource("images"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(image). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a image and updates it. Returns the server's representation of the image, and an error, if there is any. -func (c *images) Update(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (result *v1alpha1.Image, err error) { - result = &v1alpha1.Image{} - err = c.client.Put(). - Namespace(c.ns). - Resource("images"). - Name(image.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(image). - Do(ctx). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *images) UpdateStatus(ctx context.Context, image *v1alpha1.Image, opts v1.UpdateOptions) (result *v1alpha1.Image, err error) { - result = &v1alpha1.Image{} - err = c.client.Put(). - Namespace(c.ns). - Resource("images"). - Name(image.Name). - SubResource("status"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(image). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the image and deletes it. Returns an error if one occurs. -func (c *images) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("images"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *images) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("images"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched image. -func (c *images) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Image, err error) { - result = &v1alpha1.Image{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("images"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 0d9ea91d6..e87ddeb2e 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -228,6 +228,7 @@ type SharedInformerFactory interface { // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. + // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. Start(stopCh <-chan struct{}) // Shutdown marks a factory as shutting down. At that point no new diff --git a/pkg/client/listers/caching/v1alpha1/image.go b/pkg/client/listers/caching/v1alpha1/image.go index c4b190523..196643e3e 100644 --- a/pkg/client/listers/caching/v1alpha1/image.go +++ b/pkg/client/listers/caching/v1alpha1/image.go @@ -19,8 +19,8 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" v1alpha1 "knative.dev/caching/pkg/apis/caching/v1alpha1" ) @@ -38,25 +38,17 @@ type ImageLister interface { // imageLister implements the ImageLister interface. type imageLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.Image] } // NewImageLister returns a new ImageLister. func NewImageLister(indexer cache.Indexer) ImageLister { - return &imageLister{indexer: indexer} -} - -// List lists all Images in the indexer. -func (s *imageLister) List(selector labels.Selector) (ret []*v1alpha1.Image, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Image)) - }) - return ret, err + return &imageLister{listers.New[*v1alpha1.Image](indexer, v1alpha1.Resource("image"))} } // Images returns an object that can list and get Images. func (s *imageLister) Images(namespace string) ImageNamespaceLister { - return imageNamespaceLister{indexer: s.indexer, namespace: namespace} + return imageNamespaceLister{listers.NewNamespaced[*v1alpha1.Image](s.ResourceIndexer, namespace)} } // ImageNamespaceLister helps list and get Images. @@ -74,26 +66,5 @@ type ImageNamespaceLister interface { // imageNamespaceLister implements the ImageNamespaceLister // interface. type imageNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Images in the indexer for a given namespace. -func (s imageNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Image, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Image)) - }) - return ret, err -} - -// Get retrieves the Image from the indexer for a given namespace and name. -func (s imageNamespaceLister) Get(name string) (*v1alpha1.Image, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("image"), name) - } - return obj.(*v1alpha1.Image), nil + listers.ResourceIndexer[*v1alpha1.Image] }