Skip to content

test(e2e): migrate the blockdevice suite to the custom e2e-br image#2633

Open
Isteb4k wants to merge 81 commits into
mainfrom
e2e/virtual-disk-creation-custom-image
Open

test(e2e): migrate the blockdevice suite to the custom e2e-br image#2633
Isteb4k wants to merge 81 commits into
mainfrom
e2e/virtual-disk-creation-custom-image

Conversation

@Isteb4k

@Isteb4k Isteb4k commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Description

Move the whole blockdevice e2e suite from the ~350 MiB Alpine image to the
minimal from-scratch e2e-br image (~35 MiB), and fix what that surfaced:

  • All blockdevice data sources use the custom image (HTTP/Upload → qcow2 on
    Selectel, registry → ttl.sh container-disk, VI/CVI → precreated
    v12n-e2e-custom-bios); ISO tests use a custom EFI custom.iso.
  • Guest device lookup reads the SCSI serial from the sysfs VPD — the image runs
    no udev, so lsblk SERIAL / by-id are empty; SSH logs in as root, no sudo.
  • Resource waits go through observers, not Eventually (new sig-storage SIG
    label via SIGDescribe; new vmbda observer, vd BeResized, and a typed
    Project observer with BeDeployed replacing the generic UntilObjectState).
  • Controller fix: ProtectionService.RemoveProtection re-reads a fresh copy and
    patches finalizers under an optimistic lock with retry-on-conflict, so it no
    longer resurrects a finalizer on a terminating PVC (a 422 that errored and hung
    VM deletion). The two e2e log filters that masked this error are dropped.
  • Failure debug bundle for guest boot hangs: VNC screenshot capture now retries
    and leaves a *_screen_error.log breadcrumb on persistent failure, plus new
    serial-console capture (vm_<name>_serial.log) showing kernel/init output.

Two suites are gated off, both pending fixes outside this PR:

  • DataExports is skipped off-cluster (publish-mode export bug in the
    storage-volume-data-manager module — origin Ingress looked up in
    d8-user-authn instead of kube-system).
  • The entire VirtualDiskSnapshots suite is skipped: the vdsnapshot controller
    races the async freeze/unfreeze lifecycle (CanUnfreezeWithVirtualDiskSnapshot
    ignores Pending siblings and reads from a lagging cache, so late concurrent
    snapshots fail as "not consistent … has not been frozen"). TODO to un-skip
    once the controller is fixed.

VirtualDiskProvisioning no longer skips on NFS — VirtualImages on PVC now work
on filesystem storage classes, not only block.

New internal/object symbols are additive; other suites keep the Alpine image.

Why do we need it, and what problem does it solve?

e2e-br is ~10× smaller than the Alpine image the suite pulls today. This
migrates the blockdevice group to it and fixes the guest/observer/controller
issues that only appear on a truly minimal (no-udev, no-cloud-init) image.

What is the expected result?

The sig-storage (blockdevice) group passes on the custom image: disks
provision from every source (including on NFS), consumer VMs reach Running +
AgentReady, and resize works. DataExports runs on a cluster node / in CI;
VirtualDiskSnapshots is skipped pending the controller freeze/unfreeze fix.
Other suites are unaffected.

Checklist

  • The code is covered by unit tests.
  • e2e tests passed.
  • Documentation updated according to the changes.
  • Changes were tested in the Kubernetes cluster manually.

Changelog entries

section: test
type: chore
summary: Migrate the blockdevice e2e suite to the minimal custom e2e-br image.
impact_level: low

Isteb4k and others added 22 commits July 7, 2026 13:46
Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Changelog v1.9.3

Signed-off-by: deckhouse-BOaTswain <89150800+deckhouse-boatswain@users.noreply.github.com>
Co-authored-by: universal-itengineer <universal-itengineer@users.noreply.github.com>
Signed-off-by: Valeriy Khorunzhin <valeriy.khorunzhin@flant.com>
During a restore the VM is stopped inside the maintenance window: its KVVMI and then the KVVM itself are deleted. Bringing the VM back up afterwards relied on an implicit side effect — the recreated KVVM getting RunStrategy=Always at creation time. That path is racy and only covers the always-on policies.

---------

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
)

Signed-off-by: Maksim Fedotov <maksim.fedotov@flant.com>
Signed-off-by: Maksim Fedotov <maksim.fedotov@flant.com>
Add validation to getIPerfClientReport verifying that the iperf client session spans the virtual machine migration: start time before migration start, end time after migration end, and no more than one zero-byte interval during the process.

Signed-off-by: Dmitry Prytkov <dmitry.prytkov@flant.com>
…refix (#2594)

The d8 v ansible-inventory command read host variables from the bare
provisioning.virtualization.deckhouse.io/ prefix, while the
virtualization-provisioner module reads them from the separate
vars.provisioning.virtualization.deckhouse.io/ prefix. The same VM
annotations produced different inventories depending on the tool.

Read host variables from the vars. prefix to match the module. Groups
still come from provisioning.virtualization.deckhouse.io/groups. Update
the command help, usage examples and the ansible-inventory FAQ.

Signed-off-by: Pavel Tishkov <pavel.tishkov@flant.com>
…d manually (#2596)

fix(vm): fix VM stuck until the child KVVMI in Failed phase is deleted manually

Signed-off-by: Yaroslav Borbat <yaroslav.borbat@flant.com>
Virtualization has no primitive to manage a group of identical virtual machines whose count changes over time. Every "I need N identical VMs and the number varies" scenario — CI runner fleets, VDI desktop pools — has to be solved with orchestration outside the platform: users write their own controllers/scripts to create and delete VirtualMachines, watch their number, recreate lost ones and clean up their disks. This duplicates logic and is error-prone around races and node failures.

This PR introduces VirtualMachinePool (paid editions only, EE/SE+): a namespaced resource that declaratively keeps a requested number of identical VMs and integrates with kubectl scale, HPA and KEDA through the standard scale subresource. Its template is an ordinary VirtualMachineSpec, so a replica is no different from a manually created VM.

The feature is complete and covers:

Replica management — keeps the requested number of identical VMs, replaces lost ones, and reports state in status (replicas, readyReplicas, selector, conditions). It is cache-lag-safe (ReplicaSet-style expectations), so a lagging informer cache cannot double-create replicas.
Scale-down policy — NewestFirst / OldestFirst choose which replica leaves on anonymous scale-down via scale; Explicit forbids anonymous shrink through a webhook, so for "busy" workloads (CI runners, VDI) replicas can only be removed by address.
Addressed removal — the scaleDownWith subresource deletes named replicas and shrinks the pool by that count, instead of letting the controller pick victims.
In-place template propagation — editing the template rolls the change out to existing replicas; disruptive changes wait for a restart and are surfaced via status.restartPendingReplicas.
Reusable disks — per-replica disks are described in virtualDiskTemplates with a reclaim policy: Delete disks belong to the VM and are removed with it; Retain disks belong to the pool, outlive the replica and are reused on the next scale-up, with an optional warm buffer (keep) and TTL garbage-collection.
The resource is available only in paid editions, gated behind the VirtualMachinePool module feature gate (default off, locked off in CE). The API/CRD installs in every edition, but the controller self-gates on the feature gate, so the resource does nothing in CE.

---------

Signed-off-by: Pavel Tishkov <pavel.tishkov@flant.com>
Signed-off-by: Vladislav Panfilov <vladislav.panfilov@flant.com>
Co-authored-by: Vladislav Panfilov <vladislav.panfilov@flant.com>
…ate (#2621)

The VirtualMachinePool feature gate was an opt-in placeholder. As the feature
has not been released yet, drop the gate before release so the resource is
available in EE/SE+ out of the box and stays unavailable in CE — the same model
as VolumeMigration/TargetMigration. Nothing to migrate: the gate never shipped.

- gate becomes locked-on in EE/SE+, locked-off in CE (no user opt-in)
- dropped from the user-facing featureGates enum
- pool webhooks gated by edition in helm instead of the feature-gate list

Controller/webhooks keep self-gating on the now-locked gate.

Signed-off-by: Pavel Tishkov <pavel.tishkov@flant.com>
Adds:

- liveMigration.systemNetworkName ModuleConfig field. When set, VM live-migration traffic is routed over the per-node interfaces of a SystemNetwork CR from the SDN instead of the default node network.
- migrationiface controller resolves the per-node kernel interface name and writes it onto each Node as the annotation virtualization.deckhouse.io/migration-iface. virt-handler reads that annotation at startup and binds its migration proxy to the SystemNetwork's per-node IP.
- ModuleConfig validator to check if SystemNetwork added to liveMigration.systemNetworkName exists.
- New reason for VMOP if migration network is unavailable on nodes.

---------

Signed-off-by: Daniil Loktev <lokt.daniil@gmail.com>
Signed-off-by: Daniil Loktev <70405899+loktev-d@users.noreply.github.com>
Signed-off-by: Vladislav Panfilov <97229646+prismagod@users.noreply.github.com>
Co-authored-by: Vladislav Panfilov <97229646+prismagod@users.noreply.github.com>
Description
Log in to the private RU registry in the release channels workflow and check module versions against registry.deckhouse.ru/deckhouse.

Why do we need it, and what problem does it solve?
Release channel checks need access to artifacts in the RU registry. This keeps the workflow and version check pointed at the registry that contains the expected release artifacts.

---------

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…lose gaps (#2602)

Sizing policy validation errors were confusing and, in some cases, missing. When a VirtualMachineClass sets per-core memory limits, the error reported the allowed values per CPU core, while users configure the total memory — so the suggested numbers matched nothing they could actually set. Messages now report the total memory to set for the current number of cores, name the field to change, and combine multiple violations into a single readable list.

This also fixes cases where the policy was silently not enforced: the CPU cores step was never validated, and a memory / per-core minimum was ignored when no maximum was set.

Signed-off-by: Pavel Tishkov <pavel.tishkov@flant.com>
* docs: add VM launcher update notes to release notes

Signed-off-by: Vladislav Panfilov <vladislav.panfilov@flant.com>
Description
Removes CDI (Containerized Data Importer) from the platform. Disk and image provisioning no longer goes through CDI DataVolumes — the module now owns the whole import pipeline:

The VD/VI controllers create and track importer/uploader pods and target PVCs directly (new source/step pipeline instead of the DataVolume path).
A new PVC populator controller populates target PVCs from DVCR; host-assigned PVC cloning uses nbdcopy; the clone strategy (snapshot vs host-assigned) is picked from the StorageProfile, cross-CSI PVC-to-PVC cloning is forbidden.
The CDI importer sources are slimmed down into a pvc-importer image; import progress is streamed live from the target pod into the resource status.
CDI deployments (cdi-operator, cdi-apiserver, cdi-controller, cdi-cloner) and their templates/RBAC are removed; a module hook cleans up CDI resources on upgrade while keeping the CDI config CRD for safe rollback to main.
e2e: expanded block-device coverage with progress/quota observers, WFFC and cross-CSI scenarios.
Bugs fixed along the way
Progress & phases

Import progress could jump backwards after an importer pod restart (metric reset to 0); it is now monotonic (c2a61a4).
An optimistic "0%" surfaced as an intermediate Pending 0% status; Pending now reports no progress and the Pending→Provisioning transition is atomic (d122212).
Progress flip-flopped between 50%/50.0%; percent formatting is now consistent (00b93a0).
VirtualImage-on-PVC never streamed intermediate progress (hardcoded 0%→50%→100%) and under-reported the produced image size, breaking downstream PVC sizing; both now come from the importer pod (680608b).
A busy importer /metrics endpoint could freeze Status.Progress for the whole scrape budget (d122212).
Import pipeline

Interrupted PVC imports were not resumed for already-created targets (b95b230).
Importer pods for VI/CVI sourced from a VI-on-PVC always mounted the source as a block device, failing with FailedMount on volumeMode: Filesystem PVCs (b79920c).
VirtualImage PVC auto-sizing tripped a false "insufficient size" check (7edb744); status.format was copied from source metadata instead of the actual PVC storage type (0fa1bcf).
VirtualImage WFFC imports hung in the populator flow (0fb3661); smart-clone image PVCs were never bound (8cc0139).
Clone snapshots set a VolumeSnapshotClassName picked by provisioner match, which the d8-snapshot-controller webhook could reject (d59b1e2); replicated PVCs now use the snapshot clone strategy (c2f69e1).
pvc-importer inherited generic provisioning pod limits, throttling imports ~30% and risking OOMKill on huge images; limits raised to CDI parity (b50d7b2).
Importer/uploader/bounder pods are labeled to be excluded from project resource quotas (d122212, and quota guards in 9b7fc55).
A create rejection in a terminating namespace failed the reconcile instead of being surfaced on the Ready condition (c2a61a4).
Migrations & VMOP

The inbound migration limiter leaked slots of VMIs deleted mid-migration, eventually freezing all migrations cluster-wide (43e4f3c).
Affinity changes of VMs with local (RWO) disks never triggered a placement migration: the handler required live-migratability and ignored StorageLiveMigratable (67c29ba).
The workload updater kept creating evict VMOPs that the webhook was guaranteed to deny, flooding controller logs (f6b0ac0).
Why do we need it, and what problem does it solve?
CDI was a heavyweight third-party dependency (4 deployments, its own CRDs and RBAC) used only as a PVC provisioning backend. Owning the import pipeline removes the DataVolume indirection, gives accurate live import progress, allows to fix bugs directly, and cuts the CVE/maintenance surface of the vendored CDI codebase.

What is the expected result?
Creating VirtualDisks/VirtualImages from all sources (HTTP, containerRegistry, ObjectRef, upload, blank) works as before without any CDI components in the cluster; import progress is reported in the resource status. Upgrading from main cleans up CDI resources automatically; rollback to main remains safe.

---------

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Bump the size of the VirtualDisk restored from a VirtualImage in the VirtualImageCreation e2e suite from 400Mi to 450Mi. The change is in the shared runVirtualMachineFromImageDisk helper (test/e2e/blockdevice/virtual_image_creation.go), so it covers every context that boots a VM from a restored image disk (from a VirtualDisk, from a VirtualDiskSnapshot, from a VirtualImage on DVCR/PVC).

---

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Integrates the new bpfbridge network binding plugin (kubevirt side: deckhouse/3p-kubevirt#99) into the virtualization module and switches VM network interfaces to it, replacing the classic tap + veth + Linux-bridge datapath used for VM networks.

Signed-off-by: Dmitry Lopatin <dmitry.lopatin@flant.com>
Signed-off-by: Maksim Garmonov <maksim.garmonov@flant.com>
Signed-off-by: suselz <suselz@mail.ru>
Developers debugging the module with Delve had a broken helper. The dlv build/push flow shipped a single hardcoded kubectl patch snippet that assumed every component (virtualization-controller, virtualization-api, virtualization-audit) has the same sidecars (proxy, kube-rbac-proxy). Only the controller actually has them, so applying the printed patch to the api or audit deployment failed — it referenced containers that don't exist there.


---------

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
…stuck uploads (#2610)

Uploading an image or disk (a VirtualImage, ClusterVirtualImage, or VirtualDisk with an Upload data source) could hang forever in Pending with an empty status and no upload URL, so the image simply could not be uploaded.

It happened when the shared upload host started serving an invalid TLS certificate — for example after another, broken upload resource left the host serving a default self-signed certificate. In that state every upload on the cluster was blocked, not just the broken one, and recovery required manually finding and deleting the offending resource.

The controller now restores the upload host certificate on its own during reconcile, so affected uploads recover automatically, and a not-yet-ready upload endpoint no longer leaves the resource with an empty status.

This PR also restores a disk-specific regression: a recent refactor of the VirtualDisk upload flow dropped the upload-host self-healing for disks, so after the upload host changed (for example when publicDomainTemplate was updated) an in-flight disk upload could get stuck. The self-healing is reinstated for disks, matching how images already behave.



Signed-off-by: Pavel Tishkov <pavel.tishkov@flant.com>
Point every VirtualDiskCreation data source (HTTP, Upload, registry,
VirtualImage, ClusterVirtualImage) at the minimal custom e2e-br image:
a Selectel qcow2 for HTTP/Upload and a ttl.sh container-disk for the
registry source. Drop the cloud-init provisioning for the test's VM —
it only needs the VM as a disk consumer with a live guest agent and
never logs in, so no user has to be created.

New object symbols (ImageURLCustomBIOS, ImageURLCustomContainer,
PrecreatedCVICustomBIOS) are additive; existing constants are left
untouched, so other e2e tests keep their behavior.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
@Isteb4k Isteb4k added this to the v1.10.0 milestone Jul 10, 2026
loktev-d and others added 6 commits July 10, 2026 16:07
New conntrack sync metrics: d8_virtualization_virtualmachine__conntrack_sync_exports_total, d8_virtualization_virtualmachine__conntrack_sync_exported_bytes_total, d8_virtualization_virtualmachine__conntrack_sync_imports_total, d8_virtualization_virtualmachine__conntrack_sync_hook_waits_total

---------

Signed-off-by: Daniil Loktev <lokt.daniil@gmail.com>
Signed-off-by: Daniil Loktev <70405899+loktev-d@users.noreply.github.com>
Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
* chore(api): integrate crd-enricher into CRD codegen and add CRD examples

Signed-off-by: Vladislav Panfilov <vladislav.panfilov@flant.com>
…#2624)

Description
Virtual machines created without paravirtualization keep all their disks and CD-ROMs on the SATA bus forever, even after enableParavirtualization is turned on and the VM is restarted. The recorded bus of an existing device always took priority over the bus implied by the paravirtualization setting.

Now, when the paravirtualization mode changes, devices move to the bus of the new mode on the restart this change already requires. Devices hot-plugged on a non-default bus (for example USB) keep their bus as before.

---------

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
… resources with d8- (#2632)

* fix(observability): default audit TLS cert paths to certificates dir

The mounted secret is at /etc/virtualization-audit/certificates (plural),
but the flag defaults pointed at /etc/virtualization-audit/certificate,
so the server failed to load TLS when started without explicit flags.

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>

* refactor(observability): prefix audit log-shipper resources with d8- and drop to-

Rename the ClusterLoggingConfig and ClusterLogDestination objects created for
audit shipping: to-virtualization-audit -> d8-virtualization-audit and
virtualization-audit-* -> d8-virtualization-audit-*, aligning with the d8-
naming convention for module-owned cluster-scoped resources.

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>

---------

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
The custom e2e-br image is ~35 MiB and grows its root filesystem to the
disk on first boot, so the 400Mi disks are oversized. Use a 50Mi
vdCreationImageSize for the image-backed VirtualDisks instead.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
danilrwx and others added 7 commits July 14, 2026 13:41
fix(dra): load compressed usbip kernel modules (xz, gzip)

Pre-installed usbip modules may ship compressed as .ko.xz or .ko.gz
depending on the host distribution, not only .ko or .ko.zst. Resolve all
kernel-supported compression suffixes (zstd, xz, gzip) in the module path
fallback and decompress accordingly before finit_module.

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
Virtual machines with local (RWO) disks could get stuck unable to migrate whenever they had a pending restart. The "restart required to apply configuration" state can appear on its own after a module upgrade, without any user change; while it was set, volume migration of the VM's local disks was skipped entirely. Migrations initiated by evacuation (node drain), firmware updates and other workload updates then hung indefinitely — target disks were never prepared and the migration stayed Pending.

---------

Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
ProtectionService.RemoveProtection now re-reads a fresh copy and patches
under an optimistic lock with retry-on-conflict, so it no longer emits the
422 "no new finalizers can be added if the object is being deleted" error
when releasing the pvc-protection / vd-protection finalizers on a
terminating PersistentVolumeClaim. Drop the two log filters that masked it.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
…orts

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
…c state helper

Project (deckhouse.io/v1alpha2) is not served by VirtClient, so tests waited
for it to reach "Deployed" via the generic unstructured util.UntilObjectState
helper. Add a Project-specialized observer that watches through the dynamic
client and decodes events into a typed Project (mirroring the storageprofile
observer), with a BeDeployed() predicate. Extend the hand-rolled Project type
with a partial Status (State) and switch the three call sites to the observer.
Remove the now-unused UntilObjectState helper.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
@Isteb4k Isteb4k requested a review from hardcoretime July 14, 2026 13:24
Isteb4k added 4 commits July 14, 2026 15:57
The vdsnapshot controller can unfreeze the VM filesystem before all
concurrent RequiredConsistency snapshots are captured, so the late ones
fail with "virtual disk snapshot is not consistent ... has not been
frozen". The root cause is in CanUnfreezeWithVirtualDiskSnapshot (ignores
Pending siblings, reads them from a lagging cache), not in the test. Skip
with a TODO describing the controller bug until it is fixed.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
The suite is flaky beyond the concurrent case: single-disk/running-VM
cases also trip on the vdsnapshot controller's racy freeze/unfreeze
lifecycle (checkVMUnfrozen races the async thaw; CanUnfreeze can unfreeze
before all snapshots are captured). Skip the whole suite via a BeforeEach
Skip with a TODO covering both root causes until the controller is fixed.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
VirtualImages on PVC now work with filesystem storage classes, not only
block, so the NFS skip guard in the BeforeEach is obsolete. Drop it (and
the now-unused storage-class lookup) so the suite runs on NFS too.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
… hangs

When a guest boots but the agent never becomes ready, the VNC screenshot
is the key artifact — but capture failed silently, so a wedged guest left
no screenshot at all. Make screenshot capture retry and, on persistent
failure, write a *_screen_error.log breadcrumb explaining the miss.

Add serial console capture (vm_<name>_serial.log): the VNC frame only
shows the final screen, whereas the ttyS0 console shows the kernel/init
output that pins where boot wedged. Both run at the framework dump level,
so every failing blockdevice spec collects them before namespace cleanup.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
@Isteb4k Isteb4k marked this pull request as ready for review July 14, 2026 14:56
Isteb4k added 7 commits July 14, 2026 17:09
data_exports builds the VM via a bare vmbuilder.New, which leaves
Spec.Provisioning nil by default, so the explicit WithProvisioning(nil)
was a no-op. (The NewMinimalVM call sites keep it — there it clears the
AlpineCloudInit default.)

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Several blockdevice disks were built with no StorageClass, so they fell
back to the module default (the cluster-default SC) regardless of a
STORAGE_CLASS_NAME override. The expected-phase helpers derive their
answer from config.DefaultStorageClass, so on an Immediate override the
disk could land on the WaitForFirstConsumer cluster default and diverge
from what the test waits for.

This surfaced in DataExports: createUploadDisk built the restored upload
VDs with no SC, and waitDiskInExpectedPhase waited for Ready while the
disk parked at WaitForFirstConsumer, timing out after 5m.

Pin WithStorageClass(defaultStorageClass()) (or pass it to NewBlankVD /
WithPersistentVolumeClaim) on every disk so they use the SC the test
reasons about: data_exports (root/data/upload disks), virtual_disk_
provisioning, vd_snapshots and virtual_disk_resizing. Also unify the
vd_snapshots no-consumer disk onto defaultStorageClass() instead of the
ad-hoc ptr.To(cfg...Name).

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
On WaitForFirstConsumer storage classes the Attached wait covers the whole
volume provisioning: the PVC binds only after the hotplug attachment pod
arrives, and a single csi-nfs CreateVolume under parallel suite load was
observed to take 84s — more than the whole MiddleTimeout. Raise only the
VMBDA BeAttached waits (and the post-resize recheck) to LongTimeout.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
On csi-nfs a VolumeSnapshot is a physical tar.gz copy of the volume taken
over internal NFS mounts, not an instant metadata operation: under parallel
suite load the mount setup alone was observed to take ~23s and the archive
copy ~31s, so ShortTimeout/MiddleTimeout waits for VirtualDiskSnapshot
readiness time out on an otherwise healthy path. Raise only these waits to
LongTimeout; disk-creation waits already use it.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
The BeReady predicate reported a bare "entered Failed phase", hiding the
reason the vdsnapshot controller left on the VirtualDiskSnapshotReady
condition (e.g. the latched VolumeSnapshot error). Include the condition
reason and message in the predicate error.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
The custom e2e-br image is 35Mi unpacked and the guest has no growpart, so
anything above ~50Mi is dead weight: importers, csi-nfs snapshots and
restores all stream the full logical size of disk.img, zeros included.
Root disks at 400Mi/450Mi/2Gi and blanks at 100Mi/51Mi/4Gi made every
import, snapshot and clone move ~8x more data than needed, which is what
kept tripping waits on NFS under parallel load.

Reuse the existing vdCreationImageSize constant (50Mi) for every root and
blank disk in the suite; disks that relied on auto-sizing get an explicit
size too. The resizing test grows disks by a relative +100Mi, so the
smaller base does not affect it.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
getImageInfo reads the first 10 MiB of the source to probe the format and
prepends that buffer to the remaining stream, so the combined reader always
starts at byte 0. getImageInfoStandard nevertheless wrote the header buffer
to the sampling temp file separately and then copied from the combined
reader, so the first 10 MiB ended up both duplicated in the sample and
counted twice in the byte-counted VirtualSize of raw sources.

As a result every VirtualImage created from a block-device source (a
VirtualDisk or VirtualDiskSnapshot) reported unpackedSize exactly 10 MiB
larger than the actual data, and disks cloned from such images failed size
validation ("the specified pvc size is insufficient") unless oversized.

Sample the temp file straight from the combined reader and count each byte
once. Covered by a unit test that pins VirtualSize for raw sources smaller
than the probed header, larger than it, and larger than the sampled window.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
@Isteb4k Isteb4k requested a review from diafour as a code owner July 14, 2026 22:20
Isteb4k added 3 commits July 15, 2026 00:29
Set both blockdevice size constants to 52Mi: on LINSTOR the actual block
device behind a 50Mi claim is ~52Mi (extent rounding minus DRBD metadata),
so 52Mi keeps the requested size aligned with what block storage actually
provisions for the smallest image-backed disks.

The resizing test now doubles the current disk size instead of adding a
fixed increment, so the growth stays proportional to whatever base size the
suite uses.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Disks created from a VirtualImage or a VirtualDiskSnapshot no longer pin a
size: on block storage the actual device behind a claim is always larger
than requested (extent rounding, DRBD metadata), so an image or snapshot
taken from it never fits back into a disk of the same nominal size — any
hard-coded value breaks on some storage class. Let the controller derive
the size from the source instead.

Source disks provisioned from base images (CVI/HTTP/container-image/upload)
and blank disks keep an explicit size, back at 50Mi.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
sds-local-volume rounds every LV up to the 4MiB LVM extent but reports the
requested size as the PVC capacity, and only snapshots of restore-created
volumes report the rounded size as restoreSize. A VirtualImage on PVC is
restore-created, so its clone snapshot restores to 52Mi while every size
the controller can derive from says 50Mi — the clone PVC of a disk created
from such an image never provisions.

Give the three VD-from-VI-on-PVC sites an explicit 52Mi with a TODO to drop
the override once the sds-local-volume bug is fixed. Disks from a VI on
DVCR and from a VirtualDiskSnapshot keep the derived size: first-generation
snapshots restore at the nominal size.

Also make the provisioning "from a VirtualImage on a PVC" spec actually
use a VI on PVC: NewGeneratedVIFromCVI hardcodes ContainerRegistry storage,
so the spec was silently testing the DVCR path.

Signed-off-by: Dmitry Rakitin <dmitry.rakitin@flant.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.