Repository navigation
fix(kubevirt): a failed ISO import must not start the VM, read as inserted, or block a re-insert - #39
itayherzberg wants to merge 2 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @itayherzberg. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
…main Signed-off-by: itayherzberg <itayherzberg@gmail.com>
…ert/power-on race and follow-ups) (fork-only) Signed-off-by: itayherzberg <itayherzberg@gmail.com>
| // marked as failed. All three go in one patch: the VM watcher runs the | ||
| // deferred power command as soon as it sees the label gone, and a VM started | ||
| // on an empty CD-ROM is what the deferral exists to prevent. | ||
| func (c *Client) markImportFailed(vm *kubevirtv1.VirtualMachine, deviceName, podName string) error { |
There was a problem hiding this comment.
So the workflow cancels the run command and the user must retrigger both import and VM start?
There was a problem hiding this comment.
Yes. When the import pod fails, the deferred power command is removed together with the importing label, so the client has to send InsertMedia again and then the power command again.
I dropped it instead of keeping it because a power-on left on the VM would run after whatever insert succeeds next, which can be much later and for a different image. That seemed worse than asking for the power command again.
What the client sees after the failure: PowerState stays Off, Inserted is false, and the same InsertMedia is answered 202 and imports again. The insert task is no help here: it already reads Completed, because the job ends once the import pod is created.
I expect Ironic to time out waiting for the power state and retry the step, but I have not run this against a BareMetalHost.
If you prefer to keep the deferred command on the VM until a later insert succeeds, so that only the insert has to be repeated, I can change it. It is a small change in markImportFailed.
|
And I merged some of the other patches and not where is a merge conflict that needs to be resolved. |
…nserted When the import helper pod failed, the importing label was removed and nothing else changed: the VM watcher then ran the deferred power-on and the VM booted from a CD-ROM whose PVC holds no image, GET VirtualMedia reported Inserted true because the PVC is bound, and a repeated InsertMedia with the same image was answered as already inserted. A failed import now removes the importing label, withdraws the deferred power command and marks the device with import-failed.redfish/<device> in one patch, so the watcher never sees the label gone with the power command still pending. The marker makes the device read as not inserted and lets the next InsertMedia import again; the insert and the eject clear it. A device whose import is still running also reads as not inserted. Signed-off-by: itayherzberg <itayherzberg@gmail.com>
3b57680 to
5e093c2
Compare
…failed import After a failed import the next InsertMedia is accepted and marks the VM as importing before its job replaces the PVC and clears the failed marker. CheckInsertedMedia looked at the marker first, so a request for another image in that window was answered as still in progress instead of as a conflict. The marker now only applies while no import is recorded for the device. Signed-off-by: itayherzberg <itayherzberg@gmail.com>
|
Rebased onto I also added a small second commit: with #36 in the base, a request for a different image sent while a re-insert after a failed import was still pending was answered "in progress" instead of |
Problem
When the ISO import helper pod fails (the image URL returns 404, the download is cut, the pod cannot write the volume), the bridge removes the importing label and does nothing else. Three things follow:
BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00001" ... Not Found).GET .../VirtualMedia/CdanswersInserted: true, because the check is "the PVC is bound and has capacity". The same is true while the import is still running.InsertMediawith the same image is answered204("already inserted") because the PVC is attached and the stored URL matches, so Ironic's retry does not import again.The host is then "powered on, media inserted" from Redfish's point of view while it has nothing to boot. Ironic waits for the agent until its timeout and the operator sees a host stuck in
inspecting.Cause
handleImportPodCompletedtreatsFailedlikeSucceededapart from the log line: it deletes the pod and callsremoveImportingLabel. Nothing records that the attached PVC is empty, soIsVirtualMediaInsertedandCheckInsertedMediasee a normal inserted device, andhandlePowerAfterImportsees a VM whose import is over.Fix
All in
pkg/kubevirt/client.go.markImportFailed): the importing label is removed,power-after-import.redfishis removed, and the device is marked with the annotationimport-failed.redfish/<device>= the pod name. One patch and not three because the VM watcher acts on the first event in which the importing label is gone; with separate writes the deferred power-on could still fire in between, which is the bug being fixed. The dropped power command is logged as a warning:Import of cdrom0 into VM ns/vm failed (pod ...); dropped the deferred power command On. Ironic is left waiting for a power state that does not come and retries the host, which is the expected outcome for a failed import; it was not exercised against a BareMetalHost here.Insertedmeans there is an image to boot.IsVirtualMediaInsertedreturns false while the importing label is set and while the failed marker is set, bound PVC or not.InsertMediaimports again.CheckInsertedMediareturns "nothing inserted" when the marker is set, whatever the URL, so the insert path runs, replaces the PVC as it already does for a re-insert, and clears the marker (next to the URL annotation it writes). The eject clears it too.409, as for any pending import (second commit).Behaviour changes: after a failed import the VM is not started,
power-after-import.redfishis removed,Insertedisfalse,InsertMediawith the same image answers202and imports again instead of204;Insertedis alsofalsewhile an import is running. The new annotationimport-failed.redfish/<device>appears on the VM until the next insert or eject.Not covered: a CDI (
VolumeImportSource) import that fails is not detected today, since the PVC watcher only reacts toBound; that is unchanged.Verification on the cluster
OpenShift 4.22 / OpenShift Virtualization 4.22, the bridge built from fork
mainwith #36 and this branch, an in-cluster nginx serving one ISO at 1.5 MB/s. Against a halted VM:InsertMediawith a URL on that server that returns 404 (curl --failin the helper pod exits non-zero), thenOnonce the importing label is on the VM:Bridge log:
No
Successfully started VMfor that VM at any point. The same run had two other VMs importing successfully with a deferredOn; they started after theirRemoved importing labelas before.Tests
pkg/kubevirt/import_failed_test.go: a failed pod removes the importing label and the deferred power command, sets the marker, leaves the VM halted and the URL annotation alone, deletes the pod, and does it in exactly one patch (a counting wrapper around the dynamic client); a succeeded pod removes the label, keeps the deferred command for the watcher and sets no marker; a stale failed pod changes nothing;IsVirtualMediaInsertedis true for a bound PVC and false with the importing label or the marker;CheckInsertedMediareturns "nothing inserted" with the marker for the same and for another image; a new insert and an eject clear the marker; with the marker and a pending re-insert, the same image isMediaStateImportingand another image isMediaStateConflict(added after the rebase; it failed withstate = 0before the second commit). With the constant alone and none of the logic, five of the seven fail (deferred power command still set: "On",Inserted = true, want false,state = 2, want MediaStateNone,annotation import-failed.redfish/cdrom0 ... survived the new insert/... the eject); the tests do not compile onmainwithout the constant.go build ./...,go vet ./...,go test ./...,gofmt,go mod tidy(no change) pass;go test -race ./pkg/kubevirt/passes.Related
mainafter fix(kubevirt): concurrent virtual-media insert and boot override could drop the CD-ROM disk from the VM spec #33, fix(server): Power On right after InsertMedia started the VM before its ISO import (empty CD-ROM, import pod stuck on the RWO volume) #36 and fix(server): a power-off is never deferred by a pending ISO import, and withdraws a deferred power-on #37 were merged. The only conflict was the one-linedelete(annotations, ...)inEjectVirtualMedia, which now sits inside fix(kubevirt): concurrent virtual-media insert and boot override could drop the CD-ROM disk from the VM spec #33'supdateVMclosure. The cluster run above was done before the rebase, on a tree that already had fix(kubevirt): concurrent virtual-media insert and boot override could drop the CD-ROM disk from the VM spec #33, fix(server): Power On right after InsertMedia started the VM before its ISO import (empty CD-ROM, import pod stuck on the RWO volume) #36 and the first commit merged together. On the rebased branch, and for the second commit, only the unit tests,go vetandgofmtwere run.CheckInsertedMediaalso reads; the second commit orders the two checks.ForceOff/GracefulShutdownwithdraw a deferred power-on on request; this PR withdraws it when the import itself fails.