#!/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: # # USAGE: # - Show # - anvil-manage-server-storage --server srv01-fs37 # use strict; use warnings; use Anvil::Tools; require POSIX; use Term::Cap; use Text::Diff; use Data::Dumper; use Sys::Virt; 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(); # Read switches (target ([user@]host[:port]) and the file with the target's password. $anvil->Get->switches({list => [ "add", "anvil", "boot", "boot-menu", "boot-order", "confirm", "cpu", "disk", "eject", "job-uuid", "grow", "insert", "optical", "ram", "server", "storage-group", ], man => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); # 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 ($anvil->data->{switches}{'job-uuid'}) { load_job($anvil); } $anvil->Database->get_hosts(); $anvil->Database->get_anvils(); $anvil->Database->get_servers(); if ($anvil->data->{switches}{anvil}) { # Make sure they asked for a real anvil. $anvil->Get->anvil_from_switch({string => $anvil->data->{switches}{anvil}}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::anvil_name" => $anvil->data->{switches}{anvil_name}, "switches::anvil_uuid" => $anvil->data->{switches}{anvil_uuid}, }}); } if (not $anvil->data->{switches}{server}) { # Show the list of servers. show_server_list($anvil); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0456"}); $anvil->Job->update_progress({ progress => 100, message => "error_0456", }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 0}); } validate_server($anvil); if ($anvil->data->{switches}{cpu}) { manage_cpu($anvil); } elsif ($anvil->data->{switches}{ram}) { manage_ram($anvil); } elsif ($anvil->data->{switches}{'boot-order'}) { manage_boot_order($anvil); } elsif ($anvil->data->{switches}{'boot-menu'}) { manage_boot_menu($anvil); } else { show_server_details($anvil, 1); } $anvil->Job->update_progress({ progress => 100, message => "job_0281", }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 0}); ############################################################################################################# # Functions # ############################################################################################################# sub manage_cpu { my ($anvil) = @_; my $short_host_name = $anvil->Get->short_host_name; my $host_uuid = $anvil->Get->host_uuid; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name}; my $server_host_name = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:host_uuid' => $host_uuid, 's3:server_name' => $server_name, 's4:server_uuid' => $server_uuid, 's5:server_host_uuid' => $server_host_uuid, 's6:anvil_uuid' => $anvil_uuid, 's7:anvil_name' => $anvil_name, }}); my $from_source = get_definition_source($anvil); my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source, server_state => $server_state, }}); if ($server_state eq "running") { $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }}); } # Get available resources. $anvil->Get->available_resources({ debug => 2, anvil_uuid => $anvil_uuid, }); ### TODO: Add support for changing the model, fallback, etc, and features my $total_cores = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{total_cores}; my $sockets = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{sockets}; my $cores = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{cores}; my $threads = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{threads}; my $model_name = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{model_name}; my $model_fallback = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{model_fallback}; my $match = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{match}; my $vendor = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{vendor}; my $mode = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{mode}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { total_cores => $total_cores, sockets => $sockets, cores => $cores, threads => $threads, model_name => $model_name, model_fallback => $model_fallback, match => $match, vendor => $vendor, mode => $mode, }}); foreach my $name (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{feature}}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 's1:name' => $name, 's2:value' => $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{feature}{$name}, }}); } my $host_cores = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores}; my $host_threads = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}; my $max_cores = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{available}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:host_cores' => $host_cores, 's2:host_threads' => $host_threads, 's3:max_cores' => $max_cores, }}); my $recommended_max = $host_cores - 2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { recommended_max => $recommended_max }}); if ($host_cores <= 2) { $recommended_max = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { recommended_max => $recommended_max }}); } # Show the user or change? if ($anvil->data->{switches}{cpu} eq "#!SET!#") { # Show the CPU info my $variables = { total_cores => $total_cores, sockets => $sockets, cores => $cores, threads => $threads, host_cores => $host_cores, host_threads => $host_threads, max_cores => $max_cores, recommended_max => $recommended_max, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0380", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "message_0380", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; return(0); } my $new_sockets = 1; my $new_cores = 1; my $new_threads = 1; if ($anvil->data->{switches}{cpu} =~ /^(\d+),(\d+),(\d+)$/) { $new_sockets = $1; $new_cores = $2; $new_threads = $3; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:new_sockets' => $new_sockets, 's2:new_cores' => $new_cores, 's3:new_threads' => $new_threads, }}); } elsif ($anvil->data->{switches}{cpu} =~ /^(\d+),(\d+)$/) { $new_sockets = $1; $new_cores = $2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:new_sockets' => $new_sockets, 's2:new_cores' => $new_cores, }}); } elsif ($anvil->data->{switches}{cpu} =~ /^(\d+)$/) { $new_cores = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_cores => $new_cores }}); } else { # Bad formatting. my $variables = { requested_cpu => $anvil->data->{switches}{cpu} }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0476", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0476", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Is the requested number of cores sane? my $requested_cores = $new_sockets * $new_cores * $new_threads; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { requested_cores => $requested_cores }}); if (($requested_cores < 1) or ($requested_cores > $max_cores)) { my $variables = { requested_cores => $requested_cores, new_sockets => $new_sockets, new_cores => $new_cores, new_threads => $new_threads, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0477", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0477", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Still alive? my $in_cpu = 0; my $topology_seen = 0; my $topology_line = ""; my $new_server_definition = ""; foreach my $line (split/\n/, $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ($line =~ /\d+<\/vcpu>/$requested_cores<\/vcpu>/; $line =~ s/\d+<\/vcpu>/$requested_cores<\/vcpu>/; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); } if ($in_cpu) { if ($line =~ /<\/cpu>/) { if (not $topology_seen) { $new_server_definition .= " ".$topology_line."\n"; } $in_cpu = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_cpu => $in_cpu }}); } if ($line =~ /Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { topology_seen => $topology_seen }}); } } if ($line =~ / if ($line =~ //) { # Adjust to add topology my $arguments = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { arguments => $arguments }}); $new_server_definition .= " \n"; $new_server_definition .= " ".$topology_line."\n"; $new_server_definition .= " \n"; next; } $in_cpu = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_cpu => $in_cpu }}); } $new_server_definition .= $line."\n"; } # Confirm the new definition is valid my $problem = $anvil->Server->parse_definition({ debug => 2, host => $short_host_name, server => $server_name, source => "test_xml", definition => $new_server_definition, }); if ($problem) { # The new definition is bad my $variables = { new_server_definition => $new_server_definition }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0470", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0470", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Did the user confirm? if ($anvil->data->{switches}{'job-uuid'}) { # Running as a job, don't prompt $anvil->Job->update_progress({ progress => 75, message => "job_0480", }); } elsif ($anvil->data->{switches}{confirm}) { # User confirmed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0359"}); } else { # Ask the user to confirm. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0381", variables => { old_total_cores => $total_cores, old_sockets => $sockets, old_cores => $cores, old_threads => $threads, new_total_cores => $requested_cores, new_sockets => $new_sockets, new_cores => $new_cores, new_threads => $new_threads, }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0021"}); my $answer = ; chomp $answer; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0828", variables => { answer => $answer }}); if ((lc($answer) eq "y") or (lc($answer) eq "yes")) { # Proceed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0175"}); } else { # Abort $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0022"}); $anvil->nice_exit({exit_code => 0}); } } # Record the new config. $problem = $anvil->Server->update_definition({ debug => 2, server => $server_uuid, new_definition_xml => $new_server_definition, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); if ($problem) { # Failed! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0471"}); $anvil->Job->update_progress({ progress => 100, message => "error_0471", }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } else { # Done! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "log_0750"}); $anvil->Job->update_progress({ progress => 100, message => "log_0750", }) if $anvil->data->{switches}{'job-uuid'}; } return(0); } sub manage_ram { my ($anvil) = @_; my $short_host_name = $anvil->Get->short_host_name; my $host_uuid = $anvil->Get->host_uuid; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name}; my $server_host_name = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:host_uuid' => $host_uuid, 's3:server_name' => $server_name, 's4:server_uuid' => $server_uuid, 's5:server_host_uuid' => $server_host_uuid, 's6:anvil_uuid' => $anvil_uuid, 's7:anvil_name' => $anvil_name, }}); my $from_source = get_definition_source($anvil); my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source, server_state => $server_state, }}); if ($server_state eq "running") { $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }}); } # Get available resources. $anvil->Get->available_resources({ debug => 2, anvil_uuid => $anvil_uuid, }); # The RAM In the database is stored in KiB my $server_ram_in_use = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_ram_in_use}; my $server_configured_ram = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_configured_ram}; my $server_definition_ram = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{memory}; my $available_ram = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{available}; my $max_ram = $available_ram + $server_configured_ram; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_ram_in_use => $server_ram_in_use." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_in_use}).")", server_configured_ram => $server_configured_ram." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_configured_ram}).")", server_definition_ram => $server_definition_ram." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_definition_ram}).")", available_ram => $available_ram." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available_ram}).")", max_ram => $max_ram." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_ram}).")", }}); if ($anvil->data->{switches}{ram} eq "#!SET!#") { my $variables = { ram_in_use => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_in_use}), configured_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_configured_ram}), max_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_ram}), available_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $available_ram}), }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0378", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "message_0378", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; return(0); } # Is the requested RAM valid? my $requested_ram = $anvil->Convert->human_readable_to_bytes({ debug => 2, size => $anvil->data->{switches}{ram}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { requested_ram => $requested_ram }}); if ($requested_ram eq "!!error!!") { my $variables = { requested_ram => $anvil->data->{switches}{ram} }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0473", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0473", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } elsif ($requested_ram > $max_ram) { my $variables = { requested_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $requested_ram}), max_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_ram}), }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0474", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0474", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } elsif ($requested_ram < 655360) { my $variables = { requested_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $requested_ram}) }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0475", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0475", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Convert the requested bytes to KiB my $new_requested_ram = $anvil->Convert->bytes_to_human_readable({ debug => 2, 'bytes' => $requested_ram, base2 => 1, unit => "k", }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ">>new_requested_ram" => $new_requested_ram }}); $new_requested_ram =~ s/\s.*$//; $new_requested_ram =~ s/\..*$//; $new_requested_ram =~ s/,//g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "< $new_requested_ram }}); # Still here? Update the definition! my $new_server_definition = ""; foreach my $line (split/\n/, $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ($line =~ /(\d+)<\/memory>/) { my $old_unit = $1; my $old_size = $2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_unit => $old_unit, old_size => $old_size, }}); $line =~ s/\d+<\/memory>/$new_requested_ram<\/memory>/; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); } if ($line =~ /(\d+)<\/currentMemory>/) { my $old_unit = $1; my $old_size = $2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_unit => $old_unit, old_size => $old_size, }}); $line =~ s/\d+<\/currentMemory>/$new_requested_ram<\/currentMemory>/; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); } $new_server_definition .= $line."\n"; } # Confirm the new definition is valid my $problem = $anvil->Server->parse_definition({ debug => 2, host => $short_host_name, server => $server_name, source => "test_xml", definition => $new_server_definition, }); if ($problem) { # The new definition is bad my $variables = { new_server_definition => $new_server_definition }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0470", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0470", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Did the user confirm? if ($anvil->data->{switches}{'job-uuid'}) { # Running as a job, don't prompt $anvil->Job->update_progress({ progress => 75, message => "job_0480", }); } elsif ($anvil->data->{switches}{confirm}) { # User confirmed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0359"}); } else { # Ask the user to confirm. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0379", variables => { configured_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_configured_ram}), requested_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $requested_ram}), }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0021"}); my $answer = ; chomp $answer; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0828", variables => { answer => $answer }}); if ((lc($answer) eq "y") or (lc($answer) eq "yes")) { # Proceed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0175"}); } else { # Abort $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0022"}); $anvil->nice_exit({exit_code => 0}); } } # Record the new config. $problem = $anvil->Server->update_definition({ debug => 2, server => $server_uuid, new_definition_xml => $new_server_definition, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); if ($problem) { # Failed! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0471"}); $anvil->Job->update_progress({ progress => 100, message => "error_0471", }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } else { # Update the server_configured_ram (making sure we've got the current DB data first) $anvil->Database->get_servers(); $anvil->Database->insert_or_update_servers({ debug => 2, server_uuid => $server_uuid, server_name => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name}, server_anvil_uuid => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}, server_user_stop => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_user_stop}, server_start_after_server_uuid => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid}, server_start_delay => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_delay}, server_host_uuid => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}, server_state => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}, server_live_migration => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_live_migration}, server_pre_migration_file_uuid => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_pre_migration_file_uuid}, server_pre_migration_arguments => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_pre_migration_arguments}, server_post_migration_file_uuid => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_post_migration_file_uuid}, server_post_migration_arguments => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_post_migration_arguments}, server_ram_in_use => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_ram_in_use}, server_configured_ram => $requested_ram, server_updated_by_user => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_updated_by_user}, server_boot_time => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_boot_time}, }); # Done! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "log_0750"}); $anvil->Job->update_progress({ progress => 100, message => "log_0750", }) if $anvil->data->{switches}{'job-uuid'}; } return(0); } sub manage_boot_order { my ($anvil) = @_; my $short_host_name = $anvil->Get->short_host_name; my $host_uuid = $anvil->Get->host_uuid; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $server_host_name = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:host_uuid' => $host_uuid, 's3:server_name' => $server_name, 's4:server_uuid' => $server_uuid, 's5:server_host_uuid' => $server_host_uuid, }}); my $from_source = get_definition_source($anvil); my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source, server_state => $server_state, }}); if ($server_state eq "running") { $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }}); } if ($anvil->data->{switches}{'boot-order'} eq "#!SET!#") { # Show the existing boot devices and their boot order $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0372", variables => { server_name => $server_name }}); foreach my $boot_order (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}}) { my $device_target = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_target}; my $device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_type}; my $path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path}; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0373", variables => { boot_order => $boot_order, device_target => $device_target, device => $device, path => $path, }}); } $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0374"}); return(0); } else { # Updating boot devices. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0375"}); $anvil->Job->update_progress({ progress => 25, message => "message_0375", }) if $anvil->data->{switches}{'job-uuid'}; # Parse the user's input. my $boot_order = $anvil->data->{switches}{'boot-order'}; my $boot_count = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { boot_order => $boot_order }}); foreach my $device_target (split/,/, $boot_order) { $boot_count++; $anvil->data->{new_boot_order}{$device_target}{order} = $boot_count; $anvil->data->{new_boot_order}{$device_target}{device_type} = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target, boot_count => $boot_count, "new_boot_order::${device_target}" => $anvil->data->{new_boot_order}{$device_target}, }}); if (not exists $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device_target}{$device_target}{type}) { # The device was not found, exit. my $variables = { device_target => $device_target }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0469", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0469", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } else { my $device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device_target}{$device_target}{type}; $anvil->data->{new_boot_order}{$device_target}{device_type} = $device; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new_boot_order::${device_target}::device_type" => $anvil->data->{new_boot_order}{$device_target}{device_type}, }}); } } # Find any unlisted devices and bump up their boot order as needed. foreach my $boot_order (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}}) { my $device_target = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_target}; my $device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_type}; if (not exists $anvil->data->{new_boot_order}{$device_target}) { $anvil->data->{new_boot_order}{$device_target}{order} = $boot_order + $boot_count; $anvil->data->{new_boot_order}{$device_target}{device_type} = $device; } } # Make sortable foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{new_boot_order}}) { my $boot_order = $anvil->data->{new_boot_order}{$device_target}{order}; my $device = $anvil->data->{new_boot_order}{$device_target}{device_type}; $anvil->data->{new_boot_order}{$device_target}{order} = $boot_order; $anvil->data->{new_boot_order}{$device_target}{target} = $device_target; $anvil->data->{new_boot_order}{$device_target}{device} = $device; $anvil->data->{new_boot_order}{$device_target}{path} = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path}; $anvil->data->{new_order}{$boot_order}{target} = $device_target; } # Show what the new boot order will be $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0376"}); $anvil->data->{'say'}{cdrom} = $anvil->Words->string({key => "type_0001"}); $anvil->data->{'say'}{disk} = $anvil->Words->string({key => "type_0004"}); foreach my $boot_order (sort {$a <=> $b} keys %{$anvil->data->{new_order}}) { my $device_target = $anvil->data->{new_order}{$boot_order}{target}; my $device = $anvil->data->{new_boot_order}{$device_target}{device}; my $path = $anvil->data->{new_boot_order}{$device_target}{path}; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0377", variables => { boot_order => $boot_order, path => $path, device_target => $device_target, device => $anvil->data->{'say'}{$device}, }}); } # Tell the job we're about to create the new definition $anvil->Job->update_progress({ progress => 50, message => "job_0478", }) if $anvil->data->{switches}{'job-uuid'}; # Update the definition. my $in_disk = 0; my $device_target = ""; my $boot_order_seen = 0; my $new_server_definition = ""; foreach my $line (split/\n/, $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ($line =~ /Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_disk => $in_disk }}); } if ($in_disk) { if ($line =~ /<\/disk>/) { # If we didn't see the old boot order, or if it was too soon, add the # boot order now. if ((not $boot_order_seen) && ($device_target)) { my $new_boot_order = $anvil->data->{new_boot_order}{$device_target}{order}; $new_server_definition .= " \n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_boot_order => $new_boot_order }}); } $in_disk = 0; $boot_order_seen = 0; $device_target = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_disk => $in_disk, boot_order_seen => $boot_order_seen, device_target => $device_target, }}); } elsif ($line =~ /Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }}); } elsif ($line =~ /boot order='(\d+)'/) { # If we have a device_target, update the line. Otherwise, skip it and # we'll insert it later. my $old_boot_order = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_boot_order => $old_boot_order }}); if ($device_target) { $boot_order_seen = 1; my $new_boot_order = $anvil->data->{new_boot_order}{$device_target}{order}; $line =~ s/boot order='.*?'/boot order='$new_boot_order'/; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { boot_order_seen => $boot_order_seen }}); } } } $new_server_definition .= $line."\n"; } my $problem = $anvil->Server->parse_definition({ debug => 2, host => $short_host_name, server => $server_name, source => "test_xml", definition => $new_server_definition, }); if ($problem) { # The new definition is bad my $variables = { new_server_definition => $new_server_definition }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0470", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0470", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Did the user confirm? if ($anvil->data->{switches}{'job-uuid'}) { # Running as a job, don't prompt $anvil->Job->update_progress({ progress => 75, message => "job_0480", }); } elsif ($anvil->data->{switches}{confirm}) { # User confirmed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0359"}); } else { # Ask the user to confirm. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0021"}); my $answer = ; chomp $answer; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0828", variables => { answer => $answer }}); if ((lc($answer) eq "y") or (lc($answer) eq "yes")) { # Proceed $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0175"}); } else { # Abort $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0022"}); $anvil->nice_exit({exit_code => 0}); } } # Record the new config. $problem = $anvil->Server->update_definition({ debug => 2, server => $server_uuid, new_definition_xml => $new_server_definition, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); if ($problem) { # Failed! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0471"}); $anvil->Job->update_progress({ progress => 100, message => "error_0471", }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } else { # Done! $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "log_0750"}); $anvil->Job->update_progress({ progress => 100, message => "log_0750", }) if $anvil->data->{switches}{'job-uuid'}; } } return(0); } sub manage_boot_menu { my ($anvil) = @_; my $short_host_name = $anvil->Get->short_host_name; my $host_uuid = $anvil->Get->host_uuid; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $server_host_name = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:host_uuid' => $host_uuid, 's3:server_name' => $server_name, 's4:server_uuid' => $server_uuid, 's5:server_host_uuid' => $server_host_uuid, }}); my $from_source = get_definition_source($anvil); my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source, server_state => $server_state, }}); if ($server_state eq "running") { $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }}); } my $say_yes = $anvil->Words->string({key => 'unit_0001'}); my $say_no = $anvil->Words->string({key => 'unit_0002'}); my $current_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{info}{boot_menu}); my $say_old_boot_menu = $current_boot_menu eq "yes" ? $say_yes : $say_no; my $new_boot_menu = $anvil->data->{switches}{'boot-menu'}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { current_boot_menu => $current_boot_menu, say_old_boot_menu => $say_old_boot_menu, new_boot_menu => $new_boot_menu, }}); if ((lc($anvil->data->{switches}{'boot-menu'}) eq "yes") or (lc($anvil->data->{switches}{'boot-menu'}) eq "no")) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "servers::server_uuid::${server_uuid}::server_definition_xml" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}, }}); # We need to rewrite the boot menu manually. my $new_definition = ""; my $in_os = 0; my $bootmenu_seen = 0; foreach my $line (split/\n/, $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ($line =~ //) { $in_os = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_os => $in_os }}); } if ($in_os) { if ($line =~ //) { my $old_value = $1; $bootmenu_seen = 1; $line =~ s///; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_value => $old_value, bootmenu_seen => $bootmenu_seen, line => $line, }}); } if ($line =~ /<\/os>/) { $in_os = 0; if (not $bootmenu_seen) { # Insert it $new_definition .= " \n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition => $new_definition }}); } } } $new_definition .= $line."\n"; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition => $new_definition }}); # Always call this, as a previous run may have only updated some definitions. my $problem = $anvil->Server->update_definition({ debug => 2, server => $server_uuid, new_definition_xml => $new_definition, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); # Reload and parse from the DB to confirm things are updated. delete $anvil->data->{servers}{server_uuid}{$server_uuid}; $anvil->Database->get_servers(); my $server_definition_xml = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_definition_xml => $server_definition_xml }}); undef $anvil->data->{server}{$short_host_name}{$server_name}{from_db}; $anvil->Server->parse_definition({ debug => 2, host => $short_host_name, server => $server_name, source => "from_db", definition => $server_definition_xml, }); my $new_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{from_db}{info}{boot_menu}); my $say_new_boot_menu = $new_boot_menu eq "yes" ? $say_yes : $say_no; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_boot_menu => $new_boot_menu, say_new_boot_menu => $say_new_boot_menu, }}); print "Boot Menu enabled now: [".$say_new_boot_menu."]\n"; print "- The boot menu has been updated.\n"; } else { print "Boot Menu enabled: [".$say_old_boot_menu."]\n"; print "- You can change this using '--boot-menu yes' or '--boot-menu no'.\n"; } return(0); } sub show_server_details { my ($anvil, $show_nodes) = @_; my $short_host_name = $anvil->Get->short_host_name; my $host_uuid = $anvil->Get->host_uuid; my $server_name = $anvil->data->{switches}{server_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:host_uuid' => $host_uuid, 's3:server_name' => $server_name, 's4:show_nodes' => $show_nodes, }}); # Words we'll use. my $say_yes = $anvil->Words->string({key => 'unit_0001'}); my $say_no = $anvil->Words->string({key => 'unit_0002'}); my $say_disk = $anvil->Words->string({key => 'header_0068'}); my $say_optical = $anvil->Words->string({key => 'header_0111'}); my $say_ejected = $anvil->Words->string({key => 'unit_0049'}); my $from_source = get_definition_source($anvil); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); # Boot stuff my $say_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{info}{boot_menu}) eq "yes" ? $say_yes : $say_no; my $say_boot_device = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{1}{device_type}) eq "cdrom" ? $say_optical : $say_disk; my $boot_device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{1}{device_target}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_boot_menu => $say_boot_menu, say_boot_device => $say_boot_device, boot_device => $boot_device, }}); my $boot_order = []; foreach my $sequence (sort {$a <=> $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}}) { my $this_device_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$sequence}{device_type}; my $say_this_boot_device = lc($this_device_type) eq "cdrom" ? $say_optical : $say_disk; my $this_boot_device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$sequence}{device_target}; my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$this_device_type}{target}{$this_boot_device}{path} // ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sequence => $sequence, say_this_boot_device => $say_this_boot_device, this_boot_device => $this_boot_device, device_path => $device_path, }}); if ((not $device_path) && (lc($this_device_type) eq "cdrom")) { $device_path = $say_ejected; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_path => $device_path }}); } push @{$boot_order}, $sequence."; ".$this_boot_device.", type: [".$say_this_boot_device."], path: [".$device_path."]"; } print "Boot Menu enabled: [".$say_boot_menu."]\n"; print "Boot device:\n"; foreach my $say_other_boot (@{$boot_order}) { print "- ".$say_other_boot."\n"; } # CPU my $cpu_sockets = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{sockets}; my $cpu_cores = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{cores}; my $cpu_total_cores = $cpu_sockets * $cpu_cores; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cpu_sockets => $cpu_sockets, cpu_cores => $cpu_cores, cpu_total_cores => $cpu_total_cores, }}); print "CPU Total: [".$cpu_total_cores."]; Sockets: [".$cpu_sockets."], Cores per Socket: [".$cpu_cores."]\n"; # RAM my $ram = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{memory}; print "RAM: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $ram})."] (".$anvil->Convert->add_commas({number => $ram})." Bytes)\n"; return(0); } sub get_definition_source { my ($anvil) = @_; my $short_host_name = $anvil->Get->short_host_name; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $from_source = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_host_name => $short_host_name, server_name => $server_name, server_uuid => $server_uuid, server_state => $server_state, from_source => $from_source, }}); $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}; $anvil->data->{server}{$short_host_name}{$server_name}{from_disk} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}; $anvil->data->{server}{$short_host_name}{$server_name}{from_db} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_db}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "server::${short_host_name}::${server_name}::from_virsh" => $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}, "server::${short_host_name}::${server_name}::from_disk" => $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}, "server::${short_host_name}::${server_name}::from_db" => $anvil->data->{server}{$short_host_name}{$server_name}{from_db}, }}); if (($server_state eq "running") && ($server_host_uuid eq $anvil->Get->host_uuid()) && (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh})) { $from_source = "from_virsh"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); } elsif (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}) { $from_source = "from_disk"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); } else { $from_source = "from_db"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); } return($from_source); } sub show_server_list { my ($anvil) = @_; # Loop through all Anvil! nodes, then all server in that Anvil! 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, }}); if (($anvil->data->{switches}{anvil_uuid}) && ($anvil->data->{switches}{anvil_uuid} ne $anvil_uuid)) { next; } print "\n".$anvil->Words->string({key => "message_0343", variables => { anvil_name => $anvil_name, anvil_uuid => $anvil_uuid, anvil_description => $anvil_description, }})."\n"; my $server_count = 0; if (exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}) { $server_count = keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_count => $server_count }}); } if (not $server_count) { print $anvil->Words->string({key => "message_0344"})."\n"; } else { 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"; print $anvil->Words->string({key => "message_0345", variables => { server_name => $server_name, server_uuid => $server_uuid, }})."\n"; } } } return(0); } sub validate_server { my ($anvil) = @_; $anvil->Get->server_from_switch({ debug => 2, string => $anvil->data->{switches}{server}, anvil_uuid => $anvil->data->{switches}{anvil_uuid}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::server_name" => $anvil->data->{switches}{server_name}, "switches::server_uuid" => $anvil->data->{switches}{server_uuid}, }}); if (not $anvil->data->{switches}{server_uuid}) { show_server_list($anvil); my $variables = { server => $anvil->data->{switches}{server}, anvil => $anvil->data->{switches}{anvil_name}, }; if ($anvil->data->{switches}{anvil_uuid}) { # Not found on the requested Anvil! node. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0451", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0451", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; } else { # Not found at all. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0452", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0452", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; } $anvil->nice_exit({exit_code => 1}); } my $variables = { server_name => $anvil->data->{switches}{server_name}, server_uuid => $anvil->data->{switches}{server_uuid}, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0802", variables => $variables}); $anvil->Job->update_progress({ progress => 2, message => "log_0802", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; my $short_host_name = $anvil->Get->short_host_name; my $server_name = $anvil->data->{switches}{server_name}; my $server_uuid = $anvil->data->{switches}{server_uuid}; my $server_definition = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; $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_uuid' => $server_uuid, 's4:server_definition' => $server_definition, 's5:server_host_uuid' => $server_host_uuid, 's6:server_state' => $server_state, 's7:anvil_uuid' => $anvil_uuid, }}); if (not $anvil->data->{switches}{anvil_uuid}) { $anvil->data->{switches}{anvil_uuid} = $anvil_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:switches::anvil_uuid' => $anvil->data->{switches}{anvil_uuid}, }}); } if ($server_state eq "DELETED") { # The server has been deleted my $variables = { server => $server_name }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0453", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0453", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } # Parse the definition. $anvil->Server->parse_definition({ debug => 3, host => $short_host_name, server => $server_name, source => "from_db", definition => $server_definition, }); # Can we read the XML definition? $anvil->Server->get_status({ debug => 2, server => $server_name, host => $short_host_name, }); if (not $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml}) { # The server isn't actually running... Not here anyway. if ($server_state eq "running") { my $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); my $variables = { server => $server_name, host_name => $server_host_name, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0454", variables => $variables}); $anvil->Job->update_progress({ progress => 100, message => "error_0454", variables => $variables, }) if $anvil->data->{switches}{'job-uuid'}; $anvil->nice_exit({exit_code => 1}); } } return(0); } sub load_job { my ($anvil) = @_; $anvil->Job->clear({ debug => 2, job_uuid => $anvil->data->{switches}{'job-uuid'}, }); $anvil->Job->get_job_details({ debug => 2, job_uuid => $anvil->data->{switches}{'job-uuid'}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'jobs::job_data' => $anvil->data->{jobs}{job_data}, }}); foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) { my ($variable, $value) = ($line =~ /^(.*)=(.*)$/); $value =~ s/^"(.*)\"/$1/; $value =~ s/^'(.*)\'/$1/; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:line' => $line, 's2:variable' => $variable, 's3:value' => $value, }}); $anvil->data->{switches}{$variable} = $value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::${variable}" => $anvil->data->{switches}{$variable}, }}); } $anvil->Job->update_progress({ progress => 1, job_picked_up_by => $$, job_picked_up_at => time, message => "message_0350", }); return(0); }