* Added 'check_if_configured' to Database->connect(), disabled off, that triggers the check to see if the system is configured or not. Updated anvil-daemon to invoke this at the same time that the md5sums are calculated to see if a reload is needed. This reduces the background system load a fair bit.

* Got more work done on deleting peers from Striker (technically done, but untested so far).

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 6 years ago
parent facefeaccc
commit e79e7fd4f4
  1. 41
      Anvil/Tools/Database.pm
  2. 100
      cgi-bin/striker
  3. 6
      html/skins/alteeve/main.css
  4. 38
      html/skins/alteeve/striker.html
  5. 4
      share/words.xml
  6. 26
      tools/anvil-daemon

@ -601,6 +601,12 @@ This module will return the number of databases that were successfully connected
Parameters;
=head3 check_if_configured (optional, default '0')
If set to C<< 1 >>, and if this is a locally hosted database, a check will be made to see if the database is configured. If it isn't, it will be configured.
B<< Note >>: This is expensive, so should only be called periodically. This will do nothing if not called with C<< root >> access, or if the database is not local.
=head3 db_uuid (optional)
If set, the connection will be made only to the database server matching the UUID.
@ -652,17 +658,19 @@ sub connect
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->connect()" }});
my $source = defined $parameter->{source} ? $parameter->{source} : "core";
my $sql_file = defined $parameter->{sql_file} ? $parameter->{sql_file} : $anvil->data->{path}{sql}{'anvil.sql'};
my $tables = defined $parameter->{tables} ? $parameter->{tables} : "";
my $test_table = defined $parameter->{test_table} ? $parameter->{test_table} : $anvil->data->{sys}{database}{test_table};
my $db_uuid = defined $parameter->{db_uuid} ? $parameter->{db_uuid} : "";
my $check_if_configured = defined $parameter->{check_if_configured} ? $parameter->{check_if_configured} : 0;
my $db_uuid = defined $parameter->{db_uuid} ? $parameter->{db_uuid} : "";
my $source = defined $parameter->{source} ? $parameter->{source} : "core";
my $sql_file = defined $parameter->{sql_file} ? $parameter->{sql_file} : $anvil->data->{path}{sql}{'anvil.sql'};
my $tables = defined $parameter->{tables} ? $parameter->{tables} : "";
my $test_table = defined $parameter->{test_table} ? $parameter->{test_table} : $anvil->data->{sys}{database}{test_table};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
source => $source,
sql_file => $sql_file,
tables => $tables,
test_table => $test_table,
db_uuid => $db_uuid,
check_if_configured => $check_if_configured,
db_uuid => $db_uuid,
source => $source,
sql_file => $sql_file,
tables => $tables,
test_table => $test_table,
}});
# If I wasn't passed an array reference of tables, use the core tables.
@ -808,8 +816,17 @@ sub connect
$anvil->data->{sys}{database}{read_uuid} = $uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::read_uuid" => $anvil->data->{sys}{database}{read_uuid} }});
# Set it up (or update it) if needed. This method just returns if nothing is needed.
$anvil->Database->configure_pgsql({debug => $debug, uuid => $uuid});
# If requested, and if running with root access, set it up (or update it) if needed.
# This method just returns if nothing is needed.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
check_if_configured => $check_if_configured,
real_uid => $<,
effective_uid => $>,
}});
if (($check_if_configured) && ($< == 0) && ($> == 0))
{
$anvil->Database->configure_pgsql({debug => $debug, uuid => $uuid});
}
}
elsif (not $anvil->data->{sys}{database}{read_uuid})
{

@ -204,7 +204,7 @@ sub process_task
# cookies were deleted (via C<< Account->logout() >>. The user needs to log back in.
# 3 - There user's hash is invalid, it is probably expired. The user has been logged out and
# needs to log back in.
my $cookie_problem = $anvil->Account->read_cookies({debug => 2});
my $cookie_problem = $anvil->Account->read_cookies();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { cookie_problem => $cookie_problem }});
if (not $cookie_problem)
{
@ -315,7 +315,7 @@ sub process_power
# We don't need to store anything as hidden variables, we'll read it back from the database
# later.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "system_update_recorded", variables => {
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE,
@ -365,7 +365,7 @@ sub process_update
# We don't need to store anything as hidden variables, we'll read it back from the database
# later.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "system_update_recorded", variables => {
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE,
@ -453,22 +453,23 @@ sub process_sync_page
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_bidirection::value" => $anvil->data->{cgi}{new_peer_bidirection}{value} }});
}
# Are we adding a new peer?
if (($anvil->data->{cgi}{new_peer_access}{value}) && ($anvil->data->{cgi}{new_peer_password}{value} ne ""))
# Are we deleting or adding a new peer?
if ($anvil->data->{cgi}{'delete'}{value})
{
add_sync_peer($anvil);
if ($anvil->data->{form}{body})
{
# We're done
return(0);
}
delete_sync_peer($anvil);
}
elsif ($anvil->data->{cgi}{action}{value} eq "remove")
elsif (($anvil->data->{cgi}{new_peer_access}{value}) && ($anvil->data->{cgi}{new_peer_password}{value} ne ""))
{
#remove_sync_peer($anvil);
add_sync_peer($anvil);
}
# If we've got a body now, return.
if ($anvil->data->{form}{body})
{
# We're done
return(0);
}
my $host_uuid = $anvil->Get->host_uuid;
$anvil->System->get_ips();
@ -536,11 +537,13 @@ sub process_sync_page
$anvil->data->{peers}{$host}{name} = $name;
$anvil->data->{peers}{$host}{user} = $user;
$anvil->data->{peers}{$host}{ping} = $ping;
$anvil->data->{peers}{$host}{uuid} = $uuid;
$anvil->data->{peers}{$host}{password} = $password;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"peers::${host}::port" => $anvil->data->{peers}{$host}{port},
"peers::${host}::name" => $anvil->data->{peers}{$host}{name},
"peers::${host}::ping" => $anvil->data->{peers}{$host}{ping},
"peers::${host}::uuid" => $anvil->data->{peers}{$host}{uuid},
"peers::${host}::password" => $anvil->Log->secure ? $anvil->data->{peers}{$host}{password} : $anvil->Words->string({key => "log_0186"}),
}});
}
@ -552,6 +555,7 @@ sub process_sync_page
my $name = $anvil->data->{peers}{$host}{name};
my $user = $anvil->data->{peers}{$host}{user};
my $ping = $anvil->data->{peers}{$host}{ping};
my $uuid = $anvil->data->{peers}{$host}{uuid};
my $password = $anvil->data->{peers}{$host}{password};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host => $host,
@ -559,14 +563,16 @@ sub process_sync_page
name => $name,
user => $user,
ping => $ping,
uuid => $uuid,
password => $anvil->Log->secure ? $password : $anvil->Words->string({key => "log_0186"}),
}});
$anvil->data->{cgi}{new_peer_password}{value} = "" if not defined $anvil->data->{cgi}{new_peer_password}{value};
$peer_table .= $anvil->Template->get({file => "striker.html", name => "striker-sync-entry", variables => {
access => $port eq 5432 ? $user."\@".$host : $user."\@".$host.":".$port,
password => $anvil->data->{cgi}{new_peer_password}{value},
ping_checked => $ping ? "checked" : "",
uuid => $uuid,
access => $port eq 5432 ? $user."\@".$host : $user."\@".$host.":".$port,
password => $anvil->data->{cgi}{new_peer_password}{value},
say_ping => $ping ? "#!string!unit_0001!#" : "#!string!unit_0002!#",
}});
}
@ -581,6 +587,64 @@ sub process_sync_page
return(0);
}
# This deletes a sync peer.
sub delete_sync_peer
{
my ($anvil) = @_;
my $uuid = $anvil->data->{cgi}{'delete'}{value};
my $host_name = $anvil->Get->host_name({host_uuid => $uuid});
my $host = $anvil->data->{database}{$uuid}{host} ? $anvil->data->{database}{$uuid}{host} : ""; # This should fail
my $name = $anvil->data->{database}{$uuid}{name} ? $anvil->data->{database}{$uuid}{name} : $anvil->data->{sys}{database}{name};
my $user = $anvil->data->{database}{$uuid}{user} ? $anvil->data->{database}{$uuid}{user} : $anvil->data->{sys}{database}{user};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
uuid => $uuid,
host_name => $host_name,
host => $host,
name => $name,
user => $user,
}});
# Is the delete confirmed?
if ($anvil->data->{cgi}{confirm}{value})
{
# OK, save the job!
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_command => "anvil-manage-striker-peers --remove --host-uuid ".$uuid,
job_data => "",
job_name => "striker-peer::remove",
job_title => "job_0013",
job_description => "job_0014",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
# Show the use that the job has been saved.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE,
title => "#!string!striker_0044!#",
description => "#!string!striker_0104!#",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }});
}
else
{
# Show the screen the confirm the addition.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => {
title => "#!string!job_0013!#",
message => $anvil->Words->string({key => "striker_0105", variables => { peer => $user."\@".$host_name }}),
}});
}
return(0);
}
# This adds a new peer to anvil.conf.
sub add_sync_peer
{
@ -793,7 +857,7 @@ sub add_sync_peer
# We don't need to store anything as hidden variables, we'll read it back from the
# database later.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "system_update_recorded", variables => {
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE,

@ -334,3 +334,9 @@ td {
color: #d2e2d2;
white-space: nowrap;
}
.form_answer {
font: 1em 'Dejavu Sans Mono', Courier;
color: #dba0a5;
white-space: nowrap;
}

@ -265,6 +265,22 @@
</div>
<!-- end job-details -->
<!-- start job recorded -->
<table>
<div id="job recorded_div">
<tr>
<td>
<span name="#!variable!title_id!#" id="#!variable!title_id!#" class="config_header1">#!variable!title!#</span><br />
<span name="#!variable!message_id!#" id="#!variable!message_id!#" class="config_header2">#!variable!description!#</span>
<br />
<hr />
<a href="#!variable!reload_url!#" class="button">#!string!striker_0053!#</a>
</td>
</tr>
</div>
</table>
<!-- end job recorded -->
<!-- start striker-setup -->
<table align="center" class="striker_welcome">
<tr>
@ -472,10 +488,10 @@
#!variable!password!#
</td>
<td width="25%" class="padded_cell">
#!string!striker_0071!# <input type="checkbox" id="#!variable!access!#_ping" name="#!variable!access!#_ping" #!variable!ping_checked!# />
#!string!striker_0071!#: <span class="form_answer">#!variable!say_ping!#</span>
</td>
<td width="25%" class="padded_cell" align="center">
<a href="striker=true&task=sync&delete=#!variable!access!#" id="#!variable!access!#_delete" class="button">#!string!striker_0068!#<a/>
<td width="25%" class="padded_cell" align="right">
<a href="?striker=true&task=sync&delete=#!variable!uuid!#" id="#!variable!uuid!#_delete" class="button">#!string!striker_0068!#<a/>
</td>
</tr>
<!-- end striker-sync-entry -->
@ -553,19 +569,3 @@
</div>
</table>
<!-- end network_job_recorded -->
<!-- start system_update_recorded -->
<table>
<div id="system_update_recorded_div">
<tr>
<td>
<span name="#!variable!title_id!#" id="#!variable!title_id!#" class="config_header1">#!variable!title!#</span><br />
<span name="#!variable!message_id!#" id="#!variable!message_id!#" class="config_header2">#!variable!description!#</span>
<br />
<hr />
<a href="#!variable!reload_url!#" class="button">#!string!striker_0053!#</a>
</td>
</tr>
</div>
</table>
<!-- end system_update_recorded -->

@ -512,6 +512,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="striker_0101">Power off this system? If you proceed, you will be logged out and this system will be powered off. You will need physical access to the machine to turn it back on in most cases. A properly condigured Striker dashboard will power on after a power cycle (via a PDU) or any machine with IPMI if you have access to a machine on the BCN.</key>
<key name="striker_0102">The peer will be added to the local configuration shortly. Expect slight performance impacts if there is a lot of data to synchronize.</key>
<key name="striker_0103">The peer will be added to the local configuration shortly, and we will be added to their configuration as well. Expect slight performance impacts if there is a lot of data to synchronize.</key>
<key name="striker_0104">The peer will be removed from to the local configuration shortly. Any existing data will remain but no further data will be shared.</key>
<key name="striker_0105"><![CDATA[Are you sure that you want to remove the peer: [<span class="code">#!variable!peer!#</span>]? If so, no further data from this system will be written to the peer. Do note that any existing data will remain and will be reused if you add the peer back again.]]></key>
<!-- Strings used by jobs -->
<key name="job_0001">Configure Network</key>
@ -526,6 +528,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="job_0010">Powering off...</key>
<key name="job_0011">Add a Striker Peer</key>
<key name="job_0012">The Striker peer will now be added to the local configuration.</key>
<key name="job_0013">Remove a Striker Peer</key>
<key name="job_0014">The Striker peer will now be removed from the local configuration.</key>
<!-- Warnings -->
<key name="striker_warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key>

@ -42,7 +42,7 @@ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure =
# 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});
$anvil->Database->connect({debug => 3, check_if_configured => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
# If I have no databases, sleep for a second and then exit (systemd will restart us).
@ -94,23 +94,30 @@ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure =
$anvil->data->{sys}{jobs_running} = 0;
# Once a minute, we'll check the md5sums and see if we should restart. We don't check every loop as it places a
my $md5_interval = 60;
my $system_check = 60;
my $now_time = time;
my $next_check = $now_time + $md5_interval;
my $next_check = $now_time + $system_check;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"s1:md5_interval" => $md5_interval,
"s1:system_check" => $system_check,
"s2:now_time" => $now_time,
"s3:next_check" => $next_check,
}});
# When we periodically check if system files have changed, we'll also ask Database>connect() to check if it
# needs to be configured or updated. This is done periodically as it is expensive to run on every loop.
my $check_if_database_is_configured = 0;
# These are the things we always want running.
while(1)
{
# Connect to the database(s)
$anvil->Storage->read_config({file => $anvil->data->{path}{configs}{'anvil.conf'}});
$anvil->Database->connect();
$anvil->Database->connect({check_if_configured => $check_if_database_is_configured});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
# Mark that we don't want to check the database now.
$check_if_database_is_configured = 0;
if ($anvil->data->{sys}{database}{connections})
{
# Run the normal tasks
@ -133,7 +140,7 @@ while(1)
"s1:now_time" => $now_time,
"s2:next_check" => $next_check,
}});
if ($now_time >= $next_check)
if ($now_time >= $next_check)
{
# Even if it is time to check, don't if a job is running.
if ((not $anvil->data->{sys}{jobs_running}) && ($anvil->Storage->check_md5sums))
@ -142,10 +149,13 @@ while(1)
$anvil->nice_exit({code => 1});
}
# Mark that we want to check the database config next time.
$check_if_database_is_configured = 1;
# Update the next check time.
$next_check = $now_time + $md5_interval;
$next_check = $now_time + $system_check;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:md5_interval" => $md5_interval,
"s1:system_check" => $system_check,
"s2:next_check" => $next_check,
}});
}

Loading…
Cancel
Save