Skip to content

Commit 105b6bf

Browse files
authored
[Feature] PV Unschedulable condition (#1311)
1 parent cf98e1a commit 105b6bf

File tree

6 files changed

+91
-0
lines changed

6 files changed

+91
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- (Feature) Add Reason in OOM Metric
66
- (Feature) PersistentVolume Inspector
77
- (Bugfix) Discover Arango image during ID phase
8+
- (Feature) PV Unschedulable condition
89

910
## [1.2.27](https://github.com/arangodb/kube-arangodb/tree/1.2.27) (2023-04-27)
1011
- (Feature) Add InSync Cache

pkg/apis/deployment/v1/conditions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ const (
7272
ConditionTypeSpecAccepted ConditionType = "SpecAccepted"
7373
// ConditionTypeSpecPropagated indicates that the deployment has been at least once UpToDate after spec acceptance.
7474
ConditionTypeSpecPropagated ConditionType = "SpecPropagated"
75+
// ConditionTypeMemberVolumeUnschedulable indicates that the member cannot schedued due to volume issue.
76+
ConditionTypeMemberVolumeUnschedulable ConditionType = "MemberVolumeUnschedulable"
7577
// ConditionTypeMarkedToRemove indicates that the member is marked to be removed.
7678
ConditionTypeMarkedToRemove ConditionType = "MarkedToRemove"
7779
// ConditionTypeScaleDownCandidate indicates that the member will be picked in ScaleDown operaion.

pkg/apis/deployment/v2alpha1/conditions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ const (
7272
ConditionTypeSpecAccepted ConditionType = "SpecAccepted"
7373
// ConditionTypeSpecPropagated indicates that the deployment has been at least once UpToDate after spec acceptance.
7474
ConditionTypeSpecPropagated ConditionType = "SpecPropagated"
75+
// ConditionTypeMemberVolumeUnschedulable indicates that the member cannot schedued due to volume issue.
76+
ConditionTypeMemberVolumeUnschedulable ConditionType = "MemberVolumeUnschedulable"
7577
// ConditionTypeMarkedToRemove indicates that the member is marked to be removed.
7678
ConditionTypeMarkedToRemove ConditionType = "MarkedToRemove"
7779
// ConditionTypeScaleDownCandidate indicates that the member will be picked in ScaleDown operaion.

pkg/deployment/member/phase_updates.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func removeMemberConditionsMapFunc(m *api.MemberStatus) {
104104
m.Conditions.Remove(api.ConditionTypePVCResizePending)
105105
m.Conditions.Remove(api.ConditionTypeArchitectureMismatch)
106106
m.Conditions.Remove(api.ConditionTypeArchitectureChangeCannotBeApplied)
107+
m.Conditions.Remove(api.ConditionTypeMemberVolumeUnschedulable)
107108

108109
m.RemoveTerminationsBefore(time.Now().Add(-1 * recentTerminationsKeepPeriod))
109110

pkg/deployment/reconcile/plan_builder_high.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIOb
5959
ApplyIfEmpty(r.createTopologyMemberUpdatePlan).
6060
ApplyIfEmptyWithBackOff(LicenseCheck, 30*time.Second, r.updateClusterLicense).
6161
ApplyIfEmpty(r.createTopologyMemberConditionPlan).
62+
ApplyIfEmpty(r.updateMemberConditionTypeMemberVolumeUnschedulableCondition).
6263
ApplyIfEmpty(r.createRebalancerCheckPlan).
6364
ApplyIfEmpty(r.createMemberFailedRestoreHighPlan).
6465
ApplyIfEmpty(r.scaleDownCandidate).
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package reconcile
22+
23+
import (
24+
"context"
25+
26+
core "k8s.io/api/core/v1"
27+
28+
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
29+
"github.com/arangodb/kube-arangodb/pkg/deployment/reconcile/shared"
30+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
31+
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
32+
)
33+
34+
// updateMemberPhasePlan creates plan to update member phase
35+
func (r *Reconciler) updateMemberConditionTypeMemberVolumeUnschedulableCondition(ctx context.Context, apiObject k8sutil.APIObject,
36+
spec api.DeploymentSpec, status api.DeploymentStatus,
37+
context PlanBuilderContext) api.Plan {
38+
var plan api.Plan
39+
40+
cache := context.ACS().CurrentClusterCache()
41+
42+
volumeClient, err := cache.PersistentVolume().V1()
43+
if err != nil {
44+
// We cant fetch volumes, continue
45+
return nil
46+
}
47+
48+
for _, e := range status.Members.AsList() {
49+
if pvcStatus := e.Member.PersistentVolumeClaim; pvcStatus != nil {
50+
if pvc, ok := context.ACS().CurrentClusterCache().PersistentVolumeClaim().V1().GetSimple(pvcStatus.GetName()); ok {
51+
if volumeName := pvc.Spec.VolumeName; volumeName != "" {
52+
if pv, ok := volumeClient.GetSimple(volumeName); ok {
53+
// We have volume and volumeclaim, lets calculate condition
54+
unschedulable := memberConditionTypeMemberVolumeUnschedulableCalculate(cache, pv, pvc)
55+
56+
if unschedulable == e.Member.Conditions.IsTrue(api.ConditionTypeMemberVolumeUnschedulable) {
57+
continue
58+
} else if unschedulable && !e.Member.Conditions.IsTrue(api.ConditionTypeMemberVolumeUnschedulable) {
59+
plan = append(plan, shared.UpdateMemberConditionActionV2("PV Unschedulable", api.ConditionTypeMemberVolumeUnschedulable, e.Group, e.Member.ID, true,
60+
"PV Unschedulable", "PV Unschedulable", ""))
61+
} else if !unschedulable && e.Member.Conditions.IsTrue(api.ConditionTypeMemberVolumeUnschedulable) {
62+
plan = append(plan, shared.RemoveMemberConditionActionV2("PV Schedulable", api.ConditionTypeMemberVolumeUnschedulable, e.Group, e.Member.ID))
63+
}
64+
65+
}
66+
}
67+
}
68+
}
69+
}
70+
71+
return plan
72+
}
73+
74+
type memberConditionTypeMemberVolumeUnschedulableCalculateFunc func(cache inspectorInterface.Inspector, pv *core.PersistentVolume, pvc *core.PersistentVolumeClaim) bool
75+
76+
func memberConditionTypeMemberVolumeUnschedulableCalculate(cache inspectorInterface.Inspector, pv *core.PersistentVolume, pvc *core.PersistentVolumeClaim, funcs ...memberConditionTypeMemberVolumeUnschedulableCalculateFunc) bool {
77+
for _, f := range funcs {
78+
if f(cache, pv, pvc) {
79+
return true
80+
}
81+
}
82+
83+
return false
84+
}

0 commit comments

Comments
 (0)