* Finished the initial tools/striker-initialize-host!

* Created Tools->refresh to reload anvil.conf in one call.
* Created Anvil::Tools::Network to hold network-related tasks.
** Created Network->is_remote() that tests to see if a string (containing a target) refers to the remote machine (versus a local machine). Updated all previous checks to use this new method.
** Moved Get->network_details() and Get->network() to the new Network module. Renamed Get->network() to Network->get_network().
** Made Network->get_ips() work locally and remotely.
** Created Network->find_matches() that compares two scanned machines IPs (via two previous calls to Network->get_ips())
* Created Database->manage_anvil_conf() that will add, update or remove a given database connection in a local or remote anvil.conf file.
* Fixed bugs in Storage->backup() where the bash calls were quite broken. I'm not sure how it ever worked before... x_x
* Updated anvil-daemon to not initialize a database unless it's running on dashboard. Also added a check at the startup of anvil-daemon where it will go into a loop waiting for a database to become available, re-reading anvil.conf each loop.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent a54e0d4e22
commit b9a0cc4d56
  1. 37
      Anvil/Tools.pm
  2. 10
      Anvil/Tools/DRBD.pm
  3. 450
      Anvil/Tools/Database.pm
  4. 129
      Anvil/Tools/Get.pm
  5. 676
      Anvil/Tools/Network.pm
  6. 4
      Anvil/Tools/Server.pm
  7. 26
      Anvil/Tools/Storage.pm
  8. 12
      Anvil/Tools/Striker.pm
  9. 269
      Anvil/Tools/System.pm
  10. 18
      cgi-bin/striker
  11. 5
      notes
  12. 5
      share/words.xml
  13. 2
      tools/anvil-configure-host
  14. 72
      tools/anvil-daemon
  15. 18
      tools/anvil-manage-files
  16. 16
      tools/anvil-manage-firewall
  17. 30
      tools/anvil-update-states
  18. 220
      tools/striker-initialize-host
  19. 16
      tools/striker-manage-install-target

@ -23,6 +23,7 @@ my $THIS_FILE = "Tools.pm";
# data
# environment
# nice_exit
# refresh
# _add_hash_reference
# _anvil_version
# _hostname
@ -46,6 +47,7 @@ use Anvil::Tools::DRBD;
use Anvil::Tools::Get;
use Anvil::Tools::Job;
use Anvil::Tools::Log;
use Anvil::Tools::Network;
use Anvil::Tools::Remote;
use Anvil::Tools::Server;
use Anvil::Tools::Striker;
@ -126,6 +128,7 @@ sub new
GET => Anvil::Tools::Get->new(),
LOG => Anvil::Tools::Log->new(),
JOB => Anvil::Tools::Job->new(),
NETWORK => Anvil::Tools::Network->new(),
REMOTE => Anvil::Tools::Remote->new(),
SERVER => Anvil::Tools::Server->new(),
STRIKER => Anvil::Tools::Striker->new(),
@ -166,6 +169,7 @@ sub new
$anvil->Get->parent($anvil);
$anvil->Log->parent($anvil);
$anvil->Job->parent($anvil);
$anvil->Network->parent($anvil);
$anvil->Remote->parent($anvil);
$anvil->Server->parent($anvil);
$anvil->Striker->parent($anvil);
@ -407,6 +411,26 @@ sub nice_exit
exit($exit_code);
}
=head2 refresh
This method re-reads the configuration file and resets paths, defaults and re-reads the words file(s).
=cut
sub refresh
{
my $self = shift;
my $parameter = shift;
my $anvil = $self;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->_set_paths();
$anvil->_set_defaults(); # This reset the log level
$anvil->Storage->read_config(); # This reset the log level also
$anvil->Get->switches; # Re-read to let switches override again.
$anvil->Words->read();
return(0);
}
#############################################################################################################
# Public methods used to access sub modules. #
@ -514,6 +538,18 @@ sub Log
return ($self->{HANDLE}{LOG});
}
=head2 Network
Access the C<Network.pm> methods via 'C<< $anvil->Network->method >>'.
=cut
sub Network
{
my $self = shift;
return ($self->{HANDLE}{NETWORK});
}
=head2 Remote
Access the C<Remote.pm> methods via 'C<< $anvil->Remote->method >>'.
@ -1063,6 +1099,7 @@ sub _set_paths
'iptables-save' => "/usr/sbin/iptables-save",
journalctl => "/usr/bin/journalctl",
logger => "/usr/bin/logger",
ls => "/usr/bin/ls",
lvchange => "/usr/sbin/lvchange",
lvs => "/usr/sbin/lvs",
lvscan => "/usr/sbin/lvscan",

@ -186,7 +186,7 @@ sub allow_two_primaries
my $shell_call = $anvil->data->{path}{exe}{drbdsetup}." net-options ".$resource." ".$target_node_id." --allow-two-primaries=yes";
my $output = "";
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
($output, my $error, $return_code) = $anvil->Remote->call({
@ -273,7 +273,7 @@ sub get_devices
my $host = $anvil->_short_hostname;
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." dump-xml";
my $output = "";
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
($output, my $error, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->Remote->call({
@ -544,7 +544,7 @@ sub get_status
my $shell_call = $anvil->data->{path}{exe}{drbdsetup}." status --json";
my $output = "";
my $host = $anvil->_short_hostname();
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Clear the hash where we'll store the data.
$host = $target;
@ -817,7 +817,7 @@ sub manage_resource
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." ".$task." ".$resource;
my $output = "";
my $return_code = 255;
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
($output, my $error, $return_code) = $anvil->Remote->call({
@ -906,7 +906,7 @@ sub reload_defaults
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0355"});
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." adjust ".$resource;
my $output = "";
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
($output, my $error, $return_code) = $anvil->Remote->call({

@ -40,6 +40,7 @@ my $THIS_FILE = "Database.pm";
# insert_or_update_variables
# lock_file
# locking
# manage_anvil_conf
# mark_active
# query
# quote
@ -1653,7 +1654,7 @@ sub get_local_uuid
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_local_uuid()" }});
my $local_uuid = "";
my $network_details = $anvil->Get->network_details;
my $network_details = $anvil->Network->get_network_details;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -5648,6 +5649,453 @@ sub locking
return($set);
}
=head2 manage_anvil_conf
This adds, removes or updates a database entry in a machine's anvil.conf file. This returns C<< 0 >> on success, C<< 1 >> if there was a problem.
Parameters;
=head3 db_host (required)
This is the IP address or host name of the database server.
=head3 db_host_uuid (required)
This is the C<< host_uuid >> of the server hosting the database we will be managing.
=head3 db_password (required)
This is the password used to log into the database.
=head3 db_ping (optional, default '1')
This sets whether the target will ping the DB server before trying to connect. See C<< Database->connect >> for more information.
=head3 db_port (optional, default '5432')
This is the port used to connect to the database server.
=head3 password (optional)
If C<< target >> is set, this is the password used to log into the remote system as the C<< remote_user >>. If it is not set, an attempt to connect without a password will be made (though this will usually fail).
B<< NOTE >>: Do not confuse this with C<< db_password >>. This is the password to log into the remote machine being managed.
=head3 port (optional, default 22)
If C<< target >> is set, this is the TCP port number used to connect to the remote machine.
B<< NOTE >>: Do not confuse this with C<< db_port >>. This is the port used to SSH into a remote machine.
=head3 remote_user (optional)
If C<< target >> is set, this is the user account that will be used when connecting to the remote system.
B<< NOTE >>: Do not confuse this with C<< db_user >>. This is the user to use when logging into the machine being managed.
=head3 remove (optional, default '0')
If set to C<< 1 >>, any existing extries for C<< host_uuid >> will be removed from that machine being managed.
B<< NOTE >>: When this is set to C<< 1 >>, C<< db_password >> and C<< db_host >> are not required.
=head3 target (optional)
If set, the file will be read from the target machine. This must be either an IP address or a resolvable host name.
The file will be copied to the local system using C<< $anvil->Storage->rsync() >> and stored in C<< /tmp/<file_path_and_name>.<target> >>. if C<< cache >> is set, the file will be preserved locally. Otherwise it will be deleted once it has been read into memory.
B<< Note >>: the temporary file will be prefixed with the path to the file name, with the C<< / >> converted to C<< _ >>.
=cut
sub manage_anvil_conf
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->manage_anvil_conf()" }});
my $db_password = defined $parameter->{db_password} ? $parameter->{db_password} : "";
my $db_ping = defined $parameter->{db_ping} ? $parameter->{db_ping} : 1;
my $db_port = defined $parameter->{db_port} ? $parameter->{db_port} : 5432;
my $db_host = defined $parameter->{db_host} ? $parameter->{db_host} : "";
my $db_host_uuid = defined $parameter->{db_host_uuid} ? $parameter->{db_host_uuid} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : 22;
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $remove = defined $parameter->{remove} ? $parameter->{remove} : 0;
my $target = defined $parameter->{target} ? $parameter->{target} : "local";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
db_password => $anvil->Log->is_secure($db_password),
db_ping => $db_ping,
db_port => $db_port,
db_host_uuid => $db_host_uuid,
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
remove => $remove,
target => $target,
}});
if (not $db_host_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->manage_anvil_conf()", parameter => "db_host_uuid" }});
return(1);
}
elsif (not $anvil->Validate->is_uuid({uuid => $db_host_uuid}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0031", variables => { db_host_uuid => $db_host_uuid }});
return(1);
}
if (not $remove)
{
if (not $db_host)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->manage_anvil_conf()", parameter => "db_host" }});
return(0);
}
if (not $db_password)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->manage_anvil_conf()", parameter => "db_password" }});
return(0);
}
}
# Read in the anvil.conf
my ($anvil_conf) = $anvil->Storage->read_file({
debug => $debug,
file => $anvil->data->{path}{configs}{'anvil.conf'},
force_read => 1,
port => $port,
password => $anvil->Log->is_secure($password),
remote_user => $remote_user,
secure => 1,
target => $target,
});
if ($anvil_conf eq "!!error!!")
{
# Something went wrong.
return(1);
}
# Now walk through the file and look for '### end db list ###'
my $rewrite = 0;
my $host_variable = "database::${db_host_uuid}::host";
my $host_different = 1;
my $port_variable = "database::${db_host_uuid}::port";
my $port_different = 1;
my $password_variable = "database::${db_host_uuid}::password";
my $password_different = 1;
my $ping_variable = "database::${db_host_uuid}::ping";
my $ping_different = 1;
my $delete_reported = 0;
my $update_reported = 0;
my $new_body = "";
my $just_deleted = 0;
my $test_line = "database::${db_host_uuid}::";
my $insert = "";
my $host_seen = 0;
# If we're not removing, and we don't find the entry at all, this will be inserted.
if (not $remove)
{
$insert = $host_variable." = ".$db_host."\n";
$insert .= $port_variable." = ".$port."\n";
$insert .= $password_variable." = ".$password."\n";
$insert .= $ping_variable." = ".$db_ping."\n";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
host_variable => $host_variable,
port_variable => $port_variable,
password_variable => $anvil->Log->is_secure($password_variable),
ping_variable => $ping_variable,
insert => $anvil->Log->is_secure($insert),
test_line => $test_line,
}});
foreach my $line (split/\n/, $anvil_conf)
{
# Secure password lines ?
my $secure = (($line =~ /password/) && ($line !~ /^#/)) ? 1 : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, secure => $secure, level => $debug, list => { line => $line }});
# If I removed an entry, I also want to delete the white space after it.
if (($just_deleted) && ((not $line) or ($line =~ /^\s+$/)))
{
$just_deleted = 0;
next;
}
$just_deleted = 0;
# If we've hit the end of the DB list, see if we need to insert a new entry.
if ($line eq "### end db list ###")
{
# If I've not seen this DB, enter it.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, secure => 0, level => 2, list => {
host_seen => $host_seen,
remove => $remove,
}});
if ((not $host_seen) && (not $remove))
{
$new_body .= $insert."\n";
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, secure => 1, level => 2, list => {
new_body => $new_body,
rewrite => $rewrite,
}});
}
}
# Now Skip any more comments.
if ($line =~ /^#/)
{
$new_body .= $line."\n";
next;
}
# Process lines with the 'var = val' format
if ($line =~ /^(.*?)(\s*)=(\s*)(.*)$/)
{
my $variable = $1;
my $left_space = $2;
my $right_space = $3;
my $value = $4;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:variable" => $variable,
"s2:value" => $value,
"s3:left_space" => $left_space,
"s4:right_space" => $right_space,
}});
# Is the the host line we're possibly updating?
if ($variable eq $host_variable)
{
# Yup. Are we removing it, or do we need to edit it?
$host_seen = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:value" => $value,
"s2:db_host" => $db_host,
"s3:host_seen" => $host_seen,
}});
if ($remove)
{
# Remove the line
$delete_reported = 1;
$just_deleted = 1;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
just_deleted => $just_deleted,
rewrite => $rewrite,
delete_reported => $delete_reported,
}});
next;
}
elsif ($value eq $db_host)
{
# No change.
$host_different = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_different => $host_different }});
}
else
{
# Needs to be updated.
$line = $variable.$left_space."=".$right_space.$db_host;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
line => $line,
rewrite => $rewrite,
}});
}
}
elsif ($variable eq $port_variable)
{
# Port line
$host_seen = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:value" => $value,
"s2:port" => $port,
"s3:host_seen" => $host_seen,
}});
if ($remove)
{
# Remove it
$delete_reported = 1;
$just_deleted = 1;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
delete_reported => $delete_reported,
just_deleted => $just_deleted,
rewrite => $rewrite,
}});
next;
}
elsif ($value eq $port)
{
# No change.
$port_different = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port_different => $port_different }});
}
else
{
# Needs to be updated.
$update_reported = 1;
$line = $variable.$left_space."=".$right_space.$port;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
update_reported => $update_reported,
line => $line,
rewrite => $rewrite,
}});
}
}
elsif ($variable eq $password_variable)
{
# Password
$host_seen = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, list => {
"s1:value" => $value,
"s2:password" => $anvil->Log->is_secure($password),
"s3:host_seen" => $host_seen,
}});
if ($remove)
{
# Remove it
$delete_reported = 1;
$just_deleted = 1;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
delete_reported => $delete_reported,
just_deleted => $just_deleted,
rewrite => $rewrite,
}});
next;
}
elsif ($value eq $password)
{
# No change.
$password_different = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { password_different => $password_different }});
}
else
{
# Changed, update it
$update_reported = 1;
$line = $variable.$left_space."=".$right_space.$password;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
update_reported => $update_reported,
line => $anvil->Log->is_secure($line),
rewrite => $rewrite,
}});
}
}
elsif ($variable eq $ping_variable)
{
# Ping?
$host_seen = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:value" => $value,
"s2:db_ping" => $db_ping,
"s3:host_seen" => $host_seen,
}});
if ($remove)
{
# Remove it
$delete_reported = 1;
$just_deleted = 1;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
delete_reported => $delete_reported,
just_deleted => $just_deleted,
rewrite => $rewrite,
}});
next;
}
elsif ($value eq $db_ping)
{
# No change.
$ping_different = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ping_different => $ping_different }});
}
else
{
# Changed, update
$update_reported = 1;
$line = $variable.$left_space."=".$right_space.$db_ping;
$rewrite = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
update_reported => $update_reported,
line => $line,
rewrite => $rewrite,
}});
}
}
}
# Add the (modified?) line to the new body.
$new_body .= $line."\n";
}
# If there was a change, write the file out.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:new_body' => $new_body,
's2:rewrite' => $rewrite,
}});
if ($rewrite)
{
# Backup the original
my $backup_file = $anvil->Storage->backup({
debug => 2,
secure => 1,
file => $anvil->data->{path}{configs}{'anvil.conf'},
password => $password,
port => $port,
remote_user => $remote_user,
target => $target,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { backup_file => $backup_file }});
# Now update!
my ($failed) = $anvil->Storage->write_file({
secure => 1,
file => $anvil->data->{path}{configs}{'anvil.conf'},
body => $new_body,
user => "admin",
group => "admin",
mode => "0644",
overwrite => 1,
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
target => $target,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
if ($failed)
{
# Simething went weong.
return(1);
}
# If this is a local update, disconnect (if no connections exist, will still clear out known
# databases), the re-read the new config.
if (not $anvil->Network->is_remote($target))
{
$anvil->Database->disconnect;
# Re-read the config.
sleep 1;
$anvil->Storage->read_config({file => $anvil->data->{path}{configs}{'anvil.conf'}});
# Reconnect
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
}
}
return(0);
}
=head2 mark_active
This sets or clears that the caller is about to work on the database

@ -20,8 +20,6 @@ my $THIS_FILE = "Get.pm";
# date_and_time
# host_uuid
# md5sum
# network
# network_details
# switches
# users_home
# uuid
@ -136,7 +134,7 @@ sub anvil_version
}});
# Is this a local call or a remote call?
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call. If we're running as the apache user, we need to read the cached version for
# the peer. otherwise, after we read the version, will write the cached version.
@ -692,131 +690,6 @@ sub md5sum
return($sum);
}
=head2 network
This takes an IP address and subnet and returns the network it belongs too. For example;
my $network = $anvil->Get->network({ip => "10.2.4.1", subnet => "255.255.0.0"});
This would set C<< $network >> to C<< 10.2.0.0 >>.
If the network can't be caluclated for any reason, and empty string will be returned.
Parameters;
=head3 ip (required)
This is the IPv4 IP address being calculated.
=head3 subnet (required)
This is the subnet of the IP address being calculated.
=cut
sub network
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $network = "";
my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
my $subnet = defined $parameter->{subnet} ? $parameter->{subnet} : "";
if (not $ip)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Get->network()", parameter => "ip" }});
}
if (not $subnet)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Get->network()", parameter => "subnet" }});
}
my $block = Net::Netmask->new($ip."/".$subnet);
my $base = $block->base();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { base => $base }});
if ($anvil->Validate->is_ipv4({ip => $base}))
{
$network = $base;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network => $network }});
}
return($network);
}
### TODO: Is this a waste of time / duplicate of System->get_ips()?
=head2 network_details
This method returns the local hostname and IP addresses.
It returns a hash reference containing data in the following keys:
C<< hostname >> = <name>
C<< interface::<interface>::ip >> = <ip_address>
C<< interface::<interface>::netmask >> = <dotted_decimal_subnet>
=cut
sub network_details
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $network = {};
my ($hostname, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{hostname}});
(my $ip_addr_list, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ip}." addr list"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
hostname => $hostname,
ip_addr_list => $ip_addr_list,
}});
$network->{hostname} = $hostname;
my $in_interface = "";
my $ip_address = "";
my $subnet_mask = "";
foreach my $line (split/\n/, $ip_addr_list)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^\d+: (.*?):/)
{
$in_interface = $1;
$ip_address = "";
$subnet_mask = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_interface => $in_interface }});
next if $in_interface eq "lo";
$network->{interface}{$in_interface}{ip} = "--";
$network->{interface}{$in_interface}{netmask} = "--";
}
if ($in_interface)
{
next if $in_interface eq "lo";
if ($line =~ /inet (.*?)\/(.*?) /)
{
$ip_address = $1;
$subnet_mask = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
ip_address => $ip_address,
subnet_mask => $subnet_mask,
}});
if ((($subnet_mask =~ /^\d$/) or ($subnet_mask =~ /^\d\d$/)) && ($subnet_mask < 25))
{
$subnet_mask = $anvil->Convert->cidr({cidr => $subnet_mask});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { subnet_mask => $subnet_mask }});
}
$network->{interface}{$in_interface}{ip} = $ip_address;
$network->{interface}{$in_interface}{netmask} = $subnet_mask;
}
}
}
return($network);
}
=head2 switches
This reads in the command line switches used to invoke the parent program.

@ -0,0 +1,676 @@
package Anvil::Tools::Network;
#
# This module contains methods used to deal with networking stuff.
#
use strict;
use warnings;
use Data::Dumper;
use Scalar::Util qw(weaken isweak);
our $VERSION = "3.0.0";
my $THIS_FILE = "Network.pm";
### Methods;
# find_matches
# get_ips
# get_network
# is_local
=pod
=encoding utf8
=head1 NAME
Anvil::Tools::Network
Provides all methods related to networking.
=head1 SYNOPSIS
use Anvil::Tools;
# Get a common object handle on all Anvil::Tools modules.
my $anvil = Anvil::Tools->new();
# Access to methods using '$anvil->Storage->X'.
#
=head1 METHODS
Methods in this module;
=cut
sub new
{
my $class = shift;
my $self = {
};
bless $self, $class;
return ($self);
}
# Get a handle on the Anvil::Tools object. I know that technically that is a sibling module, but it makes more
# sense in this case to think of it as a parent.
sub parent
{
my $self = shift;
my $parent = shift;
$self->{HANDLE}{TOOLS} = $parent if $parent;
# Defend against memory leads. See Scalar::Util'.
if (not isweak($self->{HANDLE}{TOOLS}))
{
weaken($self->{HANDLE}{TOOLS});
}
return ($self->{HANDLE}{TOOLS});
}
#############################################################################################################
# Public methods #
#############################################################################################################
=head2 find_matches
This takes two hash keys from prior C<< Network->get_ips() >> runs and finds which are on the same network.
Paramters;
=head3 first (required)
This is the hash key of the first machine being compared.
=head3 second (required)
This is the hash key of the second machine being compared.
=cut
sub find_matches
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->find_matches()" }});
my $first = defined $parameter->{first} ? $parameter->{first} : "";
my $second = defined $parameter->{second} ? $parameter->{second} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
first => $first,
second => $second,
}});
if (ref($anvil->data->{network}{$first}) ne "HASH")
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->find_matches()", parameter => "first" }});
return("");
}
if (ref($anvil->data->{network}{$second}) ne "HASH")
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->find_matches()", parameter => "second" }});
return("");
}
# Loop through the first, and on each interface with an IP/subnet, look for a match in the second.
my $match = {};
foreach my $first_interface (sort {$b cmp $a} keys %{$anvil->data->{network}{$first}{interface}})
{
my $first_ip = $anvil->data->{network}{$first}{interface}{$first_interface}{ip};
my $first_subnet = $anvil->data->{network}{$first}{interface}{$first_interface}{subnet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
first => $first,
first_interface => $first_interface,
first_ip => $first_ip,
first_subnet => $first_subnet,
}});
if (($first_ip) && ($first_subnet))
{
# Look for a match.
my $first_network = $anvil->Network->get_network({
debug => $debug,
ip => $first_ip,
subnet => $first_subnet,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { a_network => $first_network }});
foreach my $second_interface (sort {$b cmp $a} keys %{$anvil->data->{network}{$second}{interface}})
{
my $second_ip = $anvil->data->{network}{$second}{interface}{$second_interface}{ip};
my $second_subnet = $anvil->data->{network}{$second}{interface}{$second_interface}{subnet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
second => $second,
second_interface => $second_interface,
second_ip => $second_ip,
second_subnet => $second_subnet,
}});
if (($second_ip) && ($second_subnet))
{
# Do we have a match?
my $second_network = $anvil->Network->get_network({
debug => $debug,
ip => $second_ip,
subnet => $second_subnet,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
a_network => $first_network,
b_network => $second_network,
}});
if ($first_network eq $second_network)
{
# Match!
$match->{$first}{$first_interface} = $second_network;
$match->{$second}{$second_interface} = $second_network;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"${first}::${first_interface}" => $match->{$first}{$first_interface},
"${second}::${second_interface}" => $match->{$second}{$second_interface},
}});
}
}
}
}
}
return($match);
}
=head2 get_ips
This method checks the local system for interfaces and stores them in:
* C<< network::<target>::interface::<iface_name>::ip >> - If an IP address is set
* C<< network::<target>::interface::<iface_name>::subnet >> - If an IP is set
* C<< network::<target>::interface::<iface_name>::mac >> - Always set.
* C<< network::<target>::interface::<iface_name>::default_gateway >> = C<< 0 >> if not the default gateway, C<< 1 >> if so.
* C<< network::<target>::interface::<iface_name>::gateway >> = If the default gateway, this is the gateway IP address.
* C<< network::<target>::interface::<iface_name>::dns >> = If the default gateway, this is the comma-separated list of active DNS servers.
When called without a C<< target >>, C<< local >> is used.
To aid in look-up by MAC address, C<< network::mac::<mac_address>::iface >> is also set. Note that this is not target-dependent.
Parameters;
=head3 password (optional)
If C<< target >> is set, this is the password used to log into the remote system as the C<< remote_user >>. If it is not set, an attempt to connect without a password will be made (though this will usually fail).
=head3 port (optional, default 22)
If C<< target >> is set, this is the TCP port number used to connect to the remote machine.
=head3 remote_user (optional)
If C<< target >> is set, this is the user account that will be used when connecting to the remote system.
=head3 target (optional)
If set, the file will be read from the target machine. This must be either an IP address or a resolvable host name.
The file will be copied to the local system using C<< $anvil->Storage->rsync() >> and stored in C<< /tmp/<file_path_and_name>.<target> >>. if C<< cache >> is set, the file will be preserved locally. Otherwise it will be deleted once it has been read into memory.
B<< Note >>: the temporary file will be prefixed with the path to the file name, with the C<< / >> converted to C<< _ >>.
=cut
sub get_ips
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->get_ips()" }});
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : 22;
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : "local";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
target => $target,
}});
# Reading locally or remote?
my $in_iface = "";
my $shell_call = $anvil->data->{path}{exe}{ip}." addr list";
my $output = "";
if ($anvil->Network->is_remote($target))
{
# Remote call
($output, my $error, my $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
user => $remote_user,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:error' => $error,
's3:return_code' => $return_code,
}});
}
else
{
# Local call.
($output, my $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
}
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^\d+: (.*?): /)
{
$in_iface = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_iface => $in_iface }});
$anvil->data->{network}{$target}{interface}{$in_iface}{ip} = "" if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{ip};
$anvil->data->{network}{$target}{interface}{$in_iface}{subnet} = "" if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{subnet};
$anvil->data->{network}{$target}{interface}{$in_iface}{mac} = "" if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{mac};
$anvil->data->{network}{$target}{interface}{$in_iface}{default_gateway} = 0 if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{default_gateway};
$anvil->data->{network}{$target}{interface}{$in_iface}{gateway} = "" if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{gateway};
$anvil->data->{network}{$target}{interface}{$in_iface}{dns} = "" if not defined $anvil->data->{network}{$target}{interface}{$in_iface}{dns};
}
next if not $in_iface;
if ($in_iface eq "lo")
{
# We don't care about 'lo'.
delete $anvil->data->{network}{$target}{interface}{$in_iface};
next;
}
if ($line =~ /inet (.*?)\/(.*?) /)
{
my $ip = $1;
my $cidr = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip, cidr => $cidr }});
my $subnet = $cidr;
if (($cidr =~ /^\d{1,2}$/) && ($cidr >= 0) && ($cidr <= 32))
{
# Convert to subnet
$subnet = $anvil->Convert->cidr({cidr => $cidr});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { subnet => $subnet }});
}
$anvil->data->{network}{$target}{interface}{$in_iface}{ip} = $ip;
$anvil->data->{network}{$target}{interface}{$in_iface}{subnet} = $subnet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:network::${target}::interface::${in_iface}::ip" => $anvil->data->{network}{$target}{interface}{$in_iface}{ip},
"s2:network::${target}::interface::${in_iface}::subnet" => $anvil->data->{network}{$target}{interface}{$in_iface}{subnet},
}});
}
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)
{
my $mac = $1;
$anvil->data->{network}{$target}{interface}{$in_iface}{mac} = $mac;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${target}::interface::${in_iface}::mac" => $anvil->data->{network}{$target}{interface}{$in_iface}{mac},
}});
# We only record the mac in 'network::mac' if this isn't a bond.
my $test_file = "/proc/net/bonding/".$in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { test_file => $test_file }});
if (not -e $test_file)
{
$anvil->data->{network}{mac}{$mac}{iface} = $in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::mac::${mac}::iface" => $anvil->data->{network}{mac}{$mac}{iface},
}});
}
}
}
# Read the config files for the interfaces we've found. Use 'ls' to find the interface files. Then
# we'll read them all in.
$shell_call = $anvil->data->{path}{exe}{ls}." ".$anvil->data->{path}{directories}{ifcfg};
$output = "";
if ($anvil->Network->is_remote($target))
{
# Remote call
($output, my $error, my $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
user => $remote_user,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:error' => $error,
's3:return_code' => $return_code,
}});
}
else
{
# Local call.
($output, my $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
}
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
next if $line !~ /^ifcfg-/;
my $full_path = $anvil->data->{path}{directories}{ifcfg}."/".$line;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { full_path => $full_path }});
my $file_body = $anvil->Storage->read_file({
debug => $debug,
file => $full_path,
target => $target,
password => $password,
port => $port,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:full_path" => $full_path,
"s2:file_body" => $file_body,
}});
# Break it apart and store any variables.
my $temp = {};
my $interface = "";
foreach my $line (split/\n/, $file_body)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
next if $line =~ /^#/;
if ($line =~ /(.*?)=(.*)/)
{
my $variable = $1;
my $value = $2;
$value =~ s/^"(.*)"$/$1/;
$temp->{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "temp->{$variable}" => $temp->{$variable} }});
if (uc($variable) eq "DEVICE")
{
$interface = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "interface" => $interface }});
}
}
if ($interface)
{
$anvil->data->{network}{$target}{interface}{$interface}{file} = $full_path;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${target}::interface::${interface}::file" => $anvil->data->{network}{$target}{interface}{$interface}{file},
}});
foreach my $variable (sort {$a cmp $b} keys %{$temp})
{
$anvil->data->{network}{$target}{interface}{$interface}{variable}{$variable} = $temp->{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${target}::interface::${interface}::file::variable::${variable}" => $anvil->data->{network}{$target}{interface}{$interface}{variable}{$variable},
}});
}
}
}
}
# Get the routing info.
my $lowest_metric = 99999999;
my $route_interface = "";
my $route_ip = "";
$shell_call = $anvil->data->{path}{exe}{ip}." route show";
$output = "";
if ($anvil->Network->is_remote($target))
{
# Remote call
($output, my $error, my $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
user => $remote_user,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:error' => $error,
's3:return_code' => $return_code,
}});
}
else
{
# Local call.
($output, my $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
}
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /default via (.*?) dev (.*?) proto .*? metric (\d+)/i)
{
my $this_ip = $1;
my $this_interface = $2;
my $metric = $3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:this_ip' => $this_ip,
's2:this_interface' => $this_interface,
's3:metric' => $metric,
's4:lowest_metric' => $lowest_metric,
}});
if ($metric < $lowest_metric)
{
$lowest_metric = $metric;
$route_interface = $this_interface;
$route_ip = $this_ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
lowest_metric => $lowest_metric,
route_interface => $route_interface,
route_ip => $route_ip,
}});
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
route_interface => $route_interface,
route_ip => $route_ip,
}});
# If I got a route, get the DNS.
if ($route_interface)
{
# I want to build the DNS list from only the interface that is used for routing.
my $in_interface = "";
my $dns_list = "";
my $dns_hash = {};
my $shell_call = $anvil->data->{path}{exe}{nmcli}." dev show";
my $output = "";
if ($anvil->Network->is_remote($target))
{
# Remote call
($output, my $error, my $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
user => $remote_user,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:error' => $error,
's3:return_code' => $return_code,
}});
}
else
{
# Local call.
($output, my $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
}
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /GENERAL.DEVICE:\s+(.*)$/)
{
$in_interface = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_interface => $in_interface }});
}
if (not $line)
{
$in_interface = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_interface => $in_interface }});
}
next if $in_interface ne $route_interface;
if ($line =~ /IP4.DNS\[(\d+)\]:\s+(.*)/i)
{
my $order = $1;
my $ip = $2;
$dns_hash->{$order} = $ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "dns_hash->{$order}" => $dns_hash->{$order} }});
}
}
foreach my $order (sort {$a cmp $b} keys %{$dns_hash})
{
$dns_list .= $dns_hash->{$order}.", ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:dns_hash->{$order}" => $dns_hash->{$order},
"s2:dns_list" => $dns_list,
}});
}
$dns_list =~ s/, $//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { dns_list => $dns_list }});
$anvil->data->{network}{$target}{interface}{$route_interface}{default_gateway} = 1;
$anvil->data->{network}{$target}{interface}{$route_interface}{gateway} = $route_ip;
$anvil->data->{network}{$target}{interface}{$route_interface}{dns} = $dns_list;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${target}::interface::${route_interface}::default_gateway" => $anvil->data->{network}{$target}{interface}{$route_interface}{default_gateway},
"network::${target}::interface::${route_interface}::gateway" => $anvil->data->{network}{$target}{interface}{$route_interface}{gateway},
"network::${target}::interface::${route_interface}::dns" => $anvil->data->{network}{$target}{interface}{$route_interface}{dns},
}});
}
return(0);
}
=head2 get_network
This takes an IP address and subnet and returns the network it belongs too. For example;
my $network = $anvil->Network->get_network({ip => "10.2.4.1", subnet => "255.255.0.0"});
This would set C<< $network >> to C<< 10.2.0.0 >>.
If the network can't be caluclated for any reason, and empty string will be returned.
Parameters;
=head3 ip (required)
This is the IPv4 IP address being calculated.
=head3 subnet (required)
This is the subnet of the IP address being calculated.
=cut
sub get_network
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $network = "";
my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
my $subnet = defined $parameter->{subnet} ? $parameter->{subnet} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
ip => $ip,
subnet => $subnet,
}});
if (not $ip)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->get_network()", parameter => "ip" }});
return("");
}
if (not $subnet)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->get_network()", parameter => "subnet" }});
return("");
}
my $block = Net::Netmask->new($ip."/".$subnet);
my $base = $block->base();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { base => $base }});
if ($anvil->Validate->is_ipv4({ip => $base}))
{
$network = $base;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network => $network }});
}
return($network);
}
=head2 is_remote
This looks at the C<< target >> and determines if it relates to the local system or not. If the C<< target >> is remote, C<< 1 >> is returned. Otherwise, C<< 0 >> is returned.
if ($anvil->Network->is_remote($target))
{
# Do something remotely
}
else
{
# Do something locally
}
B<< NOTE >>: Unlike most methods, this one does not take a hash reference for the parameters. It takes the string directly.
=cut
sub is_remote
{
my $self = shift;
my $target = shift;
my $anvil = $self->parent;
my $remote = 0;
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
{
# It's a remote system
$remote = 1;
}
return($remote);
}
# =head3
#
# Private Functions;
#
# =cut
#############################################################################################################
# Private functions #
#############################################################################################################
1;

@ -229,7 +229,7 @@ sub find
my $host = $anvil->_hostname;
my $virsh_output = "";
my $return_code = "";
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
($host, my $error, my $host_return_code) = $anvil->Remote->call({
@ -357,7 +357,7 @@ sub get_status
# Is this a local call or a remote call?
my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml ".$server;
my $host = $anvil->_short_hostname;
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote call.
$host = $target;

@ -156,7 +156,7 @@ sub backup
source_file => $source_file,
}});
my $proceed = 0;
my $proceed = 0;
my $target_file = "";
if (not $source_file)
{
@ -171,11 +171,12 @@ sub backup
if ($fatal) { $anvil->nice_exit({code => 1}); }
}
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Make sure the source file exists, is a file and can be read.
my $shell_call = "
if [ -e '".$source_file."' ];
then
if [ -f '".$source_file."' ];
then
if [ -r '".$source_file."' ];
@ -668,19 +669,22 @@ sub copy_file
file => $file,
}});
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Copying on a remote system.
my $proceed = 1;
my $shell_call = "
if [ -e '".$source_file."' ];
then
".$anvil->data->{path}{exe}{echo}." 'source file exists'
else
".$anvil->data->{path}{exe}{echo}." 'source file not found'
fi
if [ -d '".$target_file."' ];
if [ -e '".$target_file."' ];
then
".$anvil->data->{path}{exe}{echo}." 'target file exists'
elif [ -d '".$directory."' ];
then
".$anvil->data->{path}{exe}{echo}." 'target directory exists'
else
".$anvil->data->{path}{exe}{echo}." 'target directory not found'
@ -726,7 +730,7 @@ fi";
}});
return(1);
}
if (($line1 eq "source file exists") && (not $overwrite))
if (($line1 eq "target file exists") && (not $overwrite))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0046", variables => {
method => "copy_file",
@ -984,7 +988,7 @@ sub make_directory
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { working_directory => $working_directory }});
# Are we working locally or remotely?
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Assemble the command
my $shell_call = "
@ -1193,7 +1197,7 @@ sub move_file
}});
}
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Copying on a remote system.
my $proceed = 1;
@ -1561,7 +1565,7 @@ sub read_file
}
# Reading locally or remote?
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# Remote. Make sure the passed file is a full path and file name.
if ($file !~ /^\/\w/)
@ -1913,7 +1917,7 @@ sub rsync
# If local, call rsync directly. If remote, setup the rsync wrapper
my $wrapper_script = "";
my $shell_call = $anvil->data->{path}{exe}{rsync}." ".$switches." ".$source." ".$destination;
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# If we didn't get a port, but the target is pre-configured for a port, use it.
if ((not $parameter->{port}) && ($anvil->data->{hosts}{$target}{port}))
@ -2414,7 +2418,7 @@ sub update_config
# Did we see the variable?
if (not $seen)
{
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0175", variables => {
variable => $variable,
@ -2743,7 +2747,7 @@ sub write_file
}});
# Now, are we writing locally or on a remote system?
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
# If we didn't get a port, but the target is pre-configured for a port, use it.
if ((not $parameter->{port}) && ($anvil->data->{hosts}{$target}{port}))

@ -134,21 +134,21 @@ sub get_local_repo
}
# What are my IPs?
$anvil->System->get_ips();
$anvil->Network->get_ips();
my $base_url = "";
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { interface => $interface }});
if ($anvil->data->{sys}{network}{interface}{$interface}{ip})
if ($anvil->data->{network}{'local'}{interface}{$interface}{ip})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::network::interface::${interface}::ip" => $anvil->data->{sys}{network}{interface}{$interface}{ip} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "network::local::interface::${interface}::ip" => $anvil->data->{network}{'local'}{interface}{$interface}{ip} }});
if (not $base_url)
{
$base_url = "baseurl=http://".$anvil->data->{sys}{network}{interface}{$interface}{ip}.$directory;
$base_url = "baseurl=http://".$anvil->data->{network}{'local'}{interface}{$interface}{ip}.$directory;
}
else
{
$base_url .= "\n http://".$anvil->data->{sys}{network}{interface}{$interface}{ip}.$directory;
$base_url .= "\n http://".$anvil->data->{network}{'local'}{interface}{$interface}{ip}.$directory;
}
}
}

@ -27,7 +27,6 @@ my $THIS_FILE = "System.pm";
# get_host_type
# enable_daemon
# find_matching_ip
# get_ips
# get_uptime
# get_os_type
# hostname
@ -958,7 +957,7 @@ sub get_host_type
$host_type = $anvil->data->{sys}{host_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
}
elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/))
elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/) or ($host_name =~ /new-node+$/))
{
$host_type = "node";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
@ -968,7 +967,7 @@ sub get_host_type
$host_type = "dashboard";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
}
elsif ($host_name =~ /dr\d+$/)
elsif (($host_name =~ /dr\d+$/) or ($host_name =~ /new-dr$/))
{
$host_type = "dr";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
@ -1059,18 +1058,18 @@ sub find_matching_ip
}
# Get my local IPs
$anvil->System->get_ips({debug => $debug});
$anvil->Network->get_ips({debug => $debug});
my $ip = NetAddr::IP->new($host);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip }});
# Look through our IPs. First match wins.
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { interface => $interface }});
next if not $anvil->data->{sys}{network}{interface}{$interface}{ip};
my $this_ip = $anvil->data->{sys}{network}{interface}{$interface}{ip};
my $this_subnet = $anvil->data->{sys}{network}{interface}{$interface}{subnet};
next if not $anvil->data->{network}{'local'}{interface}{$interface}{ip};
my $this_ip = $anvil->data->{network}{'local'}{interface}{$interface}{ip};
my $this_subnet = $anvil->data->{network}{'local'}{interface}{$interface}{subnet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:this_ip" => $this_ip,
"s2:this_subnet" => $this_subnet,
@ -1096,256 +1095,6 @@ sub find_matching_ip
return($local_ip);
}
=head2 get_ips
This method checks the local system for interfaces and stores them in:
* C<< sys::network::interface::<iface_name>::ip >> - If an IP address is set
* C<< sys::network::interface::<iface_name>::subnet >> - If an IP is set
* C<< sys::network::interface::<iface_name>::mac >> - Always set.
* C<< sys::network::interface::<iface_name>::default_gateway >> = C<< 0 >> if not the default gateway, C<< 1 >> if so.
* C<< sys::network::interface::<iface_name>::gateway >> = If the default gateway, this is the gateway IP address.
* C<< sys::network::interface::<iface_name>::dns >> = If the default gateway, this is the comma-separated list of active DNS servers.
To aid in look-up by MAC address, C<< sys::mac::<mac_address>::iface >> is also set.
No parameters are accepted by this method.
=cut
sub get_ips
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->get_ips()" }});
my $in_iface = "";
my ($ip_addr, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ip}." addr list"});
foreach my $line (split/\n/, $ip_addr)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^\d+: (.*?): /)
{
$in_iface = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_iface => $in_iface }});
$anvil->data->{sys}{network}{interface}{$in_iface}{ip} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{ip};
$anvil->data->{sys}{network}{interface}{$in_iface}{subnet} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{subnet};
$anvil->data->{sys}{network}{interface}{$in_iface}{mac} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{mac};
$anvil->data->{sys}{network}{interface}{$in_iface}{default_gateway} = 0 if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{default_gateway};
$anvil->data->{sys}{network}{interface}{$in_iface}{gateway} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{gateway};
$anvil->data->{sys}{network}{interface}{$in_iface}{dns} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{dns};
}
next if not $in_iface;
if ($in_iface eq "lo")
{
# We don't care about 'lo'.
delete $anvil->data->{sys}{network}{interface}{$in_iface};
next;
}
if ($line =~ /inet (.*?)\/(.*?) /)
{
my $ip = $1;
my $cidr = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip, cidr => $cidr }});
my $subnet = $cidr;
if (($cidr =~ /^\d{1,2}$/) && ($cidr >= 0) && ($cidr <= 32))
{
# Convert to subnet
$subnet = $anvil->Convert->cidr({cidr => $cidr});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { subnet => $subnet }});
}
$anvil->data->{sys}{network}{interface}{$in_iface}{ip} = $ip;
$anvil->data->{sys}{network}{interface}{$in_iface}{subnet} = $subnet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:sys::network::interface::${in_iface}::ip" => $anvil->data->{sys}{network}{interface}{$in_iface}{ip},
"s2:sys::network::interface::${in_iface}::subnet" => $anvil->data->{sys}{network}{interface}{$in_iface}{subnet},
}});
}
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)
{
my $mac = $1;
$anvil->data->{sys}{network}{interface}{$in_iface}{mac} = $mac;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${in_iface}::mac" => $anvil->data->{sys}{network}{interface}{$in_iface}{mac},
}});
# We only record the mac in 'sys::mac' if this isn't a bond.
my $test_file = "/proc/net/bonding/".$in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { test_file => $test_file }});
if (not -e $test_file)
{
$anvil->data->{sys}{mac}{$mac}{iface} = $in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::mac::${mac}::iface" => $anvil->data->{sys}{mac}{$mac}{iface},
}});
}
}
}
# Read the config files for the interfaces we've found.
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0018", variables => { "path::directories::ifcfg" => $anvil->data->{path}{directories}{ifcfg} }});
opendir(DIRECTORY, $anvil->data->{path}{directories}{ifcfg});
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
next if $file eq "ifcfg-lo";
next if $file !~ /^ifcfg/;
next if $file =~ /\.bak$/;
my $full_path = $anvil->data->{path}{directories}{ifcfg}."/".$file;
$full_path =~ s/\/\///g;
next if not -f $full_path;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file => $file }});
# Read the file.
my $file_body = $anvil->Storage->read_file({file => $full_path});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:full_path" => $full_path,
"s2:file_body" => $file_body,
}});
# Break it apart and store any variables.
my $temp = {};
my $interface = "";
foreach my $line (split/\n/, $file_body)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
next if $line =~ /^#/;
if ($line =~ /(.*?)=(.*)/)
{
my $variable = $1;
my $value = $2;
$value =~ s/^"(.*)"$/$1/;
$temp->{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "temp->{$variable}" => $temp->{$variable} }});
if (uc($variable) eq "DEVICE")
{
$interface = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "interface" => $interface }});
}
}
if ($interface)
{
$anvil->data->{sys}{network}{interface}{$interface}{file} = $full_path;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${interface}::file" => $anvil->data->{sys}{network}{interface}{$interface}{file},
}});
foreach my $variable (sort {$a cmp $b} keys %{$temp})
{
$anvil->data->{sys}{network}{interface}{$interface}{variable}{$variable} = $temp->{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${interface}::file::variable::${variable}" => $anvil->data->{sys}{network}{interface}{$interface}{variable}{$variable},
}});
}
}
}
}
closedir(DIRECTORY);
# Get the routing info.
my $lowest_metric = 99999999;
my $route_interface = "";
my $route_ip = "";
(my $ip_route, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ip}." route show"});
foreach my $line (split/\n/, $ip_route)
{
$line = $anvil->Words->clean_spaces({ string => $line });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /default via (.*?) dev (.*?) proto .*? metric (\d+)/i)
{
my $this_ip = $1;
my $this_interface = $2;
my $metric = $3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:this_ip' => $this_ip,
's2:this_interface' => $this_interface,
's3:metric' => $metric,
's4:lowest_metric' => $lowest_metric,
}});
if ($metric < $lowest_metric)
{
$lowest_metric = $metric;
$route_interface = $this_interface;
$route_ip = $this_ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
lowest_metric => $lowest_metric,
route_interface => $route_interface,
route_ip => $route_ip,
}});
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
route_interface => $route_interface,
route_ip => $route_ip,
}});
# If I got a route, get the DNS.
if ($route_interface)
{
# I want to build the DNS list from only the interface that is used for routing.
my $in_interface = "";
my $dns_list = "";
my $dns_hash = {};
my ($ip_route, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{nmcli}." dev show"});
foreach my $line (split/\n/, $ip_route)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /GENERAL.DEVICE:\s+(.*)$/)
{
$in_interface = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_interface => $in_interface }});
}
if (not $line)
{
$in_interface = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_interface => $in_interface }});
}
next if $in_interface ne $route_interface;
if ($line =~ /IP4.DNS\[(\d+)\]:\s+(.*)/i)
{
my $order = $1;
my $ip = $2;
$dns_hash->{$order} = $ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "dns_hash->{$order}" => $dns_hash->{$order} }});
}
}
foreach my $order (sort {$a cmp $b} keys %{$dns_hash})
{
$dns_list .= $dns_hash->{$order}.", ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:dns_hash->{$order}" => $dns_hash->{$order},
"s2:dns_list" => $dns_list,
}});
}
$dns_list =~ s/, $//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { dns_list => $dns_list }});
$anvil->data->{sys}{network}{interface}{$route_interface}{default_gateway} = 1;
$anvil->data->{sys}{network}{interface}{$route_interface}{gateway} = $route_ip;
$anvil->data->{sys}{network}{interface}{$route_interface}{dns} = $dns_list;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${route_interface}::default_gateway" => $anvil->data->{sys}{network}{interface}{$route_interface}{default_gateway},
"sys::network::interface::${route_interface}::gateway" => $anvil->data->{sys}{network}{interface}{$route_interface}{gateway},
"sys::network::interface::${route_interface}::dns" => $anvil->data->{sys}{network}{interface}{$route_interface}{dns},
}});
}
return(0);
}
=head2 get_uptime
This returns, in seconds, how long the host has been up and running for.
@ -1549,7 +1298,7 @@ sub is_local
else
{
# Get the list of current IPs and see if they match.
my $network = $anvil->Get->network_details;
my $network = $anvil->Network->get_network_details;
foreach my $interface (keys %{$network->{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "network->interface::${interface}::ip" => $network->{interface}{$interface}{ip} }});
@ -2373,7 +2122,7 @@ sub ping
my $error = "";
# If the 'target' is set, we'll call over SSH unless 'target' is 'local' or our hostname.
if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname))
if ($anvil->Network->is_remote($target))
{
### Remote calls
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0166", variables => { shell_call => $shell_call, target => $target, remote_user => $remote_user }});

@ -962,15 +962,15 @@ sub process_sync_page
}
my $host_uuid = $anvil->Get->host_uuid;
$anvil->System->get_ips();
$anvil->Network->get_ips();
# We'll want to show the user way to access the local machine. For that, we'll loop through our own IPs.
my $inbound_table = "";
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
next if (($interface !~ /^bcn/) && ($interface !~ /^ifn/));
next if not $anvil->Validate->is_ipv4({ip => $anvil->data->{sys}{network}{interface}{$interface}{ip}});
next if not $anvil->Validate->is_subnet({subnet => $anvil->data->{sys}{network}{interface}{$interface}{subnet}});
next if not $anvil->Validate->is_ipv4({ip => $anvil->data->{network}{'local'}{interface}{$interface}{ip}});
next if not $anvil->Validate->is_subnet({subnet => $anvil->data->{network}{'local'}{interface}{$interface}{subnet}});
my ($network_type, $network_number) = ($interface =~ /^(.*?)(\d+)_/);
my $database_user = $anvil->data->{database}{$host_uuid}{user} ? $anvil->data->{database}{$host_uuid}{user} : $anvil->data->{sys}{database}{user};
@ -979,18 +979,18 @@ sub process_sync_page
my $say_network = $anvil->Words->string({key => $network_key, variables => { number => $network_number }});
# The user 'admin' and the port 5432 are default, so only show them if they're non-standard.
my $access_string = $database_user."\@".$anvil->data->{sys}{network}{interface}{$interface}{ip}.":".$database_port;
my $access_string = $database_user."\@".$anvil->data->{network}{'local'}{interface}{$interface}{ip}.":".$database_port;
if (($database_port eq "5432") && ($database_user eq "admin"))
{
$access_string = $anvil->data->{sys}{network}{interface}{$interface}{ip};
$access_string = $anvil->data->{network}{'local'}{interface}{$interface}{ip};
}
elsif ($database_port eq "5432")
{
$access_string = $database_user."\@".$anvil->data->{sys}{network}{interface}{$interface}{ip};
$access_string = $database_user."\@".$anvil->data->{network}{'local'}{interface}{$interface}{ip};
}
elsif ($database_user eq "admin")
{
$access_string = $anvil->data->{sys}{network}{interface}{$interface}{ip}.":".$database_port;
$access_string = $anvil->data->{network}{'local'}{interface}{$interface}{ip}.":".$database_port;
}
$inbound_table .= $anvil->Template->get({file => "striker.html", name => "striker-sync-inbound", variables => {
access => $access_string,
@ -1611,7 +1611,7 @@ ORDER BY
# Get the list of current IPs so that we can warn the user if committing the changes will require
# reconnecting.
$anvil->System->get_ips({debug => 2});
$anvil->Network->get_ips({debug => 2});
my $matched_ip = 0;
my $server_ip = $ENV{SERVER_ADDR};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_ip => $server_ip }});

@ -1126,3 +1126,8 @@ pcs constraint remove cli-ban-test_server-on-el8-a01n01
pcs constraint remove $(pcs constraint show --full | grep ban-test_server | perl -pe 's/^.*?id:(.*?)\)/$1/')
DRBD 9 - Check;
/sys/kernel/debug/drbd/resources/${resource_name}/connections/${hostname}/0/proc_drbd

@ -761,6 +761,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a
<key name="log_0436">The setuid c-wrapper: [#!variable!wrapper!#] already exists, no need to create it.</key>
<key name="log_0437">The anvil version cache file: [#!variable!file!#] for: [#!variable!target!#] needs to be created/updated.</key>
<key name="log_0438"><![CDATA[[ Error ] - No job was found for the 'job_uuid': [#!variable!job_uuid!#].]]></key>
<key name="log_0439">No databases available yet, continuing to wait.</key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key>
@ -994,6 +995,8 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec
<key name="job_0043">Verifying installation.</key>
<key name="job_0044">[ Failed ] - There may be more information in #!data!path::configs::anvil.conf!#.</key>
<key name="job_0045">Success!</key>
<key name="job_0046">Adding our database connection information to the target's anvil.conf file!</key>
<key name="job_0047">Finished! The target should be ready for initial configuration shortly. If it isn't, please check that the 'anvil-daemon' daemon is running.</key>
<!-- Warnings -->
<key name="striker_warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key>
@ -1099,6 +1102,8 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp
<key name="error_0072">Something went wrong trying to compile the C-program: [#!variable!file!#], unable to proceed.</key>
<key name="error_0073">The job UUID was not passed via '--job-uuid' and no unclaimed job was found in the database.</key>
<key name="error_0074">The initialization target: [#!variable!target!#] is not accessible. Will keep trying...</key>
<key name="error_0075">There are no databases available. Will check periodically, waiting until one becomes available.</key>
<key name="error_0076">There was a problem adding out database to the target's anvil.conf file.</key>
<!-- These are units, words and so on used when displaying information. -->
<key name="unit_0001">Yes</key>

@ -241,7 +241,7 @@ sub reconfigure_network
}
# Get the current list of IPs and MAC addresses.
$anvil->System->get_ips();
$anvil->Network->get_ips();
# Now configure the network.
my $dns = defined $anvil->data->{variables}{form}{config_step2}{dns}{value} ? [split/,/, $anvil->data->{variables}{form}{config_step2}{dns}{value}] : [];

@ -77,20 +77,41 @@ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure =
# If I have no databases, sleep for a second and then exit (systemd will restart us).
if (not $anvil->data->{sys}{database}{connections})
{
# Try to configure the local database, and then try to connect again.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0201"});
prep_database($anvil);
sleep 1;
# Try connecting again
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
# If this is a dashboard, try to configure and then connect to the local database. If this isn't a
# dashboard, then just go into a loop waiting for a database to be configured.
if ($anvil->System->get_host_type eq "dashboard")
{
# Still nothing, sleep and exit.
print $anvil->Words->string({key => "error_0003"})."\n";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, key => "error_0003"});
$anvil->nice_exit({exit_code => 2});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0201"});
prep_database($anvil);
sleep 1;
# Try connecting again
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# Still nothing, sleep and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, secure => 0, key => "error_0003"});
$anvil->nice_exit({exit_code => 2});
}
}
else
{
# Wait until we have one.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, secure => 0, key => "error_0075"});
until($anvil->data->{sys}{database}{connections})
{
sleep 10;
$anvil->refresh();
$anvil->Database->connect({debug => 3, check_if_configured => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, secure => 0, key => "log_0439"});
}
}
}
}
@ -147,11 +168,7 @@ my $check_if_database_is_configured = 0;
while(1)
{
# Reload defaults, re-read the config and then connect to the database(s)
$anvil->_set_paths();
$anvil->_set_defaults(); # This reset the log level
$anvil->Storage->read_config(); # This reset the log level also
$anvil->Get->switches; # Re-read to let switches override again.
$anvil->Words->read();
$anvil->refresh();
$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"});
@ -1014,12 +1031,21 @@ sub prep_database
{
my ($anvil) = @_;
my $shell_call = $anvil->data->{path}{exe}{'striker-prep-database'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($database_output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
if ($database_output)
# Only run this if we're a dashboard.
my $host_type = $anvil->System->get_host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type eq "dashboard")
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { database_output => $database_output }});
my ($database_output, $return_code) = $anvil->System->call({
debug => 2,
shell_call => $anvil->data->{path}{exe}{'striker-prep-database'},
source => $THIS_FILE,
line => __LINE__,
});
if ($database_output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { database_output => $database_output }});
}
}
return(0);

@ -151,7 +151,7 @@ $anvil->nice_exit({exit_code => 0});
# is server definition files. For those, we write the file out from the server's 'definition' table entry.
#
# When a missing entry is found, and an entry doesn't exist, the file will be found (if possible) and copied
# to this houst. Only machines on the same subnet are searched. The search pattern is;
# to this host. Only machines on the same subnet are searched. The search pattern is;
#
# Nodes; 1. Check for the file on the peer.
# 2. Check for the file on Strikers, in alphabetical order.
@ -243,14 +243,14 @@ sub find_file
my $found = 0;
# What are my IPs?
$anvil->System->get_ips();
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
$anvil->Network->get_ips();
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
next if not $anvil->data->{sys}{network}{interface}{$interface}{ip};
next if not $anvil->data->{sys}{network}{interface}{$interface}{subnet};
my $ip = $anvil->data->{sys}{network}{interface}{$interface}{ip};
my $subnet = $anvil->data->{sys}{network}{interface}{$interface}{subnet};
my $network = $anvil->Get->network({ip => $ip, subnet => $subnet});
next if not $anvil->data->{network}{'local'}{interface}{$interface}{ip};
next if not $anvil->data->{network}{'local'}{interface}{$interface}{subnet};
my $ip = $anvil->data->{network}{'local'}{interface}{$interface}{ip};
my $subnet = $anvil->data->{network}{'local'}{interface}{$interface}{subnet};
my $network = $anvil->Network->get_network({ip => $ip, subnet => $subnet});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
's1:interface' => $interface,
's2:ip' => $ip,
@ -360,7 +360,7 @@ AND
{
my $ip_address_address = $row->[0];
my $ip_address_subnet_mask = $row->[1];
my $network = $anvil->Get->network({ip => $ip_address_address, subnet => $ip_address_subnet_mask});
my $network = $anvil->Network->get_network({ip => $ip_address_address, subnet => $ip_address_subnet_mask});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
ip_address_address => $ip_address_address,
ip_address_subnet_mask => $ip_address_subnet_mask,

@ -98,14 +98,14 @@ sub check_initial_setup
$anvil->data->{firewall}{reload} = 0;
# Get a list of networks.
$anvil->System->get_ips({debug => 3});
$anvil->Network->get_ips({debug => 3});
# Get the list of existing zones from iptables/firewalld.
$anvil->System->check_firewall({debug => 3});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "firewall::default_zone" => $anvil->data->{firewall}{default_zone} }});
my $internet_zone = "";
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface }});
if ($interface =~ /^((bcn|ifn|sn)\d+)_/)
@ -114,24 +114,24 @@ sub check_initial_setup
# always be overridden by the ZONE="" variable in each interface's config.
my $zone = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { zone => $zone }});
if ((exists $anvil->data->{sys}{network}{interface}{$interface}{variable}{ZONE}) && ($anvil->data->{sys}{network}{interface}{$interface}{variable}{ZONE}))
if ((exists $anvil->data->{network}{'local'}{interface}{$interface}{variable}{ZONE}) && ($anvil->data->{network}{'local'}{interface}{$interface}{variable}{ZONE}))
{
$zone = $anvil->data->{sys}{network}{interface}{$interface}{variable}{ZONE};
$zone = $anvil->data->{network}{'local'}{interface}{$interface}{variable}{ZONE};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { zone => $zone }});
}
push @{$needed_zones}, $zone;
$anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{ip} = $anvil->data->{sys}{network}{interface}{$interface}{ip};
$anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{subnet} = $anvil->data->{sys}{network}{interface}{$interface}{subnet};
$anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{ip} = $anvil->data->{network}{'local'}{interface}{$interface}{ip};
$anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{subnet} = $anvil->data->{network}{'local'}{interface}{$interface}{subnet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"firewall::zone::${zone}::interface::${interface}::ip" => $anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{ip},
"firewall::zone::${zone}::interface::${interface}::subnet" => $anvil->data->{firewall}{zone}{$zone}{interface}{$interface}{subnet},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"sys::network::interface::${interface}::default_gateway" => $anvil->data->{sys}{network}{interface}{$interface}{default_gateway},
"network::local::interface::${interface}::default_gateway" => $anvil->data->{network}{'local'}{interface}{$interface}{default_gateway},
}});
if ($anvil->data->{sys}{network}{interface}{$interface}{default_gateway})
if ($anvil->data->{network}{'local'}{interface}{$interface}{default_gateway})
{
$internet_zone = $zone;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { internet_zone => $internet_zone }});

@ -45,12 +45,12 @@ sub update_network
{
my ($anvil) = @_;
# Run 'ip addr' to see what IPs are in use. The results will be stored in:
$anvil->System->get_ips();
# Run 'ip addr' to see what IPs are in use.
$anvil->Network->get_ips();
# We'll read through '/sys/class/net' looking for network interfaces.
# * 'sys::network::interface::<iface_name>::ip' - If an IP address is set
# * 'sys::network::interface::<iface_name>::subnet' - If an IP is set
# * 'network::local::interface::<iface_name>::ip' - If an IP address is set
# * 'network::local::interface::<iface_name>::subnet' - If an IP is set
my $directory = "/sys/class/net";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { directory => $directory }});
@ -111,10 +111,10 @@ sub update_network
my $down_delay = "";
my $bond_master = "";
if (exists $anvil->data->{sys}{network}{interface}{$interface})
if (exists $anvil->data->{network}{'local'}{interface}{$interface})
{
$ip_address = $anvil->data->{sys}{network}{interface}{$interface}{ip} ? $anvil->data->{sys}{network}{interface}{$interface}{ip} : "";
$subnet_mask = $anvil->data->{sys}{network}{interface}{$interface}{subnet} ? $anvil->data->{sys}{network}{interface}{$interface}{subnet} : "";
$ip_address = $anvil->data->{network}{'local'}{interface}{$interface}{ip} ? $anvil->data->{network}{'local'}{interface}{$interface}{ip} : "";
$subnet_mask = $anvil->data->{network}{'local'}{interface}{$interface}{subnet} ? $anvil->data->{network}{'local'}{interface}{$interface}{subnet} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
ip_address => $ip_address,
subnet_mask => $subnet_mask,
@ -319,9 +319,9 @@ sub update_network
my $subnet_mask = $anvil->data->{network}{interfaces}{by_name}{$interface}{subnet_mask};
my $type = $anvil->data->{network}{interfaces}{by_name}{$interface}{type};
my $up_delay = $anvil->data->{network}{interfaces}{by_name}{$interface}{up_delay};
my $default_gateway = $anvil->data->{sys}{network}{interface}{$interface}{default_gateway};
my $gateway = $anvil->data->{sys}{network}{interface}{$interface}{gateway};
my $dns = $anvil->data->{sys}{network}{interface}{$interface}{dns};
my $default_gateway = $anvil->data->{network}{'local'}{interface}{$interface}{default_gateway};
my $gateway = $anvil->data->{network}{'local'}{interface}{$interface}{gateway};
my $dns = $anvil->data->{network}{'local'}{interface}{$interface}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
active_slave => $active_slave,
bond_mode => $bond_mode,
@ -700,14 +700,14 @@ WHERE
# Did we see this IP on this scan? If not, set on_type to DELETEd.
my $found = 0;
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
interface => $interface,
ip_address_address => $ip_address_address,
"sys::network::interface::${interface}::ip" => $anvil->data->{sys}{network}{interface}{$interface}{ip},
interface => $interface,
ip_address_address => $ip_address_address,
"network::local::interface::${interface}::ip" => $anvil->data->{network}{'local'}{interface}{$interface}{ip},
}});
if ((defined $anvil->data->{sys}{network}{interface}{$interface}{ip}) && ($anvil->data->{sys}{network}{interface}{$interface}{ip} eq $ip_address_address))
if ((defined $anvil->data->{network}{'local'}{interface}{$interface}{ip}) && ($anvil->data->{network}{'local'}{interface}{$interface}{ip} eq $ip_address_address))
{
$found = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }});

@ -10,6 +10,7 @@
# 3 = Job detauls not found in the database.
# 4 = Unable to connect to the target.
# 5 = Failed to install the anvil package.
# 6 = Failed to add our database to the target's anvil.conf file.
#
use strict;
@ -66,6 +67,79 @@ sub add_databases
{
my ($anvil) = @_;
# Normally, we'd use the BCN IPs to tell the peer how to reach our database, but it's entirely
# possible at this stage that the target doesn't have a BCN IP. So we need to figure out what IP it
# has and we have that are on the same subnet.
# Scan our network and the target's network, then compare them.
update_progress($anvil, 95, "job_0046");
my $target = $anvil->data->{data}{host_ip_address};
$anvil->Network->get_ips();
$anvil->Network->get_ips({
target => $target,
remote_user => "root",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
});
my ($match) = $anvil->Network->find_matches({
debug => 3,
first => 'local',
second => $target,
});
# We'll sort in reverse order, so if there is a BCN address, we'll use it.
my $host_uuid = $anvil->data->{sys}{host_uuid};
my $db_host = "";
my $db_port = "";
my $db_password = "";
foreach my $interface (sort {$a cmp $b} keys %{$match->{'local'}})
{
my $local_ip = $anvil->data->{network}{'local'}{interface}{$interface}{ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
local_ip => $local_ip,
}});
if (($local_ip) && ($anvil->Validate->is_ipv4({ip => $local_ip})))
{
$db_host = $local_ip;
$db_port = $anvil->data->{database}{$host_uuid}{port};
$db_password = $anvil->data->{database}{$host_uuid}{password};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
db_host => $db_host,
db_port => $db_port,
db_password => $anvil->Log->is_secure($db_password),
}});
}
last if $db_host;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { db_host => $db_host }});
if ($db_host)
{
my $failed = $anvil->Database->manage_anvil_conf({
debug => 2,
target => $target,
remote_user => "root",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
db_host_uuid => $anvil->data->{sys}{host_uuid},
db_host => $db_host,
db_port => $db_port,
db_password => $db_password,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { failed => $failed }});
if ($failed)
{
# Something went wrong
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0076"});
update_progress($anvil, 100, "error_0076");
$anvil->nice_exit({exit_code => 6});
}
else
{
# Success! We're done@
update_progress($anvil, 100, "job_0047");
}
}
return(0);
}
@ -93,12 +167,12 @@ EOF
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $shell_call,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
debug => 3,
shell_call => $shell_call,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error => $error,
@ -120,12 +194,12 @@ EOF
# We'll attach subscriptions if this is set
my $subscribe = 1;
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." identity",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." identity",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
@ -146,13 +220,13 @@ EOF
my $bash_password = $anvil->data->{data}{rh_password};
$bash_password =~ s/'/\\\'/g;
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." register --username ".$anvil->data->{data}{rh_user}." --password '".$bash_password."' --auto-attach --force",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." register --username ".$anvil->data->{data}{rh_user}." --password '".$bash_password."' --auto-attach --force",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -202,13 +276,13 @@ EOF
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0036", variables => { repo => 'codeready-builder-for-rhel-8-x86_64-rpms' }});
update_progress($anvil, 10, "job_0036,!!repo!codeready-builder-for-rhel-8-x86_64-rpms!!");
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable codeready-builder-for-rhel-8-x86_64-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable codeready-builder-for-rhel-8-x86_64-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -221,15 +295,15 @@ EOF
if ($anvil->data->{data}{type} eq "node")
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0036", variables => { repo => 'rhel-8-for-x86_64-highavailability-rpms' }});
update_progress($anvil, 11, "job_0036,!!repo!rhel-8-for-x86_64-highavailability-rpms!!");
update_progress($anvil, 15, "job_0036,!!repo!rhel-8-for-x86_64-highavailability-rpms!!");
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable rhel-8-for-x86_64-highavailability-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable rhel-8-for-x86_64-highavailability-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -242,18 +316,18 @@ EOF
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0037"});
update_progress($anvil, 12, "job_0037");
update_progress($anvil, 20, "job_0037");
undef $output;
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --list-enabled",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --list-enabled",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -278,7 +352,7 @@ EOF
if (not $anvil->data->{repos}{$repo})
{
# Well this is a problem...
update_progress($anvil, 11, "job_0038,!!repo!".$repo."!!");
update_progress($anvil, 25, "job_0038,!!repo!".$repo."!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0038", variables => { repo => $repo }});
}
}
@ -286,18 +360,18 @@ EOF
}
# Call an OS update.
update_progress($anvil, 20, "job_0039");
update_progress($anvil, 25, "job_0040");
update_progress($anvil, 29, "job_0039");
update_progress($anvil, 30, "job_0040");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0039"});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0040"});
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y update",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y update",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -312,13 +386,13 @@ EOF
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y remove biosdevname",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y remove biosdevname",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -335,13 +409,13 @@ EOF
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y install ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y install ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
@ -355,13 +429,13 @@ EOF
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." list installed ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." list installed ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
remote_user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,

@ -433,15 +433,15 @@ sub setup_boot_environment
### We;re going to need the '.treeinfo' as well in anvil-striker-extra
### - https://docs.fedoraproject.org/en-US/fedora/f28/install-guide/advanced/Network_based_Installations/
# Get my BCN IP and active OS.
$anvil->System->get_ips();
$anvil->Network->get_ips();
my $bcn_interface = "";
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface }});
next if $interface !~ /^bcn/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::network::${interface}::ip" => $anvil->data->{sys}{network}{interface}{$interface}{ip} }});
if ($anvil->Validate->is_ipv4({ip => $anvil->data->{sys}{network}{interface}{$interface}{ip} }))
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "network::local::${interface}::ip" => $anvil->data->{network}{'local'}{interface}{$interface}{ip} }});
if ($anvil->Validate->is_ipv4({ip => $anvil->data->{network}{'local'}{interface}{$interface}{ip} }))
{
$bcn_interface = $interface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bcn_interface => $bcn_interface }});
@ -457,10 +457,10 @@ sub setup_boot_environment
$anvil->nice_exit({code => 2});
}
my $bcn_ip = $anvil->data->{sys}{network}{interface}{$bcn_interface}{ip};
my $bcn_subnet = $anvil->data->{sys}{network}{interface}{$bcn_interface}{subnet};
my $bcn_network = $anvil->Get->network({ip => $bcn_ip, subnet => $bcn_subnet});
my $dns = $anvil->data->{sys}{network}{interface}{$bcn_interface}{dns} ? $anvil->data->{sys}{network}{interface}{$bcn_interface}{dns} : $anvil->data->{defaults}{network}{dns};
my $bcn_ip = $anvil->data->{network}{'local'}{interface}{$bcn_interface}{ip};
my $bcn_subnet = $anvil->data->{network}{'local'}{interface}{$bcn_interface}{subnet};
my $bcn_network = $anvil->Network->get_network({ip => $bcn_ip, subnet => $bcn_subnet});
my $dns = $anvil->data->{network}{'local'}{interface}{$bcn_interface}{dns} ? $anvil->data->{network}{'local'}{interface}{$bcn_interface}{dns} : $anvil->data->{defaults}{network}{dns};
my $domain = "localdomain";
my $base_url = "http://".$bcn_ip."/".$anvil->data->{host_os}{os_type}."/".$anvil->data->{host_os}{os_arch};
if ($anvil->_hostname =~ /\./)

Loading…
Cancel
Save