#!/usr/bin/perl
# 
# This renames a server (and the DRBD resources and LVs below it). Given the nature of this program, it runs 
# on the node directly, and SSH's into the peer(s) to update the DRBD config files and rename LVs. Normally,
# this should run on Node 1. 
# 
# Exit codes;
# 0 = Normal exit.
# 1 = Any problem that causes an early exit.
# 
# TODO: 
# 

use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;

my $THIS_FILE           =  ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory   =  ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
	$running_directory =~ s/^\./$ENV{PWD}/;
}

# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
$| = 1;

my $anvil = Anvil::Tools->new();

# Get switches
$anvil->Get->switches({list => [
	"confirm",
	"job-uuid",
	"new-name",
	"server", 
	"server-uuid"
], man => $THIS_FILE});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});

$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
	# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try 
	# again after we exit.
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0075"});
	sleep 10;
	$anvil->nice_exit({exit_code => 1});
}

# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{
	# Load the job data.
	$anvil->Job->clear();
	$anvil->Job->get_job_details();
	$anvil->Job->update_progress({
		progress         => 1,
		job_picked_up_by => $$, 
		job_picked_up_at => time, 
		message          => "message_0234", 
	});
	
	# Pull out the job data.
	foreach my $line (split/\n/, $anvil->data->{jobs}{job_data})
	{
		if ($line =~ /server=(.*?)$/)
		{
			$anvil->data->{switches}{'server'} = $1;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				'switches::server' => $anvil->data->{switches}{'server'},
			}});
		}
		if ($line =~ /server-uuid=(.*?)$/)
		{
			$anvil->data->{switches}{'server-uuid'} = $1;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				'switches::server-uuid' => $anvil->data->{switches}{'server-uuid'},
			}});
		}
		if ($line =~ /new-name=(.*?)$/)
		{
			$anvil->data->{switches}{'new-name'} = $1;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				'switches::new-name' => $anvil->data->{switches}{'new-name'},
			}});
		}
	}
}

# Make sure we're in an Anvil!
$anvil->data->{sys}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid();
if (not $anvil->data->{sys}{anvil_uuid})
{
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0260"});
	$anvil->Job->update_progress({progress => 100, message => "error_0260"});
	$anvil->nice_exit({exit_code => 1});
}

# Now check that we have a server. If it's a server_uuid, read the server name.
$anvil->Database->get_servers();
if ($anvil->data->{switches}{'server-uuid'})
{
	# Convert the server_uuid to a server_name.
	my $server_uuid = $anvil->data->{switches}{'server-uuid'};
	if (not exists $anvil->data->{servers}{server_uuid}{$server_uuid})
	{
		# Invalid server UUID. 
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0269", variables => {
			server_uuid => $anvil->data->{switches}{'server-uuid'}, 
		}});
		$anvil->Job->update_progress({progress => 100, message => "error_0269,!!server_uuid!".$anvil->data->{switches}{'server-uuid'}."!!"});
		$anvil->nice_exit({exit_code => 1});
	}
	
	$anvil->data->{switches}{'server'} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name};
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		'switches::server' => $anvil->data->{switches}{'server'},
	}});
}

# Do we have a server name?
if (not $anvil->data->{switches}{'server'})
{
	# Unable to proceed.
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0276"});
	$anvil->Job->update_progress({progress => 100, message => "error_0276"});
	$anvil->nice_exit({exit_code => 1});
}

# Do we have a new server name?
if (not $anvil->data->{switches}{'new-name'})
{
	# Unable to proceed.
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0279"});
	$anvil->Job->update_progress({progress => 100, message => "error_0279"});
	$anvil->nice_exit({exit_code => 1});
}

# Make sure there are no spaces in the name
$anvil->data->{switches}{'new-name'} =~ s/^\s+//;
$anvil->data->{switches}{'new-name'} =~ s/\s$//;
if ($anvil->data->{switches}{'new-name'} =~ /\s/)
{
	# Bad new server name
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0280", variables => {
		new_name => $anvil->data->{switches}{'new-name'}, 
	}});
	$anvil->Job->update_progress({progress => 100, message => "error_0280,!!new_name!".$anvil->data->{switches}{'new-name'}."!!"});
	$anvil->nice_exit({exit_code => 1});
}

# Make sure the new name isn't in use.
my $anvil_uuid      = $anvil->data->{sys}{anvil_uuid};
my $new_server_name = $anvil->data->{switches}{'new-name'};
if (exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$new_server_name})
{
	# Conflicting server name
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0289", variables => { server => $new_server_name }});
	$anvil->Job->update_progress({progress => 100, message => "error_0289,!!server!".$new_server_name."!!"});
	$anvil->nice_exit({exit_code => 1});
}

# We're going to need a server UUID. If we don't have it, find it from the current name.
if (not $anvil->data->{switches}{'server-uuid'})
{
	# Convert the server name to a server_uuid.
	my $server_name = $anvil->data->{switches}{'server'};
	if (not exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name})
	{
		# Invalid server UUID. 
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0277", variables => { server => $server_name }});
		$anvil->Job->update_progress({progress => 100, message => "error_0277,!!server!".$server_name."!!"});
		$anvil->nice_exit({exit_code => 1});
	}
	
	$anvil->data->{switches}{'server-uuid'} = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid};
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		'switches::server-uuid' => $anvil->data->{switches}{'server-uuid'},
	}});
}

# Are we a node?
$anvil->data->{sys}{host_type} = $anvil->Get->host_type();
if ($anvil->data->{sys}{host_type} ne "node")
{
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0264"});
	$anvil->Job->update_progress({progress => 100, message => "error_0264"});
	$anvil->nice_exit({exit_code => 1});
}

# If we don't have a job_uuid and the user didn't pass 'confirm', ask to proceed.
if ((not $anvil->data->{switches}{'job-uuid'}) && (not $anvil->data->{switches}{'confirm'}))
{
	print $anvil->Words->string({key => "message_0094", variables => { 
		server_name => $anvil->data->{switches}{'server'},
		new_name    => $new_server_name, 
	}})." ";
	my $answer = <STDIN>;
	chomp($answer);
	if (($answer ne "y") && ($answer ne "Y"))
	{
		# Abort and exit.
		print $anvil->Words->string({key => "message_0061"})."\n";
		$anvil->nice_exit({exit_code => 0});
	}
}

# This is copied from anvil-boot-server, but it works here as well. We can't use 'pcs' without pacemaker 
# being up.
wait_for_pacemaker($anvil);

# Now we're ready.
gather_server_data($anvil);

# Verify that the server is off everywhere.
verify_server_is_off($anvil);

# Now start renaming things.
rename_server($anvil);

$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0281"});
$anvil->Job->update_progress({progress => 100, message => "job_0281"});

$anvil->nice_exit({exit_code => 0});


#############################################################################################################
# Functions                                                                                                 #
#############################################################################################################

# This does the actual rename. It removes the resource from the cluster, makes sure the DRBD resource is down
# on all machines, renames the XML definition file
sub rename_server
{
	my ($anvil) = @_;
	
	# Delete the server from pacemaker
	my $old_server_name = $anvil->data->{switches}{'server'};
	my $new_server_name = $anvil->data->{switches}{'new-name'};
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		old_server_name => $old_server_name,
		new_server_name => $new_server_name,
	}});
	
	### NOTE: From this point on, failing out is a bad idea. Anything going wrong here wil mean the 
	###       server could become inaccessible. As such, any errors need to be very verbose.
	my $old_definition_file    = $anvil->data->{path}{directories}{shared}{definitions}."/".$old_server_name.".xml";
	my $new_definition_file    = $anvil->data->{path}{directories}{shared}{definitions}."/".$new_server_name.".xml";
	my $old_drbd_resource_file = $anvil->data->{path}{directories}{drbd_resources}."/".$old_server_name.".res";
	my $new_drbd_resource_file = $anvil->data->{path}{directories}{drbd_resources}."/".$new_server_name.".res";
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		old_definition_file    => $old_definition_file,
		new_definition_file    => $new_definition_file, 
		old_drbd_resource_file => $old_drbd_resource_file, 
		new_drbd_resource_file => $new_drbd_resource_file, 
	}});
	
	my $progress = 40;
	# Log into the peer(s) and rename the LV, the rename our own LV.
	foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}})
	{
		my $peer_ip  = $anvil->data->{rename_server}{host}{$host_name}{is_peer} ? $anvil->data->{rename_server}{host}{$host_name}{use_ip}   : "";
		my $password = $anvil->data->{rename_server}{host}{$host_name}{is_peer} ? $anvil->data->{rename_server}{host}{$host_name}{password} : "";
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			peer_ip  => $peer_ip,
			password => $anvil->Log->is_secure($password), 
		}});
		
		# Read the old DRBD resource file.
		my $old_drbd_resource_body = $anvil->Storage->read_file({
			cache       => 0, 
			file        => $old_drbd_resource_file,
			force_read  => 1, 
			password    => $password, 
			target      => $peer_ip,
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_drbd_resource_body => $old_drbd_resource_body }});
		if ($old_drbd_resource_body eq "!!error!!")
		{
			# Failed to read the file. Could we have already written the file?
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0282", variables => { 
				file => $old_drbd_resource_file, 
				host => $host_name, 
			}});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "error_0282,!!file!".$old_drbd_resource_file."!!,!!host!".$host_name."!!"});
			$old_drbd_resource_body = $anvil->Storage->read_file({
				cache       => 0, 
				file        => $new_drbd_resource_file,
				force_read  => 1, 
				password    => $password, 
				target      => $peer_ip,
			});
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_drbd_resource_body => $old_drbd_resource_body }});
			if ($old_drbd_resource_body eq "!!error!!")
			{
				# No luck there, either.
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0282", variables => { 
					file => $new_drbd_resource_file, 
					host => $host_name, 
				}});
				$anvil->Job->update_progress({progress => 100, message => "error_0282,!!file!".$new_drbd_resource_file."!!,!!host!".$host_name."!!"});
				$anvil->nice_exit({exit_code => 1});
			}
		}
		
		# Read the old definition file.
		my $old_definition_body = $anvil->Storage->read_file({
			cache       => 0, 
			file        => $old_definition_file,
			force_read  => 1, 
			password    => $password, 
			target      => $peer_ip,
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_definition_body => $old_definition_body }});
		if ($old_definition_body eq "!!error!!")
		{
			# Failed to read the file. Could we have already written the file?
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0282", variables => { 
				file => $old_definition_file, 
				host => $host_name, 
			}});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "error_0282,!!file!".$old_definition_file."!!,!!host!".$host_name."!!"});
			$old_definition_body = $anvil->Storage->read_file({
				cache       => 0, 
				file        => $new_definition_file,
				force_read  => 1, 
				password    => $password, 
				target      => $peer_ip,
			});
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_definition_body => $old_definition_body }});
			if ($old_definition_body eq "!!error!!")
			{
				# No luck there, either.
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0282", variables => { 
					file => $new_definition_file, 
					host => $host_name, 
				}});
				$anvil->Job->update_progress({progress => 100, message => "error_0282,!!file!".$new_definition_file."!!,!!host!".$host_name."!!"});
				$anvil->nice_exit({exit_code => 1});
			}
		}
		
		# Loop through the volumes and update the new definition and resource file bodies.
		my $new_drbd_resource_body = $old_drbd_resource_body;
		my $new_definition_body    = $old_definition_body;
		foreach my $volume (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}{$host_name}{volume}})
		{
			my $old_device_path  = $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_device_path};
			my $new_device_path  = $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_device_path};
			my $old_backing_disk = $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_backing_disk};
			my $new_backing_disk = $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_backing_disk};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				old_device_path  => $old_device_path, 
				new_device_path  => $new_device_path, 
				old_backing_disk => $old_backing_disk, 
				new_backing_disk => $new_backing_disk, 
			}});
			
			$new_drbd_resource_body =~ s/$old_device_path/$new_device_path/sg;
			$new_drbd_resource_body =~ s/$old_backing_disk/$new_backing_disk/sg;
			$new_drbd_resource_body =~ s/$old_server_name/$new_server_name/sg;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_drbd_resource_body => $new_drbd_resource_body }});
			
			$new_definition_body =~ s/$old_device_path/$new_device_path/sg;
			$new_definition_body =~ s/$old_backing_disk/$new_backing_disk/sg;
			$new_definition_body =~ s/$old_server_name/$new_server_name/sg;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition_body => $new_definition_body }});
			
			# Rename the LV, if needed.
			my $shell_call = $anvil->data->{path}{exe}{lvdisplay}." ".$old_backing_disk;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
			
			my $output      = "";
			my $return_code = "";
			if ($anvil->data->{rename_server}{host}{$host_name}{is_peer})
			{
				# Remote call
				($output, my $error, $return_code) = $anvil->Remote->call({
					debug      => 2, 
					shell_call => $shell_call, 
					target     => $peer_ip,
					password   => $password,
				});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					error       => $error,
					output      => $output,
					return_code => $return_code,
				}});
			}
			else
			{
				($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					output      => $output,
					return_code => $return_code, 
				}});
			}
			if (not $return_code)
			{
				# Old LV exists, rename
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0305", variables => { 
					host_name => $host_name, 
					old_lv    => $old_backing_disk, 
					new_lv    => $new_backing_disk, 
				}});
				$progress += 3 if $progress < 90;
				$anvil->Job->update_progress({progress => $progress, message => "job_0305,!!host_name!".$host_name."!!,!!old_lv!".$old_backing_disk."!!,!!new_lv!".$new_backing_disk."!!"});
				
				my $shell_call = $anvil->data->{path}{exe}{lvrename}." --autobackup y --yes ".$old_backing_disk." ".$new_backing_disk;
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
				
				# We don't verify the LV create here, we'll check it below.
				if ($anvil->data->{rename_server}{host}{$host_name}{is_peer})
				{
					# Remote call
					my ($output, $error, $return_code) = $anvil->Remote->call({
						debug      => 2, 
						shell_call => $shell_call, 
						target     => $peer_ip,
						password   => $password,
					});
					$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
						error       => $error,
						output      => $output,
						return_code => $return_code,
					}});
				}
				else
				{
					my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
					$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
						output      => $output,
						return_code => $return_code, 
					}});
				}
			}
			
			# Verify the new LV exists.
			$output      = "";
			$return_code = "";
			$shell_call  = $anvil->data->{path}{exe}{lvdisplay}." ".$new_backing_disk;
			if ($anvil->data->{rename_server}{host}{$host_name}{is_peer})
			{
				# Remote call
				($output, my $error, $return_code) = $anvil->Remote->call({
					debug      => 2, 
					shell_call => $shell_call, 
					target     => $peer_ip,
					password   => $password,
				});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					error       => $error,
					output      => $output,
					return_code => $return_code,
				}});
			}
			else
			{
				($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					output      => $output,
					return_code => $return_code, 
				}});
			}
			if ($return_code)
			{
				# Something went wrong.
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0283", variables => { 
					old_lv    => $old_backing_disk,
					new_lv    => $new_backing_disk,  
					host_name => $host_name, 
				}});
				$anvil->Job->update_progress({progress => 100, message => "error_0283,!!host_name!".$host_name."!!,!!old_lv!".$old_backing_disk."!!,!!new_lv!".$new_backing_disk."!!"});
				$anvil->nice_exit({exit_code => 1});
			}
			else
			{
				# Success
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0306", variables => { 
					host_name => $host_name, 
					new_lv    => $new_backing_disk, 
				}});
				$progress += 3 if $progress < 90;
				$anvil->Job->update_progress({progress => $progress, message => "job_0306,!!host_name!".$host_name."!!,!!new_lv!".$new_backing_disk."!!"});
			}
		}
		
		# Write out the new DRBD resource files.
		my ($problem) = $anvil->Storage->write_file({
			debug     => 2,
			backup    => 1, 
			overwrite => 1,
			body      => $new_drbd_resource_body, 
			file      => $new_drbd_resource_file,
			group     => "root", 
			user      => "root",
			mode      => "0644",
			password  => $password, 
			target    => $peer_ip,
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
		if ($problem)
		{
			# Failed. Details of why will already be in the logs. 
			$anvil->Job->update_progress({progress => 100, message => "error_0287,!!target!".$host_name."!!,!!file!".$new_drbd_resource_file."!!"});
			$anvil->nice_exit({exit_code => 1});
		}
		else
		{
			# Success
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0307", variables => { 
				host_name => $host_name, 
				file      => $new_drbd_resource_file, 
			}});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "job_0307,!!host_name!".$host_name."!!,!!file!".$new_drbd_resource_file."!!"});
			
			# Delete the old file.
			my ($problem) = $anvil->Storage->delete_file({
				debug    => 2,
				file     => $old_drbd_resource_file,
				password => $password, 
				target   => $peer_ip,
			});
			if ($problem)
			{
				# Details of why will be in the logs.
				$anvil->Job->update_progress({progress => 100, message => "error_0285,!!target!".$host_name."!!,!!file!".$old_drbd_resource_file."!!"});
				$anvil->nice_exit({exit_code => 1});
			}
		}
		
		# Write out the new definition files.
		undef $problem;
		($problem) = $anvil->Storage->write_file({
			debug     => 2,
			backup    => 1, 
			overwrite => 1,
			body      => $new_definition_body, 
			file      => $new_definition_file,
			group     => "root", 
			user      => "root",
			mode      => "0644",
			password  => $password, 
			target    => $peer_ip,
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
		if ($problem)
		{
			# Failed. Details of why will already be in the logs. 
			$anvil->Job->update_progress({progress => 100, message => "error_0287,!!target!".$host_name."!!,!!file!".$new_definition_file."!!"});
			$anvil->nice_exit({exit_code => 1});
		}
		else
		{
			# Success
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0307", variables => { 
				host_name => $host_name, 
				file      => $new_definition_file, 
			}});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "job_0307,!!host_name!".$host_name."!!,!!file!".$new_definition_file."!!"});
			
			# Delete the old file.
			my ($problem) = $anvil->Storage->delete_file({
				debug    => 2,
				file     => $old_definition_file,
				password => $password, 
				target   => $peer_ip,
			});
			if ($problem)
			{
				# Details of why will be in the logs.
				$anvil->Job->update_progress({progress => 100, message => "error_0285,!!target!".$host_name."!!,!!file!".$old_definition_file."!!"});
				$anvil->nice_exit({exit_code => 1});
			}
		}
			
		# Now make sure the DRBD resource is down on all machines.
		my $short_host_name = $anvil->Get->short_host_name();
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_host_name => $short_host_name }});
		
		# Parse the definition file so we can tell if we need --nvram
		$problem = $anvil->Server->parse_definition({
			debug      => 2,
			server     => $new_server_name, 
			source     => "from_disk",
			definition => $new_definition_body, 
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
		
		# Make a 'virsh undefine <server>' just in case the old name is still defined. We don't care 
		# if this succeeds or fails as the server should not be defined anyway.
		my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." undefine ".$old_server_name;
		if ($anvil->data->{server}{$short_host_name}{$new_server_name}{from_disk}{nvram}{data})
		{
			$shell_call .= " --nvram";
		}
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
		
		my $output      = "";
		my $return_code = "";
		if ($anvil->data->{rename_server}{host}{$host_name}{is_peer})
		{
			# Remote call
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0310", variables => { 
				host_name   => $host_name,
				server_name => $old_server_name,
			}});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "job_0310,!!host_name!".$host_name."!!,!!server_name!".$old_server_name."!!"});
			($output, my $error, $return_code) = $anvil->Remote->call({
				debug      => 2, 
				shell_call => $shell_call, 
				target     => $peer_ip,
				password   => $password,
			});
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				error       => $error,
				output      => $output,
				return_code => $return_code,
			}});
		}
		else
		{
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0309", variables => { server_name => $old_server_name }});
			$progress += 3 if $progress < 90;
			$anvil->Job->update_progress({progress => $progress, message => "job_0309,!!server_name!".$old_server_name."!!"});
			($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				output      => $output,
				return_code => $return_code, 
			}});
		}
	}
	
	# What node does this server prefer?
	my $preferred_host_string = "prefers";
	foreach my $node (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{data}{location_constraint}{$old_server_name}{node}})
	{
		my $score = $anvil->data->{cib}{parsed}{data}{location_constraint}{$old_server_name}{node}{$node}{score};
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			"s1:node"  => $node,
			"s2:score" => $score,
		}});
		$preferred_host_string .= " ".$node."=".$score;
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { preferred_host_string => $preferred_host_string }});
	}
	
	# Delete the old server from pacemaker.
	my ($output, $return_code) = $anvil->System->call({debug => 2, shell_call => $anvil->data->{path}{exe}{pcs}." resource delete ".$old_server_name});
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		output      => $output,
		return_code => $return_code, 
	}});
	if (not $return_code)
	{
		# Success!
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0587", variables => { server_name => $old_server_name }});
		$anvil->Job->update_progress({progress => 90, message => "job_0304,!!server_name!".$old_server_name."!!"});
	}
	else
	{
		# Unexpected return code, bail out.
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => 'err', key => "error_0226", variables => { 
			server_name => $old_server_name,
			return_code => $return_code, 
			output      => $output, 
		}});
		$anvil->Job->update_progress({progress => 100, message => "job_0304,!!server_name!".$old_server_name."!!,!!return_code!".$return_code."!!,!!output!".$output."!!"});
		$anvil->nice_exit({exit_code => 1});
	}
	
	# Add the server back to pacemaker 
	my $resource_command = $anvil->data->{path}{exe}{pcs}." resource create ".$new_server_name." ocf:alteeve:server name=\"".$new_server_name."\" meta allow-migrate=\"true\" target-role=\"stopped\" op monitor interval=\"60\" start timeout=\"300\" on-fail=\"block\" stop timeout=\"86400\" on-fail=\"block\" migrate_to timeout=\"86400\"";
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { resource_command => $resource_command }});

	$output      = "";
	$return_code = "";
	($output, $return_code) = $anvil->System->call({shell_call => $resource_command});
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		output      => $output,
		return_code => $return_code, 
	}});
	if ($return_code)
	{
		# Failed.
		$anvil->Job->update_progress({progress => 100, message => "error_0288,!!server_name!".$new_server_name."!!,!!return_code!".$return_code."!!,!!output!".$output."!!"});
		$anvil->nice_exit({exit_code => 1});
	}
	else
	{
		# Success
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0308", variables => { server_name => $new_server_name }});
		$anvil->Job->update_progress({progress => 93, message => "job_0308,!!server_name!".$old_server_name."!!"});
	}
	
	# Set the preferred host
	my $prefer_command = $anvil->data->{path}{exe}{pcs}." constraint location ".$new_server_name." ".$preferred_host_string;
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { prefer_command => $prefer_command }});

	$output      = "";
	$return_code = "";
	($output, $return_code) = $anvil->System->call({shell_call => $prefer_command});
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		output      => $output,
		return_code => $return_code, 
	}});
	if ($return_code)
	{
		# Failed, but don't fail out.
		$anvil->Job->update_progress({progress => 100, message => "error_0304,!!server_name!".$new_server_name."!!,!!return_code!".$return_code."!!,!!output!".$output."!!"});
	}
	else
	{
		# Success
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0005", variables => { server_name => $new_server_name }});
		$anvil->Job->update_progress({progress => 96, message => "job_0005,!!server_name!".$old_server_name."!!"});
	}
	
	# Rename the server in the database.
	my $query = "
UPDATE 
    servers 
SET 
    server_name   = ".$anvil->Database->quote($new_server_name).", 
    modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." 
WHERE 
    server_uuid   = ".$anvil->Database->quote($anvil->data->{switches}{'server-uuid'})."
;";
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0123", variables => { query => $query }});
	$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
	
	# Update the variables -> variable_name - "server::<old_name>::stay-off" if it exists.
	$query = "
SELECT 
    variable_uuid, 
    variable_name 
FROM 
    variables 
WHERE 
    variable_source_table = 'servers' 
AND 
    variable_source_uuid = '86a39e25-c61d-486c-b840-c4a91cd17706' 
AND 
    variable_name LIKE '%::stay-off'
;";
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
	my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
	my $count   = @{$results};
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
		results => $results, 
		count   => $count, 
	}});
	if ($count)
	{
		my $variable_uuid = $results->[0]->[0];
		my $variable_name = $results->[0]->[1];
		my $stay_off_key  = "server::".$new_server_name."::stay-off";
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			's1:variable_uuid' => $variable_uuid, 
			's2:variable_name' => $variable_name, 
			's3:stay_off_key'  => $stay_off_key,
		}});
		
		if ($variable_name ne $stay_off_key)
		{
			my $query = "
UPDATE 
    variables 
SET 
    variable_name = ".$anvil->Database->quote($stay_off_key).", 
    modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." 
WHERE 
    variable_uuid = ".$anvil->Database->quote($variable_uuid)."
;";
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0123", variables => { query => $query }});
			$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
		}
	}

	# Done!
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0311", variables => { server_name => $new_server_name }});
	$anvil->Job->update_progress({progress => 99, message => "job_0311,!!server_name!".$old_server_name."!!"});
	
	return(0);
}

# Calls virsh locally and on peer(s) to ensure that the server is not running. 
sub verify_server_is_off
{
	my ($anvil) = @_;
	
	# Is the server running from pacemaker's perspective?
	my $waiting         = 1;
	my $old_server_name = $anvil->data->{switches}{'server'};
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_server_name => $old_server_name }});
	while ($waiting)
	{
		$waiting = 0;
		$anvil->Cluster->parse_cib({debug => 2});
		if (not exists $anvil->data->{cib}{parsed}{data}{server}{$old_server_name})
		{
			# Server wasn't found in the cluster config. Wat?!
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0281"});
			$anvil->Job->update_progress({progress => 100, message => "error_0281"});
			$anvil->nice_exit({exit_code => 1});
		}
		
		my $status    = $anvil->data->{cib}{parsed}{data}{server}{$old_server_name}{status};
		my $host_name = $anvil->data->{cib}{parsed}{data}{server}{$old_server_name}{host_name};
		my $role      = $anvil->data->{cib}{parsed}{data}{server}{$old_server_name}{role};
		my $active    = $anvil->data->{cib}{parsed}{data}{server}{$old_server_name}{active};
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			's1:old_server_name' => $old_server_name,
			's2:status'          => $status,
			's2:host_name'       => $host_name,
			's4:role'            => $role,
			's5:active'          => $active, 
		}});
		
		if ($status ne "off")
		{
			$waiting = 1;
			
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0299", variables => { 
				server => $old_server_name,
				status => $status,
			}});
			$anvil->Job->update_progress({progress => 22, message => "job_0299,!!server!".$old_server_name."!!,!!status!".$status."!!"});
			sleep 10;
		}
	}
	
	# Now check virsh.
	$waiting = 1;
	while ($waiting)
	{
		$waiting = 0;
		$anvil->Server->find({refresh => 1});
		foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}})
		{
			next if $anvil->data->{rename_server}{host}{$host_name}{is_peer};
			my $peer_ip  = $anvil->data->{rename_server}{host}{$host_name}{use_ip};
			my $password = $anvil->data->{rename_server}{host}{$host_name}{password};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				peer_ip  => $peer_ip,
				password => $anvil->Log->is_secure($password), 
			}});
			$anvil->Server->find({
				refresh  => 0,
				target   => $peer_ip,
				password => $password, 
			});
		}
		if ((exists $anvil->data->{server}{location}{$old_server_name}) && ($anvil->data->{server}{location}{$old_server_name}{status} ne "shut off"))
		{
			my $status = $anvil->data->{server}{location}{$old_server_name}{status};
			my $host   = $anvil->data->{server}{location}{$old_server_name}{host_name};
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0299", variables => { 
				server => $old_server_name,
				status => $status,
				host   => $host,
			}});
			$anvil->Job->update_progress({progress => 26, message => "job_0299,!!server!".$old_server_name."!!,!!status!".$status."!!,!!host!".$host."!!"});
			sleep 10;
		}
	}
	
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0300", variables => { server => $old_server_name }});
	$anvil->Job->update_progress({progress => 28, message => "job_0300,!!server!".$old_server_name."!!"});
	
	# Now make sure the DRBD resource is down on all machines.
	my $short_host_name = $anvil->Get->short_host_name();
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_host_name => $short_host_name }});
	
	# Wait until the resource is not sync'ing (if it is at all).
	$waiting = 1;
	while ($waiting)
	{
		# (Re)fresh my view of the storage.
		$waiting = 0;
		$anvil->DRBD->get_status({debug => 2});
		foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}})
		{
			next if not $anvil->data->{rename_server}{host}{$host_name}{is_peer};
			my $peer_ip  = $anvil->data->{rename_server}{host}{$host_name}{use_ip};
			my $password = $anvil->data->{rename_server}{host}{$host_name}{password};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				peer_ip  => $peer_ip,
				password => $anvil->Log->is_secure($password), 
			}});
			$anvil->DRBD->get_status({
				debug    => 2,
				target   => $peer_ip,
				password => $password,
			});
		}
		
		# Now check to see if anything is sync'ing.
		foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{drbd}{status}})
		{
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				's1:old_server_name' => $old_server_name, 
				's2:host_name'       => $host_name,
			}});
			next if not exists $anvil->data->{drbd}{status}{$host_name}{resource}{$old_server_name};
			
			foreach my $peer_name (sort {$a cmp $b} keys %{$anvil->data->{drbd}{status}{$host_name}{resource}{$old_server_name}{connection}})
			{
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_name => $peer_name }});
				foreach my $volume (sort {$a cmp $b} %{$anvil->data->{drbd}{status}{$host_name}{resource}{$old_server_name}{connection}{$peer_name}{volume}})
				{
					next if not exists $anvil->data->{drbd}{status}{$host_name}{resource}{$old_server_name}{connection}{$peer_name}{volume}{$volume}{'replication-state'};
					my $replication_state = $anvil->data->{drbd}{status}{$host_name}{resource}{$old_server_name}{connection}{$peer_name}{volume}{$volume}{'replication-state'};
					$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
						volume            => $volume,
						replication_state => $replication_state, 
					}});
					
					if ($replication_state =~ /Sync/i)
					{
						$waiting = 1;
						$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
						
						$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0301", variables => { 
							source_host       => $host_name,
							peer_host         => $peer_name,
							resource          => $old_server_name,
							volume            => $volume,
							replication_state => $replication_state, 
						}});
						$anvil->Job->update_progress({progress => 30, message => "job_0301,!!source_host!".$host_name."!!,!!peer_host!".$peer_name."!!,!!resource!".$old_server_name."!!,!!volume!".$volume."!!,!!replication_state!".$replication_state."!!"});
					}
				}
			}
		}
		if ($waiting)
		{
			sleep 10;
		}
	}
	
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0302"});
	$anvil->Job->update_progress({progress => 33, message => "job_0302"});
	
	# Shut down the peers first
	foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}})
	{
		next if not $anvil->data->{rename_server}{host}{$host_name}{is_peer};
		my $peer_ip = $anvil->data->{rename_server}{host}{$host_name}{use_ip};
		my $password = $anvil->data->{rename_server}{host}{$host_name}{password};
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			peer_ip  => $peer_ip,
			password => $anvil->Log->is_secure($password), 
		}});
		$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0303", variables => { 
			peer     => $host_name, 
			resource => $old_server_name, 
			ip       => $peer_ip,
		}});
		$anvil->Job->update_progress({progress => 35, message => "job_0303,!!peer!".$host_name."!!,!!resource!".$old_server_name."!!,!!ip!".$peer_ip."!!"});
		$anvil->DRBD->manage_resource({
			debug    => 2,
			resource => $old_server_name,
			task     => "down",
			target   => $peer_ip,
			password => $password,
		});
	}
	$anvil->DRBD->manage_resource({
		debug    => 2,
		resource => $old_server_name,
		task     => "down",
	});
	
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0304"});
	$anvil->Job->update_progress({progress => 38, message => "job_0304"});
	
	return(0);
}

# This figures out the names of the definition and DRBD resource files, LV names and other details that will
# be needed to rename the server. This will abort if anything seems wrong.
sub gather_server_data
{
	my ($anvil) = @_;
	
	my $old_server_name = $anvil->data->{switches}{'server'};
	my $new_server_name = $anvil->data->{switches}{'new-name'};
	
	# Parse the DRBD resource file to see if we have a DR target for this server.
	$anvil->DRBD->gather_data({debug => 2});
	$anvil->Database->get_hosts();
	
	# We'll store our name for finding matches later.
	my $local_drbd_node_name = "";
	
	foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{new}{resource}{$old_server_name}{host}})
	{
		my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $host_name});
		my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
		my $peer      = $host_uuid eq $anvil->Get->host_uuid ? 0 : 1;
		$anvil->data->{rename_server}{host}{$host_name}{host_uuid} = $host_uuid;
		$anvil->data->{rename_server}{host}{$host_name}{host_type} = $host_type;
		$anvil->data->{rename_server}{host}{$host_name}{is_peer}   = $peer;
		$anvil->data->{rename_server}{host}{$host_name}{use_ip}    = "";
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			"rename_server::host::${host_name}::host_uuid" => $anvil->data->{rename_server}{host}{$host_name}{host_uuid}, 
			"rename_server::host::${host_name}::host_type" => $anvil->data->{rename_server}{host}{$host_name}{host_type}, 
			"rename_server::host::${host_name}::is_peer"   => $anvil->data->{rename_server}{host}{$host_name}{is_peer}, 
		}});
		
		if (not $peer)
		{
			$local_drbd_node_name = $host_name;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { local_drbd_node_name => $local_drbd_node_name }});
			$anvil->Network->load_ips({
				host      => $local_drbd_node_name, 
				host_uuid => $host_uuid, 
			});
		}
		
		foreach my $volume (sort {$a cmp $b} keys %{$anvil->data->{new}{resource}{$old_server_name}{host}{$host_name}{volume}})
		{
			my $old_device_path  =  $anvil->data->{new}{resource}{$old_server_name}{host}{$host_name}{volume}{$volume}{device_path};
			my $new_device_path  =  $old_device_path;
			   $new_device_path  =~ s/$old_server_name/$new_server_name/g;
			my $old_backing_disk =  $anvil->data->{new}{resource}{$old_server_name}{host}{$host_name}{volume}{$volume}{backing_disk};
			my $new_backing_disk =  $old_backing_disk;
			   $new_backing_disk =~ s/$old_server_name/$new_server_name/g;
			$anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_device_path}  = $old_device_path;
			$anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_device_path}  = $new_device_path;
			$anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_backing_disk} = $old_backing_disk;
			$anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_backing_disk} = $new_backing_disk;
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				"rename_server::host::${host_name}::volume::${volume}::old_device_path"  => $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_device_path}, 
				"rename_server::host::${host_name}::volume::${volume}::new_device_path"  => $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_device_path}, 
				"rename_server::host::${host_name}::volume::${volume}::old_backing_disk" => $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{old_backing_disk}, 
				"rename_server::host::${host_name}::volume::${volume}::new_backing_disk" => $anvil->data->{rename_server}{host}{$host_name}{volume}{$volume}{new_backing_disk}, 
			}});
		}
	}
	
	# Make sure we can talk to peers.
	my $waiting = 1;
	while($waiting)
	{
		$waiting = 0;
		foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{rename_server}{host}})
		{
			next if not $anvil->data->{rename_server}{host}{$host_name}{is_peer};
			my $host_uuid  = $anvil->data->{rename_server}{host}{$host_name}{host_uuid};
			my $anvil_uuid = $anvil->data->{sys}{anvil_uuid};
			my $password   = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				host_name  => $host_name, 
				host_uuid  => $host_uuid, 
				anvil_uuid => $anvil_uuid, 
				password   => $anvil->Log->is_secure($password), 
			}});
			
			$anvil->Network->load_ips({
				host      => $host_name, 
				host_uuid => $host_uuid, 
			});
			
			my $peer_ip = "";
			my ($match)  = $anvil->Network->find_matches({
				debug  => 2,
				first  => $local_drbd_node_name,
				second => $host_name, 
				source => $THIS_FILE, 
				line   => __LINE__,
			});
			
			my $access = 0;
			if ($match)
			{
				# Yup!
				foreach my $interface (sort {$a cmp $b} keys %{$match->{$host_name}})
				{
					my $peer_ip = $match->{$host_name}{$interface}{ip};
					$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_ip => $peer_ip }});
					
					$access = $anvil->Remote->test_access({
						target   => $peer_ip,
						password => $password,
					});
					$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { access => $access }});
					if ($access)
					{
						$anvil->data->{rename_server}{host}{$host_name}{use_ip}   = $peer_ip;
						$anvil->data->{rename_server}{host}{$host_name}{password} = $password;
						$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
							"rename_server::host::${host_name}::use_ip" => $anvil->data->{rename_server}{host}{$host_name}{use_ip}, 
						}});
						last;
					}
				}
			}
			if (not $access)
			{
				# Unable to reach this peer, so we need to keep waiting.
				$waiting = 1;
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
				
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0297", variables => { host_name => $host_name }});
				$anvil->Job->update_progress({progress => 18, message => "job_0297,!!host_name!".$host_name."!!"});
			}
		}
		
		if ($waiting)
		{
			sleep 10;
		}
	}
	
	# All peer(s) are ready!
	$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0298"});
	$anvil->Job->update_progress({progress => 20, message => "job_0298"});
	
	return(0);
}

sub wait_for_pacemaker
{
	my ($anvil) = @_;

	# We need to rename the server in the cluster, and we need both nodes up to do it. 
	my $waiting = 1;
	while($waiting)
	{
		my $problem = $anvil->Cluster->parse_cib({debug => 2});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
		if (not $problem)
		{
			my $local_name   = $anvil->data->{cib}{parsed}{'local'}{name};
			my $peer_name   = $anvil->data->{cib}{parsed}{peer}{name};
			my $local_ready = $anvil->data->{cib}{parsed}{data}{node}{$local_name}{node_state}{ready};
			my $peer_ready  = $anvil->data->{cib}{parsed}{data}{node}{$local_name}{node_state}{ready};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				local_name  => $local_name,
				peer_name   => $peer_name, 
				local_ready => $local_ready, 
				peer_ready  => $peer_ready, 
			}});
			if (($local_ready) && ($peer_ready))
			{
				# We're good. 
				$waiting = 0;
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0295"});
				$anvil->Job->update_progress({progress => 15, message => "job_0295"});
			}
			else
			{
				# One or both nods are not online yet.
				$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0296", variables => {
					local_name  => $local_name,
					peer_name   => $peer_name, 
					local_ready => $local_ready, 
					peer_ready  => $peer_ready, 
				}});
				$anvil->Job->update_progress({progress => 10, message => "job_0296,!!local_name!".$local_name."!!,!!peer_name!".$peer_name."!!,!!local_ready!".$local_ready."!!,!!peer_ready!".$peer_ready."!!"});
			}
		}
		else
		{
			# Cluster hasn't started.
			$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0277"});
			$anvil->Job->update_progress({progress => 5, message => "job_0277"});
		}
		if ($waiting)
		{
			sleep 10;
		}
	}
	
	return(0);
}
