Skip to content
Open
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.25
3p-kubevirt: dvp/hotplug-cpu-fraction
3p-containerized-data-importer: v1.60.3-v12n.18
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 @@ -15,6 +15,7 @@ secrets:
shell:
install:
- |
echo "rebuild me 4"
echo "Git clone {{ $gitRepoName }} repository..."
git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,26 @@ func (c *comparatorCPU) Compare(current, desired *v1alpha2.VirtualMachineSpec) [
coresChangedAction = ActionRestart
}

fractionChangedAction := ActionApplyImmediate

// Require reboot if CPU hotplug is not enabled.
if !c.featureGate.Enabled(featuregates.HotplugCPUWithLiveMigration) {
coresChangedAction = ActionRestart
fractionChangedAction = ActionRestart
}

coresChanges := compareInts("cpu.cores", current.CPU.Cores, desired.CPU.Cores, 0, coresChangedAction)
fractionChanges := compareStrings("cpu.coreFraction", current.CPU.CoreFraction, desired.CPU.CoreFraction, DefaultCPUCoreFraction, ActionRestart)
fractionChanges := compareStrings("cpu.coreFraction", current.CPU.CoreFraction, desired.CPU.CoreFraction, DefaultCPUCoreFraction, fractionChangedAction)

// Yield full replace if both fields changed.
// Yield a full replace for cpu section if both fields are changed.
if HasChanges(coresChanges) && HasChanges(fractionChanges) {
return []FieldChange{
{
Operation: ChangeReplace,
Path: "cpu",
CurrentValue: current.CPU,
DesiredValue: desired.CPU,
ActionRequired: ActionRestart,
ActionRequired: MostDisruptiveAction(coresChangedAction, fractionChangedAction),
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ cpu:
),
},
{
"restart on cpu section change",
"restart on cpu section change when hotplug is disabled",
`
cpu:
cores: 2
Expand All @@ -88,6 +88,24 @@ cpu:
requirePathOperation("cpu", ChangeReplace),
),
},
{
"immediate apply on cpu section change when hotplug is enabled",
`
cpu:
cores: 2
coreFraction: 60%
`,
`
cpu:
cores: 6
coreFraction: 40%
`,
[]featuregate.Feature{featuregates.HotplugCPUWithLiveMigration},
assertChanges(
actionRequired(ActionApplyImmediate),
requirePathOperation("cpu", ChangeReplace),
),
},
{
"no restart cpu.coreFraction from empty to default value",
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

package vmchange

import "cmp"

type ChangeOperation string

const (
Expand All @@ -33,6 +35,12 @@ const (
ActionApplyImmediate ActionType = "ApplyImmediate"
)

var actionDisruptionOrder = map[ActionType]int{
ActionNone: 0,
ActionApplyImmediate: 1,
ActionRestart: 2,
}

type FieldChange struct {
Operation ChangeOperation `json:"operation,omitempty"`
Path string `json:"path,omitempty"`
Expand All @@ -50,3 +58,31 @@ func HasChanges(changes []FieldChange) bool {
}
return false
}

// MostDisruptiveAction returns a most dangerous action from the list.
func MostDisruptiveAction(actions ...ActionType) ActionType {
result := ActionNone
for _, action := range actions {
// Break immediately if 'action' is the most disruptive action.
if action == ActionRestart {
return action
}
if action.Cmp(result) == 1 {
result = action
}
}
return result
}

// Cmp returns 0 if the action is equal to 'other', -1 if the action is less harmless than 'other',
// or 1 if the action is more disruptive than 'other'.
func (a ActionType) Cmp(other ActionType) int {
aOrder, hasA := actionDisruptionOrder[a]
otherOrder, hasOther := actionDisruptionOrder[other]
if hasA && hasOther {
return cmp.Compare(aOrder, otherOrder)
}

// Should not reach here, but equal is safe.
return 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,5 @@ func (h *HotplugHandler) Name() string {
}

func getHotplugResourcesSum(vm *v1alpha2.VirtualMachine) string {
return fmt.Sprintf("cpu.cores=%d,memory.size=%s", vm.Spec.CPU.Cores, vm.Spec.Memory.Size.String())
return fmt.Sprintf("cpu.cores=%d,cpu.fraction=%s,memory.size=%s", vm.Spec.CPU.Cores, vm.Spec.CPU.CoreFraction, vm.Spec.Memory.Size.String())
}
Loading