fix #6184: import: ovf: add CD drives
The OVF parser only looks at disk drives, so the CD drives of a guest are dropped on import. Appliances shipped as OVA sometimes come with an ISO image in a CD drive, for example to install the guest on first boot. Such a guest then does not boot after the import, and the user is not told about the image at all. Add the CD drives of the manifest as empty drives on their controller, after the disks in the boot order, like the ESXi import does. As CD images cannot be imported, report a referenced image with the existing 'cdrom-image-ignored' warning, so that the import wizard tells the user to configure the drive in the 'Advanced' tab. As the address only takes the position on the controller into account, a CD drive can end up with the address of a disk, for example with a disk on the first IDE controller and the CD drive on the second one. Such a CD drive gets the next free address on its bus. Signed-off-by: Michal Fox <me@dualfroz.com>
This commit is contained in:
1 parent
095cd282f3
commit
b77120f913
4 files changed
+202
-4
No files matched your search
@@ -385,7 +385,46 @@ ovf:Item[rasd:InstanceID='%s']/rasd:ResourceType", $controller_id,
|
||||
$net_count++;
|
||||
}
|
||||
|
||||
return { qm => $qm, disks => \@disks, net => $net };
|
||||
# CD drives are added empty, as images cannot be imported, but the referenced image is kept
|
||||
# so the user can be told about it
|
||||
my $cdrom_id = dtmf_name_to_id('CD Drive');
|
||||
my $xpath_find_cdroms =
|
||||
"/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType=${cdrom_id}]";
|
||||
my @cdrom_items = $xpc->findnodes($xpath_find_cdroms);
|
||||
|
||||
my $addresses_in_use = { map { $_->{disk_address} => 1 } @disks };
|
||||
my @cdroms;
|
||||
for my $item_node (@cdrom_items) {
|
||||
my $controller_id = $xpc->findvalue('rasd:Parent', $item_node);
|
||||
my $xpath_find_parent_type = sprintf(
|
||||
"/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/\
|
||||
ovf:Item[rasd:InstanceID='%s']/rasd:ResourceType", $controller_id,
|
||||
);
|
||||
my $bus = id_to_pve($xpc->findvalue($xpath_find_parent_type));
|
||||
if (!$bus) {
|
||||
warn "invalid or missing controller for CD drive, skipping\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $index = $xpc->findvalue('rasd:AddressOnParent', $item_node);
|
||||
$index = 0 if $index !~ m/^\d+$/;
|
||||
$index++ while $addresses_in_use->{"$bus$index"};
|
||||
my $address = "$bus$index";
|
||||
$addresses_in_use->{$address} = 1;
|
||||
|
||||
my $image;
|
||||
my $host_resource = $xpc->findvalue('rasd:HostResource', $item_node);
|
||||
if ($host_resource =~ m|^(?:ovf:)?/file/([[:alnum:]\-\._~]+)$|) {
|
||||
my $xpath_find_image =
|
||||
sprintf("/ovf:Envelope/ovf:References/ovf:File[\@ovf:id='%s']/\@ovf:href", $1);
|
||||
$image = $xpc->findvalue($xpath_find_image) || undef;
|
||||
}
|
||||
|
||||
$qm->{$address} = 'none,media=cdrom';
|
||||
push @cdroms, { disk_address => $address, image => $image };
|
||||
}
|
||||
|
||||
return { qm => $qm, disks => \@disks, net => $net, cdroms => \@cdroms };
|
||||
}
|
||||
|
||||
my sub resolve_disks {
|
||||
@@ -436,6 +475,8 @@ my sub resolve_disks {
|
||||
push @$boot_order, $pve_disk_address;
|
||||
}
|
||||
|
||||
push @$boot_order, map { $_->{disk_address} } $qm->{cdroms}->@*;
|
||||
|
||||
$qm->{qm}->{boot} = "order=" . join(';', @$boot_order) if scalar(@$boot_order) > 0;
|
||||
|
||||
$qm->{disks} = \@disks;
|
||||
|
||||
Reference in new issue
Block a user