From 09a5278bde185dbc54f51573f717f6a456b08f8f Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 14 Jul 2022 16:06:49 +0000 Subject: [PATCH] [Feature] Move PVC resize action to high-priority plan --- CHANGELOG.md | 1 + pkg/deployment/reconcile/plan_builder_high.go | 3 +- .../reconcile/plan_builder_normal.go | 2 +- .../reconcile/plan_builder_storage.go | 103 ++++++++++-------- 4 files changed, 61 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e716a207..3403690b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) - (Bugfix) Ensure pod names not too long - (Refactor) Use cached member's clients +- (Feature) Move PVC resize action to high-priority plan ## [1.2.14](https://github.com/arangodb/kube-arangodb/tree/1.2.14) (2022-07-14) - (Feature) Add ArangoSync TLS based rotation diff --git a/pkg/deployment/reconcile/plan_builder_high.go b/pkg/deployment/reconcile/plan_builder_high.go index d1303f46e..e11653653 100644 --- a/pkg/deployment/reconcile/plan_builder_high.go +++ b/pkg/deployment/reconcile/plan_builder_high.go @@ -34,7 +34,7 @@ import ( // createHighPlan considers the given specification & status and creates a plan to get the status in line with the specification. // If a plan already exists, the given plan is returned with false. -// Otherwise the new plan is returned with a boolean true. +// Otherwise, the new plan is returned with a boolean true. func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIObject, currentPlan api.Plan, spec api.DeploymentSpec, status api.DeploymentStatus, @@ -52,6 +52,7 @@ func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIOb ApplyIfEmpty(r.updateMemberRotationConditionsPlan). ApplyIfEmpty(r.createMemberRecreationConditionsPlan). ApplyIfEmpty(r.createRotateServerStoragePVCPendingResizeConditionPlan). + ApplyIfEmpty(r.createRotateServerStorageResizePlanRuntime). ApplyIfEmpty(r.createTopologyMemberUpdatePlan). ApplyIfEmptyWithBackOff(LicenseCheck, 30*time.Second, r.updateClusterLicense). ApplyIfEmpty(r.createTopologyMemberConditionPlan). diff --git a/pkg/deployment/reconcile/plan_builder_normal.go b/pkg/deployment/reconcile/plan_builder_normal.go index a6a8cdf7d..a057b355c 100644 --- a/pkg/deployment/reconcile/plan_builder_normal.go +++ b/pkg/deployment/reconcile/plan_builder_normal.go @@ -72,7 +72,7 @@ func (r *Reconciler) createNormalPlan(ctx context.Context, apiObject k8sutil.API ApplySubPlanIfEmpty(r.createTLSStatusPropagatedFieldUpdate, r.createCARenewalPlan). ApplySubPlanIfEmpty(r.createTLSStatusPropagatedFieldUpdate, r.createCAAppendPlan). ApplyIfEmpty(r.createKeyfileRenewalPlan). - ApplyIfEmpty(r.createRotateServerStorageResizePlan). + ApplyIfEmpty(r.createRotateServerStorageResizePlanRotate). ApplySubPlanIfEmpty(r.createTLSStatusPropagatedFieldUpdate, r.createRotateTLSServerSNIPlan). ApplyIfEmpty(r.createRestorePlan). ApplySubPlanIfEmpty(r.createEncryptionKeyStatusPropagatedFieldUpdate, r.createEncryptionKeyCleanPlan). diff --git a/pkg/deployment/reconcile/plan_builder_storage.go b/pkg/deployment/reconcile/plan_builder_storage.go index 46e8471c7..8166175c5 100644 --- a/pkg/deployment/reconcile/plan_builder_storage.go +++ b/pkg/deployment/reconcile/plan_builder_storage.go @@ -31,60 +31,72 @@ import ( ) // createRotateServerStorageResizePlan creates plan to resize storage -func (r *Reconciler) createRotateServerStorageResizePlan(ctx context.Context, apiObject k8sutil.APIObject, +func (r *Reconciler) createRotateServerStorageResizePlanRuntime(ctx context.Context, apiObject k8sutil.APIObject, spec api.DeploymentSpec, status api.DeploymentStatus, context PlanBuilderContext) api.Plan { + return r.createRotateServerStorageResizePlanInternal(spec, status, context, api.PVCResizeModeRuntime) +} + +func (r *Reconciler) createRotateServerStorageResizePlanRotate(ctx context.Context, apiObject k8sutil.APIObject, + spec api.DeploymentSpec, status api.DeploymentStatus, + context PlanBuilderContext) api.Plan { + return r.createRotateServerStorageResizePlanInternal(spec, status, context, api.PVCResizeModeRotate) +} + +func (r *Reconciler) createRotateServerStorageResizePlanInternal(spec api.DeploymentSpec, status api.DeploymentStatus, context PlanBuilderContext, mode api.PVCResizeMode) api.Plan { var plan api.Plan - status.Members.ForeachServerGroup(func(group api.ServerGroup, members api.MemberStatusList) error { - for _, m := range members { - cache, ok := context.ACS().ClusterCache(m.ClusterID) - if !ok { - // Do not work without cache - continue - } - if m.Phase != api.MemberPhaseCreated { - // Only make changes when phase is created - continue - } - if m.PersistentVolumeClaimName == "" { - // Plan is irrelevant without PVC - continue - } - groupSpec := spec.GetServerGroupSpec(group) + for _, member := range status.Members.AsList() { + cache, ok := context.ACS().ClusterCache(member.Member.ClusterID) + if !ok { + // Do not work without cache + continue + } + if member.Member.Phase != api.MemberPhaseCreated { + // Only make changes when phase is created + continue + } + if member.Member.PersistentVolumeClaimName == "" { + // Plan is irrelevant without PVC + continue + } + groupSpec := spec.GetServerGroupSpec(member.Group) - if !plan.IsEmpty() && groupSpec.VolumeResizeMode.Get() == api.PVCResizeModeRotate { - // Only 1 change at a time - return nil - } + if groupSpec.VolumeResizeMode.Get() != mode { + continue + } - // Load PVC - pvc, exists := cache.PersistentVolumeClaim().V1().GetSimple(m.PersistentVolumeClaimName) - if !exists { - r.planLogger. - Str("role", group.AsRole()). - Str("id", m.ID). - Warn("Failed to get PVC") - continue - } + if !plan.IsEmpty() && groupSpec.VolumeResizeMode.Get() == api.PVCResizeModeRotate { + // Only 1 change at a time + continue + } - var res core.ResourceList - if groupSpec.HasVolumeClaimTemplate() { - res = groupSpec.GetVolumeClaimTemplate().Spec.Resources.Requests - } else { - res = groupSpec.Resources.Requests - } - if requestedSize, ok := res[core.ResourceStorage]; ok { - if volumeSize, ok := pvc.Spec.Resources.Requests[core.ResourceStorage]; ok { - cmp := volumeSize.Cmp(requestedSize) - if cmp < 0 { - plan = append(plan, r.pvcResizePlan(group, groupSpec, m)...) - } + // Load PVC + pvc, exists := cache.PersistentVolumeClaim().V1().GetSimple(member.Member.PersistentVolumeClaimName) + if !exists { + r.planLogger. + Str("role", member.Group.AsRole()). + Str("id", member.Member.ID). + Warn("Failed to get PVC") + continue + } + + var res core.ResourceList + if groupSpec.HasVolumeClaimTemplate() { + res = groupSpec.GetVolumeClaimTemplate().Spec.Resources.Requests + } else { + res = groupSpec.Resources.Requests + } + if requestedSize, ok := res[core.ResourceStorage]; ok { + if volumeSize, ok := pvc.Spec.Resources.Requests[core.ResourceStorage]; ok { + cmp := volumeSize.Cmp(requestedSize) + if cmp < 0 { + // Here we need to do proper calculation + plan = append(plan, r.pvcResizePlan(member.Group, member.Member, mode)...) } } } - return nil - }) + } return plan } @@ -118,8 +130,7 @@ func (r *Reconciler) createRotateServerStoragePVCPendingResizeConditionPlan(ctx return plan } -func (r *Reconciler) pvcResizePlan(group api.ServerGroup, groupSpec api.ServerGroupSpec, member api.MemberStatus) api.Plan { - mode := groupSpec.VolumeResizeMode.Get() +func (r *Reconciler) pvcResizePlan(group api.ServerGroup, member api.MemberStatus, mode api.PVCResizeMode) api.Plan { switch mode { case api.PVCResizeModeRuntime: return api.Plan{