feat: add CD-ROM hotplug volumes#9937
Conversation
7100a20 to
668dd26
Compare
cea8ae0 to
e30a0ec
Compare
|
This pull request is now in conflict. Could you fix it @wheatdog? 🙏 |
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
| } | ||
|
|
||
| func SupportEjectCdRomVolume(vm *kubevirtv1.VirtualMachine) (bool, error) { | ||
| volumeMaps := map[string]struct{}{} |
There was a problem hiding this comment.
same as above
| volumeMaps := map[string]struct{}{} | |
| if runtime.GOARCH == "arm64" { | |
| return false, nil | |
| } | |
| volumeMaps := map[string]struct{}{} |
pkg/api/vm/handler.go
Outdated
| } | ||
|
|
||
| func (h *vmActionHandler) ejectCdRom(ctx context.Context, name, namespace string, diskNames []string) error { | ||
| func getSataCdRomDiskPos(vm *kubevirtv1.VirtualMachine, deviceName string) (int, error) { |
There was a problem hiding this comment.
I am a bit confused by this check and why we need to return device position
based on my reading https://kubevirt.io/user-guide/storage/hotplug_volumes/ as long as there is a cdrom available in the vm.spec.template.spec.devices[*].disk of type cdrom with a sata bus, we just need to add a hot pluggable volume in vm.spec.template.volumes with the same name as disk found from vm.spec.template.spec.devices[*].disk.
If there is no volume already attached to the cdrom disk, then we can hot plug a disk or if there is one present we can unplug the disk.
Looking and using the position to insert the volume is redundant.
There was a problem hiding this comment.
thanks, sorry I missed this comment. And yes, this turns out not just redundant but also problematic for cases like error out when inserting image to the last one of multiple empty cdrom. I've removed this and simplified the logic.
|
|
||
| // addVolume add a hotplug volume with given volume source and disk name. | ||
| // name -> VM name, namespace -> VM namespace, input.VolumeSourceName -> PVC name | ||
| func (h *vmActionHandler) addVolume(ctx context.Context, namespace, name string, input AddVolumeInput) error { |
There was a problem hiding this comment.
I found a regression to "Add Volume". The API return errors but the volume is actually attached successfully.
failed to update vm default/hp, error: Operation cannot be fulfilled on virtualmachines.kubevirt.io "hp": the object has been modified; please apply your changes to the latest version and try again
Screen.Recording.2026-02-06.at.3.51.23.PM.mov
It seems that "Detach Volume" is fine.
I'll take a look.
There was a problem hiding this comment.
This error comes from
harvester/pkg/api/vm/handler.go
Lines 957 to 965 in 5c83246
There was a problem hiding this comment.
@w13915984028 @ibrokethecloud in 1d28d54, I've migrated the existing addVolume/removeVolume functions to the new declarative way such that update is called once to prevent the error.
Screen.Recording.2026-02-06.at.6.22.34.PM.mov
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
|
This pull request is now in conflict. Could you fix it @wheatdog? 🙏 |
Signed-off-by: Tim Liou <tim.liou@suse.com>
w13915984028
left a comment
There was a problem hiding this comment.
A few last questions, thanks.
pkg/api/vm/formatter.go
Outdated
| } | ||
|
|
||
| func canInsertCdRomVolume(vm *kubevirtv1.VirtualMachine) bool { | ||
| if runtime.GOARCH == "arm64" { |
There was a problem hiding this comment.
it is better if the arm64 is defined as a const for public usage
| volumeMaps[volume.Name] = struct{}{} | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
L222 check len(volumeMaps) == 0 to return early
| continue | ||
| } | ||
| useSata := isDiskSataCdRom(&disk) | ||
| if !useSata { |
There was a problem hiding this comment.
this function is used for both UI menu render and webhook check, there are some differences:
UI render does not care error, as long as the first target is found, it could return directly, e.g. L236 could trigger return directly; and L233 could also cause UI render failure
webhook/controller check all devices to ensure no error
could we split it into two functions for each purpose?
There was a problem hiding this comment.
The idea is to separate 2 intentions:
- Capability of insertion/ejection
- Correctness of VM spec
Though, as offline discussed, I would like to stick with the current implementation for now. Thanks for the suggestion still!
I still kinda prefer having one function to handle both intentions since
- They are quite related. To determine the capability of insertion/ejection, we also need to validate the correctness of the corresponding part of VM spec.
- Their implementations are quite similar. They iterate volumes and disks in VM spec.
As for UI, it has its own logic canDoVolumeHotplugAction in UI PR instead of relying on VM action APIs.
| if !reflect.DeepEqual(vm, vmCopy) { | ||
| if _, err := h.vms.Update(vmCopy); err != nil { | ||
| return err | ||
| imgSize := max(vmImage.Status.VirtualSize, vmImage.Status.Size) |
There was a problem hiding this comment.
could we put L329~L366 to a new function and make insertCdRomVolume() shorter
There was a problem hiding this comment.
I prefer keeping it as is. The most of the space it took is related to initialization of pvc and kubevirt volume, which is the main point of this function.
There was a problem hiding this comment.
I have no strong options here, as long as CI does not complain.
Signed-off-by: Tim Liou <tim.liou@suse.com>
Signed-off-by: Tim Liou <tim.liou@suse.com>
|
This pull request is now in conflict. Could you fix it @wheatdog? 🙏 |
w13915984028
left a comment
There was a problem hiding this comment.
LGTM, thanks.
BTW, please squash the commits manually or utlize the gihtub merge & cut off some commit messages to make the final commit message shorter.
|
This pull request is now in conflict. Could you fix it @wheatdog? 🙏 |
79f317c
Problem:
To support inserting and ejecting CD-ROM volumes without a restart.
Solution:
According to the announcement, a new feature gate "DeclarativeHotplugVolumes" is introduced at KubeVirt 1.6 and the existing "HotplugVolumes" is going to be deprecated.
injectCdRomVolume: add a new entry to volumes from VM spec and volumeClaimTemplates from VM annotationejectCdRomVolume: remove the corresponding element from volumes and volumeClaimTemplates from VM. Then, delete the corresponding volume (pvc).ejectCdRomand related checks -> prefer the new actionejectCdRomVolumethat doesn't require a restart.VM mutator webhook would patch hotpluggable to true for volumes of SATA CD-ROM devices to enable hotplug volume automatically.-> For flexibility, this is handled from FE.For existing VMs with CD-ROM, the hotpluggable field would be patched when the VM is stopped / restarted. This is handled by-> Old VMs would act as is: see docs(hep): CD-ROM Hotplug Volumes [skip ci] #9840 (comment)vmControllerSetSataCdRomHotpluggable.kubernetes.Interfaceinstead ofkubernetes.Clientsetfor type annotations since it's an interface, which is easier to be mocked in unit tests.Related Issue(s):
#9261
#9779
Test plan:
DeclarativeHotplugVolumesfeature gate, perform basic checks to ensure existing volume hot-plug functionalities are not regressed.Additionally, please refer to the test plan in HEP: #9840
Additional documentation or context
https://kubevirt.io/user-guide/storage/hotplug_volumes/#inject-cd-rom