Auto-update dependencies (#200)

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-11 07:07:08 -08:00 committed by GitHub
parent c41fd5336d
commit fec8f79136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 190 additions and 130 deletions

8
Gopkg.lock generated
View File

@ -966,7 +966,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:b9bf9be301ffbfd00981299321bddf3801a6f8c402e65bfd8411eae34f604aa8" digest = "1:8356c43d1864b3da53067c02c8912e1e56db1778019f1b745c5cb5e4028216a1"
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 = "32ea8458157368451b8e0383aafdacdf5ec061c8" revision = "248c9f0353cab2acd75f6d582fcdb9e45d1e285b"
[[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"

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

@ -1323,14 +1323,14 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:becb98d0dc7f7201c23df580e99e64253d79cf8894fa77bce76cfbf69009557d" digest = "1:8bd3cae999736fca901bdd918ab9e9a899f39446701a296ade11ca44ae0a741e"
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 = "b09617df210766782b2b8f164476ac3887c2baec" revision = "64615f92c4ebdd4e4423015ffc0db45877660a0d"
[[projects]] [[projects]]
digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c"

View File

@ -405,8 +405,10 @@ func reconcilerPackages(basePackage string, groupPkgName string, gv clientgentyp
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "controller", OptionalName: "controller",
}, },
typeToGenerate: t,
outputPackage: packagePath, outputPackage: packagePath,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
groupName: gv.Group.String(),
clientPkg: clientPackagePath, clientPkg: clientPackagePath,
informerPackagePath: informerPackagePath, informerPackagePath: informerPackagePath,
schemePkg: filepath.Join(customArgs.VersionedClientSetPackage, "scheme"), schemePkg: filepath.Join(customArgs.VersionedClientSetPackage, "scheme"),
@ -431,6 +433,7 @@ func reconcilerPackages(basePackage string, groupPkgName string, gv clientgentyp
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "controller", OptionalName: "controller",
}, },
typeToGenerate: t,
reconcilerPkg: packagePath, reconcilerPkg: packagePath,
outputPackage: filepath.Join(packagePath, "stub"), outputPackage: filepath.Join(packagePath, "stub"),
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
@ -456,6 +459,7 @@ func reconcilerPackages(basePackage string, groupPkgName string, gv clientgentyp
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "reconciler", OptionalName: "reconciler",
}, },
typeToGenerate: t,
outputPackage: packagePath, outputPackage: packagePath,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
clientsetPkg: customArgs.VersionedClientSetPackage, clientsetPkg: customArgs.VersionedClientSetPackage,
@ -482,6 +486,7 @@ func reconcilerPackages(basePackage string, groupPkgName string, gv clientgentyp
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "reconciler", OptionalName: "reconciler",
}, },
typeToGenerate: t,
reconcilerPkg: packagePath, reconcilerPkg: packagePath,
outputPackage: filepath.Join(packagePath, "stub"), outputPackage: filepath.Join(packagePath, "stub"),
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),

View File

@ -18,7 +18,6 @@ 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"
@ -31,8 +30,9 @@ type reconcilerControllerGenerator struct {
generator.DefaultGen generator.DefaultGen
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
filtered bool typeToGenerate *types.Type
groupName string
clientPkg string clientPkg string
schemePkg string schemePkg string
informerPackagePath string informerPackagePath string
@ -41,12 +41,8 @@ type reconcilerControllerGenerator struct {
var _ generator.Generator = (*reconcilerControllerGenerator)(nil) var _ generator.Generator = (*reconcilerControllerGenerator)(nil)
func (g *reconcilerControllerGenerator) Filter(c *generator.Context, t *types.Type) bool { func (g *reconcilerControllerGenerator) Filter(c *generator.Context, t *types.Type) bool {
// We generate a single client, so return true once. // Only process the type for this generator.
if !g.filtered { return t == g.typeToGenerate
g.filtered = true
return true
}
return false
} }
func (g *reconcilerControllerGenerator) Namers(c *generator.Context) namer.NameSystems { func (g *reconcilerControllerGenerator) Namers(c *generator.Context) namer.NameSystems {
@ -67,14 +63,27 @@ func (g *reconcilerControllerGenerator) GenerateType(c *generator.Context, t *ty
m := map[string]interface{}{ m := map[string]interface{}{
"type": t, "type": t,
"group": g.groupName,
"controllerImpl": c.Universe.Type(types.Name{ "controllerImpl": c.Universe.Type(types.Name{
Package: "knative.dev/pkg/controller", Package: "knative.dev/pkg/controller",
Name: "Impl", Name: "Impl",
}), }),
"controllerReconciler": c.Universe.Type(types.Name{
Package: "knative.dev/pkg/controller",
Name: "Reconciler",
}),
"controllerNewImpl": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/controller",
Name: "NewImpl",
}),
"loggingFromContext": c.Universe.Function(types.Name{ "loggingFromContext": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/logging", Package: "knative.dev/pkg/logging",
Name: "FromContext", Name: "FromContext",
}), }),
"ptrString": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/ptr",
Name: "String",
}),
"corev1EventSource": c.Universe.Function(types.Name{ "corev1EventSource": c.Universe.Function(types.Name{
Package: "k8s.io/api/core/v1", Package: "k8s.io/api/core/v1",
Name: "EventSource", Name: "EventSource",
@ -125,12 +134,15 @@ func (g *reconcilerControllerGenerator) GenerateType(c *generator.Context, t *ty
var reconcilerControllerNewImpl = ` var reconcilerControllerNewImpl = `
const ( const (
defaultControllerAgentName = "{{.type|lowercaseSingular}}-controller" defaultControllerAgentName = "{{.type|lowercaseSingular}}-controller"
defaultFinalizerName = "{{.type|lowercaseSingular}}" defaultFinalizerName = "{{.type|allLowercasePlural}}.{{.group}}"
defaultQueueName = "{{.type|allLowercasePlural}}"
) )
// NewImpl returns a {{.controllerImpl|raw}} that handles queuing and feeding work from
// the queue through an implementation of {{.controllerReconciler|raw}}, delegating to
// the provided Interface and optional Finalizer methods.
func NewImpl(ctx context.Context, r Interface) *{{.controllerImpl|raw}} { func NewImpl(ctx context.Context, r Interface) *{{.controllerImpl|raw}} {
logger := {{.loggingFromContext|raw}}(ctx) logger := {{.loggingFromContext|raw}}(ctx)
{{.type|lowercaseSingular}}Informer := {{.informerGet|raw}}(ctx) {{.type|lowercaseSingular}}Informer := {{.informerGet|raw}}(ctx)
recorder := {{.controllerGetEventRecorder|raw}}(ctx) recorder := {{.controllerGetEventRecorder|raw}}(ctx)
@ -152,16 +164,13 @@ func NewImpl(ctx context.Context, r Interface) *{{.controllerImpl|raw}} {
}() }()
} }
c := &reconcilerImpl{ rec := &reconcilerImpl{
Client: {{.clientGet|raw}}(ctx), Client: {{.clientGet|raw}}(ctx),
Lister: {{.type|lowercaseSingular}}Informer.Lister(), Lister: {{.type|lowercaseSingular}}Informer.Lister(),
Recorder: recorder, Recorder: recorder,
FinalizerName: defaultFinalizerName,
reconciler: r, reconciler: r,
} }
impl := controller.NewImpl(c, logger, "{{.type|allLowercasePlural}}") return {{.controllerNewImpl|raw}}(rec, logger, defaultQueueName)
return impl
} }
func init() { func init() {

View File

@ -31,7 +31,7 @@ type reconcilerControllerStubGenerator struct {
generator.DefaultGen generator.DefaultGen
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
filtered bool typeToGenerate *types.Type
reconcilerPkg string reconcilerPkg string
informerPackagePath string informerPackagePath string
@ -40,12 +40,8 @@ type reconcilerControllerStubGenerator struct {
var _ generator.Generator = (*reconcilerControllerStubGenerator)(nil) var _ generator.Generator = (*reconcilerControllerStubGenerator)(nil)
func (g *reconcilerControllerStubGenerator) Filter(c *generator.Context, t *types.Type) bool { func (g *reconcilerControllerStubGenerator) Filter(c *generator.Context, t *types.Type) bool {
// We generate a single client, so return true once. // Only process the type for this generator.
if !g.filtered { return t == g.typeToGenerate
g.filtered = true
return true
}
return false
} }
func (g *reconcilerControllerStubGenerator) Namers(c *generator.Context) namer.NameSystems { func (g *reconcilerControllerStubGenerator) Namers(c *generator.Context) namer.NameSystems {

View File

@ -30,7 +30,7 @@ type reconcilerReconcilerGenerator struct {
generator.DefaultGen generator.DefaultGen
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
filtered bool typeToGenerate *types.Type
clientsetPkg string clientsetPkg string
listerName string listerName string
listerPkg string listerPkg string
@ -39,12 +39,8 @@ type reconcilerReconcilerGenerator struct {
var _ generator.Generator = (*reconcilerReconcilerGenerator)(nil) var _ generator.Generator = (*reconcilerReconcilerGenerator)(nil)
func (g *reconcilerReconcilerGenerator) Filter(c *generator.Context, t *types.Type) bool { func (g *reconcilerReconcilerGenerator) Filter(c *generator.Context, t *types.Type) bool {
// We generate a single client, so return true once. // Only process the type for this generator.
if !g.filtered { return t == g.typeToGenerate
g.filtered = true
return true
}
return false
} }
func (g *reconcilerReconcilerGenerator) Namers(c *generator.Context) namer.NameSystems { func (g *reconcilerReconcilerGenerator) Namers(c *generator.Context) namer.NameSystems {
@ -88,6 +84,8 @@ func (g *reconcilerReconcilerGenerator) GenerateType(c *generator.Context, t *ty
}), }),
"reconcilerEvent": c.Universe.Type(types.Name{Package: "knative.dev/pkg/reconciler", Name: "Event"}), "reconcilerEvent": c.Universe.Type(types.Name{Package: "knative.dev/pkg/reconciler", Name: "Event"}),
"reconcilerReconcilerEvent": c.Universe.Type(types.Name{Package: "knative.dev/pkg/reconciler", Name: "ReconcilerEvent"}), "reconcilerReconcilerEvent": c.Universe.Type(types.Name{Package: "knative.dev/pkg/reconciler", Name: "ReconcilerEvent"}),
"reconcilerRetryUpdateConflicts": c.Universe.Function(types.Name{Package: "knative.dev/pkg/reconciler", Name: "RetryUpdateConflicts"}),
// Deps // Deps
"clientsetInterface": c.Universe.Type(types.Name{Name: "Interface", Package: g.clientsetPkg}), "clientsetInterface": c.Universe.Type(types.Name{Name: "Interface", Package: g.clientsetPkg}),
"resourceLister": c.Universe.Type(types.Name{Name: g.listerName, Package: g.listerPkg}), "resourceLister": c.Universe.Type(types.Name{Name: g.listerName, Package: g.listerPkg}),
@ -124,8 +122,7 @@ func (g *reconcilerReconcilerGenerator) GenerateType(c *generator.Context, t *ty
sw.Do(reconcilerNewReconciler, m) sw.Do(reconcilerNewReconciler, m)
sw.Do(reconcilerImplFactory, m) sw.Do(reconcilerImplFactory, m)
sw.Do(reconcilerStatusFactory, m) sw.Do(reconcilerStatusFactory, m)
// TODO(n3wscott): Follow-up to add support for managing finalizers. sw.Do(reconcilerFinalizerFactory, m)
// sw.Do(reconcilerFinalizerFactory, m)
return sw.Error() return sw.Error()
} }
@ -138,10 +135,22 @@ type Interface interface {
// to the objects .Status or .Finalizers will be propagated to the stored // to the objects .Status or .Finalizers will be propagated to the stored
// object. It is recommended that implementors do not call any update calls // object. It is recommended that implementors do not call any update calls
// for the Kind inside of ReconcileKind, it is the responsibility of the calling // for the Kind inside of ReconcileKind, it is the responsibility of the calling
// controller to propagate those properties. // controller to propagate those properties. The resource passed to ReconcileKind
// will always have an empty deletion timestamp.
ReconcileKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}} ReconcileKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}}
} }
// Finalizer defines the strongly typed interfaces to be implemented by a
// controller finalizing {{.type|raw}}.
type Finalizer interface {
// FinalizeKind implements custom logic to finalize {{.type|raw}}. Any changes
// to the objects .Status or .Finalizers will be ignored. Returning a nil or
// Normal type {{.reconcilerEvent|raw}} will allow the finalizer to be deleted on
// the resource. The resource passed to FinalizeKind will always have a set
// deletion timestamp.
FinalizeKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}}
}
// reconcilerImpl implements controller.Reconciler for {{.type|raw}} resources. // reconcilerImpl implements controller.Reconciler for {{.type|raw}} resources.
type reconcilerImpl struct { type reconcilerImpl struct {
// Client is used to write back status updates. // Client is used to write back status updates.
@ -154,10 +163,6 @@ type reconcilerImpl struct {
// Kubernetes API. // Kubernetes API.
Recorder {{.recordEventRecorder|raw}} Recorder {{.recordEventRecorder|raw}}
// FinalizerName is the name of the finalizer to use when finalizing the
// resource.
FinalizerName string
// reconciler is the implementation of the business logic of the resource. // reconciler is the implementation of the business logic of the resource.
reconciler Interface reconciler Interface
} }
@ -173,7 +178,6 @@ func NewReconciler(ctx context.Context, logger *{{.zapSugaredLogger|raw}}, clien
Client: client, Client: client,
Lister: lister, Lister: lister,
Recorder: recorder, Recorder: recorder,
FinalizerName: defaultFinalizerName,
reconciler: r, reconciler: r,
} }
} }
@ -208,23 +212,25 @@ func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
// Don't modify the informers copy. // Don't modify the informers copy.
resource := original.DeepCopy() resource := original.DeepCopy()
var reconcileEvent {{.reconcilerEvent|raw}}
if resource.GetDeletionTimestamp().IsZero() {
// Set and update the finalizer on resource if r.reconciler
// implements Finalizer.
if err := r.setFinalizerIfFinalizer(ctx, resource); err != nil {
logger.Warnw("Failed to set finalizers", zap.Error(err))
}
// Reconcile this copy of the resource and then write back any status // Reconcile this copy of the resource and then write back any status
// updates regardless of whether the reconciliation errored out. // updates regardless of whether the reconciliation errored out.
reconcileEvent := r.reconciler.ReconcileKind(ctx, resource) reconcileEvent = r.reconciler.ReconcileKind(ctx, resource)
} else if fin, ok := r.reconciler.(Finalizer); ok {
// TODO(n3wscott): Follow-up to add support for managing finalizers. // For finalizing reconcilers, if this resource being marked for deletion
// Synchronize the finalizers. // and reconciled cleanly (nil or normal event), remove the finalizer.
//if equality.Semantic.DeepEqual(original.Finalizers, resource.Finalizers) { reconcileEvent = fin.FinalizeKind(ctx, resource)
// // If we didn't change finalizers then don't call updateFinalizers. if err := r.clearFinalizer(ctx, resource, reconcileEvent); err != nil {
//} else if _, updated, fErr := r.updateFinalizers(ctx, resource); fErr != nil { logger.Warnw("Failed to clear finalizers", zap.Error(err))
// logger.Warnw("Failed to update finalizers", zap.Error(fErr)) }
// r.Recorder.Eventf(resource, {{.corev1EventTypeWarning|raw}}, "UpdateFailed", }
// "Failed to update finalizers for %q: %v", resource.Name, fErr)
// return fErr
//} else if updated {
// // There was a difference and updateFinalizers said it updated and did not return an error.
// r.Recorder.Eventf(resource, {{.corev1EventTypeNormal|raw}}, "Updated", "Updated %q finalizers", resource.GetName())
//}
// Synchronize the status. // Synchronize the status.
if equality.Semantic.DeepEqual(original.Status, resource.Status) { if equality.Semantic.DeepEqual(original.Status, resource.Status) {
@ -259,7 +265,7 @@ func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
var reconcilerStatusFactory = ` var reconcilerStatusFactory = `
func (r *reconcilerImpl) updateStatus(existing *{{.type|raw}}, desired *{{.type|raw}}) error { func (r *reconcilerImpl) updateStatus(existing *{{.type|raw}}, desired *{{.type|raw}}) error {
existing = existing.DeepCopy() existing = existing.DeepCopy()
return RetryUpdateConflicts(func(attempts int) (err error) { return {{.reconcilerRetryUpdateConflicts|raw}}(func(attempts int) (err error) {
// The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API. // The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API.
if attempts > 0 { if attempts > 0 {
existing, err = r.Client.{{.type|versionedClientset}}().{{.type|apiGroup}}(desired.Namespace).Get(desired.Name, {{.metav1GetOptions|raw}}{}) existing, err = r.Client.{{.type|versionedClientset}}().{{.type|apiGroup}}(desired.Namespace).Get(desired.Name, {{.metav1GetOptions|raw}}{})
@ -278,27 +284,18 @@ func (r *reconcilerImpl) updateStatus(existing *{{.type|raw}}, desired *{{.type|
return err return err
}) })
} }
// TODO: move this to knative.dev/pkg/reconciler
// RetryUpdateConflicts retries the inner function if it returns conflict errors.
// This can be used to retry status updates without constantly reenqueuing keys.
func RetryUpdateConflicts(updater func(int) error) error {
attempts := 0
return {{.retryRetryOnConflict|raw}}(retry.DefaultRetry, func() error {
err := updater(attempts)
attempts++
return err
})
}
` `
var reconcilerFinalizerFactory = ` var reconcilerFinalizerFactory = `
// Update the Finalizers of the resource. // updateFinalizersFiltered will update the Finalizers of the resource.
func (r *reconcilerImpl) updateFinalizers(ctx context.Context, desired *{{.type|raw}}) (*{{.type|raw}}, bool, error) { // TODO: this method could be generic and sync all finalizers. For now it only
actual, err := r.Lister.{{.type|apiGroup}}(desired.Namespace).Get(desired.Name) // updates defaultFinalizerName.
func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *{{.type|raw}}) error {
finalizerName := defaultFinalizerName
actual, err := r.Lister.{{.type|apiGroup}}(resource.Namespace).Get(resource.Name)
if err != nil { if err != nil {
return nil, false, err return err
} }
// Don't modify the informers copy. // Don't modify the informers copy.
@ -308,22 +305,22 @@ func (r *reconcilerImpl) updateFinalizers(ctx context.Context, desired *{{.type|
// If there's nothing to update, just return. // If there's nothing to update, just return.
existingFinalizers := sets.NewString(existing.Finalizers...) existingFinalizers := sets.NewString(existing.Finalizers...)
desiredFinalizers := sets.NewString(desired.Finalizers...) desiredFinalizers := sets.NewString(resource.Finalizers...)
if desiredFinalizers.Has(r.FinalizerName) { if desiredFinalizers.Has(finalizerName) {
if existingFinalizers.Has(r.FinalizerName) { if existingFinalizers.Has(finalizerName) {
// Nothing to do. // Nothing to do.
return desired, false, nil return nil
} }
// Add the finalizer. // Add the finalizer.
finalizers = append(existing.Finalizers, r.FinalizerName) finalizers = append(existing.Finalizers, finalizerName)
} else { } else {
if !existingFinalizers.Has(r.FinalizerName) { if !existingFinalizers.Has(finalizerName) {
// Nothing to do. // Nothing to do.
return desired, false, nil return nil
} }
// Remove the finalizer. // Remove the finalizer.
existingFinalizers.Delete(r.FinalizerName) existingFinalizers.Delete(finalizerName)
finalizers = existingFinalizers.List() finalizers = existingFinalizers.List()
} }
@ -336,22 +333,62 @@ func (r *reconcilerImpl) updateFinalizers(ctx context.Context, desired *{{.type|
patch, err := json.Marshal(mergePatch) patch, err := json.Marshal(mergePatch)
if err != nil { if err != nil {
return desired, false, err return err
} }
update, err := r.Client.{{.type|versionedClientset}}().{{.type|apiGroup}}(desired.Namespace).Patch(existing.Name, types.MergePatchType, patch) _, err = r.Client.{{.type|versionedClientset}}().{{.type|apiGroup}}(resource.Namespace).Patch(resource.Name, types.MergePatchType, patch)
return update, true, err if err != nil {
r.Recorder.Eventf(resource, {{.corev1EventTypeWarning|raw}}, "FinalizerUpdateFailed",
"Failed to update finalizers for %q: %v", resource.Name, err)
} else {
r.Recorder.Eventf(resource, {{.corev1EventTypeNormal|raw}}, "FinalizerUpdate",
"Updated %q finalizers", resource.GetName())
}
return err
} }
func (r *reconcilerImpl) setFinalizer(a *{{.type|raw}}) { func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *{{.type|raw}}) error {
finalizers := sets.NewString(a.Finalizers...) if _, ok := r.reconciler.(Finalizer); !ok {
finalizers.Insert(r.FinalizerName) return nil
a.Finalizers = finalizers.List() }
finalizers := sets.NewString(resource.Finalizers...)
// If this resource is not being deleted, mark the finalizer.
if resource.GetDeletionTimestamp().IsZero() {
finalizers.Insert(defaultFinalizerName)
}
resource.Finalizers = finalizers.List()
// Synchronize the finalizers filtered by defaultFinalizerName.
return r.updateFinalizersFiltered(ctx, resource)
} }
func (r *reconcilerImpl) unsetFinalizer(a *{{.type|raw}}) { func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *{{.type|raw}}, reconcileEvent {{.reconcilerEvent|raw}}) error {
finalizers := sets.NewString(a.Finalizers...) if _, ok := r.reconciler.(Finalizer); !ok {
finalizers.Delete(r.FinalizerName) return nil
a.Finalizers = finalizers.List() }
if resource.GetDeletionTimestamp().IsZero() {
return nil
}
finalizers := sets.NewString(resource.Finalizers...)
if reconcileEvent != nil {
var event *{{.reconcilerReconcilerEvent|raw}}
if reconciler.EventAs(reconcileEvent, &event) {
if event.EventType == v1.EventTypeNormal {
finalizers.Delete(defaultFinalizerName)
}
}
} else {
finalizers.Delete(defaultFinalizerName)
}
resource.Finalizers = finalizers.List()
// Synchronize the finalizers filtered by defaultFinalizerName.
return r.updateFinalizersFiltered(ctx, resource)
} }
` `

View File

@ -31,7 +31,7 @@ type reconcilerReconcilerStubGenerator struct {
generator.DefaultGen generator.DefaultGen
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
filtered bool typeToGenerate *types.Type
reconcilerPkg string reconcilerPkg string
} }
@ -39,12 +39,8 @@ type reconcilerReconcilerStubGenerator struct {
var _ generator.Generator = (*reconcilerReconcilerStubGenerator)(nil) var _ generator.Generator = (*reconcilerReconcilerStubGenerator)(nil)
func (g *reconcilerReconcilerStubGenerator) Filter(c *generator.Context, t *types.Type) bool { func (g *reconcilerReconcilerStubGenerator) Filter(c *generator.Context, t *types.Type) bool {
// We generate a single client, so return true once. // Only process the type for this generator.
if !g.filtered { return t == g.typeToGenerate
g.filtered = true
return true
}
return false
} }
func (g *reconcilerReconcilerStubGenerator) Namers(c *generator.Context) namer.NameSystems { func (g *reconcilerReconcilerStubGenerator) Namers(c *generator.Context) namer.NameSystems {
@ -77,6 +73,10 @@ func (g *reconcilerReconcilerStubGenerator) GenerateType(c *generator.Context, t
Package: g.reconcilerPkg, Package: g.reconcilerPkg,
Name: "Interface", Name: "Interface",
}), }),
"reconcilerFinalizer": c.Universe.Type(types.Name{
Package: g.reconcilerPkg,
Name: "Finalizer",
}),
"corev1EventTypeNormal": c.Universe.Type(types.Name{ "corev1EventTypeNormal": c.Universe.Type(types.Name{
Package: "k8s.io/api/core/v1", Package: "k8s.io/api/core/v1",
Name: "EventTypeNormal", Name: "EventTypeNormal",
@ -105,13 +105,12 @@ type Reconciler struct {
// Check that our Reconciler implements Interface // Check that our Reconciler implements Interface
var _ {{.reconcilerInterface|raw}} = (*Reconciler)(nil) var _ {{.reconcilerInterface|raw}} = (*Reconciler)(nil)
// Optionally check that our Reconciler implements Finalizer
//var _ {{.reconcilerFinalizer|raw}} = (*Reconciler)(nil)
// ReconcileKind implements Interface.ReconcileKind. // ReconcileKind implements Interface.ReconcileKind.
func (r *Reconciler) ReconcileKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}} { func (r *Reconciler) ReconcileKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}} {
if o.GetDeletionTimestamp() != nil {
// Check for a DeletionTimestamp. If present, elide the normal reconcile logic.
// When a controller needs finalizer handling, it would go here.
return nil
}
o.Status.InitializeConditions() o.Status.InitializeConditions()
// TODO: add custom reconciliation logic here. // TODO: add custom reconciliation logic here.
@ -119,4 +118,11 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, o *{{.type|raw}}) {{.rec
o.Status.ObservedGeneration = o.Generation o.Status.ObservedGeneration = o.Generation
return newReconciledNormal(o.Namespace, o.Name) return newReconciledNormal(o.Namespace, o.Name)
} }
// Optionally, use FinalizeKind to add finalizers. FinalizeKind will be called
// when the resource is deleted.
//func (r *Reconciler) FinalizeKind(ctx context.Context, o *{{.type|raw}}) {{.reconcilerEvent|raw}} {
// // TODO: add custom finalization logic here.
// return nil
//}
` `

View File

@ -30,7 +30,7 @@ const (
// the Kubernetes minimum version required by Knative. // the Kubernetes minimum version required by Knative.
KubernetesMinVersionKey = "KUBERNETES_MIN_VERSION" KubernetesMinVersionKey = "KUBERNETES_MIN_VERSION"
defaultMinimumVersion = "v1.15.0" defaultMinimumVersion = "v1.15.1"
) )
func getMinimumVersion() string { func getMinimumVersion() string {

View File

@ -176,6 +176,9 @@ This is a helper script for Knative E2E test scripts. To use it:
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
the tests finish, use `--skip-teardowns` if you don't want them to be called.
1. By default Istio is installed on the cluster via Addon, use 1. By default Istio is installed on the cluster via Addon, use
`--skip-istio-addon` if you choose not to have it preinstalled. `--skip-istio-addon` if you choose not to have it preinstalled.

View File

@ -365,7 +365,8 @@ function setup_test_cluster() {
export KO_DATA_PATH="${REPO_ROOT_DIR}/.git" export KO_DATA_PATH="${REPO_ROOT_DIR}/.git"
trap teardown_test_resources EXIT # Do not run teardowns if we explicitly want to skip them.
(( ! SKIP_TEARDOWNS )) && trap teardown_test_resources EXIT
# Handle failures ourselves, so we can dump useful info. # Handle failures ourselves, so we can dump useful info.
set +o errexit set +o errexit
@ -419,6 +420,7 @@ function fail_test() {
RUN_TESTS=0 RUN_TESTS=0
SKIP_KNATIVE_SETUP=0 SKIP_KNATIVE_SETUP=0
SKIP_ISTIO_ADDON=0 SKIP_ISTIO_ADDON=0
SKIP_TEARDOWNS=0
GCP_PROJECT="" GCP_PROJECT=""
E2E_SCRIPT="" E2E_SCRIPT=""
E2E_CLUSTER_VERSION="" E2E_CLUSTER_VERSION=""
@ -453,6 +455,7 @@ function initialize() {
case ${parameter} in case ${parameter} in
--run-tests) RUN_TESTS=1 ;; --run-tests) RUN_TESTS=1 ;;
--skip-knative-setup) SKIP_KNATIVE_SETUP=1 ;; --skip-knative-setup) SKIP_KNATIVE_SETUP=1 ;;
--skip-teardowns) SKIP_TEARDOWNS=1 ;;
--skip-istio-addon) SKIP_ISTIO_ADDON=1 ;; --skip-istio-addon) SKIP_ISTIO_ADDON=1 ;;
*) *)
[[ $# -ge 2 ]] || abort "missing parameter after $1" [[ $# -ge 2 ]] || abort "missing parameter after $1"
@ -487,6 +490,7 @@ function initialize() {
readonly EXTRA_CLUSTER_CREATION_FLAGS readonly EXTRA_CLUSTER_CREATION_FLAGS
readonly EXTRA_KUBETEST_FLAGS readonly EXTRA_KUBETEST_FLAGS
readonly SKIP_KNATIVE_SETUP readonly SKIP_KNATIVE_SETUP
readonly SKIP_TEARDOWNS
readonly GKE_ADDONS readonly GKE_ADDONS
if (( ! RUN_TESTS )); then if (( ! RUN_TESTS )); then