Auto-update dependencies (#201)

Produced via:
  `dep ensure -update knative.dev/test-infra knative.dev/pkg`
/assign n3wscott
/cc n3wscott
This commit is contained in:
Matt Moore 2020-02-12 07:20:22 -08:00 committed by GitHub
parent fec8f79136
commit 1094caadae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 224 additions and 15 deletions

8
Gopkg.lock generated
View File

@ -966,7 +966,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:8356c43d1864b3da53067c02c8912e1e56db1778019f1b745c5cb5e4028216a1" digest = "1:9baf7494df34e555a6a2c9ab5c951a7b07c593d8176a679eab98897b1bb50d0d"
name = "knative.dev/pkg" name = "knative.dev/pkg"
packages = [ packages = [
"apis", "apis",
@ -985,18 +985,18 @@
"metrics/metricskey", "metrics/metricskey",
] ]
pruneopts = "T" pruneopts = "T"
revision = "248c9f0353cab2acd75f6d582fcdb9e45d1e285b" revision = "a447f39709f1ee8c1854517c247330b8ecb9a6ca"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:9fc1b7e84778267884b614c45b0939aa8984dcab5794eb3c6bb5e57bd0a99c41" digest = "1:d2545cd71ef3604f5d2d792e569c6e3a4df31e336d76e709b0b8bac759c0faf7"
name = "knative.dev/test-infra" name = "knative.dev/test-infra"
packages = [ packages = [
"scripts", "scripts",
"tools/dep-collector", "tools/dep-collector",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "1b5477b12d75ea7210d970ff9a234277dcd9ee18" revision = "c7c50ccd8082344a5f8ea85a5ae8de59308d325c"
[[projects]] [[projects]]
digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c"

4
vendor/knative.dev/pkg/Gopkg.lock generated vendored
View File

@ -1323,14 +1323,14 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:8bd3cae999736fca901bdd918ab9e9a899f39446701a296ade11ca44ae0a741e" digest = "1:9fc1b7e84778267884b614c45b0939aa8984dcab5794eb3c6bb5e57bd0a99c41"
name = "knative.dev/test-infra" name = "knative.dev/test-infra"
packages = [ packages = [
"scripts", "scripts",
"tools/dep-collector", "tools/dep-collector",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "64615f92c4ebdd4e4423015ffc0db45877660a0d" revision = "1b5477b12d75ea7210d970ff9a234277dcd9ee18"
[[projects]] [[projects]]
digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c"

View File

@ -18,6 +18,7 @@ package generators
import ( import (
"io" "io"
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
"k8s.io/gengo/namer" "k8s.io/gengo/namer"
"k8s.io/gengo/types" "k8s.io/gengo/types"

View File

@ -116,6 +116,10 @@ func (g *reconcilerReconcilerGenerator) GenerateType(c *generator.Context, t *ty
Package: "go.uber.org/zap", Package: "go.uber.org/zap",
Name: "SugaredLogger", Name: "SugaredLogger",
}), }),
"setsNewString": c.Universe.Function(types.Name{
Package: "k8s.io/apimachinery/pkg/util/sets",
Name: "NewString",
}),
} }
sw.Do(reconcilerInterfaceFactory, m) sw.Do(reconcilerInterfaceFactory, m)
@ -304,8 +308,8 @@ func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource
var finalizers []string var finalizers []string
// If there's nothing to update, just return. // If there's nothing to update, just return.
existingFinalizers := sets.NewString(existing.Finalizers...) existingFinalizers := {{.setsNewString|raw}}(existing.Finalizers...)
desiredFinalizers := sets.NewString(resource.Finalizers...) desiredFinalizers := {{.setsNewString|raw}}(resource.Finalizers...)
if desiredFinalizers.Has(finalizerName) { if desiredFinalizers.Has(finalizerName) {
if existingFinalizers.Has(finalizerName) { if existingFinalizers.Has(finalizerName) {
@ -352,7 +356,7 @@ func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *
return nil return nil
} }
finalizers := sets.NewString(resource.Finalizers...) finalizers := {{.setsNewString|raw}}(resource.Finalizers...)
// If this resource is not being deleted, mark the finalizer. // If this resource is not being deleted, mark the finalizer.
if resource.GetDeletionTimestamp().IsZero() { if resource.GetDeletionTimestamp().IsZero() {
@ -373,7 +377,7 @@ func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *{{.type|r
return nil return nil
} }
finalizers := sets.NewString(resource.Finalizers...) finalizers := {{.setsNewString|raw}}(resource.Finalizers...)
if reconcileEvent != nil { if reconcileEvent != nil {
var event *{{.reconcilerReconcilerEvent|raw}} var event *{{.reconcilerReconcilerEvent|raw}}

View File

@ -33,6 +33,78 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl
} }
``` ```
### Generated Reconcilers
A code generator is available for simple subset of reconciliation requirements.
A label above the API type will signal to the injection code generator to
generate a strongly typed reconciler. Use `+genreconciler` to generate the
reconcilers.
```go
// +genclient
// +genreconciler
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ExampleType struct {
...
}
```
`+genreconciler` will produce a helper method to get a controller impl.
Update `NewController` as follows:
```go
"knative.dev/pkg/controller"
...
impl := controller.NewImpl(c, logger, "NameOfController")
```
becomes
```go
reconciler "knative.dev/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<resource>"
...
impl := reconciler.NewImpl(ctx, c)
```
See
[Generated Reconciler Responsibilities](#generated-reconciler-responsibilities)
for more information.
## Implementing Reconcilers
Type `Reconciler` is expected to implement `Reconcile`:
```go
func (r *Reconciler) Reconcile(ctx context.Context, key string) error {
...
}
```
### Generated Reconcilers
If generated reconcilers are used, Type `Reconciler` is expected to implement
`ReconcileKind`:
```go
func (r *Reconciler) ReconcileKind(ctx context.Context, o *samplesv1alpha1.AddressableService) reconciler.Event {
...
}
```
And if finalizers are required,
```go
func (r *Reconciler) FinalizeKind(ctx context.Context, o *samplesv1alpha1.AddressableService) reconciler.Event {
...
}
```
See
[Generated Reconciler Responsibilities](#generated-reconciler-responsibilities)
for more information.
## Consuming Informers ## Consuming Informers
Knative controllers use "informers" to set up the various event hooks needed to Knative controllers use "informers" to set up the various event hooks needed to
@ -86,7 +158,7 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl
Similar to `injection.Default`, we also have `injection.Fake`. While linking the Similar to `injection.Default`, we also have `injection.Fake`. While linking the
normal accessors sets up the former, linking their fakes set up the latter. normal accessors sets up the former, linking their fakes set up the latter.
``` ```go
import ( import (
"testing" "testing"
@ -112,7 +184,7 @@ func TestFoo(t *testing.T) {
The fake clients also support manually setting up contexts seeded with objects: The fake clients also support manually setting up contexts seeded with objects:
``` ```go
import ( import (
"testing" "testing"
@ -216,3 +288,133 @@ required = [
unused-packages = false unused-packages = false
non-go = false non-go = false
``` ```
## Generated Reconciler Responsibilities
The goal of generating the reconcilers is to provide the controller implementor
a strongly typed interface, and ensure correct reconciler behaviour around
status updates, Kubernetes event creation, and queue management.
We have already helped the queue management with libraries in this repo. But
there was a gap in support and standards around how status updates (and retries)
are performed, and when Kubernetes events are created for the resource.
The general flow with generated reconcilers looks like the following:
```
[k8s] -> [watches] -> [reconciler enqeueue] -> [Reconcile(key)] -> [ReconcileKind(resource)]
^-- you set up. ^-- generated ^-- stubbed and you customize
```
Optionally, support for finalizers:
```
[Reconcile(key)] -> <resource deleted?> - no -> [ReconcileKind(resource)]
`
(optional)
`- yes -> [FinalizeKind(resource)]
```
- `ReconcileKind` is only called if the resource's deletion timestamp is empty.
- `FinalizeKind` is optional, and if implemnted by the reconciler will be called
when the resource's deletion timestamp is set.
The responsibility and consequences of using the generated
`ReconcileKind(resource)` method are as follows:
- In `NewController`, set up watches and reconciler enqueue requests as before.
- Implementing `ReconcileKind(ctx, resource)` to handle active resources.
- Implementing `FinalizeKind(ctx, resource)` to finalize deleting active
resources.
- NOTE: Implementing `FinalizeKind` will result in the reconciler using
finalizers on the resource.
- Resulting changes from `Reconcile` calling `ReconcileKind(ctx, resource)`:
- DO NOT edit the spec of `resource`, it will be ignored.
- DO NOT edit the metadata of `resource`, it will be ignored.
- If `resource.status` is changed, `Reconcile` will synchronize it back to the
API Server.
- Note: the watches setup for `resource.Kind` will see the update to status
and cause another reconciliation.
- `ReconcileKind(ctx, resource)` returns a
[`reconciler.Event`](../reconciler/events.go) results in:
- If `event` is an `error` (`reconciler.Event` extends `error` internally),
`Reconciler` will produce a `Warning` kubernetes event with _reason_
`InternalError` and the body of the error as the message.
- Additionally, the `error` will be returned from `Reconciler` and `key` will
requeue back into the reconciler key queue.
- If `event` is a `reconciler.Event`, `Reconciler` will log a typed and reasoned
Kubernetes Event based on the contents of `event`.
- `event` is not considered an error for requeue and nil is returned from
`Reconciler`.
- If additional events are required to be produced, an implementation can pull a
recorder from the context: `recorder := controller.GetEventRecorder(ctx)`.
Future features to be considered:
- Leverage `configStore` and specifically `ctx = r.configStore.ToContext(ctx)`
inside `Reconcile`.
- Resulting changes from `Reconcile` calling `ReconcileKind(ctx, resource)`:
- If `resource.metadata.labels` or `.annotations` are updated, `Reconcile`
will synchronize it back to the API Server.
- Adjust `+genreconciler` to allow for generated reconcilers to be made without
annotating the type struct.
### Artifacts
The artifacts are targeted to the configured `client/injection` directory:
```go
kindreconciler "knative.dev/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>"
```
Controller related artifacts:
- `NewImpl` - gets an injection based client and lister for <kind>, sets up
Kubernetes Event recorders, and delegates to `controller.NewImpl` for queue
management.
```go
impl := reconciler.NewImpl(ctx, reconcilerInstance)
```
Reconciler related artifacts:
- `Interface` - defines the strongly typed interfaces to be implemented by a
controller reconciling <kind>.
```go
// Check that our Reconciler implements Interface
var _ addressableservicereconciler.Interface = (*Reconciler)(nil)
```
- `Finalizer` - defines the strongly typed interfaces to be implemented by a
controller finalizing <kind>.
```go
// Check that our Reconciler implements Interface
var _ addressableservicereconciler.Finalizer = (*Reconciler)(nil)
```
#### Stubs
To get started, or to use as reference. It is intended to be copied out of the
`client` dir.
`knative.dev/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>/stubs/controller.go`
- A basic implementation of `NewController`.
`knative.dev/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>/stubs/reconciler.go`
- A basic implementation of `type Reconciler struct {}` and
`Reconciler.ReconcileKind`.
- A commented out example of a basic implementation of
`Reconciler.FinalizeKind`.
- An example `reconciler.Event`: `newReconciledNormal`
### Examples
Please look at
[`sample-controller`](http://github.com/knative/sample-controller) or
[`sample-source`](http://github.com/knative/sample-source) for working
integrations of the generated geconciler code.

View File

@ -162,7 +162,7 @@ func (r *BaseReconciler) ReconcileDeletion(ctx context.Context, fb Bindable) err
// If it is our turn to finalize the Binding, then first undo the effect // If it is our turn to finalize the Binding, then first undo the effect
// of our Binding on the resource. // of our Binding on the resource.
logging.FromContext(ctx).Infof("Removing the binding for %s", fb.GetName()) logging.FromContext(ctx).Infof("Removing the binding for %s", fb.GetName())
if err := r.ReconcileSubject(ctx, fb, fb.Undo); apierrs.IsNotFound(err) { if err := r.ReconcileSubject(ctx, fb, fb.Undo); apierrs.IsNotFound(err) || apierrs.IsForbidden(err) {
// If the subject has been deleted, then there is nothing to undo. // If the subject has been deleted, then there is nothing to undo.
} else if err != nil { } else if err != nil {
return err return err
@ -252,7 +252,9 @@ func (r *BaseReconciler) ReconcileSubject(ctx context.Context, fb Bindable, muta
// use to fetch our PodSpecable resources. // use to fetch our PodSpecable resources.
_, lister, err := r.Factory.Get(gvr) _, lister, err := r.Factory.Get(gvr)
if err != nil { if err != nil {
return fmt.Errorf("error getting a lister for resource '%+v': %v", gvr, err) logging.FromContext(ctx).Errorf("Error getting a lister for resource '%+v': %v", gvr, err)
fb.GetBindingStatus().MarkBindingUnavailable("SubjectUnavailable", err.Error())
return err
} }
// Based on the type of subject reference, build up a list of referents. // Based on the type of subject reference, build up a list of referents.

View File

@ -175,7 +175,7 @@ This is a helper script for Knative E2E test scripts. To use it:
1. Calling your script with `--run-tests` and the variable `KO_DOCKER_REPO` set 1. Calling your script with `--run-tests` and the variable `KO_DOCKER_REPO` set
will immediately start the tests against the cluster currently configured for will immediately start the tests against the cluster currently configured for
`kubectl`. `kubectl`.
1. By default `knative_teardown()` and `test_teardown()` will be called after 1. By default `knative_teardown()` and `test_teardown()` will be called after
the tests finish, use `--skip-teardowns` if you don't want them to be called. the tests finish, use `--skip-teardowns` if you don't want them to be called.