Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 9 additions & 21 deletions pkg/controller/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,40 +63,28 @@ func NewController(

informers := []cache.SharedIndexInformer{informer.Informer(), revisionInformer.Informer()}

controller := &Controller{
c := &Controller{
Base: controller.NewBase(opt, controllerAgentName, "Configurations", informers),
buildClientSet: buildClientSet,
lister: informer.Lister(),
revisionLister: revisionInformer.Lister(),
}

controller.Logger.Info("Setting up event handlers")
c.Logger.Info("Setting up event handlers")
informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: controller.Enqueue,
UpdateFunc: func(old, new interface{}) {
controller.Enqueue(new)
},
DeleteFunc: controller.Enqueue,
AddFunc: c.Enqueue,
UpdateFunc: controller.PassNew(c.Enqueue),
DeleteFunc: c.Enqueue,
})

revisionInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: func(obj interface{}) bool {
if object, ok := obj.(metav1.Object); ok {
owner := metav1.GetControllerOf(object)
return owner != nil &&
owner.APIVersion == v1alpha1.SchemeGroupVersion.String() &&
owner.Kind == "Configuration"
}
return false
},
FilterFunc: controller.Filter("Configuration"),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.EnqueueControllerOf,
UpdateFunc: func(old, new interface{}) {
controller.EnqueueControllerOf(new)
},
AddFunc: c.EnqueueControllerOf,
UpdateFunc: controller.PassNew(c.Enqueue),
},
})
return controller
return c
}

// Run will set up the event handlers for types we are interested in, as well
Expand Down
3 changes: 1 addition & 2 deletions pkg/controller/configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"

buildv1alpha1 "github.com/knative/build/pkg/apis/build/v1alpha1"
fakebuildclientset "github.com/knative/build/pkg/client/clientset/versioned/fake"
Expand All @@ -45,8 +46,6 @@ import (
informers "github.com/knative/serving/pkg/client/informers/externalversions"
ctrl "github.com/knative/serving/pkg/controller"

"k8s.io/client-go/rest"

kubeinformers "k8s.io/client-go/informers"
fakekubeclientset "k8s.io/client-go/kubernetes/fake"

Expand Down
26 changes: 26 additions & 0 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"time"

"github.com/knative/serving/pkg/apis/serving/v1alpha1"
clientset "github.com/knative/serving/pkg/client/clientset/versioned"
elascheme "github.com/knative/serving/pkg/client/clientset/versioned/scheme"
"github.com/knative/serving/pkg/logging/logkey"
Expand Down Expand Up @@ -48,6 +49,31 @@ func init() {
elascheme.AddToScheme(scheme.Scheme)
}

// PassNew makes it simple to create an UpdateFunc for use with
// cache.ResourceEventHandlerFuncs that can delegate the same methods
// as AddFunc/DeleteFunc but passing through only the second argument
// (which is the "new" object).
func PassNew(f func(interface{})) func(interface{}, interface{}) {
return func(first, second interface{}) {
f(second)
}
}

// Filter makes it simple to create FilterFunc's for use with
// cache.FilteringResourceEventHandler that filter based on the
// kind of the controlling resources.
func Filter(kind string) func(obj interface{}) bool {
return func(obj interface{}) bool {
if object, ok := obj.(metav1.Object); ok {
owner := metav1.GetControllerOf(object)
return owner != nil &&
owner.APIVersion == v1alpha1.SchemeGroupVersion.String() &&
owner.Kind == kind
}
return false
}
}

// Base implements most of the boilerplate and common code
// we have in our controllers.
type Base struct {
Expand Down
56 changes: 23 additions & 33 deletions pkg/controller/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
Expand Down Expand Up @@ -64,53 +63,37 @@ func NewController(
informers := []cache.SharedIndexInformer{informer.Informer(),
configurationInformer.Informer(), routeInformer.Informer()}

controller := &Controller{
c := &Controller{
Base: controller.NewBase(opt, controllerAgentName, "Services", informers),
lister: informer.Lister(),
configurationLister: configurationInformer.Lister(),
routeLister: routeInformer.Lister(),
}

controller.Logger.Info("Setting up event handlers")
c.Logger.Info("Setting up event handlers")
informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: controller.Enqueue,
UpdateFunc: func(old, new interface{}) {
controller.Enqueue(new)
},
DeleteFunc: controller.Enqueue,
AddFunc: c.Enqueue,
UpdateFunc: controller.PassNew(c.Enqueue),
DeleteFunc: c.Enqueue,
})

configurationInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: isControlled,
FilterFunc: controller.Filter("Service"),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.EnqueueControllerOf,
UpdateFunc: func(old, new interface{}) {
controller.EnqueueControllerOf(new)
},
AddFunc: c.EnqueueControllerOf,
UpdateFunc: controller.PassNew(c.Enqueue),
},
})

routeInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: isControlled,
FilterFunc: controller.Filter("Service"),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.EnqueueControllerOf,
UpdateFunc: func(old, new interface{}) {
controller.EnqueueControllerOf(new)
},
AddFunc: c.EnqueueControllerOf,
UpdateFunc: controller.PassNew(c.Enqueue),
},
})

return controller
}

func isControlled(obj interface{}) bool {
if object, ok := obj.(metav1.Object); ok {
owner := metav1.GetControllerOf(object)
return owner != nil &&
owner.APIVersion == v1alpha1.SchemeGroupVersion.String() &&
owner.Kind == "Service"
}
return false
return c
}

// Run will set up the event handlers for types we are interested in, as well
Expand Down Expand Up @@ -210,14 +193,14 @@ func (c *Controller) Reconcile(key string) error {
}

func (c *Controller) updateStatus(service *v1alpha1.Service) (*v1alpha1.Service, error) {
serviceClient := c.ElaClientSet.ServingV1alpha1().Services(service.Namespace)
existing, err := serviceClient.Get(service.Name, metav1.GetOptions{})
existing, err := c.lister.Services(service.Namespace).Get(service.Name)
if err != nil {
return nil, err
}
// Check if there is anything to update.
if !reflect.DeepEqual(existing.Status, service.Status) {
existing.Status = service.Status
serviceClient := c.ElaClientSet.ServingV1alpha1().Services(service.Namespace)
// TODO: for CRD there's no updatestatus, so use normal update.
return serviceClient.Update(existing)
}
Expand All @@ -226,12 +209,19 @@ func (c *Controller) updateStatus(service *v1alpha1.Service) (*v1alpha1.Service,

func (c *Controller) createConfiguration(service *v1alpha1.Service) (*v1alpha1.Configuration, error) {
configClient := c.ElaClientSet.ServingV1alpha1().Configurations(service.Namespace)
return configClient.Create(MakeServiceConfiguration(service))
cfg, err := MakeServiceConfiguration(service)
if err != nil {
return nil, err
}
return configClient.Create(cfg)
}

func (c *Controller) reconcileConfiguration(service *v1alpha1.Service, config *v1alpha1.Configuration) (*v1alpha1.Configuration, error) {
logger := loggerWithServiceInfo(c.Logger, service.Namespace, service.Name)
desiredConfig := MakeServiceConfiguration(service)
desiredConfig, err := MakeServiceConfiguration(service)
if err != nil {
return nil, err
}

// TODO(#642): Remove this (needed to avoid continuous updates)
desiredConfig.Spec.Generation = config.Spec.Generation
Expand Down
10 changes: 7 additions & 3 deletions pkg/controller/service/service_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ limitations under the License.
package service

import (
"errors"

"github.com/knative/serving/pkg/apis/serving/v1alpha1"
"github.com/knative/serving/pkg/controller"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// MakeServiceConfiguration creates a Configuration from a Service object.
func MakeServiceConfiguration(service *v1alpha1.Service) *v1alpha1.Configuration {
func MakeServiceConfiguration(service *v1alpha1.Service) (*v1alpha1.Configuration, error) {
c := &v1alpha1.Configuration{
ObjectMeta: metav1.ObjectMeta{
Name: controller.GetServiceConfigurationName(service),
Expand All @@ -38,8 +40,10 @@ func MakeServiceConfiguration(service *v1alpha1.Service) *v1alpha1.Configuration

if service.Spec.RunLatest != nil {
c.Spec = service.Spec.RunLatest.Configuration
} else {
} else if service.Spec.Pinned != nil {
c.Spec = service.Spec.Pinned.Configuration
} else {
return nil, errors.New("malformed Service: one of runLatest or pinned must be present.")
Copy link
Copy Markdown
Member

@dprotaso dprotaso Jun 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The controller bails out in this scenario with no error message visible to the user

I'd actually expect ServiceConditionConfigurationReady to become false with the reason being the configuration is not set in the Service's spec. This then causing the ServiceConditionReady to become false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd actually prefer this to fail on admission though

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
return c
return c, nil
}
4 changes: 2 additions & 2 deletions pkg/controller/service/service_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func createServiceWithPinned() *v1alpha1.Service {

func TestRunLatest(t *testing.T) {
s := createServiceWithRunLatest()
c := MakeServiceConfiguration(s)
c, _ := MakeServiceConfiguration(s)
if got, want := c.Name, testServiceName; got != want {
t.Errorf("expected %q for service name got %q", want, got)
}
Expand All @@ -108,7 +108,7 @@ func TestRunLatest(t *testing.T) {

func TestPinned(t *testing.T) {
s := createServiceWithPinned()
c := MakeServiceConfiguration(s)
c, _ := MakeServiceConfiguration(s)
if got, want := c.Name, testServiceName; got != want {
t.Errorf("expected %q for service name got %q", want, got)
}
Expand Down
Loading