From 1279cbf760e53ec15915ab34a89b7692f245e50f Mon Sep 17 00:00:00 2001 From: dsionov Date: Wed, 6 Nov 2024 03:23:53 +0200 Subject: [PATCH] design-proposal: persist-vmi-firmware-uuid This proposal introduces a mechanism to persist the firmware UUID of a Virtual Machine Instance (VMI) in KubeVirt. By storing the firmware UUID, we ensure that it remains consistent across VMI restarts, which is crucial for applications and services that rely on the UUID for identification or licensing purposes. Signed-off-by: Daniel Sionov --- design-proposals/persist-vmi-firmware-uuid.md | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 design-proposals/persist-vmi-firmware-uuid.md diff --git a/design-proposals/persist-vmi-firmware-uuid.md b/design-proposals/persist-vmi-firmware-uuid.md new file mode 100644 index 00000000..06f4a388 --- /dev/null +++ b/design-proposals/persist-vmi-firmware-uuid.md @@ -0,0 +1,181 @@ +# Overview +This proposal introduces a mechanism to persist the firmware UUID of a Virtual Machine Instance (VMI) in KubeVirt. +By storing the firmware UUID, we ensure that it remains consistent across VMI restarts. +which is crucial for applications and services that rely on the UUID for identification or licensing purposes. + +## Motivation +By definition, UUID must be a universally-unique identifier. +The current implementation for the automatically-computed Firmware UUID is not universally unique: +Two VMs with the same name get the same UUID, even if they reside in different namespaces or different clusters. +This proposal discusses how to fix this, while ensuring that existing VMs keep their current ID. + +## Goals +* Generate and persist universally-unique Firmware.UUID for new VMs +* Keep the Firmware.UUID of pre-existing VMs + +## Non Goals + + +## Definition of Users +End Users: Individuals or organizations running VMs and VMIs on KubeVirt who require consistent firmware UUIDs for their applications. + +## User Stories +As an end-user, I expect my VMI to maintain its identity across restarts. + +## Repos +Kubevirt/kubevirt + +# Design + +This design provides two approaches for implementing a persistent, universally unique firmware UUID for VMs: +a single-phase solution with immediate impact and a two-phased approach that gradually transitions to global uniqueness. + +## Single-Phase Solution for Persistent, Universally Unique UUIDs + +### 1. Upgrade-Specific Persistence of Firmware.UUID + +**Description:** Prior to upgrading KubeVirt, persist the `Firmware.UUID` of existing VMs in `vm.spec`. +After the upgrade, any VM without a `Firmware.UUID` in its spec will be considered new. +For these new VMs, the system defaults to using `vm.metadata.uid` as the firmware UUID if `vm.spec.template.spec.Firmware.UUID`is not defined. + +**Pros:** +- The upgrade-specific code can be safely removed after two or three releases. +- Simple logic post-upgrade, with a straightforward UUID assignment. +- Limited disturbance to GitOps workflows, affecting only pre-existing VMs with the current method. + +**Cons:** +- Requires additional code (likely in `virt-operator`) to handle the upgrade-specific persistence. +- Patching the spec of a running VM may trigger a "restart required" condition. + +This solution is effective for establishing UUID persistence and uniqueness within a single release, +allowing existing VMs to retain their UUID while adopting a globally unique identifier (`vm.metadata.uid`) for new VMs. + +## Two-Phased Solution for Persistent, Universally Unique UUIDs + +To ensure a truly persistent and universally unique firmware UUID for VMs, +the two-phased approach provides a gradual transition, balancing workload stability with a smooth progression toward global uniqueness. + +### Phase 1: Preserve Current Generation Method and Persist UUID + +In Phase 1, we aim to maintain workload stability by preserving the UUID generated with the current method. +This phase focuses on ensuring VMs retain their UUID across restarts without modifying the existing generation approach. +Below are potential solutions for this phase: + +1. **Persist UUID in the VM’s Spec Field** + **Description:** The UUID would be generated on the VM’s first boot and stored in the VM’s spec field. + + **Pros:** + - Straightforward implementation. + - Avoids adding a new API field, maintaining backward compatibility. + + **Cons:** + - This approach "abuses" the spec by storing data that does not represent the user's desired state. + - Could lead to cluttered and harder-to-read VM definitions. + +2. **Generate UUID via Webhook and Store in the Spec Field** + **Description:** If no UUID is specified by the user, a webhook generates a random UUID and assigns it to the VM’s spec field. + + **Pros:** + - Similar to the first option, avoiding a new API field and maintaining backward compatibility. + + **Cons:** + - Adds complexity by involving webhooks, which could slow down performance if many VMs are started simultaneously. + - May potentially bottleneck `virt-api`. + +3. **Add a Firmware UUID Field to VM Status** + **Description:** Store the generated UUID within the VM’s status. + + **Pros:** + - Keeps the spec clean. + + **Cons:** + - Could introduce a new API field, impacting long-term maintenance and adding potential API bloat. + +### Phase 2: Transition to Universally Unique UUID Generation + +In Phase 2, the approach for generating the firmware UUID is modified to ensure global uniqueness. +This transition could involve incorporating the VM name and namespace into the UUID, +or adopting a pseudo-random hash to guarantee uniqueness across clusters. +The solutions for this phase are outlined below: + +1. **Use Namespace + Name for UUID Generation** + **Description:** Generate the UUID by combining the VM name and namespace, ensuring uniqueness within the cluster. + + **Pros:** + - Simple and straightforward to implement. + - Avoids reliance on an external generator for randomness. + + **Cons:** + - Introduces a breaking change, as UUIDs for existing VMs may change unless preserved. + - Does not guarantee universal uniqueness across clusters. + +2. **Adopt Pseudo-Random Hashing for UUID Generation** + **Description:** Use a pseudo-random hash to generate a unique UUID that does not depend on specific names or namespaces. + + **Pros:** + - Ensures global uniqueness, even across clusters. + - Provides flexibility by avoiding dependence on VM names and namespaces. + + **Cons:** + - Introducing randomness may make the UUID less predictable, potentially impacting certain workloads. + - Requires careful validation to ensure the hash remains consistent for each VM across restarts. + +By addressing each phase separately, we can balance immediate workload stability +with a gradual transition to globally unique UUIDs, ensuring minimal disruption for end-users +while providing a scalable solution for UUID uniqueness. + + +## API Examples +**Example uuid persistence within VM Status** + +```yaml +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: mytestvm +status: + conditions: + - lastProbeTime: "2024-11-06T01:12:29Z" + lastTransitionTime: "2024-11-06T01:12:29Z" + message: Guest VM is not reported as running + reason: GuestNotRunning + status: "False" + type: Ready + created: true + runStrategy: Once + firmwareUUID: "123e4567-e89b-12d3-a456-426614174000" +``` + +or persist via status condition + +```yaml +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: mytestvm +status: + conditions: + - type: FirmwareUUIDPersisted + status: "123e4567-e89b-12d3-a456-426614174000" + reason: UUIDGenerated + message: "Firmware UUID has been generated and persisted" + lastTransitionTime: "2024-11-06T01:12:29Z" +``` + + +## Scalability +The proposed changes have no anticipated impact on scalability capabilities of the KubeVirt framework + +## Update/Rollback Compatibility +should not affect updates / rollbacks. + +## Functional Testing Approach +Verify that a newly created VMI has a unique firmware UUID assigned and that this UUID persists across VMI restarts. +Validate that the selected persistence mechanism (spec field, status field, or condition) stores the UUID. +Include unit tests for any logic introduced in controllers to ensure the UUID is generated and persisted correctly. + +# Implementation Phases +- Based on the selected design, either introduce a new field or utilize an existing one +(such as in spec, status, or conditions) to store the firmware UUID. +- Update controller logic to check for and persist the UUID, ensuring it is generated only once per VM. +- Testing: add unit and functional tests