From bb48c090a7c3debcb535df23759cde3288960da7 Mon Sep 17 00:00:00 2001 From: Digimer Date: Thu, 7 Dec 2017 18:42:48 -0500 Subject: [PATCH] * Created Get->md5sum() to return the md5sum of the specified file. * Updated anvil-daemon to exit if the md5sum on disk changes. * Quieted a lot of logging. Signed-off-by: Digimer --- Anvil/Tools.pm | 1 + Anvil/Tools/Get.pm | 51 ++++++++++++++++---- Anvil/Tools/System.pm | 99 ++++++++++++++++++++++----------------- tools/anvil-daemon | 23 ++++++++- tools/anvil-prep-database | 58 +++++++++++------------ tools/anvil-update-states | 4 +- tools/words.xml | 1 + 7 files changed, 152 insertions(+), 85 deletions(-) diff --git a/Anvil/Tools.pm b/Anvil/Tools.pm index 7d263084..ebfe28d6 100755 --- a/Anvil/Tools.pm +++ b/Anvil/Tools.pm @@ -737,6 +737,7 @@ sub _set_paths 'iptables-save' => "/usr/sbin/iptables-save", journalctl => "/usr/bin/journalctl", logger => "/usr/bin/logger", + md5sum => "/usr/bin/md5sum", 'mkdir' => "/usr/bin/mkdir", ping => "/usr/bin/ping", pgrep => "/usr/bin/pgrep", diff --git a/Anvil/Tools/Get.pm b/Anvil/Tools/Get.pm index 3ff2987e..55186885 100755 --- a/Anvil/Tools/Get.pm +++ b/Anvil/Tools/Get.pm @@ -16,6 +16,7 @@ my $THIS_FILE = "Get.pm"; # cgi # date_and_time # host_uuid +# md5sum # network_details # switches # users_home @@ -153,7 +154,7 @@ sub cgi $anvil->data->{cgi}{$variable}{filehandle} = $cgi->upload($variable); my $file = $anvil->data->{cgi}{$variable}{filehandle}; $anvil->data->{cgi}{$variable}{mimetype} = $cgi->uploadInfo($file)->{'Content-Type'}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { variable => $variable, "cgi::${variable}::filehandle" => $anvil->data->{cgi}{$variable}{filehandle}, "cgi::${variable}::mimetype" => $anvil->data->{cgi}{$variable}{mimetype}, @@ -232,7 +233,7 @@ sub cgi # Clear the last & $anvil->data->{sys}{cgi_string} =~ s/&$//; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::cgi_string" => $anvil->data->{sys}{cgi_string} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::cgi_string" => $anvil->data->{sys}{cgi_string} }}); return(0); } @@ -417,6 +418,38 @@ sub host_uuid return($anvil->data->{HOST}{UUID}); } +=head2 md5sum + +This returns the C<< md5sum >> of a given file. + +Parameters; + +=head3 file + +This is the full or relative path to the file. If the file doesn't exist, an empty string is returned. + +=cut +sub md5sum +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + + my $sum = ""; + my $file = defined $parameter->{file} ? $parameter->{file} : ""; + + if (-e $file) + { + my $shell_call = $anvil->data->{path}{exe}{md5sum}." ".$file; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); + + $sum = $anvil->System->call({shell_call => $shell_call}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sum => $sum }}); + } + + return($sum); +} + =head2 network_details This method returns the local hostname and IP addresses. @@ -582,20 +615,20 @@ sub users_home my $home_directory = 0; my $user = $parameter->{user} ? $parameter->{user} : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { user => $user }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user => $user }}); # Make sure the user is only one digit. Sometimes $< (and others) will return multiple IDs. if ($user =~ /^\d+ \d$/) { $user =~ s/^(\d+)\s.*$/$1/; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { user => $user }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user => $user }}); } # If the user is numerical, convert it to a name. if ($user =~ /^\d+$/) { $user = getpwuid($user); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { user => $user }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user => $user }}); } # Still don't have a name? fail... @@ -607,14 +640,14 @@ sub users_home } my $body = $anvil->Storage->read_file({file => $anvil->data->{path}{data}{passwd}}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { body => $body }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { body => $body }}); foreach my $line (split /\n/, $body) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); if ($line =~ /^$user:/) { $home_directory = (split/:/, $line)[5]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { home_directory => $home_directory }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { home_directory => $home_directory }}); last; } } @@ -625,7 +658,7 @@ sub users_home $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0061", variables => { user => $user }}); } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { home_directory => $home_directory }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { home_directory => $home_directory }}); return($home_directory); } diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm index 2ad451b3..052e24f7 100755 --- a/Anvil/Tools/System.pm +++ b/Anvil/Tools/System.pm @@ -218,7 +218,7 @@ sub check_memory my $anvil = $self->parent; my $program_name = defined $parameter->{program_name} ? $parameter->{program_name} : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { program_name => $program_name }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { program_name => $program_name }}); if (not $program_name) { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0086"}); @@ -230,15 +230,15 @@ sub check_memory my $output = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{''}." --program $program_name"}); foreach my $line (split/\n/, $output) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); if ($line =~ /= (\d+) /) { $used_ram = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { used_ram => $used_ram }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { used_ram => $used_ram }}); } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { used_ram => $used_ram }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { used_ram => $used_ram }}); return($used_ram); } @@ -378,7 +378,7 @@ sub get_ips $anvil->data->{sys}{networks}{$in_iface}{ip} = $ip; $anvil->data->{sys}{networks}{$in_iface}{subnet} = $subnet; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "s1:sys::networks::${in_iface}::ip" => $anvil->data->{sys}{networks}{$in_iface}{ip}, "s2:sys::networks::${in_iface}::subnet" => $anvil->data->{sys}{networks}{$in_iface}{subnet}, }}); @@ -386,7 +386,7 @@ sub get_ips if ($line =~ /ether ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) /i) { $anvil->data->{sys}{networks}{$in_iface}{mac} = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::networks::${in_iface}::mac" => $anvil->data->{sys}{networks}{$in_iface}{mac} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::networks::${in_iface}::mac" => $anvil->data->{sys}{networks}{$in_iface}{mac} }}); } } @@ -998,7 +998,11 @@ Parameters; If set, the connection to the target will be closed at the end of the call. -=head3 no_cache (optional, default '0') +=head3 log_level (optional, default C<< 3 >>) + +If set, the method will use the given log level. Valid values are integers between C<< 0 >> and C<< 4 >>. + +=head3 no_cache (optional, default C<< 0 >>) If set, and if an existing cached connection is open, it will be closed and a new connection to the target will be established. @@ -1008,13 +1012,13 @@ This is the password used to connect to the remote target as the given user. B: Passwordless SSH is supported. If you can ssh to the target as the given user without a password, then no password needs to be given here. -=head3 port (optional, default '22') +=head3 port (optional, default C<< 22 >>) This is the TCP port to use when connecting to the C<< target >>. The default is port 22. B: See C<< target >> for optional port definition. -=head3 secure (optional, default '0') +=head3 secure (optional, default C<< 0 >>) If set, the C<< shell_call >> is treated as containing sensitive data and will not be logged unless C<< $anvil->Log->secure >> is enabled. @@ -1042,17 +1046,24 @@ sub remote_call my $anvil = $self->parent; # Get the target and port so that we can create the ssh_fh key - my $port = defined $parameter->{port} ? $parameter->{port} : 22; - my $target = defined $parameter->{target} ? $parameter->{target} : ""; + my $log_level = defined $parameter->{log_level} ? $parameter->{log_level} : 3; + if (($log_level !~ /^\d$/) or ($log_level < 0) or ($log_level > 4)) + { + # Invalid log level, set 2. + $log_level = 3; + } + + my $port = defined $parameter->{port} ? $parameter->{port} : 22; + my $target = defined $parameter->{target} ? $parameter->{target} : ""; my $ssh_fh_key = $target.":".$port; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port, target => $target, }}); # This will store the SSH file handle for the given target after the initial connection. $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} = defined $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} ? $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); # Now pick up the rest of the variables. my $close = defined $parameter->{'close'} ? $parameter->{'close'} : 0; @@ -1064,7 +1075,7 @@ sub remote_call my $start_time = time; my $ssh_fh = $anvil->data->{cache}{ssh_fh}{$ssh_fh_key}; # NOTE: The shell call might contain sensitive data, so we show '--' if 'secure' is set and $anvil->Log->secure is not. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { 'close' => $close, password => $anvil->Log->secure ? $password : "--", secure => $secure, @@ -1105,7 +1116,7 @@ sub remote_call { $target = $1; $port = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port, target => $target, }}); @@ -1114,7 +1125,7 @@ sub remote_call if ($parameter->{port} =~ /^\d+$/) { $port = $parameter->{port}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port }}); } } else @@ -1123,11 +1134,11 @@ sub remote_call $anvil->System->read_ssh_config(); $anvil->data->{hosts}{$target}{port} = "" if not defined $anvil->data->{hosts}{$target}{port}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hosts::${target}::port" => $anvil->data->{hosts}{$target}{port} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { "hosts::${target}::port" => $anvil->data->{hosts}{$target}{port} }}); if ($anvil->data->{hosts}{$target}{port} =~ /^\d+$/) { $port = $anvil->data->{hosts}{$target}{port}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port }}); } } @@ -1142,11 +1153,11 @@ sub remote_call if (not $anvil->Validate->is_ipv4({ip => $target})) { my $new_target = $anvil->Convert->hostname_to_ip({host_name => $target}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_target => $new_target }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { new_target => $new_target }}); if ($new_target) { $target = $new_target; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target => $target }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { target => $target }}); } } @@ -1155,7 +1166,7 @@ sub remote_call { # Close the connection. $ssh_fh->disconnect(); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0010", variables => { target => $target }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => "message_0010", variables => { target => $target }}); # For good measure, blank both variables. $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} = ""; @@ -1167,7 +1178,7 @@ sub remote_call my $stderr_output = []; # If I don't already have an active SSH file handle, connect now. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ssh_fh => $ssh_fh }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { ssh_fh => $ssh_fh }}); if ($ssh_fh !~ /^Net::SSH2/) { $ssh_fh = Net::SSH2->new(); @@ -1209,10 +1220,10 @@ sub remote_call $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => $message_key, variables => { $variables }}); } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { error => $error, ssh_fh => $ssh_fh }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { error => $error, ssh_fh => $ssh_fh }}); if (not $error) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { user => $user, password => $anvil->Log->secure ? $password : "--", }}); @@ -1223,7 +1234,7 @@ sub remote_call my $home_directory = $anvil->Get->users_home({user => $user}); my $public_key = $home_directory."/.ssh/id_rsa.pub"; my $private_key = $home_directory."/.ssh/id_rsa"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { user => $user, home_directory => $home_directory, public_key => $public_key, @@ -1234,10 +1245,10 @@ sub remote_call { # We're in! Record the file handle for this target. $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} = $ssh_fh; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); # Log that we got in without a password. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0062", variables => { target => $target }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => "log_0062", variables => { target => $target }}); } else { @@ -1250,10 +1261,10 @@ sub remote_call { # We're in! Record the file handle for this target. $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} = $ssh_fh; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); # Record our success - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0007", variables => { target => $target }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => "message_0007", variables => { target => $target }}); } } } @@ -1262,7 +1273,7 @@ sub remote_call ### sort out the polling and data collection in this section. # # Open a channel and make the call. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { error => $error, ssh_fh => $ssh_fh, }}); @@ -1285,7 +1296,7 @@ sub remote_call else { ### TODO: Timeout if the call doesn't respond in X seconds, closing the filehandle if hit. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { channel => $channel, shell_call => $shell_call, }}); @@ -1316,7 +1327,7 @@ sub remote_call { my $line = $1; $line =~ s/\r//g; # Remove \r from things like output of daemon start/stops. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { "STDOUT:line" => $line }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { "STDOUT:line" => $line }}); push @{$stdout_output}, $line; } @@ -1328,7 +1339,7 @@ sub remote_call while ($stderr =~ s/^(.*)\n//) { my $line = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { "STDERR:line" => $line }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { "STDERR:line" => $line }}); push @{$stderr_output}, $line; } @@ -1337,12 +1348,12 @@ sub remote_call } if ($stdout) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { stdout => $stdout }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { stdout => $stdout }}); push @{$stdout_output}, $stdout; } if ($stderr) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { stderr => $stderr }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { stderr => $stderr }}); push @{$stderr_output}, $stderr; } } @@ -1353,7 +1364,7 @@ sub remote_call foreach my $line (@{$stderr_output}, @{$stdout_output}) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { line => $line }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { line => $line }}); push @{$output}, $line; } @@ -1364,17 +1375,17 @@ sub remote_call { # Close it. $ssh_fh->disconnect(); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0009", variables => { target => $target }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => "message_0009", variables => { target => $target }}); } # For good measure, blank both variables. $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} = ""; $ssh_fh = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { "cache::ssh_fh::${ssh_fh_key}" => $anvil->data->{cache}{ssh_fh}{$ssh_fh_key} }}); } $error = "" if not defined $error; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, secure => $secure, list => { error => $error, ssh_fh => $ssh_fh, output => $output, @@ -1404,13 +1415,13 @@ sub reload_daemon my $return = undef; my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : ""; my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { daemon => $daemon, say_daemon => $say_daemon }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { daemon => $daemon, say_daemon => $say_daemon }}); my $shell_call = $anvil->data->{path}{exe}{systemctl}." reload ".$say_daemon."; ".$anvil->data->{path}{exe}{'echo'}." return_code:\$?"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); my $output = $anvil->System->call({shell_call => $shell_call}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); foreach my $line (split/\n/, $output) { if ($line =~ /return_code:(\d+)/) @@ -1420,7 +1431,7 @@ sub reload_daemon } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }}); return($return); } @@ -1528,7 +1539,7 @@ sub _load_firewalld_zones my $anvil = $self->parent; my $directory = $anvil->data->{path}{directories}{firewalld_services}; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0018", variables => { directory => $directory }}); if (not -d $directory) { # Missing directory... diff --git a/tools/anvil-daemon b/tools/anvil-daemon index eb10161c..a396dd17 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -3,7 +3,11 @@ # This is the master daemon that manages all periodically run processes on Striker dashboards and Anvil! # nodes. # -# TODO: At somepoint, we'll need to have a mechanism to fire off processes that might take a long time. +# Exit codes; +# 0 = Normal exit +# 1 = md5sum of this program changed. Exited to reload. +# +# TODO: At some point, we'll need to have a mechanism to fire off processes that might take a long time. # use strict; use warnings; @@ -25,6 +29,10 @@ $anvil->Log->level({set => 2}); # There are some things we only want to run on (re)start and don't need to always run. run_once($anvil); +# Calculate my sum so that we can exit if it changes later. +$anvil->data->{md5sum}{$THIS_FILE}{start_time} = $anvil->Get->md5sum({file => $0}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "md5sum::${THIS_FILE}::start_time" => $anvil->data->{md5sum}{$THIS_FILE}{start_time} }}); + # These are the things we always want running. while(1) { @@ -71,6 +79,19 @@ sub keep_running # Update hardware state files. update_state_file($anvil); + # Has the file on disk changed? + $anvil->data->{md5sum}{$THIS_FILE}{now} = $anvil->Get->md5sum({file => $0}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "md5sum::${THIS_FILE}::start_time" => $anvil->data->{md5sum}{$THIS_FILE}{start_time}, + "md5sum::${THIS_FILE}::now" => $anvil->data->{md5sum}{$THIS_FILE}{now}, + }}); + if ($anvil->data->{md5sum}{$THIS_FILE}{now} ne $anvil->data->{md5sum}{$THIS_FILE}{start_time}) + { + # Exit. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "warn", key => "message_0013", variables => { file => $THIS_FILE }}); + $anvil->nice_exit({code => 1}); + } + return(0); } diff --git a/tools/anvil-prep-database b/tools/anvil-prep-database index 3abbb999..53155fa1 100755 --- a/tools/anvil-prep-database +++ b/tools/anvil-prep-database @@ -35,12 +35,12 @@ $anvil->data->{path}{config}{'striker.conf'} = "/etc/anvil/anvil.conf"; $anvil->Storage->read_config({file => $anvil->data->{path}{config}{'striker.conf'}}); my $local_id = $anvil->Database->get_local_id; -$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { local_id => $local_id }}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { local_id => $local_id }}); if ($local_id) { # Start checks my $running = $anvil->System->check_daemon({daemon => "postgresql"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { running => $running }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { running => $running }}); if (not $running) { # Do we need to initialize the databae? @@ -48,7 +48,7 @@ if ($local_id) { # Initialize. my $output = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{'postgresql-setup'}." initdb", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); # Did it succeed? if (not -e $anvil->data->{path}{configs}{'pg_hba.conf'}) @@ -65,7 +65,7 @@ if ($local_id) # Setup postgresql.conf my $postgresql_backup = $anvil->data->{path}{directories}{backups}."/pgsql/postgresql.conf"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { postgresql_backup => $postgresql_backup }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { postgresql_backup => $postgresql_backup }}); $anvil->Storage->copy_file({source => $anvil->data->{path}{configs}{'postgresql.conf'}, target => $postgresql_backup}); my $postgresql_conf = $anvil->Storage->read_file({file => $anvil->data->{path}{configs}{'postgresql.conf'}}); @@ -87,7 +87,7 @@ if ($local_id) } $new_postgresql_conf .= $line."\n"; } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update_file => $update_file }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { update_file => $update_file }}); if ($update_file) { $anvil->Storage->write_file({ @@ -103,7 +103,7 @@ if ($local_id) # Setup pg_hba.conf now my $pg_hba_backup = $anvil->data->{path}{directories}{backups}."/pgsql/pg_hba.conf"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { pg_hba_backup => $pg_hba_backup }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { pg_hba_backup => $pg_hba_backup }}); $anvil->Storage->copy_file({source => $anvil->data->{path}{configs}{'pg_hba.conf'}, target => $pg_hba_backup}); my $pg_hba_conf = $anvil->Storage->read_file({file => $anvil->data->{path}{configs}{'pg_hba.conf'}}); @@ -129,7 +129,7 @@ if ($local_id) $new_pg_hba_conf .= $line."\n"; } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update_file => $update_file }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { update_file => $update_file }}); if ($update_file) { $anvil->Storage->write_file({ @@ -146,7 +146,7 @@ if ($local_id) # Start the daemon. It might fail if it has never been initialized. my $started = $anvil->System->start_daemon({daemon => "postgresql"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { started => $started }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { started => $started }}); if ($started) { # Started the daemon. @@ -162,14 +162,14 @@ if ($local_id) # Create the .pgpass file, if needed. my $created_pgpass = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 1, list => { 'path::secure::postgres_pgpass' => $anvil->data->{path}{secure}{postgres_pgpass}, "database::${local_id}::password" => $anvil->data->{database}{$local_id}{password}, }}); if ((not -e $anvil->data->{path}{secure}{postgres_pgpass}) && ($anvil->data->{database}{$local_id}{password})) { my $body = "*:*:*:postgres:".$anvil->data->{database}{$local_id}{password}."\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { body => $body }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 1, list => { body => $body }}); $anvil->Storage->write_file({ file => $anvil->data->{path}{secure}{postgres_pgpass}, body => $body, @@ -182,14 +182,14 @@ if ($local_id) if (-e $anvil->data->{path}{secure}{postgres_pgpass}) { $created_pgpass = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { created_pgpass => $created_pgpass }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { created_pgpass => $created_pgpass }}); } } # Does the database user exist? my $create_user = 1; my $scancore_user = $anvil->data->{database}{$local_id}{user}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scancore_user => $scancore_user }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { scancore_user => $scancore_user }}); if (not $scancore_user) { # No database user defined @@ -197,33 +197,33 @@ if ($local_id) exit(3); } my $user_list = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." template1 -c 'SELECT usename, usesysid FROM pg_catalog.pg_user;'\"", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { user_list => $user_list }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user_list => $user_list }}); foreach my $line (split/\n/, $user_list) { if ($line =~ /^ $scancore_user\s+\|\s+(\d+)/) { # User exists already my $id = $1; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0005", variables => { user => $scancore_user, id => $id }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0005", variables => { user => $scancore_user, id => $id }}); $create_user = 0; last; } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { create_user => $create_user }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { create_user => $create_user }}); if ($create_user) { # Create the user my $create_output = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{createuser}." --no-superuser --createdb --no-createrole $scancore_user\"", source => $THIS_FILE, line => __LINE__}); my $user_list = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." template1 -c 'SELECT usename, usesysid FROM pg_catalog.pg_user;'\"", source => $THIS_FILE, line => __LINE__}); my $user_exists = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { create_output => $create_output, user_list => $user_list }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { create_output => $create_output, user_list => $user_list }}); foreach my $line (split/\n/, $user_list) { if ($line =~ /^ $scancore_user\s+\|\s+(\d+)/) { # Success! my $id = $1; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0006", variables => { user => $scancore_user, id => $id }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0006", variables => { user => $scancore_user, id => $id }}); $user_exists = 1; last; } @@ -240,13 +240,13 @@ if ($local_id) foreach my $user ("postgres", $scancore_user) { my $update_output = $anvil->System->call({secure => 1, shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." template1 -c \\\"ALTER ROLE $user WITH PASSWORD '".$anvil->data->{database}{$local_id}{password}."';\\\"\"", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { update_output => $update_output }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 1, list => { update_output => $update_output }}); foreach my $line (split/\n/, $user_list) { if ($line =~ /ALTER ROLE/) { # Password set - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0007", variables => { user => $user }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0007", variables => { user => $user }}); } } } @@ -256,35 +256,35 @@ if ($local_id) # Create the database, if needed. my $create_database = 1; my $scancore_database = $anvil->data->{database}{$local_id}{name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "database::${local_id}::name" => $anvil->data->{database}{$local_id}{name} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "database::${local_id}::name" => $anvil->data->{database}{$local_id}{name} }}); my $database_list = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." template1 -c 'SELECT datname FROM pg_catalog.pg_database;'\"", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { database_list => $database_list }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { database_list => $database_list }}); foreach my $line (split/\n/, $database_list) { if ($line =~ /^ $scancore_database$/) { # Database already exists. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0008", variables => { database => $scancore_database }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0008", variables => { database => $scancore_database }}); $create_database = 0; last; } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { create_database => $create_database }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { create_database => $create_database }}); if ($create_database) { my $create_output = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{createdb}." --owner $scancore_user $scancore_database\"", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { create_output => $create_output }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { create_output => $create_output }}); my $database_exists = 0; my $database_list = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." template1 -c 'SELECT datname FROM pg_catalog.pg_database;'\"", source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { database_list => $database_list }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { database_list => $database_list }}); foreach my $line (split/\n/, $database_list) { if ($line =~ /^ $scancore_database$/) { # Database created - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0008", variables => { database => $scancore_database }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0008", variables => { database => $scancore_database }}); $database_exists = 1; last; } @@ -350,16 +350,16 @@ RateLimitBurst=0 $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0012", variables => { file => $anvil->data->{path}{configs}{'journald_an'} }}); my $shell_call = $anvil->data->{path}{exe}{systemctl}." restart systemd-journald.service"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); my $output = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); } } else { # Didn't find an entry for this machine. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0010"}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "message_0010"}); } exit(0); diff --git a/tools/anvil-update-states b/tools/anvil-update-states index 21860866..274eaa9a 100755 --- a/tools/anvil-update-states +++ b/tools/anvil-update-states @@ -25,7 +25,7 @@ my $connections = $anvil->Database->connect({ sql_file => $anvil->data->{sys}{database}{schema}, test_table => "network_interfaces", }); -$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132", variables => { connections => $connections }}); +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0132", variables => { connections => $connections }}); if (not $connections) { # No databases, exit. @@ -92,7 +92,7 @@ sub report_network } # Log - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface, mac_address => $mac_address, link_state => $link_state, diff --git a/tools/words.xml b/tools/words.xml index cd752537..0c0edebd 100644 --- a/tools/words.xml +++ b/tools/words.xml @@ -34,6 +34,7 @@ Author: Madison Kelly The SSH session to: [#!variable!target!#] was closed because 'no_cache' was set and there was an open SSH connection. Wrote the system UUID to the file: [#!variable!file!#] to enable the web based tools to read this system's UUID. Wrote the journald config file: [#!variable!file!#] to disable rate limiting to ensure high log levels are not lost. + The md5sum of: [#!variable!file!#] has changed since the daemon started. Exiting to reload. Starting: [#!variable!program!#].