Skip to content

Commit

Permalink
neonvm-controller: add spec.cpuScalingMode, change vm-controller to e…
Browse files Browse the repository at this point in the history
…xplicitly default the field value if it is not set

Signed-off-by: Misha Sakhnov <[email protected]>
  • Loading branch information
mikhail-sakhnov committed Oct 14, 2024
1 parent 1a7acbc commit 0ecb11d
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 2 deletions.
14 changes: 14 additions & 0 deletions neonvm/apis/neonvm/v1/virtualmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ const (
//
// The value of this annotation is always a JSON-encoded VirtualMachineResources object.
VirtualMachineResourcesAnnotation string = "vm.neon.tech/resources"

// CpuScalingModeQMP is the value of the VirtualMachineSpec.CpuScalingMode field that indicates
// that the VM should use QMP to scale CPUs.
CpuScalingModeQMP string = "qmpScaling"

// CpuScalingModeCpuSysfsState is the value of the VirtualMachineSpec.CpuScalingMode field that
// indicates that the VM should use the CPU sysfs state interface to scale CPUs.
CpuScalingModeCpuSysfsState string = "cpuSysfsStateScaling"
)

// VirtualMachineUsage provides information about a VM's current usage. This is the type of the
Expand Down Expand Up @@ -150,6 +158,11 @@ type VirtualMachineSpec struct {
// propagated to the VM.
// +optional
TargetRevision *RevisionWithTime `json:"targetRevision,omitempty"`

// Use QMP scaling mode for CPU or online/offline CPU states.
// +kubebuilder:validation:Enum=qmpScaling;cpuSysfsStateScaling
// +optional
CpuScalingMode *string `json:"cpuScalingMode,omitempty"`
}

func (spec *VirtualMachineSpec) Resources() VirtualMachineResources {
Expand Down Expand Up @@ -605,6 +618,7 @@ func (p VmPhase) IsAlive() bool {
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Node",type=string,priority=1,JSONPath=`.status.node`
// +kubebuilder:printcolumn:name="Image",type=string,priority=1,JSONPath=`.spec.guest.rootDisk.image`
// +kubebuilder:printcolumn:name="CPUScalingMode",type=string,priority=1,JSONPath=`.spec.cpuScalingMode`
type VirtualMachine struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions neonvm/apis/neonvm/v1/zz_generated.deepcopy.go

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

10 changes: 10 additions & 0 deletions neonvm/config/crd/bases/vm.neon.tech_virtualmachines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ spec:
name: Image
priority: 1
type: string
- jsonPath: .spec.cpuScalingMode
name: CPUScalingMode
priority: 1
type: string
name: v1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -831,6 +835,12 @@ spec:
type: array
type: object
type: object
cpuScalingMode:
description: Use QMP scaling mode for CPU or online/offline CPU states.
enum:
- qmpScaling
- cpuSysfsStateScaling
type: string
disks:
description: List of disk that can be mounted by virtual machine.
items:
Expand Down
10 changes: 10 additions & 0 deletions pkg/neonvm/controllers/vm_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ func (r *VMReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
return ctrl.Result{}, nil
}

// examine cpuScalingMode and set it to the default value if it is not set
if vm.Spec.CpuScalingMode == nil || *vm.Spec.CpuScalingMode == "" {
vm.Spec.CpuScalingMode = lo.ToPtr(vmv1.CpuScalingModeQMP)
if err := r.tryUpdateVM(ctx, &vm); err != nil {
log.Error(err, "Failed to set default CPU scaling mode")
return ctrl.Result{}, err
}
return ctrl.Result{Requeue: true}, nil
}

statusBefore := vm.Status.DeepCopy()
if err := r.doReconcile(ctx, &vm); err != nil {
r.Recorder.Eventf(&vm, corev1.EventTypeWarning, "Failed",
Expand Down
17 changes: 15 additions & 2 deletions pkg/neonvm/controllers/vm_controller_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ func TestReconcile(t *testing.T) {
}, res)
assert.Contains(t, params.getVM().Finalizers, virtualmachineFinalizer)

// Added default value for the cpuScalingMode
res, err = params.r.Reconcile(params.ctx, req)
assert.NoError(t, err)
assert.Equal(t, true, res.Requeue)

// Round 2
res, err = params.r.Reconcile(params.ctx, req)
assert.NoError(t, err)
Expand All @@ -184,8 +189,11 @@ func TestReconcile(t *testing.T) {
// We now have a pod
vm := params.getVM()
assert.NotEmpty(t, vm.Status.PodName)
// Spec is unchanged
assert.Equal(t, vm.Spec, origVM.Spec)
// Spec is unchanged except cpuScalingMode
var origVMWithCPUScalingMode vmv1.VirtualMachine
origVM.DeepCopy().DeepCopyInto(&origVMWithCPUScalingMode)
origVMWithCPUScalingMode.Spec.CpuScalingMode = lo.ToPtr(vmv1.CpuScalingModeQMP)
assert.Equal(t, vm.Spec, origVMWithCPUScalingMode.Spec)

// Round 4
res, err = params.r.Reconcile(params.ctx, req)
Expand Down Expand Up @@ -216,8 +224,13 @@ func TestRunningPod(t *testing.T) {
// Round 1
params.mockRecorder.On("Event", mock.Anything, "Normal", "Created",
mock.Anything)
// Requeue because we expect default values to be set
res, err := params.r.Reconcile(params.ctx, req)
require.NoError(t, err)
assert.Equal(t, true, res.Requeue)

res, err = params.r.Reconcile(params.ctx, req)
require.NoError(t, err)
assert.Equal(t, false, res.Requeue)

// We now have a pod
Expand Down
13 changes: 13 additions & 0 deletions tests/e2e/tmp-default-cpu-scaling-mode/00-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 90
---
apiVersion: vm.neon.tech/v1
kind: VirtualMachine
metadata:
name: example
# temporary added this check to validate that defaulting cpuScalingMode works as expected
# field spec.cpuScalingMode should go to default value `qmp_scaling` if it is not set
# TODO: delete once the https://github.com/neondatabase/autoscaling/issues/1082 went live
spec:
cpuScalingMode: qmpScaling
23 changes: 23 additions & 0 deletions tests/e2e/tmp-default-cpu-scaling-mode/00-create-vm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
unitTest: false
---
apiVersion: vm.neon.tech/v1
kind: VirtualMachine
metadata:
name: example
spec:
schedulerName: autoscale-scheduler
guest:
cpus:
min: 0.25
use: 0.25
max: 0.25
memorySlotSize: 1Gi
memorySlots:
min: 1
use: 1
max: 1
rootDisk:
image: vm-postgres:15-bullseye
size: 1Gi

0 comments on commit 0ecb11d

Please sign in to comment.