Skip to content

Commit

Permalink
Allow running the SSP Operator on plain kubernetes
Browse files Browse the repository at this point in the history
SSP can't run on a plain kubernetes, because it requires the
`Infrastructure` kind to be present on the cluster.

When deploying KubeVirt with HCO using OLM on plain kubernetes,
the deployment is never completed because SSP operator never becomes
ready. More details and full description of the issue can be found here:
kubevirt/hyperconverged-cluster-operator#2129

This commit disables the reconcilers and all the watches, in case the
`Infrastructure` is not found on the cluster, instead of killing the
process.

That way, the SSP operator
is runing and responding to the health and ready checks, but does
nothing else. The result is that SSP is still not working on plain
kubernetest, but the OLM deployment is successfully completed.

Signed-off-by: Nahshon Unna-Tsameret <nunnatsa@redhat.com>
  • Loading branch information
nunnatsa committed Nov 3, 2022
1 parent d2e8d82 commit efb9f76
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 29 deletions.
52 changes: 27 additions & 25 deletions controllers/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,19 @@ func CreateAndStartReconciler(ctx context.Context, mgr controllerruntime.Manager
node_labeller.New(),
}

mgrCtx, cancel := context.WithCancel(ctx)
defer cancel()

infrastructureTopology, err := common.GetInfrastructureTopology(mgrCtx, mgr.GetAPIReader())
if err != nil {
return err
}

var requiredCrds []string
for i := range sspOperands {
requiredCrds = append(requiredCrds, sspOperands[i].RequiredCrds()...)
}

mgrCtx, cancel := context.WithCancel(ctx)
defer cancel()

crdWatch := crd_watch.New(requiredCrds...)
// Cleanly stops the manager and exit. The pod will be restarted.
crdWatch.AllCrdsAddedHandler = cancel
Expand All @@ -60,33 +65,30 @@ func CreateAndStartReconciler(ctx context.Context, mgr controllerruntime.Manager
)
}

err = mgr.Add(crdWatch)
if err != nil {
return err
}

infrastructureTopology, err := common.GetInfrastructureTopology(mgrCtx, mgr.GetAPIReader())
if err != nil {
return fmt.Errorf("failed to get infrastructure topology: %w", err)
}

serviceController, err := CreateServiceController(mgrCtx, mgr)
if err != nil {
return fmt.Errorf("failed to create service controller: %w", err)
}
if len(infrastructureTopology) > 0 {
err = mgr.Add(crdWatch)
if err != nil {
return err
}

err = mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {
err := serviceController.Start(ctx, mgr)
serviceController, err := CreateServiceController(mgrCtx, mgr)
if err != nil {
return fmt.Errorf("error starting serviceController: %w", err)
return fmt.Errorf("failed to create service controller: %w", err)
}

mgr.GetLogger().Info("Services Controller started")
err = mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {
err := serviceController.Start(ctx, mgr)
if err != nil {
return fmt.Errorf("error starting serviceController: %w", err)
}

return nil
}))
if err != nil {
return fmt.Errorf("error adding service controller: %w", err)
mgr.GetLogger().Info("Services Controller started")

return nil
}))
if err != nil {
return fmt.Errorf("error adding service controller: %w", err)
}
}

reconciler := NewSspReconciler(mgr.GetClient(), mgr.GetAPIReader(), infrastructureTopology, sspOperands, crdWatch)
Expand Down
10 changes: 6 additions & 4 deletions controllers/ssp_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,13 @@ func (r *sspReconciler) setupController(mgr ctrl.Manager) error {
builder := ctrl.NewControllerManagedBy(mgr)
watchSspResource(builder)

r.areCrdsMissing = len(r.crdWatch.MissingCrds()) > 0
if len(r.topologyMode) > 0 {
r.areCrdsMissing = len(r.crdWatch.MissingCrds()) > 0

// Register watches for created objects only if all required CRDs exist
watchClusterResources(builder, r.crdWatch, r.operands, eventHandlerHook)
watchNamespacedResources(builder, r.crdWatch, r.operands, eventHandlerHook)
// Register watches for created objects only if all required CRDs exist
watchClusterResources(builder, r.crdWatch, r.operands, eventHandlerHook)
watchNamespacedResources(builder, r.crdWatch, r.operands, eventHandlerHook)
}

return builder.Complete(r)
}
Expand Down
6 changes: 6 additions & 0 deletions internal/common/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io/ioutil"
"k8s.io/apimachinery/pkg/api/meta"
"os"
"strings"

Expand Down Expand Up @@ -36,6 +37,11 @@ func GetOperatorVersion() string {
func GetInfrastructureTopology(ctx context.Context, c client.Reader) (osconfv1.TopologyMode, error) {
infraConfig := &osconfv1.Infrastructure{}
if err := c.Get(ctx, types.NamespacedName{Name: "cluster"}, infraConfig); err != nil {
if _, ok := err.(*meta.NoKindMatchError); ok {
// if the Infrastructure type is not known in this cluster, then it's a plain kubernetes.
// we'll use the stale reconciler, so the operator will actually do nothing
return "", nil
}
return "", err
}

Expand Down
31 changes: 31 additions & 0 deletions internal/common/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
Expand Down Expand Up @@ -207,6 +208,10 @@ func CreateOrUpdate(request *Request) ReconcileBuilder {
panic("Request should not be nil")
}

if request.TopologyMode == "" {
return theStaleReconsiler
}

return &reconcileBuilder{
request: request,
updateFunc: func(_, _ client.Object) {
Expand Down Expand Up @@ -431,3 +436,29 @@ func ResourceDeletedResult(resource client.Object, res OperationResult) Reconcil
OperationResult: res,
}
}

// staleReconsiler is a reconsiler that does nothing, in case the operator is running on a plain kubernetes
type staleReconsiler struct{}

func (r *staleReconsiler) NamespacedResource(client.Object) ReconcileBuilder { return r }
func (r *staleReconsiler) ClusterResource(client.Object) ReconcileBuilder { return r }
func (r *staleReconsiler) WithAppLabels(name string, component AppComponent) ReconcileBuilder {
return r
}
func (r *staleReconsiler) UpdateFunc(ResourceUpdateFunc) ReconcileBuilder { return r }
func (r *staleReconsiler) StatusFunc(ResourceStatusFunc) ReconcileBuilder { return r }
func (r *staleReconsiler) ImmutableSpec(getter ResourceSpecGetter) ReconcileBuilder { return r }
func (r *staleReconsiler) Options(options ReconcileOptions) ReconcileBuilder { return r }
func (r *staleReconsiler) Reconcile() (ReconcileResult, error) {
return ReconcileResult{
Status: ResourceStatus{
Progressing: pointer.StringPtr("false"),
NotAvailable: pointer.StringPtr("true"),
Degraded: pointer.StringPtr("false"),
},
Resource: nil,
OperationResult: OperationResultNone,
}, nil
}

var theStaleReconsiler = &staleReconsiler{}
2 changes: 2 additions & 0 deletions internal/common/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

osconfv1 "github.com/openshift/api/config/v1"
libhandler "github.com/operator-framework/operator-lib/handler"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -59,6 +60,7 @@ var _ = Describe("Resource", func() {
},
Logger: log,
VersionCache: VersionCache{},
TopologyMode: osconfv1.HighlyAvailableTopologyMode,
}
})

Expand Down
2 changes: 2 additions & 0 deletions internal/operands/common-templates/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
osconfv1 "github.com/openshift/api/config/v1"
templatev1 "github.com/openshift/api/template/v1"
libhandler "github.com/operator-framework/operator-lib/handler"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -78,6 +79,7 @@ var _ = Describe("Common-Templates operand", func() {
},
Logger: log,
VersionCache: common.VersionCache{},
TopologyMode: osconfv1.HighlyAvailableTopologyMode,
}
})

Expand Down
2 changes: 2 additions & 0 deletions internal/operands/data-sources/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

osconfv1 "github.com/openshift/api/config/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -72,6 +73,7 @@ var _ = Describe("Data-Sources operand", func() {
},
Logger: log,
VersionCache: common.VersionCache{},
TopologyMode: osconfv1.HighlyAvailableTopologyMode,
}
})

Expand Down
3 changes: 3 additions & 0 deletions internal/operands/metrics/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

osconfv1 "github.com/openshift/api/config/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
. "kubevirt.io/ssp-operator/internal/test-utils"
Expand Down Expand Up @@ -53,6 +55,7 @@ var _ = Describe("Metrics operand", func() {
},
Logger: log,
VersionCache: common.VersionCache{},
TopologyMode: osconfv1.HighlyAvailableTopologyMode,
}

_, err := operand.Reconcile(&request)
Expand Down
2 changes: 2 additions & 0 deletions internal/operands/template-validator/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
osconfv1 "github.com/openshift/api/config/v1"
admission "k8s.io/api/admissionregistration/v1"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
Expand Down Expand Up @@ -75,6 +76,7 @@ var _ = Describe("Template validator operand", func() {
},
Logger: log,
VersionCache: common.VersionCache{},
TopologyMode: osconfv1.HighlyAvailableTopologyMode,
}
})

Expand Down

0 comments on commit efb9f76

Please sign in to comment.