Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/components/versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ firmware:
libvirt: v10.9.0
edk2: stable202411
core:
3p-kubevirt: v1.6.2-v12n.42
3p-kubevirt: feat/inplace-resize # v1.6.2-v12n.42
3p-containerized-data-importer: v1.60.3-v12n.19
distribution: 2.8.3
package:
Expand Down
1 change: 1 addition & 0 deletions images/virt-artifact/werf.inc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact
final: false
fromImage: builder/src
fromCacheVersion: "005"
secrets:
- id: SOURCE_REPO
value: {{ $.SOURCE_REPO }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ const (
DefaultUSBDeviceGroup = "64535"
// DefaultUSBDeviceUser is the default device user ID for USB devices.
DefaultUSBDeviceUser = "64535"

AnnVirtualMachineInstanceInPlaceResizeInProgress = "internal.virtualization.deckhouse.io/in-place-resize-in-progress"
)

// AddAnnotation adds an annotation to an object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (c *comparatorCPU) Compare(current, desired *v1alpha2.VirtualMachineSpec) [
fractionChangedAction := ActionApplyImmediate

// Require reboot if CPU hotplug is not enabled.
if !c.featureGate.Enabled(featuregates.HotplugCPUWithLiveMigration) {
if !c.featureGate.Enabled(featuregates.HotplugCPUWithLiveMigration) && !c.featureGate.Enabled(featuregates.HotplugCPUInPlaceResize) {
coresChangedAction = ActionRestart
fractionChangedAction = ActionRestart
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (c *comparatorMemory) Compare(current, desired *v1alpha2.VirtualMachineSpec
}

// Require reboot if memory hotplug is not enabled.
if !c.featureGate.Enabled(featuregates.HotplugMemoryWithLiveMigration) {
if !c.featureGate.Enabled(featuregates.HotplugMemoryWithLiveMigration) && !c.featureGate.Enabled(featuregates.HotplugMemoryInPlaceResize) {
actionType = ActionRestart
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
"github.com/deckhouse/virtualization-controller/pkg/logger"
"github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization-controller/pkg/featuregates"
"github.com/deckhouse/virtualization-controller/pkg/common/kvvm"
)

const hotplugHandler = "HotplugHandler"
Expand All @@ -56,6 +58,18 @@ func (h *HotplugHandler) Handle(ctx context.Context, vm *v1alpha2.VirtualMachine
return reconcile.Result{}, client.IgnoreNotFound(err)
}

if h.inplaceResizeInProgress(kvvmi) {
possible, complete, err := h.inPlaceResizePossible(ctx, kvvmi)
if err != nil {
return reconcile.Result{}, err
}
if possible || complete {
return reconcile.Result{}, nil
}
// inplace resize is not possible, but it is not complete
// switch to resize via live migration
}

cond, _ := conditions.GetKVVMICondition(virtv1.VirtualMachineInstanceMemoryChange, kvvmi.Status.Conditions)
isMemoryHotplug := cond.Status == corev1.ConditionTrue

Expand All @@ -81,6 +95,46 @@ func (h *HotplugHandler) Name() string {
return hotplugHandler
}

func (h *HotplugHandler) inplaceResizeInProgress(kvvmi *virtv1.VirtualMachineInstance) bool {
if featuregates.Default().Enabled(featuregates.HotplugCPUInPlaceResize) || featuregates.Default().Enabled(featuregates.HotplugMemoryInPlaceResize) {
return kvvmi.GetAnnotations()[annotations.AnnVirtualMachineInstanceInPlaceResizeInProgress] == "true"
}

return false
}

func (h *HotplugHandler) inPlaceResizePossible(ctx context.Context, kvvmi *virtv1.VirtualMachineInstance) (bool, bool, error) {
cond, exists := conditions.GetKVVMICondition("PodResourceResizeInProgress", kvvmi.Status.Conditions)
if !exists {
return false, false, fmt.Errorf("failed to get PodResourceResizeInProgress condition")
}

switch cond.Reason {
case "PodResizeCompleted":
return false, true, nil
case "PodResizePending", "PodResizeInProgress":
default:
return false, false, fmt.Errorf("unexpected PodResourceResizeInProgress condition reason: %s", cond.Reason)
}

pod, err := kvvm.FindPodByKVVMI(ctx, h.client, kvvmi)
if err != nil {
return false, false, err
}

podResizePending, _ := conditions.GetPodCondition(corev1.PodResizePending, pod.Status.Conditions)
// https://github.com/kubernetes/kubernetes/blob/48d5bff65612a50ba5149319810a71ee151ec076/pkg/kubelet/events/event.go#L37
if podResizePending.Reason == "ResizeDeferred" || podResizePending.Reason == "ResizeInfeasible" {
return false, false, nil
}
podResizeInProgress, _ := conditions.GetPodCondition(corev1.PodResizeInProgress, pod.Status.Conditions)
if podResizeInProgress.Reason == "ResizeError" {
return false, false, nil
}

return true, false, nil
}

func getHotplugResourcesSum(vm *v1alpha2.VirtualMachine) string {
return fmt.Sprintf("cpu.cores=%d,cpu.coreFraction=%s,memory.size=%s", vm.Spec.CPU.Cores, vm.Spec.CPU.CoreFraction, vm.Spec.Memory.Size.String())
}
12 changes: 12 additions & 0 deletions images/virtualization-artifact/pkg/featuregates/featuregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const (
USB featuregate.Feature = "USB"
HotplugCPUWithLiveMigration featuregate.Feature = "HotplugCPUWithLiveMigration"
HotplugMemoryWithLiveMigration featuregate.Feature = "HotplugMemoryWithLiveMigration"
HotplugCPUInPlaceResize featuregate.Feature = "HotplugCPUInPlaceResize"
HotplugMemoryInPlaceResize featuregate.Feature = "HotplugMemoryInPlaceResize"
)

var featureSpecs = map[featuregate.Feature]featuregate.FeatureSpec{
Expand Down Expand Up @@ -69,6 +71,16 @@ var featureSpecs = map[featuregate.Feature]featuregate.FeatureSpec{
LockToDefault: version.GetEdition() == version.EditionCE,
PreRelease: featuregate.Alpha,
},
HotplugCPUInPlaceResize: {
Default: false,
LockToDefault: version.GetEdition() == version.EditionCE,
PreRelease: featuregate.Alpha,
},
HotplugMemoryInPlaceResize: {
Default: false,
LockToDefault: version.GetEdition() == version.EditionCE,
PreRelease: featuregate.Alpha,
},
}

var (
Expand Down
9 changes: 7 additions & 2 deletions openapi/config-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,15 @@ properties:
description: |
Enable experimental or early access features.

- `HotplugCPUWithLiveMigration` — enable live changing of cpu cores number. (Not available in CE);
- `HotplugMemoryWithLiveMigration` — enable live changing of memory size. (Not available in CE);
- `HotplugCPUWithLiveMigration` — enable live changing of cpu cores number via LiveMigration. (Not available in CE);
- `HotplugMemoryWithLiveMigration` — enable live changing of memory size via LiveMigration. (Not available in CE);
- `HotplugCPUInPlaceResize` - enable live changing of cpu cores number via InPlaceResize. (Not available in CE);
- `HotplugMemoryInPlaceResize` - enable live changing of memory size via InPlaceResize. (Not available in CE);
items:
type: string
enum:
- "HotplugCPUWithLiveMigration"
- "HotplugMemoryWithLiveMigration"
- "HotplugCPUInPlaceResize"
- "HotplugMemoryInPlaceResize"

6 changes: 4 additions & 2 deletions openapi/doc-ru-config-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ properties:
description: |
Включение экспериментальных или недостаточно обкатанных возможностей.

- `HotplugCPUWithLiveMigration` — включить изменение количества ядер процессора без перезагрузки. (Не доступно в CE);
- `HotplugMemoryWithLiveMigration` — включить изменение размера памяти без перезагрузки. (Не доступно в CE);
- `HotplugCPUWithLiveMigration` — включить изменение количества ядер процессора без перезагрузки через живую миграцию. (Не доступно в CE);
- `HotplugMemoryWithLiveMigration` — включить изменение размера памяти без перезагрузки через живую миграцию. (Не доступно в CE);
- `HotplugCPUInPlaceResize` - включить изменение количества ядер процессора без перезагрузки через InPlaceResize (Не доступно в CE)
- `HotplugMemoryInPlaceResize` - включить изменение размера памяти без перезагрузки через InPlaceResie (Не доступно в CE))
items:
type: string
1 change: 1 addition & 0 deletions templates/kubevirt/kubevirt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ spec:
- HostDevicesWithDRA
- HostDevices
- HotplugHostDevicesWithDRA # custom feature gate - added in our KubeVirt fork, not present in upstream
- InPlaceResize # custom feature gate - added in our KubeVirt fork, not present in upstream
virtualMachineOptions:
disableSerialConsoleLog: {}
customizeComponents:
Expand Down
6 changes: 6 additions & 0 deletions templates/kubevirt/virt-operator/rbac-for-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,12 @@ rules:
- pods/status
verbs:
- patch
- apiGroups:
- ""
resources:
- pods/resize
verbs:
- update
- apiGroups:
- ""
resources:
Expand Down
Loading