You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1565 lines
68 KiB
1565 lines
68 KiB
#!/usr/bin/perl |
|
# |
|
# This program will manage servers; Changing RAM, CPU cores, Growing virtual disks, adding virtual disks, |
|
# inserting and ejecting ISO images into virtual optical media. |
|
# |
|
# Exit codes; |
|
# 0 = Normal exit. |
|
# 1 = No database connection. |
|
# |
|
# TODO: |
|
# |
|
|
|
use strict; |
|
use warnings; |
|
use Anvil::Tools; |
|
require POSIX; |
|
use Term::Cap; |
|
|
|
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(); |
|
|
|
$anvil->data->{switches}{anvil} = ""; # This is the Anvil! Name or UUID being worked on. |
|
$anvil->data->{switches}{boot} = ""; # This is a comma-separated list of ordered boot devices |
|
$anvil->data->{switches}{cores} = ""; # This sets the server to use this number of CPU cores. |
|
$anvil->data->{switches}{drive} = ""; # drive being modified (insert/eject ISO, growing drive) |
|
$anvil->data->{switches}{eject} = ""; # This will eject whatever ISO (if any) in the '--drive'. |
|
$anvil->data->{switches}{'expand-to'} = ""; # When the drive is a disk (backed by a DRBD resource), this is the new desired size to grow to. |
|
$anvil->data->{switches}{insert} = ""; # This is the ISO to insert into the --drive |
|
$anvil->data->{switches}{'job-uuid'} = ""; |
|
$anvil->data->{switches}{ram} = ""; # This is the amount of RAM to set the server to use. |
|
$anvil->data->{switches}{server} = ""; # server name or uuid |
|
$anvil->data->{switches}{y} = ""; # Don't prompt for confirmation. Only useful when there isn't a job UUID. |
|
$anvil->Get->switches; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'switches::boot' => $anvil->data->{switches}{boot}, |
|
'switches::cores' => $anvil->data->{switches}{cores}, |
|
'switches::drive' => $anvil->data->{switches}{drive}, |
|
'switches::eject' => $anvil->data->{switches}{eject}, |
|
'switches::expand-to' => $anvil->data->{switches}{'expand-to'}, |
|
'switches::insert' => $anvil->data->{switches}{insert}, |
|
'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'}, |
|
'switches::ram' => $anvil->data->{switches}{ram}, |
|
'switches::server' => $anvil->data->{switches}{server}, |
|
'switches::y' => $anvil->data->{switches}{y}, |
|
}}); |
|
|
|
# Connect to the database(s). If we have no connections, we'll proceed anyway as one of the 'run_once' tasks |
|
# is to setup the database server. |
|
$anvil->Database->connect(); |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 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_0305"}); |
|
sleep 10; |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
|
|
# If we don't have a job UUID, try to find one. |
|
if (not $anvil->data->{switches}{'job-uuid'}) |
|
{ |
|
# Load the job data. |
|
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }}); |
|
} |
|
|
|
# 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_0251", |
|
}); |
|
|
|
# Job data will be in $anvil->data->{jobs}{job_data} |
|
run_jobs($anvil); |
|
} |
|
else |
|
{ |
|
# Interactive! |
|
$anvil->data->{new_config}{cpu}{sockets} = ""; |
|
$anvil->data->{new_config}{cpu}{cores} = ""; |
|
$anvil->data->{new_config}{ram}{'bytes'} = ""; |
|
interactive_question($anvil); |
|
} |
|
|
|
$anvil->nice_exit({exit_code => 0}); |
|
|
|
|
|
############################################################################################################# |
|
# Functions # |
|
############################################################################################################# |
|
|
|
sub run_jobs |
|
{ |
|
my ($anvil) = @_; |
|
|
|
|
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_question |
|
{ |
|
my ($anvil) = @_; |
|
|
|
$anvil->Database->get_hosts(); |
|
$anvil->Database->get_anvils(); |
|
$anvil->Database->get_servers(); |
|
|
|
$anvil->data->{target_server}{server_uuid} = "" if not defined $anvil->data->{target_server}{server_uuid}; |
|
$anvil->data->{target_server}{server_name} = "" if not defined $anvil->data->{target_server}{server_name}; |
|
$anvil->data->{target_server}{server_state} = "" if not defined $anvil->data->{target_server}{server_state}; |
|
$anvil->data->{target_server}{anvil_uuid} = "" if not defined $anvil->data->{target_server}{anvil_uuid}; |
|
$anvil->data->{target_server}{anvil_name} = "" if not defined $anvil->data->{target_server}{anvil_name}; |
|
$anvil->data->{target_server}{anvil_description} = "" if not defined $anvil->data->{target_server}{anvil_description}; |
|
$anvil->data->{target_server}{anvil_node1_host_uuid} = "" if not defined $anvil->data->{target_server}{anvil_node1_host_uuid}; |
|
$anvil->data->{target_server}{anvil_node1_host_name} = "" if not defined $anvil->data->{target_server}{anvil_node1_host_name}; |
|
$anvil->data->{target_server}{anvil_node2_host_uuid} = "" if not defined $anvil->data->{target_server}{anvil_node2_host_uuid}; |
|
$anvil->data->{target_server}{anvil_node2_host_name} = "" if not defined $anvil->data->{target_server}{anvil_node2_host_name}; |
|
$anvil->data->{target_server}{anvil_dr1_host_uuid} = "" if not defined $anvil->data->{target_server}{anvil_dr1_host_uuid}; |
|
$anvil->data->{target_server}{anvil_dr1_host_name} = "" if not defined $anvil->data->{target_server}{anvil_dr1_host_name}; |
|
|
|
### Anvil |
|
# If 'switches::anvil' is set, see if it's a UUID and then set either 'anvil-uuid' or 'anvil-name'. |
|
if ($anvil->data->{switches}{anvil}) |
|
{ |
|
if ($anvil->Validate->uuid({uuid => $anvil->data->{switches}{anvil}})) |
|
{ |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->data->{switches}{anvil}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
} |
|
else |
|
{ |
|
$anvil->data->{target_server}{anvil_name} = $anvil->data->{switches}{anvil}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
}}); |
|
} |
|
} |
|
|
|
# Do we know or can we find the Anvil! UUID? |
|
if ((not $anvil->data->{target_server}{anvil_name}) && ($anvil->data->{switches}{'anvil-name'})) |
|
{ |
|
$anvil->data->{target_server}{anvil_name} = $anvil->data->{switches}{'anvil-name'}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
}}); |
|
} |
|
if ((not $anvil->data->{target_server}{anvil_uuid}) && ($anvil->data->{switches}{'anvil-uuid'})) |
|
{ |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->data->{switches}{'anvil-uuid'}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
} |
|
|
|
if ((not $anvil->data->{target_server}{anvil_uuid}) && (not $anvil->data->{target_server}{anvil_name})) |
|
{ |
|
# Nothing given. Is this host a node, perhaps? |
|
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid(); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }}); |
|
|
|
if ($anvil_uuid) |
|
{ |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil_uuid; |
|
$anvil->data->{target_server}{anvil_name} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
} |
|
else |
|
{ |
|
# If there is only one Anvil!, choose it |
|
my $known_anvils = keys %{$anvil->data->{anvils}{anvil_name}}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { known_anvils => $known_anvils }}); |
|
if (not $known_anvils) |
|
{ |
|
my $variables = { server_uuid => $anvil->data->{target_server}{server_uuid} }; |
|
$anvil->Jobs->update_progress({ |
|
progress => 100, |
|
message => "error_0321", |
|
job_status => "failed", |
|
log_level => 1, |
|
priority => "err", |
|
}); |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
elsif ($known_anvils == 1) |
|
{ |
|
foreach my $anvil_name (keys %{$anvil->data->{anvils}{anvil_name}}) |
|
{ |
|
$anvil->data->{target_server}{anvil_name} = $anvil_name; |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
} |
|
} |
|
} |
|
} |
|
elsif (not $anvil->data->{target_server}{anvil_uuid}) |
|
{ |
|
# We have a name, get the UUID. |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid({anvil_name => $anvil->data->{target_server}{anvil_name}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid} }}); |
|
|
|
# If the name is bad, error out if not interactive |
|
if (not $anvil->data->{target_server}{anvil_uuid}) |
|
{ |
|
# Bad server UUID. If it's a job, abort. Otherwise, clear and go back to |
|
my $variables = { anvil_name => $anvil->data->{target_server}{anvil_name} }; |
|
$anvil->Jobs->update_progress({ |
|
progress => 100, |
|
message => "error_0319", |
|
variables => $variables, |
|
job_status => "failed", |
|
log_level => 1, |
|
priority => "err", |
|
}); |
|
if ($anvil->data->{switches}{'job-uuid'}) |
|
{ |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
$anvil->data->{target_server}{anvil_name} = ""; |
|
} |
|
} |
|
elsif (not $anvil->data->{target_server}{anvil_name}) |
|
{ |
|
$anvil->data->{target_server}{anvil_name} = $anvil->Cluster->get_anvil_name({anvil_uuid => $anvil->data->{target_server}{anvil_uuid}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "target_server::anvil_name" => $anvil->data->{target_server}{anvil_name} }}); |
|
|
|
# If the name is bad, error out if not interactive |
|
if (not $anvil->data->{target_server}{anvil_name}) |
|
{ |
|
# Bad server UUID. If it's a job, abort. Otherwise, clear and go back to |
|
my $variables = { anvil_uuid => $anvil->data->{target_server}{anvil_uuid} }; |
|
$anvil->Jobs->update_progress({ |
|
progress => 100, |
|
message => "error_0320", |
|
variables => $variables, |
|
job_status => "failed", |
|
log_level => 1, |
|
priority => "err", |
|
}); |
|
if ($anvil->data->{switches}{'job-uuid'}) |
|
{ |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
$anvil->data->{target_server}{anvil_uuid} = ""; |
|
} |
|
} |
|
|
|
### Server |
|
# First, has the user specified a server? If so, and if it's by name, make sure it's unique. If the |
|
# name exists on two or more Anvil! systems, we'll need an Anvil! name as well. If it's unique, we |
|
# can devine the Anvil! UUID. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"switches::server" => $anvil->data->{switches}{server}, |
|
}}); |
|
if ($anvil->data->{switches}{server}) |
|
{ |
|
my $server = $anvil->data->{switches}{server}; |
|
if ($anvil->Validate->uuid({uuid => $server})) |
|
{ |
|
$anvil->data->{target_server}{server_uuid} = $server; |
|
$anvil->data->{target_server}{server_name} = exists $anvil->data->{servers}{server_uuid}{$server} ? $anvil->data->{servers}{server_uuid}{$server}{server_name} : ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::server_uuid" => $anvil->data->{target_server}{server_uuid}, |
|
"target_server::server_name" => $anvil->data->{target_server}{server_name}, |
|
}}); |
|
} |
|
else |
|
{ |
|
$anvil->data->{target_server}{server_name} = $server; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::server_name" => $anvil->data->{target_server}{server_name}, |
|
}}); |
|
if ($anvil->data->{target_server}{anvil_uuid}) |
|
{ |
|
my $anvil_uuid = $anvil->data->{target_server}{anvil_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }}); |
|
|
|
$anvil->data->{target_server}{server_uuid} = exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server} ? $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server}{server_uuid} : ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::server_uuid" => $anvil->data->{target_server}{server_uuid}, |
|
}}); |
|
} |
|
} |
|
} |
|
|
|
# If we have a server UUID, make sure it's valid. |
|
if ($anvil->data->{target_server}{server_uuid}) |
|
{ |
|
# Pull up the server data. |
|
my $server_uuid = $anvil->data->{target_server}{server_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_uuid => $server_uuid }}); |
|
if (exists $anvil->data->{servers}{server_uuid}{$server_uuid}) |
|
{ |
|
# We can divine everthing from this. |
|
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; |
|
my $server_name = $anvil->data->{target_server}{server_name}; |
|
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; |
|
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; |
|
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; |
|
my $dr1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
anvil_uuid => $anvil_uuid, |
|
server_name => $server_name, |
|
server_host_uuid => $server_host_uuid, |
|
node1_host_uuid => $node1_host_uuid, |
|
node2_host_uuid => $node2_host_uuid, |
|
dr1_host_uuid => $dr1_host_uuid, |
|
}}); |
|
|
|
$anvil->data->{target_server}{anvil_uuid} = $anvil_uuid; |
|
$anvil->data->{target_server}{server_name} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name}; |
|
$anvil->data->{target_server}{server_state} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
|
$anvil->data->{target_server}{anvil_name} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name}; |
|
$anvil->data->{target_server}{anvil_description} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_description}; |
|
$anvil->data->{target_server}{anvil_node1_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; |
|
$anvil->data->{target_server}{anvil_node1_host_name} = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{host_name}; |
|
$anvil->data->{target_server}{anvil_node2_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}; |
|
$anvil->data->{target_server}{anvil_node2_host_name} = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{host_name}; |
|
$anvil->data->{target_server}{anvil_dr1_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; |
|
$anvil->data->{target_server}{anvil_dr1_host_name} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
"target_server::server_name" => $anvil->data->{target_server}{server_name}, |
|
"target_server::server_state" => $anvil->data->{target_server}{server_state}, |
|
"target_server::anvil_description" => $anvil->data->{target_server}{anvil_description}, |
|
"target_server::anvil_node1_host_uuid" => $anvil->data->{target_server}{anvil_node1_host_uuid}, |
|
"target_server::anvil_node1_host_name" => $anvil->data->{target_server}{anvil_node1_host_name}, |
|
"target_server::anvil_node2_host_uuid" => $anvil->data->{target_server}{anvil_node2_host_uuid}, |
|
"target_server::anvil_node2_host_name" => $anvil->data->{target_server}{anvil_node2_host_name}, |
|
"target_server::anvil_dr1_host_uuid" => $anvil->data->{target_server}{anvil_dr1_host_uuid}, |
|
"target_server::anvil_dr1_host_name" => $anvil->data->{target_server}{anvil_dr1_host_name}, |
|
}}); |
|
if ($dr1_host_uuid) |
|
{ |
|
$anvil->data->{target_server}{anvil_dr1_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid}; |
|
$anvil->data->{target_server}{anvil_dr1_host_name} = $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{host_name};; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_dr1_host_uuid" => $anvil->data->{target_server}{anvil_dr1_host_uuid}, |
|
"target_server::anvil_dr1_host_name" => $anvil->data->{target_server}{anvil_dr1_host_name}, |
|
}}); |
|
} |
|
|
|
### Pull out details of the server. |
|
# How much RAM are we using and how much is configured? |
|
$anvil->data->{target_server}{ram_in_use} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_ram_in_use}; |
|
$anvil->data->{target_server}{configured_ram} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_configured_ram}; |
|
$anvil->data->{target_server}{server_host_uuid} = $server_host_uuid; |
|
$anvil->data->{target_server}{server_host_name} = $anvil->data->{hosts}{host_uuid}{$server_host_uuid}{host_name}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::ram_in_use" => $anvil->Convert->add_commas({number => $anvil->data->{target_server}{ram_in_use}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{target_server}{ram_in_use}}).")", |
|
"target_server::configured_ram" => $anvil->Convert->add_commas({number => $anvil->data->{target_server}{configured_ram}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{target_server}{configured_ram}}).")", |
|
"target_server::server_host_uuid" => $anvil->data->{target_server}{server_host_uuid}, |
|
"target_server::server_host_name" => $anvil->data->{target_server}{server_host_name}, |
|
}}); |
|
if ($anvil->data->{target_server}{server_state} eq "shut off") |
|
{ |
|
$anvil->data->{target_server}{ram_in_use} = 0; |
|
$anvil->data->{target_server}{server_host_uuid} = ""; |
|
$anvil->data->{target_server}{server_host_name} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::ram_in_use" => $anvil->Convert->add_commas({number => $anvil->data->{target_server}{ram_in_use}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{target_server}{ram_in_use}}).")", |
|
"target_server::server_host_uuid" => $anvil->data->{target_server}{server_host_uuid}, |
|
"target_server::server_host_name" => $anvil->data->{target_server}{server_host_name}, |
|
}}); |
|
} |
|
|
|
# Does this server boot after others, or stay off? |
|
$anvil->data->{target_server}{boot}{after_server_name} = ""; |
|
$anvil->data->{target_server}{boot}{after_server_uuid} = ""; |
|
$anvil->data->{target_server}{boot}{start_delay} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"servers::server_uuid::${server_uuid}::server_start_after_server_uuid" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid}, |
|
}}); |
|
if (($anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid}) && ($anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid} ne "NULL")) |
|
{ |
|
my $start_after_server_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { start_after_server_uuid => $start_after_server_uuid }}); |
|
|
|
if ($start_after_server_uuid eq "00000000-0000-0000-0000-000000000000") |
|
{ |
|
# Stay off |
|
$anvil->data->{target_server}{boot}{after_server_name} = $anvil->Words->string({key => "striker_0292"}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::boot::after_server_name" => $anvil->data->{target_server}{boot}{after_server_name}, |
|
}}); |
|
} |
|
else |
|
{ |
|
# Server proper |
|
$anvil->data->{target_server}{boot}{after_server_name} = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$start_after_server_uuid}{server_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::boot::after_server_name" => $anvil->data->{target_server}{boot}{after_server_name}, |
|
}}); |
|
} |
|
$anvil->data->{target_server}{boot}{after_server_uuid} = "00000000-0000-0000-0000-000000000000"; |
|
$anvil->data->{target_server}{boot}{start_delay} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_delay}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::boot::after_server_uuid" => $anvil->data->{target_server}{boot}{after_server_uuid}, |
|
"target_server::boot::start_delay" => $anvil->data->{target_server}{boot}{start_delay}, |
|
}}); |
|
} |
|
|
|
# Get a list of files on this Anvil! |
|
foreach my $file_uuid (keys %{$anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}}) |
|
{ |
|
my $file_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_name}; |
|
my $file_type = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_type}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
file_uuid => $file_uuid, |
|
file_name => $file_name, |
|
file_type => $file_type, |
|
}}); |
|
|
|
$anvil->data->{files}{$file_type}{name}{$file_name}{directory} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_directory}; |
|
$anvil->data->{files}{$file_type}{name}{$file_name}{file_size} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_size}; |
|
$anvil->data->{files}{$file_type}{name}{$file_name}{md5sum} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_md5sum}; |
|
$anvil->data->{files}{$file_type}{name}{$file_name}{file_uuid} = $file_uuid; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"files::${file_type}::name::${file_name}::directory" => $anvil->data->{files}{$file_type}{name}{$file_name}{directory}, |
|
"files::${file_type}::name::${file_name}::file_size" => $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->Convert->add_commas({number => $anvil->data->{files}{$file_type}{name}{$file_name}{file_size}})})." (".$anvil->data->{files}{$file_type}{name}{$file_name}{file_size}.")", |
|
"files::${file_type}::name::${file_name}::md5sum" => $anvil->data->{files}{$file_type}{name}{$file_name}{md5sum}, |
|
"files::${file_type}::name::${file_name}::file_uuid" => $anvil->data->{files}{$file_type}{name}{$file_name}{file_uuid}, |
|
}}); |
|
} |
|
|
|
# Get and parse the server's definition. |
|
$anvil->Database->get_server_definitions({ |
|
debug => 2, |
|
server_uuid => $server_uuid, |
|
}); |
|
|
|
my $short_host_name = $anvil->Get->short_host_name(); |
|
my $definition_uuid = $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_uuid}; |
|
my $definition_xml = $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_xml}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
's1:short_host_name' => $short_host_name, |
|
's2:definition_uuid' => $definition_uuid, |
|
's3:definition_xml' => $definition_xml, |
|
}}); |
|
|
|
$anvil->Server->parse_definition({ |
|
debug => 2, |
|
source => "from_db", |
|
server => $anvil->data->{target_server}{server_name}, |
|
definition => $definition_xml, |
|
host => $short_host_name, |
|
}); |
|
|
|
# If only VCPU is set, cores and threads will both be '1' but 'total' will be higher. |
|
# Windows (and others?) interprets this as X number of single core sockets. |
|
$anvil->data->{target_server}{server_cpu_total} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{cpu}{total_cores} if not defined $anvil->data->{target_server}{server_cpu_total}; |
|
$anvil->data->{target_server}{server_cpu_sockets} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{cpu}{sockets} if not defined $anvil->data->{target_server}{server_cpu_sockets}; |
|
$anvil->data->{target_server}{server_cpu_cores} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{cpu}{threads} if not defined $anvil->data->{target_server}{server_cpu_cores}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
's1:target_server::server_cpu_sockets' => $anvil->data->{target_server}{server_cpu_sockets}, |
|
's2:target_server::server_cpu_cores' => $anvil->data->{target_server}{server_cpu_cores}, |
|
's3:target_server::server_cpu_total' => $anvil->data->{target_server}{server_cpu_total}, |
|
}}); |
|
|
|
if (($anvil->data->{target_server}{server_cpu_sockets} == 1) && ($anvil->data->{target_server}{server_cpu_cores} == 1) && ($anvil->data->{target_server}{server_cpu_total} > 1)) |
|
{ |
|
$anvil->data->{target_server}{server_cpu_sockets} = $anvil->data->{target_server}{server_cpu_total}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
's1:target_server::server_cpu_sockets' => $anvil->data->{target_server}{server_cpu_sockets}, |
|
}}); |
|
} |
|
|
|
# Pull out the existing disks. |
|
foreach my $target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target => $target }}); |
|
|
|
$anvil->data->{target_server}{disk}{$target}{device_bus} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{device_bus}; |
|
$anvil->data->{target_server}{disk}{$target}{boot_order} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{boot_order} ? $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{boot_order} : 0; |
|
$anvil->data->{target_server}{disk}{$target}{cache} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{driver}{cache}; |
|
$anvil->data->{target_server}{disk}{$target}{io} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{driver}{io}; |
|
$anvil->data->{target_server}{disk}{$target}{path} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{disk}{target}{$target}{path}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::disk::${target}::device_bus" => $anvil->data->{target_server}{disk}{$target}{device_bus}, |
|
"target_server::disk::${target}::boot_order" => $anvil->data->{target_server}{disk}{$target}{boot_order}, |
|
"target_server::disk::${target}::cache" => $anvil->data->{target_server}{disk}{$target}{cache}, |
|
"target_server::disk::${target}::io" => $anvil->data->{target_server}{disk}{$target}{io}, |
|
"target_server::disk::${target}::path" => $anvil->data->{target_server}{disk}{$target}{path}, |
|
}}); |
|
|
|
if ($anvil->data->{target_server}{disk}{$target}{boot_order}) |
|
{ |
|
my $boot_order = $anvil->data->{target_server}{disk}{$target}{boot_order}; |
|
$anvil->data->{target_server}{boot}{$boot_order}{$target} = $anvil->data->{target_server}{disk}{$target}{path}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::boot::${boot_order}::${target}" => $anvil->data->{target_server}{boot}{$boot_order}{$target}, |
|
}}); |
|
} |
|
} |
|
|
|
foreach my $target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{cdrom}{target}}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target => $target }}); |
|
|
|
$anvil->data->{target_server}{cdrom}{$target}{device_bus} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{cdrom}{target}{$target}{device_bus}; |
|
$anvil->data->{target_server}{cdrom}{$target}{boot_order} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{cdrom}{target}{$target}{boot_order} ? $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{cdrom}{target}{$target}{boot_order} : 0; |
|
$anvil->data->{target_server}{cdrom}{$target}{path} = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{cdrom}{target}{$target}{path}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::cdrom::${target}::device_bus" => $anvil->data->{target_server}{cdrom}{$target}{device_bus}, |
|
"target_server::cdrom::${target}::boot_order" => $anvil->data->{target_server}{cdrom}{$target}{boot_order}, |
|
"target_server::cdrom::${target}::path" => $anvil->data->{target_server}{cdrom}{$target}{path}, |
|
}}); |
|
|
|
if ($anvil->data->{target_server}{cdrom}{$target}{boot_order}) |
|
{ |
|
my $boot_order = $anvil->data->{target_server}{cdrom}{$target}{boot_order}; |
|
$anvil->data->{target_server}{boot}{$boot_order}{$target} = $anvil->data->{target_server}{cdrom}{$target}{path}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::boot::${boot_order}::${target}" => $anvil->data->{target_server}{boot}{$boot_order}{$target}, |
|
}}); |
|
} |
|
} |
|
|
|
foreach my $script ("pre_migration", "post_migration") |
|
{ |
|
my $file_uuid_key = "server_".$script."_file_uuid"; |
|
my $argument_key = "server_".$script."_arguments"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
script => $script, |
|
file_uuid_key => $file_uuid_key, |
|
}}); |
|
|
|
$anvil->data->{target_server}{scripts}{$script}{file_uuid} = ""; |
|
$anvil->data->{target_server}{scripts}{$script}{file_name} = ""; |
|
$anvil->data->{target_server}{scripts}{$script}{arguments} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"servers::server_uuid::${server_uuid}::${file_uuid_key}" => $anvil->data->{servers}{server_uuid}{$server_uuid}{$file_uuid_key}, |
|
}}); |
|
if (($anvil->data->{servers}{server_uuid}{$server_uuid}{$file_uuid_key}) && ($anvil->data->{servers}{server_uuid}{$server_uuid}{$file_uuid_key} ne "NULL")) |
|
{ |
|
my $file_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{$file_uuid_key}; |
|
my $file_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_name}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
file_uuid => $file_uuid, |
|
file_name => $file_name, |
|
}}); |
|
|
|
$anvil->data->{target_server}{scripts}{$script}{file_uuid} = $file_uuid; |
|
$anvil->data->{target_server}{scripts}{$script}{file_name} = $file_name; |
|
$anvil->data->{target_server}{scripts}{$script}{arguments} = $anvil->data->{servers}{server_uuid}{$server_uuid}{$argument_key}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::scripts::${script}::file_uuid" => $anvil->data->{target_server}{scripts}{$script}{file_uuid}, |
|
"target_server::scripts::${script}::file_name" => $anvil->data->{target_server}{scripts}{$script}{file_name}, |
|
"target_server::scripts::${script}::arguments" => $anvil->data->{target_server}{scripts}{$script}{arguments}, |
|
}}); |
|
} |
|
} |
|
|
|
# Get the available resources. |
|
$anvil->Get->available_resources({debug => 2}); |
|
} |
|
else |
|
{ |
|
# Bad server UUID. If it's a job, abort. Otherwise, clear and go back to |
|
my $variables = { server_uuid => $anvil->data->{target_server}{server_uuid} }; |
|
$anvil->Jobs->update_progress({ |
|
progress => 100, |
|
message => "error_0318", |
|
variables => $variables, |
|
job_status => "failed", |
|
log_level => 1, |
|
priority => "err", |
|
}); |
|
if ($anvil->data->{switches}{'job-uuid'}) |
|
{ |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
$anvil->data->{target_server}{server_uuid} = ""; |
|
} |
|
} |
|
|
|
# If we don't have an Anvil! UUID at this point, we need to ask the user. |
|
my $termios = new POSIX::Termios; |
|
$termios->getattr; |
|
my $ospeed = $termios->getospeed; |
|
|
|
my $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed }; |
|
$terminal->Trequire(qw/ce ku kd/); |
|
|
|
if (not $anvil->data->{target_server}{anvil_uuid}) |
|
{ |
|
interactive_ask_anvil_name($anvil, $terminal); |
|
} |
|
if (not $anvil->data->{target_server}{server_uuid}) |
|
{ |
|
interactive_ask_server_name($anvil, $terminal); |
|
} |
|
|
|
# Made it here? Show the menu. |
|
interactive_configure_main($anvil, $terminal); |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_configure_main |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
while(1) |
|
{ |
|
print $terminal->Tputs('cl'); |
|
print $anvil->Words->string({key => "job_0355", variables => { |
|
anvil_name => $anvil->data->{target_server}{anvil_name}, |
|
server_name => $anvil->data->{target_server}{server_name}, |
|
}})."\n"; |
|
my $changes = 0; |
|
my $cpu_star = ""; |
|
my $ram_star = ""; |
|
if (($anvil->data->{new_config}{cpu}{sockets}) or ($anvil->data->{new_config}{cpu}{cores})) |
|
{ |
|
$cpu_star = "*"; |
|
$changes = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
cpu_star => $cpu_star, |
|
changes => $changes, |
|
}}); |
|
} |
|
if ($anvil->data->{new_config}{ram}{'bytes'}) |
|
{ |
|
$ram_star = "*"; |
|
$changes = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
ram_star => $ram_star, |
|
changes => $changes, |
|
}}); |
|
} |
|
|
|
print "[ 1 ] - CPU".$cpu_star."\n"; |
|
print "[ 2 ] - RAM".$ram_star."\n"; |
|
print "[ 3 ] - Storage\n"; |
|
print "[ 4 ] - Network\n"; |
|
print "[ 5 ] - Boot Order\n"; |
|
print "[ 6 ] - Cluster Management\n"; |
|
print "\n"; |
|
print "[ B ] - Back\n"; |
|
print "[ Q ] - Quit\n"; |
|
if ($changes) |
|
{ |
|
print "[ S ] - Save and commit the changes.\n"; |
|
} |
|
print "\n"; |
|
print $terminal->Tgoto('cm', 0, (9+$changes))."? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
if ($answer eq "1") |
|
{ |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
elsif ($answer eq "2") |
|
{ |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
elsif ($answer eq "3") |
|
{ |
|
interactive_configure_storage($anvil, $terminal); |
|
} |
|
elsif ($answer eq "4") |
|
{ |
|
print "Going to Network menu\n"; |
|
sleep 1; |
|
} |
|
elsif ($answer eq "5") |
|
{ |
|
print "Going to Boot order menu\n"; |
|
sleep 1; |
|
} |
|
elsif ($answer eq "6") |
|
{ |
|
print "Going to cluster manager menu\n"; |
|
sleep 1; |
|
} |
|
elsif (lc($answer) eq "b") |
|
{ |
|
$anvil->data->{target_server}{server_name} = ""; |
|
$anvil->data->{target_server}{server_uuid} = ""; |
|
$anvil->data->{switches}{server} = ""; |
|
interactive_ask_server_name($anvil, $terminal); |
|
} |
|
elsif (lc($answer) eq "q") |
|
{ |
|
print "NO CARRIER, good bye.\n"; |
|
$anvil->nice_exit({exit_code => 0}); |
|
} |
|
elsif (lc($answer) eq "s") |
|
{ |
|
# Confirm changes |
|
print "Confirm chagnes menu\n"; |
|
sleep 1; |
|
} |
|
else |
|
{ |
|
print "Invalid selection, please enter the digit for the menu you want.\n"; |
|
sleep 1; |
|
} |
|
=cut |
|
1. CPU |
|
* Max (threads): X |
|
1. Sockets: |
|
2. Cores: |
|
2. RAM |
|
* Available: X |
|
* In use: y |
|
* Configured: z |
|
1. Size: |
|
3. Storage |
|
1. Optical media |
|
<list drives> |
|
1. Insert / change |
|
<file list> |
|
2. Eject |
|
2. Disks |
|
1. New |
|
<storage groups (size available)> |
|
<list drives> |
|
1. Grow |
|
2. Delete |
|
3. Move <when 2+ storage groups> |
|
3. Boot order |
|
<list disks, 0 == don't boot> |
|
4. Network |
|
<interface list> |
|
1. MAC Address |
|
2. emulation type |
|
3. <toggle> Plug in / Unplug |
|
4. Bridge |
|
5. Delete |
|
1. Add |
|
5. Boot Order |
|
=cut |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_configure_storage |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
# Get the |
|
$anvil->Database->get_storage_group_data({debug => 2}); |
|
while(1) |
|
{ |
|
# Here, we'll list each storage pool and for each indicate if it's used and, if so |
|
my $index = 1; |
|
my $lines = 2; |
|
my $changes = 0; |
|
my $storage_group_selection = []; |
|
push @{$storage_group_selection}, "NULL"; |
|
|
|
print $terminal->Tputs('cl'); |
|
print $anvil->Words->string({key => "job_0355", variables => { |
|
anvil_name => $anvil->data->{target_server}{anvil_name}, |
|
server_name => $anvil->data->{target_server}{server_name}, |
|
}})."\n"; |
|
print "* Storage configuration.\n"; |
|
my $anvil_uuid = $anvil->data->{target_server}{anvil_uuid}; |
|
foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}}) |
|
{ |
|
my $storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid}; |
|
my $vg_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size}; |
|
my $free_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{free_size}; |
|
my $vg_size_on_dr = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size_on_dr}; |
|
my $available_on_dr = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{available_on_dr}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
's1:storage_group_name' => $storage_group_name, |
|
's2:storage_group_uuid' => $storage_group_uuid, |
|
's3:vg_size' => $vg_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size}).")", |
|
's4:free_size' => $free_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_size}).")", |
|
's5:vg_size_on_dr' => $vg_size_on_dr." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size_on_dr}).")", |
|
's6:available_on_dr' => $free_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available_on_dr}).")", |
|
}}); |
|
|
|
my $paths = {}; |
|
foreach my $target (sort {$a cmp $b} keys %{$anvil->data->{target_server}{disk}}) |
|
{ |
|
my $device_bus = $anvil->data->{target_server}{disk}{$target}{device_bus}; |
|
my $cache = $anvil->data->{target_server}{disk}{$target}{cache}; |
|
my $io = $anvil->data->{target_server}{disk}{$target}{io}; |
|
my $this_path = $anvil->data->{target_server}{disk}{$target}{path}; |
|
my $boot_order = $anvil->data->{target_server}{disk}{$target}{boot_order} ? $anvil->data->{target_server}{disk}{$target}{boot_order} : "--"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
target => $target, |
|
device_bus => $device_bus, |
|
cache => $cache, |
|
io => $io, |
|
this_path => $this_path, |
|
boot_order => $boot_order, |
|
}}); |
|
|
|
my $this_storage_group_uuid = $anvil->Storage->get_storage_group_from_path({ |
|
debug => 2, |
|
anvil_uuid => $anvil_uuid, |
|
path => $this_path, |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_storage_group_uuid => $this_storage_group_uuid }}); |
|
|
|
if (($this_storage_group_uuid) && ($storage_group_uuid eq $this_storage_group_uuid)) |
|
{ |
|
$paths->{$target}{path} = $this_path; |
|
$paths->{$target}{boot_order} = $boot_order; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"s1:paths->{".$target."}{path}" => $paths->{$target}{path}, |
|
"s2:paths->{".$target."}{boot_order}" => $paths->{$target}{boot_order}, |
|
}}); |
|
} |
|
} |
|
|
|
$lines += 2; |
|
print "[ ".$index." ] - Name: \"".$storage_group_name."\" - Size: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size})."], Free: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_size})."]\n"; |
|
|
|
my $path_count = keys %{$paths}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { path_count => $path_count }}); |
|
if ($path_count) |
|
{ |
|
foreach my $target (sort {$a cmp $b} keys %{$paths}) |
|
{ |
|
my $path = $paths->{$target}{path}; |
|
my $boot_order = $paths->{$target}{boot_order}; |
|
my $size = $anvil->Storage->get_size_of_block_device({ |
|
debug => 2, |
|
path => $path, |
|
}); |
|
my $say_size = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
size => $size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size}).")", |
|
}}); |
|
if ($size !~ /^\d+$/) |
|
{ |
|
$say_size = "<unknwon>"; |
|
} |
|
else |
|
{ |
|
$say_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $size}) |
|
} |
|
print " - Target: [".$target."], boot order: [".$boot_order."], backed by: [".$path."], Size: [".$say_size."]\n"; |
|
$lines++; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { lines => $lines }}); |
|
} |
|
} |
|
else |
|
{ |
|
print " - <Storage group not used by this server>\n"; |
|
} |
|
$index++; |
|
} |
|
|
|
print "\n"; |
|
print "[ B ] - Back\n"; |
|
print "[ Q ] - Quit\n"; |
|
if ($changes) |
|
{ |
|
print "- Changes can be committed on the main page.\n"; |
|
print $terminal->Tgoto('cm', 0, ($lines+5))."? "; |
|
} |
|
else |
|
{ |
|
print $terminal->Tgoto('cm', 0, ($lines+4))."? "; |
|
} |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_configure_ram |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
while(1) |
|
{ |
|
# Threads will be the maximum, even without hyperthreading being available. |
|
my $anvil_uuid = $anvil->data->{target_server}{anvil_uuid}; |
|
my $say_current_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{target_server}{configured_ram}}); |
|
my $say_total_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware}}); |
|
my $say_available_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{available}}); |
|
my $max_assignable = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{available} + $anvil->data->{target_server}{configured_ram}; |
|
my $say_max_assignable = $anvil->Convert->bytes_to_human_readable({'bytes' => $max_assignable}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
anvil_uuid => $anvil_uuid, |
|
say_current_ram => $say_current_ram, |
|
say_total_ram => $say_total_ram, |
|
say_available_ram => $say_available_ram, |
|
say_max_assignable => $say_max_assignable, |
|
}}); |
|
|
|
my $changes = 0; |
|
my $say_new_ram = 0; |
|
if ($anvil->data->{new_config}{ram}{'bytes'}) |
|
{ |
|
$say_new_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new_config}{ram}{'bytes'}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_new_ram => $say_new_ram }}); |
|
} |
|
|
|
my $ram_star = " "; |
|
if (($anvil->data->{new_config}{ram}{'bytes'}) && ($anvil->data->{new_config}{ram}{'bytes'} ne $anvil->data->{target_server}{server_ram_bytes})) |
|
{ |
|
$ram_star = "*"; |
|
$changes = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
ram_star => $ram_star, |
|
changes => $changes, |
|
}}); |
|
} |
|
|
|
print $terminal->Tputs('cl'); |
|
print $anvil->Words->string({key => "job_0355", variables => { |
|
anvil_name => $anvil->data->{target_server}{anvil_name}, |
|
server_name => $anvil->data->{target_server}{server_name}, |
|
}})."\n"; |
|
print "* RAM configuration. Currently allocated: [".$say_current_ram."], Maximum RAM: [".$say_max_assignable."] (current + free).\n"; |
|
print "[ 1 ] - RAM".$ram_star." (currently: [".$say_current_ram."], new: [".$say_new_ram."])\n"; |
|
|
|
print "\n"; |
|
print "[ B ] - Back\n"; |
|
print "[ Q ] - Quit\n"; |
|
if ($changes) |
|
{ |
|
print "- Changes can be committed on the main page.\n"; |
|
print $terminal->Tgoto('cm', 0, 7)."? "; |
|
} |
|
else |
|
{ |
|
print $terminal->Tgoto('cm', 0, 6)."? "; |
|
} |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
if ($answer eq "1") |
|
{ |
|
print "- Can specify in bytes or base2 human readible (ie: '4 GiB', '4G', etc)\n"; |
|
print "How much RAM would you like? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$answer =~ s/^\s+//; |
|
$answer =~ s/\s+$//; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
if (not $answer) |
|
{ |
|
# Go back |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
# Convert to bytes |
|
my $requested_bytes = $answer; |
|
if ($requested_bytes =~ /\D/) |
|
{ |
|
$requested_bytes = $anvil->Convert->human_readable_to_bytes({ |
|
base2 => 1, |
|
size => $requested_bytes, |
|
}); |
|
if ($requested_bytes eq "!!error!!") |
|
{ |
|
# Problem. |
|
print "[ Error ] - The answer: [".$answer."] could not be interpretted.\n"; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
} |
|
elsif (not $requested_bytes) |
|
{ |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
|
|
if (($requested_bytes =~ /^\d+$/) && ($requested_bytes > $max_assignable)) |
|
{ |
|
$anvil->data->{new_config}{ram}{'bytes'} = 0; |
|
print "[ Error ] - You asked for: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $requested_bytes})."] (".$anvil->Convert->add_commas({number => $max_assignable})." bytes) RAM, but the max available is: [".$say_max_assignable."] (".$anvil->Convert->add_commas({number => $max_assignable})." bytes).\n"; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
$anvil->data->{new_config}{ram}{'bytes'} = $requested_bytes; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"new_config::ram::bytes" => $anvil->data->{new_config}{ram}{'bytes'}, |
|
}}); |
|
} |
|
} |
|
} |
|
elsif (lc($answer) eq "b") |
|
{ |
|
interactive_configure_main($anvil, $terminal); |
|
} |
|
elsif (lc($answer) eq "q") |
|
{ |
|
print "NO CARRIER, good bye.\n"; |
|
$anvil->nice_exit({exit_code => 0}); |
|
} |
|
else |
|
{ |
|
interactive_configure_ram($anvil, $terminal); |
|
} |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_configure_cpu |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
while(1) |
|
{ |
|
# Threads will be the maximum, even without hyperthreading being available. |
|
my $anvil_uuid = $anvil->data->{target_server}{anvil_uuid}; |
|
my $maximum_cores = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}; |
|
my $current_cores = $anvil->data->{target_server}{server_cpu_cores}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
anvil_uuid => $anvil_uuid, |
|
maximum_cores => $maximum_cores, |
|
current_cores => $current_cores, |
|
}}); |
|
|
|
my $changes = 0; |
|
my $star_cores = " "; |
|
if (($anvil->data->{new_config}{cpu}{cores}) && ($anvil->data->{new_config}{cpu}{cores} ne $anvil->data->{target_server}{server_cpu_cores})) |
|
{ |
|
$star_cores = "*"; |
|
$changes = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
star_cores => $star_cores, |
|
changes => $changes, |
|
}}); |
|
} |
|
my $star_sockets = " "; |
|
if (($anvil->data->{new_config}{cpu}{sockets}) && ($anvil->data->{new_config}{cpu}{sockets} ne $anvil->data->{target_server}{server_cpu_sockets})) |
|
{ |
|
$star_sockets = "*"; |
|
$changes = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
star_sockets => $star_sockets, |
|
changes => $changes, |
|
}}); |
|
} |
|
|
|
print $terminal->Tputs('cl'); |
|
print $anvil->Words->string({key => "job_0355", variables => { |
|
anvil_name => $anvil->data->{target_server}{anvil_name}, |
|
server_name => $anvil->data->{target_server}{server_name}, |
|
}})."\n"; |
|
print "* CPU configuration. Maximum cores X sockets is: [".$maximum_cores."]\n"; |
|
print "[ 1 ] - Cores per socket".$star_cores." (currently: [".$anvil->data->{target_server}{server_cpu_cores}."], new: [".$anvil->data->{new_config}{cpu}{cores}."])\n"; |
|
print "[ 2 ] - Sockets".$star_sockets." (currently: [".$anvil->data->{target_server}{server_cpu_sockets}."], new: [".$anvil->data->{new_config}{cpu}{sockets}."])\n"; |
|
|
|
print "\n"; |
|
print "[ B ] - Back\n"; |
|
print "[ Q ] - Quit\n"; |
|
if ($changes) |
|
{ |
|
print "- Changes can be committed on the main page.\n"; |
|
print $terminal->Tgoto('cm', 0, 8)."? "; |
|
} |
|
else |
|
{ |
|
print $terminal->Tgoto('cm', 0, 7)."? "; |
|
} |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
if ($answer eq "1") |
|
{ |
|
print "How many cores per socket would you like? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
if (not $answer) |
|
{ |
|
# Go back |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
elsif ($answer =~ /\D/) |
|
{ |
|
print "[ Error ] - The answer: [".$answer."] is not valid. You need to specify a digit.\n"; |
|
print "Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
# Did they ask for too many? |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"new_config::cpu::sockets" => $anvil->data->{new_config}{cpu}{sockets}, |
|
"target_server::server_cpu_sockets" => $anvil->data->{target_server}{server_cpu_sockets}, |
|
maximum_cores => $maximum_cores, |
|
}}); |
|
if (($anvil->data->{new_config}{cpu}{sockets}) && (($answer * $anvil->data->{new_config}{cpu}{sockets}) > $maximum_cores)) |
|
{ |
|
print "[ Error ] - With the current socket count of: [".$anvil->data->{new_config}{cpu}{sockets}."], the requested number of cores: [".$answer."] would result in: [".($answer * $anvil->data->{new_config}{cpu}{sockets})."] total cores.\n"; |
|
print " The maximum available on this Anvil! is: [".$maximum_cores."].\n"; |
|
if ($anvil->data->{new_config}{cpu}{sockets} > 1) |
|
{ |
|
print " You may wish to reduce the socket count first.\n"; |
|
} |
|
print __LINE__."; Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
elsif ((not $anvil->data->{new_config}{cpu}{sockets}) && (($answer * $anvil->data->{target_server}{server_cpu_sockets}) > $maximum_cores)) |
|
{ |
|
print "[ Error ] - With the current socket count of: [".$anvil->data->{target_server}{server_cpu_sockets}."], the requested number of cores: [".$answer."] would result in: [".($answer * $anvil->data->{target_server}{server_cpu_sockets})."] total cores.\n"; |
|
print " The maximum available on this Anvil! is: [".$maximum_cores."].\n"; |
|
if ($anvil->data->{target_server}{server_cpu_sockets} > 1) |
|
{ |
|
print " You may wish to reduce the socket count first.\n"; |
|
} |
|
print __LINE__."; Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
$anvil->data->{new_config}{cpu}{cores} = $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"new_config::cpu::cores" => $anvil->data->{new_config}{cpu}{cores}, |
|
}}); |
|
} |
|
} |
|
} |
|
elsif ($answer eq "2") |
|
{ |
|
print "How many sockets would you like? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
if (not $answer) |
|
{ |
|
# Go back |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
elsif ($answer =~ /\D/) |
|
{ |
|
print "[ Error ] - The answer: [".$answer."] is not valid. You need to specify a digit.\n"; |
|
print "Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
# Did they ask for too many? |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"new_config::cpu::cores" => $anvil->data->{new_config}{cpu}{cores}, |
|
"target_server::server_cpu_cores" => $anvil->data->{target_server}{server_cpu_cores}, |
|
maximum_cores => $maximum_cores, |
|
}}); |
|
if (($anvil->data->{new_config}{cpu}{cores}) && (($answer * $anvil->data->{new_config}{cpu}{cores}) > $maximum_cores)) |
|
{ |
|
print "[ Error ] - With the current core count of: [".$anvil->data->{new_config}{cpu}{cores}."], the requested number of sockets: [".$answer."] would result in: [".($answer * $anvil->data->{new_config}{cpu}{cores})."] total cores.\n"; |
|
print " The maximum available on this Anvil! is: [".$maximum_cores."].\n"; |
|
if ($anvil->data->{new_config}{cpu}{cores} > 1) |
|
{ |
|
print " You may wish to reduce the core count first.\n"; |
|
} |
|
print __LINE__."; Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
elsif ((not $anvil->data->{new_config}{cpu}{cores}) && (($answer * $anvil->data->{target_server}{server_cpu_cores}) > $maximum_cores)) |
|
{ |
|
print "[ Error ] - With the current core count of: [".$anvil->data->{target_server}{server_cpu_cores}."], the requested number of sockets: [".$answer."] would result in: [".($answer * $anvil->data->{target_server}{server_cpu_cores})."] total cores.\n"; |
|
print " The maximum available on this Anvil! is: [".$maximum_cores."].\n"; |
|
if ($anvil->data->{target_server}{server_cpu_sockets} > 1) |
|
{ |
|
print " You may wish to reduce the core count first.\n"; |
|
} |
|
print __LINE__."; Press any key to continue.\n"; |
|
my $answer = <STDIN>; |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
else |
|
{ |
|
$anvil->data->{new_config}{cpu}{sockets} = $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"new_config::cpu::sockets" => $anvil->data->{new_config}{cpu}{sockets}, |
|
}}); |
|
} |
|
} |
|
} |
|
elsif (lc($answer) eq "b") |
|
{ |
|
interactive_configure_main($anvil, $terminal); |
|
} |
|
elsif (lc($answer) eq "q") |
|
{ |
|
print "NO CARRIER, good bye.\n"; |
|
$anvil->nice_exit({exit_code => 0}); |
|
} |
|
else |
|
{ |
|
interactive_configure_cpu($anvil, $terminal); |
|
} |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_ask_anvil_name |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
my $retry = 0; |
|
while(1) |
|
{ |
|
my $default = ""; |
|
if ($anvil->data->{target_server}{anvil_name}) |
|
{ |
|
$default = $anvil->data->{target_server}{anvil_name}; |
|
} |
|
print $terminal->Tputs('cl'); |
|
print $anvil->Words->string({key => "message_0257"})."\n"; |
|
|
|
my $anvil_selection = []; |
|
push @{$anvil_selection}, "NULL"; |
|
|
|
my $anvil_count = 0; |
|
my $longest_anvil_name = 0; |
|
foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}}) |
|
{ |
|
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid}; |
|
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
anvil_name => $anvil_name, |
|
anvil_uuid => $anvil_uuid, |
|
anvil_description => $anvil_description, |
|
}}); |
|
next if $anvil_description eq "DELETED"; |
|
|
|
$anvil_count++; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_count => $anvil_count }}); |
|
push @{$anvil_selection}, $anvil_name; |
|
|
|
if (length($anvil_name) > $longest_anvil_name) |
|
{ |
|
$longest_anvil_name = length($anvil_name); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { longest_anvil_name => $longest_anvil_name }}); |
|
} |
|
} |
|
|
|
my $number_length = length($anvil_count + 1); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { number_length => $number_length }}); |
|
for (my $i = 1; $i < @{$anvil_selection}; $i++) |
|
{ |
|
my $anvil_name = $anvil_selection->[$i]; |
|
next if $anvil_name eq "NULL"; |
|
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid}; |
|
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
i => $i, |
|
anvil_name => $anvil_name, |
|
anvil_uuid => $anvil_uuid, |
|
anvil_description => $anvil_description, |
|
}}); |
|
|
|
print $anvil->Words->string({key => "message_0258", variables => { |
|
number => sprintf("%-${number_length}s", $i), |
|
anvil_name => sprintf("%-${longest_anvil_name}s", $anvil_name), |
|
anvil_description => $anvil_description, |
|
}})."\n"; |
|
} |
|
print "\n"; |
|
print "[ Q ] - Quit\n"; |
|
print "\n"; |
|
|
|
my $column = 3 + $anvil_count; |
|
print $terminal->Tgoto('cm', 0, $column)."? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
if ((not $answer) && ($default)) |
|
{ |
|
$answer = $default; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
} |
|
|
|
# Reload in case a new anvil! was saved while we waited. |
|
$anvil->Database->get_anvils(); |
|
if (($answer =~ /^\d+$/) && (exists $anvil_selection->[$answer]) && (not exists $anvil->data->{anvils}{anvil_name}{$answer})) |
|
{ |
|
$answer = $anvil_selection->[$answer]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
$anvil->data->{target_server}{anvil_name} = $answer; |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid({anvil_name => $answer}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
last; |
|
} |
|
elsif ((exists $anvil->data->{anvils}{anvil_name}{$answer}) && (ref($anvil->data->{anvils}{anvil_name}{$answer}) eq "HASH")) |
|
{ |
|
# Valid. |
|
$anvil->data->{target_server}{anvil_name} = $answer; |
|
$anvil->data->{target_server}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid({anvil_name => $answer}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::anvil_name" => $anvil->data->{target_server}{anvil_name}, |
|
"target_server::anvil_uuid" => $anvil->data->{target_server}{anvil_uuid}, |
|
}}); |
|
last; |
|
} |
|
elsif (lc($answer) eq "q") |
|
{ |
|
print "NO CARRIER, good bye.\n"; |
|
$anvil->nice_exit({exit_code => 0}); |
|
} |
|
else |
|
{ |
|
$retry = 1; |
|
} |
|
} |
|
|
|
interactive_question($anvil); |
|
|
|
return(0); |
|
} |
|
|
|
sub interactive_ask_server_name |
|
{ |
|
my ($anvil, $terminal) = @_; |
|
|
|
$anvil->Database->get_servers({debug => 2}); |
|
|
|
### TODO: Figure out how many rows we have and break the server list into columns if too long. |
|
### tput cols |
|
### tput rows |
|
my $retry = 0; |
|
my $not_found = ""; |
|
while(1) |
|
{ |
|
my $default = ""; |
|
if ($anvil->data->{target_server}{server_name}) |
|
{ |
|
$default = $anvil->data->{target_server}{server_name}; |
|
} |
|
print $terminal->Tputs('cl'); |
|
|
|
# Show all the current server names. |
|
if ($retry) |
|
{ |
|
print $anvil->Words->string({key => "job_0353"})."\n\n"; |
|
} |
|
my $anvil_uuid = $anvil->data->{target_server}{anvil_uuid}; |
|
print $anvil->Words->string({key => "job_0354", variables => { anvil_name => $anvil->data->{target_server}{anvil_name} }})."\n"; |
|
|
|
# Push the server names into an array, with '0' being null so the list we show the user |
|
# starts at '1'. |
|
my $server_selection = []; |
|
push @{$server_selection}, "NULL"; |
|
|
|
my $server_count = 0; |
|
my $longest_server_name = 0; |
|
foreach my $server_name (sort {$a cmp $b} keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}}) |
|
{ |
|
my $server_uuid = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid}; |
|
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
server_name => $server_name, |
|
server_uuid => $server_uuid, |
|
server_state => $server_state, |
|
}}); |
|
next if $server_state eq "DELETED"; |
|
|
|
$server_count++; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_count => $server_count }}); |
|
push @{$server_selection}, $server_name; |
|
|
|
if (length($server_name) > $longest_server_name) |
|
{ |
|
$longest_server_name = length($server_name); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { longest_server_name => $longest_server_name }}); |
|
} |
|
} |
|
|
|
my $number_length = length($server_count + 1); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { number_length => $number_length }}); |
|
for (my $i = 1; $i < @{$server_selection}; $i++) |
|
{ |
|
my $server_name = $server_selection->[$i]; |
|
next if $server_name eq "NULL"; |
|
my $server_uuid = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid}; |
|
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
server_name => $server_name, |
|
server_uuid => $server_uuid, |
|
server_state => $server_state, |
|
}}); |
|
|
|
print $anvil->Words->string({key => "message_0256", variables => { |
|
number => sprintf("%-${number_length}s", $i), |
|
server_name => sprintf("%-${longest_server_name}s", $server_name), |
|
server_state => $server_state, |
|
}})."\n"; |
|
} |
|
print "\n"; |
|
print "[ B ] - Back\n"; |
|
print "[ Q ] - Quit\n"; |
|
print "\n"; |
|
|
|
my $column = 4 + $server_count; |
|
print $terminal->Tgoto('cm', 0, $column)."? "; |
|
my $answer = <STDIN>; |
|
chomp $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
|
|
if ((not $answer) && ($default)) |
|
{ |
|
$answer = $default; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
} |
|
|
|
# Reload in case a new anvil! was saved while we waited. |
|
$anvil->Database->get_servers(); |
|
if ($answer) |
|
{ |
|
# Found? |
|
if (($answer =~ /^\d+$/) && (exists $server_selection->[$answer]) && (not exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$answer})) |
|
{ |
|
$answer = $server_selection->[$answer]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); |
|
} |
|
if ((exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$answer}) && (ref($anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$answer}) eq "HASH")) |
|
{ |
|
# Valid |
|
$anvil->data->{target_server}{server_name} = $answer; |
|
$anvil->data->{target_server}{server_uuid} = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$answer}{server_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"target_server::server_name" => $anvil->data->{target_server}{server_name}, |
|
"target_server::server_uuid" => $anvil->data->{target_server}{server_uuid}, |
|
}}); |
|
last; |
|
} |
|
elsif (lc($answer) eq "b") |
|
{ |
|
$anvil->data->{target_server}{anvil_name} = ""; |
|
$anvil->data->{target_server}{anvil_uuid} = ""; |
|
$anvil->data->{switches}{anvil} = ""; |
|
$anvil->data->{switches}{'anvil-name'} = ""; |
|
$anvil->data->{switches}{'anvil-uuid'} = ""; |
|
print "Going back\n"; |
|
interactive_ask_anvil_name($anvil, $terminal); |
|
} |
|
elsif (lc($answer) eq "q") |
|
{ |
|
print "NO CARRIER, good bye.\n"; |
|
$anvil->nice_exit({exit_code => 0}); |
|
} |
|
else |
|
{ |
|
# Inalid. |
|
$not_found = $answer; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { not_found => $not_found }}); |
|
} |
|
last; |
|
} |
|
else |
|
{ |
|
$retry = 1; |
|
} |
|
} |
|
interactive_question($anvil); |
|
|
|
return(0); |
|
} |
|
|
|
sub show_stats |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Load the server's details. |
|
my $server_xml = $anvil->Server->get_definition({server_uuid => $anvil->data->{sys}{server_uuid}}); |
|
my $server_name = $anvil->data->{sys}{server_name}; |
|
my $short_host_name = $anvil->Get->short_host_name(); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
's1:short_host_name' => $short_host_name, |
|
's2:server_name' => $server_name, |
|
's3:server_xml' => $server_xml, |
|
}}); |
|
|
|
$anvil->Server->parse_definition({ |
|
debug => 2, |
|
source => "from_db", |
|
definition => $server_xml, |
|
server => $server_name, |
|
}); |
|
|
|
my $cpu_cores = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{cpu}{total_cores}; |
|
my $ram_bytes = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{memory}; |
|
my $say_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $ram_bytes}); |
|
print "Cores: [".$cpu_cores."], RAM: [".$say_ram."] (".$ram_bytes." bytes)\n"; |
|
|
|
# Show disks |
|
foreach my $device ("disk", "cdrom") |
|
{ |
|
print "- Device: [".$device."]\n"; |
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{$device}{target}}) |
|
{ |
|
my $boot_order = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{$device}{target}{$device_target}{boot_order}; |
|
my $type = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{$device}{target}{$device_target}{type}; |
|
my $device_bus = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{$device}{target}{$device_target}{device_bus}; |
|
my $path = $anvil->data->{server}{$short_host_name}{$server_name}{from_db}{device}{$device}{target}{$device_target}{path}; |
|
print " - Target: [".$device_target."], type: [".$type."], boot order: [".$boot_order."], bus: [".$device_bus."]\n"; |
|
print " - Path: [".$path."]\n"; |
|
if ($device eq "disk") |
|
{ |
|
# Pull the size |
|
my $volume = ($path =~ /\/(\d+)$/)[0]; |
|
print " - Volume: [".$volume."]\n"; |
|
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{new}{resource}{$server_name}{host}}) |
|
{ |
|
my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $host_name}); |
|
my $device_path = $anvil->data->{new}{resource}{$server_name}{host}{$host_name}{volume}{$volume}{device_path}; |
|
my $backing_disk = $anvil->data->{new}{resource}{$server_name}{host}{$host_name}{volume}{$volume}{backing_disk}; |
|
print " - Host: [".$host_name."] (".$host_uuid."), path: [".$device_path."], backing disk: [".$backing_disk."]\n"; |
|
} |
|
} |
|
else |
|
{ |
|
} |
|
} |
|
} |
|
|
|
return(0); |
|
}
|
|
|