From e79e7fd4f4d0100a82ce21c8baeb944c89699803 Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 2 Oct 2018 03:31:42 -0400 Subject: [PATCH] * 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 --- Anvil/Tools/Database.pm | 41 +++++++++---- cgi-bin/striker | 100 ++++++++++++++++++++++++++------ html/skins/alteeve/main.css | 6 ++ html/skins/alteeve/striker.html | 38 ++++++------ share/words.xml | 4 ++ tools/anvil-daemon | 26 ++++++--- 6 files changed, 158 insertions(+), 57 deletions(-) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index f38f7d76..38fe54e0 100755 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -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}) { diff --git a/cgi-bin/striker b/cgi-bin/striker index f6a4230f..093a833d 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -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, diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index 7864f28e..317347f6 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -334,3 +334,9 @@ td { color: #d2e2d2; white-space: nowrap; } + +.form_answer { + font: 1em 'Dejavu Sans Mono', Courier; + color: #dba0a5; + white-space: nowrap; +} diff --git a/html/skins/alteeve/striker.html b/html/skins/alteeve/striker.html index 4052ca9f..56156b44 100644 --- a/html/skins/alteeve/striker.html +++ b/html/skins/alteeve/striker.html @@ -265,6 +265,22 @@ + + +
+
+ + + +
+ #!variable!title!#
+ #!variable!description!# +
+
+ #!string!striker_0053!# +
+ + @@ -472,10 +488,10 @@ #!variable!password!# - @@ -553,19 +569,3 @@
- #!string!striker_0071!# + #!string!striker_0071!#: #!variable!say_ping!# - #!string!striker_0068!# + + #!string!striker_0068!#
- - - -
-
- - - -
- #!variable!title!#
- #!variable!description!# -
-
- #!string!striker_0053!# -
- diff --git a/share/words.xml b/share/words.xml index 8c15dac7..dc02a3c3 100644 --- a/share/words.xml +++ b/share/words.xml @@ -512,6 +512,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st 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. The peer will be added to the local configuration shortly. Expect slight performance impacts if there is a lot of data to synchronize. 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. + The peer will be removed from to the local configuration shortly. Any existing data will remain but no further data will be shared. + #!variable!peer!#]? 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.]]> Configure Network @@ -526,6 +528,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st Powering off... Add a Striker Peer The Striker peer will now be added to the local configuration. + Remove a Striker Peer + The Striker peer will now be removed from the local configuration. The IP address will change. You will need to reconnect after applying these changes. diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 50d63f12..9ecdc949 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -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, }}); }