Skip to content

tests/virtual_disk: build a non-empty .vmdk fixture (fixes target on HyperCore 9.8.x) - #378

Open
ddemlow wants to merge 1 commit into
mainfrom
fix/virtual-disk-vmdk-fixture-9.8.2
Open

tests/virtual_disk: build a non-empty .vmdk fixture (fixes target on HyperCore 9.8.x)#378
ddemlow wants to merge 1 commit into
mainfrom
fix/virtual-disk-vmdk-fixture-9.8.2

Conversation

@ddemlow

@ddemlow ddemlow commented Aug 14, 2026

Copy link
Copy Markdown
Member

What this fixes

The virtual_disk integration target currently fails on HyperCore 9.8.2.226476. The
Upload virtual disk file .vmdk task returns:

Unexpected response - 502 b'<html>\r\n<head><title>502 Bad Gateway</title></head>...

The cause is the fixture, not the module. The target builds its VMDK with:

qemu-img create -f vmdk xlab-ci-test-VD.vmdk 10M

which produces a 65 536-byte file with nothing allocated. Uploading that file is what 9.8.2 rejects.

The boundary is the file size, not the virtual size

A monolithicSparse VMDK's file grows in steps as virtual size increases, which makes this easy to
separate. Measured on 9.8.2.226476, one upload per row, record deleted between:

virtual size file bytes upload
100M 65 536 502
200M 65 536 502
300M 65 536 502
400M 65 536 502
500M 131 072 200
600M 131 072 200
800M 131 072 200
1G 196 608 200

Virtual size has no effect of its own — 100M and 400M behave identically, and the only difference
between 400M and 500M is that the file crosses 65 536 → 131 072 bytes. A VMDK whose file is 64 KiB
fails; 128 KiB and above succeeds.

It is also not the subformat: streamOptimized behaves the same way (fails at 64 KiB, passes above it).
Not emptiness as such either — a 1G all-zero image passes, because its file is 192 KiB.

It is new in 9.8.x

The same twelve images were run against 9.7.6.226153, which accepts all of them, including every
64 KiB one. Reproduced on two independent 9.8.2 clusters, one of them entirely on a local network with no
proxy or tunnel in the path, and reproduced with plain curl as well as through this collection — so it
is not a client-side or network artifact.

An issue has been filed with Scale Computing against the HyperCore product for the underlying 64 KiB
upload defect.
This PR is not a fix for that and does not try to be one — it only stops the test
depending on the one case that triggers it, so CI is not blocked while the product side is addressed.

The change

-      # Empty vmdk image seems to be OK
-      # But non-empty image with ext4 filesystem is a problem.
-      qemu-img create -f vmdk xlab-ci-test-VD.vmdk 10M
+      qemu-img create -f raw xlab-ci-test-VD-vmdk-src.raw 10M
+      dd if=/dev/urandom of=xlab-ci-test-VD-vmdk-src.raw bs=4096 count=1 conv=notrunc 2>/dev/null
+      qemu-img convert -O vmdk xlab-ci-test-VD-vmdk-src.raw xlab-ci-test-VD.vmdk

Writing 4 KiB into a scratch raw and converting it yields a 131 072-byte VMDK — over the boundary, still
a 10 MiB image, so every existing assertion is unchanged.

Two deliberate choices:

  • Not an ext4 image. The comment being removed warned that a non-empty ext4 filesystem inside a VMDK
    was itself a problem. That does not reproduce on any version tested here (see Verification), but a few
    KiB of data is all this needs, so there is no reason to reintroduce a filesystem and depend on that.
  • No mkfs.ext4 for the .vmdk. Only dd and qemu-img, so the VMDK half of the fixture works
    anywhere. (The .qcow2 still uses mkfs.ext4, unchanged — see the note below.)

The replaced comments are preserved as a longer explanation in the file, including the measured numbers,
so the next person to look at an upload failure here has the context.

Verification

The old fixture (65 536-byte file) and the new one (131 072 bytes), uploaded one at a time to eight
clusters spanning six release lines:

HyperCore old fixture (65 536 b) new fixture (131 072 b)
9.3.5.212852 200 200
9.4.17.215487 200 200
9.5.10.221215 200 200
9.6.31.226375 200 200
9.6.32.226689 200 200
9.7.6.226153 200 200
9.7.8.226633 200 200
9.8.2.226476 502 200

The new fixture works on every version tested; the old one fails only on 9.8.2. 9.7.8 passing places
the change squarely in 9.8.x rather than late 9.7.

9.3.5 and 9.4.17 are included because they are still in the current matrix, and because the comment this
PR removes was written in that era. Worth noting for reviewers: an ext4-populated vmdk also uploads
fine on both (200), so the removed warning — "non-empty image with ext4 filesystem is a problem" — does
not reproduce on the versions it was presumably written about. The fixture here avoids ext4 anyway, so
nothing depends on that result.

Module-level assertions were checked on all eight versions above — record.size == 10485760,
record.block_size == 1048576, and the record.keys() sort all hold.

The virtual_disk target was additionally run end to end and passes on 9.8.2.226476, 9.7.8.226633,
9.6.31.226375 and 9.5.10.221215
. On 9.8.2 there is a clean before/after: it failed on four consecutive
runs with the old fixture and passes with the new one. For the other three versions I only have
after-data end to end — the old fixture's behaviour on them is covered by the image table above, where
the 65 536-byte file uploads fine on every version except 9.8.2.

One observation, kept because it would otherwise look like something this PR caused: on the 9.5.10
cluster the target needed a retry (passed on 1 of 3 attempts). Both failures were on the .qcow2
upload — a step this PR does not touch — and neither is attributable to this change: the same populated
qcow2 uploaded to that cluster directly succeeded 6/6, and the fixture generation is byte-for-byte
deterministic across repeated runs. The .vmdk step passed on every attempt on every version.

One thing reviewers should know, not changed here

The .qcow2 fixture still depends on mkfs.ext4. Ansible's shell module does not set -e, so if
mkfs.ext4 is unavailable that step fails silently and the qcow2 is built from an unformatted raw —
196 616 bytes, effectively empty, which is the case the 9.4.21-era comment says HyperCore struggles with.
The target then tests something different from what it intends, with no error to say so.

CI runners have mkfs.ext4, so CI is unaffected. Left alone here to keep this PR to one thing. Happy to
follow up with either a guard that fails loudly when mkfs.ext4 is missing, or the same dd treatment
for the qcow2, whichever you prefer.



🤖 Generated with Claude Code

The target built its .vmdk with a bare `qemu-img create -f vmdk ... 10M`, which
produces a 65536-byte file with nothing allocated. Uploading that file fails with
HTTP 502 on HyperCore 9.8.2.226476, so the whole target fails there.

The boundary is the file size, not the virtual size: a monolithicSparse vmdk whose
file is 65536 bytes fails, and 131072 bytes or more succeeds. 1M/10M/100M/400M
virtual sizes all produce a 65536-byte file and all fail; 500M produces 131072
bytes and passes. 9.3.5, 9.4.17, 9.5.10, 9.6.31, 9.6.32, 9.7.6 and 9.7.8 all accept
the 65536-byte file, so this is new in 9.8.x.

An issue has been filed with Scale Computing against the HyperCore product for the
underlying defect. This commit does not work around it — it only stops the test
depending on the one case that triggers it.

Writing 4 KiB into a scratch raw and converting that to vmdk crosses the boundary.
Deliberately not an ext4 image: the previous comment warned that a non-empty ext4
filesystem inside a vmdk was itself a problem. That does not reproduce on any version
tested, but a few KiB of data is all this needs, so there is no reason to depend on
it — and this also keeps the .vmdk independent of mkfs.ext4 being installed.

Verification. The new fixture image uploads successfully on 9.3.5.212852,
9.4.17.215487, 9.5.10.221215, 9.6.31.226375, 9.6.32.226689, 9.7.6.226153,
9.7.8.226633 and 9.8.2.226476, with the module-level assertions holding on each
(`record.size == 10485760`, `record.block_size == 1048576`, and the `record.keys()`
sort). The target itself was run end to end on 9.8.2.226476, where it went from
failing on four consecutive runs to passing, and also passes on 9.7.8.226633,
9.6.31.226375 and 9.5.10.221215.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.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.

1 participant