Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(catalogsource): allow grpc source types that don't require an image #709

Merged
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
1 change: 0 additions & 1 deletion cmd/catalog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,3 @@ func main() {
_, done := catalogOperator.Run(stopCh)
<-done
}

6 changes: 5 additions & 1 deletion deploy/chart/templates/0000_50_olm_05-catalogsource.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ spec:
type: string
description: The name of a ConfigMap that holds the entries for an in-memory catalog.

address:
type: string
description: An optional address. When set, directs OLM to connect to use a pre-existing registry server at this address.

image:
type: string
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
description: An image that serves a grpc registry. Only valid for `grpc` sourceType. If both image and address are set, OLM does not use the address field.

displayName:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ spec:
type: string
description: The name of a ConfigMap that holds the entries for an in-memory catalog.

address:
type: string
description: An optional address. When set, directs OLM to connect to use a pre-existing registry server at this address.

image:
type: string
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
description: An image that serves a grpc registry. Only valid for `grpc` sourceType. If both image and address are set, OLM does not use the address field.

displayName:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ spec:
type: string
description: The name of a ConfigMap that holds the entries for an in-memory catalog.

address:
type: string
description: An optional address. When set, directs OLM to connect to use a pre-existing registry server at this address.

image:
type: string
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
description: An image that serves a grpc registry. Only valid for `grpc` sourceType. If both image and address are set, OLM does not use the address field.

displayName:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ spec:
type: string
description: The name of a ConfigMap that holds the entries for an in-memory catalog.

address:
type: string
description: An optional address. When set, directs OLM to connect to use a pre-existing registry server at this address.

image:
type: string
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
description: An image that serves a grpc registry. Only valid for `grpc` sourceType. If both image and address are set, OLM does not use the address field.

displayName:
type: string
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ require (
k8s.io/klog v0.2.0 // indirect
k8s.io/kube-aggregator v0.0.0-20181204002017-122bac39d429
k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd
k8s.io/kubernetes v1.11.8-beta.0.0.20190208223919-e6f6fa1f2dd1
k8s.io/kubernetes v1.11.8-beta.0.0.20190214232326-4e0b35876724
)
9 changes: 5 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.9+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.11+incompatible h1:0gCnqKsq7XxMi69JsnbmMc1o+RJH3XH64sV9aiTTYko=
github.com/coreos/etcd v3.3.11+incompatible h1:U0wJghY374q+UrjOM2mfROHSwEspsQVkCACB1PGka1g=
github.com/coreos/etcd v3.3.11+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
Expand Down Expand Up @@ -112,7 +112,7 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f h1:ShTPMJQes6tubcjzGMODIVG5hlrCeImaBnZzKF2N8SM=
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:BWIsLfhgKhV5g/oF34aRjniBHLTZe5DNekSjbAjIS6c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down Expand Up @@ -297,6 +297,7 @@ k8s.io/apimachinery v0.0.0-20181203235515-3d8ee2261517/go.mod h1:ccL7Eh7zubPUSh9
k8s.io/apimachinery v0.0.0-20190118094746-1525e4dadd2d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/apimachinery v0.0.0-20190208202428-1a579f8a7b42 h1:ju2lLx7i6XE8A9QLtwxlQngelP8SosMIjK4IYE/TLFI=
k8s.io/apimachinery v0.0.0-20190208202428-1a579f8a7b42/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/apimachinery v0.0.0-20190213190008-5eb658cbe970 h1:alS6VCwjuZxqOAhOnpSY/TbMvwVRAOWSTeE63v5Iz+M=
k8s.io/apiserver v0.0.0-20181026151315-13cfe3978170 h1:CqI85nZvPaV+7JFono0nAOGOx2brocqefcOhDPVhHKI=
k8s.io/apiserver v0.0.0-20181026151315-13cfe3978170/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w=
k8s.io/client-go v0.0.0-20180718001006-59698c7d9724/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
Expand All @@ -318,5 +319,5 @@ k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd h1:ggv/Vfza0i5xuhUZyYyxcc
k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kubernetes v1.11.7-beta.0.0.20181219023948-b875d52ea96d/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.11.8-beta.0.0.20190124204751-3a10094374f2/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.11.8-beta.0.0.20190208223919-e6f6fa1f2dd1 h1:KXhECItYGlIqgwjGvb46A8eZ4qB3WgTmunAcEecVsE8=
k8s.io/kubernetes v1.11.8-beta.0.0.20190208223919-e6f6fa1f2dd1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.11.8-beta.0.0.20190214232326-4e0b35876724 h1:THwYErr8LUBf1Je2gh9lzarMPzLxN6SsdtuiLLZMtoQ=
k8s.io/kubernetes v1.11.8-beta.0.0.20190214232326-4e0b35876724/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
6 changes: 5 additions & 1 deletion manifests/0000_50_olm_05-catalogsource.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ spec:
type: string
description: The name of a ConfigMap that holds the entries for an in-memory catalog.

address:
type: string
description: An optional address. When set, directs OLM to connect to use a pre-existing registry server at this address.

image:
type: string
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
description: An image that serves a grpc registry. Only valid for `grpc` sourceType. If both image and address are set, OLM does not use the address field.

displayName:
type: string
Expand Down
45 changes: 40 additions & 5 deletions pkg/api/apis/operators/v1alpha1/catalogsource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,43 @@ const (
type SourceType string

const (
SourceTypeInternal SourceType = "internal"
// SourceTypeInternal (deprecated) specifies a CatalogSource of type SourceTypeConfigmap
SourceTypeInternal SourceType = "internal"

// SourceTypeConfigmap specifies a CatalogSource that generates a configmap-server registry
SourceTypeConfigmap SourceType = "configmap"
SourceTypeGrpc SourceType = "grpc"

// SourceTypeGrpc specifies a CatalogSource that can use an operator registry image to generate a
// registry-server or connect to a pre-existing registry at an address.
SourceTypeGrpc SourceType = "grpc"
)

type CatalogSourceSpec struct {
// SourceType is the type of source
SourceType SourceType `json:"sourceType"`
ConfigMap string `json:"configMap,omitempty"`
Image string `json:"image,omitempty"`
Secrets []string `json:"secrets,omitempty"`

// ConfigMap is the name of the ConfigMap to be used to back a configmap-server registry.
// Only used when SourceType = SourceTypeConfigmap or SourceTypeInternal.
// +Optional
ConfigMap string `json:"configMap,omitempty"`

// Address is a host that OLM can use to connect to a pre-existing registry.
// Format: <registry-host or ip>:<port>
// Only used when SourceType = SourceTypeGrpc.
// Ignored when the Image field is set.
// +Optional
Address string `json:"address,omitempty"`

// Image is an operator-registry container image to instantiate a registry-server with.
// Only used when SourceType = SourceTypeGrpc.
// If present, the address field is ignored.
// +Optional
Image string `json:"image,omitempty"`

// Secrets represent set of secrets that can be used to access the contents of the catalog.
// It is best to keep this list small, since each will need to be tried for every catalog entry.
// +Optional
Secrets []string `json:"secrets,omitempty"`

// Metadata
DisplayName string `json:"displayName,omitempty"`
Expand All @@ -53,6 +80,7 @@ type CatalogSourceStatus struct {
RegistryServiceStatus *RegistryServiceStatus `json:"registryService,omitempty"`
LastSync metav1.Time `json:"lastSync,omitempty"`
}

type ConfigMapResourceReference struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Expand All @@ -71,6 +99,13 @@ type CatalogSource struct {
Status CatalogSourceStatus `json:"status"`
}

func (c *CatalogSource) Address() string {
if c.Spec.Address != "" {
return c.Spec.Address
}
return c.Status.RegistryServiceStatus.Address()
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type CatalogSourceList struct {
metav1.TypeMeta `json:",inline"`
Expand Down
20 changes: 11 additions & 9 deletions pkg/controller/operators/catalog/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func NewOperator(kubeconfigPath string, logger *logrus.Logger, wakeupInterval ti
watchedNamespaces = []string{metav1.NamespaceAll}
}

// Create a new client for ALM types (CRs)
// Create a new client for OLM types (CRs)
crClient, err := client.NewClient(kubeconfigPath)
if err != nil {
return nil, err
Expand Down Expand Up @@ -381,24 +381,26 @@ func (o *Operator) syncCatalogSources(obj interface{}) (syncError error) {

return nil
}

logger.Debug("catsrc configmap state good, checking registry pod")
}

reconciler := o.reconciler.ReconcilerForSourceType(catsrc.Spec.SourceType)
reconciler := o.reconciler.ReconcilerForSource(catsrc)
if reconciler == nil {
// TODO: Add failure status on catalogsource and remove from sources
return fmt.Errorf("no reconciler for source type %s", catsrc.Spec.SourceType)
}

logger.Debug("catsrc configmap state good, checking registry pod")

// if registry pod hasn't been created or hasn't been updated since the last configmap update, recreate it
if catsrc.Status.RegistryServiceStatus == nil || catsrc.Status.RegistryServiceStatus.CreatedAt.Before(&catsrc.Status.LastSync) {
logger.Debug("registry pod scheduled for recheck")
logger.Debug("registry server scheduled recheck")

if err := reconciler.EnsureRegistryServer(out); err != nil {
logger.WithError(err).Warn("couldn't ensure registry server")
return err
}
logger.Debug("ensured registry pod")
logger.Debug("ensured registry server")

out.Status.RegistryServiceStatus.CreatedAt = timeNow()
out.Status.LastSync = timeNow()
Expand All @@ -410,18 +412,18 @@ func (o *Operator) syncCatalogSources(obj interface{}) (syncError error) {
}

o.sourcesLastUpdate = timeNow()
logger.Debug("registry pod recreated")
logger.Debug("registry server recreated")

return nil
}
logger.Debug("registry pod state good")
logger.Debug("registry state good")

// update operator's view of sources
sourcesUpdated := false
func() {
o.sourcesLock.Lock()
defer o.sourcesLock.Unlock()
address := catsrc.Status.RegistryServiceStatus.Address()
address := catsrc.Address()
currentSource, ok := o.sources[sourceKey]
logger = logger.WithField("currentSource", sourceKey)
if !ok || currentSource.Address != address || catsrc.Status.LastSync.After(currentSource.LastConnect.Time) {
Expand Down Expand Up @@ -664,7 +666,7 @@ func (o *Operator) ensureResolverSources(logger *logrus.Entry, namespace string)
logger.WithField("clientState", client.Conn.GetState()).Debug("source")
if client.Conn.GetState() == connectivity.TransientFailure {
logger.WithField("clientState", client.Conn.GetState()).Debug("waiting for connection")
ctx, _ := context.WithTimeout(context.TODO(), 5*time.Second)
ctx, _ := context.WithTimeout(context.TODO(), 2*time.Second)
Copy link

Choose a reason for hiding this comment

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

I assume that was an arbitrary time out.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was playing with the timeouts - I'm changing it back, thanks for pointing it out. Yeah it's arbitrary. I really hope over the next sprint we can encapsulate connection logic into a separate module (I'm thinking a ConnectionManager in a separate thread).

changed := client.Conn.WaitForStateChange(ctx, connectivity.TransientFailure)
if !changed {
logger.WithField("clientState", client.Conn.GetState()).Debug("source in transient failure and didn't recover")
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/operators/catalog/subscriptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ func TestSyncSubscriptions(t *testing.T) {
require.NoError(t, err)

o.reconciler = &fakes.FakeReconcilerFactory{
ReconcilerForSourceTypeStub: func(sourceType v1alpha1.SourceType) reconciler.RegistryReconciler {
ReconcilerForSourceStub: func(source *v1alpha1.CatalogSource) reconciler.RegistryReconciler {
return &fakes.FakeRegistryReconciler{
EnsureRegistryServerStub: func(source *v1alpha1.CatalogSource) error {
return nil
Expand Down
19 changes: 19 additions & 0 deletions pkg/controller/registry/reconciler/grpc_address.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package reconciler

import (
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
)

type GrpcAddressRegistryReconciler struct{}

var _ RegistryReconciler = &GrpcAddressRegistryReconciler{}

func (g *GrpcAddressRegistryReconciler) EnsureRegistryServer(catalogSource *v1alpha1.CatalogSource) error {

catalogSource.Status.RegistryServiceStatus = &v1alpha1.RegistryServiceStatus{
CreatedAt: timeNow(),
Protocol: "grpc",
}

return nil
}
Loading