diff --git a/Anvil/Tools/Account.pm b/Anvil/Tools/Account.pm index 8dc564c3..ce729957 100755 --- a/Anvil/Tools/Account.pm +++ b/Anvil/Tools/Account.pm @@ -398,12 +398,18 @@ sub logout $anvil->Account->_write_cookies({debug => $debug}); my $user_uuid = defined $parameter->{user_uuid} ? $parameter->{user_uuid} : ""; - my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid; + my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - user_uuid => $user_uuid. + user_uuid => $user_uuid, host_uuid => $host_uuid, }}); + if (not $host_uuid) + { + $host_uuid = $anvil->Get->host_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }}); + } + if (($anvil->data->{cookie}{anvil_user_uuid}) && (not $user_uuid)) { $user_uuid = $anvil->data->{cookie}{anvil_user_uuid}; diff --git a/Anvil/Tools/Convert.pm b/Anvil/Tools/Convert.pm index 49cffd4e..137b1725 100755 --- a/Anvil/Tools/Convert.pm +++ b/Anvil/Tools/Convert.pm @@ -86,6 +86,10 @@ This takes an integer and inserts commas to make it more readable by people. If the input string isn't a string of digits, it is simply returned as-is. + my $string = $anvil->Convert->add_commas({number => 123456789}); + + # string = 123,456,789 + Parameters; =head3 number (required) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 38fe54e0..368469be 100755 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -706,6 +706,7 @@ sub connect foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}}) { # Periodically, autovivication causes and empty key to appear. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }}); next if ((not $uuid) or (not $anvil->Validate->is_uuid({uuid => $uuid}))); if (($db_uuid) && ($db_uuid ne $uuid)) @@ -1190,6 +1191,7 @@ sub connect # Add ourselves to the database, if needed. $anvil->Database->insert_or_update_hosts({debug => $debug}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::connections" => $anvil->data->{sys}{database}{connections} }}); return($anvil->data->{sys}{database}{connections}); } @@ -1587,11 +1589,11 @@ sub initialize }); $anvil->data->{sys}{db_initialized}{$uuid} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::db_initialized::${uuid}" => $anvil->data->{sys}{db_initialized}{$uuid} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::db_initialized::${uuid}" => $anvil->data->{sys}{db_initialized}{$uuid} }}); # Mark that we need to update the DB. $anvil->data->{sys}{database}{resync_needed} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { success => $success }}); return($success); @@ -3399,7 +3401,7 @@ sub insert_or_update_sessions 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_states()" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_sessions()" }}); my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : ""; my $file = defined $parameter->{file} ? $parameter->{file} : ""; @@ -3732,6 +3734,7 @@ WHERE $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0216", variables => { uuid_name => "state_uuid", uuid => $state_uuid }}); return(""); } + foreach my $row (@{$results}) { my $old_state_name = $row->[0]; @@ -4763,7 +4766,6 @@ sub mark_active state_note => $value, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { state_uuid => $state_uuid }}); - return($state_uuid); } @@ -5191,7 +5193,7 @@ sub resync_databases my $column_value = defined $row->[$column_number] ? $row->[$column_number] : "NULL"; my $not_null = $anvil->data->{sys}{database}{table}{$table}{column}{$column_name}{not_null}; my $data_type = $anvil->data->{sys}{database}{table}{$table}{column}{$column_name}{data_type}; - $anvil->Log->variables({source => 2, line => __LINE__, level => $debug, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "s1:id" => $uuid, "s2:row_number" => $row_number, "s3:column_number" => $column_number, @@ -5419,7 +5421,7 @@ sub resync_databases { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0221", variables => { to_write => $to_write_count, - host_name => $anvil->Get->host_name({debug => 2, host_uuid => $uuid}), + host_name => $anvil->Get->host_name({host_uuid => $uuid}), }}); $anvil->Database->write({uuid => $uuid, query => $merged, source => $THIS_FILE, line => __LINE__}); undef $merged; @@ -5427,6 +5429,10 @@ sub resync_databases } } # foreach my $table + # Clear the variable that indicates we need a resync. + $anvil->data->{sys}{database}{resync_needed} = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'sys::database::resync_needed' => $anvil->data->{sys}{database}{resync_needed} }}); + # Show tables; # SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema') ORDER BY table_name ASC, table_schema DESC; @@ -5474,9 +5480,15 @@ sub write }}); } + ### NOTE: The careful checks below are to avoid autovivication biting our arses later. # Make logging code a little cleaner - my $database_name = defined $anvil->data->{database}{$uuid}{name} ? $anvil->data->{database}{$uuid}{name} : $anvil->data->{sys}{database}{name}; - my $say_server = $uuid eq "" ? $anvil->Words->string({key => "log_0129"}) : $anvil->data->{database}{$uuid}{host}.":".$anvil->data->{database}{$uuid}{port}." -> ".$database_name; + my $database_name = $anvil->data->{sys}{database}{name}; + my $say_server = $anvil->Words->string({key => "log_0129"}); + if (($uuid) && (exists $anvil->data->{database}{$uuid}) && (defined $anvil->data->{database}{$uuid}{name}) && ($anvil->data->{database}{$uuid}{name})) + { + $database_name = $anvil->data->{database}{$uuid}{name}; + $say_server = $anvil->data->{database}{$uuid}{host}.":".$anvil->data->{database}{$uuid}{port}." -> ".$database_name; + } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { database_name => $database_name, say_server => $say_server, @@ -5951,13 +5963,16 @@ ORDER BY if ($anvil->data->{sys}{database}{table}{$table}{last_updated} > $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{last_updated}) { # Resync needed. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::table::${table}::last_updated" => $anvil->data->{sys}{database}{table}{$table}{last_updated}, "sys::database::table::${table}::uuid::${uuid}::last_updated" => $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{last_updated}, }}); + my $difference = $anvil->Convert->add_commas({number => ($anvil->data->{sys}{database}{table}{$table}{last_updated} - $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{last_updated}) });; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0106", variables => { - uuid => $uuid, - host => $anvil->Get->host_name({debug => 2, host_uuid => $uuid}), + seconds => $difference, + table => $table, + uuid => $uuid, + host => $anvil->Get->host_name({host_uuid => $uuid}), }}); # Mark it as behind. @@ -5967,13 +5982,16 @@ ORDER BY elsif ($anvil->data->{sys}{database}{table}{$table}{row_count} > $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{row_count}) { # Resync needed. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::table::${table}::row_count" => $anvil->data->{sys}{database}{table}{$table}{row_count}, "sys::database::table::${table}::uuid::${uuid}::row_count" => $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{row_count}, }}); + my $difference = $anvil->Convert->add_commas({number => ($anvil->data->{sys}{database}{table}{$table}{row_count} - $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{row_count}) });; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0219", variables => { - uuid => $uuid, - host => $anvil->Get->host_name({debug => 2, host_uuid => $uuid}), + missing => $difference, + table => $table, + uuid => $uuid, + host => $anvil->Get->host_name({host_uuid => $uuid}), }}); # Mark it as behind. @@ -5983,10 +6001,7 @@ ORDER BY } last if $anvil->data->{sys}{database}{resync_needed}; } - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed}, - }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed} }}); return(0); } diff --git a/cgi-bin/striker b/cgi-bin/striker index 093a833d..ee5ca2be 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -301,7 +301,7 @@ sub process_power { # Record the job! my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - debug => 2, + debug => 3, file => $THIS_FILE, line => __LINE__, job_command => $task eq "poweroff" ? "anvil-manage-power --poweroff -y" : "anvil-manage-power --reboot -y", @@ -332,8 +332,9 @@ sub process_power { # Show the screen the confirm the addition. $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { - title => $task eq "poweroff" ? "#!string!job_0007!#" : "#!string!job_0005!#", - message => $task eq "poweroff" ? "#!string!striker_0101!#" : "#!string!striker_0100!#", + title => $task eq "poweroff" ? "#!string!job_0007!#" : "#!string!job_0005!#", + message => $task eq "poweroff" ? "#!string!striker_0101!#" : "#!string!striker_0100!#", + hidden_fields => "", }}); } @@ -351,7 +352,7 @@ sub process_update { # Record the job! my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - debug => 2, + debug => 3, file => $THIS_FILE, line => __LINE__, job_command => "anvil-update-system", @@ -381,8 +382,9 @@ sub process_update { # Show the screen the confirm the addition. $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { - title => "#!string!striker_0078!#", - message => "#!string!striker_0086!#", + title => "#!string!striker_0078!#", + message => "#!string!striker_0086!#", + hidden_fields => "", }}); } @@ -610,7 +612,7 @@ sub delete_sync_peer { # OK, save the job! my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - debug => 2, + debug => 3, file => $THIS_FILE, line => __LINE__, job_command => "anvil-manage-striker-peers --remove --host-uuid ".$uuid, @@ -626,7 +628,7 @@ sub delete_sync_peer $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { title_id => "", message_id => "", - reload_url => "/cgi-bin/".$THIS_FILE, + reload_url => "/cgi-bin/".$THIS_FILE."?striker=true&task=sync", title => "#!string!striker_0044!#", description => "#!string!striker_0104!#", }}); @@ -636,8 +638,9 @@ sub delete_sync_peer { # 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 }}), + title => "#!string!job_0013!#", + message => $anvil->Words->string({key => "striker_0105", variables => { peer => $user."\@".$host_name }}), + hidden_fields => "", }}); } @@ -843,7 +846,7 @@ sub add_sync_peer # Store the job my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - debug => 2, + debug => 3, file => $THIS_FILE, line => __LINE__, job_command => $job_command, @@ -860,7 +863,7 @@ sub add_sync_peer $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { title_id => "", message_id => "", - reload_url => "/cgi-bin/".$THIS_FILE, + reload_url => "/cgi-bin/".$THIS_FILE."?striker=true&task=sync", title => "#!string!striker_0044!#", description => $ping ? "#!string!striker_0103!#" : "#!string!striker_0102!#", }}); @@ -926,7 +929,7 @@ sub configure_striker { # User has confirmed, update the system! my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - debug => 2, + debug => 3, file => $THIS_FILE, line => __LINE__, job_command => "anvil-configure-striker", diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index 317347f6..d7e5da2d 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -10,14 +10,67 @@ Colours; - Footer text: #515151 */ -.login { - width: 600px; - height: 50px; - position: fixed; - margin-left: -300px; /* half of width */ - margin-top: -25px; /* half of height */ - top: 50%; - left: 50%; +a { + font-family: 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; + color: #f2f2f2; + text-decoration: none; +} + +body { + font-family: 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; + background-image: url("/skins/alteeve/images/Texture.jpg"); + background-repeat: repeat; + color: #f2f2f2; +} + +.body_table { + width: 90%; + margin: auto; + top: 0; + position: absolute; + left: 5%; +} + +.button { + color: #343434; + font: 0.9em 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; + text-decoration: none; + background-color: #f2f2f2; + padding: 5px 10px 5px 10px; + border: 1px solid #343434; + border-radius: 3px; +} + +#center_body { + height: 100%; +} + +.code { + font-family: 'Dejavu Sans Mono', Courier; +} + +.column_header { + text-align: left; + color: #9ba0a5; + padding: 0.15em; +} + +.config_header1 { + color: #f7f7f7; + text-align: center; + font-size: 2em; +} + +.config_header2 { + color: #f2f2f2; + text-align: center; + font-size: 1.5em; +} + +.config_header3 { + color: #f2f2f2; + text-align: center; + font-size: 1em; } .error_message { @@ -30,12 +83,93 @@ Colours; color: #ffdfdf; } -input[type=text].input_clear, input[type=number].input_clear, select.input_clear { +.fixed_width { + font-family: 'Dejavu Sans Mono', Courier; +} + +.footer { + background: #171717; + font-size: 12px; + color: #515151; + width: 90%; + position: fixed; + bottom: 0; + left: 5%; +} + +.footer a:hover { + cursor: pointer; + text-decoration: none; + color: #616161; +} + +.footer a:link, .footer a:visited { + cursor: pointer; + text-decoration: none; + color: #515151; +} + +.form_answer { + font: 1em 'Dejavu Sans Mono', Courier; + color: #dba0a5; + white-space: nowrap; +} + +.form_group_header1 { + text-align: left; + font-size: 1.1em; + font-weight: bold; +} + +.form_group_header2 { + text-align: left; + font-size: 1.1em; +} + +.job_output { + font: 0.8em 'Dejavu Sans Mono', Courier; + color: #d2e2d2; + white-space: nowrap; +} + +.job_status { border: 1px solid #9ba0a5; } -input[type=text].input_alert, input[type=number].input_alert, select.input_alert { - border: 1px solid #ff3f3f; +.job_table { + border-left: 1px dotted #d02724; +} + +.header { + text-align: center; + background: #343434; + color: #f2f2f2; + border-bottom: 0.2em solid #d02724; +} + +.header a:hover { + cursor: pointer; + color: #f6f6f6; + text-decoration: none; +} + +.header a:link, .header a:visited { + cursor: pointer; + color: #f6f6f6; + text-decoration: none; +} + +/* This is used by HTML::FromText when converting a text string to HTML */ +.hft-lines { + text-align: left; + font-family: 'Dejavu Sans Mono', Courier; + padding: 0.2em; + font-size: 0.9em; +} + +.icon_button { + padding-top: 30px; + vertical-align: top; } input[type=text], input[type=number], input[type=password] { @@ -50,6 +184,44 @@ input[type=text], input[type=number], input[type=password] { color: #f7f7f7; } +input[type=text].input_alert, input[type=number].input_alert, select.input_alert { + border: 1px solid #ff3f3f; +} + +input[type=text].input_clear, input[type=number].input_clear, select.input_clear { + border: 1px solid #9ba0a5; +} + +.login { + width: 600px; + height: 50px; + position: fixed; + margin-left: -300px; /* half of width */ + margin-top: -25px; /* half of height */ + top: 50%; + left: 50%; +} + +.logo { + border-top: 0.3em solid transparent; + border-left: 0.3em solid transparent; + border-right: 0.3em solid transparent; + height: 2.5em; +} + +.menu_details { + padding-left: 10px; + padding-right: 10px; +} + +.menu_title { + color: #dbe0e5; + font-size: 1.3em; + padding-top: 30px; + padding-left: 20px; + padding-bottom: 10px; +} + select { width: 100%; /* padding: 6px 10px; */ @@ -64,40 +236,30 @@ select { font-size: 1.0em; } -.code { - font-family: 'Dejavu Sans Mono', Courier; -} - -body { - font-family: 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; - background-image: url("/skins/alteeve/images/Texture.jpg"); - background-repeat: repeat; - color: #f2f2f2; +table { + border-spacing: 0; + border-collapse: collapse; + vertical-align: top; } -a { - font-family: 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; - color: #f2f2f2; - text-decoration: none; +table.centered { + margin: auto; } -table.data_table_nowrap { +table.data_table { border: 1px solid #8f8f8f; border-radius: 4px; - white-space: nowrap; } -table.data_table { +table.data_table_nowrap { border: 1px solid #8f8f8f; border-radius: 4px; + white-space: nowrap; } -table.centered { - margin: auto; -} - -tr.data_row { - border-top: 1px solid #5f5f5f; +td { + padding: 0; + border-collapse: collapse; } td.button_cell { @@ -105,27 +267,11 @@ td.button_cell { text-align: center; } -td.top_padded_cell { - padding-top: 5px; - padding-left: 5px; - padding-right: 5px; - padding-bottom: 0px; -} - -td.padded_cell { - padding: 0px 5px; -} - td.column_header { text-align: left; color: #9ba0a5; padding: 0.15em; } -.column_header { - text-align: left; - color: #9ba0a5; - padding: 0.15em; -} td.column_row_name { text-align: left; @@ -134,13 +280,6 @@ td.column_row_name { padding: 0.2em; } -td.column_subrow_name { - text-align: right; - vertical-align: top; - color: #c7c7c7; - padding: 0.1em; -} - td.column_row_value { text-align: left; color: #f7f7f7; @@ -154,6 +293,7 @@ td.column_row_value_fixed { padding: 0.2em; font-size: 0.9em; } + td.column_row_value_fixed_centered { text-align: center; color: #f7f7f7; @@ -162,59 +302,27 @@ td.column_row_value_fixed_centered { font-size: 0.9em; } -.body_table { - width: 90%; - margin: auto; - top: 0; - position: absolute; - left: 5%; +td.column_subrow_name { + text-align: right; + vertical-align: top; + color: #c7c7c7; + padding: 0.1em; } -.config_header1 { - color: #f7f7f7; - text-align: center; - font-size: 2em; +td.padded_cell { + padding: 0px 5px; } -.config_header2 { - color: #f2f2f2; - text-align: center; - font-size: 1.5em; +td.top_padded_cell { + padding-top: 5px; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 0px; } -.config_header3 { - color: #f2f2f2; +.title { + font-size: 1.2em; text-align: center; - font-size: 1em; -} - -.form_group_header1 { - text-align: left; - font-size: 1.1em; - font-weight: bold; -} - -.form_group_header2 { - text-align: left; - font-size: 1.1em; -} - -table { - border-spacing: 0; - border-collapse: collapse; - vertical-align: top; -} -td { -/* border: 1px solid green; */ - padding: 0; - border-collapse: collapse; -} - -.logo { - border-top: 0.3em solid transparent; - border-left: 0.3em solid transparent; - border-right: 0.3em solid transparent; - height: 2.5em; } .top_icon { @@ -224,119 +332,15 @@ td { height: 2.5em; } -.subtle_text { - color: #9D9D9D; - text-align: left; - font-size: 0.9em; -} - -.header { - text-align: center; - background: #343434; - color: #f2f2f2; - border-bottom: 0.2em solid #d02724; -} -.header a:link, .header a:visited { - cursor: pointer; - color: #f6f6f6; - text-decoration: none; -} -.header a:hover { - cursor: pointer; - color: #f6f6f6; - text-decoration: none; -} - -.footer { - background: #171717; - font-size: 12px; - color: #515151; - width: 90%; - position: fixed; - bottom: 0; - left: 5%; -} - -.footer a:link, .footer a:visited { - cursor: pointer; - text-decoration: none; - color: #515151; -} - -.footer a:hover { - cursor: pointer; - text-decoration: none; - color: #616161; -} - -.fixed_width { - font-family: 'Dejavu Sans Mono', Courier; -} - -#center_body { - height: 100%; +tr.data_row { + border-top: 1px solid #5f5f5f; } .striker_welcome { } -.title { - font-size: 1.2em; - text-align: center; -} - -.button { - color: #343434; - font: 0.9em 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; - text-decoration: none; - background-color: #f2f2f2; - padding: 5px 10px 5px 10px; - border: 1px solid #343434; - border-radius: 3px; -} - -.icon_button { - padding-top: 30px; - vertical-align: top; -} - -.menu_title { - color: #dbe0e5; - font-size: 1.3em; - padding-top: 30px; - padding-left: 20px; - padding-bottom: 10px; -} - -.menu_details { - padding-left: 10px; - padding-right: 10px; -} - -/* This is used by HTML::FromText when converting a text string to HTML */ -.hft-lines { - text-align: left; - font-family: 'Dejavu Sans Mono', Courier; - padding: 0.2em; - font-size: 0.9em; -} - -.job_table { - border-left: 1px dotted #d02724; -} - -.job_status { - border: 1px solid #9ba0a5; -} - -.job_output { - font: 0.8em 'Dejavu Sans Mono', Courier; - color: #d2e2d2; - white-space: nowrap; -} - -.form_answer { - font: 1em 'Dejavu Sans Mono', Courier; - color: #dba0a5; - white-space: nowrap; +.subtle_text { + color: #9D9D9D; + text-align: left; + font-size: 0.9em; } diff --git a/html/skins/alteeve/striker.html b/html/skins/alteeve/striker.html index 56156b44..a1319677 100644 --- a/html/skins/alteeve/striker.html +++ b/html/skins/alteeve/striker.html @@ -25,6 +25,7 @@ + #!variable!hidden_fields!# @@ -270,8 +271,8 @@
- #!variable!title!#
- #!variable!description!# + #!variable!title!#
+ #!variable!description!#

#!string!striker_0053!# @@ -494,6 +495,11 @@ #!string!striker_0068!# + + +
+ + @@ -559,8 +565,8 @@
- #!variable!title!#
- #!variable!description!# + #!variable!title!#
+ #!variable!description!#

#!string!striker_0053!# diff --git a/share/words.xml b/share/words.xml index dc02a3c3..c131d398 100644 --- a/share/words.xml +++ b/share/words.xml @@ -254,7 +254,7 @@ The database connection error was: The local machine's UUID was not read properly. It should be stored in: [#!data!sys::host_uuid!#] and contain hexadecimal characters in the format: '012345-6789-abcd-ef01-23456789abcd' and usually matches the output of 'dmidecode --string system-uuid'. If this file exists and if there is a string in the file, please verify that it is structured correctly. The database with UUID: [#!variable!uuid!#] for: [#!variable!file!#] is behind. Anvil! database: [#!variable!database!#] already exists. - The database on: [#!variable!host!#] (UUID: [#!variable!uuid!#]) is behind. A database resync will be requested. + The table: [#!variable!table!#] (and possibly others) in the database on: [#!variable!host!#] (UUID: [#!variable!uuid!#]) is behind by: [#!variable!seconds!#] seconds. A database resync will be requested. [ Warning ] - Failed to delete the temporary postgres password. insert_or_update_states() was called but the 'state_host_uuid' parameter was not passed or it is empty. Normally this is set to 'sys::data_uuid'.]]> [ Error ] - Failed to create the Anvil! database: [#!variable!database!#] @@ -358,7 +358,7 @@ The database connection error was: update_progress() called without 'job_uuid' being set, and 'jobs::job_uuid' was also not set. Unable to find the job to update.]]> update_progress() called with the 'job_uuid': [#!variable!job_uuid!#], which was not found. Unable to find the job to update.]]> update_progress() called with 'progress' set to an invalid value: [#!variable!progress!#]. This must be a whole number between '0' and '100' (fractions not allowed).]]> - + find_matching_ip(), but it failed to resolve to an IP address.]]> We've been asked to have the new peer add us. We will now wait for the peer to show up in the 'hosts' table and then request the job for it to add us. The peer: [#!variable!peer_uuid!#] is not yet in 'hosts', continuing to wait. @@ -367,9 +367,11 @@ The database connection error was: The #!variable!uuid_name!#: [#!variable!uuid!#] was passed in, but no record with that UUID was found in the database. The variable with variable_uuid: [#!variable!variable_uuid!#], variable_source_table: [#!variable!variable_source_table!#] and variable_source_uuid: [#!variable!variable_source_uuid!#] was not found in the database, so unable to update. The variable: [#!variable!name!#] was expected to be an array reference, but it wasn't. It contained (if anything): [#!variable!value!#]. - The database on: [#!variable!host!#] (UUID: [#!variable!uuid!#]) is missing rows. A database resync will be requested. + The table: [#!variable!table!#] (and possibly others) in the database on: [#!variable!host!#] (UUID: [#!variable!uuid!#]) is missing: [#!variable!missing!#] row(s). A database resync will be requested. insert_or_update_jobs() was called with 'update_progress_only' but without a 'job_uuid' being set.]]> Writing: [#!variable!to_write!#] record(s) to resync the database on: [#!variable!host_name!#]. + The connection to the database on: [#!variable!host!#] isn't established, trying again... + The connection to the database on: [#!variable!host!#] has been successfully established. Test diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 9ecdc949..4e550301 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -27,6 +27,8 @@ use JSON; use HTML::Strip; use HTML::FromText; +use Data::Dumper; + my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; if (($running_directory =~ /^\./) && ($ENV{PWD})) @@ -111,10 +113,22 @@ my $check_if_database_is_configured = 0; while(1) { # Connect to the database(s) - $anvil->Storage->read_config({file => $anvil->data->{path}{configs}{'anvil.conf'}}); + $anvil->Storage->read_config({force_read => 1, file => $anvil->data->{path}{configs}{'anvil.conf'}}); $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"}); + ### DEBUG: + my $db_count = keys %{$anvil->data->{database}}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { db_count => $db_count }}); + foreach my $uuid (keys %{$anvil->data->{database}}) + { + my $host = $anvil->data->{database}{$uuid}{host}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "s1:uuid" => $uuid, + "s2:host" => $host, + }}); + } + # Mark that we don't want to check the database now. $check_if_database_is_configured = 0; @@ -168,7 +182,22 @@ while(1) } # Disconnect from the database(s) and sleep now. - $anvil->Database->disconnect(); + $anvil->Database->disconnect({debug => 2}); + + ### DEBUG: + $db_count = 0; + $db_count = keys %{$anvil->data->{database}}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { db_count => $db_count }}); + foreach my $uuid (keys %{$anvil->data->{database}}) + { + my $host = $anvil->data->{database}{$uuid}{host}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "s1:uuid" => $uuid, + "s2:host" => $host, + }}); + } + + die; sleep(1); } @@ -387,7 +416,7 @@ sub run_jobs my $job_status = $hash_ref->{job_status}; my $started_seconds_ago = $job_picked_up_at ? (time - $job_picked_up_at) : 0; my $updated_seconds_ago = $job_updated ? (time - $job_updated) : 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { job_uuid => $job_uuid, job_command => $job_command, job_data => $job_data, @@ -406,7 +435,7 @@ sub run_jobs if ($job_progress ne "100") { $anvil->data->{sys}{jobs_running} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::jobs_running" => $anvil->data->{sys}{jobs_running} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::jobs_running" => $anvil->data->{sys}{jobs_running} }}); } # See if the job was picked up by a now-dead instance. @@ -422,28 +451,46 @@ sub run_jobs # If the job is done, just clear the 'job_picked_up_by' and be done. if ($job_progress ne "100") { - # The previous job is gone, but the job isn't finished. Start it again. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "striker_warning_0007", variables => { - command => $job_command, - pid => $job_picked_up_by, - percent => $job_progress, - }}); - - # Clear some variables. - $job_progress = 0; - $job_status = "message_0056"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - job_progress => $job_progress, - job_status => $job_status, - }}); - - # Clear the job. - $anvil->Job->clear({debug => 3, job_uuid => $job_uuid}); + # It's possible that the job updated to 100% and exited after we + # gathered the job data, so we won't restart until we've seen it not + # running and not at 100% after 5 loops. + if ((not exists $anvil->data->{lost_job_count}{$job_uuid}) or (not defined $anvil->data->{lost_job_count}{$job_uuid})) + { + $anvil->data->{lost_job_count}{$job_uuid} = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "lost_job_count::${job_uuid}" => $anvil->data->{lost_job_count}{$job_uuid} }}); + } + if ($anvil->data->{lost_job_count}{$job_uuid} > 5) + { + # The previous job is gone, but the job isn't finished. Start it again. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "striker_warning_0007", variables => { + command => $job_command, + pid => $job_picked_up_by, + percent => $job_progress, + }}); + + # Clear some variables. + $job_progress = 0; + $job_status = "message_0056"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + job_progress => $job_progress, + job_status => $job_status, + }}); + + # Clear the job. + $anvil->Job->clear({debug => 3, job_uuid => $job_uuid}); + $anvil->data->{lost_job_count}{$job_uuid} = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "lost_job_count::${job_uuid}" => $anvil->data->{lost_job_count}{$job_uuid} }}); + } + else + { + $anvil->data->{lost_job_count}{$job_uuid}++; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "lost_job_count::${job_uuid}" => $anvil->data->{lost_job_count}{$job_uuid} }}); + } } # Clear the PID $job_picked_up_by = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_picked_up_by => $job_picked_up_by }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { job_picked_up_by => $job_picked_up_by }}); } } diff --git a/tools/anvil-manage-striker-peers b/tools/anvil-manage-striker-peers index 1ed122d8..a476dd31 100755 --- a/tools/anvil-manage-striker-peers +++ b/tools/anvil-manage-striker-peers @@ -41,9 +41,15 @@ $| = 1; my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1}); # Read switches -$anvil->data->{switches}{list} = ""; -$anvil->data->{switches}{add} = 0; -$anvil->data->{switches}{remove} = 0; +$anvil->data->{switches}{list} = ""; +$anvil->data->{switches}{add} = 0; +$anvil->data->{switches}{remove} = 0; +$anvil->data->{switches}{'job-uuid'} = ""; +$anvil->data->{switches}{'host-uuid'} = ""; +$anvil->data->{switches}{'host'} = ""; +$anvil->data->{switches}{'port'} = 5432; +$anvil->data->{switches}{'password-file'} = ""; +$anvil->data->{switches}{'ping'} = 0; $anvil->Get->switches; # Make sure we're running as 'root' @@ -63,9 +69,9 @@ $anvil->Database->connect(); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); # Am I adding, editing or deleting? -if (not $anvil->data->{switches}{list}) +if ((not $anvil->data->{switches}{list}) && ($anvil->data->{switches}{'host-uuid'})) { - process_entry($anvil) ; + process_entry($anvil); } ### Report the peers. @@ -141,12 +147,12 @@ sub process_entry { my ($anvil) = @_; - my $job_uuid = defined $anvil->data->{switches}{'job-uuid'} ? $anvil->data->{switches}{'job-uuid'} : ""; - my $host_uuid = defined $anvil->data->{switches}{'host-uuid'} ? $anvil->data->{switches}{'host-uuid'} : ""; - my $host = defined $anvil->data->{switches}{'host'} ? $anvil->data->{switches}{'host'} : ""; - my $port = defined $anvil->data->{switches}{'port'} ? $anvil->data->{switches}{'port'} : 5432; - my $password_file = defined $anvil->data->{switches}{'password-file'} ? $anvil->data->{switches}{'password-file'} : ""; - my $ping = defined $anvil->data->{switches}{'ping'} ? $anvil->data->{switches}{'ping'} : 0; + my $job_uuid = $anvil->data->{switches}{'job-uuid'}; + my $host_uuid = $anvil->data->{switches}{'host-uuid'}; + my $host = $anvil->data->{switches}{'host'}; + my $port = $anvil->data->{switches}{'port'}; + my $password_file = $anvil->data->{switches}{'password-file'}; + my $ping = $anvil->data->{switches}{'ping'}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, secure => 0, level => 2, list => { job_uuid => $job_uuid, host_uuid => $host_uuid, @@ -537,7 +543,35 @@ sub process_entry $anvil->Database->connect; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); - # Now loop until we see the peer's host_uuid show up + # Now loop until we see the peer's host_uuid show up and we have a connection to the peer's + # database. + my $peer_connected = 0; + until($peer_connected) + { + my $say_host = $anvil->Get->host_name({host_uuid => $host_uuid}); + $say_host = $host_uuid if not $say_host; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + say_host => $say_host, + "cache::database_handle::${host_uuid}" => $anvil->data->{cache}{database_handle}{$host_uuid}, + }}); + if ($anvil->data->{cache}{database_handle}{$host_uuid} =~ /^DBI::db=HASH/) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0223", variables => { host => $say_host }}); + $peer_connected = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_connected => $peer_connected }}); + } + else + { + # Sleep and then try again to connect. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0222", variables => { host => $say_host }}); + + sleep 1; + + $anvil->Database->connect({db_uuid => $host_uuid}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); + } + } + my $peer_host_name = ""; my $host_seen = 0; until($host_seen)