* WIP - Slowly working on anvil-manage-server

* Updated the scancore interval to 60 seconds.
* Updated Database->insert_or_update_health() so that 'delete' can find the health_uuid.
* Updated Convert->time() to return silently when passed '-1'.
* Fixed a bug scan-hardware to call Convert->round(). Also fixed it so it didn't set health scores of 0 for mismatch RAM when the RAM was not mismatched.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 5639eda8c3
commit 73267a8ea9
  1. 4
      Anvil/Tools.pm
  2. 6
      Anvil/Tools/Convert.pm
  3. 50
      Anvil/Tools/Database.pm
  4. 15
      scancore-agents/scan-hardware/scan-hardware
  5. 4
      share/words.xml
  6. 247
      tools/anvil-manage-server
  7. 2
      tools/anvil-provision-server

@ -834,10 +834,10 @@ sub _set_defaults
$anvil->data->{scancore} = {
timing => {
# Delay between DB connection attempts when no databases are available?
agent_runtime => 60,
agent_runtime => 30,
db_retry_interval => 2,
# Delay between scans?
run_interval => 30,
run_interval => 60,
},
database => {
# This is the number of hours, after which, transient data (like temperature and

@ -1340,10 +1340,10 @@ sub time
translate => $translate,
}});
# If the 'time' is '--', return silently.
if ($time eq "--")
# If the 'time' is '--' or '-1', return silently.
if (($time eq "--") or ($time eq "-1"))
{
return("--");
return($time);
}
# Remote commas and verify we're left with a number.

@ -6840,10 +6840,50 @@ sub insert_or_update_health
{
if (not $health_uuid)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_health()", parameter => "health_uuid" }});
return("");
# If we've got an agent and source name, try to find a health UUID.
if (($health_agent_name) && ($health_source_name))
{
# See if we can find an entry. If not, this might be a simple check to clear.
my $query = "
SELECT
health_uuid
FROM
health
WHERE
health_host_uuid = ".$anvil->Database->quote($health_host_uuid)."
AND
health_agent_name = ".$anvil->Database->quote($health_agent_name)."
AND
health_source_name = ".$anvil->Database->quote($health_source_name)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
$health_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { health_uuid => $health_uuid }});
}
else
{
# Silently exit.
return("");
}
}
else
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_health()", parameter => "health_uuid" }});
return("");
}
}
# Still alive? do a DELETE.
my $query = "
UPDATE
health
@ -6855,7 +6895,7 @@ WHERE
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
$query = "
DELETE FROM
health
@ -12167,7 +12207,7 @@ sub insert_or_update_temperature
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_temperature()", parameter => "temperature_is" }});
return("");
}
elsif (($temperature_is ne "nominal") && ($temperature_is ne "warning") && ($temperature_is ne "critical"))
elsif (($temperature_is ne "nominal") && ($temperature_is ne "high") && ($temperature_is ne "low"))
{
# Invalid value.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0547", variables => { temperature_is => $temperature_is }});

@ -925,8 +925,8 @@ sub find_changes
my $new_swap_bytes_used = $new_scan_hardware_swap_total - $new_scan_hardware_swap_free;
my $old_swap_bytes_used = $old_scan_hardware_swap_total - $old_scan_hardware_swap_free;
my $new_swap_percent_used = $anvil->Math->round({number => (($new_swap_bytes_used / $new_scan_hardware_swap_total) * 100)});
my $old_swap_percent_used = $anvil->Math->round({number => (($old_swap_bytes_used / $old_scan_hardware_swap_total) * 100)});
my $new_swap_percent_used = $anvil->Convert->round({number => (($new_swap_bytes_used / $new_scan_hardware_swap_total) * 100)});
my $old_swap_percent_used = $anvil->Convert->round({number => (($old_swap_bytes_used / $old_scan_hardware_swap_total) * 100)});
my $swap_percent_high = $anvil->data->{scancore}{'scan-hardware'}{swap}{high_threshold} =~ /^\d+/ ? $anvil->data->{scancore}{'scan-hardware'}{swap}{high_threshold} : 75;
my $swap_percent_low = $anvil->data->{scancore}{'scan-hardware'}{swap}{clear_threshold} =~ /^\d+/ ? $anvil->data->{scancore}{'scan-hardware'}{swap}{clear_threshold} : 25;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -1356,7 +1356,7 @@ sub process_health
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }});
}
elsif (($peer_ram_total == $hardware_ram_total) or ($difference < $anvil->data->{scancore}{'scan-hardware'}{ram}{clear_threshold}))
elsif ((not $difference) or ($difference < $anvil->data->{scancore}{'scan-hardware'}{ram}{clear_threshold}))
{
my $age = $anvil->Alert->check_condition_age({
debug => 2,
@ -1364,6 +1364,7 @@ sub process_health
name => "scan-hardware::less_ram_than_peer",
host_uuid => $anvil->Get->host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { age => $age }});
my $changed = $anvil->Alert->check_alert_sent({
debug => 3,
record_locator => "scan_hardware::less_ram_than_peer",
@ -1381,10 +1382,10 @@ sub process_health
$anvil->Alert->register({alert_level => "warning", message => "scan_hardware_alert_0028", variables => $variables, set_by => $THIS_FILE});
}
my ($health_uuid) = $anvil->Database->insert_or_update_health({
debug => 2,
health_agent_name => $THIS_FILE,
health_source_name => "less_ram_than_peer",
health_source_weight => 0,
debug => 2,
health_agent_name => $THIS_FILE,
health_source_name => "less_ram_than_peer",
'delete' => 1,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }});
}

@ -416,6 +416,8 @@ The attempt to start the servers appears to have failed. The return code '0' was
<key name="error_0302">The passed in Anvil! UUID: [#!variable!anvil_uuid!#] was not found in the database.</key>
<key name="error_0303">The passed in host UUID: [#!variable!host_uuid!#] was not found in the database.</key>
<key name="error_0304">Failed to parse the request body: [#!variable!request_body_string!#]. Reason: [#!variable!json_decode_error!#]</key>
<key name="error_0305">Unable to connect to the database, unable to manage a server at this time.</key>
<key name="error_0306">Unable to connect to the database, unable to provision a server at this time.</key>
<!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -2145,6 +2147,8 @@ Are you sure that you want to delete the server: [#!variable!server_name!#]? [Ty
<key name="message_0248">Created the journald directory: [#!variable!directory!#].</key>
<key name="message_0249">Checking that the daemon: [#!variable!daemon!#] is running.</key>
<key name="message_0250">The daemon: [#!variable!daemon!#] was not running, starting it now.</key>
<key name="message_0251">Preparing to manage a server.</key>
<key name="message_0252">Found the server: [#!variable!server_name!#] in the database, loading details now.</key>
<!-- Success messages shown to the user -->
<key name="ok_0001">Saved the mail server information successfully!</key>

@ -13,6 +13,8 @@
use strict;
use warnings;
use Anvil::Tools;
require POSIX;
use Term::Cap;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
@ -26,35 +28,106 @@ $| = 1;
my $anvil = Anvil::Tools->new();
$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}{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}{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->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::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::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'},
'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 => 2, secure => 0, key => "log_0132"});
$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!
interactive_question($anvil);
}
$anvil->nice_exit({exit_code => 0});
# Make sure we're in an Anvil!
$anvil->data->{sys}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid();
@ -137,6 +210,146 @@ $anvil->nice_exit({exit_code => 0});
# Functions #
#############################################################################################################
sub run_jobs
{
my ($anvil) = @_;
return(0);
}
sub interactive_question
{
my ($anvil) = @_;
$anvil->Database->get_anvils();
$anvil->Database->get_servers();
### 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.
if ($anvil->data->{switches}{server})
{
if ($anvil->Validate->uuid({uuid => $anvil->data->{switches}{server}}))
{
$anvil->data->{target_server}{server_uuid} = $anvil->data->{switches}{server};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"target_server::server_uuid" => $anvil->data->{target_server}{server_uuid},
}});
}
else
{
$anvil->data->{target_server}{server_name} = $anvil->data->{switches}{server};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"target_server::server_name" => $anvil->data->{target_server}{server_name},
}});
}
}
# Do we know or can we find the Anvil! UUID?
$anvil->data->{target_server}{server_uuid} = $anvil->data->{switches}{'server-uuid'} ? $anvil->data->{switches}{'server-uuid'} : "";
$anvil->data->{target_server}{server_name} = $anvil->data->{switches}{'server-name'} ? $anvil->data->{switches}{'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},
}});
# 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};
if (exists $anvil->data->{servers}{server_uuid}{$server_uuid})
{
# We can divine everthing from this.
$anvil->data->{target_server}{server_name} = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"target_server::server_name" => $anvil->data->{target_server}{server_name},
}});
}
}
if (not $anvil->data->{target_server}{server_name})
{
$anvil->data->{target_server}{server_name} = $anvil->Cluster->get_server_name({server_uuid => $anvil->data->{target_server}{server_uuid}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "target_server::server_name" => $anvil->data->{target_server}{server_name} }});
}
elsif (not $anvil->data->{target_server}{server_uuid})
{
$anvil->data->{target_server}{server_uuid} = $anvil->Cluster->get_server_uuid({server_name => $anvil->data->{target_server}{server_name}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "target_server::server_uuid" => $anvil->data->{target_server}{server_uuid} }});
}
### 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?
$anvil->data->{target_server}{anvil_uuid} = $anvil->data->{switches}{'anvil-uuid'} ? $anvil->data->{switches}{'anvil-uuid'} : "";
$anvil->data->{target_server}{anvil_name} = $anvil->data->{switches}{'anvil-name'} ? $anvil->data->{switches}{'anvil-name'} : "";
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},
}});
}
}
elsif (not $anvil->data->{target_server}{anvil_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} }});
}
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 this is a node, load the anvil_uuid automatically.
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/);
return(0);
}
sub show_stats
{
my ($anvil) = @_;

@ -65,7 +65,7 @@ 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_0077"});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0306"});
sleep 10;
$anvil->nice_exit({exit_code => 1});
}

Loading…
Cancel
Save