#!/usr/bin/perl -w
###############################################################################
# $Id$
###############################################################################
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################

=head1 NAME

VCL::Module::Provisioning - VCL provisioning base module

=head1 SYNOPSIS

 use base qw(VCL::Module::Provisioning);

=head1 DESCRIPTION

 Needs to be written.

=cut

###############################################################################
package VCL::Module::Provisioning;

# Specify the lib path using FindBin
use FindBin;
use lib "$FindBin::Bin/../..";

# Configure inheritance
use base qw(VCL::Module);

# Specify the version of this module
our $VERSION = '2.5.1';

# Specify the version of Perl to use
use 5.008000;

use strict;
use warnings;
use diagnostics;
use English qw(-no_match_vars);
use File::Basename;

use VCL::utils;

###############################################################################

=head1 OBJECT METHODS

=cut

#//////////////////////////////////////////////////////////////////////////////

=head2 node_status

 Parameters  : none
 Returns     : string
 Description : Checks the status of the computer in order to determine if the
               computer is ready to be reserved or needs to be reloaded. A
               string is returned depending on the status of the computer:
               'READY':
                  * Computer is ready to be reserved
                  * It is accessible
                  * It is loaded with the correct image
                  * OS module's post-load tasks have run
                  * Computer has not been tagged with a tainted tag
               'POST_LOAD':
                  * Computer is loaded with the correct image
                  * OS module's post-load tasks have not run
               'RELOAD':
                  * Computer is not accessible or not loaded with the correct
                    image

=cut

sub node_status {
	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;
	}
	
	my $computer_name = $self->data->get_computer_node_name();
	my $image_name = $self->data->get_image_name();
	my $reservation_imagerevision_id = $self->data->get_imagerevision_id();
	
	notify($ERRORS{'DEBUG'}, 0, "checking if $computer_name is responding and loaded with $image_name, imagerevision ID: $reservation_imagerevision_id");
	
	# Check if SSH is available
	if (!$self->os->is_ssh_responding()) {
		notify($ERRORS{'OK'}, 0, "$computer_name is not responding to SSH, returning 'RELOAD'");
		return 'RELOAD';
	}
	
	# Check if the imagerevision ID loaded on the computer matches the reservation
	my $current_image_revision_id = $self->os->get_current_imagerevision_id();
	if (!$current_image_revision_id) {
		notify($ERRORS{'OK'}, 0, "unable to retrieve imagerevision ID from $computer_name, returning 'RELOAD'");
		return 'RELOAD';
	}
	elsif ($current_image_revision_id ne $reservation_imagerevision_id) {
		notify($ERRORS{'OK'}, 0, "$computer_name is loaded with imagerevision ID: $current_image_revision_id, not $reservation_imagerevision_id, returning 'RELOAD'");
		return 'RELOAD';
	}
	else {
		notify($ERRORS{'DEBUG'}, 0, "$computer_name is loaded with the correct imagerevision ID: $current_image_revision_id");
	}
	
	# Check if current image has been tagged as tainted
	my $tainted_status = $self->os->get_tainted_status();
	if ($tainted_status) {
		notify($ERRORS{'WARNING'}, 0, "user may have previously had the ability to log in to the image currently loaded on $computer_name, current image is tagged as tainted, returning 'RELOAD'");
		return 'RELOAD';
	}
	
	# Check if the post-load tasks have been completed
	my $post_load_status = $self->os->get_post_load_status();
	if (!$post_load_status) {
		notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have NOT been completed on $computer_name, returning 'POST_LOAD'");
		return 'POST_LOAD';
	}
	
	# Check if OS module implements a node_status_os_check subroutine
	# Currently, this is only used by the Windows module to ensure the AD configuration is correct if an image's AD configuration is changed after a computer is loaded
	if ($self->os->can('node_status_os_check')) {
		if (!$self->os->node_status_os_check()) {
			notify($ERRORS{'DEBUG'}, 0, "OS module's node_status_os_check returned false, returning 'RELOAD'");
			return 'RELOAD';
		}
	}
	
	notify($ERRORS{'DEBUG'}, 0, "general node status checks all succeeded, returning 'READY'");
	return 'READY';
}

#//////////////////////////////////////////////////////////////////////////////

=head2 get_image_repository_search_paths

 Parameters  : $management_node_identifier (optional)
 Returns     : array
 Description : Returns an array containing paths on the management node where an
               image may reside. The paths may contain wildcards. This is used
               to attempt to locate an image on another managment node in order
               to retrieve it.

=cut

sub get_image_repository_search_paths {
	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;
	}
	
	my $management_node_identifier = shift;
	
	my $image_name = $self->data->get_image_name();
	
	my @search_paths;
	
	my $management_node_install_path = $self->data->get_management_node_install_path($management_node_identifier);
	if ($management_node_install_path) {
		push @search_paths, "$management_node_install_path/$image_name*";
		push @search_paths, "$management_node_install_path/vmware_images/$image_name*";
	}
	
	my $vmhost_profile_repository_path = $self->data->get_vmhost_profile_repository_path(0);
	push @search_paths, "$vmhost_profile_repository_path/$image_name*" if $vmhost_profile_repository_path;
	
	return @search_paths;
} ## end sub get_image_repository_search_paths

#//////////////////////////////////////////////////////////////////////////////

=head2 retrieve_image

 Parameters  : none
 Returns     : boolean
 Description : Retrieves an image from another management node.

=cut

sub retrieve_image {
	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;	
	}

	my $reservation_id = $self->data->get_reservation_id();
	my $computer_id = $self->data->get_computer_id();

	# Make sure image library functions are enabled
	my $image_lib_enable = $self->data->get_management_node_image_lib_enable();
	if (!$image_lib_enable) {
		notify($ERRORS{'OK'}, 0, "image retrieval skipped, image library functions are disabled for this management node");
		return;
	}

	# Get the image name from the reservation data
	my $image_name = $self->data->get_image_name();
	if (!$image_name) {
		notify($ERRORS{'WARNING'}, 0, "failed to determine image name from reservation data");
		return;
	}
	
	# Get a semaphore so only 1 process is able to retrieve the image at a time
	# Do this before checking if the image exists in case another process is retrieving the image
	# Wait up to 2 hours in case a large image is being retrieved
	my $semaphore = $self->get_semaphore("retrieve_$image_name", (60 * 120)) || return;
	
	# Make sure image does not already exist on this management node
	if ($self->does_image_exist($image_name)) {
		notify($ERRORS{'OK'}, 0, "$image_name already exists on this management node");
		return 1;
	}

	# Get the image library partner string
	my $image_lib_partners = $self->data->get_management_node_image_lib_partners();
	if (!$image_lib_partners) {
		notify($ERRORS{'WARNING'}, 0, "image library partners could not be determined");
		return;
	}
	
	# Split up the partner list
	my @partner_list = split(/,/, $image_lib_partners);
	if ((scalar @partner_list) == 0) {
		notify($ERRORS{'WARNING'}, 0, "image lib partners variable is not listed correctly or does not contain any information: $image_lib_partners");
		return;
	}
	
	# Get the image repository path
	my $image_repository_path_local;
	if ($self->can('get_image_repository_path')) {
		$image_repository_path_local = $self->get_image_repository_path();
	}
	elsif ($self->can('get_image_repository_directory_path')) {
		$image_repository_path_local = $self->get_image_repository_directory_path();
	}
	else {
		$image_repository_path_local = $self->data->get_vmhost_profile_repository_path(0);
		
		# Add the image name as an intermediate directory
		$image_repository_path_local =~ s/[\/\s]+$//;
		$image_repository_path_local .= "/$image_name";
	}
	
	if (!$image_repository_path_local) {
		notify($ERRORS{'WARNING'}, 0, "unable to determine the local image repository path");
		return;
	}
	
	# Make sure the parent image repository path exists
	my ($image_repository_directory_name, $image_repository_parent_directory_path) = fileparse($image_repository_path_local, qr/\.[^\\\/]*/);
	if (!$image_repository_parent_directory_path) {
		notify($ERRORS{'WARNING'}, 0, "unable to retrieve image from another management node because the path specified as the VM host profile repository could not be parsed: $image_repository_path_local");
		return;
	}
	elsif (!$self->mn_os->file_exists($image_repository_parent_directory_path)) {
		notify($ERRORS{'WARNING'}, 0, "unable to retrieve image from another management node because the path on this management node where the image files are to be copied does not exist, the path specified as the VM host profile repository path is: $image_repository_parent_directory_path, either a directory, mount point, or symbolic link must exist on this management node in this location");
		return;
	}
	
	# Loop through the partners
	# Find partners which have the image
	# Check size for each partner
	# Retrieve image from partner with largest image
	# It's possible that another partner (management node) is currently copying the image from another managment node
	# This should prevent copying a partial image
	my %partner_info;
	my $largest_partner_image_size = 0;
	my @partners_with_image;
	
	PARTNER: foreach my $partner (@partner_list) {
		# Get the connection information for the partner management node
		$partner_info{$partner}{hostname} = $self->data->get_management_node_hostname($partner);
		$partner_info{$partner}{user} = $self->data->get_management_node_image_lib_user($partner) || 'root';
		$partner_info{$partner}{identity_key} = $self->data->get_management_node_image_lib_key($partner) || '';
		$partner_info{$partner}{port} = $self->data->get_management_node_ssh_port($partner) || '22';
		
		# Call the provisioning module's get_image_repository_search_paths() subroutine
		# This returns an array of strings to pass to du
		my @search_paths = $self->get_image_repository_search_paths($partner);
		if (@search_paths) {
			notify($ERRORS{'DEBUG'}, 0, "retrieved image repository search paths for partner $partner:\n" . join("\n", @search_paths));
			$partner_info{$partner}{search_paths} = \@search_paths;
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to retrieve image repository search paths for partner: $partner");
			next PARTNER;
		}
		
		# Run du to get the size of the image files on the partner if the image exists in any of the search paths
		my $du_command = "du -ba " . join(" ", @{$partner_info{$partner}{search_paths}});
		# Add 2>&1 or else STDOUT and STDERR may get mixed together (See VCL-688)
		$du_command .= " 2>&1";
		my ($du_exit_status, $du_output) = VCL::Module::OS::execute(
			{
				node => $partner,
				command => $du_command,
				display_output => 0,
				timeout => 30,
				max_attempts => 2,
				port => $partner_info{$partner}{port},
				user => $partner_info{$partner}{user},
				identity_key => $partner_info{$partner}{identity_key},
			}
		);
		
		if (!defined($du_output)) {
			notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if image $image_name exists on $partner_info{$partner}{hostname}: $du_command");
			next PARTNER;
		}
		
		# Loop through the du output lines, parse lines beginning with a number followed by a '/'
		LINE: for my $line (@$du_output) {
			my ($file_size, $file_path) = $line =~ /^(\d+)\s+(\/.+)/;
			next if (!defined($file_size) || !defined($file_path));
			
			my ($file_prefix, $directory_path, $file_extension) = fileparse($file_path, qr/\.[^.]*/);
			if (!$file_prefix || !$directory_path || !$file_extension) {
				next LINE;
			}
			
			my $file_name = "$file_prefix$file_extension";
			$partner_info{$partner}{directory_paths}{$directory_path}{file_paths}{$file_path}{file_name} = $file_name;
			$partner_info{$partner}{directory_paths}{$directory_path}{file_paths}{$file_path}{file_size} = $file_size;
			$partner_info{$partner}{directory_paths}{$directory_path}{image_size} += $file_size;
		}
		
		if (!$partner_info{$partner}{directory_paths}) {
			notify($ERRORS{'OK'}, 0, "$image_name does NOT exist on $partner_info{$partner}{hostname}, output:\n" . join("\n", @$du_output));
			next PARTNER;
		}
		
		# Loop through the directories containing image files found on the partner
		# The image may have been found in multiple directories
		my $directory_path;
		DIRECTORY_PATH: for my $check_directory_path (keys %{$partner_info{$partner}{directory_paths}}) {
			if (!$directory_path) {
				$directory_path = $check_directory_path;
				next DIRECTORY_PATH;
			}
			
			my $file_count = scalar(keys %{$partner_info{$partner}{directory_paths}{$directory_path}{file_paths}});
			my $image_size = $partner_info{$partner}{directory_paths}{$directory_path}{image_size};
			my $check_file_count = scalar(keys %{$partner_info{$partner}{directory_paths}{$check_directory_path}{file_paths}});
			my $check_image_size = $partner_info{$partner}{directory_paths}{$check_directory_path}{image_size};
			
			notify($ERRORS{'DEBUG'}, 0, "found $image_name in multiple directories on $partner_info{$partner}{hostname}:\n" .
				"$directory_path: file count: $file_count, image size: $image_size\n" .
				"$check_directory_path: file count: $check_file_count, image size: $check_image_size"
			);
			
			# Compare the file count and image size, use the larger image
			if ($check_image_size > $image_size || $check_file_count > $file_count) {
				$directory_path = $check_directory_path;
			}
		}
		
		# Add the info for the winning directory to the top of the hash
		$partner_info{$partner}{file_paths} = $partner_info{$partner}{directory_paths}{$directory_path}{file_paths};
		$partner_info{$partner}{image_size} = $partner_info{$partner}{directory_paths}{$directory_path}{image_size};
		
		# Display the image size if any files were found
		if ($partner_info{$partner}{image_size}) {
			notify($ERRORS{'OK'}, 0, "$image_name exists on $partner_info{$partner}{hostname}, size: " . format_number($partner_info{$partner}{image_size}) . " bytes");
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "$image_name does NOT exist on $partner_info{$partner}{hostname}");
			next PARTNER;
		}
		
		# Check if the image size is larger than any previously found on other partners
		if ($partner_info{$partner}{image_size} > $largest_partner_image_size) {
			@partners_with_image = ();
		}
		
		# Check if the image size is larger than any previously found on other partners
		if ($partner_info{$partner}{image_size} >= $largest_partner_image_size) {
			push @partners_with_image, $partner;
			$largest_partner_image_size = $partner_info{$partner}{image_size};
		}
	}
	
	# Check if any partner was found
	if (!@partners_with_image) {
		notify($ERRORS{'WARNING'}, 0, "unable to find $image_name on other management nodes");
		return;
	}
	
	notify($ERRORS{'OK'}, 0, "found $image_name on partner management nodes:\n" . join("\n", map { $partner_info{$_}{hostname} } (sort @partners_with_image)));
	
	# Choose a random partner so that the same management node isn't used for most transfers
	my $random_index = int(rand(scalar(@partners_with_image)));
	my $retrieval_partner = $partners_with_image[$random_index];
	my $retrieval_partner_hostname = $partner_info{$retrieval_partner}{hostname};
	
	notify($ERRORS{'OK'}, 0, "selected random retrieval partner: $retrieval_partner_hostname:\n" . format_data($partner_info{$retrieval_partner}));
	
	# Create the directory in the image repository
	my $mkdir_command = "mkdir -pv $image_repository_path_local";
	my ($mkdir_exit_status, $mkdir_output) = run_command($mkdir_command);
	if (!defined($mkdir_output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to run command to create image repository directory: $mkdir_command");
		return;
	}
	
	# Copy each file path to the image repository directory
	my $image_size_total_bytes = $partner_info{$retrieval_partner}{image_size};
	my $image_size_total_gb = format_number(($image_size_total_bytes / 1024 / 1024 / 1024), 1);
	
	my $image_size_retrieved_bytes = 0;
	my $image_size_retrieved_gb = 0.0;
	
	my $file_total_count = scalar(keys %{$partner_info{$retrieval_partner}{file_paths}});
	my $file_retrieved_count = 0;
	
	for my $partner_file_path (sort {lc($a) cmp lc($b)} keys %{$partner_info{$retrieval_partner}{file_paths}}) {
		$file_retrieved_count++;
		my $file_name = $partner_info{$retrieval_partner}{file_paths}{$partner_file_path}{file_name};
		my $local_file_path = "$image_repository_path_local/$file_name";
		
		my $file_size_bytes = $partner_info{$retrieval_partner}{file_paths}{$partner_file_path}{file_size};
		
		notify($ERRORS{'DEBUG'}, 0, "retrieving image file $file_retrieved_count/$file_total_count from $retrieval_partner_hostname: $partner_file_path --> $local_file_path (" . get_file_size_info_string($file_size_bytes) . ')');
		if (run_scp_command("$partner_info{$retrieval_partner}{user}\@$retrieval_partner:$partner_file_path", $local_file_path, $partner_info{$retrieval_partner}{key}, $partner_info{$retrieval_partner}{port})) {
			$image_size_retrieved_bytes += $file_size_bytes;
			$image_size_retrieved_gb = format_number(($image_size_retrieved_bytes / 1024 / 1024 / 1024), 1);
			my $retrieved_percent = format_number(int($image_size_retrieved_bytes / $image_size_total_bytes * 100), 0);			
			notify($ERRORS{'OK'}, 0, "retrieved image file $file_retrieved_count/$file_total_count, $retrieved_percent\% complete, $image_size_retrieved_gb/$image_size_total_gb GB");
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to copy image $image_name from $retrieval_partner_hostname");
			return;
		}
	}
	
	# Make sure image was retrieved
	if (!$self->does_image_exist($image_name)) {
		notify($ERRORS{'WARNING'}, 0, "does_image_exist subroutine returned false for $image_name after it should have been retrieved");
		return;
	}
	
	return 1;
}

#//////////////////////////////////////////////////////////////////////////////

=head2 wait_for_power_off

 Parameters  : Maximum number of seconds to wait (optional), seconds to delay between attempts (optional)
 Returns     : 1 - If computer is powered off
               0 - If computer is still powered on after waiting
               undefined - Unable to determine power status
 Description : Attempts to check the power status of the computer specified in
               the DataStructure for the current reservation. It will wait up to
               a maximum number of seconds for the computer to be powered off
               (default: 300 seconds). The delay between attempts can be
               specified as the 2nd argument in seconds (default: 15 seconds).

=cut

sub wait_for_power_off {
	my $self = shift;
	if (ref($self) !~ /VCL::Module/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}
	
	# Attempt to get the total number of seconds to wait from the arguments
	my $total_wait_seconds = shift;
	if (!defined($total_wait_seconds) || $total_wait_seconds !~ /^\d+$/) {
		$total_wait_seconds = 300;
	}
	
	# Seconds to wait in between loop attempts
	my $attempt_delay_seconds = shift;
	if (!defined($attempt_delay_seconds) || $attempt_delay_seconds !~ /^\d+$/) {
		$attempt_delay_seconds = 15;
	}
	
	# Check if the provisioning module implements a power status subroutine
	if (!$self->can('power_status')) {
		notify($ERRORS{'WARNING'}, 0, "power_status subroutine has not been implemented by the provisioning module: " . ref($self));
		return;
	}
	
	my $computer_name = $self->data->get_computer_short_name();
	
	my $message = "waiting a maximum of $total_wait_seconds for $computer_name to be powered off";
	
	# Call code_loop_timeout and invert the result
	my $code_loop_result = $self->code_loop_timeout(
		sub{
			my $power_status = $self->power_status();
			if (!defined($power_status)) {
				return;
			}
			elsif ($power_status =~ /off/i) {
				return 1;
			}
			else {
				return 0;
			}
		},
		[$computer_name],
		"waiting for $computer_name to power off",
		$total_wait_seconds,
		$attempt_delay_seconds
	);
	
	if (!defined($code_loop_result)) {
		notify($ERRORS{'WARNING'}, 0, "failed to determine power status of $computer_name, returning undefined");
		return;
	}
	elsif ($code_loop_result) {
		return 1;
	}
	else {
		notify($ERRORS{'WARNING'}, 0, "$computer_name has not powered off after waiting $total_wait_seconds seconds, returning 0");
		return 0;
	}
}

#//////////////////////////////////////////////////////////////////////////////

1;
__END__

=head1 SEE ALSO

L<http://cwiki.apache.org/VCL/>

=cut
