Skip to content

Commit

Permalink
re-org code
Browse files Browse the repository at this point in the history
  • Loading branch information
free6om committed Sep 30, 2024
1 parent 5c2efaa commit 3d84e4c
Show file tree
Hide file tree
Showing 16 changed files with 414 additions and 249 deletions.
10 changes: 0 additions & 10 deletions config/crd/bases/view.kubeblocks.io_reconciliationviews.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,6 @@ spec:
Revision can be compared globally between all ObjectChanges of all Objects, to build a total order object change sequence.
format: int64
type: integer
state:
description: State represents the state calculated by StateEvaluationExpression.
type: string
timestamp:
description: |-
Timestamp is a timestamp representing the ReconciliationView Controller time when this change occurred.
Expand Down Expand Up @@ -474,9 +471,6 @@ spec:
Revision can be compared globally between all ObjectChanges of all Objects, to build a total order object change sequence.
format: int64
type: integer
state:
description: State represents the state calculated by StateEvaluationExpression.
type: string
timestamp:
description: |-
Timestamp is a timestamp representing the ReconciliationView Controller time when this change occurred.
Expand Down Expand Up @@ -729,10 +723,6 @@ spec:
Revision can be compared globally between all ObjectChanges of all Objects, to build a total order object change sequence.
format: int64
type: integer
state:
description: State represents the state calculated by
StateEvaluationExpression.
type: string
timestamp:
description: |-
Timestamp is a timestamp representing the ReconciliationView Controller time when this change occurred.
Expand Down
27 changes: 12 additions & 15 deletions controllers/view/change_capture_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"sync/atomic"

"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -46,13 +45,11 @@ type ChangeCaptureStore interface {
}

type changeCaptureStore struct {
scheme *runtime.Scheme
i18nResources *corev1.ConfigMap
defaultLocale string
locale *string
store map[model.GVKNObjKey]client.Object
clock atomic.Int64
changes []viewv1.ObjectChange
scheme *runtime.Scheme
formatter descriptionFormatter
store map[model.GVKNObjKey]client.Object
clock atomic.Int64
changes []viewv1.ObjectChange
}

func (s *changeCaptureStore) Load(objects ...client.Object) error {
Expand Down Expand Up @@ -148,11 +145,11 @@ func (s *changeCaptureStore) GetChanges() []viewv1.ObjectChange {
return s.changes
}

func newChangeCaptureStore(scheme *runtime.Scheme, resource *corev1.ConfigMap) ChangeCaptureStore {
func newChangeCaptureStore(scheme *runtime.Scheme, formatter descriptionFormatter) ChangeCaptureStore {
return &changeCaptureStore{
scheme: scheme,
i18nResources: resource,
store: make(map[model.GVKNObjKey]client.Object),
scheme: scheme,
store: make(map[model.GVKNObjKey]client.Object),
formatter: formatter,
}
}

Expand All @@ -164,23 +161,23 @@ func (s *changeCaptureStore) captureCreation(objectRef *model.GVKNObjKey, object
changes := buildChanges(
make(map[model.GVKNObjKey]client.Object),
map[model.GVKNObjKey]client.Object{*objectRef: object},
buildDescriptionFormatter(s.i18nResources, s.defaultLocale, s.locale))
s.formatter)
s.changes = append(s.changes, changes...)
}

func (s *changeCaptureStore) captureUpdate(objectRef *model.GVKNObjKey, obj client.Object, object client.Object) {
changes := buildChanges(
map[model.GVKNObjKey]client.Object{*objectRef: obj},
map[model.GVKNObjKey]client.Object{*objectRef: object},
buildDescriptionFormatter(s.i18nResources, s.defaultLocale, s.locale))
s.formatter)
s.changes = append(s.changes, changes...)
}

func (s *changeCaptureStore) captureDeletion(objectRef *model.GVKNObjKey, object client.Object) {
changes := buildChanges(
map[model.GVKNObjKey]client.Object{*objectRef: object},
make(map[model.GVKNObjKey]client.Object),
buildDescriptionFormatter(s.i18nResources, s.defaultLocale, s.locale))
s.formatter)
s.changes = append(s.changes, changes...)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ package view

import (
"context"
"k8s.io/apimachinery/pkg/util/sets"

"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/client"

kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
Expand Down Expand Up @@ -184,7 +184,7 @@ func filterEvents(eventLister func() ([]client.Object, error), objectMap map[mod
return matchedEventMap, nil
}

func viewCalculation(ctx context.Context, cli client.Client, scheme *runtime.Scheme, store ObjectRevisionStore) kubebuilderx.Reconciler {
func updateCurrentState(ctx context.Context, cli client.Client, scheme *runtime.Scheme, store ObjectRevisionStore) kubebuilderx.Reconciler {
return &viewCalculator{
ctx: ctx,
cli: cli,
Expand Down
48 changes: 48 additions & 0 deletions controllers/view/deletion_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright (C) 2022-2024 ApeCloud Co., Ltd
This file is part of KubeBlocks project
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package view

import (
"github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx"
"github.com/apecloud/kubeblocks/pkg/controller/model"
)

type deletionHandler struct{}

func (h *deletionHandler) PreCondition(tree *kubebuilderx.ObjectTree) *kubebuilderx.CheckResult {
if tree.GetRoot() == nil || !model.IsObjectDeleting(tree.GetRoot()) {
return kubebuilderx.ConditionUnsatisfied
}
return kubebuilderx.ConditionSatisfied
}

func (h *deletionHandler) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx.Result, error) {
// TODO(free6om)
// unwatch resources
// store cleanup
// remove finalizer
return kubebuilderx.Commit, nil
}

func handleDeletion() kubebuilderx.Reconciler {
return &deletionHandler{}
}

var _ kubebuilderx.Reconciler = &deletionHandler{}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common/types"
"google.golang.org/protobuf/types/known/structpb"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -39,7 +40,7 @@ import (

type stateEvaluation struct {
ctx context.Context
reader client.Reader
cli client.Client
store ObjectRevisionStore
scheme *runtime.Scheme
}
Expand All @@ -53,6 +54,11 @@ func (s *stateEvaluation) PreCondition(tree *kubebuilderx.ObjectTree) *kubebuild

func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx.Result, error) {
view, _ := tree.GetRoot().(*viewv1.ReconciliationView)
objs := tree.List(&corev1.ConfigMap{})
var i18nResource *corev1.ConfigMap
if len(objs) > 0 {
i18nResource, _ = objs[0].(*corev1.ConfigMap)
}

// build new object set from cache
root := &kbappsv1.Cluster{}
Expand All @@ -63,7 +69,7 @@ func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx
Name: view.Spec.TargetObject.Name,
}
}
if err := s.reader.Get(s.ctx, objectKey, root); err != nil {
if err := s.cli.Get(s.ctx, objectKey, root); err != nil {
return kubebuilderx.Commit, err
}

Expand All @@ -79,6 +85,7 @@ func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx
Kind: kbappsv1.ClusterKind,
}
latestReconciliationCycleStart := 0
var initialRoot *kbappsv1.Cluster
for i := len(view.Status.CurrentState.Changes) - 1; i >= 0; i-- {
change := view.Status.CurrentState.Changes[i]
objType := objectReferenceToType(&change.ObjectReference)
Expand Down Expand Up @@ -107,6 +114,7 @@ func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx
}
if state && firstFalseStateFound {
latestReconciliationCycleStart = i
initialRoot, _ = obj.(*kbappsv1.Cluster)
break
}
}
Expand All @@ -125,10 +133,21 @@ func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx

// build new InitialObjectTree
var err error
view.Status.InitialObjectTree, err = getObjectTreeWithRevision(root, kbOwnershipRules, s.store, view.Status.CurrentState.Changes[latestReconciliationCycleStart].Revision, s.scheme)
view.Status.InitialObjectTree, err = getObjectTreeWithRevision(initialRoot, kbOwnershipRules, s.store, view.Status.CurrentState.Changes[latestReconciliationCycleStart].Revision, s.scheme)
if err != nil {
return kubebuilderx.Commit, err
}

// update desired state
generator := newPlanGenerator(s.ctx, s.cli, s.scheme,
treeObjectLoader(view.Status.InitialObjectTree, s.store, s.scheme),
buildDescriptionFormatter(i18nResource, defaultLocale, view.Spec.Locale))
patch := client.MergeFrom(root)
plan, err := generator.generatePlan(initialRoot, patch)
if err != nil {
return kubebuilderx.Commit, err
}
view.Status.DesiredState = &plan.Plan

// delete unused object revisions
for i := 0; i < latestReconciliationCycleStart; i++ {
Expand All @@ -138,12 +157,21 @@ func (s *stateEvaluation) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx
}
// TODO(free6om): delete unused event revisions

// truncate view
// truncate outage changes
view.Status.CurrentState.Changes = view.Status.CurrentState.Changes[latestReconciliationCycleStart:]

return kubebuilderx.Continue, nil
}

func updateDesiredState(ctx context.Context, cli client.Client, scheme *runtime.Scheme, store ObjectRevisionStore) kubebuilderx.Reconciler {
return &stateEvaluation{
ctx: ctx,
cli: cli,
scheme: scheme,
store: store,
}
}

func doStateEvaluation(object client.Object, expression viewv1.StateEvaluationExpression) (bool, error) {
if expression.CELExpression == nil {
return false, fmt.Errorf("CEL expression can't be empty")
Expand Down Expand Up @@ -199,12 +227,9 @@ func doStateEvaluation(object client.Object, expression viewv1.StateEvaluationEx
return result, nil
}

func viewStateEvaluation(ctx context.Context, reader client.Reader, scheme *runtime.Scheme, store ObjectRevisionStore) kubebuilderx.Reconciler {
return &stateEvaluation{
ctx: ctx,
reader: reader,
scheme: scheme,
store: store,
func treeObjectLoader(tree *viewv1.ObjectTreeNode, store ObjectRevisionStore, scheme *runtime.Scheme) objectLoader {
return func() (map[model.GVKNObjKey]client.Object, error) {
return getObjectsFromTree(tree, store, scheme)
}
}

Expand Down
Loading

0 comments on commit 3d84e4c

Please sign in to comment.