Skip to content

Commit

Permalink
feat: support node selector and runtime class name for devbox. suppor…
Browse files Browse the repository at this point in the history
…t custom resource name.
  • Loading branch information
lingdie committed Dec 9, 2024
1 parent fd9542c commit 63d75e6
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 65 deletions.
15 changes: 5 additions & 10 deletions controllers/devbox/api/v1alpha1/devbox_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,10 @@ package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type ResourceName string

const (
// ResourceCPU CPU, in cores. (500m = .5 cores)
ResourceCPU ResourceName = "cpu"
// ResourceMemory Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
ResourceMemory ResourceName = "memory"
// FinalizerName is the finalizer for Devbox
FinalizerName = "devbox.sealos.io/finalizer"
DevBoxPartOf = "devbox"
Expand All @@ -52,8 +45,6 @@ const (
NetworkTypeTailnet NetworkType = "Tailnet"
)

type ResourceList map[ResourceName]resource.Quantity

type RuntimeRef struct {
// +kubebuilder:validation:Required
Name string `json:"name"`
Expand All @@ -75,7 +66,7 @@ type DevboxSpec struct {
// +kubebuilder:validation:Enum=Running;Stopped
State DevboxState `json:"state"`
// +kubebuilder:validation:Required
Resource ResourceList `json:"resource"`
Resource corev1.ResourceList `json:"resource"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=false
Expand Down Expand Up @@ -109,6 +100,10 @@ type DevboxSpec struct {
// +kubebuilder:validation:Optional
ExtraVolumeMounts []corev1.VolumeMount `json:"extraVolumeMounts,omitempty"`

// +kubebuilder:validation:Optional
RuntimeClassName string `json:"runtimeClassName,omitempty"`
// +kubebuilder:validation:Optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// +kubebuilder:validation:Optional
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
// +kubebuilder:validation:Optional
Expand Down
30 changes: 8 additions & 22 deletions controllers/devbox/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2656,14 +2656,21 @@ spec:
required:
- type
type: object
nodeSelector:
additionalProperties:
type: string
type: object
resource:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: ResourceList is a set of (resource name, quantity) pairs.
type: object
runtimeClassName:
type: string
runtimeRef:
properties:
name:
Expand Down
7 changes: 5 additions & 2 deletions controllers/devbox/internal/controller/devbox_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,11 @@ func (r *DevboxReconciler) generateDevboxPod(devbox *devboxv1alpha1.Devbox, runt
Containers: containers,
Volumes: volumes,

Tolerations: devbox.Spec.Tolerations,
Affinity: devbox.Spec.Affinity,
RuntimeClassName: ptr.To(devbox.Spec.RuntimeClassName),

NodeSelector: devbox.Spec.NodeSelector,
Tolerations: devbox.Spec.Tolerations,
Affinity: devbox.Spec.Affinity,
},
}
// set controller reference and finalizer
Expand Down
47 changes: 16 additions & 31 deletions controllers/devbox/internal/controller/helper/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,36 +398,22 @@ func GenerateSSHVolume(devbox *devboxv1alpha1.Devbox) corev1.Volume {
}
}

func GenerateResourceRequirements(devbox *devboxv1alpha1.Devbox,
requestCPURate, requestMemoryRate float64,
requestEphemeralStorage, limitEphemeralStorage string,
) corev1.ResourceRequirements {
return corev1.ResourceRequirements{
Requests: calculateResourceRequest(
corev1.ResourceList{
corev1.ResourceCPU: devbox.Spec.Resource["cpu"],
corev1.ResourceMemory: devbox.Spec.Resource["memory"],
corev1.ResourceEphemeralStorage: resource.MustParse(requestEphemeralStorage),
},
requestCPURate, requestMemoryRate,
),
Limits: corev1.ResourceList{
corev1.ResourceCPU: devbox.Spec.Resource["cpu"],
corev1.ResourceMemory: devbox.Spec.Resource["memory"],
corev1.ResourceEphemeralStorage: resource.MustParse(limitEphemeralStorage),
},
func GenerateResourceRequirements(devbox *devboxv1alpha1.Devbox, requestCPURate, requestMemoryRate float64, requestEphemeralStorage, limitEphemeralStorage string) corev1.ResourceRequirements {
res := corev1.ResourceRequirements{}
res.Limits = devbox.Spec.Resource
if limitEphemeralStorage != "" {
res.Limits[corev1.ResourceEphemeralStorage] = resource.MustParse(limitEphemeralStorage)
}
}

func IsExceededQuotaError(err error) bool {
return strings.Contains(err.Error(), "exceeded quota")
res.Requests = calculateResourceRequest(res.Limits, requestCPURate, requestMemoryRate)
if requestEphemeralStorage != "" {
res.Requests[corev1.ResourceEphemeralStorage] = resource.MustParse(requestEphemeralStorage)
}
return res
}

func calculateResourceRequest(limit corev1.ResourceList, requestCPURate, requestMemoryRate float64) corev1.ResourceList {
if limit == nil {
return nil
}
request := make(corev1.ResourceList)
// deep copy limit to request, only cpu and memory are calculated
request := limit.DeepCopy()
// Calculate CPU request
if cpu, ok := limit[corev1.ResourceCPU]; ok {
cpuValue := cpu.AsApproximateFloat64()
Expand All @@ -440,11 +426,6 @@ func calculateResourceRequest(limit corev1.ResourceList, requestCPURate, request
memoryRequest := memoryValue / requestMemoryRate
request[corev1.ResourceMemory] = *resource.NewQuantity(int64(memoryRequest), resource.BinarySI)
}

if ephemeralStorage, ok := limit[corev1.ResourceEphemeralStorage]; ok {
request[corev1.ResourceEphemeralStorage] = ephemeralStorage
}

return request
}

Expand All @@ -471,3 +452,7 @@ func GenerateDevboxArgs(devbox *devboxv1alpha1.Devbox, runtime *devboxv1alpha1.R
}
return runtime.Spec.Config.Args
}

func IsExceededQuotaError(err error) bool {
return strings.Contains(err.Error(), "exceeded quota")
}

0 comments on commit 63d75e6

Please sign in to comment.