rebase: update controller-runtime

update controller-runtime to latest
release.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2024-08-19 10:02:11 +02:00
committed by mergify[bot]
parent 5a66991bb3
commit dbbca6ebf8
28 changed files with 739 additions and 361 deletions

View File

@ -28,6 +28,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
internal "sigs.k8s.io/controller-runtime/pkg/internal/source"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/predicate"
@ -41,45 +42,74 @@ import (
// * Use Channel for events originating outside the cluster (e.g. GitHub Webhook callback, Polling external urls).
//
// Users may build their own Source implementations.
type Source interface {
// Start is internal and should be called only by the Controller to register an EventHandler with the Informer
// to enqueue reconcile.Requests.
Start(context.Context, workqueue.RateLimitingInterface) error
type Source = TypedSource[reconcile.Request]
// TypedSource is a generic source of events (e.g. Create, Update, Delete operations on Kubernetes Objects, Webhook callbacks, etc)
// which should be processed by event.EventHandlers to enqueue a request.
//
// * Use Kind for events originating in the cluster (e.g. Pod Create, Pod Update, Deployment Update).
//
// * Use Channel for events originating outside the cluster (e.g. GitHub Webhook callback, Polling external urls).
//
// Users may build their own Source implementations.
type TypedSource[request comparable] interface {
// Start is internal and should be called only by the Controller to start the source.
// Start must be non-blocking.
Start(context.Context, workqueue.TypedRateLimitingInterface[request]) error
}
// SyncingSource is a source that needs syncing prior to being usable. The controller
// will call its WaitForSync prior to starting workers.
type SyncingSource interface {
Source
type SyncingSource = TypedSyncingSource[reconcile.Request]
// TypedSyncingSource is a source that needs syncing prior to being usable. The controller
// will call its WaitForSync prior to starting workers.
type TypedSyncingSource[request comparable] interface {
TypedSource[request]
WaitForSync(ctx context.Context) error
}
// Kind creates a KindSource with the given cache provider.
func Kind[T client.Object](cache cache.Cache, object T, handler handler.TypedEventHandler[T], predicates ...predicate.TypedPredicate[T]) SyncingSource {
return &internal.Kind[T]{
Type: object,
func Kind[object client.Object](
cache cache.Cache,
obj object,
handler handler.TypedEventHandler[object, reconcile.Request],
predicates ...predicate.TypedPredicate[object],
) SyncingSource {
return TypedKind(cache, obj, handler, predicates...)
}
// TypedKind creates a KindSource with the given cache provider.
func TypedKind[object client.Object, request comparable](
cache cache.Cache,
obj object,
handler handler.TypedEventHandler[object, request],
predicates ...predicate.TypedPredicate[object],
) TypedSyncingSource[request] {
return &internal.Kind[object, request]{
Type: obj,
Cache: cache,
Handler: handler,
Predicates: predicates,
}
}
var _ Source = &channel[string]{}
var _ Source = &channel[string, reconcile.Request]{}
// ChannelOpt allows to configure a source.Channel.
type ChannelOpt[T any] func(*channel[T])
type ChannelOpt[object any, request comparable] func(*channel[object, request])
// WithPredicates adds the configured predicates to a source.Channel.
func WithPredicates[T any](p ...predicate.TypedPredicate[T]) ChannelOpt[T] {
return func(c *channel[T]) {
func WithPredicates[object any, request comparable](p ...predicate.TypedPredicate[object]) ChannelOpt[object, request] {
return func(c *channel[object, request]) {
c.predicates = append(c.predicates, p...)
}
}
// WithBufferSize configures the buffer size for a source.Channel. By
// default, the buffer size is 1024.
func WithBufferSize[T any](bufferSize int) ChannelOpt[T] {
return func(c *channel[T]) {
func WithBufferSize[object any, request comparable](bufferSize int) ChannelOpt[object, request] {
return func(c *channel[object, request]) {
c.bufferSize = &bufferSize
}
}
@ -87,8 +117,23 @@ func WithBufferSize[T any](bufferSize int) ChannelOpt[T] {
// Channel is used to provide a source of events originating outside the cluster
// (e.g. GitHub Webhook callback). Channel requires the user to wire the external
// source (e.g. http handler) to write GenericEvents to the underlying channel.
func Channel[T any](source <-chan event.TypedGenericEvent[T], handler handler.TypedEventHandler[T], opts ...ChannelOpt[T]) Source {
c := &channel[T]{
func Channel[object any](
source <-chan event.TypedGenericEvent[object],
handler handler.TypedEventHandler[object, reconcile.Request],
opts ...ChannelOpt[object, reconcile.Request],
) Source {
return TypedChannel[object, reconcile.Request](source, handler, opts...)
}
// TypedChannel is used to provide a source of events originating outside the cluster
// (e.g. GitHub Webhook callback). Channel requires the user to wire the external
// source (e.g. http handler) to write GenericEvents to the underlying channel.
func TypedChannel[object any, request comparable](
source <-chan event.TypedGenericEvent[object],
handler handler.TypedEventHandler[object, request],
opts ...ChannelOpt[object, request],
) TypedSource[request] {
c := &channel[object, request]{
source: source,
handler: handler,
}
@ -99,34 +144,34 @@ func Channel[T any](source <-chan event.TypedGenericEvent[T], handler handler.Ty
return c
}
type channel[T any] struct {
type channel[object any, request comparable] struct {
// once ensures the event distribution goroutine will be performed only once
once sync.Once
// source is the source channel to fetch GenericEvents
source <-chan event.TypedGenericEvent[T]
source <-chan event.TypedGenericEvent[object]
handler handler.TypedEventHandler[T]
handler handler.TypedEventHandler[object, request]
predicates []predicate.TypedPredicate[T]
predicates []predicate.TypedPredicate[object]
bufferSize *int
// dest is the destination channels of the added event handlers
dest []chan event.TypedGenericEvent[T]
dest []chan event.TypedGenericEvent[object]
// destLock is to ensure the destination channels are safely added/removed
destLock sync.Mutex
}
func (cs *channel[T]) String() string {
func (cs *channel[object, request]) String() string {
return fmt.Sprintf("channel source: %p", cs)
}
// Start implements Source and should only be called by the Controller.
func (cs *channel[T]) Start(
func (cs *channel[object, request]) Start(
ctx context.Context,
queue workqueue.RateLimitingInterface,
queue workqueue.TypedRateLimitingInterface[request],
) error {
// Source should have been specified by the user.
if cs.source == nil {
@ -140,7 +185,7 @@ func (cs *channel[T]) Start(
cs.bufferSize = ptr.To(1024)
}
dst := make(chan event.TypedGenericEvent[T], *cs.bufferSize)
dst := make(chan event.TypedGenericEvent[object], *cs.bufferSize)
cs.destLock.Lock()
cs.dest = append(cs.dest, dst)
@ -174,7 +219,7 @@ func (cs *channel[T]) Start(
return nil
}
func (cs *channel[T]) doStop() {
func (cs *channel[object, request]) doStop() {
cs.destLock.Lock()
defer cs.destLock.Unlock()
@ -183,7 +228,7 @@ func (cs *channel[T]) doStop() {
}
}
func (cs *channel[T]) distribute(evt event.TypedGenericEvent[T]) {
func (cs *channel[object, request]) distribute(evt event.TypedGenericEvent[object]) {
cs.destLock.Lock()
defer cs.destLock.Unlock()
@ -197,7 +242,7 @@ func (cs *channel[T]) distribute(evt event.TypedGenericEvent[T]) {
}
}
func (cs *channel[T]) syncLoop(ctx context.Context) {
func (cs *channel[object, request]) syncLoop(ctx context.Context) {
for {
select {
case <-ctx.Done():
@ -228,7 +273,7 @@ var _ Source = &Informer{}
// Start is internal and should be called only by the Controller to register an EventHandler with the Informer
// to enqueue reconcile.Requests.
func (is *Informer) Start(ctx context.Context, queue workqueue.RateLimitingInterface) error {
func (is *Informer) Start(ctx context.Context, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) error {
// Informer should have been specified by the user.
if is.Informer == nil {
return fmt.Errorf("must specify Informer.Informer")
@ -251,13 +296,16 @@ func (is *Informer) String() string {
var _ Source = Func(nil)
// Func is a function that implements Source.
type Func func(context.Context, workqueue.RateLimitingInterface) error
type Func = TypedFunc[reconcile.Request]
// TypedFunc is a function that implements Source.
type TypedFunc[request comparable] func(context.Context, workqueue.TypedRateLimitingInterface[request]) error
// Start implements Source.
func (f Func) Start(ctx context.Context, queue workqueue.RateLimitingInterface) error {
func (f TypedFunc[request]) Start(ctx context.Context, queue workqueue.TypedRateLimitingInterface[request]) error {
return f(ctx, queue)
}
func (f Func) String() string {
func (f TypedFunc[request]) String() string {
return fmt.Sprintf("func source: %p", f)
}