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 2016/08/30 20:18:52 UTC
svn commit: r1758462 -
/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
Author: arkurth
Date: Tue Aug 30 20:18:52 2016
New Revision: 1758462
URL: http://svn.apache.org/viewvc?rev=1758462&view=rev
Log:
VCL-987
Pulled logic out of xCAT.pm::get_image_repository_directory_path to dedicated get_nodetype_image_os_name subroutine since it needs to be used elsewhere.
Added calls to get_nodetype_image_os_name in get_image_repository_directory_path and _edit_nodetype.
Modified:
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm?rev=1758462&r1=1758461&r2=1758462&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm Tue Aug 30 20:18:52 2016
@@ -848,27 +848,33 @@ sub get_image_size {
} ## end sub get_image_size
-
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_image_repository_directory_path
+=head2 get_nodetype_image_os_name
- Parameters : $image_name, $management_node_identifier (optional)
+ Parameters : $image_name
Returns : string
- Description : Determines the path where the image resides on the management
- node. Examples:
- Partimage image: /install/image/x86
- Kickstart image: /install/centos5/x86_64
+ Description : Determines the name of the directory where installation files
+ should reside under the management node's install path.
+ Examples:
+ * image
+ * centos5
+ * rhels7.2
+ * ubuntu16.04.1
- The path is constructed from the following database values:
- * managementnode.installpath
- * OS.sourcepath
- * image.architecture
+ The path is determined by first checking if a directory exists
+ matching the database values:
+ * managementnode.installpath (ex: /install)
+ * OS.sourcepath (ex: rhel7)
+ * image.architecture (ex: x86_64)
+
+ Based on these values, the default path will be:
+ /install/rhel7/x86_64
If a directory exactly matching OS.sourcepath cannot be located
on the managementnode node, an attempt is made to locate an
alternate suitable directory matching the distribution and major
- version. Example, if OS.sourcepath = 'rhel7' and the following
+ version. Example, if OS.sourcepath = 'rhel7' and the default
directory does not exist:
/install/rhel7/x86_64
@@ -876,17 +882,17 @@ sub get_image_size {
be returned:
/install/rhel7.1/x86_64
/install/rhels7.2/x86_64
- /install/rhels7.10/x86_64
If all of these paths exist, the path with the highest version is
returned:
- /install/rhels7.10/x86_64
+ rhels7.2
Note: for 'rhel', both 'rhel' and 'rhels' are checked.
=cut
-sub get_image_repository_directory_path {
+
+sub get_nodetype_image_os_name {
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
@@ -896,11 +902,180 @@ sub get_image_repository_directory_path
# Get the image name argument
my $image_name = shift || $self->data->get_image_name();
- my $local_management_node_hostname = $self->data->get_management_node_hostname();
- my $management_node_hostname;
+ # Check if path has already been determined
+ if (defined($self->{xcat_image_os_name}{$image_name})) {
+ return $self->{xcat_image_os_name}{$image_name};
+ }
+
+ my $management_node_hostname = $self->data->get_management_node_hostname();
+ my $management_node_install_path = $self->data->get_management_node_install_path();
+
+ # Create a DataStructure object containing info about the image
+ my $image_data = $self->create_datastructure_object({image_identifier => $image_name}) || return;
+ my $os_install_type = $image_data->get_image_os_install_type() || return;
+ my $os_source_path = $image_data->get_image_os_source_path() || return;
+ my $image_architecture = $image_data->get_image_architecture() || return;
+
+ if ($os_install_type =~ /image/i) {
+ notify($ERRORS{'DEBUG'}, 0, "OS install type for image $image_name is $os_install_type, returning 'image'");
+ $self->{xcat_image_os_name}{$image_name} = 'image';
+ return 'image';
+ }
+ elsif ($os_install_type !~ /(kickstart|netboot)/) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine nodetype image OS name for image $image_name, OS install type is not supported: $os_install_type");
+ return;
+ }
+
+ # Remove trailing / from $management_node_install_path if exists
+ $management_node_install_path =~ s/\/+$//g;
+
+ # Remove leading and trailing slashes from $os_source_path if exists
+ $os_source_path =~ s/^\/+//g;
+ $os_source_path =~ s/\/+$//g;
+
+ notify($ERRORS{'DEBUG'}, 0, "attempting to determine nodetype OS name for image on $management_node_hostname:\n" .
+ "image name : $image_name\n" .
+ "OS install type : $os_install_type\n" .
+ "install path : $management_node_install_path\n" .
+ "OS source path : $os_source_path\n" .
+ "architecture : $image_architecture"
+ );
+
+ my $installation_repository_directory_path = "$management_node_install_path/$os_source_path/$image_architecture";
+
+ # Check if the default path exists - it's often named something different
+ # xCAT's copycds command will use something like /install/rhels6.6
+ # OS.sourcepath is probably set to rhel6
+ # Creating a symlink doesn't work correctly because xCAT fails to parse directory names which don't contain a period correctly
+ if ($self->mn_os->file_exists($installation_repository_directory_path)) {
+ $self->{xcat_image_os_name}{$image_name} = $os_source_path;
+ notify($ERRORS{'DEBUG'}, 0, "default installation repository directory exists: $installation_repository_directory_path, returning '$self->{xcat_image_os_name}{$image_name}'");
+ return $self->{xcat_image_os_name}{$image_name};
+ }
+
+ # Parse the version of the requested OS source path
+ my ($os_distribution_name, $os_version_string, $major_os_version_string) = $os_source_path =~ /^([a-z]+)((\d+)[\d\.]*)$/ig;
+ if (!defined($os_distribution_name) || !defined($os_version_string) || !defined($major_os_version_string)) {
+ $self->{xcat_image_os_name}{$image_name} = $os_source_path;
+ notify($ERRORS{'WARNING'}, 0, "failed to determine nodetype OS name for image $image_name, OS.sourcepath could not be parsed: $os_source_path, returning default path: '$self->{xcat_image_os_name}{$image_name}'");
+ return $self->{xcat_image_os_name}{$image_name};
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "default installation repository directory path does not exist: $installation_repository_directory_path, attempting to locate another suitable path matching distribution: $os_distribution_name, version: $os_version_string, major version: $major_os_version_string");
+
+ # Fix regex for 'rhel' and 'rhels'
+ my $os_distribution_regex = $os_distribution_name;
+ if ($os_distribution_name =~ /rhel/) {
+ $os_distribution_regex = 'rhels?';
+ }
+
+ my $highest_version_string;
+ my $highest_version_directory_path;
+ my $highest_version_nodetype_os_name;
+
+ # Retrieve list of directories under the root management node install path
+ my @check_directory_paths = $self->mn_os->find_files($management_node_install_path, "*", 0, 'd');
+ for my $check_directory_path (@check_directory_paths) {
+ # Remove trailing slash
+ $check_directory_path =~ s/\/+$//g;
+
+ next if $check_directory_path eq $management_node_install_path;
+
+ # Ignore directories that don't contain the Linux OS distribution name
+ if ($check_directory_path !~ /$os_distribution_regex/) {
+ #notify($ERRORS{'DEBUG'}, 0, "ignoring directory: $check_directory_path, it does not match the pattern for the OS distribution: '$os_distribution_regex'");
+ next;
+ }
+
+ my ($check_nodetype_os_name) = $check_directory_path =~ /\/([^\/]+)$/;
+ if (!defined($check_nodetype_os_name)) {
+ notify($ERRORS{'WARNING'}, 0, "ignoring directory: $check_directory_path, failed to parse directory name (nodetype OS name)");
+ next;
+ }
+
+ # Parse the version and major version from the directory name
+ my ($directory_version_string, $directory_major_version_string) = $check_directory_path =~ /$os_distribution_regex((\d+)[\d\.]*)/;
+ if (!defined($directory_version_string) || !defined($directory_major_version_string)) {
+ notify($ERRORS{'DEBUG'}, 0, "ignoring directory: $check_directory_path, version could not be determined");
+ next;
+ }
+
+ # Make sure the major version matches
+ if ($directory_major_version_string ne $major_os_version_string) {
+ notify($ERRORS{'DEBUG'}, 0, "ignoring directory: $check_directory_path, major version $directory_major_version_string does not match requested major version $major_os_version_string");
+ next;
+ }
+
+ # Make sure the correct architecture subdirectory exists
+ my $check_installation_repository_directory_path = "$check_directory_path/$image_architecture";
+ if (!$self->mn_os->file_exists($check_installation_repository_directory_path)) {
+ notify($ERRORS{'DEBUG'}, 0, "ignoring directory: $check_directory_path, '$image_architecture' subdirectory does not exist");
+ next;
+ }
+
+ if (!$highest_version_string) {
+ notify($ERRORS{'DEBUG'}, 0, "1st matching directory is possibly an alternate path: $check_installation_repository_directory_path, version: $directory_version_string");
+ $highest_version_string = $directory_version_string;
+ $highest_version_directory_path = $check_installation_repository_directory_path;
+ $highest_version_nodetype_os_name = $check_nodetype_os_name;
+ next;
+ }
+
+ # Check if the version isn't less than one previously checked
+ # Use version->declare->numify to correctly compare versions, otherwise 6.9 > 6.10
+ my $matching_version_numified = version->declare("$directory_version_string")->numify;
+ my $highest_matching_version_numified = version->declare("$highest_version_string")->numify;
+ if ($matching_version_numified <= $highest_matching_version_numified) {
+ notify($ERRORS{'DEBUG'}, 0, "directory ignored, version $directory_version_string ($matching_version_numified) is not higher than $highest_version_string ($highest_matching_version_numified): $check_directory_path");
+ next;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "directory version $directory_version_string ($matching_version_numified) is greater than $highest_version_string ($highest_matching_version_numified): $check_installation_repository_directory_path");
+ $highest_version_string = $directory_version_string;
+ $highest_version_directory_path = $check_installation_repository_directory_path;
+ $highest_version_nodetype_os_name = $check_nodetype_os_name;
+ next;
+ }
+ }
+
+ if ($highest_version_nodetype_os_name) {
+ $self->{xcat_image_os_name}{$image_name} = $highest_version_nodetype_os_name;
+ notify($ERRORS{'OK'}, 0, "located alternate repository directory path on the local management node for kickstart image $image_name: $highest_version_directory_path, returning nodetype OS name: $self->{xcat_image_os_name}{$image_name}");
+ return $self->{xcat_image_os_name}{$image_name};
+ }
+ else {
+ $self->{xcat_image_os_name}{$image_name} = $os_source_path;
+ notify($ERRORS{'WARNING'}, 0, "failed to locate repository directory path on the local management node for kickstart image $image_name, returning default nodetype OS name: $self->{xcat_image_os_name}{$image_name}");
+ return $self->{xcat_image_os_name}{$image_name};
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_image_repository_directory_path
+
+ Parameters : $image_name, $management_node_identifier (optional)
+ Returns : string
+ Description : Determines the path where the image resides on the management
+ node. Examples:
+ Partimage image: /install/image/x86
+ Kickstart image: /install/centos5/x86_64
+
+=cut
+
+sub get_image_repository_directory_path {
+ my $self = shift;
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
+ return;
+ }
+
+ # Get the image name argument
+ my $image_name = shift || $self->data->get_image_name();
# Check if a management node identifier argument was passed
my $management_node_identifier = shift;
+ my $management_node_hostname;
if ($management_node_identifier) {
$management_node_hostname = $self->data->get_management_node_hostname($management_node_identifier);
if ($management_node_hostname) {
@@ -912,12 +1087,12 @@ sub get_image_repository_directory_path
}
}
else {
- $management_node_hostname = $local_management_node_hostname;
+ $management_node_hostname = $self->data->get_management_node_hostname();
}
# Check if path has already been determined
- if (defined($self->{image_repository_path}{$image_name}{$management_node_hostname})) {
- return $self->{image_repository_path}{$image_name}{$management_node_hostname};
+ if (defined($self->{xcat_image_repository_directory_path}{$image_name}{$management_node_hostname})) {
+ return $self->{xcat_image_repository_directory_path}{$image_name}{$management_node_hostname};
}
my $management_node_install_path = $self->data->get_management_node_install_path($management_node_identifier);
@@ -942,117 +1117,24 @@ sub get_image_repository_directory_path
"architecture : $image_architecture"
);
- # If image OS source path has a leading /, assume it was meant to be absolute
- # Otherwise, prepend the install path
- my $image_install_path;
+
+ my $image_repository_directory_path;
if ($os_source_path =~ /^\//) {
- $image_install_path = $os_source_path;
+ # If image OS source path has a leading /, assume it was meant to be absolute
+ $image_repository_directory_path = $os_source_path;
}
- else {
- $image_install_path = "$management_node_install_path/$os_source_path";
- }
-
- # Note: $XCAT_ROOT has a leading /
- # Note: $image_install_path has a leading /
- if ($os_install_type eq 'kickstart') {
- # Kickstart installs use the xCAT path for both repo and tmpl paths
- my $kickstart_repository_path = "$image_install_path/$image_architecture";
-
- # If retrieving directory path for local management node, check if it exists
- # xCAT's copycds command will use something like a /install/rhels6.6 directory
- # os.sourcepath may be set to rhel6
- # Creating a symlink doesn't work correctly because xCAT fails to parse directory names which don't contain a period correctly
- if ($management_node_hostname eq $local_management_node_hostname) {
- if (!$self->mn_os->file_exists($kickstart_repository_path)) {
- # Parse the version of the requested OS
- my ($os_distribution, $os_version_string, $major_os_version_string) = $os_source_path =~ /^([a-z]+)((\d+)[\d\.]*)$/ig;
- if (!defined($os_distribution) || !defined($os_version_string) || !defined($major_os_version_string)) {
- notify($ERRORS{'WARNING'}, 0, "failed to locate repository directory path on the local management node for kickstart image $image_name, the OS.sourcepath could not be parsed: $os_source_path, returning default path: $kickstart_repository_path");
- $self->{image_repository_path}{$management_node_hostname} = $kickstart_repository_path;
- return $kickstart_repository_path;
- }
- notify($ERRORS{'DEBUG'}, 0, "kickstart repository path based on the OS.sourcepath value '$os_source_path' does not exist: $kickstart_repository_path, attempting to locate another suitable path matching distribution: $os_distribution, version: $os_version_string, major version: $major_os_version_string");
-
-
- my @matching_distribution_paths = $self->mn_os->find_files($management_node_install_path, "*", 0, 'd');
- my $highest_matching_version_string;
- my $highest_kickstart_repository_path;
- for my $matching_distribution_path (@matching_distribution_paths) {
- my $os_distribution_regex = $os_distribution;
- if ($os_distribution =~ /rhel/) {
- # Match 'rhel' and 'rhels'
- $os_distribution_regex = 'rhels?';
- }
-
- if ($matching_distribution_path !~ /$os_distribution_regex/) {
- #notify($ERRORS{'DEBUG'}, 0, "ignoring directory, it does not match the OS distribution regex '$os_distribution_regex': $matching_distribution_path");
- next;
- }
-
-
- my ($matching_version_string, $matching_major_version_string) = $matching_distribution_path =~ /$os_distribution_regex((\d+)[\d\.]*)/;
- if (!defined($matching_version_string) || !defined($matching_major_version_string)) {
- notify($ERRORS{'DEBUG'}, 0, "ignoring directory, version could not be determined: $matching_distribution_path");
- next;
- }
-
-
- # Make sure the major version matches
- if ($matching_major_version_string ne $major_os_version_string) {
- notify($ERRORS{'DEBUG'}, 0, "distribution directory ignored, major version $matching_major_version_string does not match requested major version $major_os_version_string: $matching_distribution_path");
- next;
- }
-
- # Make sure the correct architecture subdirectory exists
- my $matching_kickstart_repository_path = "$matching_distribution_path/$image_architecture";
- if (!$self->mn_os->file_exists($matching_kickstart_repository_path)) {
- notify($ERRORS{'DEBUG'}, 0, "ignoring directory becuase $image_architecture subdirectory does not exist: $matching_distribution_path");
- next;
- }
-
- if (!$highest_matching_version_string) {
- notify($ERRORS{'DEBUG'}, 0, "1st matching distribution directory is possibly an alternate path: $matching_kickstart_repository_path, version: $matching_version_string");
- $highest_kickstart_repository_path = $matching_kickstart_repository_path;
- $highest_matching_version_string = $matching_version_string;
- next;
- }
-
- # Check if the version isn't less than one previously checked
- # Use version->declare->numify to correctly compare versions, otherwise 6.9 > 6.10
- my $matching_version_numified = version->declare("$matching_version_string")->numify;
- my $highest_matching_version_numified = version->declare("$highest_matching_version_string")->numify;
- if ($highest_matching_version_numified > $matching_version_numified) {
- notify($ERRORS{'DEBUG'}, 0, "distribution directory ignored, version $matching_version_string ($matching_version_numified) is less than $highest_matching_version_string ($highest_matching_version_numified): $matching_distribution_path");
- next;
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "distribution directory version $matching_version_string ($matching_version_numified) is greater than $highest_matching_version_string ($highest_matching_version_numified): $matching_kickstart_repository_path");
- $highest_kickstart_repository_path = $matching_kickstart_repository_path;
- $highest_matching_version_string = $matching_version_string;
- next;
- }
- }
-
- if ($highest_kickstart_repository_path) {
- notify($ERRORS{'OK'}, 0, "located alternate repository directory path on the local management node for kickstart image $image_name: $highest_kickstart_repository_path");
- $kickstart_repository_path = $highest_kickstart_repository_path;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to locate repository directory path on the local management node for kickstart image $image_name, the OS.sourcepath could not be parsed: $os_source_path, returning default path: $kickstart_repository_path");
- }
- }
- }
-
- $self->{image_repository_path}{$management_node_hostname} = $kickstart_repository_path;
- notify($ERRORS{'DEBUG'}, 0, "kickstart install type, returning $kickstart_repository_path");
- return $kickstart_repository_path;
+ elsif ($os_install_type eq 'kickstart') {
+ my $nodetype_image_os_name = $self->get_nodetype_image_os_name($image_name) || $os_source_path;
+ $image_repository_directory_path = "$management_node_install_path/$nodetype_image_os_name/$image_architecture";
}
else {
- my $repo_path = "$image_install_path/$image_architecture";
- $self->{image_repository_path}{$image_name}{$management_node_hostname} = $repo_path;
- notify($ERRORS{'DEBUG'}, 0, "returning repository path for $management_node_hostname: $repo_path");
- return $repo_path;
+ # Partimage
+ $image_repository_directory_path = "$management_node_install_path/$os_source_path/$image_architecture";
}
+
+ $self->{xcat_image_repository_directory_path}{$image_name}{$management_node_hostname} = $image_repository_directory_path;
+ notify($ERRORS{'DEBUG'}, 0, "determined repository directory path: $self->{xcat_image_repository_directory_path}{$image_name}{$management_node_hostname}");
+ return $self->{xcat_image_repository_directory_path}{$image_name}{$management_node_hostname};
} ## end sub get_image_repository_directory_path
#/////////////////////////////////////////////////////////////////////////////
@@ -1337,7 +1419,6 @@ sub _edit_nodelist {
my $image_data = $self->create_datastructure_object({image_identifier => $image_name}) || return;
my $image_os_install_type = $image_data->get_image_os_install_type() || return;
my $image_project = $image_data->get_image_project() || return;
- my $image_os_name = $image_data->get_image_os_name() || return;
my $request_state_name = $self->data->get_request_state_name();
@@ -1421,11 +1502,19 @@ sub _edit_nodetype {
my $request_state_name = $self->data->get_request_state_name();
+ my $nodetype_os;
if ($request_state_name eq 'image' || $image_os_install_type =~ /image/) {
- $image_os_name = 'image';
+ $nodetype_os = 'image';
+ }
+ elsif ($image_os_install_type =~ /kickstart/i) {
+ # Try to dynamically determine the value for nodetype.os
+ $nodetype_os = $self->get_nodetype_image_os_name($image_name);
+ }
+ else {
+ $nodetype_os = $image_os_name;
}
- my $command = "$XCAT_ROOT/bin/nodech $computer_node_name nodetype.os=$image_os_name nodetype.arch=$image_architecture nodetype.profile=$image_name";
+ my $command = "$XCAT_ROOT/bin/nodech $computer_node_name nodetype.os=$nodetype_os nodetype.arch=$image_architecture nodetype.profile=$image_name";
my ($exit_status, $output) = $self->mn_os->execute($command);
if (!defined($output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to edit xCAT configuration of $computer_node_name: $command");