From 0760a51f56ac6decf4139318a73f99e6f2d76d50 Mon Sep 17 00:00:00 2001 From: Tim Serong Date: Wed, 20 Mar 2024 19:53:02 +1100 Subject: [PATCH] Take image virtual size into account when creating VMs Prior to this, the default size for volumes attached to VMs was 10GiB, regardless of the size of the underlying image. This is fine if the image is smaller, but if the image is either physically larger (as in the case of a >10GiB ISO), or has a larger virtual size (as can be true with qcow2 images), the result is a corrupt volume. This commit fixes the problem by checking both the physical size and virtual size of the image, and using whichever is greater as the default size of the volume. Virtual size should always be >= physical size, but it is still theoretically possible for either value to be zero in case of error, so taking the greater of the two is the safest approach. There are two exceptions to the above rule: 1) For non-ISO images, if the image is < 10GiB, we still default to a size of 10GiB for consistency with the behaviour of earlier Harvester releases. The user can always lower this if they want/need to. 2) ISO images smaller than 1GiB will be given a size of 1GiB, simply because the size control in the UI is set to work in GiB units. It is actually possible to get a value of 0.2 GiB in there for a 200MiB ISO, but doing that is pretty ugly IMO, and there's no real harm in having the volume that backs a CD-ROM image be a bit larger than the source in this case. Related issue: https://github.com/harvester/harvester/issues/4905 Related issue: https://github.com/harvester/harvester/issues/2189 Signed-off-by: Tim Serong (cherry picked from commit ec15f49975d452332e7d99ab6688de102c8805b2) --- .../VirtualMachineVolume/type/vmImage.vue | 13 ++++++++++++- pkg/harvester/mixins/harvester-vm/index.js | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue index be545945fcf..68b46bb2881 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue @@ -140,8 +140,10 @@ export default { onImageChange() { const imageResource = this.$store.getters['harvester/all'](HCI.IMAGE)?.find( I => this.value.image === I.id); + const isIsoImage = /iso$/i.test(imageResource?.imageSuffix); + const imageSize = Math.max(imageResource?.status?.size, imageResource?.status?.virtualSize); - if (/iso$/i.test(imageResource?.imageSuffix)) { + if (isIsoImage) { this.$set(this.value, 'type', 'cd-rom'); this.$set(this.value, 'bus', 'sata'); } else { @@ -149,6 +151,15 @@ export default { this.$set(this.value, 'bus', 'virtio'); } + if (imageSize) { + let imageSizeGiB = Math.ceil(imageSize / 1024 / 1024 / 1024); + + if (!isIsoImage) { + imageSizeGiB = Math.max(imageSizeGiB, 10); + } + this.$set(this.value, 'size', `${ imageSizeGiB }Gi`); + } + this.update(); }, diff --git a/pkg/harvester/mixins/harvester-vm/index.js b/pkg/harvester/mixins/harvester-vm/index.js index 380ca00d767..17f0b729c6c 100644 --- a/pkg/harvester/mixins/harvester-vm/index.js +++ b/pkg/harvester/mixins/harvester-vm/index.js @@ -414,14 +414,26 @@ export default { if (_disks.length === 0) { let bus = 'virtio'; let type = HARD_DISK; + let size = '10Gi'; const imageResource = this.images.find( I => this.imageId === I.id); + const isIsoImage = /iso$/i.test(imageResource?.imageSuffix); + const imageSize = Math.max(imageResource?.status?.size, imageResource?.status?.virtualSize); - if (/iso$/i.test(imageResource?.imageSuffix)) { + if (isIsoImage) { bus = 'sata'; type = CD_ROM; } + if (imageSize) { + let imageSizeGiB = Math.ceil(imageSize / 1024 / 1024 / 1024); + + if (!isIsoImage) { + imageSizeGiB = Math.max(imageSizeGiB, 10); + } + size = `${ imageSizeGiB }Gi`; + } + out.push({ id: randomStr(5), source: SOURCE_TYPE.IMAGE, @@ -429,7 +441,7 @@ export default { accessMode: 'ReadWriteMany', bus, volumeName: '', - size: '10Gi', + size, type, storageClassName: '', image: this.imageId,