Skip to content

Commit

Permalink
WIP - Add CrdWatch component
Browse files Browse the repository at this point in the history
Signed-off-by: Andrej Krejcir <akrejcir@redhat.com>
  • Loading branch information
akrejcir committed Sep 27, 2022
1 parent 4445c6d commit c157842
Show file tree
Hide file tree
Showing 18 changed files with 1,070 additions and 279 deletions.
101 changes: 0 additions & 101 deletions controllers/crd_controller.go

This file was deleted.

84 changes: 0 additions & 84 deletions controllers/finishable/finishable.go

This file was deleted.

90 changes: 32 additions & 58 deletions controllers/setup.go
Expand Up @@ -5,9 +5,8 @@ import (
"fmt"
"path/filepath"

extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

"kubevirt.io/ssp-operator/internal/common"
crd_watch "kubevirt.io/ssp-operator/internal/crd-watch"
"kubevirt.io/ssp-operator/internal/operands"
common_templates "kubevirt.io/ssp-operator/internal/operands/common-templates"
data_sources "kubevirt.io/ssp-operator/internal/operands/data-sources"
Expand All @@ -19,6 +18,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager"
)

// Need to watch CRDs
// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch

func CreateAndStartReconciler(ctx context.Context, mgr controllerruntime.Manager) error {
templatesFile := filepath.Join(templateBundleDir, "common-templates-"+common_templates.Version+".yaml")
templatesBundle, err := template_bundle.ReadBundle(templatesFile)
Expand All @@ -39,19 +41,36 @@ func CreateAndStartReconciler(ctx context.Context, mgr controllerruntime.Manager
requiredCrds = append(requiredCrds, sspOperands[i].RequiredCrds()...)
}

// Check if all needed CRDs exist
crdList := &extv1.CustomResourceDefinitionList{}
err = mgr.GetAPIReader().List(ctx, crdList)
mgrCtx, cancel := context.WithCancel(ctx)
defer cancel()

crdWatch := crd_watch.New(requiredCrds...)
crdWatch.AllCrdsAddedHandler = func() {
// Cleanly stops the manager and exits. The pod will be restarted.
// TODO -- explain why this is necessary
cancel()
}
crdWatch.SomeCrdRemovedHandler = func() {
// Cleanly stops the manager and exits. The pod will be restarted.
cancel()
}

err = crdWatch.Init(mgrCtx, mgr.GetAPIReader())
if err != nil {
return fmt.Errorf("failed to list CRDs: %w", err)
return err
}

infrastructureTopology, err := common.GetInfrastructureTopology(ctx, mgr.GetAPIReader())
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(ctx, mgr)
serviceController, err := CreateServiceController(mgrCtx, mgr)
if err != nil {
return fmt.Errorf("failed to create service controller: %w", err)
}
Expand All @@ -70,62 +89,17 @@ func CreateAndStartReconciler(ctx context.Context, mgr controllerruntime.Manager
return fmt.Errorf("error adding service controller: %w", err)
}

reconciler := NewSspReconciler(mgr.GetClient(), mgr.GetAPIReader(), infrastructureTopology, sspOperands)

if requiredCrdsExist(requiredCrds, crdList.Items) {
// No need to start CRD controller
err := reconciler.setupController(mgr)
if err != nil {
return fmt.Errorf("error setting up SSP controller: %w", err)
}

} else {
mgr.GetLogger().Info("Required CRDs do not exist. Waiting until they are installed.",
"required_crds", requiredCrds,
)
reconciler := NewSspReconciler(mgr.GetClient(), mgr.GetAPIReader(), infrastructureTopology, sspOperands, crdWatch)

crdController, err := CreateCrdController(mgr, requiredCrds)
if err != nil {
return fmt.Errorf("failed to create crd controller: %w", err)
}

err = mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {
// First start the CRD controller
err := crdController.Start(ctx)
if err != nil {
return fmt.Errorf("error from crd controller: %w", err)
}

mgr.GetLogger().Info("Required CRDs were installed, starting SSP operator.")

// Clear variable, so it can be garbage collected
crdController = nil

// After it is finished, add the SSP controller to the manager
return reconciler.setupController(mgr)
}))
if err != nil {
return err
}
err = reconciler.setupController(mgr)
if err != nil {
return err
}

mgr.GetLogger().Info("starting manager")
if err := mgr.Start(ctx); err != nil {
if err := mgr.Start(mgrCtx); err != nil {
mgr.GetLogger().Error(err, "problem running manager")
return err
}
return nil
}

func requiredCrdsExist(required []string, foundCrds []extv1.CustomResourceDefinition) bool {
OuterLoop:
for i := range required {
for j := range foundCrds {
if required[i] == foundCrds[j].Name {
continue OuterLoop
}
}
return false
}
return true
}

0 comments on commit c157842

Please sign in to comment.