Repository navigation
Commit 8d965ab
kvm: support direct download templates on NVMe-oF pools
createTemplateFromDirectDownloadFile() threw UnsupportedOperationException, so a
template registered with directdownload=true could not be deployed onto an
NVMe-TCP pool: the download itself succeeded and the deployment then failed on
the host.
The two path arguments are different kinds of thing, and conflating them is what
made this look harder than it is. templateFilePath is a plain local file produced
by the direct-download helper, while destTemplatePath is a managed volume path of
the form "type=NVMETCP;address=...". Only the destination may be resolved through
KVMStoragePool.getPhysicalDisk(); handing the local file to that would pass a file
name to parseAndValidatePath() and fail. KVMStorageProcessor has already issued
connectPhysicalDisk() for the destination by the time we are called, so the
namespace is present.
Worth recording that the Fibre Channel implementation does conflate them. It calls
destPool.getPhysicalDisk(templateFilePath), and FiberChannelAdapter's
parseAndValidatePath() treats any string without a ";" as a bare WWN, so a local
file path becomes "/dev/mapper/3" + that path and the lookup cannot succeed. This
implementation follows ScaleIOStorageAdaptor instead, which is the working
precedent for block-backed managed storage.
The template is written as QCOW2 onto the raw namespace rather than as RAW. Three
reasons: it matches ScaleIO; it agrees with the QCOW2 format the template is
registered with, so stored content and declared format do not contradict each
other; and KVMStorageProcessor runs Qcow2Inspector.validateQcow2File() on the path
we return, which for a block device that exists would fail on RAW content and then
try to delete the device.
The disk returned to the caller is constructed rather than being the one
getPhysicalDisk() handed back, because its *name* matters and not just its path.
KVMStorageProcessor puts disk.getName() into the DirectDownloadAnswer, which
becomes the template's install path in template_spool_ref and later its external
name, and the provider interpolates that external name into array REST calls.
getPhysicalDisk() names a disk AddressInfo.toString(), e.g.
AddressInfo NVMETCP [address=006c..., connectionId=2172, path=/dev/disk/by-id/...]
Recording that as the install path makes the first deployment from a freshly
registered template fail: revokeAccess() -> detach() builds
"/connections?host_names=kvm01&volume_names=cloudstack2::<external name>" and
URI.create() rejects the spaces and brackets with "Illegal character in query".
The surfaced error is a misleading "Failed to update state", because the resulting
CloudRuntimeException is followed by applying OperationFailed to a template that
has already reached Ready. Naming the returned disk with the managed volume path
gives the same install path shape a volume records:
type=NVMETCP; address=006c...; providerName=cloudstack2::tpl-9-0-2-210; providerID=...
Also handles compressed templates via TemplateDownloaderUtil, since
direct-download templates are commonly published that way, and refuses up front if
the template will not fit the namespace rather than failing part way through the
convert.
Tested on a two-host KVM cluster against a FlashArray over NVMe-TCP: registered a
QCOW2 template with directdownload=true and deployed a VM from it, on the first
attempt, with a storage offering tagged for the NVMe-TCP pool:
ROOT-32 Everpure X90 NVMe-TCP pool2 Ready
type=NVMETCP; address=006c1b16ce1c034d24a9371c0623b125
Signed-off-by: Eugenio Grosso <eugenio.grosso@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>1 parent 34edb22 commit 8d965ab
1 file changed
Lines changed: 103 additions & 7 deletions
File tree
- plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage
Lines changed: 103 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| 37 | + | |
36 | 38 | | |
37 | 39 | | |
38 | 40 | | |
| |||
382 | 384 | | |
383 | 385 | | |
384 | 386 | | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
385 | 412 | | |
386 | 413 | | |
387 | | - | |
388 | | - | |
389 | | - | |
390 | | - | |
391 | | - | |
392 | | - | |
393 | | - | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
394 | 490 | | |
395 | 491 | | |
396 | 492 | | |
| |||
0 commit comments