You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2017/01/11 21:13:08 UTC
svn commit: r1778352 -
/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
Author: arkurth
Date: Wed Jan 11 21:13:07 2017
New Revision: 1778352
URL: http://svn.apache.org/viewvc?rev=1778352&view=rev
Log:
VCL-1008
Added code and uncommented existing code to libvirt.pm::capture to save a .xml file in the image library and repository locations when an image is captured.
Added libvirt.pm::get_master_xml_info which reads the .xml file and convert it to a hash reference.
Updated libvirt.pm::generate_domain_xml to attempt to retrieve the disk and network interface types from the master XML file for an image revision.
Updated libvirt.pm::get_master_image_file_path to prevent it from ever returning the path to the .xml file saved for an image.
Modified:
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm?rev=1778352&r1=1778351&r2=1778352&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm Wed Jan 11 21:13:07 2017
@@ -456,6 +456,16 @@ EOF
return;
}
+ # Save the domain XML definition to a file in the master image directory
+ my $master_xml_file_path = $self->get_master_xml_file_path();
+ if ($self->vmhost_os->create_text_file($master_xml_file_path, $domain_xml_string)) {
+ notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to master image directory: $master_xml_file_path");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file: $master_xml_file_path");
+ return;
+ }
+
# Update the image name in the database
if ($old_image_name ne $new_image_name && !update_image_name($image_id, $imagerevision_id, $new_image_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to update image name in the database: $old_image_name --> $new_image_name");
@@ -487,7 +497,7 @@ EOF
notify($ERRORS{'WARNING'}, 0, "found multiple disks defined in the XML definition for $domain_name, only domains with a single disk may be captured:\n" . format_data(\@disk_file_paths));
return;
}
-
+
# Copy the linked clone to create a new master image file
my $linked_clone_file_path = $disk_file_paths[0];
notify($ERRORS{'DEBUG'}, 0, "retrieved linked clone file path from domain $domain_name: $linked_clone_file_path");
@@ -508,16 +518,6 @@ EOF
return;
}
- ## Save the domain XML definition to a file in the master image directory
- #my $master_xml_file_path = $self->get_master_xml_file_path();
- #if ($self->vmhost_os->create_text_file($master_xml_file_path, $domain_xml)) {
- # notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to master image directory: $master_xml_file_path");
- #}
- #else {
- # notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file: $master_xml_file_path");
- # return;
- #}
-
# Copy the master image to the repository if the repository path is configured in the VM host profile
if ($repository_image_file_path) {
if (my $semaphore = $self->get_repository_image_semaphore()) {
@@ -534,15 +534,15 @@ EOF
return;
}
- ## Save the domain XML definition to a file in the repository image directory
- #my $repository_xml_file_path = $self->get_repository_xml_file_path();
- #if ($self->vmhost_os->create_text_file($repository_xml_file_path, $domain_xml)) {
- # notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to repository image directory: $master_xml_file_path");
- #}
- #else {
- # notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file to repository image directory: $master_xml_file_path");
- # return;
- #}
+ # Save the domain XML definition to a file in the repository image directory
+ my $repository_xml_file_path = $self->get_repository_xml_file_path();
+ if ($self->vmhost_os->create_text_file($repository_xml_file_path, $domain_xml_string)) {
+ notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to repository image directory: $master_xml_file_path");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file to repository image directory: $master_xml_file_path");
+ return;
+ }
}
}
@@ -1233,6 +1233,10 @@ sub get_master_image_file_path {
# Check if the master image file exists on the VM host
my @master_image_files_found = $self->vmhost_os->find_files($master_image_directory_path, "$image_name.*");
+
+ # Prune known metadata files - otherwise if only a .xml file exists for the image, the .xml path will be returned
+ @master_image_files_found = grep(!/\.(xml|reference)$/i, @master_image_files_found);
+
if (@master_image_files_found == 1) {
$self->{master_image_file_path} = $master_image_files_found[0];
notify($ERRORS{'DEBUG'}, 0, "found master image file on $node_name: $self->{master_image_file_path}");
@@ -1241,7 +1245,7 @@ sub get_master_image_file_path {
# File was not found, construct it
my $datastore_imagetype = $self->data->get_vmhost_datastore_imagetype_name();
- my $master_image_file_path = "$master_image_directory_path/$image_name.$datastore_imagetype";
+ my $master_image_file_path = "$master_image_directory_path/$image_name.$datastore_imagetype";
notify($ERRORS{'DEBUG'}, 0, "constructed master image file path: $master_image_file_path");
return $master_image_file_path;
}
@@ -1660,6 +1664,7 @@ sub generate_domain_xml {
my $copy_on_write_file_path = $self->get_copy_on_write_file_path();
my $image_type = $self->data->get_vmhost_datastore_imagetype_name();
my $disk_driver_name = $self->driver->get_disk_driver_name();
+ my $disk_bus_type = $self->get_master_xml_disk_bus_type();
my $eth0_source_device = $self->data->get_vmhost_profile_virtualswitch0();
my $eth1_source_device = $self->data->get_vmhost_profile_virtualswitch1();
@@ -1696,6 +1701,8 @@ sub generate_domain_xml {
$eth1_mac_address = $self->data->get_computer_eth1_mac_address();
}
+ my $interface_model_type = $self->get_master_xml_interface_model_type();
+
my $cpu_count = $self->data->get_image_minprocnumber() || 1;
my $memory_mb = $self->data->get_image_minram();
@@ -1763,7 +1770,7 @@ sub generate_domain_xml {
'file' => $copy_on_write_file_path,
},
'target' => {
- 'bus' => 'ide',
+ 'bus' => $disk_bus_type,
'dev' => 'vda'
},
}
@@ -1781,7 +1788,7 @@ sub generate_domain_xml {
'dev' => 'vnet0',
},
'model' => {
- #'type' => 'rtl8139',
+ 'type' => $interface_model_type,
},
},
{
@@ -1796,7 +1803,7 @@ sub generate_domain_xml {
'dev' => 'vnet1',
},
'model' => {
- #'type' => 'rtl8139',
+ 'type' => $interface_model_type,
},
}
],
@@ -2704,6 +2711,124 @@ sub get_node_interface_xml_string {
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_master_xml_info
+
+ Parameters : none
+ Returns : hash reference
+ Description : Retrieves the XML definition from the file saved when the image
+ was captured.
+
+=cut
+
+sub get_master_xml_info {
+ my $self = shift;
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ if (defined($self->{master_xml_info})) {
+ return $self->{master_xml_info};
+ }
+
+ # Save the domain XML definition to a file in the master image directory
+ my $master_xml_file_path = $self->get_master_xml_file_path();
+ if (!$self->vmhost_os->file_exists($master_xml_file_path)) {
+ notify($ERRORS{'DEBUG'}, 0, "master XML file does not exist: $master_xml_file_path");
+ $self->{master_xml_info} = {};
+ return $self->{master_xml_info};
+ }
+
+ my $master_xml_file_contents = $self->vmhost_os->get_file_contents($master_xml_file_path);
+ if (!$master_xml_file_contents) {
+ notify($ERRORS{'WARNING'}, 0, "master XML file contents could not be retrieved");
+ $self->{master_xml_info} = {};
+ return $self->{master_xml_info};
+ }
+
+ my $master_xml_hashref = xml_string_to_hash($master_xml_file_contents);
+ if ($master_xml_hashref) {
+ $self->{master_xml_info} = $master_xml_hashref;
+ #notify($ERRORS{'DEBUG'}, 0, "retrieved master XML info:\n" . format_data($self->{master_xml_info}));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "retrieved master XML info could not be parsed");
+ $self->{master_xml_info} = {};
+ }
+ return $self->{master_xml_info};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_master_xml_disk_bus_type
+
+ Parameters : none
+ Returns : string
+ Description : Retrieves the disk bus type from the master XML file saved when
+ the image was captured.
+
+=cut
+
+sub get_master_xml_disk_bus_type {
+ my $self = shift;
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ return $self->{master_xml_disk_bus_type} if defined($self->{master_xml_disk_bus_type});
+
+ $self->{master_xml_disk_bus_type} = 'ide';
+ my $master_xml_info = $self->get_master_xml_info() || return $self->{master_xml_disk_bus_type};
+
+ my $type = $master_xml_info->{devices}->[0]->{disk}->[0]->{target}->[0]->{bus};
+ if ($type) {
+ $self->{master_xml_disk_bus_type} = $type;
+ notify($ERRORS{'DEBUG'}, 0, "retrieved disk bus type from master XML info: $self->{master_xml_disk_bus_type}");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve disk bus type (->{devices}->[0]->{disk}->[0]->{target}->[0]->{bus}) from master XML info:\n" . format_data($master_xml_info));
+ }
+ return $self->{master_xml_disk_bus_type};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_master_xml_interface_model_type
+
+ Parameters : none
+ Returns : string
+ Description : Retrieves the interface model type from the master XML file saved
+ when the image was captured.
+
+=cut
+
+sub get_master_xml_interface_model_type {
+ my $self = shift;
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ return $self->{master_xml_interface_model_type} if defined($self->{master_xml_interface_model_type});
+
+ $self->{master_xml_interface_model_type} = 'rtl8139';
+ my $master_xml_info = $self->get_master_xml_info() || return $self->{master_xml_interface_model_type};
+
+ my $type = $master_xml_info->{devices}->[0]->{interface}->[0]->{model}->[0]->{type};
+ if ($type) {
+ $self->{master_xml_interface_model_type} = $type;
+ notify($ERRORS{'DEBUG'}, 0, "retrieved interface model type from master XML info: $self->{master_xml_interface_model_type}");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve interface model type () from master XML info:\n" . format_data($master_xml_info));
+ }
+ return $self->{master_xml_interface_model_type};
+}
+
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__