-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(reconciler): update harbor cluster ctrl
- define a status object to handle the status updates - add fields to the HarborClusterStatus object - concurently provisioning/checking the dependent services - update the overall cluster reconciler logic Signed-off-by: Steven Zou <szou@vmware.com>
- Loading branch information
1 parent
ff824c8
commit 919c802
Showing
10 changed files
with
476 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package harborcluster | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/goharbor/harbor-operator/apis/goharbor.io/v1alpha2" | ||
"golang.org/x/sync/errgroup" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
const ( | ||
defaultWaitCycle = 10 * time.Second | ||
) | ||
|
||
// Reconcile logic of the HarborCluster | ||
func (r *Reconciler) Reconcile(req ctrl.Request) (res ctrl.Result, err error) { | ||
ctx := context.TODO() | ||
log := r.Log.WithValues("resource", req.NamespacedName) | ||
|
||
// Get the harborcluster first | ||
harborcluster := &v1alpha2.HarborCluster{} | ||
if err := r.Client.Get(ctx, req.NamespacedName, harborcluster); err != nil { | ||
if apierrors.IsNotFound(err) { | ||
// The resource may have be deleted after reconcile request coming in | ||
// Reconcile is done | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
return ctrl.Result{}, fmt.Errorf("get harbor cluster CR error: %w", err) | ||
} | ||
|
||
// Check if it is being deleted | ||
if !harborcluster.ObjectMeta.DeletionTimestamp.IsZero() { | ||
log.Info("harbor cluster is being deleted", "name", req.NamespacedName) | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
// For tracking status | ||
st := NewStatus(harborcluster). | ||
WithContext(ctx). | ||
WithClient(r.Client). | ||
WithLog(log) | ||
|
||
defer func() { | ||
// Execute the status update operation | ||
if er := st.Update(); er != nil { | ||
sec, wait := apierrors.SuggestsClientDelay(err) | ||
if wait { | ||
res.RequeueAfter = time.Duration(sec) * time.Second | ||
r.Log.Info("suggest client delay", "seconds", sec) | ||
} | ||
|
||
er = fmt.Errorf("defer: update status error: %s", er) | ||
if err != nil { | ||
err = fmt.Errorf("%s, upstreaming error: %w", er.Error(), err) | ||
} else { | ||
err = er | ||
} | ||
} | ||
}() | ||
|
||
// Deploy or check dependent services concurrently and fail earlier | ||
g, _ := errgroup.WithContext(ctx) | ||
g.Go(func() error { | ||
cacheStatus, err := r.CacheCtrl.Apply(ctx, harborcluster) | ||
if cacheStatus != nil { | ||
st.UpdateCache(cacheStatus.Condition) | ||
r.HarborCtrl.WithDependency(v1alpha2.ComponentCache, cacheStatus) | ||
} | ||
|
||
return err | ||
}) | ||
|
||
g.Go(func() error { | ||
dbStatus, err := r.DatabaseCtrl.Apply(ctx, harborcluster) | ||
if dbStatus != nil { | ||
st.UpdateDatabase(dbStatus.Condition) | ||
r.HarborCtrl.WithDependency(v1alpha2.ComponentDatabase, dbStatus) | ||
} | ||
|
||
return err | ||
}) | ||
|
||
g.Go(func() error { | ||
storageStatus, err := r.StorageCtrl.Apply(ctx, harborcluster) | ||
if storageStatus != nil { | ||
st.UpdateStorage(storageStatus.Condition) | ||
r.HarborCtrl.WithDependency(v1alpha2.ComponentStorage, storageStatus) | ||
} | ||
|
||
return err | ||
}) | ||
|
||
if err := g.Wait(); err != nil { | ||
return ctrl.Result{}, fmt.Errorf("reconcile dependent services error: %w", err) | ||
} | ||
|
||
if !st.DependsReady() { | ||
r.Log.Info("not all the dependent services are ready") | ||
return ctrl.Result{ | ||
RequeueAfter: defaultWaitCycle, | ||
}, nil | ||
} | ||
|
||
// Create Harbor instance now | ||
harborStatus, err := r.HarborCtrl.Apply(ctx, harborcluster) | ||
if harborStatus != nil { | ||
st.UpdateHarbor(harborStatus.Condition) | ||
} | ||
if err != nil { | ||
return ctrl.Result{}, fmt.Errorf("reconcile harbor service error: %w", err) | ||
} | ||
|
||
// Reconcile done | ||
r.Log.Info("reconcile is completed") | ||
return ctrl.Result{}, nil | ||
} |
Oops, something went wrong.