in managementnode/lib/VCL/Module/Provisioning/xCAT.pm [895:1051]
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");
return;
}
# Get the image name argument
my $image_name = shift || $self->data->get_image_name();
# 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() || return;
# 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};
}
}