From 8bec498f3633b2a98010fde5c1cc95cd37487f2c Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 25 Nov 2025 18:11:22 +0300 Subject: [PATCH 1/9] refactor(kubevirt): bump version to 1.6.2 Signed-off-by: Dmitry Lopatin --- Taskfile.yaml | 8 +- api/client/examples/cancel-evacuation/go.mod | 4 +- api/client/examples/cancel-evacuation/go.sum | 2 + api/client/examples/list-resources/go.mod | 4 +- api/client/examples/list-resources/go.sum | 2 + api/go.mod | 6 +- api/go.sum | 4 + build/components/versions.yml | 2 +- crds/embedded/virtualmachineinstances.yaml | 472 ++++++++++++++++-- crds/embedded/virtualmachines.yaml | 426 ++++++++++++++-- images/hooks/go.mod | 2 +- images/hooks/go.sum | 4 +- images/virt-api/debug/dlv.Dockerfile | 10 +- images/virt-artifact/werf.inc.yaml | 2 +- images/virt-controller/debug/dlv.Dockerfile | 10 +- images/virt-handler/debug/dlv.Dockerfile | 20 +- images/virt-handler/werf.inc.yaml | 4 - images/virtualization-artifact/go.mod | 4 +- images/virtualization-artifact/go.sum | 4 +- .../livemigration/migration_configuration.go | 3 + images/vm-route-forge/go.mod | 5 +- images/vm-route-forge/go.sum | 10 +- src/cli/go.mod | 4 +- src/cli/go.sum | 4 + templates/kubevirt/kubevirt.yaml | 4 - .../kubevirt/virt-operator/rbac-for-us.yaml | 15 + test/e2e/go.mod | 2 +- test/e2e/go.sum | 2 + 28 files changed, 899 insertions(+), 140 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 93eef4dcee..020d59f4f7 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -165,8 +165,7 @@ tasks: "ports": [ { "containerPort": 2345, "name": "dlv" } ], "readinessProbe": null, "livenessProbe": null, - "command": null, - "args": [] + "command": null }, { "name": "proxy", @@ -264,8 +263,7 @@ tasks: "ports": [ { "containerPort": 2345, "name": "dlv" } ], "readinessProbe": null, "livenessProbe": null, - "command": null, - "args": [] + "command": null }, { "name": "proxy", @@ -282,5 +280,5 @@ tasks: } } }' - kubectl -n d8-virtualization port-forward deploy/vit-api 2345:2345 + kubectl -n d8-virtualization port-forward deploy/virt-api 2345:2345 EOF diff --git a/api/client/examples/cancel-evacuation/go.mod b/api/client/examples/cancel-evacuation/go.mod index 63f821ce75..86339fe572 100644 --- a/api/client/examples/cancel-evacuation/go.mod +++ b/api/client/examples/cancel-evacuation/go.mod @@ -53,8 +53,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/api/client/examples/cancel-evacuation/go.sum b/api/client/examples/cancel-evacuation/go.sum index d7db165b6a..cf69ab2158 100644 --- a/api/client/examples/cancel-evacuation/go.sum +++ b/api/client/examples/cancel-evacuation/go.sum @@ -372,8 +372,10 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= diff --git a/api/client/examples/list-resources/go.mod b/api/client/examples/list-resources/go.mod index 8251bcd219..9888494628 100644 --- a/api/client/examples/list-resources/go.mod +++ b/api/client/examples/list-resources/go.mod @@ -49,8 +49,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/api/client/examples/list-resources/go.sum b/api/client/examples/list-resources/go.sum index 3dba2c12dd..2e9bbd8060 100644 --- a/api/client/examples/list-resources/go.sum +++ b/api/client/examples/list-resources/go.sum @@ -365,8 +365,10 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= diff --git a/api/go.mod b/api/go.mod index 79b0495d1e..a4b3951825 100644 --- a/api/go.mod +++ b/api/go.mod @@ -17,7 +17,8 @@ require ( k8s.io/apiextensions-apiserver v0.33.3 k8s.io/apimachinery v0.33.3 k8s.io/client-go v0.33.3 - kubevirt.io/api v1.3.1 + k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 + kubevirt.io/api v1.6.2 sigs.k8s.io/controller-runtime v0.21.0 ) @@ -70,9 +71,8 @@ require ( k8s.io/code-generator v0.33.3 // indirect k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-tools v0.18.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect diff --git a/api/go.sum b/api/go.sum index fd5f073e7c..620d6a5a4a 100644 --- a/api/go.sum +++ b/api/go.sum @@ -570,8 +570,12 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/build/components/versions.yml b/build/components/versions.yml index 906d683c8a..d542b6d5ed 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.3.1-v12n.25 + 3p-kubevirt: v1.6.2-v12n.0.dlopatin7 3p-containerized-data-importer: v1.60.3-v12n.12 distribution: 2.8.3 package: diff --git a/crds/embedded/virtualmachineinstances.yaml b/crds/embedded/virtualmachineinstances.yaml index b9cc1d5949..b676c9ed3a 100644 --- a/crds/embedded/virtualmachineinstances.yaml +++ b/crds/embedded/virtualmachineinstances.yaml @@ -461,7 +461,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -476,7 +476,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -642,7 +642,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -657,7 +657,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -820,7 +820,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -835,7 +835,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1001,7 +1001,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1016,7 +1016,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1127,9 +1127,12 @@ spec: of a pod. properties: name: - description: Required. + description: |- + Name is this DNS resolver option's name. + Required. type: string value: + description: Value is this DNS resolver option's value. type: string type: object type: array @@ -1447,7 +1450,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the vmi. @@ -1567,12 +1574,24 @@ spec: description: Whether to attach a GPU device to the vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: + description: DeviceName is the name of the device provisioned + by device-plugins type: string name: description: Name of the GPU device as exposed by a device plugin type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest @@ -1601,7 +1620,6 @@ spec: type: object type: object required: - - deviceName - name type: object type: array @@ -1610,19 +1628,28 @@ spec: description: Whether to attach a host device to the vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: - description: DeviceName is the resource name of the - host device exposed by a device plugin + description: DeviceName is the name of the device provisioned + by device-plugins type: string name: type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive type: string required: - - deviceName - name type: object type: array @@ -1743,9 +1770,8 @@ spec: model: description: |- Interface model. - One of: e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio. + One of: e1000, e1000e, igb, ne2k_pci, pcnet, rtl8139, virtio. Defaults to virtio. - TODO:(ihar) switch to enums once opengen-api supports them. See: https://github.com/kubernetes/kube-openapi/issues/51 type: string name: description: |- @@ -1805,7 +1831,11 @@ spec: state: description: |- State represents the requested operational state of the interface. - The (only) value supported is 'absent', expressing a request to remove the interface. + The supported values are: + 'absent', expressing a request to remove the interface. + 'down', expressing a request to set the link down. + 'up', expressing a request to set the link up. + Empty value functions as 'up'. type: string tag: description: If specified, the virtual network interface @@ -1831,6 +1861,19 @@ spec: depends on additional factors of the VirtualMachineInstance, like the number of guest CPUs. type: boolean + panicDevices: + description: PanicDevices provides additional crash information + when a guest crashes. + items: + properties: + model: + description: |- + Model specifies what type of panic device is provided. + The panic model used when this attribute is missing depends on the hypervisor and guest arch. + One of: isa, hyperv, pvpanic. + type: string + type: object + type: array rng: description: Whether to have random number generator from host @@ -1853,6 +1896,11 @@ spec: tpm: description: Whether to emulate a TPM device. properties: + enabled: + description: |- + Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine + Defaults to True + type: boolean persistent: description: |- Persistent indicates the state of the TPM device should be kept accross reboots @@ -1865,10 +1913,30 @@ spec: This is helpful for old machines like CentOS6 or RHEL6 which do not understand virtio_non_transitional (virtio 1.0). type: boolean + video: + description: Video describes the video device configuration + for the vmi. + properties: + type: + description: |- + Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + type: string + type: object watchdog: description: Watchdog describes a watchdog device which can be added to the vmi. properties: + diag288: + description: diag288 watchdog device (specific to s390x + architecture). + properties: + action: + description: |- + The action to take. Valid values are poweroff, reset, shutdown. + Defaults to reset. + type: string + type: object i6300esb: description: i6300esb watchdog device. properties: @@ -2138,6 +2206,11 @@ spec: acpi: description: Information that can be set in the ACPI table properties: + msdmNameRef: + description: |- + Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. + The above points to the spec of MSDM too. + type: string slicNameRef: description: |- SlicNameRef should match the volume name of a secret object. The data in the secret should @@ -2221,11 +2294,20 @@ spec: Defaults to a random generated uid. type: string type: object + ioThreads: + description: IOThreads specifies the IOThreads options. + properties: + supplementalPoolThreadCount: + description: SupplementalPoolThreadCount specifies how many + iothreads are allocated for the supplementalPool policy. + format: int32 + type: integer + type: object ioThreadsPolicy: description: |- Controls whether or not disks will share IOThreads. Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto + One of: shared, auto, supplementalPool type: string launchSecurity: description: Launch Security setting of the vmi. @@ -2340,7 +2422,7 @@ spec: - "None": No action will be taken, according to the specified 'RunStrategy' the VirtualMachine will be restarted or shutdown. - "LiveMigrate": the VirtualMachineInstance will be migrated instead of being shutdown. - "LiveMigrateIfPossible": the same as "LiveMigrate" but only if the VirtualMachine is Live-Migratable, otherwise it will behave as "None". - - "External": the VirtualMachineInstance will be protected by a PDB and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. + - "External": the VirtualMachineInstance will be protected and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. type: string hostname: description: |- @@ -2453,7 +2535,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -2652,7 +2733,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -2682,6 +2762,65 @@ spec: format: int32 type: integer type: object + resourceClaims: + description: |- + ResourceClaims define which ResourceClaims must be allocated + and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources + will be made available to the domain which consumes them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate in kubernetes + https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map schedulerName: description: |- If specified, the VMI will be dispatched by specified scheduler. @@ -2809,7 +2948,6 @@ spec: Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string @@ -2849,7 +2987,6 @@ spec: Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | @@ -2867,7 +3004,6 @@ spec: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -2879,7 +3015,6 @@ spec: has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. - If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -2952,10 +3087,13 @@ spec: that contains config drive networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2964,10 +3102,13 @@ spec: contains config drive userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2999,10 +3140,13 @@ spec: that contains NoCloud networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3011,10 +3155,13 @@ spec: contains NoCloud userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3033,10 +3180,13 @@ spec: More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or it's keys @@ -3076,6 +3226,8 @@ spec: description: Path defines the path to disk file in the container type: string hotpluggable: + description: Hotpluggable indicates whether the volume can + be hotplugged and hotunplugged. type: boolean required: - image @@ -3090,9 +3242,8 @@ spec: be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the PVC in + the same namespace. type: string required: - name @@ -3340,10 +3491,13 @@ spec: be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3353,10 +3507,13 @@ spec: be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3436,6 +3593,97 @@ spec: format: int32 type: integer type: object + deviceStatus: + description: |- + DeviceStatus reflects the state of devices requested in spec.domain.devices. This is an optional field available + only when DRA feature gate is enabled + This field will only be populated if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + properties: + gpuStatuses: + description: GPUStatuses reflects the state of GPUs requested + in spec.domain.devices.gpus + items: + properties: + deviceResourceClaimStatus: + description: DeviceResourceClaimStatus reflects the DRA + related information for the device + properties: + attributes: + description: |- + Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more + about the device, like pciAddress or mdevUUID + properties: + mDevUUID: + description: MDevUUID is the mediated device uuid + of the allocated device + type: string + pciAddress: + description: PCIAddress is the PCIe bus address + of the allocated device + type: string + type: object + name: + description: Name is the name of actual device on the + host provisioned by the driver as reflected in resourceclaim.status + type: string + resourceClaimName: + description: ResourceClaimName is the name of the resource + claims object used to provision this resource + type: string + type: object + name: + description: Name of the device as specified in spec.domain.devices.gpus.name + or spec.domain.devices.hostDevices.name + type: string + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + hostDeviceStatuses: + description: |- + HostDeviceStatuses reflects the state of GPUs requested in spec.domain.devices.hostDevices + DRA + items: + properties: + deviceResourceClaimStatus: + description: DeviceResourceClaimStatus reflects the DRA + related information for the device + properties: + attributes: + description: |- + Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more + about the device, like pciAddress or mdevUUID + properties: + mDevUUID: + description: MDevUUID is the mediated device uuid + of the allocated device + type: string + pciAddress: + description: PCIAddress is the PCIe bus address + of the allocated device + type: string + type: object + name: + description: Name is the name of actual device on the + host provisioned by the driver as reflected in resourceclaim.status + type: string + resourceClaimName: + description: ResourceClaimName is the name of the resource + claims object used to provision this resource + type: string + type: object + name: + description: Name of the device as specified in spec.domain.devices.gpus.name + or spec.domain.devices.hostDevices.name + type: string + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object evacuationNodeName: description: |- EvacuationNodeName is used to track the eviction process of a VMI. It stores the name of the node that we want @@ -3443,8 +3691,9 @@ spec: type: string fsFreezeStatus: description: |- - FSFreezeStatus is the state of the fs of the guest - it can be either frozen or thawed + FSFreezeStatus indicates whether a freeze operation was requested for the guest filesystem. + It will be set to "frozen" if the request was made, or unset otherwise. + This does not reflect the actual state of the guest filesystem. type: string guestOSInfo: description: Guest OS Information @@ -3496,6 +3745,10 @@ spec: items: type: string type: array + linkState: + description: 'LinkState Reports the current operational link + state''. values: up, down.' + type: string mac: description: Hardware address of a Virtual Machine interface type: string @@ -3503,6 +3756,10 @@ spec: description: Name of the interface, corresponds to name of the network assigned to the interface type: string + podInterfaceName: + description: PodInterfaceName represents the name of the pod + network interface + type: string queueCount: description: Specifies how many queues are allocated by MultiQueue format: int32 @@ -3731,6 +3988,13 @@ spec: If set to true, migrations will still start in pre-copy, but switch to post-copy when CompletionTimeoutPerGiB triggers. Defaults to false type: boolean + allowWorkloadDisruption: + description: |- + AllowWorkloadDisruption indicates that the migration shouldn't be + canceled after acceptableCompletionTime is exceeded. Instead, if + permitted, migration will be switched to post-copy or the VMI will be + paused to allow the migration to complete + type: boolean bandwidthPerMigration: anyOf: - type: integer @@ -3743,8 +4007,8 @@ spec: completionTimeoutPerGiB: description: |- CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take. - If a live-migration takes longer to migrate than this value multiplied by the size of the VMI, - the migration will be cancelled, unless AllowPostCopy is true. Defaults to 800 + If the timeout is reached, the migration will be either paused, switched + to post-copy or cancelled depending on other settings. Defaults to 150 format: int64 type: integer disableTLS: @@ -3794,6 +4058,9 @@ spec: indicates the migration will be unsafe to the guest. Defaults to false type: boolean type: object + migrationNetworkType: + description: The type of migration network, either 'pod' or 'migration' + type: string migrationPolicyName: description: Name of the migration policy. If string is empty, no policy is matched @@ -3809,8 +4076,57 @@ spec: sourceNode: description: The source node that the VMI originated on type: string + sourcePersistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string sourcePod: type: string + sourceState: + description: SourceState contains migration state managed by the + source virt handler + properties: + domainName: + description: The name of the domain on the source libvirt + domain + type: string + domainNamespace: + description: Namespace used in the name of the source libvirt + domain. Can be used to find and modify paths in the domain + type: string + migrationUID: + description: The Source VirtualMachineInstanceMigration object + associated with this migration + type: string + node: + description: The source node that the VMI originated on + type: string + nodeSelectors: + additionalProperties: + type: string + description: Node selectors needed by the target to start + the receiving pod. + type: object + persistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string + pod: + description: The source pod that the VMI is originated on + type: string + selinuxContext: + description: SELinuxContext is the actual SELinux context + of the pod + type: string + syncAddress: + description: The ip address/fqdn:port combination to use to + synchronize the VMI with the target. + type: string + virtualMachineInstanceUID: + description: VirtualMachineInstanceUID is the UID of the target + virtual machine instance + type: string + type: object startTimestamp: description: The time the migration action began format: date-time @@ -3853,9 +4169,87 @@ spec: If the VMI requires dedicated CPUs, this field will hold the numa topology on the target node type: string + targetPersistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its target PVC name is saved here + type: string targetPod: description: The target pod that the VMI is moving to type: string + targetState: + description: TargetState contains migration state managed by the + target virt handler + properties: + attachmentPodUID: + description: The UID of the target attachment pod for hotplug + volumes + type: string + cpuSet: + description: |- + If the VMI requires dedicated CPUs, this field will + hold the dedicated CPU set on the target node + items: + type: integer + type: array + x-kubernetes-list-type: atomic + directMigrationNodePorts: + additionalProperties: + type: integer + description: The list of ports opened for live migration on + the destination node + type: object + domainDetected: + description: The Target Node has seen the Domain Start Event + type: boolean + domainName: + description: The name of the domain on the source libvirt + domain + type: string + domainNamespace: + description: Namespace used in the name of the source libvirt + domain. Can be used to find and modify paths in the domain + type: string + domainReadyTimestamp: + description: The timestamp at which the target node detects + the domain is active + format: date-time + type: string + migrationUID: + description: The Source VirtualMachineInstanceMigration object + associated with this migration + type: string + node: + description: The source node that the VMI originated on + type: string + nodeAddress: + description: The address of the target node to use for the + migration + type: string + nodeTopology: + description: |- + If the VMI requires dedicated CPUs, this field will + hold the numa topology on the target node + type: string + persistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string + pod: + description: The source pod that the VMI is originated on + type: string + selinuxContext: + description: SELinuxContext is the actual SELinux context + of the pod + type: string + syncAddress: + description: The ip address/fqdn:port combination to use to + synchronize the VMI with the target. + type: string + virtualMachineInstanceUID: + description: VirtualMachineInstanceUID is the UID of the target + virtual machine instance + type: string + type: object type: object migrationTransport: description: This represents the migration transport diff --git a/crds/embedded/virtualmachines.yaml b/crds/embedded/virtualmachines.yaml index 72d9f865f6..a0bfe284f4 100644 --- a/crds/embedded/virtualmachines.yaml +++ b/crds/embedded/virtualmachines.yaml @@ -319,7 +319,7 @@ spec: set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -812,6 +812,7 @@ spec: description: |- Running controls whether the associatied VirtualMachineInstance is created or not Mutually exclusive with RunStrategy + Deprecated: VirtualMachineInstance field "Running" is now deprecated, please use RunStrategy instead. type: boolean template: description: Template is the direct specification of VirtualMachineInstance @@ -1219,7 +1220,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1234,7 +1235,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1402,7 +1403,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1417,7 +1418,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1583,7 +1584,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1598,7 +1599,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1766,7 +1767,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1781,7 +1782,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1894,9 +1895,13 @@ spec: options of a pod. properties: name: - description: Required. + description: |- + Name is this DNS resolver option's name. + Required. type: string value: + description: Value is this DNS resolver option's + value. type: string type: object type: array @@ -2217,7 +2222,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the @@ -2344,12 +2353,24 @@ spec: vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: + description: DeviceName is the name of the device + provisioned by device-plugins type: string name: description: Name of the GPU device as exposed by a device plugin type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided @@ -2388,19 +2409,28 @@ spec: vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: - description: DeviceName is the resource name - of the host device exposed by a device plugin + description: DeviceName is the name of the device + provisioned by device-plugins type: string name: type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive type: string required: - - deviceName - name type: object type: array @@ -2523,9 +2553,8 @@ spec: model: description: |- Interface model. - One of: e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio. + One of: e1000, e1000e, igb, ne2k_pci, pcnet, rtl8139, virtio. Defaults to virtio. - TODO:(ihar) switch to enums once opengen-api supports them. See: https://github.com/kubernetes/kube-openapi/issues/51 type: string name: description: |- @@ -2587,7 +2616,11 @@ spec: state: description: |- State represents the requested operational state of the interface. - The (only) value supported is 'absent', expressing a request to remove the interface. + The supported values are: + 'absent', expressing a request to remove the interface. + 'down', expressing a request to set the link down. + 'up', expressing a request to set the link up. + Empty value functions as 'up'. type: string tag: description: If specified, the virtual network @@ -2614,6 +2647,19 @@ spec: of the VirtualMachineInstance, like the number of guest CPUs. type: boolean + panicDevices: + description: PanicDevices provides additional crash + information when a guest crashes. + items: + properties: + model: + description: |- + Model specifies what type of panic device is provided. + The panic model used when this attribute is missing depends on the hypervisor and guest arch. + One of: isa, hyperv, pvpanic. + type: string + type: object + type: array rng: description: Whether to have random number generator from host @@ -2637,6 +2683,11 @@ spec: tpm: description: Whether to emulate a TPM device. properties: + enabled: + description: |- + Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine + Defaults to True + type: boolean persistent: description: |- Persistent indicates the state of the TPM device should be kept accross reboots @@ -2649,10 +2700,30 @@ spec: This is helpful for old machines like CentOS6 or RHEL6 which do not understand virtio_non_transitional (virtio 1.0). type: boolean + video: + description: Video describes the video device configuration + for the vmi. + properties: + type: + description: |- + Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + type: string + type: object watchdog: description: Watchdog describes a watchdog device which can be added to the vmi. properties: + diag288: + description: diag288 watchdog device (specific + to s390x architecture). + properties: + action: + description: |- + The action to take. Valid values are poweroff, reset, shutdown. + Defaults to reset. + type: string + type: object i6300esb: description: i6300esb watchdog device. properties: @@ -2923,6 +2994,11 @@ spec: description: Information that can be set in the ACPI table properties: + msdmNameRef: + description: |- + Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. + The above points to the spec of MSDM too. + type: string slicNameRef: description: |- SlicNameRef should match the volume name of a secret object. The data in the secret should @@ -3009,11 +3085,21 @@ spec: Defaults to a random generated uid. type: string type: object + ioThreads: + description: IOThreads specifies the IOThreads options. + properties: + supplementalPoolThreadCount: + description: SupplementalPoolThreadCount specifies + how many iothreads are allocated for the supplementalPool + policy. + format: int32 + type: integer + type: object ioThreadsPolicy: description: |- Controls whether or not disks will share IOThreads. Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto + One of: shared, auto, supplementalPool type: string launchSecurity: description: Launch Security setting of the vmi. @@ -3129,7 +3215,7 @@ spec: - "None": No action will be taken, according to the specified 'RunStrategy' the VirtualMachine will be restarted or shutdown. - "LiveMigrate": the VirtualMachineInstance will be migrated instead of being shutdown. - "LiveMigrateIfPossible": the same as "LiveMigrate" but only if the VirtualMachine is Live-Migratable, otherwise it will behave as "None". - - "External": the VirtualMachineInstance will be protected by a PDB and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. + - "External": the VirtualMachineInstance will be protected and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. type: string hostname: description: |- @@ -3242,7 +3328,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -3441,7 +3526,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -3471,6 +3555,65 @@ spec: format: int32 type: integer type: object + resourceClaims: + description: |- + ResourceClaims define which ResourceClaims must be allocated + and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources + will be made available to the domain which consumes them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate in kubernetes + https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map schedulerName: description: |- If specified, the VMI will be dispatched by specified scheduler. @@ -3600,7 +3743,6 @@ spec: Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string @@ -3640,7 +3782,6 @@ spec: Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | @@ -3658,7 +3799,6 @@ spec: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -3670,7 +3810,6 @@ spec: has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. - If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -3743,10 +3882,13 @@ spec: secret that contains config drive networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3755,10 +3897,13 @@ spec: secret that contains config drive userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3790,10 +3935,13 @@ spec: secret that contains NoCloud networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3802,10 +3950,13 @@ spec: secret that contains NoCloud userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3824,10 +3975,13 @@ spec: More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or it's @@ -3882,9 +4036,8 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the + PVC in the same namespace. type: string required: - name @@ -4137,10 +4290,13 @@ spec: that should be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -4150,10 +4306,13 @@ spec: that should be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -4219,6 +4378,35 @@ spec: updated through an Update() before ObservedGeneration in Status. format: int64 type: integer + instancetypeRef: + description: InstancetypeRef captures the state of any referenced + instance type from the VirtualMachine + nullable: true + properties: + controllerRevisionRef: + description: |- + ControllerRef specifies the ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller + properties: + name: + description: Name of the ControllerRevision + type: string + type: object + inferFromVolume: + description: InferFromVolume lists the name of a volume that should + be used to infer or discover the resource + type: string + inferFromVolumeFailurePolicy: + description: InferFromVolumeFailurePolicy controls what should + happen on failure when inferring the resource + type: string + kind: + description: Kind specifies the kind of resource + type: string + name: + description: Name is the name of resource + type: string + type: object memoryDumpRequest: description: |- MemoryDumpRequest tracks memory dump request phase and info of getting a memory @@ -4262,6 +4450,35 @@ spec: vmi when started. format: int64 type: integer + preferenceRef: + description: PreferenceRef captures the state of any referenced preference + from the VirtualMachine + nullable: true + properties: + controllerRevisionRef: + description: |- + ControllerRef specifies the ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller + properties: + name: + description: Name of the ControllerRevision + type: string + type: object + inferFromVolume: + description: InferFromVolume lists the name of a volume that should + be used to infer or discover the resource + type: string + inferFromVolumeFailurePolicy: + description: InferFromVolumeFailurePolicy controls what should + happen on failure when inferring the resource + type: string + kind: + description: Kind specifies the kind of resource + type: string + name: + description: Name is the name of resource + type: string + type: object printableStatus: default: Stopped description: PrintableStatus is a human readable, high-level representation @@ -4378,7 +4595,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the vmi. @@ -4531,9 +4752,8 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the + PVC in the same namespace. type: string required: - name @@ -4615,6 +4835,134 @@ spec: - name type: object type: array + volumeUpdateState: + description: |- + VolumeUpdateState contains the information about the volumes set + updates related to the volumeUpdateStrategy + properties: + volumeMigrationState: + description: VolumeMigrationState tracks the information related + to the volume migration + properties: + migratedVolumes: + description: MigratedVolumes lists the source and destination + volumes during the volume migration + items: + description: StorageMigratedVolumeInfo tracks the information + about the source and destination volumes during the volume + migration + properties: + destinationPVCInfo: + description: DestinationPVCInfo contains the information + about the destination PVC + properties: + accessModes: + description: |- + AccessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents the capacity set + on the corresponding PVC status + type: object + claimName: + description: ClaimName is the name of the PVC + type: string + filesystemOverhead: + description: Percentage of filesystem's size to + be reserved when resizing the PVC + pattern: ^(0(?:\.\d{1,3})?|1)$ + type: string + preallocated: + description: Preallocated indicates if the PVC's + storage is preallocated or not + type: boolean + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Requests represents the resources requested + by the corresponding PVC spec + type: object + volumeMode: + description: |- + VolumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + type: object + sourcePVCInfo: + description: SourcePVCInfo contains the information + about the source PVC + properties: + accessModes: + description: |- + AccessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents the capacity set + on the corresponding PVC status + type: object + claimName: + description: ClaimName is the name of the PVC + type: string + filesystemOverhead: + description: Percentage of filesystem's size to + be reserved when resizing the PVC + pattern: ^(0(?:\.\d{1,3})?|1)$ + type: string + preallocated: + description: Preallocated indicates if the PVC's + storage is preallocated or not + type: boolean + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Requests represents the resources requested + by the corresponding PVC spec + type: object + volumeMode: + description: |- + VolumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + type: object + volumeName: + description: VolumeName is the name of the volume that + is being migrated + type: string + required: + - volumeName + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object type: object required: - spec diff --git a/images/hooks/go.mod b/images/hooks/go.mod index bb211a4a08..3aa044a027 100644 --- a/images/hooks/go.mod +++ b/images/hooks/go.mod @@ -105,7 +105,7 @@ require ( k8s.io/component-base v0.33.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect - kubevirt.io/api v1.3.1 // indirect + kubevirt.io/api v1.6.2 // indirect kubevirt.io/containerized-data-importer-api v1.60.3 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-runtime v0.21.0 // indirect diff --git a/images/hooks/go.sum b/images/hooks/go.sum index 4433af27eb..663744542f 100644 --- a/images/hooks/go.sum +++ b/images/hooks/go.sum @@ -623,8 +623,8 @@ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= -kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.60.3 h1:kQEXi7scpzUa0RPf3/3MKk1Kmem0ZlqqiuK3kDF5L2I= kubevirt.io/containerized-data-importer-api v1.60.3/go.mod h1:8mwrkZIdy8j/LmCyKt2wFXbiMavLUIqDaegaIF67CZs= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= diff --git a/images/virt-api/debug/dlv.Dockerfile b/images/virt-api/debug/dlv.Dockerfile index bca504a4d3..fe10ced68b 100644 --- a/images/virt-api/debug/dlv.Dockerfile +++ b/images/virt-api/debug/dlv.Dockerfile @@ -1,10 +1,10 @@ -FROM golang:1.22.7 AS builder +FROM golang:1.23 AS builder RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="1.6.2-virtualization" +ENV VERSION="1.6.2" +ENV GOVERSION="1.23.0" # Copy the git commits for rebuilding the image if the branch changes ADD "https://api.github.com/repos/deckhouse/3p-kubevirt/commits/$BRANCH" /.git-commit-hash.tmp @@ -14,7 +14,7 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor ENV GO111MODULE=on ENV GOOS=linux diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 33742cfd40..8a5235efe0 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -83,7 +83,7 @@ shell: cd /kubevirt go mod download - go mod vendor + go work vendor for p in patches/*.patch ; do echo -n "Apply ${p} ... " diff --git a/images/virt-controller/debug/dlv.Dockerfile b/images/virt-controller/debug/dlv.Dockerfile index ab4f9606db..fec4948301 100644 --- a/images/virt-controller/debug/dlv.Dockerfile +++ b/images/virt-controller/debug/dlv.Dockerfile @@ -1,10 +1,10 @@ -FROM golang:1.22.7 AS builder +FROM golang:1.23 AS builder RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="v1.6.1-virtualization" +ENV VERSION="1.6.1" +ENV GOVERSION="1.23.0" # Copy the git commits for rebuilding the image if the branch changes ADD "https://api.github.com/repos/deckhouse/3p-kubevirt/commits/$BRANCH" /.git-commit-hash.tmp @@ -14,7 +14,7 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor ENV GO111MODULE=on ENV GOOS=linux diff --git a/images/virt-handler/debug/dlv.Dockerfile b/images/virt-handler/debug/dlv.Dockerfile index 12142d5178..86af33b002 100644 --- a/images/virt-handler/debug/dlv.Dockerfile +++ b/images/virt-handler/debug/dlv.Dockerfile @@ -3,6 +3,7 @@ RUN groupadd --gid 1001 nonroot-user && useradd nonroot-user --uid 1001 --gid 10 FROM basealt AS builder +# TODO add pin repository url RUN apt-get update RUN apt-get install -y \ @@ -17,9 +18,9 @@ RUN apt-get install -y \ RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="1.6.2-virtualization" +ENV VERSION="1.6.2" +ENV GOVERSION="1.23.0" RUN mkdir /kubevirt-config-files && echo "v$VERSION-dirty" > /kubevirt-config-files/.version @@ -31,11 +32,11 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor -RUN for p in patches/*.patch ; do \ - echo -n "Apply ${p} ... " \ - git apply --ignore-space-change --ignore-whitespace ${p} && echo OK || (echo FAIL ; exit 1) \ +RUN for p in patches/*.patch; do \ + echo -n "Apply ${p} ... " && \ + git apply --ignore-space-change --ignore-whitespace "${p}" && echo OK || (echo FAIL && exit 1); \ done ENV GO111MODULE=on @@ -52,9 +53,7 @@ FROM basealt RUN apt-get update && apt-get install --yes \ acl \ procps \ - nftables \ - qemu-img==9.1.2-alt1 \ - xorriso==1.5.6-alt1 && \ + nftables && \ apt-get clean && \ rm --recursive --force /var/lib/apt/lists/ftp.altlinux.org* /var/cache/apt/*.bin @@ -63,7 +62,6 @@ RUN echo "qemu:x:107:107::/home/qemu:/bin/bash" >> /etc/passwd && \ mkdir -p /home/qemu && \ chown -R 107:107 /home/qemu -COPY --from=builder /kubevirt/cmd/virt-handler/virt_launcher.cil /virt_launcher.cil COPY --from=builder /kubevirt-config-files/.version /.version COPY --from=builder /kubevirt/cmd/virt-handler/nsswitch.conf /etc/nsswitch.conf diff --git a/images/virt-handler/werf.inc.yaml b/images/virt-handler/werf.inc.yaml index 4888e05684..3db87a474a 100644 --- a/images/virt-handler/werf.inc.yaml +++ b/images/virt-handler/werf.inc.yaml @@ -25,10 +25,6 @@ import: - virt-chroot - virt-handler - container-disk -- image: {{ .ModuleNamePrefix }}virt-artifact - add: /kubevirt/cmd/{{ $.ImageName }}/virt_launcher.cil - to: /virt_launcher.cil - after: install - image: {{ .ModuleNamePrefix }}virt-artifact add: /kubevirt-config-files/.version to: /.version diff --git a/images/virtualization-artifact/go.mod b/images/virtualization-artifact/go.mod index 3ade7764fa..c8ed344d7a 100644 --- a/images/virtualization-artifact/go.mod +++ b/images/virtualization-artifact/go.mod @@ -32,7 +32,7 @@ require ( k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - kubevirt.io/api v1.3.1 + kubevirt.io/api v1.6.2 kubevirt.io/containerized-data-importer-api v1.60.3 sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/yaml v1.4.0 @@ -165,4 +165,4 @@ replace ( ) // Kubevirt API replaces -replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18 +replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0 diff --git a/images/virtualization-artifact/go.sum b/images/virtualization-artifact/go.sum index 39d45d303a..db865f72ea 100644 --- a/images/virtualization-artifact/go.sum +++ b/images/virtualization-artifact/go.sum @@ -45,8 +45,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18 h1:9pstD3PiPmby/Chh24ickwUNbAcqbceOPp253/jSr8k= -github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0 h1:Ro9oG/eakqMxfFSEs91BZYhDXggghuJjFvawV6/EKSo= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5 h1:PsN1E0oxC/+4zdA977txrqUCuObFL3HAuu5Xnud8m8c= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5/go.mod h1:Mk5HRzkc5pIcDIZ2JJ6DPuuqnwhXVkb3you8M8Mg+4w= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= diff --git a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go index 21910bc868..0fe5d9851a 100644 --- a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go +++ b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go @@ -38,6 +38,7 @@ const ( MigrationCompletionTimeoutPerGiB int64 = 800 DefaultUnsafeMigrationOverride bool = false MigrationAllowPostCopy bool = false + MigrationAllowWorkloadDisruption bool = false ) func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) *virtv1.MigrationConfiguration { @@ -63,6 +64,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) completionTimeoutPerGiB := MigrationCompletionTimeoutPerGiB defaultUnsafeMigrationOverride := DefaultUnsafeMigrationOverride allowPostCopy := MigrationAllowPostCopy + allowWorkloadDisruption := MigrationAllowWorkloadDisruption return &virtv1.MigrationConfiguration{ ParallelMigrationsPerCluster: ¶llelMigrationsPerCluster, @@ -74,6 +76,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) UnsafeMigrationOverride: &defaultUnsafeMigrationOverride, AllowAutoConverge: &allowAutoConverge, AllowPostCopy: &allowPostCopy, + AllowWorkloadDisruption: &allowWorkloadDisruption, DisableTLS: nil, Network: nil, MatchSELinuxLevelOnMigration: nil, diff --git a/images/vm-route-forge/go.mod b/images/vm-route-forge/go.mod index 57bbcc5dcc..1748f07e51 100644 --- a/images/vm-route-forge/go.mod +++ b/images/vm-route-forge/go.mod @@ -67,7 +67,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 // indirect github.com/openshift/custom-resource-status v1.1.2 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect @@ -123,8 +122,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/images/vm-route-forge/go.sum b/images/vm-route-forge/go.sum index 65cc2e5874..3c63121653 100644 --- a/images/vm-route-forge/go.sum +++ b/images/vm-route-forge/go.sum @@ -300,8 +300,6 @@ github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxj github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 h1:t/CahSnpqY46sQR01SoS+Jt0jtjgmhgE6lFmRnO4q70= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= @@ -677,10 +675,10 @@ k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= -kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/src/cli/go.mod b/src/cli/go.mod index bd767e6226..d859fe42de 100644 --- a/src/cli/go.mod +++ b/src/cli/go.mod @@ -66,8 +66,8 @@ require ( k8s.io/api v0.33.3 // indirect k8s.io/apiextensions-apiserver v0.33.3 // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-runtime v0.21.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect diff --git a/src/cli/go.sum b/src/cli/go.sum index 2c8e3bc9b0..8bb70c9518 100644 --- a/src/cli/go.sum +++ b/src/cli/go.sum @@ -589,8 +589,12 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index 2951618f9d..81b71c9949 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -52,16 +52,12 @@ spec: virtOperator: {{ $logVerbosity }} featureGates: - HotplugVolumes - - GPU - Snapshot - ExpandDisks - Root - - VMLiveUpdateFeatures - CPUManager - Sidecar - VolumeSnapshotDataSource - - VolumeMigration - - VolumesUpdateStrategy virtualMachineOptions: disableSerialConsoleLog: {} customizeComponents: diff --git a/templates/kubevirt/virt-operator/rbac-for-us.yaml b/templates/kubevirt/virt-operator/rbac-for-us.yaml index d52cec41b0..91a6311478 100644 --- a/templates/kubevirt/virt-operator/rbac-for-us.yaml +++ b/templates/kubevirt/virt-operator/rbac-for-us.yaml @@ -26,6 +26,8 @@ rules: - kubevirt-virt-api-certs - kubevirt-controller-certs - kubevirt-exportproxy-certs + - kubevirt-synchronization-controller-certs + - kubevirt-synchronization-controller-server-certs resources: - secrets verbs: @@ -834,6 +836,9 @@ rules: - virtualmachineinstances/userlist - virtualmachineinstances/sev/fetchcertchain - virtualmachineinstances/sev/querylaunchmeasurement + - virtualmachineinstances/usbredir + - virtualmachines/objectgraph + - virtualmachineinstances/objectgraph verbs: - get - apiGroups: @@ -846,6 +851,7 @@ rules: - virtualmachineinstances/freeze - virtualmachineinstances/unfreeze - virtualmachineinstances/softreboot + - virtualmachineinstances/reset - virtualmachineinstances/sev/setupsession - virtualmachineinstances/sev/injectlaunchsecret verbs: @@ -1214,6 +1220,15 @@ rules: - subjectaccessreviews verbs: - create +- apiGroups: + - resource.k8s.io + resources: + - resourceclaims + - resourceslices + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/test/e2e/go.mod b/test/e2e/go.mod index b727c9ceab..5ddb0f733b 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -16,7 +16,7 @@ require ( k8s.io/cli-runtime v0.33.3 k8s.io/client-go v0.33.3 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - kubevirt.io/api v1.3.1 + kubevirt.io/api v1.6.2 sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/yaml v1.4.0 ) diff --git a/test/e2e/go.sum b/test/e2e/go.sum index f72cde1b6d..66999d0350 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -582,6 +582,8 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.60.3 h1:kQEXi7scpzUa0RPf3/3MKk1Kmem0ZlqqiuK3kDF5L2I= kubevirt.io/containerized-data-importer-api v1.60.3/go.mod h1:8mwrkZIdy8j/LmCyKt2wFXbiMavLUIqDaegaIF67CZs= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= From 1df81347b4b09a0a7968a5502f2510805f3fe321 Mon Sep 17 00:00:00 2001 From: Vladislav Panfilov Date: Tue, 9 Dec 2025 14:04:43 +0400 Subject: [PATCH 2/9] Review embedded YAML descriptions Signed-off-by: Vladislav Panfilov --- crds/embedded/virtualmachineinstances.yaml | 209 ++++++++---------- crds/embedded/virtualmachines.yaml | 235 +++++++++------------ 2 files changed, 188 insertions(+), 256 deletions(-) diff --git a/crds/embedded/virtualmachineinstances.yaml b/crds/embedded/virtualmachineinstances.yaml index b676c9ed3a..a36f250777 100644 --- a/crds/embedded/virtualmachineinstances.yaml +++ b/crds/embedded/virtualmachineinstances.yaml @@ -1128,11 +1128,11 @@ spec: properties: name: description: |- - Name is this DNS resolver option's name. - Required. + DNS resolver option name. + Required field. type: string value: - description: Value is this DNS resolver option's value. + description: DNS resolver option value. type: string type: object type: array @@ -1576,26 +1576,22 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device provisioned - by device-plugins + description: Name of the device provisioned by device plugins. type: string name: - description: Name of the GPU device as exposed by a - device plugin + description: Name of the GPU device as exposed by a device plugin. type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network interface - address and its tag will be provided to the guest - via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string virtualGPUOptions: properties: @@ -1630,24 +1626,21 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device provisioned - by device-plugins + description: Name of the device provisioned by device plugins. type: string name: type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network interface - address and its tag will be provided to the guest - via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -1862,15 +1855,14 @@ spec: like the number of guest CPUs. type: boolean panicDevices: - description: PanicDevices provides additional crash information - when a guest crashes. + description: Provides additional crash information when a guest crashes. items: properties: model: description: |- - Model specifies what type of panic device is provided. - The panic model used when this attribute is missing depends on the hypervisor and guest arch. - One of: isa, hyperv, pvpanic. + Type of panic device to provide. + If this attribute is missing, the panic model used depends on the hypervisor and guest architecture. + Valid values: `isa`, `hyperv`, `pvpanic`. type: string type: object type: array @@ -1898,13 +1890,13 @@ spec: properties: enabled: description: |- - Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine - Defaults to True + Allows explicitly disabling the vTPM even when one is enabled by a preference referenced by the VirtualMachine. + Defaults to true. type: boolean persistent: description: |- - Persistent indicates the state of the TPM device should be kept accross reboots - Defaults to false + Indicates whether the state of the TPM device should be kept across reboots. + Defaults to false. type: boolean type: object useVirtioTransitional: @@ -1914,13 +1906,12 @@ spec: do not understand virtio_non_transitional (virtio 1.0). type: boolean video: - description: Video describes the video device configuration - for the vmi. + description: Video device configuration for the VMI. properties: type: description: |- - Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). - If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + Video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent: VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64, virtio for Arm and s390x. type: string type: object watchdog: @@ -1928,12 +1919,11 @@ spec: be added to the vmi. properties: diag288: - description: diag288 watchdog device (specific to s390x - architecture). + description: diag288 watchdog device specific to s390x architecture. properties: action: description: |- - The action to take. Valid values are poweroff, reset, shutdown. + Action to take when the watchdog triggers. Valid values: poweroff, reset, shutdown. Defaults to reset. type: string type: object @@ -2295,19 +2285,18 @@ spec: type: string type: object ioThreads: - description: IOThreads specifies the IOThreads options. + description: IOThreads options. properties: supplementalPoolThreadCount: - description: SupplementalPoolThreadCount specifies how many - iothreads are allocated for the supplementalPool policy. + description: Number of IO threads allocated for the `supplementalPool` policy. format: int32 type: integer type: object ioThreadsPolicy: description: |- - Controls whether or not disks will share IOThreads. - Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto, supplementalPool + Controls whether disks share IOThreads. + Omitting this field disables the use of IOThreads. + Valid values: shared, auto, supplementalPool. type: string launchSecurity: description: Launch Security setting of the vmi. @@ -2764,55 +2753,47 @@ spec: type: object resourceClaims: description: |- - ResourceClaims define which ResourceClaims must be allocated - and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources - will be made available to the domain which consumes them - by name. + Defines which ResourceClaims must be allocated and reserved before the VMI, + hence the `virt-launcher` pod is allowed to start. The resources will be made available to the domain + which consumes them by name. - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate in kubernetes - https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ - This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This is an alpha field and requires enabling the `DynamicResourceAllocation` feature gate in Kubernetes. + See https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature gates `GPUsWithDRA` or `HostDevicesWithDRA` is enabled. This feature is in alpha. items: description: |- - PodResourceClaim references exactly one ResourceClaim, either directly + References exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod. - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Adds a name that uniquely identifies the ResourceClaim inside the pod. Containers that need access to the ResourceClaim reference it with this name. properties: name: description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. + Uniquely identifies this resource claim inside the pod. + Must be a `DNS_LABEL`. type: string resourceClaimName: description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. + Name of a ResourceClaim object in the same namespace as this pod. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string resourceClaimTemplateName: description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. + Name of a ResourceClaimTemplate object in the same namespace as this pod. - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + The template will be used to create a new ResourceClaim, which will be bound to this pod. + When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, + along with a generated component, will be used to form a unique name for the ResourceClaim, + which will be recorded in `pod.status.resourceClaimStatuses`. - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. + This field is immutable and no changes will be made to the corresponding ResourceClaim + by the control plane after creating the ResourceClaim. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string required: - name @@ -3226,8 +3207,7 @@ spec: description: Path defines the path to disk file in the container type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean required: - image @@ -3238,12 +3218,10 @@ spec: the process of populating that PVC with a disk image. properties: hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the PVC in - the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -3409,8 +3387,7 @@ spec: More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean readOnly: description: |- @@ -3438,8 +3415,7 @@ spec: More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean readOnly: description: |- @@ -3601,40 +3577,34 @@ spec: This feature is in alpha. properties: gpuStatuses: - description: GPUStatuses reflects the state of GPUs requested - in spec.domain.devices.gpus + description: State of GPUs requested in `spec.domain.devices.gpus`. items: properties: deviceResourceClaimStatus: - description: DeviceResourceClaimStatus reflects the DRA - related information for the device + description: DRA-related information for the device. properties: attributes: description: |- - Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more - about the device, like pciAddress or mdevUUID + Properties of the device that could be used by kubevirt and other components to learn more + about the device, like `pciAddress` or `mdevUUID`. properties: mDevUUID: - description: MDevUUID is the mediated device uuid - of the allocated device + description: Mediated device UUID of the allocated device. type: string pciAddress: - description: PCIAddress is the PCIe bus address - of the allocated device + description: PCIe bus address of the allocated device. type: string type: object name: - description: Name is the name of actual device on the - host provisioned by the driver as reflected in resourceclaim.status + description: Name of actual device on the host provisioned by the driver as reflected in `resourceclaim.status`. type: string resourceClaimName: - description: ResourceClaimName is the name of the resource - claims object used to provision this resource + description: Name of the resource claims object used to provision this resource. type: string type: object name: - description: Name of the device as specified in spec.domain.devices.gpus.name - or spec.domain.devices.hostDevices.name + description: Name of the device as specified in `spec.domain.devices.gpus.name` + or `spec.domain.devices.hostDevices.name`. type: string required: - name @@ -3643,40 +3613,35 @@ spec: x-kubernetes-list-type: atomic hostDeviceStatuses: description: |- - HostDeviceStatuses reflects the state of GPUs requested in spec.domain.devices.hostDevices + State of host devices requested in `spec.domain.devices.hostDevices`. DRA items: properties: deviceResourceClaimStatus: - description: DeviceResourceClaimStatus reflects the DRA - related information for the device + description: DRA-related information for the device. properties: attributes: description: |- - Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more - about the device, like pciAddress or mdevUUID + Properties of the device that could be used by kubevirt and other components to learn more + about the device, like `pciAddress` or `mdevUUID`. properties: mDevUUID: - description: MDevUUID is the mediated device uuid - of the allocated device + description: Mediated device UUID of the allocated device. type: string pciAddress: - description: PCIAddress is the PCIe bus address - of the allocated device + description: PCIe bus address of the allocated device. type: string type: object name: - description: Name is the name of actual device on the - host provisioned by the driver as reflected in resourceclaim.status + description: Name of actual device on the host provisioned by the driver as reflected in `resourceclaim.status`. type: string resourceClaimName: - description: ResourceClaimName is the name of the resource - claims object used to provision this resource + description: Name of the resource claims object used to provision this resource. type: string type: object name: - description: Name of the device as specified in spec.domain.devices.gpus.name - or spec.domain.devices.hostDevices.name + description: Name of the device as specified in `spec.domain.devices.gpus.name` + or `spec.domain.devices.hostDevices.name`. type: string required: - name @@ -3746,19 +3711,17 @@ spec: type: string type: array linkState: - description: 'LinkState Reports the current operational link - state''. values: up, down.' + description: 'Current operational link state. Values: up, down.' type: string mac: - description: Hardware address of a Virtual Machine interface + description: Hardware address of a Virtual Machine interface. type: string name: description: Name of the interface, corresponds to name of the - network assigned to the interface + network assigned to the interface. type: string podInterfaceName: - description: PodInterfaceName represents the name of the pod - network interface + description: Name of the pod network interface. type: string queueCount: description: Specifies how many queues are allocated by MultiQueue @@ -4059,7 +4022,7 @@ spec: type: boolean type: object migrationNetworkType: - description: The type of migration network, either 'pod' or 'migration' + description: Type of migration network, either 'pod' or 'migration'. type: string migrationPolicyName: description: Name of the migration policy. If string is empty, @@ -4078,7 +4041,7 @@ spec: type: string sourcePersistentStatePVCName: description: If the VMI being migrated uses persistent features - (backend-storage), its source PVC name is saved here + (backend-storage), its source PVC name is saved here. type: string sourcePod: type: string @@ -4171,7 +4134,7 @@ spec: type: string targetPersistentStatePVCName: description: If the VMI being migrated uses persistent features - (backend-storage), its target PVC name is saved here + (backend-storage), its target PVC name is saved here. type: string targetPod: description: The target pod that the VMI is moving to diff --git a/crds/embedded/virtualmachines.yaml b/crds/embedded/virtualmachines.yaml index a0bfe284f4..f8da8608f7 100644 --- a/crds/embedded/virtualmachines.yaml +++ b/crds/embedded/virtualmachines.yaml @@ -1896,12 +1896,11 @@ spec: properties: name: description: |- - Name is this DNS resolver option's name. - Required. + DNS resolver option name. + Required field. type: string value: - description: Value is this DNS resolver option's - value. + description: DNS resolver option value. type: string type: object type: array @@ -2221,12 +2220,12 @@ spec: type: integer cache: description: |- - Cache specifies which kvm disk cache mode should be used. - Supported values are: - none: Guest I/O not cached on the host, but may be kept in a disk cache. - writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. - writeback: Guest I/O cached on the host. - Defaults to none if the storage supports O_DIRECT, otherwise writethrough. + Specifies which KVM disk cache mode should be used. Supported values: + + - `none`: Guest I/O is not cached on the host, but may be kept in a disk cache. + - `writethrough`: Guest I/O is cached on the host but written through to the physical medium. This is the slowest mode but provides the most guarantees. + - `writeback`: Guest I/O is cached on the host. + Defaults to `none` if the storage supports O_DIRECT, otherwise `writethrough`. type: string cdrom: description: Attach a volume as a cdrom to the @@ -2355,26 +2354,22 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device - provisioned by device-plugins + description: Name of the device provisioned by device plugins. type: string name: - description: Name of the GPU device as exposed - by a device plugin + description: Name of the GPU device as exposed by a device plugin. type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string virtualGPUOptions: properties: @@ -2411,24 +2406,21 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device - provisioned by device-plugins + description: Name of the device provisioned by device plugins. type: string name: type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -2615,17 +2607,15 @@ spec: type: object state: description: |- - State represents the requested operational state of the interface. - The supported values are: - 'absent', expressing a request to remove the interface. - 'down', expressing a request to set the link down. - 'up', expressing a request to set the link up. - Empty value functions as 'up'. + Requested operational state of the interface. Supported values: + + - 'absent': Expresses a request to remove the interface. + - 'down': Expresses a request to set the link down. + - 'up': Expresses a request to set the link up. + An empty value functions as 'up'. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -2648,15 +2638,14 @@ spec: guest CPUs. type: boolean panicDevices: - description: PanicDevices provides additional crash - information when a guest crashes. + description: Provides additional crash information when a guest crashes. items: properties: model: description: |- - Model specifies what type of panic device is provided. - The panic model used when this attribute is missing depends on the hypervisor and guest arch. - One of: isa, hyperv, pvpanic. + Type of panic device to provide. + If this attribute is missing, the panic model used depends on the hypervisor and guest architecture. + Valid values: `isa`, `hyperv`, `pvpanic`. type: string type: object type: array @@ -2685,13 +2674,13 @@ spec: properties: enabled: description: |- - Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine - Defaults to True + Allows explicitly disabling the vTPM even when one is enabled by a preference referenced by the VirtualMachine. + Defaults to true. type: boolean persistent: description: |- - Persistent indicates the state of the TPM device should be kept accross reboots - Defaults to false + Indicates whether the state of the TPM device should be kept across reboots. + Defaults to false. type: boolean type: object useVirtioTransitional: @@ -2701,13 +2690,12 @@ spec: do not understand virtio_non_transitional (virtio 1.0). type: boolean video: - description: Video describes the video device configuration - for the vmi. + description: Video device configuration for the VMI. properties: type: description: |- - Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). - If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + Video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent: VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64, virtio for Arm and s390x. type: string type: object watchdog: @@ -2715,12 +2703,11 @@ spec: which can be added to the vmi. properties: diag288: - description: diag288 watchdog device (specific - to s390x architecture). + description: diag288 watchdog device specific to s390x architecture. properties: action: description: |- - The action to take. Valid values are poweroff, reset, shutdown. + Action to take when the watchdog triggers. Valid values: poweroff, reset, shutdown. Defaults to reset. type: string type: object @@ -2996,12 +2983,12 @@ spec: properties: msdmNameRef: description: |- - Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. - The above points to the spec of MSDM too. + Similar to `SlicNameRef`, this is another ACPI entry used in more recent Windows versions. + This field points to the MSDM specification as well. type: string slicNameRef: description: |- - SlicNameRef should match the volume name of a secret object. The data in the secret should + Should match the volume name of a secret object. The data in the secret should be a binary blob that follows the ACPI SLIC standard, see: https://learn.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653305(v=vs.85) type: string @@ -3089,17 +3076,15 @@ spec: description: IOThreads specifies the IOThreads options. properties: supplementalPoolThreadCount: - description: SupplementalPoolThreadCount specifies - how many iothreads are allocated for the supplementalPool - policy. + description: Number of IO threads allocated for the supplementalPool policy. format: int32 type: integer type: object ioThreadsPolicy: description: |- - Controls whether or not disks will share IOThreads. - Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto, supplementalPool + Controls whether disks share IOThreads. + Omitting this field disables the use of IOThreads. + Valid values: shared, auto, supplementalPool. type: string launchSecurity: description: Launch Security setting of the vmi. @@ -3557,55 +3542,47 @@ spec: type: object resourceClaims: description: |- - ResourceClaims define which ResourceClaims must be allocated - and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources - will be made available to the domain which consumes them - by name. + Defines which ResourceClaims must be allocated and reserved before the VMI, + hence the `virt-launcher` pod is allowed to start. The resources will be made available to the domain + which consumes them by name. - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate in kubernetes - https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ - This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This is an alpha field and requires enabling the `DynamicResourceAllocation` feature gate in Kubernetes. + See https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature gates `GPUsWithDRA` or `HostDevicesWithDRA` is enabled. This feature is in alpha. items: description: |- - PodResourceClaim references exactly one ResourceClaim, either directly + References exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod. - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Adds a name that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name. properties: name: description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. + Uniquely identifies this resource claim inside the pod. + This must be a `DNS_LABEL`. type: string resourceClaimName: description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. + Name of a ResourceClaim object in the same namespace as this pod. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string resourceClaimTemplateName: description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. + Name of a ResourceClaimTemplate object in the same namespace as this pod. - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + The template will be used to create a new ResourceClaim, which will be bound to this pod. + When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, + along with a generated component, will be used to form a unique name for the ResourceClaim, + which will be recorded in `pod.status.resourceClaimStatuses`. - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. + This field is immutable and no changes will be made to the corresponding ResourceClaim + by the control plane after creating the ResourceClaim. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string required: - name @@ -4036,8 +4013,7 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the - PVC in the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -4385,26 +4361,25 @@ spec: properties: controllerRevisionRef: description: |- - ControllerRef specifies the ControllerRevision storing a copy of the object captured - when it is first seen by the VirtualMachine controller + ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller. properties: name: - description: Name of the ControllerRevision + description: Name of ControllerRevision. type: string type: object inferFromVolume: - description: InferFromVolume lists the name of a volume that should - be used to infer or discover the resource + description: Lists the name of a volume that should + be used to infer or discover the resource. type: string inferFromVolumeFailurePolicy: - description: InferFromVolumeFailurePolicy controls what should - happen on failure when inferring the resource + description: Controls what happens on failure when inferring the resource. type: string kind: - description: Kind specifies the kind of resource + description: Kind of resource. type: string name: - description: Name is the name of resource + description: Name of resource. type: string type: object memoryDumpRequest: @@ -4414,31 +4389,27 @@ spec: nullable: true properties: claimName: - description: ClaimName is the name of the pvc that will contain - the memory dump + description: Name of the PVC that will contain + the memory dump. type: string endTimestamp: - description: EndTimestamp represents the time the memory dump - was completed + description: Time when the memory dump was completed. format: date-time type: string fileName: - description: FileName represents the name of the output file + description: Name of the output file. type: string message: - description: Message is a detailed message about failure of the - memory dump + description: Detailed message about failure of the memory dump. type: string phase: - description: Phase represents the memory dump phase + description: Memory dump phase. type: string remove: - description: Remove represents request of dissociating the memory - dump pvc + description: Request to dissociate the memory dump PVC. type: boolean startTimestamp: - description: StartTimestamp represents the time the memory dump - started + description: Time when the memory dump started. format: date-time type: string required: @@ -4457,26 +4428,25 @@ spec: properties: controllerRevisionRef: description: |- - ControllerRef specifies the ControllerRevision storing a copy of the object captured - when it is first seen by the VirtualMachine controller + Specifies the `ControllerRevision` storing a copy of the object captured + when it is first seen by the VirtualMachine controller. properties: name: - description: Name of the ControllerRevision + description: Name of ControllerRevision. type: string type: object inferFromVolume: - description: InferFromVolume lists the name of a volume that should - be used to infer or discover the resource + description: Lists the name of a volume that should + be used to infer or discover the resource. type: string inferFromVolumeFailurePolicy: - description: InferFromVolumeFailurePolicy controls what should - happen on failure when inferring the resource + description: Controls what happens on failure when inferring the resource. type: string kind: - description: Kind specifies the kind of resource + description: Kind of resource. type: string name: - description: Name is the name of resource + description: Name of resource. type: string type: object printableStatus: @@ -4594,11 +4564,11 @@ spec: type: integer cache: description: |- - Cache specifies which kvm disk cache mode should be used. - Supported values are: - none: Guest I/O not cached on the host, but may be kept in a disk cache. - writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. - writeback: Guest I/O cached on the host. + Cache specifies which KVM disk cache mode should be used. Supported values: + + - `none`: Guest I/O is not cached on the host, but may be kept in a disk cache. + - `writethrough`: Guest I/O is cached on the host but written through to the physical medium. This is the slowest mode but provides the most guarantees. + - `writeback`: Guest I/O is cached on the host. Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: @@ -4752,8 +4722,7 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the - PVC in the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -4875,7 +4844,7 @@ spec: on the corresponding PVC status type: object claimName: - description: ClaimName is the name of the PVC + description: Name of the PVC. type: string filesystemOverhead: description: Percentage of filesystem's size to @@ -4925,7 +4894,7 @@ spec: on the corresponding PVC status type: object claimName: - description: ClaimName is the name of the PVC + description: Name of the PVC. type: string filesystemOverhead: description: Percentage of filesystem's size to From 460666096d66b0340339285ae3570d68f080a72d Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 16 Dec 2025 13:23:55 +0300 Subject: [PATCH 3/9] feat(vm): support network configuration without a 'main' network Signed-off-by: Dmitry Lopatin --- images/virtualization-artifact/hack/dlv.sh | 3 +- .../pkg/common/network/network.go | 18 +++- .../pkg/common/network/network_test.go | 68 ++++++++----- .../pkg/controller/kvbuilder/kvvm_utils.go | 9 +- .../pkg/controller/vm/internal/ipam.go | 96 ++++++++++--------- .../pkg/controller/vm/internal/mac.go | 16 +++- .../pkg/controller/vm/internal/network.go | 33 +++++-- .../pkg/controller/vm/internal/sync_kvvm.go | 11 ++- .../vm/internal/validators/ipam_validator.go | 21 ++++ .../internal/validators/networks_validator.go | 55 +++++++---- .../validators/networks_validator_test.go | 82 +++++++++++----- .../vmip/internal/attached_handler.go | 46 +++++---- .../vmip/internal/deletion_handler.go | 61 ++++++++++++ .../pkg/controller/vmip/vmip_controller.go | 1 + 14 files changed, 365 insertions(+), 155 deletions(-) create mode 100644 images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go diff --git a/images/virtualization-artifact/hack/dlv.sh b/images/virtualization-artifact/hack/dlv.sh index 9881789165..2cc956599d 100755 --- a/images/virtualization-artifact/hack/dlv.sh +++ b/images/virtualization-artifact/hack/dlv.sh @@ -82,8 +82,7 @@ kubectl -n d8-virtualization patch deployment ${deployment} --type='strategic' - "ports": [{"containerPort": 2345, "name": "dlv"}], "readinessProbe": null, "livenessProbe": null, - "command": null, - "args": [] + "command": null }, { "name": "proxy", diff --git a/images/virtualization-artifact/pkg/common/network/network.go b/images/virtualization-artifact/pkg/common/network/network.go index c53142c755..cc495acf8d 100644 --- a/images/virtualization-artifact/pkg/common/network/network.go +++ b/images/virtualization-artifact/pkg/common/network/network.go @@ -77,6 +77,12 @@ func CreateNetworkSpec(vm *v1alpha2.VirtualMachine, vmmacs []*v1alpha2.VirtualMa } for _, n := range vm.Spec.Networks { if n.Type == v1alpha2.NetworksTypeMain { + res = append(res, InterfaceSpec{ + Type: n.Type, + Name: n.Name, + InterfaceName: NameDefaultInterface, + MAC: "", + }) continue } var mac string @@ -103,8 +109,16 @@ func CreateNetworkSpec(vm *v1alpha2.VirtualMachine, vmmacs []*v1alpha2.VirtualMa return res } -func (c InterfaceSpecList) ToString() (string, error) { - data, err := json.Marshal(c) +func (s InterfaceSpecList) ToString() (string, error) { + filtered := InterfaceSpecList{} + for _, spec := range s { + if spec.Type == v1alpha2.NetworksTypeMain { + continue + } + filtered = append(filtered, spec) + } + + data, err := json.Marshal(filtered) if err != nil { return "", err } diff --git a/images/virtualization-artifact/pkg/common/network/network_test.go b/images/virtualization-artifact/pkg/common/network/network_test.go index 2ac2f823a0..7643aa0ed3 100644 --- a/images/virtualization-artifact/pkg/common/network/network_test.go +++ b/images/virtualization-artifact/pkg/common/network/network_test.go @@ -74,7 +74,10 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(0)) + Expect(configs).To(HaveLen(1)) + Expect(configs[0].Name).To(Equal("")) + Expect(configs[0].InterfaceName).To(HavePrefix("default")) + Expect(configs[0].MAC).To(HavePrefix("")) }) It("should generate correct interface name for Network type", func() { @@ -90,10 +93,14 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(1)) - Expect(configs[0].Type).To(Equal(v1alpha2.NetworksTypeNetwork)) - Expect(configs[0].Name).To(Equal("mynet")) - Expect(configs[0].InterfaceName).To(HavePrefix("veth_n")) + Expect(configs).To(HaveLen(2)) + Expect(configs[0].Name).To(Equal("")) + Expect(configs[0].InterfaceName).To(HavePrefix("default")) + Expect(configs[0].MAC).To(HavePrefix("")) + + Expect(configs[1].Type).To(Equal(v1alpha2.NetworksTypeNetwork)) + Expect(configs[1].Name).To(Equal("mynet")) + Expect(configs[1].InterfaceName).To(HavePrefix("veth_n")) }) It("should generate correct interface name for ClusterNetwork type", func() { @@ -109,10 +116,13 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(1)) - Expect(configs[0].Type).To(Equal(v1alpha2.NetworksTypeClusterNetwork)) - Expect(configs[0].Name).To(Equal("clusternet")) - Expect(configs[0].InterfaceName).To(HavePrefix("veth_cn")) + Expect(configs).To(HaveLen(2)) + Expect(configs[0].Name).To(Equal("")) + Expect(configs[0].InterfaceName).To(HavePrefix("default")) + Expect(configs[0].MAC).To(HavePrefix("")) + Expect(configs[1].Type).To(Equal(v1alpha2.NetworksTypeClusterNetwork)) + Expect(configs[1].Name).To(Equal("clusternet")) + Expect(configs[1].InterfaceName).To(HavePrefix("veth_cn")) }) It("should generate unique names for different networks", func() { @@ -132,8 +142,11 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(2)) - Expect(configs[0].InterfaceName).NotTo(Equal(configs[1].InterfaceName)) + Expect(configs).To(HaveLen(3)) + Expect(configs[0].Name).To(Equal("")) + Expect(configs[0].InterfaceName).To(HavePrefix("default")) + Expect(configs[0].MAC).To(HavePrefix("")) + Expect(configs[1].InterfaceName).NotTo(Equal(configs[2].InterfaceName)) }) It("should preserve MAC order for existing networks and assign free MAC to new network", func() { @@ -147,10 +160,12 @@ var _ = Describe("Network Config Generation", func() { MAC: "00:1A:2B:3C:4D:5E", }, { + Type: v1alpha2.NetworksTypeNetwork, Name: "name1", MAC: "00:1A:2B:3C:4D:5F", }, { + Type: v1alpha2.NetworksTypeNetwork, Name: "name1", MAC: "00:1A:2B:3C:4D:6A", }, @@ -186,19 +201,22 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(4)) + Expect(configs).To(HaveLen(5)) - Expect(configs[0].Name).To(Equal("name1")) - Expect(configs[0].MAC).To(Equal("00:1A:2B:3C:4D:5E")) + Expect(configs[0].Name).To(Equal("")) + Expect(configs[0].MAC).To(Equal("")) Expect(configs[1].Name).To(Equal("name1")) - Expect(configs[1].MAC).To(Equal("00:1A:2B:3C:4D:5F")) + Expect(configs[1].MAC).To(Equal("00:1A:2B:3C:4D:5E")) - Expect(configs[3].Name).To(Equal("name1")) - Expect(configs[3].MAC).To(Equal("00:1A:2B:3C:4D:6A")) + Expect(configs[2].Name).To(Equal("name1")) + Expect(configs[2].MAC).To(Equal("00:1A:2B:3C:4D:5F")) - Expect(configs[2].Name).To(Equal("name2")) - Expect(configs[2].MAC).To(Equal("00:1A:2B:3C:4D:7F")) + Expect(configs[3].Name).To(Equal("name2")) + Expect(configs[3].MAC).To(Equal("00:1A:2B:3C:4D:7F")) + + Expect(configs[4].Name).To(Equal("name1")) + Expect(configs[4].MAC).To(Equal("00:1A:2B:3C:4D:6A")) }) It("should preserve MAC order when delete network", func() { @@ -252,15 +270,15 @@ var _ = Describe("Network Config Generation", func() { configs := CreateNetworkSpec(vm, vmmacs) - Expect(configs).To(HaveLen(3)) - - Expect(configs[0].Name).To(Equal("name1")) - Expect(configs[0].MAC).To(Equal("00:1A:2B:3C:4D:5E")) + Expect(configs).To(HaveLen(4)) Expect(configs[1].Name).To(Equal("name1")) - Expect(configs[1].MAC).To(Equal("00:1A:2B:3C:4D:5F")) + Expect(configs[1].MAC).To(Equal("00:1A:2B:3C:4D:5E")) Expect(configs[2].Name).To(Equal("name1")) - Expect(configs[2].MAC).To(Equal("00:1A:2B:3C:4D:6A")) + Expect(configs[2].MAC).To(Equal("00:1A:2B:3C:4D:5F")) + + Expect(configs[3].Name).To(Equal("name1")) + Expect(configs[3].MAC).To(Equal("00:1A:2B:3C:4D:6A")) }) }) diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go index 034d25714a..15529eeb17 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -282,8 +282,11 @@ func ApplyVirtualMachineSpec( }) kvvm.AddFinalizer(v1alpha2.FinalizerKVVMProtection) - // Set ip address cni request annotation. - kvvm.SetKVVMIAnnotation(netmanager.AnnoIPAddressCNIRequest, ipAddress) + if ipAddress != "" { + // Set ip address cni request annotation. + kvvm.SetKVVMIAnnotation(netmanager.AnnoIPAddressCNIRequest, ipAddress) + } + // Set live migration annotation. kvvm.SetKVVMIAnnotation(virtv1.AllowPodBridgeNetworkLiveMigrationAnnotation, "true") // Set label to skip the check for PodSecurityStandards to avoid irrelevant alerts related to a privileged virtual machine pod. @@ -337,8 +340,6 @@ func ApplyMigrationVolumes(kvvm *KVVM, vm *v1alpha2.VirtualMachine, vdsByName ma func setNetwork(kvvm *KVVM, networkSpec network.InterfaceSpecList) { kvvm.ClearNetworkInterfaces() - kvvm.SetNetworkInterface(network.NameDefaultInterface, "") - for _, n := range networkSpec { kvvm.SetNetworkInterface(n.InterfaceName, n.MAC) } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go index d26d450f3c..a8c39b7078 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go @@ -65,38 +65,44 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( if s.VirtualMachine().IsEmpty() { return reconcile.Result{}, nil } - current := s.VirtualMachine().Current() - changed := s.VirtualMachine().Changed() + vm := s.VirtualMachine().Changed() - if update := addAllUnknown(changed, vmcondition.TypeIPAddressReady); update { - return reconcile.Result{Requeue: true}, nil + if isDeletion(vm) { + return reconcile.Result{}, nil } - //nolint:staticcheck // it's deprecated. - mgr := conditions.NewManager(changed.Status.Conditions) cb := conditions.NewConditionBuilder(vmcondition.TypeIPAddressReady). - Generation(current.GetGeneration()) + Status(metav1.ConditionUnknown). + Reason(conditions.ReasonUnknown). + Generation(vm.GetGeneration()) + + defer func() { + conditions.SetCondition(cb, &vm.Status.Conditions) + }() + + if !hasDefaultNetwork(vm.Status.Networks) { + vm.Status.IPAddress = "" + vm.Status.VirtualMachineIPAddress = "" + cb.Status(metav1.ConditionTrue).Reason(vmcondition.ReasonIPAddressReady) + return reconcile.Result{}, nil + } ipAddress, err := s.IPAddress(ctx) if err != nil { + cb.Reason(vmcondition.ReasonIPAddressNotReady).Message(fmt.Sprintf("Failed to get VirtualMachineIPAddress: %v", err)) return reconcile.Result{}, err } - if isDeletion(current) { - return reconcile.Result{}, nil - } - // 1. OK: already bound. - if h.ipam.IsBound(current.GetName(), ipAddress) { - mgr.Update(cb.Status(metav1.ConditionTrue). - Reason(vmcondition.ReasonIPAddressReady). - Condition()) - changed.Status.VirtualMachineIPAddress = ipAddress.GetName() - if changed.Status.Phase != v1alpha2.MachineRunning && changed.Status.Phase != v1alpha2.MachineStopping { - changed.Status.IPAddress = ipAddress.Status.Address + if h.ipam.IsBound(vm.GetName(), ipAddress) { + cb.Status(metav1.ConditionTrue).Reason(vmcondition.ReasonIPAddressReady) + vm.Status.VirtualMachineIPAddress = ipAddress.GetName() + if vm.Status.Phase != v1alpha2.MachineRunning && vm.Status.Phase != v1alpha2.MachineStopping { + vm.Status.IPAddress = ipAddress.Status.Address } kvvmi, err := s.KVVMI(ctx) if err != nil { + cb.Reason(vmcondition.ReasonIPAddressNotReady).Message(fmt.Sprintf("Failed to get KVVMI: %v", err)) return reconcile.Result{}, err } if kvvmi != nil && kvvmi.Status.Phase == virtv1.Running { @@ -110,17 +116,13 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( } if !hasClaimedIP { msg := fmt.Sprintf("IP address (%s) is not among addresses assigned to '%s' network interface (%s)", ipAddress.Status.Address, network.NameDefaultInterface, strings.Join(iface.IPs, ", ")) - mgr.Update(cb.Status(metav1.ConditionFalse). - Reason(vmcondition.ReasonIPAddressNotAssigned). - Message(msg). - Condition()) + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonIPAddressNotAssigned).Message(msg) log.Warn(msg) } break } } } - changed.Status.Conditions = mgr.Generate() return reconcile.Result{}, nil } @@ -129,50 +131,50 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( // 2. Ip address not found: create if possible or wait for the ip address. if ipAddress == nil { cb.Reason(vmcondition.ReasonIPAddressNotReady) - if current.Spec.VirtualMachineIPAddress != "" { - log.Info(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", current.Spec.VirtualMachineIPAddress)) - cb.Message(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", current.Spec.VirtualMachineIPAddress)) - mgr.Update(cb.Condition()) - changed.Status.Conditions = mgr.Generate() + if vm.Spec.VirtualMachineIPAddress != "" { + log.Info(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", vm.Spec.VirtualMachineIPAddress)) + cb.Message(fmt.Sprintf("The requested ip address (%s) for the virtual machine not found: waiting for the ip address", vm.Spec.VirtualMachineIPAddress)) return reconcile.Result{}, nil } - log.Info("VirtualMachineIPAddress not found: create the new one", slog.String("vmipName", current.GetName())) - cb.Message(fmt.Sprintf("VirtualMachineIPAddress %q not found: it may be in the process of being created", current.GetName())) - mgr.Update(cb.Condition()) - changed.Status.Conditions = mgr.Generate() - return reconcile.Result{}, h.ipam.CreateIPAddress(ctx, changed, h.client) + log.Info("VirtualMachineIPAddress not found: create the new one", slog.String("vmipName", vm.GetName())) + cb.Message(fmt.Sprintf("VirtualMachineIPAddress %q not found: it may be in the process of being created", vm.GetName())) + return reconcile.Result{}, h.ipam.CreateIPAddress(ctx, vm, h.client) } // 3. Check if possible to bind virtual machine with the found ip address. - err = h.ipam.CheckIPAddressAvailableForBinding(current.GetName(), ipAddress) + err = h.ipam.CheckIPAddressAvailableForBinding(vm.GetName(), ipAddress) if err != nil { - log.Info("Ip address is not available to be bound", "err", err, "vmipName", current.Spec.VirtualMachineIPAddress) + log.Info("Ip address is not available to be bound", "err", err, "vmipName", vm.Spec.VirtualMachineIPAddress) reason := vmcondition.ReasonIPAddressNotAvailable - mgr.Update(cb.Reason(reason).Message(err.Error()).Condition()) - changed.Status.Conditions = mgr.Generate() - h.recorder.Event(changed, corev1.EventTypeWarning, reason.String(), err.Error()) + cb.Reason(reason).Message(err.Error()) + h.recorder.Event(vm, corev1.EventTypeWarning, reason.String(), err.Error()) return reconcile.Result{}, nil } // 4. Ip address exist and attached to another VirtualMachine - if ipAddress.Status.VirtualMachine != "" && ipAddress.Status.VirtualMachine != changed.Name { - msg := fmt.Sprintf("The requested ip address (%s) attached to VirtualMachine '%s': waiting for the ip address", current.Spec.VirtualMachineIPAddress, ipAddress.Status.VirtualMachine) + if ipAddress.Status.VirtualMachine != "" && ipAddress.Status.VirtualMachine != vm.Name { + msg := fmt.Sprintf("The requested ip address (%s) attached to VirtualMachine '%s': waiting for the ip address", vm.Spec.VirtualMachineIPAddress, ipAddress.Status.VirtualMachine) log.Info(msg) - mgr.Update(cb.Reason(vmcondition.ReasonIPAddressNotReady). - Message(msg).Condition()) - changed.Status.Conditions = mgr.Generate() + cb.Reason(vmcondition.ReasonIPAddressNotReady).Message(msg) return reconcile.Result{}, nil } // 5. Ip address exists and available for binding with virtual machine: waiting for the ip address. - log.Info("Waiting for the ip address to be bound to VM", "vmipName", current.Spec.VirtualMachineIPAddress) - mgr.Update(cb.Reason(vmcondition.ReasonIPAddressNotReady). - Message("Ip address not bound: waiting for the ip address").Condition()) - changed.Status.Conditions = mgr.Generate() + log.Info("Waiting for the ip address to be bound to VM", "vmipName", vm.Spec.VirtualMachineIPAddress) + cb.Reason(vmcondition.ReasonIPAddressNotReady).Message("Ip address not bound: waiting for the ip address") return reconcile.Result{}, nil } +func hasDefaultNetwork(ns []v1alpha2.NetworksStatus) bool { + for _, n := range ns { + if n.Type == v1alpha2.NetworksTypeMain { + return true + } + } + return false +} + func (h *IPAMHandler) Name() string { return nameIpamHandler } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/mac.go b/images/virtualization-artifact/pkg/controller/vm/internal/mac.go index 62841d21fd..9758984102 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/mac.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/mac.go @@ -82,14 +82,22 @@ func (h *MACHandler) Handle(ctx context.Context, s state.VirtualMachineState) (r vmmacs, err := s.VirtualMachineMACAddresses(ctx) if err != nil { + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Failed to get VirtualMachineMACAddresses: %s", err)) return reconcile.Result{}, err } - // 'Main' network is always present but not require a MAC address. - expectedMACAddresses := len(vm.Spec.Networks) - 1 + expectedMACAddresses := 0 + for _, network := range vm.Spec.Networks { + // 'Main' network not require a MAC address. + if network.Type == v1alpha2.NetworksTypeMain { + continue + } + expectedMACAddresses++ + } kvvm, err := s.KVVM(ctx) if err != nil { + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Failed to get KVVM: %s", err)) return reconcile.Result{}, err } if len(vmmacs) < expectedMACAddresses { @@ -100,6 +108,7 @@ func (h *MACHandler) Handle(ctx context.Context, s state.VirtualMachineState) (r err = h.macManager.CreateMACAddress(ctx, vm, h.client, iface.MacAddress) createdCount++ if err != nil { + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Failed to create VirtualMachineMACAddress: %s", err)) return reconcile.Result{}, err } } @@ -110,6 +119,7 @@ func (h *MACHandler) Handle(ctx context.Context, s state.VirtualMachineState) (r for i := 0; i < macsToCreate; i++ { err = h.macManager.CreateMACAddress(ctx, vm, h.client, "") if err != nil { + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonMACAddressNotReady).Message(fmt.Sprintf("Failed to create VirtualMachineMACAddress: %s", err)) return reconcile.Result{}, err } } @@ -176,7 +186,7 @@ func countNetworksWithMACRequest(networkSpec []v1alpha2.NetworksSpec, vmmacs []* count := 0 for _, ns := range networkSpec { - if ns.Type != v1alpha2.NetworksTypeMain { + if ns.Type == v1alpha2.NetworksTypeMain { continue } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/network.go b/images/virtualization-artifact/pkg/controller/vm/internal/network.go index e50ff5b0b0..b0b02d75c7 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/network.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/network.go @@ -72,7 +72,7 @@ func (h *NetworkInterfaceHandler) Handle(ctx context.Context, s state.VirtualMac } }() - if len(vm.Spec.Networks) > 1 { + if !hasOnlyDefaultNetwork(vm) { if !h.featureGate.Enabled(featuregates.SDN) { cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonSDNModuleDisable).Message("For additional network interfaces, please enable SDN module") return reconcile.Result{}, nil @@ -98,6 +98,11 @@ func (h *NetworkInterfaceHandler) Handle(ctx context.Context, s state.VirtualMac return h.UpdateNetworkStatus(ctx, s, vm) } +func hasOnlyDefaultNetwork(vm *v1alpha2.VirtualMachine) bool { + nets := vm.Spec.Networks + return len(nets) == 0 || (len(nets) == 1 && nets[0].Type == v1alpha2.NetworksTypeMain) +} + func (h *NetworkInterfaceHandler) Name() string { return nameNetworkHandler } @@ -110,6 +115,16 @@ func (h *NetworkInterfaceHandler) UpdateNetworkStatus(ctx context.Context, s sta } } + if hasOnlyDefaultNetwork(vm) { + vm.Status.Networks = []v1alpha2.NetworksStatus{ + { + Type: v1alpha2.NetworksTypeMain, + Name: network.NameDefaultInterface, + }, + } + return reconcile.Result{}, nil + } + kvvm, err := s.KVVM(ctx) if err != nil { return reconcile.Result{}, err @@ -134,14 +149,16 @@ func (h *NetworkInterfaceHandler) UpdateNetworkStatus(ctx context.Context, s sta } } - networksStatus := []v1alpha2.NetworksStatus{ - { - Type: v1alpha2.NetworksTypeMain, - Name: "default", - }, - } - + var networksStatus []v1alpha2.NetworksStatus for _, interfaceSpec := range network.CreateNetworkSpec(vm, vmmacs) { + if interfaceSpec.Type == v1alpha2.NetworksTypeMain { + networksStatus = append(networksStatus, v1alpha2.NetworksStatus{ + Type: v1alpha2.NetworksTypeMain, + Name: network.NameDefaultInterface, + }) + continue + } + networksStatus = append(networksStatus, v1alpha2.NetworksStatus{ Type: interfaceSpec.Type, Name: interfaceSpec.Name, diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go index 474b6b5f71..0979bce0e7 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -414,8 +414,13 @@ func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState) (*virt return nil, err } - if ip.Status.Address == "" { - return nil, fmt.Errorf("the IP address is not found for the virtual machine") + ipAddress := "" + if ip != nil { + if ip.Status.Address == "" { + return nil, fmt.Errorf("the IP address is not found for the virtual machine") + } else { + ipAddress = ip.Status.Address + } } vmmacs, err := s.VirtualMachineMACAddresses(ctx) @@ -431,7 +436,7 @@ func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState) (*virt } // Create kubevirt VirtualMachine resource from d8 VirtualMachine spec. - err = kvbuilder.ApplyVirtualMachineSpec(kvvmBuilder, current, bdState.VDByName, bdState.VIByName, bdState.CVIByName, vmbdas, class, ip.Status.Address, networkSpec) + err = kvbuilder.ApplyVirtualMachineSpec(kvvmBuilder, current, bdState.VDByName, bdState.VIByName, bdState.CVIByName, vmbdas, class, ipAddress, networkSpec) if err != nil { return nil, err } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/validators/ipam_validator.go b/images/virtualization-artifact/pkg/controller/vm/internal/validators/ipam_validator.go index 17996664e0..18a2aa33fa 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/validators/ipam_validator.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/validators/ipam_validator.go @@ -36,7 +36,24 @@ func NewIPAMValidator(client client.Client) *IPAMValidator { return &IPAMValidator{client: client} } +func hasMainNetwork(vm *v1alpha2.VirtualMachine) bool { + if vm.Spec.Networks == nil { + return true + } + + for _, network := range vm.Spec.Networks { + if network.Type == v1alpha2.NetworksTypeMain { + return true + } + } + return false +} + func (v *IPAMValidator) ValidateCreate(ctx context.Context, vm *v1alpha2.VirtualMachine) (admission.Warnings, error) { + if vm.Spec.VirtualMachineIPAddress != "" && !hasMainNetwork(vm) { + return nil, fmt.Errorf("spec.virtualMachineIPAddressName cannot be set without Main network type in spec.networks") + } + vmipName := vm.Spec.VirtualMachineIPAddress if vmipName == "" { vmipName = vm.Name @@ -62,6 +79,10 @@ func (v *IPAMValidator) ValidateCreate(ctx context.Context, vm *v1alpha2.Virtual } func (v *IPAMValidator) ValidateUpdate(ctx context.Context, oldVM, newVM *v1alpha2.VirtualMachine) (admission.Warnings, error) { + if newVM.Spec.VirtualMachineIPAddress != "" && !hasMainNetwork(newVM) { + return nil, fmt.Errorf("spec.virtualMachineIPAddressName cannot be set without Main network type in spec.networks") + } + if oldVM.Spec.VirtualMachineIPAddress == newVM.Spec.VirtualMachineIPAddress { return nil, nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator.go b/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator.go index bf441ecda2..b41451f1b1 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator.go @@ -69,31 +69,50 @@ func (v *NetworksValidator) ValidateUpdate(_ context.Context, oldVM, newVM *v1al } func (v *NetworksValidator) validateNetworksSpec(networksSpec []v1alpha2.NetworksSpec) (admission.Warnings, error) { - if networksSpec[0].Type != v1alpha2.NetworksTypeMain { - return nil, fmt.Errorf("first network in the list must be of type '%s'", v1alpha2.NetworksTypeMain) - } - if networksSpec[0].Name != "" { - return nil, fmt.Errorf("network with type '%s' should not have a name", v1alpha2.NetworksTypeMain) - } - namesSet := make(map[string]struct{}) - for i, network := range networksSpec { - if network.Type == v1alpha2.NetworksTypeMain { - if i > 0 { - return nil, fmt.Errorf("only one network of type '%s' is allowed", v1alpha2.NetworksTypeMain) - } - continue + typ := network.Type + name := network.Name + + if typ == v1alpha2.NetworksTypeMain && i > 0 { + return nil, fmt.Errorf("first network in the list must be of type '%s'", v1alpha2.NetworksTypeMain) } - if network.Name == "" { - return nil, fmt.Errorf("network at index %d with type '%s' must have a non-empty name", i, network.Type) + + if err := v.validateNetworkName(typ, name); err != nil { + return nil, err } - if _, exists := namesSet[network.Name]; exists { - return nil, fmt.Errorf("network name '%s' is duplicated", network.Name) + if err := v.validateNetworkUniqueness(typ, name, namesSet); err != nil { + return nil, err } - namesSet[network.Name] = struct{}{} } return nil, nil } + +func (v *NetworksValidator) validateNetworkName(networkType, networkName string) error { + if networkType == v1alpha2.NetworksTypeMain { + if networkName != "" { + return fmt.Errorf("network with type '%s' should not have a name", v1alpha2.NetworksTypeMain) + } + return nil + } + + if networkName == "" { + return fmt.Errorf("network with type '%s' must have a non-empty name", networkType) + } + + return nil +} + +func (v *NetworksValidator) validateNetworkUniqueness(networkType, networkName string, namesSet map[string]struct{}) error { + key := fmt.Sprintf("%s/%s", networkType, networkName) + if _, exists := namesSet[key]; exists { + if networkName != "" { + return fmt.Errorf("network %s:%s is duplicated", networkType, networkName) + } + return fmt.Errorf("network %s is duplicated", networkType) + } + namesSet[key] = struct{}{} + return nil +} diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator_test.go index 9a35d4a80d..4ee64f58af 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/validators/networks_validator_test.go @@ -24,6 +24,12 @@ import ( "github.com/deckhouse/virtualization/api/core/v1alpha2" ) +var ( + mainNetwork = v1alpha2.NetworksSpec{Type: v1alpha2.NetworksTypeMain} + network = v1alpha2.NetworksSpec{Type: v1alpha2.NetworksTypeNetwork, Name: "test"} + clusterNetwork = v1alpha2.NetworksSpec{Type: v1alpha2.NetworksTypeClusterNetwork, Name: "test"} +) + func TestNetworksValidateCreate(t *testing.T) { tests := []struct { networks []v1alpha2.NetworksSpec @@ -31,14 +37,16 @@ func TestNetworksValidateCreate(t *testing.T) { valid bool }{ {[]v1alpha2.NetworksSpec{}, true, true}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}}, true, true}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}, {Type: v1alpha2.NetworksTypeMain}}, true, false}, + {[]v1alpha2.NetworksSpec{mainNetwork}, true, true}, + {[]v1alpha2.NetworksSpec{mainNetwork, mainNetwork}, true, false}, + {[]v1alpha2.NetworksSpec{network, mainNetwork, mainNetwork}, true, false}, {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain, Name: "main"}}, true, false}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, {Type: v1alpha2.NetworksTypeMain}}, true, false}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}, {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}}, true, true}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}, {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}}, true, false}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}, {Type: v1alpha2.NetworksTypeNetwork}}, true, false}, - {[]v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}}, false, false}, + {[]v1alpha2.NetworksSpec{network}, true, true}, + {[]v1alpha2.NetworksSpec{network, clusterNetwork}, true, true}, + {[]v1alpha2.NetworksSpec{mainNetwork, network}, true, true}, + {[]v1alpha2.NetworksSpec{mainNetwork, network, network}, true, false}, + {[]v1alpha2.NetworksSpec{mainNetwork, {Type: v1alpha2.NetworksTypeNetwork}}, true, false}, + {[]v1alpha2.NetworksSpec{mainNetwork}, false, false}, } for i, test := range tests { @@ -78,15 +86,15 @@ func TestNetworksValidateUpdate(t *testing.T) { }, { oldNetworksSpec: []v1alpha2.NetworksSpec{}, - newNetworksSpec: []v1alpha2.NetworksSpec{{Type: v1alpha2.NetworksTypeMain}}, + newNetworksSpec: []v1alpha2.NetworksSpec{mainNetwork}, sdnEnabled: true, valid: true, }, { oldNetworksSpec: []v1alpha2.NetworksSpec{}, newNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, }, sdnEnabled: true, valid: true, @@ -94,38 +102,60 @@ func TestNetworksValidateUpdate(t *testing.T) { { oldNetworksSpec: []v1alpha2.NetworksSpec{}, newNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, + network, }, sdnEnabled: true, valid: false, }, { oldNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, + network, + network, }, newNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, + network, }, sdnEnabled: true, valid: false, }, { oldNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, + network, + network, + }, + newNetworksSpec: []v1alpha2.NetworksSpec{ + mainNetwork, + network, + }, + sdnEnabled: true, + valid: true, + }, + { + oldNetworksSpec: []v1alpha2.NetworksSpec{ + mainNetwork, + network, + }, + newNetworksSpec: []v1alpha2.NetworksSpec{ + network, + }, + sdnEnabled: true, + valid: true, + }, + { + oldNetworksSpec: []v1alpha2.NetworksSpec{ + network, }, newNetworksSpec: []v1alpha2.NetworksSpec{ - {Type: v1alpha2.NetworksTypeMain}, - {Type: v1alpha2.NetworksTypeNetwork, Name: "test"}, + mainNetwork, + network, }, sdnEnabled: true, valid: true, diff --git a/images/virtualization-artifact/pkg/controller/vmip/internal/attached_handler.go b/images/virtualization-artifact/pkg/controller/vmip/internal/attached_handler.go index 9bf4a651b0..5017bc651f 100644 --- a/images/virtualization-artifact/pkg/controller/vmip/internal/attached_handler.go +++ b/images/virtualization-artifact/pkg/controller/vmip/internal/attached_handler.go @@ -102,28 +102,40 @@ func (h *AttachedHandler) getAttachedVirtualMachine(ctx context.Context, vmip *v } } - if attachedVM != nil { - return attachedVM, nil - } + if attachedVM == nil { + // If there's no match for the spec either, then try to find the vm by ownerRef. + var vmName string + for _, ownerRef := range vmip.OwnerReferences { + if ownerRef.Kind == v1alpha2.VirtualMachineKind && string(ownerRef.UID) == vmip.Labels[annotations.LabelVirtualMachineUID] { + vmName = ownerRef.Name + break + } + } - // If there's no match for the spec either, then try to find the vm by ownerRef. - var vmName string - for _, ownerRef := range vmip.OwnerReferences { - if ownerRef.Kind == v1alpha2.VirtualMachineKind && string(ownerRef.UID) == vmip.Labels[annotations.LabelVirtualMachineUID] { - vmName = ownerRef.Name - break + if vmName == "" { + return nil, nil } - } - if vmName == "" { - return nil, nil + vmKey := types.NamespacedName{Name: vmName, Namespace: vmip.Namespace} + attachedVM, err = object.FetchObject(ctx, vmKey, h.client, &v1alpha2.VirtualMachine{}) + if err != nil { + return nil, fmt.Errorf("fetch vm %s: %w", vmKey, err) + } } - vmKey := types.NamespacedName{Name: vmName, Namespace: vmip.Namespace} - attachedVM, err = object.FetchObject(ctx, vmKey, h.client, &v1alpha2.VirtualMachine{}) - if err != nil { - return nil, fmt.Errorf("fetch vm %s: %w", vmKey, err) + if attachedVM != nil { + for _, ns := range attachedVM.Status.Networks { + if ns.Type == v1alpha2.NetworksTypeMain { + return attachedVM, nil + } + } + + for _, ns := range attachedVM.Spec.Networks { + if ns.Type == v1alpha2.NetworksTypeMain { + return attachedVM, nil + } + } } - return attachedVM, nil + return nil, nil } diff --git a/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go b/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go new file mode 100644 index 0000000000..33f5abd9f2 --- /dev/null +++ b/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go @@ -0,0 +1,61 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" + "fmt" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" + "github.com/deckhouse/virtualization/api/core/v1alpha2" + "github.com/deckhouse/virtualization/api/core/v1alpha2/vmipcondition" +) + +type DeletionHandler struct { + client client.Client +} + +func NewDeletionHandler(client client.Client) *DeletionHandler { + return &DeletionHandler{ + client: client, + } +} + +func (h *DeletionHandler) Handle(ctx context.Context, vmip *v1alpha2.VirtualMachineIPAddress) (reconcile.Result, error) { + attachedCondition, _ := conditions.GetCondition(vmipcondition.AttachedType, vmip.Status.Conditions) + if attachedCondition.Status == metav1.ConditionTrue || !conditions.IsLastUpdated(attachedCondition, vmip) { + return reconcile.Result{}, nil + } + + // This is done to allow new resources to be created while ensuring they are deleted when the interface is removed from the virtual machine's specification. + diff := vmip.CreationTimestamp.Time.Sub(attachedCondition.LastTransitionTime.Time).Abs() + if diff.Seconds() < 1 { + return reconcile.Result{}, nil + } + + err := h.client.Delete(ctx, vmip) + if err != nil && !k8serrors.IsNotFound(err) { + return reconcile.Result{}, fmt.Errorf("delete vmip: %w", err) + } + + return reconcile.Result{}, nil +} diff --git a/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go b/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go index 3fe393b7fd..471ada07fc 100644 --- a/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go +++ b/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go @@ -56,6 +56,7 @@ func NewController( internal.NewAttachedHandler(recorder, mgr.GetClient()), internal.NewLifecycleHandler(recorder), internal.NewProtectionHandler(), + internal.NewDeletionHandler(mgr.GetClient()), } r, err := NewReconciler(mgr.GetClient(), virtClient, handlers...) From 5b88b96a91ce27c65fe496eae1d3733bd815f29c Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 18 Dec 2025 20:07:42 +0300 Subject: [PATCH 4/9] fix vmip deletion Signed-off-by: Daniil Loktev --- .../pkg/controller/vm/internal/ipam.go | 21 +++++++ .../vmip/internal/deletion_handler.go | 61 ------------------- .../pkg/controller/vmip/vmip_controller.go | 1 - 3 files changed, 21 insertions(+), 62 deletions(-) delete mode 100644 images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go index a8c39b7078..9c0d28f7a2 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go @@ -23,11 +23,13 @@ import ( "strings" corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + "github.com/deckhouse/virtualization-controller/pkg/common/annotations" "github.com/deckhouse/virtualization-controller/pkg/common/network" "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" "github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state" @@ -83,6 +85,11 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( if !hasDefaultNetwork(vm.Status.Networks) { vm.Status.IPAddress = "" vm.Status.VirtualMachineIPAddress = "" + if err := h.deleteManagedVMIP(ctx, s); err != nil { + cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonIPAddressNotReady). + Message(fmt.Sprintf("Failed to delete VirtualMachineIPAddress: %v", err)) + return reconcile.Result{}, err + } cb.Status(metav1.ConditionTrue).Reason(vmcondition.ReasonIPAddressReady) return reconcile.Result{}, nil } @@ -175,6 +182,20 @@ func hasDefaultNetwork(ns []v1alpha2.NetworksStatus) bool { return false } +func (h *IPAMHandler) deleteManagedVMIP(ctx context.Context, s state.VirtualMachineState, vm *v1alpha2.VirtualMachine) error { + vmip, err := s.IPAddress(ctx) + if err != nil { + return err + } + if vmip == nil || vm == nil || vmip.Labels[annotations.LabelVirtualMachineUID] != string(vm.GetUID()) { + return nil + } + if err := h.client.Delete(ctx, vmip); err != nil && !k8serrors.IsNotFound(err) { + return err + } + return nil +} + func (h *IPAMHandler) Name() string { return nameIpamHandler } diff --git a/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go b/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go deleted file mode 100644 index 33f5abd9f2..0000000000 --- a/images/virtualization-artifact/pkg/controller/vmip/internal/deletion_handler.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2025 Flant JSC - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import ( - "context" - "fmt" - - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" - "github.com/deckhouse/virtualization/api/core/v1alpha2" - "github.com/deckhouse/virtualization/api/core/v1alpha2/vmipcondition" -) - -type DeletionHandler struct { - client client.Client -} - -func NewDeletionHandler(client client.Client) *DeletionHandler { - return &DeletionHandler{ - client: client, - } -} - -func (h *DeletionHandler) Handle(ctx context.Context, vmip *v1alpha2.VirtualMachineIPAddress) (reconcile.Result, error) { - attachedCondition, _ := conditions.GetCondition(vmipcondition.AttachedType, vmip.Status.Conditions) - if attachedCondition.Status == metav1.ConditionTrue || !conditions.IsLastUpdated(attachedCondition, vmip) { - return reconcile.Result{}, nil - } - - // This is done to allow new resources to be created while ensuring they are deleted when the interface is removed from the virtual machine's specification. - diff := vmip.CreationTimestamp.Time.Sub(attachedCondition.LastTransitionTime.Time).Abs() - if diff.Seconds() < 1 { - return reconcile.Result{}, nil - } - - err := h.client.Delete(ctx, vmip) - if err != nil && !k8serrors.IsNotFound(err) { - return reconcile.Result{}, fmt.Errorf("delete vmip: %w", err) - } - - return reconcile.Result{}, nil -} diff --git a/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go b/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go index 471ada07fc..3fe393b7fd 100644 --- a/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go +++ b/images/virtualization-artifact/pkg/controller/vmip/vmip_controller.go @@ -56,7 +56,6 @@ func NewController( internal.NewAttachedHandler(recorder, mgr.GetClient()), internal.NewLifecycleHandler(recorder), internal.NewProtectionHandler(), - internal.NewDeletionHandler(mgr.GetClient()), } r, err := NewReconciler(mgr.GetClient(), virtClient, handlers...) From d4039a3aabf7e3d629336b5e4371ba4ee2c12a2b Mon Sep 17 00:00:00 2001 From: Daniil Loktev Date: Thu, 18 Dec 2025 20:13:16 +0300 Subject: [PATCH 5/9] wip Signed-off-by: Daniil Loktev --- .../virtualization-artifact/pkg/controller/vm/internal/ipam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go index 9c0d28f7a2..b427588c17 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/ipam.go @@ -85,7 +85,7 @@ func (h *IPAMHandler) Handle(ctx context.Context, s state.VirtualMachineState) ( if !hasDefaultNetwork(vm.Status.Networks) { vm.Status.IPAddress = "" vm.Status.VirtualMachineIPAddress = "" - if err := h.deleteManagedVMIP(ctx, s); err != nil { + if err := h.deleteManagedVMIP(ctx, s, vm); err != nil { cb.Status(metav1.ConditionFalse).Reason(vmcondition.ReasonIPAddressNotReady). Message(fmt.Sprintf("Failed to delete VirtualMachineIPAddress: %v", err)) return reconcile.Result{}, err From ecdd14e47468b032dc849c6c4abd67c47769990b Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 25 Nov 2025 18:11:22 +0300 Subject: [PATCH 6/9] refactor(kubevirt): bump version to 1.6.2 Signed-off-by: Dmitry Lopatin --- Taskfile.yaml | 8 +- api/client/examples/cancel-evacuation/go.mod | 4 +- api/client/examples/cancel-evacuation/go.sum | 2 + api/client/examples/list-resources/go.mod | 4 +- api/client/examples/list-resources/go.sum | 2 + api/go.mod | 6 +- api/go.sum | 4 + build/components/versions.yml | 2 +- crds/embedded/virtualmachineinstances.yaml | 472 ++++++++++++++++-- crds/embedded/virtualmachines.yaml | 426 ++++++++++++++-- images/hooks/go.mod | 2 +- images/hooks/go.sum | 4 +- images/virt-api/debug/dlv.Dockerfile | 10 +- images/virt-artifact/werf.inc.yaml | 2 +- images/virt-controller/debug/dlv.Dockerfile | 10 +- images/virt-handler/debug/dlv.Dockerfile | 20 +- images/virt-handler/werf.inc.yaml | 4 - images/virtualization-artifact/go.mod | 4 +- images/virtualization-artifact/go.sum | 4 +- .../livemigration/migration_configuration.go | 3 + images/vm-route-forge/go.mod | 5 +- images/vm-route-forge/go.sum | 10 +- src/cli/go.mod | 4 +- src/cli/go.sum | 4 + templates/kubevirt/kubevirt.yaml | 4 - .../kubevirt/virt-operator/rbac-for-us.yaml | 15 + test/e2e/go.mod | 2 +- test/e2e/go.sum | 2 + 28 files changed, 899 insertions(+), 140 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 93eef4dcee..020d59f4f7 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -165,8 +165,7 @@ tasks: "ports": [ { "containerPort": 2345, "name": "dlv" } ], "readinessProbe": null, "livenessProbe": null, - "command": null, - "args": [] + "command": null }, { "name": "proxy", @@ -264,8 +263,7 @@ tasks: "ports": [ { "containerPort": 2345, "name": "dlv" } ], "readinessProbe": null, "livenessProbe": null, - "command": null, - "args": [] + "command": null }, { "name": "proxy", @@ -282,5 +280,5 @@ tasks: } } }' - kubectl -n d8-virtualization port-forward deploy/vit-api 2345:2345 + kubectl -n d8-virtualization port-forward deploy/virt-api 2345:2345 EOF diff --git a/api/client/examples/cancel-evacuation/go.mod b/api/client/examples/cancel-evacuation/go.mod index 63f821ce75..86339fe572 100644 --- a/api/client/examples/cancel-evacuation/go.mod +++ b/api/client/examples/cancel-evacuation/go.mod @@ -53,8 +53,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/api/client/examples/cancel-evacuation/go.sum b/api/client/examples/cancel-evacuation/go.sum index d7db165b6a..cf69ab2158 100644 --- a/api/client/examples/cancel-evacuation/go.sum +++ b/api/client/examples/cancel-evacuation/go.sum @@ -372,8 +372,10 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= diff --git a/api/client/examples/list-resources/go.mod b/api/client/examples/list-resources/go.mod index 8251bcd219..9888494628 100644 --- a/api/client/examples/list-resources/go.mod +++ b/api/client/examples/list-resources/go.mod @@ -49,8 +49,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/api/client/examples/list-resources/go.sum b/api/client/examples/list-resources/go.sum index 3dba2c12dd..2e9bbd8060 100644 --- a/api/client/examples/list-resources/go.sum +++ b/api/client/examples/list-resources/go.sum @@ -365,8 +365,10 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= diff --git a/api/go.mod b/api/go.mod index 79b0495d1e..a4b3951825 100644 --- a/api/go.mod +++ b/api/go.mod @@ -17,7 +17,8 @@ require ( k8s.io/apiextensions-apiserver v0.33.3 k8s.io/apimachinery v0.33.3 k8s.io/client-go v0.33.3 - kubevirt.io/api v1.3.1 + k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 + kubevirt.io/api v1.6.2 sigs.k8s.io/controller-runtime v0.21.0 ) @@ -70,9 +71,8 @@ require ( k8s.io/code-generator v0.33.3 // indirect k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-tools v0.18.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect diff --git a/api/go.sum b/api/go.sum index fd5f073e7c..620d6a5a4a 100644 --- a/api/go.sum +++ b/api/go.sum @@ -570,8 +570,12 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/build/components/versions.yml b/build/components/versions.yml index 906d683c8a..d542b6d5ed 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.3.1-v12n.25 + 3p-kubevirt: v1.6.2-v12n.0.dlopatin7 3p-containerized-data-importer: v1.60.3-v12n.12 distribution: 2.8.3 package: diff --git a/crds/embedded/virtualmachineinstances.yaml b/crds/embedded/virtualmachineinstances.yaml index b9cc1d5949..b676c9ed3a 100644 --- a/crds/embedded/virtualmachineinstances.yaml +++ b/crds/embedded/virtualmachineinstances.yaml @@ -461,7 +461,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -476,7 +476,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -642,7 +642,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -657,7 +657,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -820,7 +820,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -835,7 +835,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1001,7 +1001,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1016,7 +1016,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1127,9 +1127,12 @@ spec: of a pod. properties: name: - description: Required. + description: |- + Name is this DNS resolver option's name. + Required. type: string value: + description: Value is this DNS resolver option's value. type: string type: object type: array @@ -1447,7 +1450,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the vmi. @@ -1567,12 +1574,24 @@ spec: description: Whether to attach a GPU device to the vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: + description: DeviceName is the name of the device provisioned + by device-plugins type: string name: description: Name of the GPU device as exposed by a device plugin type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest @@ -1601,7 +1620,6 @@ spec: type: object type: object required: - - deviceName - name type: object type: array @@ -1610,19 +1628,28 @@ spec: description: Whether to attach a host device to the vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: - description: DeviceName is the resource name of the - host device exposed by a device plugin + description: DeviceName is the name of the device provisioned + by device-plugins type: string name: type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive type: string required: - - deviceName - name type: object type: array @@ -1743,9 +1770,8 @@ spec: model: description: |- Interface model. - One of: e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio. + One of: e1000, e1000e, igb, ne2k_pci, pcnet, rtl8139, virtio. Defaults to virtio. - TODO:(ihar) switch to enums once opengen-api supports them. See: https://github.com/kubernetes/kube-openapi/issues/51 type: string name: description: |- @@ -1805,7 +1831,11 @@ spec: state: description: |- State represents the requested operational state of the interface. - The (only) value supported is 'absent', expressing a request to remove the interface. + The supported values are: + 'absent', expressing a request to remove the interface. + 'down', expressing a request to set the link down. + 'up', expressing a request to set the link up. + Empty value functions as 'up'. type: string tag: description: If specified, the virtual network interface @@ -1831,6 +1861,19 @@ spec: depends on additional factors of the VirtualMachineInstance, like the number of guest CPUs. type: boolean + panicDevices: + description: PanicDevices provides additional crash information + when a guest crashes. + items: + properties: + model: + description: |- + Model specifies what type of panic device is provided. + The panic model used when this attribute is missing depends on the hypervisor and guest arch. + One of: isa, hyperv, pvpanic. + type: string + type: object + type: array rng: description: Whether to have random number generator from host @@ -1853,6 +1896,11 @@ spec: tpm: description: Whether to emulate a TPM device. properties: + enabled: + description: |- + Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine + Defaults to True + type: boolean persistent: description: |- Persistent indicates the state of the TPM device should be kept accross reboots @@ -1865,10 +1913,30 @@ spec: This is helpful for old machines like CentOS6 or RHEL6 which do not understand virtio_non_transitional (virtio 1.0). type: boolean + video: + description: Video describes the video device configuration + for the vmi. + properties: + type: + description: |- + Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + type: string + type: object watchdog: description: Watchdog describes a watchdog device which can be added to the vmi. properties: + diag288: + description: diag288 watchdog device (specific to s390x + architecture). + properties: + action: + description: |- + The action to take. Valid values are poweroff, reset, shutdown. + Defaults to reset. + type: string + type: object i6300esb: description: i6300esb watchdog device. properties: @@ -2138,6 +2206,11 @@ spec: acpi: description: Information that can be set in the ACPI table properties: + msdmNameRef: + description: |- + Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. + The above points to the spec of MSDM too. + type: string slicNameRef: description: |- SlicNameRef should match the volume name of a secret object. The data in the secret should @@ -2221,11 +2294,20 @@ spec: Defaults to a random generated uid. type: string type: object + ioThreads: + description: IOThreads specifies the IOThreads options. + properties: + supplementalPoolThreadCount: + description: SupplementalPoolThreadCount specifies how many + iothreads are allocated for the supplementalPool policy. + format: int32 + type: integer + type: object ioThreadsPolicy: description: |- Controls whether or not disks will share IOThreads. Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto + One of: shared, auto, supplementalPool type: string launchSecurity: description: Launch Security setting of the vmi. @@ -2340,7 +2422,7 @@ spec: - "None": No action will be taken, according to the specified 'RunStrategy' the VirtualMachine will be restarted or shutdown. - "LiveMigrate": the VirtualMachineInstance will be migrated instead of being shutdown. - "LiveMigrateIfPossible": the same as "LiveMigrate" but only if the VirtualMachine is Live-Migratable, otherwise it will behave as "None". - - "External": the VirtualMachineInstance will be protected by a PDB and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. + - "External": the VirtualMachineInstance will be protected and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. type: string hostname: description: |- @@ -2453,7 +2535,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -2652,7 +2733,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -2682,6 +2762,65 @@ spec: format: int32 type: integer type: object + resourceClaims: + description: |- + ResourceClaims define which ResourceClaims must be allocated + and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources + will be made available to the domain which consumes them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate in kubernetes + https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map schedulerName: description: |- If specified, the VMI will be dispatched by specified scheduler. @@ -2809,7 +2948,6 @@ spec: Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string @@ -2849,7 +2987,6 @@ spec: Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | @@ -2867,7 +3004,6 @@ spec: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -2879,7 +3015,6 @@ spec: has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. - If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -2952,10 +3087,13 @@ spec: that contains config drive networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2964,10 +3102,13 @@ spec: contains config drive userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2999,10 +3140,13 @@ spec: that contains NoCloud networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3011,10 +3155,13 @@ spec: contains NoCloud userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3033,10 +3180,13 @@ spec: More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or it's keys @@ -3076,6 +3226,8 @@ spec: description: Path defines the path to disk file in the container type: string hotpluggable: + description: Hotpluggable indicates whether the volume can + be hotplugged and hotunplugged. type: boolean required: - image @@ -3090,9 +3242,8 @@ spec: be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the PVC in + the same namespace. type: string required: - name @@ -3340,10 +3491,13 @@ spec: be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3353,10 +3507,13 @@ spec: be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3436,6 +3593,97 @@ spec: format: int32 type: integer type: object + deviceStatus: + description: |- + DeviceStatus reflects the state of devices requested in spec.domain.devices. This is an optional field available + only when DRA feature gate is enabled + This field will only be populated if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + properties: + gpuStatuses: + description: GPUStatuses reflects the state of GPUs requested + in spec.domain.devices.gpus + items: + properties: + deviceResourceClaimStatus: + description: DeviceResourceClaimStatus reflects the DRA + related information for the device + properties: + attributes: + description: |- + Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more + about the device, like pciAddress or mdevUUID + properties: + mDevUUID: + description: MDevUUID is the mediated device uuid + of the allocated device + type: string + pciAddress: + description: PCIAddress is the PCIe bus address + of the allocated device + type: string + type: object + name: + description: Name is the name of actual device on the + host provisioned by the driver as reflected in resourceclaim.status + type: string + resourceClaimName: + description: ResourceClaimName is the name of the resource + claims object used to provision this resource + type: string + type: object + name: + description: Name of the device as specified in spec.domain.devices.gpus.name + or spec.domain.devices.hostDevices.name + type: string + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + hostDeviceStatuses: + description: |- + HostDeviceStatuses reflects the state of GPUs requested in spec.domain.devices.hostDevices + DRA + items: + properties: + deviceResourceClaimStatus: + description: DeviceResourceClaimStatus reflects the DRA + related information for the device + properties: + attributes: + description: |- + Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more + about the device, like pciAddress or mdevUUID + properties: + mDevUUID: + description: MDevUUID is the mediated device uuid + of the allocated device + type: string + pciAddress: + description: PCIAddress is the PCIe bus address + of the allocated device + type: string + type: object + name: + description: Name is the name of actual device on the + host provisioned by the driver as reflected in resourceclaim.status + type: string + resourceClaimName: + description: ResourceClaimName is the name of the resource + claims object used to provision this resource + type: string + type: object + name: + description: Name of the device as specified in spec.domain.devices.gpus.name + or spec.domain.devices.hostDevices.name + type: string + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object evacuationNodeName: description: |- EvacuationNodeName is used to track the eviction process of a VMI. It stores the name of the node that we want @@ -3443,8 +3691,9 @@ spec: type: string fsFreezeStatus: description: |- - FSFreezeStatus is the state of the fs of the guest - it can be either frozen or thawed + FSFreezeStatus indicates whether a freeze operation was requested for the guest filesystem. + It will be set to "frozen" if the request was made, or unset otherwise. + This does not reflect the actual state of the guest filesystem. type: string guestOSInfo: description: Guest OS Information @@ -3496,6 +3745,10 @@ spec: items: type: string type: array + linkState: + description: 'LinkState Reports the current operational link + state''. values: up, down.' + type: string mac: description: Hardware address of a Virtual Machine interface type: string @@ -3503,6 +3756,10 @@ spec: description: Name of the interface, corresponds to name of the network assigned to the interface type: string + podInterfaceName: + description: PodInterfaceName represents the name of the pod + network interface + type: string queueCount: description: Specifies how many queues are allocated by MultiQueue format: int32 @@ -3731,6 +3988,13 @@ spec: If set to true, migrations will still start in pre-copy, but switch to post-copy when CompletionTimeoutPerGiB triggers. Defaults to false type: boolean + allowWorkloadDisruption: + description: |- + AllowWorkloadDisruption indicates that the migration shouldn't be + canceled after acceptableCompletionTime is exceeded. Instead, if + permitted, migration will be switched to post-copy or the VMI will be + paused to allow the migration to complete + type: boolean bandwidthPerMigration: anyOf: - type: integer @@ -3743,8 +4007,8 @@ spec: completionTimeoutPerGiB: description: |- CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take. - If a live-migration takes longer to migrate than this value multiplied by the size of the VMI, - the migration will be cancelled, unless AllowPostCopy is true. Defaults to 800 + If the timeout is reached, the migration will be either paused, switched + to post-copy or cancelled depending on other settings. Defaults to 150 format: int64 type: integer disableTLS: @@ -3794,6 +4058,9 @@ spec: indicates the migration will be unsafe to the guest. Defaults to false type: boolean type: object + migrationNetworkType: + description: The type of migration network, either 'pod' or 'migration' + type: string migrationPolicyName: description: Name of the migration policy. If string is empty, no policy is matched @@ -3809,8 +4076,57 @@ spec: sourceNode: description: The source node that the VMI originated on type: string + sourcePersistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string sourcePod: type: string + sourceState: + description: SourceState contains migration state managed by the + source virt handler + properties: + domainName: + description: The name of the domain on the source libvirt + domain + type: string + domainNamespace: + description: Namespace used in the name of the source libvirt + domain. Can be used to find and modify paths in the domain + type: string + migrationUID: + description: The Source VirtualMachineInstanceMigration object + associated with this migration + type: string + node: + description: The source node that the VMI originated on + type: string + nodeSelectors: + additionalProperties: + type: string + description: Node selectors needed by the target to start + the receiving pod. + type: object + persistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string + pod: + description: The source pod that the VMI is originated on + type: string + selinuxContext: + description: SELinuxContext is the actual SELinux context + of the pod + type: string + syncAddress: + description: The ip address/fqdn:port combination to use to + synchronize the VMI with the target. + type: string + virtualMachineInstanceUID: + description: VirtualMachineInstanceUID is the UID of the target + virtual machine instance + type: string + type: object startTimestamp: description: The time the migration action began format: date-time @@ -3853,9 +4169,87 @@ spec: If the VMI requires dedicated CPUs, this field will hold the numa topology on the target node type: string + targetPersistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its target PVC name is saved here + type: string targetPod: description: The target pod that the VMI is moving to type: string + targetState: + description: TargetState contains migration state managed by the + target virt handler + properties: + attachmentPodUID: + description: The UID of the target attachment pod for hotplug + volumes + type: string + cpuSet: + description: |- + If the VMI requires dedicated CPUs, this field will + hold the dedicated CPU set on the target node + items: + type: integer + type: array + x-kubernetes-list-type: atomic + directMigrationNodePorts: + additionalProperties: + type: integer + description: The list of ports opened for live migration on + the destination node + type: object + domainDetected: + description: The Target Node has seen the Domain Start Event + type: boolean + domainName: + description: The name of the domain on the source libvirt + domain + type: string + domainNamespace: + description: Namespace used in the name of the source libvirt + domain. Can be used to find and modify paths in the domain + type: string + domainReadyTimestamp: + description: The timestamp at which the target node detects + the domain is active + format: date-time + type: string + migrationUID: + description: The Source VirtualMachineInstanceMigration object + associated with this migration + type: string + node: + description: The source node that the VMI originated on + type: string + nodeAddress: + description: The address of the target node to use for the + migration + type: string + nodeTopology: + description: |- + If the VMI requires dedicated CPUs, this field will + hold the numa topology on the target node + type: string + persistentStatePVCName: + description: If the VMI being migrated uses persistent features + (backend-storage), its source PVC name is saved here + type: string + pod: + description: The source pod that the VMI is originated on + type: string + selinuxContext: + description: SELinuxContext is the actual SELinux context + of the pod + type: string + syncAddress: + description: The ip address/fqdn:port combination to use to + synchronize the VMI with the target. + type: string + virtualMachineInstanceUID: + description: VirtualMachineInstanceUID is the UID of the target + virtual machine instance + type: string + type: object type: object migrationTransport: description: This represents the migration transport diff --git a/crds/embedded/virtualmachines.yaml b/crds/embedded/virtualmachines.yaml index 72d9f865f6..a0bfe284f4 100644 --- a/crds/embedded/virtualmachines.yaml +++ b/crds/embedded/virtualmachines.yaml @@ -319,7 +319,7 @@ spec: set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -812,6 +812,7 @@ spec: description: |- Running controls whether the associatied VirtualMachineInstance is created or not Mutually exclusive with RunStrategy + Deprecated: VirtualMachineInstance field "Running" is now deprecated, please use RunStrategy instead. type: boolean template: description: Template is the direct specification of VirtualMachineInstance @@ -1219,7 +1220,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1234,7 +1235,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1402,7 +1403,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1417,7 +1418,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1583,7 +1584,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1598,7 +1599,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1766,7 +1767,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1781,7 +1782,7 @@ spec: pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). items: type: string type: array @@ -1894,9 +1895,13 @@ spec: options of a pod. properties: name: - description: Required. + description: |- + Name is this DNS resolver option's name. + Required. type: string value: + description: Value is this DNS resolver option's + value. type: string type: object type: array @@ -2217,7 +2222,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the @@ -2344,12 +2353,24 @@ spec: vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: + description: DeviceName is the name of the device + provisioned by device-plugins type: string name: description: Name of the GPU device as exposed by a device plugin type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided @@ -2388,19 +2409,28 @@ spec: vmi. items: properties: + claimName: + description: |- + ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this + device is allocated + type: string deviceName: - description: DeviceName is the resource name - of the host device exposed by a device plugin + description: DeviceName is the name of the device + provisioned by device-plugins type: string name: type: string + requestName: + description: |- + RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this + device is requested + type: string tag: description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive type: string required: - - deviceName - name type: object type: array @@ -2523,9 +2553,8 @@ spec: model: description: |- Interface model. - One of: e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio. + One of: e1000, e1000e, igb, ne2k_pci, pcnet, rtl8139, virtio. Defaults to virtio. - TODO:(ihar) switch to enums once opengen-api supports them. See: https://github.com/kubernetes/kube-openapi/issues/51 type: string name: description: |- @@ -2587,7 +2616,11 @@ spec: state: description: |- State represents the requested operational state of the interface. - The (only) value supported is 'absent', expressing a request to remove the interface. + The supported values are: + 'absent', expressing a request to remove the interface. + 'down', expressing a request to set the link down. + 'up', expressing a request to set the link up. + Empty value functions as 'up'. type: string tag: description: If specified, the virtual network @@ -2614,6 +2647,19 @@ spec: of the VirtualMachineInstance, like the number of guest CPUs. type: boolean + panicDevices: + description: PanicDevices provides additional crash + information when a guest crashes. + items: + properties: + model: + description: |- + Model specifies what type of panic device is provided. + The panic model used when this attribute is missing depends on the hypervisor and guest arch. + One of: isa, hyperv, pvpanic. + type: string + type: object + type: array rng: description: Whether to have random number generator from host @@ -2637,6 +2683,11 @@ spec: tpm: description: Whether to emulate a TPM device. properties: + enabled: + description: |- + Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine + Defaults to True + type: boolean persistent: description: |- Persistent indicates the state of the TPM device should be kept accross reboots @@ -2649,10 +2700,30 @@ spec: This is helpful for old machines like CentOS6 or RHEL6 which do not understand virtio_non_transitional (virtio 1.0). type: boolean + video: + description: Video describes the video device configuration + for the vmi. + properties: + type: + description: |- + Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + type: string + type: object watchdog: description: Watchdog describes a watchdog device which can be added to the vmi. properties: + diag288: + description: diag288 watchdog device (specific + to s390x architecture). + properties: + action: + description: |- + The action to take. Valid values are poweroff, reset, shutdown. + Defaults to reset. + type: string + type: object i6300esb: description: i6300esb watchdog device. properties: @@ -2923,6 +2994,11 @@ spec: description: Information that can be set in the ACPI table properties: + msdmNameRef: + description: |- + Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. + The above points to the spec of MSDM too. + type: string slicNameRef: description: |- SlicNameRef should match the volume name of a secret object. The data in the secret should @@ -3009,11 +3085,21 @@ spec: Defaults to a random generated uid. type: string type: object + ioThreads: + description: IOThreads specifies the IOThreads options. + properties: + supplementalPoolThreadCount: + description: SupplementalPoolThreadCount specifies + how many iothreads are allocated for the supplementalPool + policy. + format: int32 + type: integer + type: object ioThreadsPolicy: description: |- Controls whether or not disks will share IOThreads. Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto + One of: shared, auto, supplementalPool type: string launchSecurity: description: Launch Security setting of the vmi. @@ -3129,7 +3215,7 @@ spec: - "None": No action will be taken, according to the specified 'RunStrategy' the VirtualMachine will be restarted or shutdown. - "LiveMigrate": the VirtualMachineInstance will be migrated instead of being shutdown. - "LiveMigrateIfPossible": the same as "LiveMigrate" but only if the VirtualMachine is Live-Migratable, otherwise it will behave as "None". - - "External": the VirtualMachineInstance will be protected by a PDB and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. + - "External": the VirtualMachineInstance will be protected and 'vmi.Status.EvacuationNodeName' will be set on eviction. This is mainly useful for cluster-api-provider-kubevirt (capk) which needs a way for VMI's to be blocked from eviction, yet signal capk that eviction has been called on the VMI so the capk controller can handle tearing the VMI down. Details can be found in the commit description https://github.com/kubevirt/kubevirt/commit/c1d77face705c8b126696bac9a3ee3825f27f1fa. type: string hostname: description: |- @@ -3242,7 +3328,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -3441,7 +3526,6 @@ spec: description: |- TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported - TODO: implement a realistic TCP lifecycle hook properties: host: description: 'Optional: Host name to connect to, defaults @@ -3471,6 +3555,65 @@ spec: format: int32 type: integer type: object + resourceClaims: + description: |- + ResourceClaims define which ResourceClaims must be allocated + and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources + will be made available to the domain which consumes them + by name. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate in kubernetes + https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This feature is in alpha. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim + for the pod. + + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + + Exactly one of ResourceClaimName and ResourceClaimTemplateName must + be set. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map schedulerName: description: |- If specified, the VMI will be dispatched by specified scheduler. @@ -3600,7 +3743,6 @@ spec: Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. - This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string @@ -3640,7 +3782,6 @@ spec: Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. - For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | @@ -3658,7 +3799,6 @@ spec: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. - If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -3670,7 +3810,6 @@ spec: has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. - If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string @@ -3743,10 +3882,13 @@ spec: secret that contains config drive networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3755,10 +3897,13 @@ spec: secret that contains config drive userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3790,10 +3935,13 @@ spec: secret that contains NoCloud networkdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3802,10 +3950,13 @@ spec: secret that contains NoCloud userdata. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3824,10 +3975,13 @@ spec: More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or it's @@ -3882,9 +4036,8 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the + PVC in the same namespace. type: string required: - name @@ -4137,10 +4290,13 @@ spec: that should be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -4150,10 +4306,13 @@ spec: that should be attached as disk of CDROM type. properties: name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -4219,6 +4378,35 @@ spec: updated through an Update() before ObservedGeneration in Status. format: int64 type: integer + instancetypeRef: + description: InstancetypeRef captures the state of any referenced + instance type from the VirtualMachine + nullable: true + properties: + controllerRevisionRef: + description: |- + ControllerRef specifies the ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller + properties: + name: + description: Name of the ControllerRevision + type: string + type: object + inferFromVolume: + description: InferFromVolume lists the name of a volume that should + be used to infer or discover the resource + type: string + inferFromVolumeFailurePolicy: + description: InferFromVolumeFailurePolicy controls what should + happen on failure when inferring the resource + type: string + kind: + description: Kind specifies the kind of resource + type: string + name: + description: Name is the name of resource + type: string + type: object memoryDumpRequest: description: |- MemoryDumpRequest tracks memory dump request phase and info of getting a memory @@ -4262,6 +4450,35 @@ spec: vmi when started. format: int64 type: integer + preferenceRef: + description: PreferenceRef captures the state of any referenced preference + from the VirtualMachine + nullable: true + properties: + controllerRevisionRef: + description: |- + ControllerRef specifies the ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller + properties: + name: + description: Name of the ControllerRevision + type: string + type: object + inferFromVolume: + description: InferFromVolume lists the name of a volume that should + be used to infer or discover the resource + type: string + inferFromVolumeFailurePolicy: + description: InferFromVolumeFailurePolicy controls what should + happen on failure when inferring the resource + type: string + kind: + description: Kind specifies the kind of resource + type: string + name: + description: Name is the name of resource + type: string + type: object printableStatus: default: Stopped description: PrintableStatus is a human readable, high-level representation @@ -4378,7 +4595,11 @@ spec: cache: description: |- Cache specifies which kvm disk cache mode should be used. - Supported values are: CacheNone, CacheWriteThrough. + Supported values are: + none: Guest I/O not cached on the host, but may be kept in a disk cache. + writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. + writeback: Guest I/O cached on the host. + Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: description: Attach a volume as a cdrom to the vmi. @@ -4531,9 +4752,8 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: |- - Name of both the DataVolume and the PVC in the same namespace. - After PVC population the DataVolume is garbage collected by default. + description: Name of both the DataVolume and the + PVC in the same namespace. type: string required: - name @@ -4615,6 +4835,134 @@ spec: - name type: object type: array + volumeUpdateState: + description: |- + VolumeUpdateState contains the information about the volumes set + updates related to the volumeUpdateStrategy + properties: + volumeMigrationState: + description: VolumeMigrationState tracks the information related + to the volume migration + properties: + migratedVolumes: + description: MigratedVolumes lists the source and destination + volumes during the volume migration + items: + description: StorageMigratedVolumeInfo tracks the information + about the source and destination volumes during the volume + migration + properties: + destinationPVCInfo: + description: DestinationPVCInfo contains the information + about the destination PVC + properties: + accessModes: + description: |- + AccessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents the capacity set + on the corresponding PVC status + type: object + claimName: + description: ClaimName is the name of the PVC + type: string + filesystemOverhead: + description: Percentage of filesystem's size to + be reserved when resizing the PVC + pattern: ^(0(?:\.\d{1,3})?|1)$ + type: string + preallocated: + description: Preallocated indicates if the PVC's + storage is preallocated or not + type: boolean + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Requests represents the resources requested + by the corresponding PVC spec + type: object + volumeMode: + description: |- + VolumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + type: object + sourcePVCInfo: + description: SourcePVCInfo contains the information + about the source PVC + properties: + accessModes: + description: |- + AccessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents the capacity set + on the corresponding PVC status + type: object + claimName: + description: ClaimName is the name of the PVC + type: string + filesystemOverhead: + description: Percentage of filesystem's size to + be reserved when resizing the PVC + pattern: ^(0(?:\.\d{1,3})?|1)$ + type: string + preallocated: + description: Preallocated indicates if the PVC's + storage is preallocated or not + type: boolean + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Requests represents the resources requested + by the corresponding PVC spec + type: object + volumeMode: + description: |- + VolumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + type: object + volumeName: + description: VolumeName is the name of the volume that + is being migrated + type: string + required: + - volumeName + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object type: object required: - spec diff --git a/images/hooks/go.mod b/images/hooks/go.mod index b83313b898..0b23217359 100644 --- a/images/hooks/go.mod +++ b/images/hooks/go.mod @@ -105,7 +105,7 @@ require ( k8s.io/component-base v0.33.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect - kubevirt.io/api v1.3.1 // indirect + kubevirt.io/api v1.6.2 // indirect kubevirt.io/containerized-data-importer-api v1.60.3 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-runtime v0.21.0 // indirect diff --git a/images/hooks/go.sum b/images/hooks/go.sum index 3e1497b592..f94e4c5651 100644 --- a/images/hooks/go.sum +++ b/images/hooks/go.sum @@ -647,8 +647,8 @@ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= -kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.60.3 h1:kQEXi7scpzUa0RPf3/3MKk1Kmem0ZlqqiuK3kDF5L2I= kubevirt.io/containerized-data-importer-api v1.60.3/go.mod h1:8mwrkZIdy8j/LmCyKt2wFXbiMavLUIqDaegaIF67CZs= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= diff --git a/images/virt-api/debug/dlv.Dockerfile b/images/virt-api/debug/dlv.Dockerfile index bca504a4d3..fe10ced68b 100644 --- a/images/virt-api/debug/dlv.Dockerfile +++ b/images/virt-api/debug/dlv.Dockerfile @@ -1,10 +1,10 @@ -FROM golang:1.22.7 AS builder +FROM golang:1.23 AS builder RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="1.6.2-virtualization" +ENV VERSION="1.6.2" +ENV GOVERSION="1.23.0" # Copy the git commits for rebuilding the image if the branch changes ADD "https://api.github.com/repos/deckhouse/3p-kubevirt/commits/$BRANCH" /.git-commit-hash.tmp @@ -14,7 +14,7 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor ENV GO111MODULE=on ENV GOOS=linux diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 86f8472824..68ad38042c 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -83,7 +83,7 @@ shell: cd /kubevirt go mod download - go mod vendor + go work vendor for p in patches/*.patch ; do echo -n "Apply ${p} ... " diff --git a/images/virt-controller/debug/dlv.Dockerfile b/images/virt-controller/debug/dlv.Dockerfile index ab4f9606db..fec4948301 100644 --- a/images/virt-controller/debug/dlv.Dockerfile +++ b/images/virt-controller/debug/dlv.Dockerfile @@ -1,10 +1,10 @@ -FROM golang:1.22.7 AS builder +FROM golang:1.23 AS builder RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="v1.6.1-virtualization" +ENV VERSION="1.6.1" +ENV GOVERSION="1.23.0" # Copy the git commits for rebuilding the image if the branch changes ADD "https://api.github.com/repos/deckhouse/3p-kubevirt/commits/$BRANCH" /.git-commit-hash.tmp @@ -14,7 +14,7 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor ENV GO111MODULE=on ENV GOOS=linux diff --git a/images/virt-handler/debug/dlv.Dockerfile b/images/virt-handler/debug/dlv.Dockerfile index 12142d5178..86af33b002 100644 --- a/images/virt-handler/debug/dlv.Dockerfile +++ b/images/virt-handler/debug/dlv.Dockerfile @@ -3,6 +3,7 @@ RUN groupadd --gid 1001 nonroot-user && useradd nonroot-user --uid 1001 --gid 10 FROM basealt AS builder +# TODO add pin repository url RUN apt-get update RUN apt-get install -y \ @@ -17,9 +18,9 @@ RUN apt-get install -y \ RUN go install github.com/go-delve/delve/cmd/dlv@latest -ARG BRANCH="1.3.1-virtualization" -ENV VERSION="1.3.1" -ENV GOVERSION="1.22.7" +ARG BRANCH="1.6.2-virtualization" +ENV VERSION="1.6.2" +ENV GOVERSION="1.23.0" RUN mkdir /kubevirt-config-files && echo "v$VERSION-dirty" > /kubevirt-config-files/.version @@ -31,11 +32,11 @@ WORKDIR /kubevirt RUN go mod edit -go=$GOVERSION && \ go mod download -RUN go mod vendor +RUN go work vendor -RUN for p in patches/*.patch ; do \ - echo -n "Apply ${p} ... " \ - git apply --ignore-space-change --ignore-whitespace ${p} && echo OK || (echo FAIL ; exit 1) \ +RUN for p in patches/*.patch; do \ + echo -n "Apply ${p} ... " && \ + git apply --ignore-space-change --ignore-whitespace "${p}" && echo OK || (echo FAIL && exit 1); \ done ENV GO111MODULE=on @@ -52,9 +53,7 @@ FROM basealt RUN apt-get update && apt-get install --yes \ acl \ procps \ - nftables \ - qemu-img==9.1.2-alt1 \ - xorriso==1.5.6-alt1 && \ + nftables && \ apt-get clean && \ rm --recursive --force /var/lib/apt/lists/ftp.altlinux.org* /var/cache/apt/*.bin @@ -63,7 +62,6 @@ RUN echo "qemu:x:107:107::/home/qemu:/bin/bash" >> /etc/passwd && \ mkdir -p /home/qemu && \ chown -R 107:107 /home/qemu -COPY --from=builder /kubevirt/cmd/virt-handler/virt_launcher.cil /virt_launcher.cil COPY --from=builder /kubevirt-config-files/.version /.version COPY --from=builder /kubevirt/cmd/virt-handler/nsswitch.conf /etc/nsswitch.conf diff --git a/images/virt-handler/werf.inc.yaml b/images/virt-handler/werf.inc.yaml index 4888e05684..3db87a474a 100644 --- a/images/virt-handler/werf.inc.yaml +++ b/images/virt-handler/werf.inc.yaml @@ -25,10 +25,6 @@ import: - virt-chroot - virt-handler - container-disk -- image: {{ .ModuleNamePrefix }}virt-artifact - add: /kubevirt/cmd/{{ $.ImageName }}/virt_launcher.cil - to: /virt_launcher.cil - after: install - image: {{ .ModuleNamePrefix }}virt-artifact add: /kubevirt-config-files/.version to: /.version diff --git a/images/virtualization-artifact/go.mod b/images/virtualization-artifact/go.mod index 19f7218e17..acc024b811 100644 --- a/images/virtualization-artifact/go.mod +++ b/images/virtualization-artifact/go.mod @@ -32,7 +32,7 @@ require ( k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - kubevirt.io/api v1.3.1 + kubevirt.io/api v1.6.2 kubevirt.io/containerized-data-importer-api v1.60.3 sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/yaml v1.4.0 @@ -165,4 +165,4 @@ replace ( ) // Kubevirt API replaces -replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18 +replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0 diff --git a/images/virtualization-artifact/go.sum b/images/virtualization-artifact/go.sum index 657b17c4fb..13c0de21fe 100644 --- a/images/virtualization-artifact/go.sum +++ b/images/virtualization-artifact/go.sum @@ -45,8 +45,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18 h1:9pstD3PiPmby/Chh24ickwUNbAcqbceOPp253/jSr8k= -github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.3.1-v12n.18/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0 h1:Ro9oG/eakqMxfFSEs91BZYhDXggghuJjFvawV6/EKSo= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v1.6.2-v12n.0/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5 h1:PsN1E0oxC/+4zdA977txrqUCuObFL3HAuu5Xnud8m8c= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5/go.mod h1:Mk5HRzkc5pIcDIZ2JJ6DPuuqnwhXVkb3you8M8Mg+4w= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= diff --git a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go index 21910bc868..0fe5d9851a 100644 --- a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go +++ b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go @@ -38,6 +38,7 @@ const ( MigrationCompletionTimeoutPerGiB int64 = 800 DefaultUnsafeMigrationOverride bool = false MigrationAllowPostCopy bool = false + MigrationAllowWorkloadDisruption bool = false ) func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) *virtv1.MigrationConfiguration { @@ -63,6 +64,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) completionTimeoutPerGiB := MigrationCompletionTimeoutPerGiB defaultUnsafeMigrationOverride := DefaultUnsafeMigrationOverride allowPostCopy := MigrationAllowPostCopy + allowWorkloadDisruption := MigrationAllowWorkloadDisruption return &virtv1.MigrationConfiguration{ ParallelMigrationsPerCluster: ¶llelMigrationsPerCluster, @@ -74,6 +76,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) UnsafeMigrationOverride: &defaultUnsafeMigrationOverride, AllowAutoConverge: &allowAutoConverge, AllowPostCopy: &allowPostCopy, + AllowWorkloadDisruption: &allowWorkloadDisruption, DisableTLS: nil, Network: nil, MatchSELinuxLevelOnMigration: nil, diff --git a/images/vm-route-forge/go.mod b/images/vm-route-forge/go.mod index 57bbcc5dcc..1748f07e51 100644 --- a/images/vm-route-forge/go.mod +++ b/images/vm-route-forge/go.mod @@ -67,7 +67,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 // indirect github.com/openshift/custom-resource-status v1.1.2 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect @@ -123,8 +122,8 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/images/vm-route-forge/go.sum b/images/vm-route-forge/go.sum index 65cc2e5874..3c63121653 100644 --- a/images/vm-route-forge/go.sum +++ b/images/vm-route-forge/go.sum @@ -300,8 +300,6 @@ github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxj github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 h1:t/CahSnpqY46sQR01SoS+Jt0jtjgmhgE6lFmRnO4q70= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= @@ -677,10 +675,10 @@ k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= -kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/src/cli/go.mod b/src/cli/go.mod index 08d54d3720..b1f4841b36 100644 --- a/src/cli/go.mod +++ b/src/cli/go.mod @@ -66,8 +66,8 @@ require ( k8s.io/api v0.33.3 // indirect k8s.io/apiextensions-apiserver v0.33.3 // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect - kubevirt.io/api v1.3.1 // indirect - kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/api v1.6.2 // indirect + kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/controller-runtime v0.21.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect diff --git a/src/cli/go.sum b/src/cli/go.sum index 19170b2178..c1dd9838cd 100644 --- a/src/cli/go.sum +++ b/src/cli/go.sum @@ -589,8 +589,12 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= +kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index 2951618f9d..81b71c9949 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -52,16 +52,12 @@ spec: virtOperator: {{ $logVerbosity }} featureGates: - HotplugVolumes - - GPU - Snapshot - ExpandDisks - Root - - VMLiveUpdateFeatures - CPUManager - Sidecar - VolumeSnapshotDataSource - - VolumeMigration - - VolumesUpdateStrategy virtualMachineOptions: disableSerialConsoleLog: {} customizeComponents: diff --git a/templates/kubevirt/virt-operator/rbac-for-us.yaml b/templates/kubevirt/virt-operator/rbac-for-us.yaml index d52cec41b0..91a6311478 100644 --- a/templates/kubevirt/virt-operator/rbac-for-us.yaml +++ b/templates/kubevirt/virt-operator/rbac-for-us.yaml @@ -26,6 +26,8 @@ rules: - kubevirt-virt-api-certs - kubevirt-controller-certs - kubevirt-exportproxy-certs + - kubevirt-synchronization-controller-certs + - kubevirt-synchronization-controller-server-certs resources: - secrets verbs: @@ -834,6 +836,9 @@ rules: - virtualmachineinstances/userlist - virtualmachineinstances/sev/fetchcertchain - virtualmachineinstances/sev/querylaunchmeasurement + - virtualmachineinstances/usbredir + - virtualmachines/objectgraph + - virtualmachineinstances/objectgraph verbs: - get - apiGroups: @@ -846,6 +851,7 @@ rules: - virtualmachineinstances/freeze - virtualmachineinstances/unfreeze - virtualmachineinstances/softreboot + - virtualmachineinstances/reset - virtualmachineinstances/sev/setupsession - virtualmachineinstances/sev/injectlaunchsecret verbs: @@ -1214,6 +1220,15 @@ rules: - subjectaccessreviews verbs: - create +- apiGroups: + - resource.k8s.io + resources: + - resourceclaims + - resourceslices + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/test/e2e/go.mod b/test/e2e/go.mod index 337850b52c..5b10ad4c6e 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -16,7 +16,7 @@ require ( k8s.io/cli-runtime v0.33.3 k8s.io/client-go v0.33.3 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - kubevirt.io/api v1.3.1 + kubevirt.io/api v1.6.2 kubevirt.io/containerized-data-importer-api v1.60.3 sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/yaml v1.4.0 diff --git a/test/e2e/go.sum b/test/e2e/go.sum index 8184d943d5..304dba8d26 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -582,6 +582,8 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= +kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= +kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= kubevirt.io/containerized-data-importer-api v1.60.3 h1:kQEXi7scpzUa0RPf3/3MKk1Kmem0ZlqqiuK3kDF5L2I= kubevirt.io/containerized-data-importer-api v1.60.3/go.mod h1:8mwrkZIdy8j/LmCyKt2wFXbiMavLUIqDaegaIF67CZs= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= From 50e96692151279d4e7e9975f652f465047f1d2d0 Mon Sep 17 00:00:00 2001 From: Vladislav Panfilov Date: Tue, 9 Dec 2025 14:04:43 +0400 Subject: [PATCH 7/9] Review embedded YAML descriptions Signed-off-by: Vladislav Panfilov --- crds/embedded/virtualmachineinstances.yaml | 209 ++++++++---------- crds/embedded/virtualmachines.yaml | 235 +++++++++------------ 2 files changed, 188 insertions(+), 256 deletions(-) diff --git a/crds/embedded/virtualmachineinstances.yaml b/crds/embedded/virtualmachineinstances.yaml index b676c9ed3a..a36f250777 100644 --- a/crds/embedded/virtualmachineinstances.yaml +++ b/crds/embedded/virtualmachineinstances.yaml @@ -1128,11 +1128,11 @@ spec: properties: name: description: |- - Name is this DNS resolver option's name. - Required. + DNS resolver option name. + Required field. type: string value: - description: Value is this DNS resolver option's value. + description: DNS resolver option value. type: string type: object type: array @@ -1576,26 +1576,22 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device provisioned - by device-plugins + description: Name of the device provisioned by device plugins. type: string name: - description: Name of the GPU device as exposed by a - device plugin + description: Name of the GPU device as exposed by a device plugin. type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network interface - address and its tag will be provided to the guest - via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string virtualGPUOptions: properties: @@ -1630,24 +1626,21 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device provisioned - by device-plugins + description: Name of the device provisioned by device plugins. type: string name: type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network interface - address and its tag will be provided to the guest - via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -1862,15 +1855,14 @@ spec: like the number of guest CPUs. type: boolean panicDevices: - description: PanicDevices provides additional crash information - when a guest crashes. + description: Provides additional crash information when a guest crashes. items: properties: model: description: |- - Model specifies what type of panic device is provided. - The panic model used when this attribute is missing depends on the hypervisor and guest arch. - One of: isa, hyperv, pvpanic. + Type of panic device to provide. + If this attribute is missing, the panic model used depends on the hypervisor and guest architecture. + Valid values: `isa`, `hyperv`, `pvpanic`. type: string type: object type: array @@ -1898,13 +1890,13 @@ spec: properties: enabled: description: |- - Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine - Defaults to True + Allows explicitly disabling the vTPM even when one is enabled by a preference referenced by the VirtualMachine. + Defaults to true. type: boolean persistent: description: |- - Persistent indicates the state of the TPM device should be kept accross reboots - Defaults to false + Indicates whether the state of the TPM device should be kept across reboots. + Defaults to false. type: boolean type: object useVirtioTransitional: @@ -1914,13 +1906,12 @@ spec: do not understand virtio_non_transitional (virtio 1.0). type: boolean video: - description: Video describes the video device configuration - for the vmi. + description: Video device configuration for the VMI. properties: type: description: |- - Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). - If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + Video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent: VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64, virtio for Arm and s390x. type: string type: object watchdog: @@ -1928,12 +1919,11 @@ spec: be added to the vmi. properties: diag288: - description: diag288 watchdog device (specific to s390x - architecture). + description: diag288 watchdog device specific to s390x architecture. properties: action: description: |- - The action to take. Valid values are poweroff, reset, shutdown. + Action to take when the watchdog triggers. Valid values: poweroff, reset, shutdown. Defaults to reset. type: string type: object @@ -2295,19 +2285,18 @@ spec: type: string type: object ioThreads: - description: IOThreads specifies the IOThreads options. + description: IOThreads options. properties: supplementalPoolThreadCount: - description: SupplementalPoolThreadCount specifies how many - iothreads are allocated for the supplementalPool policy. + description: Number of IO threads allocated for the `supplementalPool` policy. format: int32 type: integer type: object ioThreadsPolicy: description: |- - Controls whether or not disks will share IOThreads. - Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto, supplementalPool + Controls whether disks share IOThreads. + Omitting this field disables the use of IOThreads. + Valid values: shared, auto, supplementalPool. type: string launchSecurity: description: Launch Security setting of the vmi. @@ -2764,55 +2753,47 @@ spec: type: object resourceClaims: description: |- - ResourceClaims define which ResourceClaims must be allocated - and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources - will be made available to the domain which consumes them - by name. + Defines which ResourceClaims must be allocated and reserved before the VMI, + hence the `virt-launcher` pod is allowed to start. The resources will be made available to the domain + which consumes them by name. - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate in kubernetes - https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ - This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This is an alpha field and requires enabling the `DynamicResourceAllocation` feature gate in Kubernetes. + See https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature gates `GPUsWithDRA` or `HostDevicesWithDRA` is enabled. This feature is in alpha. items: description: |- - PodResourceClaim references exactly one ResourceClaim, either directly + References exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod. - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Adds a name that uniquely identifies the ResourceClaim inside the pod. Containers that need access to the ResourceClaim reference it with this name. properties: name: description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. + Uniquely identifies this resource claim inside the pod. + Must be a `DNS_LABEL`. type: string resourceClaimName: description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. + Name of a ResourceClaim object in the same namespace as this pod. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string resourceClaimTemplateName: description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. + Name of a ResourceClaimTemplate object in the same namespace as this pod. - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + The template will be used to create a new ResourceClaim, which will be bound to this pod. + When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, + along with a generated component, will be used to form a unique name for the ResourceClaim, + which will be recorded in `pod.status.resourceClaimStatuses`. - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. + This field is immutable and no changes will be made to the corresponding ResourceClaim + by the control plane after creating the ResourceClaim. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string required: - name @@ -3226,8 +3207,7 @@ spec: description: Path defines the path to disk file in the container type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean required: - image @@ -3238,12 +3218,10 @@ spec: the process of populating that PVC with a disk image. properties: hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the PVC in - the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -3409,8 +3387,7 @@ spec: More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean readOnly: description: |- @@ -3438,8 +3415,7 @@ spec: More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims type: string hotpluggable: - description: Hotpluggable indicates whether the volume can - be hotplugged and hotunplugged. + description: Indicates whether the volume can be hotplugged and hotunplugged. type: boolean readOnly: description: |- @@ -3601,40 +3577,34 @@ spec: This feature is in alpha. properties: gpuStatuses: - description: GPUStatuses reflects the state of GPUs requested - in spec.domain.devices.gpus + description: State of GPUs requested in `spec.domain.devices.gpus`. items: properties: deviceResourceClaimStatus: - description: DeviceResourceClaimStatus reflects the DRA - related information for the device + description: DRA-related information for the device. properties: attributes: description: |- - Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more - about the device, like pciAddress or mdevUUID + Properties of the device that could be used by kubevirt and other components to learn more + about the device, like `pciAddress` or `mdevUUID`. properties: mDevUUID: - description: MDevUUID is the mediated device uuid - of the allocated device + description: Mediated device UUID of the allocated device. type: string pciAddress: - description: PCIAddress is the PCIe bus address - of the allocated device + description: PCIe bus address of the allocated device. type: string type: object name: - description: Name is the name of actual device on the - host provisioned by the driver as reflected in resourceclaim.status + description: Name of actual device on the host provisioned by the driver as reflected in `resourceclaim.status`. type: string resourceClaimName: - description: ResourceClaimName is the name of the resource - claims object used to provision this resource + description: Name of the resource claims object used to provision this resource. type: string type: object name: - description: Name of the device as specified in spec.domain.devices.gpus.name - or spec.domain.devices.hostDevices.name + description: Name of the device as specified in `spec.domain.devices.gpus.name` + or `spec.domain.devices.hostDevices.name`. type: string required: - name @@ -3643,40 +3613,35 @@ spec: x-kubernetes-list-type: atomic hostDeviceStatuses: description: |- - HostDeviceStatuses reflects the state of GPUs requested in spec.domain.devices.hostDevices + State of host devices requested in `spec.domain.devices.hostDevices`. DRA items: properties: deviceResourceClaimStatus: - description: DeviceResourceClaimStatus reflects the DRA - related information for the device + description: DRA-related information for the device. properties: attributes: description: |- - Attributes are properties of the device that could be used by kubevirt and other copmonents to learn more - about the device, like pciAddress or mdevUUID + Properties of the device that could be used by kubevirt and other components to learn more + about the device, like `pciAddress` or `mdevUUID`. properties: mDevUUID: - description: MDevUUID is the mediated device uuid - of the allocated device + description: Mediated device UUID of the allocated device. type: string pciAddress: - description: PCIAddress is the PCIe bus address - of the allocated device + description: PCIe bus address of the allocated device. type: string type: object name: - description: Name is the name of actual device on the - host provisioned by the driver as reflected in resourceclaim.status + description: Name of actual device on the host provisioned by the driver as reflected in `resourceclaim.status`. type: string resourceClaimName: - description: ResourceClaimName is the name of the resource - claims object used to provision this resource + description: Name of the resource claims object used to provision this resource. type: string type: object name: - description: Name of the device as specified in spec.domain.devices.gpus.name - or spec.domain.devices.hostDevices.name + description: Name of the device as specified in `spec.domain.devices.gpus.name` + or `spec.domain.devices.hostDevices.name`. type: string required: - name @@ -3746,19 +3711,17 @@ spec: type: string type: array linkState: - description: 'LinkState Reports the current operational link - state''. values: up, down.' + description: 'Current operational link state. Values: up, down.' type: string mac: - description: Hardware address of a Virtual Machine interface + description: Hardware address of a Virtual Machine interface. type: string name: description: Name of the interface, corresponds to name of the - network assigned to the interface + network assigned to the interface. type: string podInterfaceName: - description: PodInterfaceName represents the name of the pod - network interface + description: Name of the pod network interface. type: string queueCount: description: Specifies how many queues are allocated by MultiQueue @@ -4059,7 +4022,7 @@ spec: type: boolean type: object migrationNetworkType: - description: The type of migration network, either 'pod' or 'migration' + description: Type of migration network, either 'pod' or 'migration'. type: string migrationPolicyName: description: Name of the migration policy. If string is empty, @@ -4078,7 +4041,7 @@ spec: type: string sourcePersistentStatePVCName: description: If the VMI being migrated uses persistent features - (backend-storage), its source PVC name is saved here + (backend-storage), its source PVC name is saved here. type: string sourcePod: type: string @@ -4171,7 +4134,7 @@ spec: type: string targetPersistentStatePVCName: description: If the VMI being migrated uses persistent features - (backend-storage), its target PVC name is saved here + (backend-storage), its target PVC name is saved here. type: string targetPod: description: The target pod that the VMI is moving to diff --git a/crds/embedded/virtualmachines.yaml b/crds/embedded/virtualmachines.yaml index a0bfe284f4..f8da8608f7 100644 --- a/crds/embedded/virtualmachines.yaml +++ b/crds/embedded/virtualmachines.yaml @@ -1896,12 +1896,11 @@ spec: properties: name: description: |- - Name is this DNS resolver option's name. - Required. + DNS resolver option name. + Required field. type: string value: - description: Value is this DNS resolver option's - value. + description: DNS resolver option value. type: string type: object type: array @@ -2221,12 +2220,12 @@ spec: type: integer cache: description: |- - Cache specifies which kvm disk cache mode should be used. - Supported values are: - none: Guest I/O not cached on the host, but may be kept in a disk cache. - writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. - writeback: Guest I/O cached on the host. - Defaults to none if the storage supports O_DIRECT, otherwise writethrough. + Specifies which KVM disk cache mode should be used. Supported values: + + - `none`: Guest I/O is not cached on the host, but may be kept in a disk cache. + - `writethrough`: Guest I/O is cached on the host but written through to the physical medium. This is the slowest mode but provides the most guarantees. + - `writeback`: Guest I/O is cached on the host. + Defaults to `none` if the storage supports O_DIRECT, otherwise `writethrough`. type: string cdrom: description: Attach a volume as a cdrom to the @@ -2355,26 +2354,22 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device - provisioned by device-plugins + description: Name of the device provisioned by device plugins. type: string name: - description: Name of the GPU device as exposed - by a device plugin + description: Name of the GPU device as exposed by a device plugin. type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string virtualGPUOptions: properties: @@ -2411,24 +2406,21 @@ spec: properties: claimName: description: |- - ClaimName needs to be provided from the list vmi.spec.resourceClaims[].name where this - device is allocated + Must be provided from `vmi.spec.resourceClaims[].name` where this + device is allocated. type: string deviceName: - description: DeviceName is the name of the device - provisioned by device-plugins + description: Name of the device provisioned by device plugins. type: string name: type: string requestName: description: |- - RequestName needs to be provided from resourceClaim.spec.devices.requests[].name where this - device is requested + Must be provided from `resourceClaim.spec.devices.requests[].name` where this + device is requested. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -2615,17 +2607,15 @@ spec: type: object state: description: |- - State represents the requested operational state of the interface. - The supported values are: - 'absent', expressing a request to remove the interface. - 'down', expressing a request to set the link down. - 'up', expressing a request to set the link up. - Empty value functions as 'up'. + Requested operational state of the interface. Supported values: + + - 'absent': Expresses a request to remove the interface. + - 'down': Expresses a request to set the link down. + - 'up': Expresses a request to set the link up. + An empty value functions as 'up'. type: string tag: - description: If specified, the virtual network - interface address and its tag will be provided - to the guest via config drive + description: If specified, the virtual network interface address and its tag will be provided to the guest via config drive. type: string required: - name @@ -2648,15 +2638,14 @@ spec: guest CPUs. type: boolean panicDevices: - description: PanicDevices provides additional crash - information when a guest crashes. + description: Provides additional crash information when a guest crashes. items: properties: model: description: |- - Model specifies what type of panic device is provided. - The panic model used when this attribute is missing depends on the hypervisor and guest arch. - One of: isa, hyperv, pvpanic. + Type of panic device to provide. + If this attribute is missing, the panic model used depends on the hypervisor and guest architecture. + Valid values: `isa`, `hyperv`, `pvpanic`. type: string type: object type: array @@ -2685,13 +2674,13 @@ spec: properties: enabled: description: |- - Enabled allows a user to explicitly disable the vTPM even when one is enabled by a preference referenced by the VirtualMachine - Defaults to True + Allows explicitly disabling the vTPM even when one is enabled by a preference referenced by the VirtualMachine. + Defaults to true. type: boolean persistent: description: |- - Persistent indicates the state of the TPM device should be kept accross reboots - Defaults to false + Indicates whether the state of the TPM device should be kept across reboots. + Defaults to false. type: boolean type: object useVirtioTransitional: @@ -2701,13 +2690,12 @@ spec: do not understand virtio_non_transitional (virtio 1.0). type: boolean video: - description: Video describes the video device configuration - for the vmi. + description: Video device configuration for the VMI. properties: type: description: |- - Type specifies the video device type (e.g., virtio, vga, bochs, ramfb). - If not specified, the default is architecture-dependent (VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64; virtio for Arm and s390x). + Video device type (e.g., virtio, vga, bochs, ramfb). + If not specified, the default is architecture-dependent: VGA for BIOS-based VMs, Bochs for EFI-based VMs on AMD64, virtio for Arm and s390x. type: string type: object watchdog: @@ -2715,12 +2703,11 @@ spec: which can be added to the vmi. properties: diag288: - description: diag288 watchdog device (specific - to s390x architecture). + description: diag288 watchdog device specific to s390x architecture. properties: action: description: |- - The action to take. Valid values are poweroff, reset, shutdown. + Action to take when the watchdog triggers. Valid values: poweroff, reset, shutdown. Defaults to reset. type: string type: object @@ -2996,12 +2983,12 @@ spec: properties: msdmNameRef: description: |- - Similar to SlicNameRef, another ACPI entry that is used in more recent Windows versions. - The above points to the spec of MSDM too. + Similar to `SlicNameRef`, this is another ACPI entry used in more recent Windows versions. + This field points to the MSDM specification as well. type: string slicNameRef: description: |- - SlicNameRef should match the volume name of a secret object. The data in the secret should + Should match the volume name of a secret object. The data in the secret should be a binary blob that follows the ACPI SLIC standard, see: https://learn.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653305(v=vs.85) type: string @@ -3089,17 +3076,15 @@ spec: description: IOThreads specifies the IOThreads options. properties: supplementalPoolThreadCount: - description: SupplementalPoolThreadCount specifies - how many iothreads are allocated for the supplementalPool - policy. + description: Number of IO threads allocated for the supplementalPool policy. format: int32 type: integer type: object ioThreadsPolicy: description: |- - Controls whether or not disks will share IOThreads. - Omitting IOThreadsPolicy disables use of IOThreads. - One of: shared, auto, supplementalPool + Controls whether disks share IOThreads. + Omitting this field disables the use of IOThreads. + Valid values: shared, auto, supplementalPool. type: string launchSecurity: description: Launch Security setting of the vmi. @@ -3557,55 +3542,47 @@ spec: type: object resourceClaims: description: |- - ResourceClaims define which ResourceClaims must be allocated - and reserved before the VMI, hence virt-launcher pod is allowed to start. The resources - will be made available to the domain which consumes them - by name. + Defines which ResourceClaims must be allocated and reserved before the VMI, + hence the `virt-launcher` pod is allowed to start. The resources will be made available to the domain + which consumes them by name. - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate in kubernetes - https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ - This field should only be configured if one of the feature-gates GPUsWithDRA or HostDevicesWithDRA is enabled. + This is an alpha field and requires enabling the `DynamicResourceAllocation` feature gate in Kubernetes. + See https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/ + This field should only be configured if one of the feature gates `GPUsWithDRA` or `HostDevicesWithDRA` is enabled. This feature is in alpha. items: description: |- - PodResourceClaim references exactly one ResourceClaim, either directly + References exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod. - It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Adds a name that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name. properties: name: description: |- - Name uniquely identifies this resource claim inside the pod. - This must be a DNS_LABEL. + Uniquely identifies this resource claim inside the pod. + This must be a `DNS_LABEL`. type: string resourceClaimName: description: |- - ResourceClaimName is the name of a ResourceClaim object in the same - namespace as this pod. + Name of a ResourceClaim object in the same namespace as this pod. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string resourceClaimTemplateName: description: |- - ResourceClaimTemplateName is the name of a ResourceClaimTemplate - object in the same namespace as this pod. + Name of a ResourceClaimTemplate object in the same namespace as this pod. - The template will be used to create a new ResourceClaim, which will - be bound to this pod. When this pod is deleted, the ResourceClaim - will also be deleted. The pod name and resource name, along with a - generated component, will be used to form a unique name for the - ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + The template will be used to create a new ResourceClaim, which will be bound to this pod. + When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, + along with a generated component, will be used to form a unique name for the ResourceClaim, + which will be recorded in `pod.status.resourceClaimStatuses`. - This field is immutable and no changes will be made to the - corresponding ResourceClaim by the control plane after creating the - ResourceClaim. + This field is immutable and no changes will be made to the corresponding ResourceClaim + by the control plane after creating the ResourceClaim. - Exactly one of ResourceClaimName and ResourceClaimTemplateName must - be set. + Exactly one of `ResourceClaimName` and `ResourceClaimTemplateName` must be set. type: string required: - name @@ -4036,8 +4013,7 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the - PVC in the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -4385,26 +4361,25 @@ spec: properties: controllerRevisionRef: description: |- - ControllerRef specifies the ControllerRevision storing a copy of the object captured - when it is first seen by the VirtualMachine controller + ControllerRevision storing a copy of the object captured + when it is first seen by the VirtualMachine controller. properties: name: - description: Name of the ControllerRevision + description: Name of ControllerRevision. type: string type: object inferFromVolume: - description: InferFromVolume lists the name of a volume that should - be used to infer or discover the resource + description: Lists the name of a volume that should + be used to infer or discover the resource. type: string inferFromVolumeFailurePolicy: - description: InferFromVolumeFailurePolicy controls what should - happen on failure when inferring the resource + description: Controls what happens on failure when inferring the resource. type: string kind: - description: Kind specifies the kind of resource + description: Kind of resource. type: string name: - description: Name is the name of resource + description: Name of resource. type: string type: object memoryDumpRequest: @@ -4414,31 +4389,27 @@ spec: nullable: true properties: claimName: - description: ClaimName is the name of the pvc that will contain - the memory dump + description: Name of the PVC that will contain + the memory dump. type: string endTimestamp: - description: EndTimestamp represents the time the memory dump - was completed + description: Time when the memory dump was completed. format: date-time type: string fileName: - description: FileName represents the name of the output file + description: Name of the output file. type: string message: - description: Message is a detailed message about failure of the - memory dump + description: Detailed message about failure of the memory dump. type: string phase: - description: Phase represents the memory dump phase + description: Memory dump phase. type: string remove: - description: Remove represents request of dissociating the memory - dump pvc + description: Request to dissociate the memory dump PVC. type: boolean startTimestamp: - description: StartTimestamp represents the time the memory dump - started + description: Time when the memory dump started. format: date-time type: string required: @@ -4457,26 +4428,25 @@ spec: properties: controllerRevisionRef: description: |- - ControllerRef specifies the ControllerRevision storing a copy of the object captured - when it is first seen by the VirtualMachine controller + Specifies the `ControllerRevision` storing a copy of the object captured + when it is first seen by the VirtualMachine controller. properties: name: - description: Name of the ControllerRevision + description: Name of ControllerRevision. type: string type: object inferFromVolume: - description: InferFromVolume lists the name of a volume that should - be used to infer or discover the resource + description: Lists the name of a volume that should + be used to infer or discover the resource. type: string inferFromVolumeFailurePolicy: - description: InferFromVolumeFailurePolicy controls what should - happen on failure when inferring the resource + description: Controls what happens on failure when inferring the resource. type: string kind: - description: Kind specifies the kind of resource + description: Kind of resource. type: string name: - description: Name is the name of resource + description: Name of resource. type: string type: object printableStatus: @@ -4594,11 +4564,11 @@ spec: type: integer cache: description: |- - Cache specifies which kvm disk cache mode should be used. - Supported values are: - none: Guest I/O not cached on the host, but may be kept in a disk cache. - writethrough: Guest I/O cached on the host but written through to the physical medium. Slowest but with most guarantees. - writeback: Guest I/O cached on the host. + Cache specifies which KVM disk cache mode should be used. Supported values: + + - `none`: Guest I/O is not cached on the host, but may be kept in a disk cache. + - `writethrough`: Guest I/O is cached on the host but written through to the physical medium. This is the slowest mode but provides the most guarantees. + - `writeback`: Guest I/O is cached on the host. Defaults to none if the storage supports O_DIRECT, otherwise writethrough. type: string cdrom: @@ -4752,8 +4722,7 @@ spec: volume can be hotplugged and hotunplugged. type: boolean name: - description: Name of both the DataVolume and the - PVC in the same namespace. + description: Name of both the DataVolume and the PVC in the same namespace. type: string required: - name @@ -4875,7 +4844,7 @@ spec: on the corresponding PVC status type: object claimName: - description: ClaimName is the name of the PVC + description: Name of the PVC. type: string filesystemOverhead: description: Percentage of filesystem's size to @@ -4925,7 +4894,7 @@ spec: on the corresponding PVC status type: object claimName: - description: ClaimName is the name of the PVC + description: Name of the PVC. type: string filesystemOverhead: description: Percentage of filesystem's size to From 7adbdc6497dbda2c1da9494600c0a90cd17b3edb Mon Sep 17 00:00:00 2001 From: Yaroslav Borbat Date: Thu, 18 Dec 2025 19:42:33 +0300 Subject: [PATCH 8/9] update kubevirt dep Signed-off-by: Yaroslav Borbat # Conflicts: # build/components/versions.yml --- build/components/versions.yml | 2 +- images/virt-artifact/werf.inc.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build/components/versions.yml b/build/components/versions.yml index d542b6d5ed..0df96ff257 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.6.2-v12n.0.dlopatin7 + 3p-kubevirt: v1.6.2-virtualization 3p-containerized-data-importer: v1.60.3-v12n.12 distribution: 2.8.3 package: diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 68ad38042c..4e972a4590 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,6 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src +fromCacheVersion: "000" # TODO: Delete me secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} From 0e059f47e643d8f51108d7432494c9a77ab5f91a Mon Sep 17 00:00:00 2001 From: Yaroslav Borbat Date: Fri, 19 Dec 2025 12:27:45 +0300 Subject: [PATCH 9/9] gen Signed-off-by: Yaroslav Borbat --- api/go.mod | 3 +-- api/go.sum | 6 ------ crds/virtualmachineclasses.yaml | 6 +++--- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/api/go.mod b/api/go.mod index a4b3951825..ab0a3f4f5f 100644 --- a/api/go.mod +++ b/api/go.mod @@ -17,7 +17,6 @@ require ( k8s.io/apiextensions-apiserver v0.33.3 k8s.io/apimachinery v0.33.3 k8s.io/client-go v0.33.3 - k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 kubevirt.io/api v1.6.2 sigs.k8s.io/controller-runtime v0.21.0 ) @@ -47,7 +46,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 // indirect github.com/openshift/custom-resource-status v1.1.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/spf13/cobra v1.9.1 // indirect @@ -71,6 +69,7 @@ require ( k8s.io/code-generator v0.33.3 // indirect k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect diff --git a/api/go.sum b/api/go.sum index 620d6a5a4a..af967a273e 100644 --- a/api/go.sum +++ b/api/go.sum @@ -208,8 +208,6 @@ github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxj github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 h1:t/CahSnpqY46sQR01SoS+Jt0jtjgmhgE6lFmRnO4q70= -github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= @@ -568,12 +566,8 @@ k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kubevirt.io/api v1.3.1 h1:MoTNo/zvDlZ44c2ocXLPln8XTaQOeUodiYbEKrTCqv4= -kubevirt.io/api v1.3.1/go.mod h1:tCn7VAZktEvymk490iPSMPCmKM9UjbbfH2OsFR/IOLU= kubevirt.io/api v1.6.2 h1:aoqZ4KsbOyDjLnuDw7H9wEgE/YTd/q5BBmYeQjJNizc= kubevirt.io/api v1.6.2/go.mod h1:p66fEy/g79x7VpgUwrkUgOoG2lYs5LQq37WM6JXMwj4= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= -kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 h1:KTb8wO1Lxj220DX7d2Rdo9xovvlyWWNo3AVm2ua+1nY= kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9/go.mod h1:SDJjLGhbPyayDqAqawcGmVNapBp0KodOQvhKPLVGCQU= kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= diff --git a/crds/virtualmachineclasses.yaml b/crds/virtualmachineclasses.yaml index 91390c4a4e..58caf23455 100644 --- a/crds/virtualmachineclasses.yaml +++ b/crds/virtualmachineclasses.yaml @@ -283,8 +283,8 @@ spec: type: array defaultCoreFraction: description: |- - Default `coreFraction` value for the VirtualMachineClass. - Used when creating a VM when `coreFraction` is not specified. + Default core fraction value for the VirtualMachineClass. + This value will be used when creating a VM without an explicitly specified coreFraction. maximum: 100 minimum: 1 type: integer @@ -783,7 +783,7 @@ spec: type: boolean type: array defaultCoreFraction: - description: Default `coreFraction` value for the VirtualMachineClass. + description: Default core fraction value for the VirtualMachineClass. type: string memory: description: Memory sizing policy.