* Created Cluster->get_anvil_uuid() that returns the 'anvil_uuid' of a given 'host_uuid'.

* Renamed the 'defitintions' table to 'server_definitions' to clarify the purpose, and made all the 'server' columns have then 'not null' constraint.
* Created Database->insert_or_update_servers(), ->get_servers(), ->insert_or_update_server_definitions() and ->get_server_definitions().
* Updated scancore, anvil-daemon, and scan agents to not run unless they're run with root privs.
* Got scan-server to update the servers / server_definition tables and the on-disk file when needed.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent e85823fe16
commit 1a1fa7ce88
  1. 55
      Anvil/Tools/Cluster.pm
  2. 342
      Anvil/Tools/Database.pm
  3. 3
      Anvil/Tools/ScanCore.pm
  4. 145
      notes
  5. 15
      scancore-agents/scan-cluster/scan-cluster
  6. 15
      scancore-agents/scan-hardware/scan-hardware
  7. 199
      scancore-agents/scan-server/scan-server
  8. 15
      scancore-agents/scan-server/scan-server.xml
  9. 62
      share/anvil.sql
  10. 29
      share/words.xml
  11. 15
      tools/anvil-daemon
  12. 16
      tools/scancore

@ -288,6 +288,61 @@ sub check_node_status
return($anvil->data->{cib}{parsed}{data}{node}{$node_name}{node_state}{ready});
}
=head2 get_anvil_uuid
This returns the C<< anvils >> -> C<< anvil_uuid >> that a host belongs to. If the host is not found in any Anvil!, an empty string is returned.
Parameters;
=head3 host_uuid (optional, default Get->host_uuid)
This is the C<< host_uuid >> of the host who we're looking for Anvil! membership of.
=cut
sub get_anvil_uuid
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Cluster->check_node_status()" }});
my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
host_uuid => $host_uuid,
}});
# Load the Anvil! data.
$anvil->Database->get_anvils({debug => $debug});
my $member_anvil_uuid = "";
foreach my $anvil_uuid (keys %{$anvil->data->{anvils}{anvil_uuid}})
{
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
my $anvil_node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $anvil_node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
my $anvil_dr1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
anvil_name => $anvil_name,
anvil_node1_host_uuid => $anvil_node1_host_uuid,
anvil_node2_host_uuid => $anvil_node2_host_uuid,
anvil_dr1_host_uuid => $anvil_dr1_host_uuid,
}});
if (($host_uuid eq $anvil_node1_host_uuid) or
($host_uuid eq $anvil_node2_host_uuid) or
($host_uuid eq $anvil_dr1_host_uuid))
{
# Found ot!
$member_anvil_uuid = $anvil_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { member_anvil_uuid => $member_anvil_uuid }});
last;
}
}
return($member_anvil_uuid);
}
=head2 get_peers
This method uses the local machine's host UUID and finds the host names of the cluster memebers. If this host is in a cluster and it is a node, the peer's short host name is returned. Otherwise, an empty string is returned.

@ -8,8 +8,9 @@ use warnings;
use DBI;
use Scalar::Util qw(weaken isweak);
use Data::Dumper;
use Time::HiRes qw(gettimeofday tv_interval);
use Text::Diff;
use Time::HiRes qw(gettimeofday tv_interval);
use XML::LibXML;
our $VERSION = "3.0.0";
my $THIS_FILE = "Database.pm";
@ -58,6 +59,8 @@ my $THIS_FILE = "Database.pm";
# insert_or_update_oui
# insert_or_update_power
# insert_or_update_recipients
# insert_or_update_servers
# insert_or_update_server_definitions
# insert_or_update_sessions
# insert_or_update_ssh_keys
# insert_or_update_states
@ -3184,13 +3187,13 @@ FROM
$anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_authentication} = $mail_server_authentication;
$anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_helo_domain} = $mail_server_helo_domain;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_address" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_address},
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_port" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_port},
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_username" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_username},
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_password" => $anvil->Log->is_secure($anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_password}),
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_security" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_security},
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_authentication" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_authentication},
"mail_servers::mail_server::${mail_server_uuid}}::mail_server_helo_domain" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_helo_domain},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_address" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_address},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_port" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_port},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_username" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_username},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_password" => $anvil->Log->is_secure($anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_password}),
"mail_servers::mail_server::${mail_server_uuid}::mail_server_security" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_security},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_authentication" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_authentication},
"mail_servers::mail_server::${mail_server_uuid}::mail_server_helo_domain" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_helo_domain},
}});
# Make it easy to look up the mail server's UUID from the server address.
@ -3510,11 +3513,11 @@ WHERE
$anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_level} = $recipient_level;
$anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host} = $recipient_level;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"recipients::recipient_uuid::${recipient_uuid}}::recipient_name" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_name},
"recipients::recipient_uuid::${recipient_uuid}}::recipient_email" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_email},
"recipients::recipient_uuid::${recipient_uuid}}::recipient_language" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_language},
"recipients::recipient_uuid::${recipient_uuid}}::recipient_level" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_level},
"recipients::recipient_uuid::${recipient_uuid}}::level_on_host" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host},
"recipients::recipient_uuid::${recipient_uuid}::recipient_name" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_name},
"recipients::recipient_uuid::${recipient_uuid}::recipient_email" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_email},
"recipients::recipient_uuid::${recipient_uuid}::recipient_language" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_language},
"recipients::recipient_uuid::${recipient_uuid}::recipient_level" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_level},
"recipients::recipient_uuid::${recipient_uuid}::level_on_host" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host},
}});
# Make it easy to look up the mail server's UUID from the server address.
@ -3538,7 +3541,7 @@ WHERE
{
$anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host} = $notification_alert_level;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"recipients::recipient_uuid::${recipient_uuid}}::level_on_host" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host},
"recipients::recipient_uuid::${recipient_uuid}::level_on_host" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{level_on_host},
}});
last;
}
@ -3582,7 +3585,7 @@ sub get_servers
delete $anvil->data->{sys}{servers}{by_uuid};
delete $anvil->data->{sys}{servers}{by_name};
my $query = "
my $query = "
SELECT
server_uuid,
server_name,
@ -3602,18 +3605,12 @@ FROM
;";
$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 $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if (not $count)
{
# I have a server_uuid but no matching record. Probably an error.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0216", variables => { uuid_name => "server_uuid", uuid => $server_uuid }});
return("");
}
foreach my $row (@{$results})
{
my $server_uuid = $row->[0];
@ -3658,7 +3655,6 @@ FROM
$anvil->data->{servers}{server_uuid}{$server_uuid}{server_post_migration_file_uuid} = $server_post_migration_file_uuid;
$anvil->data->{servers}{server_uuid}{$server_uuid}{server_post_migration_arguments} = $server_post_migration_arguments;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"servers::server_uuid::${server_uuid}::" => $anvil->data->{servers}{server_uuid}{$server_uuid}{},
"servers::server_uuid::${server_uuid}::server_anvil_uuid" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid},
"servers::server_uuid::${server_uuid}::server_clean_stop" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_clean_stop},
"servers::server_uuid::${server_uuid}::server_start_after_server_uuid" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_start_after_server_uuid},
@ -3677,6 +3673,96 @@ FROM
}
=head2 get_server_definitions
This loads all known server definition records from the database.
Data is stored in two formats;
server_definitions::server_definition_uuid::<server_definition_uuid>::server_definition_server_uuid
server_definitions::server_definition_uuid::<server_definition_uuid>::server_definition_xml
server_definitions::server_definition_uuid::<server_definition_uuid>::unix_modified_time
And;
server_definitions::server_definition_server_uuid::<server_definition_server_uuid>::$server_definition_uuid
server_definitions::server_definition_server_uuid::<server_definition_server_uuid>::server_definition_xml
server_definitions::server_definition_server_uuid::<server_definition_server_uuid>::unix_modified_time
This method takes no parameters.
=cut
sub get_server_definitions
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_server_definitions()" }});
# We're going to include the alert levels for this host based on overrides that might exist in the
# 'notifications' table. If the data hasn't already been loaded, we'll load it now.
if (not $anvil->data->{notifications}{notification_uuid})
{
$anvil->Database->get_notifications({debug => $debug});
}
my $host_uuid = $anvil->Get->host_uuid();
my $query = "
SELECT
server_definition_uuid,
server_definition_server_uuid,
server_definition_xml,
round(extract(epoch from modified_date)) AS mtime
FROM
server_definitions
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $server_definition_uuid = $row->[0];
my $server_definition_server_uuid = $row->[1];
my $server_definition_xml = $row->[2];
my $unix_modified_time = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
server_definition_uuid => $server_definition_uuid,
server_definition_server_uuid => $server_definition_server_uuid,
server_definition_xml => $server_definition_xml,
unix_modified_time => $unix_modified_time,
}});
# Store the data
$anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{server_definition_server_uuid} = $server_definition_server_uuid;
$anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{server_definition_xml} = $server_definition_xml;
$anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{unix_modified_time} = $unix_modified_time;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"server_definitions::server_definition_uuid::${server_definition_uuid}::server_definition_server_uuid" => $anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{server_definition_server_uuid},
"server_definitions::server_definition_uuid::${server_definition_uuid}::server_definition_xml" => $anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{server_definition_xml},
"server_definitions::server_definition_uuid::${server_definition_uuid}::unix_modified_time" => $anvil->data->{server_definitions}{server_definition_uuid}{$server_definition_uuid}{unix_modified_time},
}});
# Make it easy to locate records by 'server_uuid' as well.
$anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{server_definition_uuid} = $server_definition_uuid;
$anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{server_definition_xml} = $server_definition_xml;
$anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{unix_modified_time} = $unix_modified_time;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"server_definitions::server_definition_server_uuid::${server_definition_server_uuid}::$server_definition_uuid" => $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{server_definition_uuid},
"server_definitions::server_definition_server_uuid::${server_definition_server_uuid}::server_definition_xml" => $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{server_definition_xml},
"server_definitions::server_definition_server_uuid::${server_definition_server_uuid}::unix_modified_time" => $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_definition_server_uuid}{unix_modified_time},
}});
}
return(0);
}
=head2 get_ssh_keys
This loads all known user's SSH public keys and all known machine's public keys into the data hash. On success, this method returns C<< 0 >>. If any problems occur, C<< 1 >> is returned.
@ -9274,7 +9360,7 @@ sub insert_or_update_servers
# Do we already know about this
my $exists = 0;
my $query = "SELECT COUNT(*) FROM servers WHERE server_uuid = ".$anvil->Database->quote($server_uuid).";";
my $count = $anvil->Database->query({query => $function_query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }});
if ($count)
{
@ -9305,7 +9391,7 @@ sub insert_or_update_servers
my $old_server_state = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_server_state => $old_server_state }});
if ($old_server_name ne "DELETED")
if ($old_server_state ne "DELETED")
{
my $query = "
UPDATE
@ -9474,6 +9560,212 @@ WHERE
}
=head2 insert_or_update_server_definitions
This inserts or updates the C<< server_definitions >> table used to store (virtual) server XML definitions.
Parameters;
=head3 server_definition_uuid (optional)
This is the server_definition UUID of a specific record to update.
=head3 server_definition_server_uuid (required)
This is the C<< servers >> -> C<< server_uuid >> of the server whose server_definition this belongs to.
server_definition_xml (required)
This is the server's XML definition file itself.
=cut
sub insert_or_update_server_definitions
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_server_definitions()" }});
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : "";
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $server_definition_uuid = defined $parameter->{server_definition_uuid} ? $parameter->{server_definition_uuid} : "";
my $server_definition_server_uuid = defined $parameter->{server_definition_server_uuid} ? $parameter->{server_definition_server_uuid} : "";
my $server_definition_xml = defined $parameter->{server_definition_xml} ? $parameter->{server_definition_xml} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
file => $file,
line => $line,
server_definition_uuid => $server_definition_uuid,
server_definition_server_uuid => $server_definition_server_uuid,
server_definition_xml => $server_definition_xml,
}});
if (not $server_definition_server_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_server_definitions()", parameter => "server_definition_server_uuid" }});
return("!!error!!");
}
if (not $anvil->Validate->uuid({uuid => $server_definition_server_uuid}))
{
# Bad UUID.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0130", variables => { method => "Database->insert_or_update_server_definitions()", parameter => "server_definition_server_uuid", uuid => $server_definition_server_uuid }});
return("!!error!!");
}
if (not $server_definition_xml)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_server_definitions()", parameter => "server_definition_xml" }});
return("!!error!!");
}
# Make sure the server_definition_xml looks valid.
local $@;
my $dom = eval { XML::LibXML->load_xml(string => $server_definition_xml); };
if ($@)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0066", variables => {
xml => $server_definition_xml,
error => $@,
}});
return("!!error!!");
}
# Verify that I can read the UUID from the XML and verify that it matches the
# 'server_definition_server_uuid'.
my $server_name = $dom->findvalue('/domain/name');
my $read_uuid = $dom->findvalue('/domain/uuid');
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
server_name => $server_name,
read_uuid => $read_uuid,
}});
if (not $read_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0067", variables => { xml => $server_definition_xml }});
return("!!error!!");
}
elsif ($read_uuid ne $server_definition_server_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0067", variables => {
passed_uuid => $server_definition_server_uuid,
read_uuid => $read_uuid,
xml => $server_definition_xml,
}});
return("!!error!!");
}
# If we don't have a server_definition_uuid, look for one using the server_uuid.
if (not $server_definition_uuid)
{
my $query = "
SELECT
server_definition_uuid
FROM
server_definitions
WHERE
server_definition_server_uuid = ".$anvil->Database->quote($server_definition_server_uuid)."
;";
$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)
{
$server_definition_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { server_definition_uuid => $server_definition_uuid }});
}
}
# UPDATE or INSERT.
if ($server_definition_uuid)
{
# Is there any difference?
my $query = "
SELECT
server_definition_server_uuid,
server_definition_xml
FROM
server_definitions
WHERE
server_definition_uuid = ".$anvil->Database->quote($server_definition_uuid)."
;";
$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,
}});
foreach my $row (@{$results})
{
my $old_server_definition_server_uuid = $row->[0];
my $old_server_definition_xml = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_server_definition_server_uuid => $old_server_definition_server_uuid,
old_server_definition_xml => $old_server_definition_xml,
}});
if (($old_server_definition_server_uuid ne $server_definition_server_uuid) or
($old_server_definition_xml ne $server_definition_xml))
{
# If the server_definition is what changed, log the diff.
if ($old_server_definition_xml ne $server_definition_xml)
{
my $difference = diff \$old_server_definition_xml, \$server_definition_xml, { STYLE => 'Unified' };
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0556", variables => {
server_name => $server_name,
server_definition_server_uuid => $server_definition_server_uuid,
difference => $difference,
}});
}
# Save the changes.
my $query = "
UPDATE
server_definitions
SET
server_definition_xml = ".$anvil->Database->quote($server_definition_xml).",
server_definition_server_uuid = ".$anvil->Database->quote($server_definition_server_uuid).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
server_definition_uuid = ".$anvil->Database->quote($server_definition_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query =~ /passw/ ? $anvil->Log->is_secure($query) : $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
}
}
else
{
$server_definition_uuid = $anvil->Get->uuid();
my $query = "
INSERT INTO
server_definitions
(
server_definition_uuid,
server_definition_server_uuid,
server_definition_xml,
modified_date
) VALUES (
".$anvil->Database->quote($server_definition_uuid).",
".$anvil->Database->quote($server_definition_server_uuid).",
".$anvil->Database->quote($server_definition_xml).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
);
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query =~ /passw/ ? $anvil->Log->is_secure($query) : $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
return($server_definition_uuid);
}
=head2 insert_or_update_sessions
This updates (or inserts) a record in the 'sessions' table. The C<< session_uuid >> referencing the database row will be returned.

@ -132,6 +132,9 @@ sub agent_startup
return("!!error!!");
}
my $table_count = @{$tables};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { table_count => $table_count }});
# It's possible that some agents don't have a database (or use core database tables only)
if (@{$tables} > 0)
{

145
notes

@ -264,6 +264,151 @@ CREATE TRIGGER trigger_temperature
AFTER INSERT OR UPDATE ON temperature
FOR EACH ROW EXECUTE PROCEDURE history_temperature();
DROP FUNCTION history_definitions() CASCADE;
DROP TABLE history.definitions;
DROP TABLE definitions;
DROP FUNCTION history_servers() CASCADE;
DROP TABLE history.servers;
DROP TABLE servers;
-- This stores servers made available to Anvil! systems and DR hosts.
CREATE TABLE servers (
server_uuid uuid not null primary key,
server_name text not null, -- This is the server's name. It can change without re-uploading the server.
server_anvil_uuid uuid not null, -- This is the Anvil! system that the server lives on. It can move to another Anvil!, so this can change.
server_clean_stop boolean not null default FALSE, -- When set, the server was stopped by a user. The Anvil! will not start a server that has been cleanly stopped.
server_start_after_server_uuid uuid not null, -- This can be the server_uuid of another server. If set, this server will boot 'server_start_delay' seconds after the referenced server boots. A value of '00000000-0000-0000-0000-000000000000' will tell 'anvil-safe-start' to not boot the server at all. If a server is set not to start, any dependent servers will also stay off.
server_start_delay integer not null default 0, -- See above.
server_host_uuid uuid not null, -- This is the current hosts -> host_uuid for this server. If the server is off, this will be blank.
server_state text not null, -- This is the current state of this server.
server_live_migration boolean not null default TRUE, -- When false, servers will be stopped and then rebooted when a migration is requested. Also, when false, preventative migrations will not happen.
server_pre_migration_file_uuid uuid not null, -- This is set to the files -> file_uuid of a script to run BEFORE migrating a server. If the file isn't found or can't run, the script is ignored.
server_pre_migration_arguments text not null, -- These are arguments to pass to the pre-migration script
server_post_migration_file_uuid uuid not null, -- This is set to the files -> file_uuid of a script to run AFTER migrating a server. If the file isn't found or can't run, the script is ignored.
server_post_migration_arguments text not null, -- These are arguments to pass to the post-migration script
modified_date timestamp with time zone not null,
FOREIGN KEY(server_anvil_uuid) REFERENCES anvils(anvil_uuid),
FOREIGN KEY(server_start_after_server_uuid) REFERENCES servers(server_uuid),
FOREIGN KEY(server_host_uuid) REFERENCES hosts(host_uuid),
FOREIGN KEY(server_pre_migration_file_uuid) REFERENCES files(file_uuid),
FOREIGN KEY(server_post_migration_file_uuid) REFERENCES files(file_uuid)
);
ALTER TABLE servers OWNER TO admin;
CREATE TABLE history.servers (
history_id bigserial,
server_uuid uuid,
server_name text,
server_anvil_uuid uuid,
server_clean_stop boolean,
server_start_after_server_uuid uuid,
server_start_delay integer,
server_host_uuid uuid,
server_state text,
server_live_migration boolean,
server_pre_migration_file_uuid uuid,
server_pre_migration_arguments text,
server_post_migration_file_uuid uuid,
server_post_migration_arguments text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.servers OWNER TO admin;
CREATE FUNCTION history_servers() RETURNS trigger
AS $$
DECLARE
history_servers RECORD;
BEGIN
SELECT INTO history_servers * FROM servers WHERE server_uuid = new.server_uuid;
INSERT INTO history.servers
(server_uuid,
server_name,
server_anvil_uuid,
server_clean_stop,
server_start_after_server_uuid,
server_start_delay,
server_host_uuid,
server_state,
server_live_migration,
server_pre_migration_file_uuid,
server_pre_migration_arguments,
server_post_migration_file_uuid,
server_post_migration_arguments,
modified_date)
VALUES
(history_servers.server_uuid,
history_servers.server_name,
history_servers.server_clean_stop,
history_servers.server_start_after_server_uuid,
history_servers.server_start_delay,
history_servers.server_host_uuid,
history_servers.server_state,
history_servers.server_live_migration,
history_servers.server_pre_migration_file_uuid,
history_servers.server_pre_migration_arguments,
history_servers.server_post_migration_file_uuid,
history_servers.server_post_migration_arguments,
history_servers.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_servers() OWNER TO admin;
CREATE TRIGGER trigger_servers
AFTER INSERT OR UPDATE ON servers
FOR EACH ROW EXECUTE PROCEDURE history_servers();
-- This stores the XML definition for a server. Whenever a server_definition is found missing on a node or DR host,
-- it will be rewritten from here. If this copy changes, it will be updated on the hosts.
CREATE TABLE server_definitions (
server_definition_uuid uuid not null primary key,
server_definition_server_uuid uuid not null, -- This is the servers -> server_uuid of the server
server_definition_xml text not null, -- This is the XML body.
modified_date timestamp with time zone not null,
FOREIGN KEY(server_definition_server_uuid) REFERENCES servers(server_uuid)
);
ALTER TABLE server_definitions OWNER TO admin;
CREATE TABLE history.server_definitions (
history_id bigserial,
server_definition_uuid uuid,
server_definition_server_uuid uuid,
server_definition_xml text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.server_definitions OWNER TO admin;
CREATE FUNCTION history_server_definitions() RETURNS trigger
AS $$
DECLARE
history_server_definitions RECORD;
BEGIN
SELECT INTO history_server_definitions * FROM server_definitions WHERE server_definition_uuid = new.server_definition_uuid;
INSERT INTO history.server_definitions
(server_definition_uuid,
server_definition_server_uuid,
server_definition_xml,
modified_date)
VALUES
(history_server_definitions.server_definition_uuid,
history_server_definitions.server_definition_server_uuid,
history_server_definitions.server_definition_xml,
history_server_definitions.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_server_definitions() OWNER TO admin;
CREATE TRIGGER trigger_server_definitions
AFTER INSERT OR UPDATE ON server_definitions
FOR EACH ROW EXECUTE PROCEDURE history_server_definitions();
COMMIT;
============

@ -9,7 +9,7 @@
#
# Exit codes;
# 0 = Normal exit.
# 1 = Startup failure (no DB, bad file read, etc)
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
#
# TODO:
# -
@ -23,6 +23,10 @@ use Data::Dumper;
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
@ -34,6 +38,15 @@ my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
$anvil->data->{scancore}{'scan-cluster'}{disable} = 0;
$anvil->data->{switches}{force} = 0;

@ -6,7 +6,7 @@
#
# Exit codes;
# 0 = Normal exit.
# 1 = Startup failure (no DB, bad file read, etc)
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
#
# TODO:
# -
@ -20,6 +20,10 @@ use Data::Dumper;
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
@ -31,6 +35,15 @@ my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
# These are the threasholds for when to alert when swap is running out.
$anvil->data->{scancore}{'scan-hardware'}{disable} = 0;
$anvil->data->{scancore}{'scan-hardware'}{ram}{clear_threshold} = 134217728; # 128 MiB

@ -8,7 +8,7 @@
#
# Exit codes;
# 0 = Normal exit.
# 1 = Startup failure (no DB, bad file read, etc)
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
# 2 = libvirtd is not running.
#
# TODO:
@ -19,10 +19,15 @@ use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use Text::Diff;
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
@ -34,6 +39,15 @@ my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
$anvil->data->{scancore}{'scan-server'}{disable} = 0;
$anvil->data->{switches}{force} = 0;
@ -50,7 +64,7 @@ if (($anvil->data->{scancore}{'scan-server'}{disable}) && (not $anvil->data->{sw
}
# This scan agent only uses core tables (server and definitions).
$anvil->data->{scancore}{'scan-server'}{tables} = [""];
$anvil->data->{scancore}{'scan-server'}{tables} = [];
# Handle start-up tasks
my $problem = $anvil->ScanCore->agent_startup({
@ -103,6 +117,10 @@ sub collect_data
$anvil->nice_exit({exit_code => 2});
}
# Load data we know about
$anvil->Database->get_servers({debug => 2});
$anvil->Database->get_server_definitions({debug => 2});
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list --all", source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output, return_code => $return_code }});
foreach my $line (split/\n/, $output)
@ -112,8 +130,8 @@ sub collect_data
if ($line =~ /^\d+ (.*?) (.*)$/)
{
my $server = $1;
my $state = $2;
my $server = $1;
my $state = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
server => $server,
'state' => $state,
@ -165,25 +183,174 @@ sub collect_data
}
my $server_uuid = $anvil->data->{server}{$target}{$server}{$source}{info}{uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server_uuid => $server_uuid }});
my $server_name = $anvil->data->{server}{$target}{$server}{$source}{info}{name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
server_uuid => $server_uuid,
server_name => $server_name,
}});
# See if this server is in the database.
my $query = "SELECT COUNT(*) FROM servers WHERE server_uuid = ".$anvil->Database->quote($server_uuid).";";
my $count = $anvil->Database->query({query => $function_query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }});
if (not $count)
if (not exists $anvil->data->{servers}{server_uuid}{$server_uuid})
{
# Add it. I'll need my anvil_uuid first.
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid({debug => 2});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
my $got_server_uuid = $anvil->Database->insert_or_update_servers({
debug => 2,
server_uuid => $server_uuid,
server_name => $server_name,
server_anvil_uuid => $anvil_uuid,
server_clean_stop => "",
server_start_after_server_uuid => "",
server_start_delay => 0,
server_host_uuid => $anvil->Get->host_uuid,
server_state => $anvil->data->{'scan-server'}{server}{$server}{'state'},
server_live_migration => 1,
server_pre_migration_file_uuid => "",
server_pre_migration_arguments => "",
server_post_migration_file_uuid => "",
server_post_migration_arguments => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { got_server_uuid => $got_server_uuid }});
if ((not $got_server_uuid) or ($got_server_uuid eq "!!error!!"))
{
# What?
next;
}
else
{
# Store the definition from memory
my $server_definition_uuid = $anvil->Database->insert_or_update_server_definitions({
debug => 2,
server_definition_xml => $definition,
server_definition_server_uuid => $server_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_definition_uuid => $server_definition_uuid }});
if ((not $server_definition_uuid) or ($server_definition_uuid ne "!!error!!"))
{
# What?
next;
}
}
# Reload the servers.
$anvil->Database->get_servers({debug => 2});
$anvil->Database->get_server_definitions({debug => 2});
}
# If the defition in the database isn't the same as the definition in memory, update it.
if ($definition ne $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_xml})
{
# Register a notice-level alert.
my $difference = diff \$anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_xml}, \$definition, { STYLE => 'Unified' };
my $variables = {
server => $server,
difference => $difference,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_server_alert_0001", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_server_alert_0001",
message_variables => $variables,
set_by => $THIS_FILE,
});
# Update the definition in the database.
my $server_definition_uuid = $anvil->Database->insert_or_update_server_definitions({
debug => 2,
server_definition_xml => $definition,
server_definition_server_uuid => $server_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_definition_uuid => $server_definition_uuid }});
if ((not $server_definition_uuid) or ($server_definition_uuid ne "!!error!!"))
{
# What?
next;
}
$anvil->Database->get_server_definitions({debug => 2});
}
### NOTE: If the disk version differs from the in-memory or in-database copy, and the
### age of the file on disk is newer than the age of the database record (which will
### match the in-memory definition by this point), we'll leave the disk version alone.
### This is done so that a manual edit of the definition file won't be immediately
### overwritten by the definition in memory.
# If the file doesn't exist, we'll write it out.
# If it does exist, but differs from the version in memory, we'll write the file.
my $write_file = 0;
my $xml_file = $anvil->data->{path}{directories}{shared}{definitions}."/".$server.".xml";
if (not -e $xml_file)
{
# Add it.
$write_file = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { write_file => $write_file }});
}
else
{
my $on_disk_definition = $anvil->Storage->read_file({
debug => 2,
file => $xml_file,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { on_disk_definition => $on_disk_definition }});
if (($on_disk_definition ne "!!error!!") && ($on_disk_definition) && ($definition ne $on_disk_definition))
{
$anvil->Storage->get_file_stats({
debug => 2,
file_path => $xml_file,
});
### TODO: left off here, look for the XML file on disk. If it's not found, write it.
my $xml_file = $anvil->data->{path}{directories}{shared}{definitions}."/".$server.".xml";
if (-e $xml_file)
my $current_time = time;
my $file_modified_time = $anvil->data->{file_stat}{$xml_file}{modified_time};
my $database_modified_time = $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{unix_modified_time};
my $file_age = $current_time - $file_modified_time;
my $database_age = $current_time - $database_modified_time;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:current_time' => $current_time,
's2:file_modified_time' => $file_modified_time,
's3:database_modified_time' => $database_modified_time,
's4:file_age' => $file_age,
's5:database_age' => $database_age,
}});
# Compare the age of the on-disk file with the age of the database record. If
# the database age is newer, update the on-disk copy.
if ($file_age >= $database_age)
{
# Update the disk copy.
my $difference = diff \$anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_xml}, \$definition, { STYLE => 'Unified' };
my $variables = {
server => $server,
difference => $difference,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_server_alert_0002", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_server_alert_0002",
message_variables => $variables,
set_by => $THIS_FILE,
});
$write_file = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { write_file => $write_file }});
}
}
}
if ($write_file)
{
$anvil->Storage->get_file_stats({
debug => 2,
file_path => $xml_file,
my $return = $anvil->Storage->write_file({
debug => 3,
body => $definition,
file => $xml_file,
overwrite => 1,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return }});
if ($return)
{
# Something went wrong.
next;
}
}
}

@ -14,7 +14,20 @@ NOTE: All string keys MUST be prefixed with the agent name! ie: 'scan_server_log
<language name="en_CA" long_name="Canadian English" description="ScanCore scan agent that monitors hardware, like RAM modules, CSS LED status, CPU information, etc.">
<!-- Alert entries -->
<key name="scan_server_alert_0001"></key>
<key name="scan_server_alert_0001">
The definition file for the server: [#!variable!server!#] has changed relative to the database record. This is usually harmless.
The differences are:
====
#!variable!difference!#
====
</key>
<key name="scan_server_alert_0002">
The definition file for the server: [#!variable!server!#] has changed relative to disk record. This is usually harmless.
The differences are:
====
#!variable!difference!#
====
</key>
<!-- Log entries -->
<key name="scan_server_log_0001">Starting: [#!variable!program!#].</key>

@ -1325,52 +1325,52 @@ CREATE TRIGGER trigger_servers
FOR EACH ROW EXECUTE PROCEDURE history_servers();
-- This stores the XML definition for a server. Whenever a definition is found missing on a node or DR host,
-- This stores the XML definition for a server. Whenever a server_definition is found missing on a node or DR host,
-- it will be rewritten from here. If this copy changes, it will be updated on the hosts.
CREATE TABLE definitions (
definition_uuid uuid not null primary key,
definition_server_uuid uuid not null, -- This is the servers -> server_uuid of the server
definition_xml text not null, -- This is the XML body.
modified_date timestamp with time zone not null,
CREATE TABLE server_definitions (
server_definition_uuid uuid not null primary key,
server_definition_server_uuid uuid not null, -- This is the servers -> server_uuid of the server
server_definition_xml text not null, -- This is the XML body.
modified_date timestamp with time zone not null,
FOREIGN KEY(definition_server_uuid) REFERENCES servers(server_uuid)
FOREIGN KEY(server_definition_server_uuid) REFERENCES servers(server_uuid)
);
ALTER TABLE definitions OWNER TO admin;
CREATE TABLE history.definitions (
history_id bigserial,
definition_uuid uuid,
definition_server_uuid uuid,
definition_xml text,
modified_date timestamp with time zone not null
ALTER TABLE server_definitions OWNER TO admin;
CREATE TABLE history.server_definitions (
history_id bigserial,
server_definition_uuid uuid,
server_definition_server_uuid uuid,
server_definition_xml text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.definitions OWNER TO admin;
ALTER TABLE history.server_definitions OWNER TO admin;
CREATE FUNCTION history_definitions() RETURNS trigger
CREATE FUNCTION history_server_definitions() RETURNS trigger
AS $$
DECLARE
history_definitions RECORD;
history_server_definitions RECORD;
BEGIN
SELECT INTO history_definitions * FROM definitions WHERE definition_uuid = new.definition_uuid;
INSERT INTO history.definitions
(definition_uuid,
definition_server_uuid,
definition_xml,
SELECT INTO history_server_definitions * FROM server_definitions WHERE server_definition_uuid = new.server_definition_uuid;
INSERT INTO history.server_definitions
(server_definition_uuid,
server_definition_server_uuid,
server_definition_xml,
modified_date)
VALUES
(history_definitions.definition_uuid,
history_definitions.definition_server_uuid,
history_definitions.definition_xml,
history_definitions.modified_date);
(history_server_definitions.server_definition_uuid,
history_server_definitions.server_definition_server_uuid,
history_server_definitions.server_definition_xml,
history_server_definitions.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_definitions() OWNER TO admin;
ALTER FUNCTION history_server_definitions() OWNER TO admin;
CREATE TRIGGER trigger_definitions
AFTER INSERT OR UPDATE ON definitions
FOR EACH ROW EXECUTE PROCEDURE history_definitions();
CREATE TRIGGER trigger_server_definitions
AFTER INSERT OR UPDATE ON server_definitions
FOR EACH ROW EXECUTE PROCEDURE history_server_definitions();
-- It stores a general list of OUI (Organizationally Unique Identifier) to allow lookup of MAC address to

@ -1058,6 +1058,11 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0553">The server: [#!variable!server!#] has booted!</key>
<key name="log_0554">Waiting for the server: [#!variable!server!#] to shut down...</key>
<key name="log_0555">The server: [#!variable!server!#] is now off.</key>
<key name="log_0556">The server: [#!variable!server!#] (#!variable!server_uuid!#) has a definition change:
====
#!variable!difference!#
====
</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
@ -1857,6 +1862,30 @@ The error was:
</key>
<key name="warning_0064">[ Warning ] - The server: [#!variable!server!#] was asked to be migrated to: [#!variable!requested_node!#], but the server is shutting down. Aborting.</key>
<key name="warning_0065">[ Warning ] - The server: [#!variable!server!#] was asked to be migrated to: [#!variable!requested_node!#], but the server is already in the middle of a migration. Aborting.</key>
<key name="warning_0066">[ Warning ] - Failed to parse the XML:
========
#!variable!xml!#
========
The error was:
========
#!variable!error!#
========
</key>
<key name="warning_0067">[ Warning ] - Failed to find the server's UUID from the definition XML:
========
#!variable!xml!#
========
</key>
<key name="warning_0068">[ Warning ] - The server UUID read: from the definition XML doesn't match the passed-in server UUID.
Passed in UUID: [#!variable!passed_uuid!#]
Read UUID: .... [#!variable!read_uuid!#]
========
#!variable!xml!#
========
</key>
</language>
<!-- 日本語 -->

@ -5,7 +5,7 @@
#
# Exit codes;
# 0 = Normal exit or md5sum of this program changed and it exited to reload.
# 1 =
# 1 = Not running as root.
# 2 = Unable to connect to any database, even after trying to initialize the local system.
#
# TODO:
@ -65,6 +65,10 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
# NOTE: Setting 'log_level' and 'log_secure' here will get overridden in the main lopp. Use the Log methods
# in the loop as well to override defaults in code.
my $anvil = Anvil::Tools->new();
@ -72,6 +76,15 @@ $anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
# 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({debug => 3, check_if_configured => 1});

@ -6,7 +6,8 @@
#
# Exit codes;
# 0 = Normal exit.
# 1 = No database connections available.
# 1 = Not running as root.
# 2 =
#
# TODO:
# - Decide if it's worth having a separate ScanCore.log file or just feed into anvil.log.
@ -20,6 +21,10 @@ use Data::Dumper;
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
@ -29,6 +34,15 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
$anvil->data->{scancore} = {
threshold => {
warning_temperature => 5,

Loading…
Cancel
Save