Skip to content

Commit

Permalink
chore: tidy up
Browse files Browse the repository at this point in the history
  • Loading branch information
iziang committed Jun 7, 2023
1 parent 8f0fdab commit 94638dc
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 44 deletions.
51 changes: 36 additions & 15 deletions apis/apps/v1alpha1/componentresourceconstraint_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,37 +200,62 @@ func (m *ResourceConstraint) ValidateStorage(storage *resource.Quantity) bool {
return true
}

// ValidateResourceRequirements validates if the resources meets the constraint
func (m *ResourceConstraint) ValidateResourceRequirements(r *corev1.ResourceRequirements) bool {
if !m.ValidateCPU(r.Requests.Cpu()) {
// ValidateResources validates if the resources meets the constraint
func (m *ResourceConstraint) ValidateResources(r corev1.ResourceList) bool {
if !m.ValidateCPU(r.Cpu()) {
return false
}

if !m.ValidateMemory(r.Requests.Cpu(), r.Requests.Memory()) {
if !m.ValidateMemory(r.Cpu(), r.Memory()) {
return false
}

if !m.ValidateStorage(r.Requests.Storage()) {
if !m.ValidateStorage(r.Storage()) {
return false
}

return true
}

func (m *ResourceConstraint) CompleteResources(r corev1.ResourceList) corev1.ResourceList {
if r.Cpu().IsZero() || !r.Memory().IsZero() {
return corev1.ResourceList{corev1.ResourceCPU: *r.Cpu(), corev1.ResourceMemory: *r.Memory()}
}

var memory *inf.Dec
if m.Memory.SizePerCPU != nil {
memory = inf.NewDec(1, 0).Mul(r.Cpu().AsDec(), m.Memory.SizePerCPU.AsDec())
} else {
memory = inf.NewDec(1, 0).Mul(r.Cpu().AsDec(), m.Memory.MinPerCPU.AsDec())
}
return corev1.ResourceList{
corev1.ResourceCPU: *r.Cpu(),
corev1.ResourceMemory: resource.MustParse(memory.String()),
}
}

// GetMinimalResources gets the minimal resources meets the constraint
func (m *ResourceConstraint) GetMinimalResources() corev1.ResourceList {
var (
minCPU resource.Quantity
minMemory resource.Quantity
minCPU = resource.Quantity{}
minMemory = resource.Quantity{}
)

if len(m.CPU.Slots) == 0 && (m.CPU.Min == nil || m.CPU.Min.IsZero()) {
return corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1"),
corev1.ResourceMemory: resource.MustParse("1Gi"),
}
}

if len(m.CPU.Slots) > 0 {
minCPU = m.CPU.Slots[0]
}

if m.CPU.Min != nil && minCPU.Cmp(*m.CPU.Min) > 0 {
if minCPU.IsZero() || (m.CPU.Min != nil && minCPU.Cmp(*m.CPU.Min) > 0) {
minCPU = *m.CPU.Min
}

var memory *inf.Dec
if m.Memory.MinPerCPU != nil {
memory = inf.NewDec(1, 0).Mul(minCPU.AsDec(), m.Memory.MinPerCPU.AsDec())
Expand All @@ -242,13 +267,13 @@ func (m *ResourceConstraint) GetMinimalResources() corev1.ResourceList {
}

// FindMatchingConstraints find all constraints that resource satisfies.
func (c *ComponentResourceConstraint) FindMatchingConstraints(r *corev1.ResourceRequirements) []ResourceConstraint {
func (c *ComponentResourceConstraint) FindMatchingConstraints(r corev1.ResourceList) []ResourceConstraint {
if c == nil {
return nil
}
var constraints []ResourceConstraint
for _, constraint := range c.Spec.Constraints {
if constraint.ValidateResourceRequirements(r) {
if constraint.ValidateResources(r) {
constraints = append(constraints, constraint)
}
}
Expand All @@ -261,10 +286,6 @@ func (c *ComponentResourceConstraint) MatchClass(class *ComponentClassInstance)
corev1.ResourceCPU: class.CPU,
corev1.ResourceMemory: class.Memory,
}
resource := &corev1.ResourceRequirements{
Limits: request,
Requests: request,
}
constraints := c.FindMatchingConstraints(resource)
constraints := c.FindMatchingConstraints(request)
return len(constraints) > 0
}
10 changes: 4 additions & 6 deletions apis/apps/v1alpha1/componentresourceconstraint_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,11 @@ func TestResourceConstraints(t *testing.T) {
cpu = resource.MustParse(item.cpu)
memory = resource.MustParse(item.memory)
)
requirements := &corev1.ResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceCPU: cpu,
corev1.ResourceMemory: memory,
},
requests := corev1.ResourceList{
corev1.ResourceCPU: cpu,
corev1.ResourceMemory: memory,
}
assert.Equal(t, item.expect, len(cf.FindMatchingConstraints(requirements)) > 0)
assert.Equal(t, item.expect, len(cf.FindMatchingConstraints(requests)) > 0)

class := &ComponentClassInstance{
ComponentClass: ComponentClass{
Expand Down
43 changes: 27 additions & 16 deletions internal/class/class_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/ghodss/yaml"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
Expand Down Expand Up @@ -106,16 +105,14 @@ func (r *Manager) ValidateResources(comp *v1alpha1.ClusterComponentSpec) error {
var constraints []v1alpha1.ResourceConstraint
// all volumes should match the constraints
for _, volume := range comp.VolumeClaimTemplates {
resources := corev1.ResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{},
}
resources := corev1.ResourceList{}
for k, v := range comp.Resources.Requests {
resources.Requests[k] = v
resources[k] = v
}
for k, v := range volume.Spec.Resources.Requests {
resources.Requests[k] = v
resources[k] = v
}
result := constraint.FindMatchingConstraints(&resources)
result := constraint.FindMatchingConstraints(resources)
if len(result) == 0 {
break
}
Expand All @@ -131,7 +128,7 @@ func (r *Manager) ValidateResources(comp *v1alpha1.ClusterComponentSpec) error {
func (r *Manager) GetResources(comp *v1alpha1.ClusterComponentSpec) (corev1.ResourceList, error) {
result := corev1.ResourceList{}

if comp.ClassDefRef != nil {
if comp.ClassDefRef != nil && comp.ClassDefRef.Class != "" {
cls, err := r.ChooseClass(comp)
if err != nil {
return result, err
Expand All @@ -143,20 +140,34 @@ func (r *Manager) GetResources(comp *v1alpha1.ClusterComponentSpec) (corev1.Reso
return nil, nil
}

var constraints []v1alpha1.ResourceConstraint
var resourcesList []corev1.ResourceList
for _, constraint := range r.constraints {
for _, volume := range comp.VolumeClaimTemplates {
resources := corev1.ResourceRequirements{}
comp.Resources.DeepCopyInto(&resources)
volume.Spec.Resources.DeepCopyInto(&resources)
constraints = append(constraints, constraint.FindMatchingConstraints(&resources)...)
resources := corev1.ResourceList{}
for k, v := range comp.Resources.Requests {
resources[k] = v
}
for k, v := range volume.Spec.Resources.Requests {
resources[k] = v
}
rules := constraint.FindMatchingConstraints(resources)
if len(rules) == 0 {
break
}
for _, rule := range rules {
if resources.Cpu().IsZero() && resources.Memory().IsZero() {
resourcesList = append(resourcesList, rule.GetMinimalResources())
} else {
resourcesList = append(resourcesList, rule.CompleteResources(resources))
}
}
}
}
if len(constraints) == 0 {
if len(resourcesList) == 0 {
return nil, ErrInvalidResource
}
sort.Sort(ByConstraintList(constraints))
return constraints[0].GetMinimalResources(), nil
sort.Sort(ByResourceList(resourcesList))
return resourcesList[0], nil
}

// ChooseClass chooses the classes to be used for a given component with constraints
Expand Down
38 changes: 34 additions & 4 deletions internal/class/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,39 @@ package class
import (
"sort"

corev1 "k8s.io/api/core/v1"

appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
)

var _ sort.Interface = ByResourceList{}

type ByResourceList []corev1.ResourceList

func (b ByResourceList) Len() int {
return len(b)
}

func (b ByResourceList) Less(i, j int) bool {
switch b[i].Cpu().Cmp(*b[j].Cpu()) {
case 1:
return true
case -1:
return false
}
switch b[i].Memory().Cmp(*b[j].Memory()) {
case 1:
return true
case -1:
return false
}
return false
}

func (b ByResourceList) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}

var _ sort.Interface = ByConstraintList{}

type ByConstraintList []appsv1alpha1.ResourceConstraint
Expand All @@ -40,15 +70,15 @@ func (m ByConstraintList) Less(i, j int) bool {
)
switch resource1.Cpu().Cmp(*resource2.Cpu()) {
case 1:
return true
case -1:
return false
case -1:
return true
}
switch resource1.Memory().Cmp(*resource2.Memory()) {
case 1:
return true
case -1:
return false
case -1:
return true
}
return false
}
Expand Down
1 change: 0 additions & 1 deletion internal/class/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ func TestResourceConstraint_ConstraintList(t *testing.T) {
for _, constraint := range cf.Spec.Constraints {
constraints = append(constraints, constraint)
}
resource.MustParse("200Mi")
sort.Sort(ByConstraintList(constraints))
resources := constraints[0].GetMinimalResources()
assert.Equal(t, resources.Cpu().Cmp(resource.MustParse("0.1")) == 0, true)
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func buildComponent(reqCtx intctrlutil.RequestCtx,
if clusterCompSpec.Resources.Requests != nil || clusterCompSpec.Resources.Limits != nil {
component.PodSpec.Containers[0].Resources = clusterCompSpec.Resources
}
if err = fillResources(&cluster, component, clusterCompSpec, clsMgr); err != nil {
if err = updateResources(&cluster, component, clusterCompSpec, clsMgr); err != nil {
reqCtx.Log.Error(err, "update class resources failed")
return nil, err
}
Expand Down Expand Up @@ -363,7 +363,7 @@ func getClassManager(ctx context.Context, cli types2.ReadonlyClient, cluster *ap
return class.NewManager(classDefinitionList, constraintList)
}

func fillResources(cluster *appsv1alpha1.Cluster, component *SynthesizedComponent, clusterCompSpec appsv1alpha1.ClusterComponentSpec, clsMgr *class.Manager) error {
func updateResources(cluster *appsv1alpha1.Cluster, component *SynthesizedComponent, clusterCompSpec appsv1alpha1.ClusterComponentSpec, clsMgr *class.Manager) error {
if ignoreResourceConstraint(cluster) {
return nil
}
Expand Down

0 comments on commit 94638dc

Please sign in to comment.