Merge pull request #570 from ClusterLabs/log-collection

Log collection
main
digimer-bot 11 months ago committed by GitHub
commit 492983d7ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      Anvil/Tools.pm
  2. 14
      Anvil/Tools/Cluster.pm
  3. 383
      Anvil/Tools/Database.pm
  4. 2
      Anvil/Tools/Email.pm
  5. 24
      Anvil/Tools/Get.pm
  6. 105
      Anvil/Tools/Job.pm
  7. 4
      Anvil/Tools/Log.pm
  8. 1155
      Anvil/Tools/Network.pm
  9. 14
      Anvil/Tools/Storage.pm
  10. 2
      Anvil/Tools/Striker.pm
  11. 77
      Anvil/Tools/System.pm
  12. 6
      anvil.spec.in
  13. 9
      man/anvil-manage-host.8
  14. 451
      scancore-agents/scan-network/scan-network
  15. 2
      scancore-agents/scan-network/scan-network.xml
  16. 1
      scancore-agents/scan-server/scan-server
  17. 115
      share/anvil.sql
  18. 71
      share/words.xml
  19. 1
      tools/Makefile.am
  20. 6
      tools/anvil-check-memory
  21. 2890
      tools/anvil-configure-host
  22. 253
      tools/anvil-daemon
  23. 8
      tools/anvil-download-file
  24. 490
      tools/anvil-join-anvil
  25. 4
      tools/anvil-manage-dr
  26. 119
      tools/anvil-manage-host
  27. 505
      tools/anvil-monitor-network
  28. 4
      tools/anvil-parse-fence-agents
  29. 12
      tools/anvil-provision-server
  30. 9
      tools/anvil-safe-start
  31. 2
      tools/anvil-sync-shared
  32. 1161
      tools/anvil-update-states
  33. 301
      tools/anvil-version-changes
  34. 2
      tools/anvil-watch-servers
  35. 16
      tools/fence_pacemaker
  36. 6
      tools/scancore
  37. 1
      tools/striker-auto-initialize-all
  38. 20
      tools/striker-collect-debug
  39. 5
      tools/striker-initialize-host
  40. 2
      tools/striker-manage-install-target
  41. 6
      tools/striker-prep-database
  42. 16
      tools/unfence_pacemaker
  43. 1
      units/Makefile.am
  44. 12
      units/anvil-monitor-network.service

@ -1069,6 +1069,7 @@ sub _set_paths
'journald.conf' => "/etc/systemd/journald.conf", 'journald.conf' => "/etc/systemd/journald.conf",
'logind.conf' => "/etc/systemd/logind.conf", 'logind.conf' => "/etc/systemd/logind.conf",
'lvm.conf' => "/etc/lvm/lvm.conf", 'lvm.conf' => "/etc/lvm/lvm.conf",
'persistent-net' => "/etc/udev/rules.d/70-persistent-net.rules",
'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf", 'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf",
'postgresql.conf' => "/var/lib/pgsql/data/postgresql.conf", 'postgresql.conf' => "/var/lib/pgsql/data/postgresql.conf",
pxe_default => "/var/lib/tftpboot/pxelinux.cfg/default", pxe_default => "/var/lib/tftpboot/pxelinux.cfg/default",
@ -1078,6 +1079,7 @@ sub _set_paths
postfix_relay_password => "/etc/postfix/relay_password", postfix_relay_password => "/etc/postfix/relay_password",
'qemu.conf' => "/etc/libvirt/qemu.conf", 'qemu.conf' => "/etc/libvirt/qemu.conf",
ssh_config => "/etc/ssh/ssh_config", ssh_config => "/etc/ssh/ssh_config",
sshd_root_password => "/etc/ssh/sshd_config.d/01-permitrootlogin.conf",
'type.striker' => "/etc/anvil/type.striker", 'type.striker' => "/etc/anvil/type.striker",
'type.dr' => "/etc/anvil/type.dr", 'type.dr' => "/etc/anvil/type.dr",
'type.node' => "/etc/anvil/type.node", 'type.node' => "/etc/anvil/type.node",
@ -1129,6 +1131,7 @@ sub _set_paths
provision => "/mnt/shared/provision", provision => "/mnt/shared/provision",
temp => "/mnt/shared/temp", temp => "/mnt/shared/temp",
}, },
'sshd_config.d' => "/etc/ssh/sshd_config.d",
skins => "/var/www/html/skins", skins => "/var/www/html/skins",
status => "/var/www/html/status", status => "/var/www/html/status",
syslinux => "/usr/share/syslinux", syslinux => "/usr/share/syslinux",
@ -1169,7 +1172,6 @@ sub _set_paths
'anvil-special-operations' => "/usr/sbin/anvil-special-operations", 'anvil-special-operations' => "/usr/sbin/anvil-special-operations",
'anvil-sync-shared' => "/usr/sbin/anvil-sync-shared", 'anvil-sync-shared' => "/usr/sbin/anvil-sync-shared",
'anvil-update-files' => "/usr/sbin/anvil-update-files", 'anvil-update-files' => "/usr/sbin/anvil-update-files",
'anvil-update-states' => "/usr/sbin/anvil-update-states",
'anvil-update-system' => "/usr/sbin/anvil-update-system", 'anvil-update-system' => "/usr/sbin/anvil-update-system",
'anvil-version-changes' => "/usr/sbin/anvil-version-changes", 'anvil-version-changes' => "/usr/sbin/anvil-version-changes",
augtool => "/usr/bin/augtool", augtool => "/usr/bin/augtool",
@ -1195,6 +1197,7 @@ sub _set_paths
df => "/usr/bin/df", df => "/usr/bin/df",
dmidecode => "/usr/sbin/dmidecode", dmidecode => "/usr/sbin/dmidecode",
dnf => "/usr/bin/dnf", dnf => "/usr/bin/dnf",
dracut => "/usr/bin/dracut",
drbdadm => "/usr/sbin/drbdadm", drbdadm => "/usr/sbin/drbdadm",
drbdsetup => "/usr/sbin/drbdsetup", drbdsetup => "/usr/sbin/drbdsetup",
dropdb => "/usr/bin/dropdb", dropdb => "/usr/bin/dropdb",
@ -1210,6 +1213,7 @@ sub _set_paths
'grep' => "/usr/bin/grep", 'grep' => "/usr/bin/grep",
groupadd => "/usr/sbin/groupadd", groupadd => "/usr/sbin/groupadd",
head => "/usr/bin/head", head => "/usr/bin/head",
hostname => "/usr/bin/hostname",
hostnamectl => "/usr/bin/hostnamectl", hostnamectl => "/usr/bin/hostnamectl",
hpacucli => "/usr/sbin/hpacucli", hpacucli => "/usr/sbin/hpacucli",
htpasswd => "/usr/bin/htpasswd", htpasswd => "/usr/bin/htpasswd",

@ -105,6 +105,10 @@ This takes a server name, finds where it is running and then adds it to pacemake
Parameters; Parameters;
=head3 ok_if_exists (optional, default '0')
Normally, if the server is already in the cluster, C<< !!error!! >> is returned. If this is set to C<< 1 >> and the server is already in pacemaker, we'll return C<< 0 >> instead.
=head3 server_name (required) =head3 server_name (required)
This is the name of the server being added. This is the name of the server being added.
@ -118,9 +122,11 @@ sub add_server
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 2; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Cluster->add_server()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Cluster->add_server()" }});
my $server_name = defined $parameter->{server_name} ? $parameter->{server_name} : ""; my $ok_if_exists = defined $parameter->{ok_if_exists} ? $parameter->{ok_if_exists} : "";
my $server_name = defined $parameter->{server_name} ? $parameter->{server_name} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
server_name => $server_name, ok_if_exists => $ok_if_exists,
server_name => $server_name,
}}); }});
if (not $server_name) if (not $server_name)
@ -146,6 +152,10 @@ sub add_server
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::cib::resources::primitive::${server_name}::type" => $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$server_name}{type}, "cib::parsed::cib::resources::primitive::${server_name}::type" => $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$server_name}{type},
}}); }});
if ($ok_if_exists)
{
return(0);
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0213", variables => { server_name => $server_name }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0213", variables => { server_name => $server_name }});
return("!!error!!"); return("!!error!!");
} }

@ -786,7 +786,11 @@ If the system is already configured, this method will do nothing, so it is safe
If the method completes, C<< 0 >> is returned. If this method is called without C<< root >> access, it returns C<< 1 >> without doing anything. If there is a problem, C<< !!error!! >> is returned. If the method completes, C<< 0 >> is returned. If this method is called without C<< root >> access, it returns C<< 1 >> without doing anything. If there is a problem, C<< !!error!! >> is returned.
This method takes no parameters. Parameters;
=head3 check_db_exists (optional, default 0)
If set, the database will be checked to see if the schema exists. This is normally not needed, but can be triggered if the database was DROP'ed by a user.
=cut =cut
### TODO: Much of this logic is in striker-prep-database, consolidate! ### TODO: Much of this logic is in striker-prep-database, consolidate!
@ -797,6 +801,11 @@ sub configure_pgsql
my $anvil = $self->parent; my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->configure_pgsql()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->configure_pgsql()" }});
my $check_db_exists = defined $parameter->{check_db_exists} ? $parameter->{check_db_exists} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
check_db_exists => $check_db_exists,
}});
# The local host_uuid is the ID of the local database, so get that. # The local host_uuid is the ID of the local database, so get that.
my $uuid = $anvil->Get->host_uuid(); my $uuid = $anvil->Get->host_uuid();
@ -971,7 +980,7 @@ sub configure_pgsql
{ {
# Did we initialize? # Did we initialize?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { initialized => $initialized }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { initialized => $initialized }});
if ($initialized) if (($initialized) or (not $running))
{ {
# Start the daemon. # Start the daemon.
my $return_code = $anvil->System->start_daemon({daemon => $anvil->data->{sys}{daemon}{postgresql}}); my $return_code = $anvil->System->start_daemon({daemon => $anvil->data->{sys}{daemon}{postgresql}});
@ -1012,7 +1021,7 @@ sub configure_pgsql
's2:update_postgresql_file' => $update_postgresql_file, 's2:update_postgresql_file' => $update_postgresql_file,
's3:update_pg_hba_file' => $update_pg_hba_file, 's3:update_pg_hba_file' => $update_pg_hba_file,
}}); }});
if (($initialized) or ($update_postgresql_file) or ($update_pg_hba_file)) if (($initialized) or ($update_postgresql_file) or ($update_pg_hba_file) or ($check_db_exists))
{ {
# Create the .pgpass file, if needed. # Create the .pgpass file, if needed.
my $created_pgpass = 0; my $created_pgpass = 0;
@ -1366,7 +1375,11 @@ sub connect
# This method just returns if nothing is needed. # This method just returns if nothing is needed.
if (($local_host_type eq "striker") && ($check_if_configured) && ($< == 0) && ($> == 0)) if (($local_host_type eq "striker") && ($check_if_configured) && ($< == 0) && ($> == 0))
{ {
$anvil->Database->configure_pgsql({debug => 2, uuid => $local_host_uuid}); $anvil->Database->configure_pgsql({
debug => 2,
uuid => $local_host_uuid,
check_db_exists => $check_if_configured,
});
} }
# Now setup or however-many connections # Now setup or however-many connections
@ -1675,7 +1688,6 @@ sub connect
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $count = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; my $count = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }});
if ($count < 1) if ($count < 1)
{ {
@ -1765,6 +1777,9 @@ sub connect
# Record this as successful # Record this as successful
$anvil->data->{sys}{database}{connections}++; $anvil->data->{sys}{database}{connections}++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
push @{$successful_connections}, $uuid; push @{$successful_connections}, $uuid;
} }
@ -1825,6 +1840,9 @@ sub connect
$anvil->data->{sys}{database}{primary_db} = "" if $anvil->data->{sys}{database}{read_active} eq $uuid; $anvil->data->{sys}{database}{primary_db} = "" if $anvil->data->{sys}{database}{read_active} eq $uuid;
$anvil->data->{sys}{database}{read_uuid} = "" if $anvil->data->{sys}{database}{read_uuid} eq $uuid; $anvil->data->{sys}{database}{read_uuid} = "" if $anvil->data->{sys}{database}{read_uuid} eq $uuid;
$anvil->data->{sys}{database}{connections}--; $anvil->data->{sys}{database}{connections}--;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
delete $anvil->data->{database}{$uuid}; delete $anvil->data->{database}{$uuid};
next; next;
} }
@ -3971,7 +3989,7 @@ AND
}}); }});
$anvil->data->{host_from_uuid}{$host_uuid}{full} = $host_name; $anvil->data->{host_from_uuid}{$host_uuid}{full} = $host_name;
$anvil->data->{host_from_uuid}{$host_uuid}{short} = $short_host_name; $anvil->data->{host_from_uuid}{$host_uuid}{short} = $short_host_name ? $short_host_name : $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"host_from_uuid::${host_uuid}::full" => $anvil->data->{host_from_uuid}{$host_uuid}{full}, "host_from_uuid::${host_uuid}::full" => $anvil->data->{host_from_uuid}{$host_uuid}{full},
"host_from_uuid::${host_uuid}::short" => $anvil->data->{host_from_uuid}{$host_uuid}{short}, "host_from_uuid::${host_uuid}::short" => $anvil->data->{host_from_uuid}{$host_uuid}{short},
@ -4470,7 +4488,8 @@ AND
$query = " $query = "
SELECT SELECT
network_interface_uuid, network_interface_uuid,
network_interface_name network_interface_name,
network_interface_device
FROM FROM
network_interfaces network_interfaces
WHERE WHERE
@ -4488,14 +4507,18 @@ AND
}}); }});
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
my $network_interface_uuid = $row->[0]; my $network_interface_uuid = $row->[0];
my $network_interface_name = $row->[1]; my $network_interface_name = $row->[1];
my $network_interface_device = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
network_interface_uuid => $network_interface_uuid, network_interface_uuid => $network_interface_uuid,
network_interface_name => $network_interface_name, network_interface_name => $network_interface_name,
network_interface_device => $network_interface_device,
}}); }});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name; # The interface_device is the name used by 'ip addr list', and the name is the 'enX'
# biosdevname device. So we only use the name now if there is no device.
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_device ? $network_interface_device : $network_interface_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name}, "hosts::host_uuid::${host_uuid}::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name},
}}); }});
@ -4561,51 +4584,37 @@ AND
$on_interface = $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$ip_address_on_uuid}{network_interface_name}; $on_interface = $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$ip_address_on_uuid}{network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_interface => $on_interface }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_interface => $on_interface }});
} }
my $on_network = ($on_interface =~ /^(.*?)_/)[0];
if (not defined $on_network)
{
# This isn't a network we should know about (ie: it might be a stray 'virbrX'
# birdge), delete this IP.
my $query = "
UPDATE
ip_addresses
SET
ip_address_note = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
next;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_network => $on_network }});
# Store it. # We want to be able to map IPs to hosts.
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address} = $ip_address_address; $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid} = $ip_address_host_uuid;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask} = $ip_address_subnet_mask; $anvil->data->{ip_addresses}{$ip_address_address}{ip_address_uuid} = $ip_address_uuid;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface} = $on_interface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::network::${on_network}::ip_address" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address}, "ip_addresses::${ip_address_address}::host_uuid" => $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid},
"hosts::host_uuid::${host_uuid}::network::${on_network}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask}, "ip_addresses::${ip_address_address}::ip_address_uuid" => $anvil->data->{ip_addresses}{$ip_address_address}{ip_address_uuid},
"hosts::host_uuid::${host_uuid}::network::${on_network}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface},
}}); }});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask} = $ip_address_subnet_mask; $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask} = $ip_address_subnet_mask;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface} = $on_interface; $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface} = $on_interface;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network} = $on_network;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask}, "hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask},
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface}, "hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface},
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_network" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network},
}}); }});
# We also want to be able to map IPs to hosts. # If this is an interface that doesn't belong to us, we're done.
$anvil->data->{ip_addresses}{$ip_address_address}{host_uuid} = $ip_address_host_uuid; my $on_network = ($on_interface =~ /^(.*?)_/)[0];
$anvil->data->{ip_addresses}{$ip_address_address}{ip_address_uuid} = $ip_address_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_network => $on_network }});
next if not $on_network;
# Store it by network.
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address} = $ip_address_address;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask} = $ip_address_subnet_mask;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface} = $on_interface;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network} = $on_network;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"ip_addresses::${ip_address_address}::host_uuid" => $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid}, "hosts::host_uuid::${host_uuid}::network::${on_network}::ip_address" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address},
"ip_addresses::${ip_address_address}::ip_address_uuid" => $anvil->data->{ip_addresses}{$ip_address_address}{ip_address_uuid}, "hosts::host_uuid::${host_uuid}::network::${on_network}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask},
"hosts::host_uuid::${host_uuid}::network::${on_network}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface},
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_network" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network},
}}); }});
} }
@ -6948,6 +6957,7 @@ sub initialize
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { sql => $sql }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { sql => $sql }});
# In the off chance that the database user isn't 'admin', update the SQL file. # In the off chance that the database user isn't 'admin', update the SQL file.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { user => $user }});
if ($user ne "admin") if ($user ne "admin")
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0253", variables => { database_user => $user }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0253", variables => { database_user => $user }});
@ -6968,11 +6978,12 @@ sub initialize
# Now that I am ready, disable autocommit, write and commit. # Now that I am ready, disable autocommit, write and commit.
$anvil->Database->write({ $anvil->Database->write({
debug => $debug, debug => $debug,
uuid => $uuid, uuid => $uuid,
query => $sql, query => $sql,
source => $THIS_FILE, initializing => 1,
line => __LINE__, source => $THIS_FILE,
line => __LINE__,
}); });
$anvil->data->{sys}{db_initialized}{$uuid} = 1; $anvil->data->{sys}{db_initialized}{$uuid} = 1;
@ -7522,7 +7533,6 @@ WHERE
return($anvil_uuid); return($anvil_uuid);
} }
=head2 insert_or_update_bridges =head2 insert_or_update_bridges
This updates (or inserts) a record in the 'bridges' table. The C<< bridge_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'bridges' table. The C<< bridge_uuid >> referencing the database row will be returned.
@ -7555,6 +7565,10 @@ This is the host that the IP address is on. If not passed, the local C<< sys::ho
This is the bridge's device name. This is the bridge's device name.
=head3 bridge_nm_uuid (optional)
This is the network manager UUID for the bridge.
=head3 bridge_id (optional) =head3 bridge_id (optional)
This is the unique identifier for the bridge. This is the unique identifier for the bridge.
@ -7591,6 +7605,7 @@ sub insert_or_update_bridges
my $bridge_uuid = defined $parameter->{bridge_uuid} ? $parameter->{bridge_uuid} : ""; my $bridge_uuid = defined $parameter->{bridge_uuid} ? $parameter->{bridge_uuid} : "";
my $bridge_host_uuid = defined $parameter->{bridge_host_uuid} ? $parameter->{bridge_host_uuid} : $anvil->data->{sys}{host_uuid}; my $bridge_host_uuid = defined $parameter->{bridge_host_uuid} ? $parameter->{bridge_host_uuid} : $anvil->data->{sys}{host_uuid};
my $bridge_name = defined $parameter->{bridge_name} ? $parameter->{bridge_name} : ""; my $bridge_name = defined $parameter->{bridge_name} ? $parameter->{bridge_name} : "";
my $bridge_nm_uuid = $parameter->{bridge_nm_uuid} ? $parameter->{bridge_nm_uuid} : 'NULL';
my $bridge_id = defined $parameter->{bridge_id} ? $parameter->{bridge_id} : ""; my $bridge_id = defined $parameter->{bridge_id} ? $parameter->{bridge_id} : "";
my $bridge_mac_address = defined $parameter->{bridge_mac_address} ? $parameter->{bridge_mac_address} : ""; my $bridge_mac_address = defined $parameter->{bridge_mac_address} ? $parameter->{bridge_mac_address} : "";
my $bridge_mtu = defined $parameter->{bridge_mtu} ? $parameter->{bridge_mtu} : ""; my $bridge_mtu = defined $parameter->{bridge_mtu} ? $parameter->{bridge_mtu} : "";
@ -7603,6 +7618,7 @@ sub insert_or_update_bridges
bridge_uuid => $bridge_uuid, bridge_uuid => $bridge_uuid,
bridge_host_uuid => $bridge_host_uuid, bridge_host_uuid => $bridge_host_uuid,
bridge_name => $bridge_name, bridge_name => $bridge_name,
bridge_nm_uuid => $bridge_nm_uuid,
bridge_id => $bridge_id, bridge_id => $bridge_id,
bridge_mac_address => $bridge_mac_address, bridge_mac_address => $bridge_mac_address,
bridge_mtu => $bridge_mtu, bridge_mtu => $bridge_mtu,
@ -7735,6 +7751,7 @@ INSERT INTO
( (
bridge_uuid, bridge_uuid,
bridge_host_uuid, bridge_host_uuid,
bridge_nm_uuid,
bridge_name, bridge_name,
bridge_id, bridge_id,
bridge_mac_address, bridge_mac_address,
@ -7744,6 +7761,7 @@ INSERT INTO
) VALUES ( ) VALUES (
".$anvil->Database->quote($bridge_uuid).", ".$anvil->Database->quote($bridge_uuid).",
".$anvil->Database->quote($bridge_host_uuid).", ".$anvil->Database->quote($bridge_host_uuid).",
".$anvil->Database->quote($bridge_nm_uuid).",
".$anvil->Database->quote($bridge_name).", ".$anvil->Database->quote($bridge_name).",
".$anvil->Database->quote($bridge_id).", ".$anvil->Database->quote($bridge_id).",
".$anvil->Database->quote($bridge_mac_address).", ".$anvil->Database->quote($bridge_mac_address).",
@ -7752,6 +7770,7 @@ INSERT INTO
".$anvil->Database->quote($anvil->Database->refresh_timestamp)." ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
); );
"; ";
$query =~ s/'NULL'/NULL/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
} }
@ -7761,6 +7780,7 @@ INSERT INTO
my $query = " my $query = "
SELECT SELECT
bridge_host_uuid, bridge_host_uuid,
bridge_nm_uuid,
bridge_name, bridge_name,
bridge_id, bridge_id,
bridge_mac_address, bridge_mac_address,
@ -7787,14 +7807,16 @@ WHERE
} }
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
my $old_bridge_host_uuid = $row->[0]; my $old_bridge_host_uuid = $row->[0];
my $old_bridge_name = $row->[1]; my $old_bridge_nm_uuid = defined $row->[1] ? $row->[1] : 'NULL';
my $old_bridge_id = $row->[2]; my $old_bridge_name = $row->[2];
my $old_bridge_mac_address = $row->[3]; my $old_bridge_id = $row->[3];
my $old_bridge_mtu = $row->[4]; my $old_bridge_mac_address = $row->[4];
my $old_bridge_stp_enabled = $row->[5]; my $old_bridge_mtu = $row->[5];
my $old_bridge_stp_enabled = $row->[6];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_bridge_host_uuid => $old_bridge_host_uuid, old_bridge_host_uuid => $old_bridge_host_uuid,
old_bridge_nm_uuid => $old_bridge_nm_uuid,
old_bridge_name => $old_bridge_name, old_bridge_name => $old_bridge_name,
old_bridge_id => $old_bridge_id, old_bridge_id => $old_bridge_id,
old_bridge_mac_address => $old_bridge_mac_address, old_bridge_mac_address => $old_bridge_mac_address,
@ -7804,6 +7826,7 @@ WHERE
# Anything change? # Anything change?
if (($old_bridge_host_uuid ne $bridge_host_uuid) or if (($old_bridge_host_uuid ne $bridge_host_uuid) or
($old_bridge_nm_uuid ne $bridge_nm_uuid) or
($old_bridge_name ne $bridge_name) or ($old_bridge_name ne $bridge_name) or
($old_bridge_id ne $bridge_id) or ($old_bridge_id ne $bridge_id) or
($old_bridge_mac_address ne $bridge_mac_address) or ($old_bridge_mac_address ne $bridge_mac_address) or
@ -7816,6 +7839,7 @@ UPDATE
bridges bridges
SET SET
bridge_host_uuid = ".$anvil->Database->quote($bridge_host_uuid).", bridge_host_uuid = ".$anvil->Database->quote($bridge_host_uuid).",
bridge_nm_uuid = ".$anvil->Database->quote($bridge_nm_uuid).",
bridge_name = ".$anvil->Database->quote($bridge_name).", bridge_name = ".$anvil->Database->quote($bridge_name).",
bridge_id = ".$anvil->Database->quote($bridge_id).", bridge_id = ".$anvil->Database->quote($bridge_id).",
bridge_mac_address = ".$anvil->Database->quote($bridge_mac_address).", bridge_mac_address = ".$anvil->Database->quote($bridge_mac_address).",
@ -7825,6 +7849,7 @@ SET
WHERE WHERE
bridge_uuid = ".$anvil->Database->quote($bridge_uuid)." bridge_uuid = ".$anvil->Database->quote($bridge_uuid)."
"; ";
$query =~ s/'NULL'/NULL/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
} }
@ -7871,6 +7896,10 @@ This is the host that the IP address is on. If not passed, the local C<< sys::ho
This is the bond's device name. This is the bond's device name.
=head3 bond_nm_uuid (optional)
This is the network manager UUID for this bond.
=head3 bond_mode (required) =head3 bond_mode (required)
This is the bonding mode used for this bond. This is the bonding mode used for this bond.
@ -7931,6 +7960,7 @@ sub insert_or_update_bonds
my $bond_uuid = defined $parameter->{bond_uuid} ? $parameter->{bond_uuid} : ""; my $bond_uuid = defined $parameter->{bond_uuid} ? $parameter->{bond_uuid} : "";
my $bond_host_uuid = defined $parameter->{bond_host_uuid} ? $parameter->{bond_host_uuid} : $anvil->data->{sys}{host_uuid}; my $bond_host_uuid = defined $parameter->{bond_host_uuid} ? $parameter->{bond_host_uuid} : $anvil->data->{sys}{host_uuid};
my $bond_name = defined $parameter->{bond_name} ? $parameter->{bond_name} : ""; my $bond_name = defined $parameter->{bond_name} ? $parameter->{bond_name} : "";
my $bond_nm_uuid = $parameter->{bond_nm_uuid} ? $parameter->{bond_nm_uuid} : 'NULL';
my $bond_mode = defined $parameter->{bond_mode} ? $parameter->{bond_mode} : ""; my $bond_mode = defined $parameter->{bond_mode} ? $parameter->{bond_mode} : "";
my $bond_mtu = defined $parameter->{bond_mtu} ? $parameter->{bond_mtu} : ""; my $bond_mtu = defined $parameter->{bond_mtu} ? $parameter->{bond_mtu} : "";
my $bond_primary_interface = defined $parameter->{bond_primary_interface} ? $parameter->{bond_primary_interface} : ""; my $bond_primary_interface = defined $parameter->{bond_primary_interface} ? $parameter->{bond_primary_interface} : "";
@ -7941,7 +7971,7 @@ sub insert_or_update_bonds
my $bond_down_delay = defined $parameter->{bond_down_delay} ? $parameter->{bond_down_delay} : ""; my $bond_down_delay = defined $parameter->{bond_down_delay} ? $parameter->{bond_down_delay} : "";
my $bond_mac_address = defined $parameter->{bond_mac_address} ? $parameter->{bond_mac_address} : ""; my $bond_mac_address = defined $parameter->{bond_mac_address} ? $parameter->{bond_mac_address} : "";
my $bond_operational = defined $parameter->{bond_operational} ? $parameter->{bond_operational} : ""; my $bond_operational = defined $parameter->{bond_operational} ? $parameter->{bond_operational} : "";
my $bond_bridge_uuid = defined $parameter->{bond_bridge_uuid} ? $parameter->{bond_bridge_uuid} : 'NULL'; my $bond_bridge_uuid = $parameter->{bond_bridge_uuid} ? $parameter->{bond_bridge_uuid} : 'NULL';
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid, uuid => $uuid,
file => $file, file => $file,
@ -7950,6 +7980,7 @@ sub insert_or_update_bonds
bond_uuid => $bond_uuid, bond_uuid => $bond_uuid,
bond_host_uuid => $bond_host_uuid, bond_host_uuid => $bond_host_uuid,
bond_name => $bond_name, bond_name => $bond_name,
bond_nm_uuid => $bond_nm_uuid,
bond_mode => $bond_mode, bond_mode => $bond_mode,
bond_mtu => $bond_mtu, bond_mtu => $bond_mtu,
bond_primary_interface => $bond_primary_interface, bond_primary_interface => $bond_primary_interface,
@ -8101,6 +8132,7 @@ INSERT INTO
( (
bond_uuid, bond_uuid,
bond_host_uuid, bond_host_uuid,
bond_nm_uuid,
bond_name, bond_name,
bond_mode, bond_mode,
bond_mtu, bond_mtu,
@ -8117,6 +8149,7 @@ INSERT INTO
) VALUES ( ) VALUES (
".$anvil->Database->quote($bond_uuid).", ".$anvil->Database->quote($bond_uuid).",
".$anvil->Database->quote($bond_host_uuid).", ".$anvil->Database->quote($bond_host_uuid).",
".$anvil->Database->quote($bond_nm_uuid).",
".$anvil->Database->quote($bond_name).", ".$anvil->Database->quote($bond_name).",
".$anvil->Database->quote($bond_mode).", ".$anvil->Database->quote($bond_mode).",
".$anvil->Database->quote($bond_mtu).", ".$anvil->Database->quote($bond_mtu).",
@ -8142,6 +8175,7 @@ INSERT INTO
my $query = " my $query = "
SELECT SELECT
bond_host_uuid, bond_host_uuid,
bond_nm_uuid,
bond_name, bond_name,
bond_mode, bond_mode,
bond_mtu, bond_mtu,
@ -8176,20 +8210,22 @@ WHERE
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
my $old_bond_host_uuid = $row->[0]; my $old_bond_host_uuid = $row->[0];
my $old_bond_name = $row->[1]; my $old_bond_nm_uuid = defined $row->[1] ? $row->[1] : 'NULL';
my $old_bond_mode = $row->[2]; my $old_bond_name = $row->[2];
my $old_bond_mtu = $row->[3]; my $old_bond_mode = $row->[3];
my $old_bond_primary_interface = $row->[4]; my $old_bond_mtu = $row->[4];
my $old_bond_primary_reselect = $row->[5]; my $old_bond_primary_interface = $row->[5];
my $old_bond_active_interface = $row->[6]; my $old_bond_primary_reselect = $row->[6];
my $old_bond_mii_polling_interval = $row->[7]; my $old_bond_active_interface = $row->[7];
my $old_bond_up_delay = $row->[8]; my $old_bond_mii_polling_interval = $row->[8];
my $old_bond_down_delay = $row->[9]; my $old_bond_up_delay = $row->[9];
my $old_bond_mac_address = $row->[10]; my $old_bond_down_delay = $row->[10];
my $old_bond_operational = $row->[11]; my $old_bond_mac_address = $row->[11];
my $old_bond_bridge_uuid = defined $row->[12] ? $row->[12] : 'NULL'; my $old_bond_operational = $row->[12];
my $old_bond_bridge_uuid = defined $row->[13] ? $row->[12] : 'NULL';
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_bond_host_uuid => $old_bond_host_uuid, old_bond_host_uuid => $old_bond_host_uuid,
old_bond_nm_uuid => $old_bond_nm_uuid,
old_bond_name => $old_bond_name, old_bond_name => $old_bond_name,
old_bond_mode => $old_bond_mode, old_bond_mode => $old_bond_mode,
old_bond_mtu => $old_bond_mtu, old_bond_mtu => $old_bond_mtu,
@ -8206,6 +8242,7 @@ WHERE
# Anything change? # Anything change?
if (($old_bond_host_uuid ne $bond_host_uuid) or if (($old_bond_host_uuid ne $bond_host_uuid) or
($old_bond_nm_uuid ne $bond_nm_uuid) or
($old_bond_name ne $bond_name) or ($old_bond_name ne $bond_name) or
($old_bond_mode ne $bond_mode) or ($old_bond_mode ne $bond_mode) or
($old_bond_mtu ne $bond_mtu) or ($old_bond_mtu ne $bond_mtu) or
@ -8225,6 +8262,7 @@ UPDATE
bonds bonds
SET SET
bond_host_uuid = ".$anvil->Database->quote($bond_host_uuid).", bond_host_uuid = ".$anvil->Database->quote($bond_host_uuid).",
bond_nm_uuid = ".$anvil->Database->quote($bond_nm_uuid).",
bond_name = ".$anvil->Database->quote($bond_name).", bond_name = ".$anvil->Database->quote($bond_name).",
bond_mode = ".$anvil->Database->quote($bond_mode).", bond_mode = ".$anvil->Database->quote($bond_mode).",
bond_mtu = ".$anvil->Database->quote($bond_mtu).", bond_mtu = ".$anvil->Database->quote($bond_mtu).",
@ -9606,9 +9644,9 @@ sub insert_or_update_hosts
my $line = defined $parameter->{line} ? $parameter->{line} : ""; my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $host_ipmi = defined $parameter->{host_ipmi} ? $parameter->{host_ipmi} : ""; my $host_ipmi = defined $parameter->{host_ipmi} ? $parameter->{host_ipmi} : "";
my $host_key = defined $parameter->{host_key} ? $parameter->{host_key} : ""; my $host_key = defined $parameter->{host_key} ? $parameter->{host_key} : "";
my $host_name = defined $parameter->{host_name} ? $parameter->{host_name} : $anvil->Get->host_name; my $host_name = defined $parameter->{host_name} ? $parameter->{host_name} : "";
my $host_type = defined $parameter->{host_type} ? $parameter->{host_type} : $anvil->Get->host_type; my $host_type = defined $parameter->{host_type} ? $parameter->{host_type} : "";
my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid; my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : "";
my $host_status = defined $parameter->{host_status} ? $parameter->{host_status} : "no_change"; my $host_status = defined $parameter->{host_status} ? $parameter->{host_status} : "no_change";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid, uuid => $uuid,
@ -9624,15 +9662,34 @@ sub insert_or_update_hosts
if (not $host_name) if (not $host_name)
{ {
# Throw an error and exit. # Can we get it?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_name" }}); $host_name = $anvil->Get->host_name({debug => $debug});
return(""); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_name => $host_name }});
if (not $host_name)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_name" }});
return("");
}
}
if (not $host_type)
{
$host_type = $anvil->Get->host_type({debug => $debug});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
} }
if (not $host_uuid) if (not $host_uuid)
{ {
# Throw an error and exit. # Can we get it?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_uuid" }}); $host_uuid = $anvil->Get->host_uuid({debug => $debug});
return(""); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }});
if (not $host_uuid)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_uuid" }});
return("");
}
} }
# If we're looking at ourselves and we don't have the host_key, read it in. # If we're looking at ourselves and we don't have the host_key, read it in.
@ -11364,6 +11421,10 @@ If this interface is part of a bond, this UUID will be the C<< bonds >> -> C<< b
If this interface is connected to a bridge, this is the C<< bridges >> -> C<< bridge_uuid >> of that bridge. If this interface is connected to a bridge, this is the C<< bridges >> -> C<< bridge_uuid >> of that bridge.
=head3 network_interface_device (optional)
This is the device name (nmcli's GENERAL.IP-IFACE) of the device. This is the name shown in 'ip addr list'. When the interface is down, this will be blank. Use the MAC address ideally, or the 'connection.id' if needed, to find this interface.
=head3 network_interface_duplex (optional) =head3 network_interface_duplex (optional)
This can be set to C<< full >>, C<< half >> or C<< unknown >>, with the later being the default. This can be set to C<< full >>, C<< half >> or C<< unknown >>, with the later being the default.
@ -11390,7 +11451,11 @@ This is the maximum transmit unit (MTU) that this interface supports, in bytes p
=head3 network_interface_name (required) =head3 network_interface_name (required)
This is the current device name for this interface. This is the nmcli 'connection.id' name (bios device name) for the current device of this interface. If the previously recorded MAC address is no longer found, but a new/unknown interface with this name is found, it is sane to configure the device with this name as the replacement 'network_interface_device'.
=head3 network_interface_nm_uuid (optional)
This is the network manager's UUID for this interface.
=head3 network_interface_operational (optional) =head3 network_interface_operational (optional)
@ -11420,6 +11485,7 @@ sub insert_or_update_network_interfaces
my $link_only = defined $parameter->{link_only} ? $parameter->{link_only} : 0; my $link_only = defined $parameter->{link_only} ? $parameter->{link_only} : 0;
my $network_interface_bond_uuid = $parameter->{network_interface_bond_uuid} ? $parameter->{network_interface_bond_uuid} : 'NULL'; my $network_interface_bond_uuid = $parameter->{network_interface_bond_uuid} ? $parameter->{network_interface_bond_uuid} : 'NULL';
my $network_interface_bridge_uuid = $parameter->{network_interface_bridge_uuid} ? $parameter->{network_interface_bridge_uuid} : 'NULL'; my $network_interface_bridge_uuid = $parameter->{network_interface_bridge_uuid} ? $parameter->{network_interface_bridge_uuid} : 'NULL';
my $network_interface_device = defined $parameter->{network_interface_device} ? $parameter->{network_interface_device} : "";
my $network_interface_duplex = defined $parameter->{network_interface_duplex} ? $parameter->{network_interface_duplex} : "unknown"; my $network_interface_duplex = defined $parameter->{network_interface_duplex} ? $parameter->{network_interface_duplex} : "unknown";
my $network_interface_host_uuid = defined $parameter->{network_interface_host_uuid} ? $parameter->{network_interface_host_uuid} : $anvil->Get->host_uuid; my $network_interface_host_uuid = defined $parameter->{network_interface_host_uuid} ? $parameter->{network_interface_host_uuid} : $anvil->Get->host_uuid;
my $network_interface_link_state = defined $parameter->{network_interface_link_state} ? $parameter->{network_interface_link_state} : "unknown"; my $network_interface_link_state = defined $parameter->{network_interface_link_state} ? $parameter->{network_interface_link_state} : "unknown";
@ -11428,6 +11494,7 @@ sub insert_or_update_network_interfaces
my $network_interface_medium = defined $parameter->{network_interface_medium} ? $parameter->{network_interface_medium} : ""; my $network_interface_medium = defined $parameter->{network_interface_medium} ? $parameter->{network_interface_medium} : "";
my $network_interface_mtu = defined $parameter->{network_interface_mtu} ? $parameter->{network_interface_mtu} : 0; my $network_interface_mtu = defined $parameter->{network_interface_mtu} ? $parameter->{network_interface_mtu} : 0;
my $network_interface_name = defined $parameter->{network_interface_name} ? $parameter->{network_interface_name} : ""; my $network_interface_name = defined $parameter->{network_interface_name} ? $parameter->{network_interface_name} : "";
my $network_interface_nm_uuid = defined $parameter->{network_interface_nm_uuid} ? $parameter->{network_interface_nm_uuid} : "";
my $network_interface_speed = defined $parameter->{network_interface_speed} ? $parameter->{network_interface_speed} : 0; my $network_interface_speed = defined $parameter->{network_interface_speed} ? $parameter->{network_interface_speed} : 0;
my $network_interface_uuid = defined $parameter->{network_interface_uuid} ? $parameter->{network_interface_uuid} : ""; my $network_interface_uuid = defined $parameter->{network_interface_uuid} ? $parameter->{network_interface_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -11438,6 +11505,7 @@ sub insert_or_update_network_interfaces
link_only => $link_only, link_only => $link_only,
network_interface_bond_uuid => $network_interface_bond_uuid, network_interface_bond_uuid => $network_interface_bond_uuid,
network_interface_bridge_uuid => $network_interface_bridge_uuid, network_interface_bridge_uuid => $network_interface_bridge_uuid,
network_interface_device => $network_interface_device,
network_interface_duplex => $network_interface_duplex, network_interface_duplex => $network_interface_duplex,
network_interface_host_uuid => $network_interface_host_uuid, network_interface_host_uuid => $network_interface_host_uuid,
network_interface_link_state => $network_interface_link_state, network_interface_link_state => $network_interface_link_state,
@ -11446,6 +11514,7 @@ sub insert_or_update_network_interfaces
network_interface_medium => $network_interface_medium, network_interface_medium => $network_interface_medium,
network_interface_mtu => $network_interface_mtu, network_interface_mtu => $network_interface_mtu,
network_interface_name => $network_interface_name, network_interface_name => $network_interface_name,
network_interface_nm_uuid => $network_interface_nm_uuid,
network_interface_speed => $network_interface_speed, network_interface_speed => $network_interface_speed,
network_interface_uuid => $network_interface_uuid, network_interface_uuid => $network_interface_uuid,
}}); }});
@ -11504,6 +11573,7 @@ WHERE ";
network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address)." network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address)."
AND "; AND ";
} }
### TODO: We may need to switch this to 'device' if the name or MAC address isn't found
$query .= " $query .= "
network_interface_name = ".$anvil->Database->quote($network_interface_name)." network_interface_name = ".$anvil->Database->quote($network_interface_name)."
AND AND
@ -11522,6 +11592,68 @@ AND
$network_interface_uuid = $results->[0]->[0]; $network_interface_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network_interface_uuid => $network_interface_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network_interface_uuid => $network_interface_uuid }});
} }
elsif ($network_interface_device)
{
# Try again using the device name.
my $query = "
SELECT
network_interface_uuid
FROM
network_interfaces
WHERE ";
if ($network_interface_name !~ /^vnet/)
{
$query .= "
network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address)."
AND ";
}
### TODO: We may need to switch this to 'device' if the name or MAC address isn't found
$query .= "
network_interface_device = ".$anvil->Database->quote($network_interface_device)."
AND
network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
$network_interface_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network_interface_uuid => $network_interface_uuid }});
}
}
elsif ($network_interface_name !~ /^vnet/)
{
# Try finding it by MAC
my $query = "
SELECT
network_interface_uuid
FROM
network_interfaces
WHERE
network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address)."
AND
network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
$network_interface_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network_interface_uuid => $network_interface_uuid }});
}
}
if (($link_only) && (not $network_interface_uuid)) if (($link_only) && (not $network_interface_uuid))
{ {
@ -11585,8 +11717,10 @@ WHERE
my $query = " my $query = "
SELECT SELECT
network_interface_host_uuid, network_interface_host_uuid,
network_interface_nm_uuid,
network_interface_mac_address, network_interface_mac_address,
network_interface_name, network_interface_name,
network_interface_device,
network_interface_speed, network_interface_speed,
network_interface_mtu, network_interface_mtu,
network_interface_link_state, network_interface_link_state,
@ -11617,20 +11751,24 @@ WHERE
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
my $old_network_interface_host_uuid = $row->[0]; my $old_network_interface_host_uuid = $row->[0];
my $old_network_interface_nm_uuid = defined $row->[1] ? $row->[1] : 'NULL';
my $old_network_interface_mac_address = $row->[1]; my $old_network_interface_mac_address = $row->[1];
my $old_network_interface_name = $row->[2]; my $old_network_interface_name = $row->[2];
my $old_network_interface_speed = $row->[3]; my $old_network_interface_device = $row->[3];
my $old_network_interface_mtu = $row->[4]; my $old_network_interface_speed = $row->[4];
my $old_network_interface_link_state = $row->[5]; my $old_network_interface_mtu = $row->[5];
my $old_network_interface_operational = $row->[6]; my $old_network_interface_link_state = $row->[6];
my $old_network_interface_duplex = $row->[7]; my $old_network_interface_operational = $row->[7];
my $old_network_interface_medium = $row->[8]; my $old_network_interface_duplex = $row->[8];
my $old_network_interface_bond_uuid = defined $row->[9] ? $row->[9] : 'NULL'; my $old_network_interface_medium = $row->[9];
my $old_network_interface_bridge_uuid = defined $row->[10] ? $row->[10] : 'NULL'; my $old_network_interface_bond_uuid = defined $row->[10] ? $row->[10] : 'NULL';
my $old_network_interface_bridge_uuid = defined $row->[11] ? $row->[11] : 'NULL';
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_network_interface_host_uuid => $old_network_interface_host_uuid, old_network_interface_host_uuid => $old_network_interface_host_uuid,
old_network_interface_nm_uuid => $old_network_interface_nm_uuid,
old_network_interface_mac_address => $old_network_interface_mac_address, old_network_interface_mac_address => $old_network_interface_mac_address,
old_network_interface_name => $old_network_interface_name, old_network_interface_name => $old_network_interface_name,
old_network_interface_device => $old_network_interface_device,
old_network_interface_speed => $old_network_interface_speed, old_network_interface_speed => $old_network_interface_speed,
old_network_interface_mtu => $old_network_interface_mtu, old_network_interface_mtu => $old_network_interface_mtu,
old_network_interface_link_state => $old_network_interface_link_state, old_network_interface_link_state => $old_network_interface_link_state,
@ -11644,7 +11782,9 @@ WHERE
# If 'link_only' is set, we're only checking/updating a subset of values. # If 'link_only' is set, we're only checking/updating a subset of values.
if ($link_only) if ($link_only)
{ {
if (($network_interface_name ne $old_network_interface_name) or if (($network_interface_nm_uuid ne $old_network_interface_nm_uuid) or
($network_interface_name ne $old_network_interface_name) or
($network_interface_device ne $old_network_interface_device) or
($network_interface_link_state ne $old_network_interface_link_state) or ($network_interface_link_state ne $old_network_interface_link_state) or
($network_interface_operational ne $old_network_interface_operational) or ($network_interface_operational ne $old_network_interface_operational) or
($network_interface_mac_address ne $old_network_interface_mac_address) or ($network_interface_mac_address ne $old_network_interface_mac_address) or
@ -11656,7 +11796,9 @@ UPDATE
network_interfaces network_interfaces
SET SET
network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid).", network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid).",
network_interface_nm_uuid = ".$anvil->Database->quote($network_interface_nm_uuid).",
network_interface_name = ".$anvil->Database->quote($network_interface_name).", network_interface_name = ".$anvil->Database->quote($network_interface_name).",
network_interface_device = ".$anvil->Database->quote($network_interface_device).",
network_interface_link_state = ".$anvil->Database->quote($network_interface_link_state).", network_interface_link_state = ".$anvil->Database->quote($network_interface_link_state).",
network_interface_operational = ".$anvil->Database->quote($network_interface_operational).", network_interface_operational = ".$anvil->Database->quote($network_interface_operational).",
network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address).", network_interface_mac_address = ".$anvil->Database->quote($network_interface_mac_address).",
@ -11676,7 +11818,9 @@ WHERE
# not passed in, we want to not compare it. # not passed in, we want to not compare it.
if (($network_interface_bond_uuid ne $old_network_interface_bond_uuid) or if (($network_interface_bond_uuid ne $old_network_interface_bond_uuid) or
($network_interface_bridge_uuid ne $old_network_interface_bridge_uuid) or ($network_interface_bridge_uuid ne $old_network_interface_bridge_uuid) or
($network_interface_nm_uuid ne $old_network_interface_nm_uuid) or
($network_interface_name ne $old_network_interface_name) or ($network_interface_name ne $old_network_interface_name) or
($network_interface_device ne $old_network_interface_device) or
($network_interface_duplex ne $old_network_interface_duplex) or ($network_interface_duplex ne $old_network_interface_duplex) or
($network_interface_link_state ne $old_network_interface_link_state) or ($network_interface_link_state ne $old_network_interface_link_state) or
($network_interface_operational ne $old_network_interface_operational) or ($network_interface_operational ne $old_network_interface_operational) or
@ -11692,9 +11836,11 @@ UPDATE
network_interfaces network_interfaces
SET SET
network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid).", network_interface_host_uuid = ".$anvil->Database->quote($network_interface_host_uuid).",
network_interface_nm_uuid = ".$anvil->Database->quote($network_interface_nm_uuid).",
network_interface_bond_uuid = ".$anvil->Database->quote($network_interface_bond_uuid).", network_interface_bond_uuid = ".$anvil->Database->quote($network_interface_bond_uuid).",
network_interface_bridge_uuid = ".$anvil->Database->quote($network_interface_bridge_uuid).", network_interface_bridge_uuid = ".$anvil->Database->quote($network_interface_bridge_uuid).",
network_interface_name = ".$anvil->Database->quote($network_interface_name).", network_interface_name = ".$anvil->Database->quote($network_interface_name).",
network_interface_device = ".$anvil->Database->quote($network_interface_device).",
network_interface_duplex = ".$anvil->Database->quote($network_interface_duplex).", network_interface_duplex = ".$anvil->Database->quote($network_interface_duplex).",
network_interface_link_state = ".$anvil->Database->quote($network_interface_link_state).", network_interface_link_state = ".$anvil->Database->quote($network_interface_link_state).",
network_interface_operational = ".$anvil->Database->quote($network_interface_operational).", network_interface_operational = ".$anvil->Database->quote($network_interface_operational).",
@ -11723,9 +11869,11 @@ INSERT INTO
network_interfaces network_interfaces
( (
network_interface_uuid, network_interface_uuid,
network_interface_nm_uuid,
network_interface_bond_uuid, network_interface_bond_uuid,
network_interface_bridge_uuid, network_interface_bridge_uuid,
network_interface_name, network_interface_name,
network_interface_device,
network_interface_duplex, network_interface_duplex,
network_interface_host_uuid, network_interface_host_uuid,
network_interface_link_state, network_interface_link_state,
@ -11737,9 +11885,11 @@ INSERT INTO
modified_date modified_date
) VALUES ( ) VALUES (
".$anvil->Database->quote($network_interface_uuid).", ".$anvil->Database->quote($network_interface_uuid).",
".$anvil->Database->quote($network_interface_nm_uuid).",
".$anvil->Database->quote($network_interface_bond_uuid).", ".$anvil->Database->quote($network_interface_bond_uuid).",
".$anvil->Database->quote($network_interface_bridge_uuid).", ".$anvil->Database->quote($network_interface_bridge_uuid).",
".$anvil->Database->quote($network_interface_name).", ".$anvil->Database->quote($network_interface_name).",
".$anvil->Database->quote($network_interface_device).",
".$anvil->Database->quote($network_interface_duplex).", ".$anvil->Database->quote($network_interface_duplex).",
".$anvil->Database->quote($network_interface_host_uuid).", ".$anvil->Database->quote($network_interface_host_uuid).",
".$anvil->Database->quote($network_interface_link_state).", ".$anvil->Database->quote($network_interface_link_state).",
@ -17825,7 +17975,7 @@ sub resync_databases
$query .= " ORDER BY utc_modified_date DESC;"; $query .= " ORDER BY utc_modified_date DESC;";
} }
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0074", variables => { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0074", variables => {
uuid => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid}), uuid => $anvil->Database->get_host_from_uuid({debug => $debug, short => 1, host_uuid => $uuid}),
query => $query, query => $query,
}}); }});
@ -18071,7 +18221,7 @@ sub resync_databases
# Already in, redirect to the history schema. # Already in, redirect to the history schema.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0029", variables => { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0029", variables => {
table => $table, table => $table,
host_name => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid}), host_name => $anvil->Database->get_host_from_uuid({debug => $debug, short => 1, host_uuid => $uuid}),
host_uuid => $uuid, host_uuid => $uuid,
column => $uuid_column, column => $uuid_column,
uuid => $row_uuid, uuid => $row_uuid,
@ -18494,7 +18644,6 @@ sub track_files
}}); }});
next if $file_type eq "DELETED"; next if $file_type eq "DELETED";
### TODO - Left off here, not adding DR links.
my $anvil_needs_file = 0; my $anvil_needs_file = 0;
foreach my $host_uuid ($anvil_node1_host_uuid, $anvil_node2_host_uuid) foreach my $host_uuid ($anvil_node1_host_uuid, $anvil_node2_host_uuid)
{ {
@ -18679,6 +18828,10 @@ This records data to one or all of the databases. If a UUID is passed, the query
Parameters; Parameters;
=head3 initializing (optional, default 0)
When set to C<< 1 >>, this tells the method that the database is being initialized, so some checks and lookups are disabled.
=head3 line (optional) =head3 line (optional)
If you want errors to be traced back to the query called, this can be set (usually to C<< __LINE__ >>) along with the C<< source >> parameter. In such a case, if there is an error in this method, the caller's file and line are displayed in the logs. If you want errors to be traced back to the query called, this can be set (usually to C<< __LINE__ >>) along with the C<< source >> parameter. In such a case, if there is an error in this method, the caller's file and line are displayed in the logs.
@ -18718,20 +18871,23 @@ sub write
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->write()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->write()" }});
my $line = $parameter->{line} ? $parameter->{line} : __LINE__; my $initializing = $parameter->{initializing} ? $parameter->{initializing} : 0;
my $query = $parameter->{query} ? $parameter->{query} : ""; my $line = $parameter->{line} ? $parameter->{line} : __LINE__;
my $reenter = $parameter->{reenter} ? $parameter->{reenter} : ""; my $query = $parameter->{query} ? $parameter->{query} : "";
my $secure = $parameter->{secure} ? $parameter->{secure} : 0; my $reenter = $parameter->{reenter} ? $parameter->{reenter} : "";
my $source = $parameter->{source} ? $parameter->{source} : $THIS_FILE; my $secure = $parameter->{secure} ? $parameter->{secure} : 0;
my $transaction = $parameter->{transaction} ? $parameter->{transaction} : 0; my $source = $parameter->{source} ? $parameter->{source} : $THIS_FILE;
my $uuid = $parameter->{uuid} ? $parameter->{uuid} : ""; my $transaction = $parameter->{transaction} ? $parameter->{transaction} : 0;
my $uuid = $parameter->{uuid} ? $parameter->{uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid, initializing => $initializing,
line => $line, line => $line,
query => (not $secure) ? $query : $anvil->Log->is_secure($query), query => (not $secure) ? $query : $anvil->Log->is_secure($query),
secure => $secure, reenter => $reenter,
source => $source, secure => $secure,
reenter => $reenter, source => $source,
transaction => $transaction,
uuid => $uuid,
}}); }});
if ($uuid) if ($uuid)
@ -18765,7 +18921,7 @@ sub write
} }
# If I am still alive check if any locks need to be renewed. # If I am still alive check if any locks need to be renewed.
$anvil->Database->check_lock_age({debug => $debug}); $anvil->Database->check_lock_age({debug => $debug}) if not $initializing;
# This array will hold either just the passed DB ID or all of them, if no ID was specified. # This array will hold either just the passed DB ID or all of them, if no ID was specified.
my @db_uuids; my @db_uuids;
@ -18822,6 +18978,10 @@ sub write
{ {
push @{$query_set}, $this_query; push @{$query_set}, $this_query;
$i++; $i++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
this_query => $this_query,
i => $i,
}});
if ($i > $next) if ($i > $next)
{ {
@ -18852,6 +19012,7 @@ sub write
foreach my $this_query (@{$query}) foreach my $this_query (@{$query})
{ {
push @{$query_set}, $this_query; push @{$query_set}, $this_query;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { this_query => $this_query }});
} }
} }
} }
@ -18867,8 +19028,11 @@ sub write
foreach my $uuid (@db_uuids) foreach my $uuid (@db_uuids)
{ {
# Test access to the DB before we do the actual query # Test access to the DB before we do the actual query
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }}); if (not $initializing)
$anvil->Database->_test_access({debug => $debug, uuid => $uuid}); {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }});
$anvil->Database->_test_access({debug => $debug, uuid => $uuid});
}
# Do the actual query(ies) # Do the actual query(ies)
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -18886,7 +19050,7 @@ sub write
if (($anvil->data->{sys}{database}{log_transactions}) or ($debug <= $anvil->Log->level)) if (($anvil->data->{sys}{database}{log_transactions}) or ($debug <= $anvil->Log->level))
{ {
$anvil->Log->entry({source => $source, line => $line, secure => $secure, level => 0, key => "log_0083", variables => { $anvil->Log->entry({source => $source, line => $line, secure => $secure, level => 0, key => "log_0083", variables => {
uuid => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid}), uuid => $initializing ? $uuid : $anvil->Database->get_host_from_uuid({debug => 1, short => 1, host_uuid => $uuid}),
query => $query, query => $query,
}}); }});
} }
@ -18905,6 +19069,7 @@ sub write
's1:test' => $test, 's1:test' => $test,
's2:$@' => $@, 's2:$@' => $@,
}}); }});
if (not $test) if (not $test)
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0090", variables => { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0090", variables => {

@ -487,9 +487,9 @@ sub send_alerts
if ($alert_title) if ($alert_title)
{ {
my $title = "[ ".$alert_set_by." ] ".$anvil->Words->parse_banged_string({ my $title = "[ ".$alert_set_by." ] ".$anvil->Words->parse_banged_string({
debug => $debug,
language => $recipient_language, language => $recipient_language,
key_string => $alert_title, key_string => $alert_title,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { title => $title }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { title => $title }});

@ -1513,10 +1513,29 @@ sub host_name
{ {
# Failed to read the file, too. What the hell? Exit out. # Failed to read the file, too. What the hell? Exit out.
print "Failed to query the hostname using 'hostnamectl --static' and failed to read the content of: [".$anvil->data->{path}{configs}{hostname}."]. Something is very wrong, exiting.\n"; print "Failed to query the hostname using 'hostnamectl --static' and failed to read the content of: [".$anvil->data->{path}{configs}{hostname}."]. Something is very wrong, exiting.\n";
$anvil->nice_exit({exit_code => 1});
} }
} }
else else
{ {
# Did we get a real answer? If it's "unet", the string will be emtpy.
if (not $host_name)
{
# Try seeing if there is a transient hostname.
($host_name, my $return_code) = $anvil->System->call({debug => 9999, shell_call => $anvil->data->{path}{exe}{hostnamectl}." --transient"});
if (not $host_name)
{
# OK, can we get it from the 'hostname' command?
($host_name, my $return_code) = $anvil->System->call({debug => 9999, shell_call => $anvil->data->{path}{exe}{hostname}});
if (not $host_name)
{
# Failed to find the hostname at all.
print "Failed to query the hostname using 'hostnamectl --static', 'hostnamectl --transient' or 'hostname'. Something is very wrong, exiting.\n";
$anvil->nice_exit({exit_code => 1});
}
}
}
# Cache the answer # Cache the answer
$anvil->data->{sys}{host_name} = $host_name; $anvil->data->{sys}{host_name} = $host_name;
} }
@ -2146,6 +2165,11 @@ sub os_type
$os_type = "centos-stream".$1; $os_type = "centos-stream".$1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }});
} }
elsif ($release =~ /AlmaLinux .*? (\d+)/)
{
$os_type = "alma".$1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }});
}
elsif ($release =~ /CentOS .*? (\d+)\./) elsif ($release =~ /CentOS .*? (\d+)\./)
{ {
# CentOS, with the major version number appended # CentOS, with the major version number appended

@ -12,6 +12,7 @@ our $VERSION = "3.0.0";
my $THIS_FILE = "Job.pm"; my $THIS_FILE = "Job.pm";
### Methods; ### Methods;
# bump_progress
# clear # clear
# get_job_details # get_job_details
# get_job_uuid # get_job_uuid
@ -80,6 +81,84 @@ sub parent
# Public methods # # Public methods #
############################################################################################################# #############################################################################################################
=head2 bump_progress
This method is meant to make it easier to bump the progress of a jump by some number of steps when a job doesn't run in a linear fashion.
It does this by storing the progress in the C<< sys::job_progress >> hash and incrementing it by the C<< steps >> parameter value (setting it to C<< 0 >> if it doesn't exist or exists with a non-digit value). If the progress goes over C<< 99 >>, it will return C<< 99 >>.
If you want to set the progress to C<< 0 >> or C<< 100 >>, use the C<< set >> parameter.
Parameters;
=head3 set (optional)
If you want to set the progress to a specific value, use this parameter.
B<< NOTE >>: If the set value is less than the current value, the current progress + 1 will be returns. This is meant to prevent progress bars from backing up.
=head3 steps (default '1')
This takes an integer and it will increase the job progress by that value. If this is not specified, or if it is set to a non-integer value, C<< 1 >> will be used.
=cut
sub bump_progress
{
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 => "Job->bump_progress()" }});
my $set = defined $parameter->{set} ? $parameter->{set} : "";
my $steps = defined $parameter->{steps} ? $parameter->{steps} : 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
set => $set,
steps => $steps,
}});
if ((not exists $anvil->data->{sys}{job_progress}) or ($anvil->data->{sys}{job_progress} !~ /^\d+$/))
{
$anvil->data->{sys}{job_progress} = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
if ($set =~ /^\d+$/)
{
if ($set > 100)
{
$anvil->data->{sys}{job_progress} = 100;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
elsif ($set > $anvil->data->{sys}{job_progress})
{
$anvil->data->{sys}{job_progress}++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
}
$anvil->data->{sys}{job_progress} += $steps;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
if ($anvil->data->{sys}{job_progress} > 99)
{
$anvil->data->{sys}{job_progress} = 99;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
return($anvil->data->{sys}{job_progress});
}
=head2 clear =head2 clear
This clears the C<< job_picked_up_by >> value for the given job. This clears the C<< job_picked_up_by >> value for the given job.
@ -501,8 +580,8 @@ sub html_list
} }
# Convert the double-banged strings into a proper message. # Convert the double-banged strings into a proper message.
my $say_title = $job_title ? $anvil->Words->parse_banged_string({key_string => $job_title}) : ""; my $say_title = $job_title ? $anvil->Words->parse_banged_string({debug => $debug, key_string => $job_title}) : "";
my $say_description = $job_description ? $anvil->Words->parse_banged_string({key_string => $job_description}) : ""; my $say_description = $job_description ? $anvil->Words->parse_banged_string({debug => $debug, key_string => $job_description}) : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
job_title => $job_title, job_title => $job_title,
say_description => $say_description, say_description => $say_description,
@ -537,10 +616,18 @@ B<< Note >>: Some special C<< job_status >> processing is done to support some s
Parameters; Parameters;
=head3 file (optional)
When logging as well, this is the file causing the update. Use with C<< line >>. Ignored if C<< log_level >> is not set, or such that it wouldn't be logged anyway.
=head3 job_uuid (optional, default 'jobs::job_uuid') =head3 job_uuid (optional, default 'jobs::job_uuid')
This is the UUID of the job to update. If it isn't set, but C<< jobs::job_uuid >> is set, it will be used. If that is also not set, This is the UUID of the job to update. If it isn't set, but C<< jobs::job_uuid >> is set, it will be used. If that is also not set,
=head3 line (optional_
When logging as well, this is the line the update came from. Use with C<< file >>. Ignored if C<< log_level >> is not set, or such that it wouldn't be logged anyway.
=head3 log_level (optional) =head3 log_level (optional)
If set to a numeric level, the job's message will also be logged. This is designed to simplify code as most job progress messages will also want to be logged. If set to a numeric level, the job's message will also be logged. This is designed to simplify code as most job progress messages will also want to be logged.
@ -584,7 +671,9 @@ sub update_progress
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Job->update_progress()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Job->update_progress()" }});
my $file = defined $parameter->{file} ? $parameter->{file} : $THIS_FILE;
my $job_uuid = defined $parameter->{job_uuid} ? $parameter->{job_uuid} : ""; my $job_uuid = defined $parameter->{job_uuid} ? $parameter->{job_uuid} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : __LINE__;
my $log_level = defined $parameter->{log_level} ? $parameter->{log_level} : ""; my $log_level = defined $parameter->{log_level} ? $parameter->{log_level} : "";
my $message = defined $parameter->{message} ? $parameter->{message} : ""; my $message = defined $parameter->{message} ? $parameter->{message} : "";
my $picked_up_by = defined $parameter->{picked_up_by} ? $parameter->{picked_up_by} : ""; my $picked_up_by = defined $parameter->{picked_up_by} ? $parameter->{picked_up_by} : "";
@ -594,11 +683,13 @@ sub update_progress
my $secure = defined $parameter->{secure} ? $parameter->{secure} : ""; my $secure = defined $parameter->{secure} ? $parameter->{secure} : "";
my $variables = defined $parameter->{variables} ? $parameter->{variables} : ""; my $variables = defined $parameter->{variables} ? $parameter->{variables} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
file => $file,
job_uuid => $job_uuid, job_uuid => $job_uuid,
line => $line,
log_level => $log_level,
picked_up_by => $picked_up_by, picked_up_by => $picked_up_by,
'print' => $print, 'print' => $print,
progress => $progress, progress => $progress,
log_level => $log_level,
message => $message, message => $message,
variables => $variables, variables => $variables,
secure => $secure, secure => $secure,
@ -608,7 +699,7 @@ sub update_progress
if (($message ne "clear") && ($log_level =~ /^\d+$/)) if (($message ne "clear") && ($log_level =~ /^\d+$/))
{ {
# Log this message. # Log this message.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, 'print' => $print, secure => $secure, priority => $priority, key => $message, variables => $variables}); $anvil->Log->entry({source => $file, line => $line, level => $log_level, 'print' => $print, secure => $secure, priority => $priority, key => $message, variables => $variables});
} }
if ($picked_up_by eq "") if ($picked_up_by eq "")
@ -654,6 +745,12 @@ sub update_progress
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::last_update" => $anvil->data->{sys}{last_update} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::last_update" => $anvil->data->{sys}{last_update} }});
} }
# If we don't have a database connection, we're done.
if (not $anvil->data->{sys}{database}{connections})
{
return(0);
}
# Add variables to the message, if required # Add variables to the message, if required
if (ref($variables) eq "HASH") if (ref($variables) eq "HASH")
{ {

@ -491,7 +491,7 @@ sub entry
binmode($anvil->data->{HANDLE}{'log'}{main}, ':encoding(utf-8)'); binmode($anvil->data->{HANDLE}{'log'}{main}, ':encoding(utf-8)');
print $THIS_FILE." ".__LINE__."; HANDLE::log::main: [".$anvil->data->{HANDLE}{'log'}{main}."]\n" if $test; print $THIS_FILE." ".__LINE__."; HANDLE::log::main: [".$anvil->data->{HANDLE}{'log'}{main}."]\n" if $test;
# Make sure it can be written to by apache. # Make sure it can be written to by striker-ui-api.
$anvil->Storage->change_mode({test => $test, debug => $debug, path => $log_file, mode => "0666"}); $anvil->Storage->change_mode({test => $test, debug => $debug, path => $log_file, mode => "0666"});
} }
@ -531,7 +531,7 @@ sub entry
$anvil->data->{HANDLE}{'log'}{alert} = $file_handle; $anvil->data->{HANDLE}{'log'}{alert} = $file_handle;
print $THIS_FILE." ".__LINE__."; HANDLE::log::alert: [".$anvil->data->{HANDLE}{'log'}{alert}."]\n" if $test; print $THIS_FILE." ".__LINE__."; HANDLE::log::alert: [".$anvil->data->{HANDLE}{'log'}{alert}."]\n" if $test;
# Make sure it can be written to by apache. # Make sure it can be written to by striker-ui-api.
$anvil->Storage->change_mode({test => $test, debug => $debug, path => $log_file, mode => "0666"}); $anvil->Storage->change_mode({test => $test, debug => $debug, path => $log_file, mode => "0666"});
} }

File diff suppressed because it is too large Load Diff

@ -3232,6 +3232,8 @@ fi;";
=head2 manage_lvm_conf =head2 manage_lvm_conf
B<< Note >>: This only works on EL8. If used on another distro, this method will return without actually doing anything.
This method configures C<< lvm.conf >> to add the C<< filter = [ ... ] >> to ensure DRBD devices aren't scanned. This method configures C<< lvm.conf >> to add the C<< filter = [ ... ] >> to ensure DRBD devices aren't scanned.
If there was a problem, C<< 1 >> is returned. Otherwise, C<< 0 >> is returned. If there was a problem, C<< 1 >> is returned. Otherwise, C<< 0 >> is returned.
@ -3274,6 +3276,18 @@ sub manage_lvm_conf
target => $target, target => $target,
}}); }});
### NOTE: Only add the filter on EL8 machines.
my ($os_type, $os_arch) = $anvil->Get->os_type({debug => $debug});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
os_type => $os_type,
os_arch => $os_arch,
}});
if ($os_type !~ /\D8/)
{
# Not EL8, return
return(0);
}
my $body = $anvil->Storage->read_file({ my $body = $anvil->Storage->read_file({
debug => $debug, debug => $debug,
file => $anvil->data->{path}{configs}{'lvm.conf'}, file => $anvil->data->{path}{configs}{'lvm.conf'},

@ -14,7 +14,7 @@ our $VERSION = "3.0.0";
my $THIS_FILE = "Striker.pm"; my $THIS_FILE = "Striker.pm";
### Methods; ### Methods;
# check_httpd_conf # check_httpd_conf - Deprecated
# generate_manifest # generate_manifest
# get_fence_data # get_fence_data
# get_local_repo # get_local_repo

@ -26,6 +26,7 @@ my $THIS_FILE = "System.pm";
# check_if_configured # check_if_configured
# check_ssh_keys # check_ssh_keys
# check_memory # check_memory
# check_network_type
# check_storage # check_storage
# collect_ipmi_data # collect_ipmi_data
# configure_ipmi # configure_ipmi
@ -1279,6 +1280,62 @@ sub check_ssh_keys
} }
=head2 check_network_type
This method checks to see if this host is using network manager to configure the network, versus the older C<< ifcfg-X >> based config. It does this by looking for any C<< ifcfg-X >> files in C<< /etc/sysconfig/network-scripts >>.
If any 'ifcfg-X' files are found, C<< ifcfg >> is returned. Otherwise, C<< nm >> is returned.
The results are cached in C<< sys::network_type >>.
This method takes no parameters.
=cut
sub check_network_type
{
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->check_storage()" }});
if ((exists $anvil->data->{sys}{network_type}) && ($anvil->data->{sys}{network_type}))
{
# Cached.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::network_type" => $anvil->data->{sys}{network_type} }});
return($anvil->data->{sys}{network_type});
}
# Open the 'ifcfg' directory, if it exists, and see if there are any 'ifcfg-X' files.
my $type = "nm";
my $directory = $anvil->data->{path}{directories}{ifcfg};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
if (-e $directory)
{
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file => $file }});
if ($file =~ /^ifcfg-(.*)$/)
{
$type = "ifcfg";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { type => $type }});
last;
}
}
closedir(DIRECTORY);
}
# Cache the results
$anvil->data->{sys}{network_type} = $type;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::network_type" => $anvil->data->{sys}{network_type} }});
return($anvil->data->{sys}{network_type});
}
=head2 check_storage =head2 check_storage
Thic gathers LVM data from the local system. Thic gathers LVM data from the local system.
@ -2790,6 +2847,7 @@ sub disable_daemon
return($return_code); return($return_code);
} }
=head2 generate_state_json =head2 generate_state_json
This method generates the C<< all_status.json >> file. This method generates the C<< all_status.json >> file.
@ -2879,13 +2937,14 @@ sub generate_state_json
my $mac_address = $anvil->data->{network}{$host}{interface}{$interface}{mac_address}; my $mac_address = $anvil->data->{network}{$host}{interface}{$interface}{mac_address};
my $iface_hash = {}; my $iface_hash = {};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:interface" => $interface, "s1:host" => $host,
"s2:mac_address" => $mac_address, "s2:interface" => $interface,
"s3:type" => $type, "s3:mac_address" => $mac_address,
"s4:mtu" => $mtu, "s4:type" => $type,
"s5:configured" => $configured, "s5:mtu" => $mtu,
"s6:host_uuid" => $host_uuid, "s6:configured" => $configured,
"s7:host_key" => $host_key, "s7:host_uuid" => $host_uuid,
"s8:host_key" => $host_key,
}}); }});
$iface_hash->{name} = $interface; $iface_hash->{name} = $interface;
$iface_hash->{type} = $type; $iface_hash->{type} = $type;
@ -3191,8 +3250,8 @@ sub generate_state_json
backup => 0, backup => 0,
file => $json_file, file => $json_file,
body => $json, body => $json,
group => "apache", group => "striker-ui-api",
user => "apache", user => "striker-ui-api",
mode => "0644", mode => "0644",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { error => $error }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { error => $error }});

@ -247,6 +247,7 @@ setenforce 0
### TODO: check it if was disabled (if it existed before) and, if so, leave it disabled. ### TODO: check it if was disabled (if it existed before) and, if so, leave it disabled.
systemctl enable --now chronyd.service systemctl enable --now chronyd.service
systemctl enable --now anvil-daemon.service systemctl enable --now anvil-daemon.service
systemctl enable --now anvil-monitor-network.service
systemctl enable --now scancore.service systemctl enable --now scancore.service
%pre striker %pre striker
@ -285,11 +286,6 @@ then
systemctl enable gdm.service systemctl enable gdm.service
fi fi
### This is handled by anvil-daemon now
#echo "Preparing the database"
#striker-prep-database
#anvil-update-states
# Touch the system type file. # Touch the system type file.
echo "Touching the system type file" echo "Touching the system type file"
if [ -e '/etc/anvil/type.node' ] if [ -e '/etc/anvil/type.node' ]

@ -35,9 +35,6 @@ Check to see if the host is marked as configured or yet.
\fB\-\-check\-database\fR \fB\-\-check\-database\fR
This checks to see if the database is enabled or not. This checks to see if the database is enabled or not.
.TP .TP
\fB\-\-check\-network\-mapping\fR
This reports if the host is currently in network mapping (this disables several features and watches the network states much more frequently)
.TP
\fB\-\-confirm\fR \fB\-\-confirm\fR
This confirms actions that would normally prompt the user to confirm before proceeding. This confirms actions that would normally prompt the user to confirm before proceeding.
.TP .TP
@ -47,12 +44,6 @@ This enables the database on the local Striker dashboard.
\fB\-\-database\-inactive\fR \fB\-\-database\-inactive\fR
This disables the database on the local Striker dashboard. This disables the database on the local Striker dashboard.
.TP .TP
\fB\-\-disable\-network\-mapping\fR
This disables the network mapping mode.
.TP
\fB\-\-enable\-network\-mapping\fR
This enables the network mapping mode.
.TP
\fB\-\-mark\-configured\fR \fB\-\-mark\-configured\fR
This marks the host as having been configured. This marks the host as having been configured.
.TP .TP

@ -69,6 +69,9 @@ if ($anvil->data->{switches}{purge})
$anvil->nice_exit({exit_code => 0}); $anvil->nice_exit({exit_code => 0});
} }
# If there's no DB (or cached data isn't recorded to the database yet), this will store those records.
$anvil->data->{cache}{new_file} = "# interface (nm_device),timestamp,mac_address,speed,link_state,operational,nm_uuid,nm_name\n";
process_interface_cache($anvil);
# Read the data. # Read the data.
collect_data($anvil); collect_data($anvil);
@ -88,6 +91,18 @@ clear_old_variables($anvil);
# This removes network interfaces that have been marked as DELETED for a while now. # This removes network interfaces that have been marked as DELETED for a while now.
clear_old_interfaces($anvil); clear_old_interfaces($anvil);
# Write out the interface cache
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"cache::new_file" => $anvil->data->{cache}{new_file},
"path::data::network_cache" => $anvil->data->{path}{data}{network_cache},
}});
$anvil->Storage->write_file({
body => $anvil->data->{cache}{new_file},
file => $anvil->data->{path}{data}{network_cache},
overwrite => 1,
backup => 0,
});
# Shut down. # Shut down.
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE}); $anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
@ -96,6 +111,66 @@ $anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
# Functions # # Functions #
############################################################################################################# #############################################################################################################
# This reads in the interface cache file and looks for records that haven't been stored in the database yet.
sub process_interface_cache
{
my ($anvil) = @_;
# Does the file exist? If so, read it in.
if (-e $anvil->data->{path}{data}{network_cache})
{
my $body = $anvil->Storage->read_file({debug => 2, cache => 0, force_read => 1, file => $anvil->data->{path}{data}{network_cache}});
foreach my $line (split/\n/, $body)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
next if $line =~ /^#/;
my ($nm_device, $timestamp, $mac_address, $speed, $link_state, $operational, $nm_uuid, $nm_name) = (split/,/, $line);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
timestamp => $timestamp,
speed => $speed,
mac_address => $mac_address,
link_state => $link_state,
operational => $operational,
nm_uuid => $nm_uuid,
nm_device => $nm_device,
}});
if ($anvil->data->{sys}{database}{connections})
{
my ($network_interface_uuid) = $anvil->Database->insert_or_update_network_interfaces({
debug => 2,
link_only => 1,
timestamp => $timestamp,
network_interface_name => $nm_device,
network_interface_link_state => $link_state,
network_interface_mac_address => $mac_address,
network_interface_operational => $operational,
network_interface_speed => $speed,
network_interface_nm_uuid => $nm_uuid,
network_interface_device => $nm_device,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_uuid => $network_interface_uuid }});
if (not $network_interface_uuid)
{
# Failed to update, could be that we cached data for an interface not yet
# seen. If so, the coming scan will add it and this cache should flush out
# next time.
$anvil->data->{cache}{new_file} .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }});
}
}
else
{
# No database, re-cache
$anvil->data->{cache}{new_file} .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }});
}
}
}
return(0);
}
# This removes network interfaces that have been marked as DELETED for a while now. # This removes network interfaces that have been marked as DELETED for a while now.
sub clear_old_interfaces sub clear_old_interfaces
{ {
@ -124,7 +199,7 @@ sub clear_old_interfaces
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}}) foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
uuid => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid})." (".$uuid.")", uuid => $anvil->Database->get_host_from_uuid({debug => 2, short => 1, host_uuid => $uuid})." (".$uuid.")",
}}); }});
my $query = " my $query = "
SELECT SELECT
@ -460,19 +535,12 @@ sub collect_data
{ {
my ($anvil) = @_; my ($anvil) = @_;
$anvil->Network->get_ips({debug => 2}); # Read in data from Network Manager
$anvil->Network->collect_data({debug => 2});
# Read the data from the ifcfg files, if available. We'll use this to check for bond interfaces that
# didn't start.
$anvil->Network->check_network();
my $uptime = $anvil->Get->uptime();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uptime => $uptime }});
if ($uptime < 600)
{
$anvil->Network->read_nmcli({debug => 2})
}
### TODO: We can get the IPs from collect_data, we should phase this out.
# The 'local_host' is needed to pull data recorded by Network->get_ips(); # The 'local_host' is needed to pull data recorded by Network->get_ips();
$anvil->Network->get_ips({debug => 2});
my $local_host = $anvil->Get->short_host_name(); my $local_host = $anvil->Get->short_host_name();
my $directory = "/sys/class/net"; my $directory = "/sys/class/net";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -480,6 +548,7 @@ sub collect_data
directory => $directory, directory => $directory,
}}); }});
### TODO: Convert this to use Sys::Virt
# Make sure there are no virsh bridges, removing any found. # Make sure there are no virsh bridges, removing any found.
my $host_type = $anvil->Get->host_type(); my $host_type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
@ -516,61 +585,11 @@ sub collect_data
set_by => $THIS_FILE, set_by => $THIS_FILE,
}); });
} }
=cut
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-list --all --name";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
# This often hangs.
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if (not $return_code)
{
# Virsh is up.
foreach my $line (split/\n/, $output)
{
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next if not $line;
next if $line =~ /^error/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "striker_0287", variables => { bridge => $line }});
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-destroy ".$line;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-undefine ".$line;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Register an alert
my $variables = {
bridge => $line,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0001", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_network_alert_0001",
variables => $variables,
set_by => $THIS_FILE,
});
}
}
=cut
} }
# Collect data from nmcli
$anvil->Network->collect_data({debug => 2});
# Walk through the sysfs files. # Walk through the sysfs files.
local(*DIRECTORY); local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
@ -584,27 +603,27 @@ sub collect_data
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }});
if (-d $full_path) if (-d $full_path)
{ {
### NOTE: The 'interface' maps to the network manager 'GENERAL.IP-IFACE', which is
### 'network_interface_device'. The 'network_interface_name' is the biosdevname.
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces. # Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
my $interface = $file; my $interface = $file;
my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0; my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
$link_state =~ s/\n$//;
my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0; my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
$mtu =~ s/\n$//;
my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half? my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
$duplex =~ s/\n$//;
my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
$operational =~ s/\n$//;
my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown"; my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
$modalias =~ s/\n$//;
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
my $media = "unknown"; $speed =~ s/\n$//;
my $type = "interface"; my $media = "unknown";
my $driver = ""; my $type = "interface";
my $tx_bytes = 0; # How many bytes transmitted my $driver = "";
my $rx_bytes = 0; # How many bytes received my $tx_bytes = 0; # How many bytes transmitted
my $rx_bytes = 0; # How many bytes received
# Clean up some newlines.
$link_state =~ s/\n$//;
$mtu =~ s/\n$//;
$duplex =~ s/\n$//;
$operational =~ s/\n$//;
$speed =~ s/\n$//;
$modalias =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface, interface => $interface,
link_state => $link_state, link_state => $link_state,
@ -615,6 +634,31 @@ sub collect_data
modalias => $modalias, modalias => $modalias,
}}); }});
# Try to find the nm_uuid
my $nm_uuid = "";
if ((exists $anvil->data->{nmcli}{name}{$interface}) && ($anvil->data->{nmcli}{name}{$interface}{uuid}))
{
$nm_uuid = $anvil->data->{nmcli}{name}{$interface}{uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { nm_uuid => $nm_uuid }});
}
elsif ((exists $anvil->data->{nmcli}{device}{$interface}) && ($anvil->data->{nmcli}{device}{$interface}{uuid}))
{
$nm_uuid = $anvil->data->{nmcli}{device}{$interface}{uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { nm_uuid => $nm_uuid }});
}
my $nm_device = ""; # biosdevname
my $nm_name = ""; # ip name
if ($nm_uuid)
{
$nm_device = $anvil->data->{nmcli}{uuid}{$nm_uuid}{device};
$nm_name = $anvil->data->{nmcli}{uuid}{$nm_uuid}{name};
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
nm_device => $nm_device,
nm_name => $nm_name,
}});
### NOTE: This only parses virtio so far. ### NOTE: This only parses virtio so far.
# Pick out our driver. # Pick out our driver.
if ($modalias =~ /^virtio:/) if ($modalias =~ /^virtio:/)
@ -729,7 +773,12 @@ sub collect_data
{ {
# Yup, we'll neet to dig into the bond proc files to get the proper slaved # Yup, we'll neet to dig into the bond proc files to get the proper slaved
# interface MAC addresses. # interface MAC addresses.
$type = "bond"; $type = "bond";
$nm_uuid = $anvil->data->{nmcli}{bond}{$interface}{uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
type => $type,
nm_uuid => $nm_uuid,
}});
# Read the bond mode. # Read the bond mode.
$bond_mode = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/mode"}); $bond_mode = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/mode"});
@ -777,9 +826,9 @@ sub collect_data
$bridge_stp_enabled =~ s/\n$//; $bridge_stp_enabled =~ s/\n$//;
$speed = 0; $speed = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
type => $type,
bridge_id => $bridge_id, bridge_id => $bridge_id,
bridge_stp_enabled => $bridge_stp_enabled, bridge_stp_enabled => $bridge_stp_enabled,
type => $type,
}}); }});
if ($bridge_stp_enabled eq "0") if ($bridge_stp_enabled eq "0")
{ {
@ -851,7 +900,7 @@ sub collect_data
} }
# Find the media, if possible. # Find the media, if possible.
(my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." $interface"}); (my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." ".$interface});
foreach my $line (split/\n/, $ethtool) foreach my $line (split/\n/, $ethtool)
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
@ -871,6 +920,9 @@ sub collect_data
} }
# Store new information we found. # Store new information we found.
$anvil->data->{network}{$local_host}{interface}{$interface}{nm_uuid} = $nm_uuid;
$anvil->data->{network}{$local_host}{interface}{$interface}{nm_device} = $nm_device;
$anvil->data->{network}{$local_host}{interface}{$interface}{nm_name} = $nm_name;
$anvil->data->{network}{$local_host}{interface}{$interface}{active_interface} = $active_interface; $anvil->data->{network}{$local_host}{interface}{$interface}{active_interface} = $active_interface;
$anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode} = $bond_mode; $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode} = $bond_mode;
$anvil->data->{network}{$local_host}{interface}{$interface}{bond_master} = $bond_master; $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master} = $bond_master;
@ -892,6 +944,9 @@ sub collect_data
$anvil->data->{network}{$local_host}{interface}{$interface}{type} = $type; $anvil->data->{network}{$local_host}{interface}{$interface}{type} = $type;
$anvil->data->{network}{$local_host}{interface}{$interface}{up_delay} = $up_delay; $anvil->data->{network}{$local_host}{interface}{$interface}{up_delay} = $up_delay;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"network::${local_host}::interface::${interface}::nm_uuid" => $anvil->data->{network}{$local_host}{interface}{$interface}{nm_uuid},
"network::${local_host}::interface::${interface}::nm_device" => $anvil->data->{network}{$local_host}{interface}{$interface}{nm_device},
"network::${local_host}::interface::${interface}::nm_name" => $anvil->data->{network}{$local_host}{interface}{$interface}{nm_name},
"network::${local_host}::interface::${interface}::active_interface" => $anvil->data->{network}{$local_host}{interface}{$interface}{active_interface}, "network::${local_host}::interface::${interface}::active_interface" => $anvil->data->{network}{$local_host}{interface}{$interface}{active_interface},
"network::${local_host}::interface::${interface}::bond_mode" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode}, "network::${local_host}::interface::${interface}::bond_mode" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode},
"network::${local_host}::interface::${interface}::bond_master" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master}, "network::${local_host}::interface::${interface}::bond_master" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master},
@ -921,7 +976,12 @@ sub collect_data
# If this is a link and there's no database connections, cache the data. # If this is a link and there's no database connections, cache the data.
if (($type eq "interface") && (not $anvil->data->{sys}{database}{connections})) if (($type eq "interface") && (not $anvil->data->{sys}{database}{connections}))
{ {
$anvil->data->{cache}{new_file} .= $interface.",".$anvil->Database->refresh_timestamp.",".$mac_address.",".$speed.",".$link_state.",".$operational."\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
nm_name => $nm_name,
nm_device => $nm_device,
}});
# nm_device,timestamp,mac_address,speed,link_state,operational,nm_uuid,nm_name
$anvil->data->{cache}{new_file} .= $nm_device.",".$anvil->Database->refresh_timestamp.",".$mac_address.",".$speed.",".$link_state.",".$operational.",".$nm_uuid.",".$nm_name."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cache::new_file" => $anvil->data->{cache}{new_file}, "cache::new_file" => $anvil->data->{cache}{new_file},
}}); }});
@ -950,6 +1010,7 @@ sub collect_data
if ($type eq "bridge") if ($type eq "bridge")
{ {
# Store the bridge # Store the bridge
$anvil->data->{new}{bridge}{$interface}{nm_uuid} = $anvil->data->{network}{$local_host}{interface}{$interface}{nm_uuid};
$anvil->data->{new}{bridge}{$interface}{id} = $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_id}; $anvil->data->{new}{bridge}{$interface}{id} = $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_id};
$anvil->data->{new}{bridge}{$interface}{mac_address} = $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address}; $anvil->data->{new}{bridge}{$interface}{mac_address} = $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address};
$anvil->data->{new}{bridge}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu}; $anvil->data->{new}{bridge}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu};
@ -957,6 +1018,7 @@ sub collect_data
$anvil->data->{new}{bridge}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes}; $anvil->data->{new}{bridge}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
$anvil->data->{new}{bridge}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes}; $anvil->data->{new}{bridge}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::bridge::${interface}::nm_uuid" => $anvil->data->{new}{bridge}{$interface}{nm_uuid},
"new::bridge::${interface}::id" => $anvil->data->{new}{bridge}{$interface}{id}, "new::bridge::${interface}::id" => $anvil->data->{new}{bridge}{$interface}{id},
"new::bridge::${interface}::mac_address" => $anvil->data->{new}{bridge}{$interface}{mac_address}, "new::bridge::${interface}::mac_address" => $anvil->data->{new}{bridge}{$interface}{mac_address},
"new::bridge::${interface}::mtu" => $anvil->data->{new}{bridge}{$interface}{mtu}, "new::bridge::${interface}::mtu" => $anvil->data->{new}{bridge}{$interface}{mtu},
@ -968,6 +1030,7 @@ sub collect_data
elsif ($type eq "bond") elsif ($type eq "bond")
{ {
# Store the bond # Store the bond
$anvil->data->{new}{bond}{$interface}{nm_uuid} = $anvil->data->{network}{$local_host}{interface}{$interface}{nm_uuid};
$anvil->data->{new}{bond}{$interface}{mode} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode}; $anvil->data->{new}{bond}{$interface}{mode} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode};
$anvil->data->{new}{bond}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu}; $anvil->data->{new}{bond}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu};
$anvil->data->{new}{bond}{$interface}{master} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master}; $anvil->data->{new}{bond}{$interface}{master} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master};
@ -984,6 +1047,7 @@ sub collect_data
$anvil->data->{new}{bond}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes}; $anvil->data->{new}{bond}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
$anvil->data->{new}{bond}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes}; $anvil->data->{new}{bond}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::bond::${interface}::nm_uuid" => $anvil->data->{new}{bond}{$interface}{nm_uuid},
"new::bond::${interface}::mode" => $anvil->data->{new}{bond}{$interface}{mode}, "new::bond::${interface}::mode" => $anvil->data->{new}{bond}{$interface}{mode},
"new::bond::${interface}::mtu" => $anvil->data->{new}{bond}{$interface}{mtu}, "new::bond::${interface}::mtu" => $anvil->data->{new}{bond}{$interface}{mtu},
"new::bond::${interface}::master" => $anvil->data->{new}{bond}{$interface}{master}, "new::bond::${interface}::master" => $anvil->data->{new}{bond}{$interface}{master},
@ -1004,6 +1068,9 @@ sub collect_data
elsif ($type eq "interface") elsif ($type eq "interface")
{ {
# Store the interface # Store the interface
$anvil->data->{new}{interface}{$interface}{nm_uuid} = $anvil->data->{network}{$local_host}{interface}{$interface}{nm_uuid};
$anvil->data->{new}{interface}{$interface}{nm_device} = $anvil->data->{network}{$local_host}{interface}{$interface}{nm_device};
$anvil->data->{new}{interface}{$interface}{nm_name} = $anvil->data->{network}{$local_host}{interface}{$interface}{nm_name};
$anvil->data->{new}{interface}{$interface}{bond_uuid} = ""; $anvil->data->{new}{interface}{$interface}{bond_uuid} = "";
$anvil->data->{new}{interface}{$interface}{bond_name} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master}; $anvil->data->{new}{interface}{$interface}{bond_name} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master};
$anvil->data->{new}{interface}{$interface}{bridge_uuid} = ""; $anvil->data->{new}{interface}{$interface}{bridge_uuid} = "";
@ -1018,6 +1085,9 @@ sub collect_data
$anvil->data->{new}{interface}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes}; $anvil->data->{new}{interface}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
$anvil->data->{new}{interface}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes}; $anvil->data->{new}{interface}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::interface::${interface}::nm_uuid" => $anvil->data->{new}{interface}{$interface}{nm_uuid},
"new::interface::${interface}::nm_device" => $anvil->data->{new}{interface}{$interface}{nm_device},
"new::interface::${interface}::nm_name" => $anvil->data->{new}{interface}{$interface}{nm_name},
"new::interface::${interface}::bond_uuid" => $anvil->data->{new}{interface}{$interface}{bond_uuid}, "new::interface::${interface}::bond_uuid" => $anvil->data->{new}{interface}{$interface}{bond_uuid},
"new::interface::${interface}::bond_name" => $anvil->data->{new}{interface}{$interface}{bond_name}, "new::interface::${interface}::bond_name" => $anvil->data->{new}{interface}{$interface}{bond_name},
"new::interface::${interface}::bridge_uuid" => $anvil->data->{new}{interface}{$interface}{bridge_uuid}, "new::interface::${interface}::bridge_uuid" => $anvil->data->{new}{interface}{$interface}{bridge_uuid},
@ -1032,48 +1102,6 @@ sub collect_data
"new::interface::${interface}::tx_bytes" => $anvil->data->{new}{interface}{$interface}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{tx_bytes}}).")", "new::interface::${interface}::tx_bytes" => $anvil->data->{new}{interface}{$interface}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{tx_bytes}}).")",
"new::interface::${interface}::rx_bytes" => $anvil->data->{new}{interface}{$interface}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{rx_bytes}}).")", "new::interface::${interface}::rx_bytes" => $anvil->data->{new}{interface}{$interface}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{rx_bytes}}).")",
}}); }});
# On some occassions, an interface that is in a bond won't start. If the host uptime
# is less than ten minutes, and a bond's member interface is down, up it.
if ($uptime < 600)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"nmcli::${local_host}::device_to_uuid::${interface}" => $anvil->data->{nmcli}{$local_host}{device_to_uuid}{$interface},
}});
my $uuid = $anvil->data->{nmcli}{$local_host}{device_to_uuid}{$interface};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
if ($uuid)
{
my $state = $anvil->data->{nmcli}{$local_host}{uuid}{$uuid}{'state'};
my $filename = $anvil->data->{nmcli}{$local_host}{uuid}{$uuid}{filename};
my $name = ($filename =~ /ifcfg-(.*?)$/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
filename => $filename,
name => $name,
'state' => $state,
}});
# This could be 'active' or 'activated'
if ($state !~ /activ/)
{
# Try brinding the interface up.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0147", variables => {
interface => $interface,
uptime => $uptime,
'state' => $state,
}});
my $shell_call = $anvil->data->{path}{exe}{ifup}." ".$name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
}
}
} }
# Record the IP address info. # Record the IP address info.
@ -1097,7 +1125,7 @@ sub collect_data
}}); }});
} }
} }
return(0); return(0);
} }
@ -1778,9 +1806,11 @@ sub load_interface_data
# Process interfaces # Process interfaces
my $query = " my $query = "
SELECT SELECT
network_interface_uuid, network_interface_uuid,
network_interface_nm_uuid,
network_interface_mac_address, network_interface_mac_address,
network_interface_name, network_interface_name,
network_interface_device,
network_interface_speed, network_interface_speed,
network_interface_mtu, network_interface_mtu,
network_interface_link_state, network_interface_link_state,
@ -1805,12 +1835,14 @@ WHERE
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
my $network_interface_uuid = $row->[0]; my $network_interface_uuid = $row->[0];
my $network_interface_mac_address = $row->[1]; my $network_interface_mac_address = $row->[2];
my $network_interface_name = $row->[2]; my $network_interface_name = $row->[3];
my $network_interface_device = $row->[4];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_interface_uuid => $network_interface_uuid, network_interface_uuid => $network_interface_uuid,
network_interface_mac_address => $network_interface_mac_address, network_interface_mac_address => $network_interface_mac_address,
network_interface_name => $network_interface_name, network_interface_name => $network_interface_name,
network_interface_device => $network_interface_device,
}}); }});
# Read in the RX/TX values, set to '0' if not found. # Read in the RX/TX values, set to '0' if not found.
@ -1833,23 +1865,27 @@ WHERE
tx_variable_uuid => $tx_variable_uuid, tx_variable_uuid => $tx_variable_uuid,
}}); }});
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_nm_uuid} = $row->[1];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address} = $network_interface_mac_address; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address} = $network_interface_mac_address;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed} = $row->[3]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_device} = $network_interface_device;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu} = $row->[4]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed} = $row->[5];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state} = $row->[5]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu} = $row->[6];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational} = $row->[6]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state} = $row->[7];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex} = $row->[7]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational} = $row->[8];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium} = $row->[8]; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex} = $row->[9];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid} = defined $row->[9] ? $row->[9] : ''; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium} = $row->[10];
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid} = defined $row->[10] ? $row->[10] : ''; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid} = defined $row->[11] ? $row->[11] : '';
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid} = defined $row->[12] ? $row->[12] : '';
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes} = $rx_bytes =~ /^\d+$/ ? $rx_bytes : 0; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes} = $rx_bytes =~ /^\d+$/ ? $rx_bytes : 0;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid} = $rx_variable_uuid; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid} = $rx_variable_uuid;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes} = $tx_bytes =~ /^\d+$/ ? $tx_bytes : 0; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes} = $tx_bytes =~ /^\d+$/ ? $tx_bytes : 0;
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid} = $tx_variable_uuid; $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid} = $tx_variable_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_nm_uuid" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_nm_uuid},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address}, "old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name}, "old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_device" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_device},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_speed" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed}, "old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_speed" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mtu" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu}, "old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mtu" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu},
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_link_state" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state}, "old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_link_state" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state},
@ -1865,14 +1901,18 @@ WHERE
}}); }});
$anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name} = $network_interface_uuid; $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
$anvil->data->{network_interfaces}{device_to_uuid}{$network_interface_device} = $network_interface_uuid;
$anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name; $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name;
$anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address} = $network_interface_uuid; $anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address} = $network_interface_uuid;
$anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid; $anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
$anvil->data->{interface}{device_to_uuid}{$network_interface_device} = $network_interface_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name}, "network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name},
"network_interfaces::device_to_uuid::${network_interface_device}" => $anvil->data->{network_interfaces}{device_to_uuid}{$network_interface_device},
"network_interfaces::uuid_to_name::${network_interface_name}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid}, "network_interfaces::uuid_to_name::${network_interface_name}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid},
"network_interfaces::mac_to_uuid::${network_interface_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address}, "network_interfaces::mac_to_uuid::${network_interface_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address},
"interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name}, "interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name},
"interface::device_to_uuid::${network_interface_device}" => $anvil->data->{interface}{device_to_uuid}{$network_interface_device},
}}); }});
} }
@ -2105,7 +2145,6 @@ sub check_ip_addresses
{ {
my $on_interface = $anvil->data->{new}{ip_address}{$ip_address}{on_interface}; my $on_interface = $anvil->data->{new}{ip_address}{$ip_address}{on_interface};
my $new_on_type = $anvil->data->{interface}{name_to_type}{$on_interface}; my $new_on_type = $anvil->data->{interface}{name_to_type}{$on_interface};
my $new_on_uuid = $anvil->data->{interface}{name_to_uuid}{$on_interface};
my $new_subnet_mask = $anvil->data->{new}{ip_address}{$ip_address}{subnet_mask}; my $new_subnet_mask = $anvil->data->{new}{ip_address}{$ip_address}{subnet_mask};
my $new_gateway = $anvil->data->{new}{ip_address}{$ip_address}{gateway}; my $new_gateway = $anvil->data->{new}{ip_address}{$ip_address}{gateway};
my $new_default_gateway = $anvil->data->{new}{ip_address}{$ip_address}{default_gateway}; my $new_default_gateway = $anvil->data->{new}{ip_address}{$ip_address}{default_gateway};
@ -2114,12 +2153,22 @@ sub check_ip_addresses
ip_address => $ip_address, ip_address => $ip_address,
on_interface => $on_interface, on_interface => $on_interface,
new_on_type => $new_on_type, new_on_type => $new_on_type,
new_on_uuid => $new_on_uuid,
new_subnet_mask => $new_subnet_mask, new_subnet_mask => $new_subnet_mask,
new_gateway => $new_gateway, new_gateway => $new_gateway,
new_default_gateway => $new_default_gateway, new_default_gateway => $new_default_gateway,
new_dns => $new_dns, new_dns => $new_dns,
}}); }});
my $new_on_uuid = "";
if ($anvil->data->{interface}{name_to_uuid}{$on_interface})
{
$new_on_uuid = $anvil->data->{interface}{name_to_uuid}{$on_interface};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_on_uuid => $new_on_uuid }});
}
elsif ($anvil->data->{interface}{device_to_uuid}{$on_interface})
{
$new_on_uuid = $anvil->data->{interface}{device_to_uuid}{$on_interface};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_on_uuid => $new_on_uuid }});
}
if (exists $anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address}) if (exists $anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address})
{ {
@ -2381,8 +2430,13 @@ sub check_interfaces
{ {
my ($anvil) = @_; my ($anvil) = @_;
my $interfaces = keys %{$anvil->data->{new}{interface}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interfaces => $interfaces }});
foreach my $network_interface_name (sort {$a cmp $b} keys %{$anvil->data->{new}{interface}}) foreach my $network_interface_name (sort {$a cmp $b} keys %{$anvil->data->{new}{interface}})
{ {
my $new_nm_uuid = $anvil->data->{new}{interface}{$network_interface_name}{nm_uuid};
my $new_nm_name = $anvil->data->{new}{interface}{$network_interface_name}{nm_name};
my $new_nm_device = $anvil->data->{new}{interface}{$network_interface_name}{nm_device};
my $new_bond_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bond_uuid}; my $new_bond_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bond_uuid};
my $new_bond_name = $anvil->data->{new}{interface}{$network_interface_name}{bond_name}; my $new_bond_name = $anvil->data->{new}{interface}{$network_interface_name}{bond_name};
my $new_bridge_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bridge_uuid}; my $new_bridge_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bridge_uuid};
@ -2398,6 +2452,9 @@ sub check_interfaces
my $new_rx_bytes = $anvil->data->{new}{interface}{$network_interface_name}{rx_bytes}; my $new_rx_bytes = $anvil->data->{new}{interface}{$network_interface_name}{rx_bytes};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_interface_name => $network_interface_name, network_interface_name => $network_interface_name,
new_nm_uuid => $new_nm_uuid,
new_nm_name => $new_nm_name,
new_nm_device => $new_nm_device,
new_bond_uuid => $new_bond_uuid, new_bond_uuid => $new_bond_uuid,
new_bond_name => $new_bond_name, new_bond_name => $new_bond_name,
new_bridge_uuid => $new_bridge_uuid, new_bridge_uuid => $new_bridge_uuid,
@ -2431,26 +2488,45 @@ sub check_interfaces
} }
# New or existing? # New or existing?
my $network_interface_uuid = "";
if (exists $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name}) if (exists $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name})
{
$network_interface_uuid = $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
}
elsif (exists $anvil->data->{network_interfaces}{device_to_uuid}{$network_interface_name})
{
$network_interface_uuid = $anvil->data->{network_interfaces}{device_to_uuid}{$network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
}
elsif (($new_mac_address) && (exists $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address}))
{
$network_interface_uuid = $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
}
if ($network_interface_uuid)
{ {
# Existing. Changes? # Existing. Changes?
my $network_interface_uuid = $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name}; my $old_nm_name = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name};
my $old_bond_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid}; my $old_nm_device = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_device};
my $old_bond_name = ""; my $old_bond_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid};
my $old_bridge_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid}; my $old_bond_name = "";
my $old_bridge_name = ""; my $old_bridge_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid};
my $old_duplex = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex}; my $old_bridge_name = "";
my $old_link_state = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state}; my $old_duplex = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex};
my $old_operational = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational}; my $old_link_state = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state};
my $old_mac_address = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address}; my $old_operational = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational};
my $old_medium = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium}; my $old_mac_address = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address};
my $old_mtu = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu}; my $old_medium = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium};
my $old_speed = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed}; my $old_mtu = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu};
my $old_rx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes}; my $old_speed = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed};
my $rx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid}; my $old_rx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes};
my $old_tx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes}; my $rx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid};
my $tx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid}; my $old_tx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes};
my $tx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_nm_name => $old_nm_name,
old_nm_device => $old_nm_device,
old_bond_uuid => $old_bond_uuid, old_bond_uuid => $old_bond_uuid,
old_bridge_uuid => $old_bridge_uuid, old_bridge_uuid => $old_bridge_uuid,
old_duplex => $old_duplex, old_duplex => $old_duplex,
@ -2484,6 +2560,52 @@ sub check_interfaces
# Look for changes. # Look for changes.
my $changes = 0; my $changes = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_nm_name => $new_nm_name,
old_nm_name => $old_nm_name,
}});
if ($new_nm_name ne $old_nm_name)
{
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
my $variables = {
name => $network_interface_name,
old => $old_nm_name,
new => $new_nm_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0062", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_network_alert_0062",
variables => $variables,
set_by => $THIS_FILE,
});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_nm_device => $new_nm_device,
old_nm_device => $old_nm_device,
}});
if ($new_nm_device ne $old_nm_device)
{
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
my $variables = {
name => $network_interface_name,
old => $old_nm_device,
new => $new_nm_device,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0063", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_network_alert_0063",
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($new_bond_uuid ne $old_bond_uuid) if ($new_bond_uuid ne $old_bond_uuid)
{ {
# We're making this a warning level alert as it should not be changing. # We're making this a warning level alert as it should not be changing.
@ -2813,11 +2935,17 @@ sub check_interfaces
if ($changes) if ($changes)
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_nm_name => $new_nm_name,
new_nm_device => $new_nm_device,
}});
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({ my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
debug => 2, debug => 2,
network_interface_nm_uuid => $new_nm_uuid,
network_interface_bond_uuid => $new_bond_uuid, network_interface_bond_uuid => $new_bond_uuid,
network_interface_bridge_uuid => $new_bridge_uuid, network_interface_bridge_uuid => $new_bridge_uuid,
network_interface_name => $network_interface_name, network_interface_name => $new_nm_name, # biosdevname
network_interface_device => $new_nm_device, # ip name
network_interface_duplex => $new_duplex, network_interface_duplex => $new_duplex,
network_interface_link_state => $new_link_state, network_interface_link_state => $new_link_state,
network_interface_operational => $new_operational, network_interface_operational => $new_operational,
@ -2946,11 +3074,18 @@ sub check_interfaces
else else
{ {
# Record the interface # Record the interface
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_nm_name => $new_nm_name,
network_interface_name => $network_interface_name,
new_nm_device => $new_nm_device,
}});
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({ my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
debug => 2, debug => 2,
network_interface_nm_uuid => $new_nm_uuid,
network_interface_bond_uuid => $new_bond_uuid, network_interface_bond_uuid => $new_bond_uuid,
network_interface_bridge_uuid => $new_bridge_uuid, network_interface_bridge_uuid => $new_bridge_uuid,
network_interface_name => $network_interface_name, network_interface_name => $new_nm_name,
network_interface_device => $network_interface_name,
network_interface_duplex => $new_duplex, network_interface_duplex => $new_duplex,
network_interface_link_state => $new_link_state, network_interface_link_state => $new_link_state,
network_interface_operational => $new_operational, network_interface_operational => $new_operational,
@ -2966,11 +3101,13 @@ sub check_interfaces
$anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name; $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name;
$anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address} = $network_interface_uuid; $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address} = $network_interface_uuid;
$anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid; $anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
$anvil->data->{interface}{device_to_uuid}{$new_nm_device} = $network_interface_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name}, "network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name},
"network_interfaces::uuid_to_name::${network_interface_uuid}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid}, "network_interfaces::uuid_to_name::${network_interface_uuid}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid},
"network_interfaces::mac_to_uuid::${new_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address}, "network_interfaces::mac_to_uuid::${new_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address},
"interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name}, "interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name},
"interface::device_to_uuid::${new_nm_device}" => $anvil->data->{interface}{device_to_uuid}{$new_nm_device},
}}); }});
# Store the rx_bytes and tx_bytes # Store the rx_bytes and tx_bytes
@ -3079,6 +3216,7 @@ sub check_bonds
foreach my $bond_name (sort {$a cmp $b} keys %{$anvil->data->{new}{bond}}) foreach my $bond_name (sort {$a cmp $b} keys %{$anvil->data->{new}{bond}})
{ {
# Store the bond # Store the bond
my $new_nm_uuid = $anvil->data->{new}{bond}{$bond_name}{nm_uuid};
my $new_mode = $anvil->data->{new}{bond}{$bond_name}{mode}; my $new_mode = $anvil->data->{new}{bond}{$bond_name}{mode};
my $new_mtu = $anvil->data->{new}{bond}{$bond_name}{mtu}; my $new_mtu = $anvil->data->{new}{bond}{$bond_name}{mtu};
my $new_operational = $anvil->data->{new}{bond}{$bond_name}{operational}; my $new_operational = $anvil->data->{new}{bond}{$bond_name}{operational};
@ -3449,6 +3587,7 @@ sub check_bonds
{ {
my $bond_uuid = $anvil->Database->insert_or_update_bonds({ my $bond_uuid = $anvil->Database->insert_or_update_bonds({
debug => 2, debug => 2,
bond_nm_uuid => $new_nm_uuid,
bond_name => $bond_name, bond_name => $bond_name,
bond_mode => $new_mode, bond_mode => $new_mode,
bond_mtu => $new_mtu, bond_mtu => $new_mtu,

@ -133,6 +133,8 @@ Note: If this is a Storage Network directly connected to the peer, and the peer
<key name="scan_network_alert_0059">The network interface: [#!variable!name!#] appears to have been removed. The last time we saw it, it had transmitted: [#!variable!tx!#] and received: [#!variable!rx!#].</key> <key name="scan_network_alert_0059">The network interface: [#!variable!name!#] appears to have been removed. The last time we saw it, it had transmitted: [#!variable!tx!#] and received: [#!variable!rx!#].</key>
<key name="scan_network_alert_0060">The IP address: [#!variable!ip!#] appears to no longer be used on this machine.</key> <key name="scan_network_alert_0060">The IP address: [#!variable!ip!#] appears to no longer be used on this machine.</key>
<key name="scan_network_alert_0061">The network interface: [#!variable!name!#] MAC address has changed from: [#!variable!old!#] to: [#!variable!new!#]. This is normal when a server boots or migrates.</key> <key name="scan_network_alert_0061">The network interface: [#!variable!name!#] MAC address has changed from: [#!variable!old!#] to: [#!variable!new!#]. This is normal when a server boots or migrates.</key>
<key name="scan_network_alert_0062">The network interface: [#!variable!name!#] network manager's 'connection.id' name (biosdevname) has changed from: [#!variable!old!#] to: [#!variable!new!#].</key>
<key name="scan_network_alert_0063">The network interface: [#!variable!name!#] network manager's 'GENERAL.IP-IFACE' name (ip addr name) has changed from: [#!variable!old!#] to: [#!variable!new!#].</key>
<!-- Error entries --> <!-- Error entries -->
<key name="scan_network_error_0001">Failed to read the network interface speed from the file: [#!variable!file!#]. Ignoring interface.</key> <key name="scan_network_error_0001">Failed to read the network interface speed from the file: [#!variable!file!#]. Ignoring interface.</key>

@ -856,6 +856,7 @@ sub collect_data
new_anvil_name => $anvil->Get->anvil_name_from_uuid({anvil_uuid => $server_anvil_uuid}), new_anvil_name => $anvil->Get->anvil_name_from_uuid({anvil_uuid => $server_anvil_uuid}),
new_anvil_uuid => $server_anvil_uuid, new_anvil_uuid => $server_anvil_uuid,
}; };
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_server_alert_0009", variables => $variables}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_server_alert_0009", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_server_alert_0009", variables => $variables, set_by => $THIS_FILE}); $anvil->Alert->register({alert_level => "notice", message => "scan_server_alert_0009", variables => $variables, set_by => $THIS_FILE});
$update = 1; $update = 1;

@ -855,6 +855,7 @@ CREATE TRIGGER trigger_jobs
CREATE TABLE bridges ( CREATE TABLE bridges (
bridge_uuid uuid not null primary key, bridge_uuid uuid not null primary key,
bridge_host_uuid uuid not null, bridge_host_uuid uuid not null,
bridge_nm_uuid uuid, -- This is the network manager UUID for this bridge interface
bridge_name text not null, bridge_name text not null,
bridge_id text not null, bridge_id text not null,
bridge_mac_address text not null, bridge_mac_address text not null,
@ -870,6 +871,7 @@ CREATE TABLE history.bridges (
history_id bigserial, history_id bigserial,
bridge_uuid uuid, bridge_uuid uuid,
bridge_host_uuid uuid, bridge_host_uuid uuid,
bridge_nm_uuid uuid,
bridge_name text, bridge_name text,
bridge_id text, bridge_id text,
bridge_mac_address text, bridge_mac_address text,
@ -888,6 +890,7 @@ BEGIN
INSERT INTO history.bridges INSERT INTO history.bridges
(bridge_uuid, (bridge_uuid,
bridge_host_uuid, bridge_host_uuid,
bridge_nm_uuid,
bridge_name, bridge_name,
bridge_id, bridge_id,
bridge_mac_address, bridge_mac_address,
@ -897,6 +900,7 @@ BEGIN
VALUES VALUES
(history_bridges.bridge_uuid, (history_bridges.bridge_uuid,
history_bridges.bridge_host_uuid, history_bridges.bridge_host_uuid,
history_bridges.bridge_nm_uuid,
history_bridges.bridge_name, history_bridges.bridge_name,
history_bridges.bridge_id, history_bridges.bridge_id,
history_bridges.bridge_mac_address, history_bridges.bridge_mac_address,
@ -918,6 +922,7 @@ CREATE TRIGGER trigger_bridges
CREATE TABLE bonds ( CREATE TABLE bonds (
bond_uuid uuid not null primary key, bond_uuid uuid not null primary key,
bond_host_uuid uuid not null, bond_host_uuid uuid not null,
bond_nm_uuid uuid, -- The is the network manager UUID for this bond.
bond_name text not null, bond_name text not null,
bond_mode text not null, -- This is the numerical bond type (will translate to the user's language in the Anvil!) bond_mode text not null, -- This is the numerical bond type (will translate to the user's language in the Anvil!)
bond_mtu bigint not null, bond_mtu bigint not null,
@ -941,6 +946,7 @@ CREATE TABLE history.bonds (
history_id bigserial, history_id bigserial,
bond_uuid uuid, bond_uuid uuid,
bond_host_uuid uuid, bond_host_uuid uuid,
bond_nm_uuid uuid,
bond_name text, bond_name text,
bond_mode text, bond_mode text,
bond_mtu bigint, bond_mtu bigint,
@ -964,8 +970,9 @@ DECLARE
BEGIN BEGIN
SELECT INTO history_bonds * FROM bonds WHERE bond_uuid = new.bond_uuid; SELECT INTO history_bonds * FROM bonds WHERE bond_uuid = new.bond_uuid;
INSERT INTO history.bonds INSERT INTO history.bonds
(bond_uuid, (bond_uuid,
bond_host_uuid, bond_host_uuid,
bond_nm_uuid,
bond_name, bond_name,
bond_mode, bond_mode,
bond_mtu, bond_mtu,
@ -980,8 +987,9 @@ BEGIN
bond_bridge_uuid, bond_bridge_uuid,
modified_date) modified_date)
VALUES VALUES
(history_bonds.bond_uuid, (history_bonds.bond_uuid,
history_bonds.bond_host_uuid, history_bonds.bond_host_uuid,
history_bonds.bond_nm_uuid,
history_bonds.bond_name, history_bonds.bond_name,
history_bonds.bond_mode, history_bonds.bond_mode,
history_bonds.bond_mtu, history_bonds.bond_mtu,
@ -1011,8 +1019,10 @@ CREATE TRIGGER trigger_bonds
CREATE TABLE network_interfaces ( CREATE TABLE network_interfaces (
network_interface_uuid uuid not null primary key, network_interface_uuid uuid not null primary key,
network_interface_host_uuid uuid not null, network_interface_host_uuid uuid not null,
network_interface_mac_address text not null, network_interface_nm_uuid uuid, -- This is the network manager UUID used to track the device. It can change, so we can't used this as the main UUID
network_interface_name text not null, -- This is the current name of the interface. network_interface_mac_address text not null, -- This is the interface MAC address, and it can change if a failed controller it replaced.
network_interface_name text not null, -- This is the current name (network manager's connection.id) of the interface.
network_interface_device text not null, -- This is the current device name (network manager's GENERAL.IP-IFACE) of the interface.
network_interface_speed bigint not null, -- This is the speed, in bits-per-second, of the interface. network_interface_speed bigint not null, -- This is the speed, in bits-per-second, of the interface.
network_interface_mtu bigint not null, -- This is the MTU (Maximum Transmitable Size), in bytes, for this interface. network_interface_mtu bigint not null, -- This is the MTU (Maximum Transmitable Size), in bytes, for this interface.
network_interface_link_state text not null, -- 0 or 1 network_interface_link_state text not null, -- 0 or 1
@ -1033,8 +1043,10 @@ CREATE TABLE history.network_interfaces (
history_id bigserial, history_id bigserial,
network_interface_uuid uuid not null, network_interface_uuid uuid not null,
network_interface_host_uuid uuid, network_interface_host_uuid uuid,
network_interface_nm_uuid uuid,
network_interface_mac_address text, network_interface_mac_address text,
network_interface_name text, network_interface_name text,
network_interface_device text,
network_interface_speed bigint, network_interface_speed bigint,
network_interface_mtu bigint, network_interface_mtu bigint,
network_interface_link_state text, network_interface_link_state text,
@ -1056,8 +1068,10 @@ BEGIN
INSERT INTO history.network_interfaces INSERT INTO history.network_interfaces
(network_interface_uuid, (network_interface_uuid,
network_interface_host_uuid, network_interface_host_uuid,
network_interface_nm_uuid,
network_interface_mac_address, network_interface_mac_address,
network_interface_name, network_interface_name,
network_interface_device,
network_interface_speed, network_interface_speed,
network_interface_mtu, network_interface_mtu,
network_interface_link_state, network_interface_link_state,
@ -1070,8 +1084,10 @@ BEGIN
VALUES VALUES
(history_network_interfaces.network_interface_uuid, (history_network_interfaces.network_interface_uuid,
history_network_interfaces.network_interface_host_uuid, history_network_interfaces.network_interface_host_uuid,
history_network_interfaces.network_interface_nm_uuid,
history_network_interfaces.network_interface_mac_address, history_network_interfaces.network_interface_mac_address,
history_network_interfaces.network_interface_name, history_network_interfaces.network_interface_name,
history_network_interfaces.network_interface_device,
history_network_interfaces.network_interface_speed, history_network_interfaces.network_interface_speed,
history_network_interfaces.network_interface_mtu, history_network_interfaces.network_interface_mtu,
history_network_interfaces.network_interface_link_state, history_network_interfaces.network_interface_link_state,
@ -1096,7 +1112,7 @@ CREATE TRIGGER trigger_network_interfaces
CREATE TABLE ip_addresses ( CREATE TABLE ip_addresses (
ip_address_uuid uuid not null primary key, ip_address_uuid uuid not null primary key,
ip_address_host_uuid uuid not null, ip_address_host_uuid uuid not null,
ip_address_on_type text not null, -- Either 'interface', 'bond' or 'bridge' ip_address_on_type text not null, -- Either 'interface', 'bond', 'bridge' or 'network_manager'
ip_address_on_uuid uuid not null, -- This is the UUID of the interface, bond or bridge that has this IP ip_address_on_uuid uuid not null, -- This is the UUID of the interface, bond or bridge that has this IP
ip_address_address text not null, -- The actual IP address ip_address_address text not null, -- The actual IP address
ip_address_subnet_mask text not null, -- The subnet mask (in dotted decimal format) ip_address_subnet_mask text not null, -- The subnet mask (in dotted decimal format)
@ -1167,6 +1183,91 @@ CREATE TRIGGER trigger_ip_addresses
FOR EACH ROW EXECUTE PROCEDURE history_ip_addresses(); FOR EACH ROW EXECUTE PROCEDURE history_ip_addresses();
/*
TODO - This will be added only if we need to use it if the existing network tables aren't sufficient
-- This stores information about network interfaces on hosts. It is mainly used to match a MAC address to a
-- host. Given that it is possible that network devices can move, the linkage to the host_uuid can change.
CREATE TABLE network_manager (
network_manager_uuid uuid not null primary key, -- Unlike most other tables, this UUID comes from nmcli itself, and so this matches what's displayed nmcli
network_manager_host_uuid uuid not null, -- The host_uuid for this interface
network_manager_device text not null, -- This is the nmcli "device" name
network_manager_name text not null, -- This is the nmcli "name" name
network_manager_mac text not null, -- This is the MAC address of the interface
network_manager_type text not null, -- This is the nmcli "type" string
network_manager_active text not null, -- This is the nmcli "active" field
network_manager_state text not null, -- This is the nmcli "state" field
network_manager_connected numeric not null, -- This is '0' if the connection is down, or a unix timestamp if it's up.
network_manager_mtu numeric not null, -- This is the MTU of the interface
modified_date timestamp with time zone not null,
FOREIGN KEY(network_manager_host_uuid) REFERENCES hosts(host_uuid)
);
ALTER TABLE network_manager OWNER TO admin;
CREATE TABLE history.network_manager (
history_id bigserial,
network_manager_uuid uuid not null,
network_manager_host_uuid uuid,
network_manager_mac_address text,
network_manager_name text,
network_manager_speed bigint,
network_manager_mtu bigint,
network_manager_link_state text,
network_manager_operational text,
network_manager_duplex text,
network_manager_medium text,
network_manager_bond_uuid uuid,
network_manager_bridge_uuid uuid,
modified_date timestamp with time zone not null
);
ALTER TABLE history.network_manager OWNER TO admin;
CREATE FUNCTION history_network_manager() RETURNS trigger
AS $$
DECLARE
history_network_manager RECORD;
BEGIN
SELECT INTO history_network_manager * FROM network_manager WHERE network_manager_uuid = new.network_manager_uuid;
INSERT INTO history.network_manager
(network_manager_uuid,
network_manager_host_uuid,
network_manager_mac_address,
network_manager_name,
network_manager_speed,
network_manager_mtu,
network_manager_link_state,
network_manager_operational,
network_manager_duplex,
network_manager_medium,
network_manager_bond_uuid,
network_manager_bridge_uuid,
modified_date)
VALUES
(history_network_manager.network_manager_uuid,
history_network_manager.network_manager_host_uuid,
history_network_manager.network_manager_mac_address,
history_network_manager.network_manager_name,
history_network_manager.network_manager_speed,
history_network_manager.network_manager_mtu,
history_network_manager.network_manager_link_state,
history_network_manager.network_manager_operational,
history_network_manager.network_manager_duplex,
history_network_manager.network_manager_medium,
history_network_manager.network_manager_bond_uuid,
history_network_manager.network_manager_bridge_uuid,
history_network_manager.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_network_manager() OWNER TO admin;
CREATE TRIGGER trigger_network_manager
AFTER INSERT OR UPDATE ON network_manager
FOR EACH ROW EXECUTE PROCEDURE history_network_manager();
*/
-- This stores files made available to Anvil! systems and DR hosts. -- This stores files made available to Anvil! systems and DR hosts.
CREATE TABLE files ( CREATE TABLE files (
file_uuid uuid not null primary key, file_uuid uuid not null primary key,

@ -752,6 +752,33 @@ The XML that failed sanity check was:
<key name="error_0477">[ Error ] - The requested number of cores: [#!variable!requested_cores!#] (sockets: [#!variable!new_sockets!], cores per socket: [#!variable!new_cores!#], threads per core: [#!variable!new_threads!#]).</key> <key name="error_0477">[ Error ] - The requested number of cores: [#!variable!requested_cores!#] (sockets: [#!variable!new_sockets!], cores per socket: [#!variable!new_cores!#], threads per core: [#!variable!new_threads!#]).</key>
<key name="error_0478">[ Error ] - This program must be run on a subnode.</key> <key name="error_0478">[ Error ] - This program must be run on a subnode.</key>
<key name="error_0479">[ Error ] - This subnode is not in the cluster (failed to parse the CIB). Exiting.</key> <key name="error_0479">[ Error ] - This subnode is not in the cluster (failed to parse the CIB). Exiting.</key>
<key name="error_0480">[ Error ] - The wanted interface: [#!variable!interface_name!#] which should have the MAC address: [#!variable!mac_address!#] was not found in Network Manager. Unable to proceed.</key>
<key name="error_0481">[ Error ] - Failed to delete the 'connection.interface-name', got: [#!variable!output!#] and it should bhave been blank, aborting!</key>
<key name="error_0482">[ Error ] - Failed to create the 'match.interface-name' value. Expected: [#!variable!new_name!#,#!variable!old_device!#], got: [#!variable!output!#], aborting!</key>
<key name="error_0483">[ Error ] - The attempt to add the bond: [#!variable!bond_name!#] failed! The return code was: [#!variable!return_code!#]. The output, if any, was:
========
#!variable!output!#
========
</key>
<key name="error_0484">[ Error ] - The attempt to add the network link: [#!variable!link_name!#] to the bond: [#!variable!bond_name!#] failed! The return code was: [#!variable!return_code!#]. The output, if any, was:
========
#!variable!output!#
========
</key>
<key name="error_0485">[ Error ] - The attempt to add the bridge: [#!variable!bridge_name!# failed! The return code was: [#!variable!return_code!#]. The output, if any, was:
========
#!variable!output!#
========
</key>
<key name="error_0486">[ Error ] - The attempt to add the device: [#!variable!on_device!#] to the bridge: [#!variable!bridge_name!#] failed! The return code was: [#!variable!return_code!#]. The output, if any, was:
========
#!variable!output!#
========
</key>
<key name="error_0487">[ Error ] - The subnet_mask: [#!variable!subnet_mask!#] is not valid. It must be either a CIDR notation, or a dotted-decimal mask that can be translated to CIDR notation.</key>
<key name="error_0488">[ Error ] - Can't find a device to assign the: [#!variable!network!#] IP address: [#!variable!ip_address!#/#!variable!subnet_mask!#] to!</key>
<key name="error_0489">[ Error ] - Failed to map the IP address: [#!variable!ip_address!#] to a network manager connection UUID!</key>
<key name="error_0490">[ Error ] - Both the netbios name: [#!variable!wanted_link_name!#] and the old device name: [#!variable!old_device!#] are the same, 'match.interface-name' would break!</key>
<!-- Files templates --> <!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable --> <!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -2681,6 +2708,13 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
</key> </key>
<key name="log_0827">The physical volume: [#!variable!pv_name!#] has been resized!</key> <key name="log_0827">The physical volume: [#!variable!pv_name!#] has been resized!</key>
<key name="log_0828">The user answered: [#!variable!answer!#]</key> <key name="log_0828">The user answered: [#!variable!answer!#]</key>
<key name="log_0829">Failed to connect to any database, waiting before trying to connect again. We will reboot if we do not connect in: [#!variable!time_left!#] second.</key>
<key name="log_0830">The host: [#!variable!host_name!#] was found in the '/etc/hosts' file with the expected IP: [#!variable!ip_address!#]!</key>
<key name="log_0831">The host: [#!variable!host_name!#] was found in the '/etc/hosts' file, but the expected IP: [#!variable!ip_address!#] doesn't match the found IP: [#!variable!found_ip!#]! Ignoring this entry.</key>
<key name="log_0832">The host: [#!variable!host_name!#] was found not found in the '/etc/hosts' file! We'll wait a few seconds and check again.</key>
<key name="log_0833">All host names were found in '/etc/hosts', ready to proceed!</key>
<key name="log_0834">One or more hosts are not yet in the '/etc/hosts' file with expected IPs. We'll wait a short bit and check again.</key>
<key name="log_0835">There are entries we need to add to the '/etc/hosts' file before we can form the cluster, updating it now.</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. --> <!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key> <key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
@ -3284,6 +3318,42 @@ proceeding.
- Threads per Core: [#!variable!old_threads!#] -> [#!variable!new_threads!#] - Threads per Core: [#!variable!old_threads!#] -> [#!variable!new_threads!#]
- Total Cores: .... [#!variable!old_total_cores!#] -> [#!variable!new_total_cores!#]]]></key> - Total Cores: .... [#!variable!old_total_cores!#] -> [#!variable!new_total_cores!#]]]></key>
<key name="message_0382"><![CDATA[-=] Updated: #!variable!date!# - Press '<ctrl> + <c>' to exit]]></key> <key name="message_0382"><![CDATA[-=] Updated: #!variable!date!# - Press '<ctrl> + <c>' to exit]]></key>
<key name="message_0383">Renaming old device/name: [#!variable!old_device!#/#!variable!old_name!#] with MAC: [#!variable!mac_address!#] to: [#!variable!new_name!#] using UUID: [#!variable!nm_uuid!#].</key>
<key name="message_0384">- Updating the udev file: [#!variable!file!#].</key>
<key name="message_0385">- Removing the old 'connection.interface-name': [#!variable!name!#].</key>
<key name="message_0386">- Matching the new interface name: [#!variable!new_name!#] to the bios device name: [#!variable!old_device!#].</key>
<key name="message_0387">- Setting the connection.id to the bios device name: [#!variable!old_device!#]</key>
<key name="message_0388">The new interface names need a reboot to take effect.</key>
<key name="message_0389">Rebooting NOW! The job will restart on reboot.</key>
<key name="message_0390">Checking if the bond: [#!variable!bond_name!#] exists or not.</key>
<key name="message_0391">- It does, its UUID is: [#!variable!nm_uuid!#].</key>
<key name="message_0392">- The bond: [#!variable!bond_name!#] doesn't exist. Will create it using the primary interface: [#!variable!link1_name!#] (MAC: [#!variable!link1_mac!#], NM UUID: [#!variable!link1_nm_uuid!#) and the backup interface: [#!variable!link2_name!#] (MAC: [#!variable!link2_mac!#], NM UUID: [#!variable!link2_nm_uuid!#).</key>
<key name="message_0393">Checking to see if the IP address: [#!variable!ip_address!#/#!variable!subnet_mask!#] is assigned to: [#!variable!device!#] yet.</key>
<key name="message_0394"> - Done! Rescanning the network config.</key>
<key name="message_0395">- The interface: [#!variable!link_name!#] (#!variable!nm_uuid!#) is already a member of the bond.</key>
<key name="message_0396">- The interface: [#!variable!link_name!#] (#!variable!nm_uuid!#) is a member of the bond: [#!variable!old_bond!#], switching it to this bond.</key>
<key name="message_0397">- The interface: [#!variable!link_name!#] (#!variable!nm_uuid!#) needs to be connected to the bond.</key>
<key name="message_0398">- The IP exists, checking if it needs to be updated.</key>
<key name="message_0399"> - Connecting the interface: [#!variable!link_name!#] to the bond: [#!variable!bond_name!#].</key>
<key name="message_0400">Checking if the bridge: [#!variable!bridge_name!#] exists and that it is on: [#!variable!on_device!#]</key>
<key name="message_0401">- The bridge exists!</key>
<key name="message_0402">- The IP address is on: [#!variable!device!#], will move the IP.</key>
<key name="message_0403"> - Resetting the device: [#!variable!device!#] (#!variable!device_uuid!#) to make sure the new config takes effect.</key>
<key name="message_0404">- Checking that the device: [#!variable!on_device!#] is connected to this bridge.</key>
<key name="message_0405">- The device is connected to the bridge already.</key>
<key name="message_0406">- The device is on the bridge: [#!variable!on_device_parent!#], moving it.</key>
<key name="message_0407">- The device is not on this bridge, connecting it.</key>
<key name="message_0408"> - Disabling DHCP on the device: [#!variable!device!#] (#!variable!device_uuid!#).</key>
<key name="message_0409"> - Connecting it now.</key>
<key name="message_0410">- The current subnet mask is: [#!variable!current_subnet_mask!#], will update.</key>
<key name="message_0411">- The current gateway is: [#!variable!current_gateway!#], will update.</key>
<key name="message_0412">- The current DNS is: [#!variable!current_dns!#], will update.</key>
<key name="message_0413">- No update is needed.</key>
<key name="message_0414">- The IP address needs to be assigned.</key>
<key name="message_0415">[ Note ] - Reconfiguring the network will break connections. Disconnecting from the database before starting. It might take a bit before this system reconnects and progress can be seen.</key>
<key name="message_0416">[ Note ] - The network has reconnected to the database, configuring will complete shortly.</key>
<key name="message_0417">[ Note ] - The old 'ifcfg' style config file: [#!variable!file!#] will be backed up and then removed!</key>
<key name="message_0418">[ Note ] - Updated the ssh daemon config file: [#!variable!file!#] to enable ssh access for the root user.</key>
<!-- Translate names (protocols, etc) --> <!-- Translate names (protocols, etc) -->
<key name="name_0001">Normal Password</key> <!-- none in mail-server --> <key name="name_0001">Normal Password</key> <!-- none in mail-server -->
@ -4094,6 +4164,7 @@ We will try to proceed anyway.</key>
==== ====
</key> </key>
<key name="warning_0168">Please specify a storage group to use to add the new drive to.</key> <key name="warning_0168">Please specify a storage group to use to add the new drive to.</key>
<key name="warning_0169">[ Warning ] - After reconfiguring the network, we've failed to connect to any database for two minutes. Rebooting in case this fixes the connection.</key>
</language> </language>
<!-- 日本語 --> <!-- 日本語 -->

@ -42,7 +42,6 @@ dist_sbin_SCRIPTS = \
anvil-test-alerts \ anvil-test-alerts \
anvil-update-definition \ anvil-update-definition \
anvil-update-issue \ anvil-update-issue \
anvil-update-states \
anvil-update-system \ anvil-update-system \
anvil-version-changes \ anvil-version-changes \
anvil-virsh-wrapper \ anvil-virsh-wrapper \

@ -84,7 +84,7 @@ foreach my $pid (sort {$a cmp $b} @{$anvil->data->{sys}{pids}})
{ {
my $size = $1; my $size = $1;
my $type = $2; my $type = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
type => $type, type => $type,
size => $size, size => $size,
}}); }});
@ -94,10 +94,10 @@ foreach my $pid (sort {$a cmp $b} @{$anvil->data->{sys}{pids}})
# This uses 'kB' for 'KiB' >_> # This uses 'kB' for 'KiB' >_>
$type = lc($type); $type = lc($type);
$type =~ s/b$/ib/ if $type !~ /ib$/; $type =~ s/b$/ib/ if $type !~ /ib$/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { type => $type }});
my $size_in_bytes = $anvil->Convert->human_readable_to_bytes({size => $size, type => $type, base2 => 1}); my $size_in_bytes = $anvil->Convert->human_readable_to_bytes({size => $size, type => $type, base2 => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
size_in_bytes => $anvil->Convert->add_commas({number => $size_in_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size_in_bytes}).")", size_in_bytes => $anvil->Convert->add_commas({number => $size_in_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size_in_bytes}).")",
}}); }});

File diff suppressed because it is too large Load Diff

@ -75,6 +75,7 @@ $anvil->System->wait_on_dnf();
$anvil->Database->connect({ $anvil->Database->connect({
check_if_configured => 1, check_if_configured => 1,
check_for_resync => 2, check_for_resync => 2,
debug => 2,
}); });
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"});
@ -100,6 +101,9 @@ if (not $anvil->data->{sys}{database}{connections})
} }
else else
{ {
# Striker can't initialize us unless it can ssh into us, so make sure root login is enabled.
chech_sshd($anvil);
# Wait until we have one. # Wait until we have one.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0075"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0075"});
@ -200,7 +204,7 @@ while(1)
# Reload defaults, re-read the config and then connect to the database(s) # Reload defaults, re-read the config and then connect to the database(s)
$anvil->refresh(); $anvil->refresh();
# If, so some reason, anvil.conf is lost, create it. # If, for some reason, anvil.conf is lost, create it.
$anvil->System->_check_anvil_conf(); $anvil->System->_check_anvil_conf();
$anvil->Database->connect({check_if_configured => $check_if_database_is_configured, check_for_resync => 2}); $anvil->Database->connect({check_if_configured => $check_if_database_is_configured, check_for_resync => 2});
@ -208,26 +212,13 @@ while(1)
# Mark that we don't want to check the database now. # Mark that we don't want to check the database now.
$check_if_database_is_configured = 0; $check_if_database_is_configured = 0;
# If this host is mapping the network, we'll skip a lot of stuff. If set for over an hour, we'll
# clear it.
$anvil->data->{sys}{mapping_network} = check_if_mapping($anvil);
if ($anvil->data->{sys}{database}{connections}) if ($anvil->data->{sys}{database}{connections})
{ {
# Run the normal tasks # Run the normal tasks
keep_running($anvil); keep_running($anvil);
# Handle periodic tasks # Handle periodic tasks
handle_periodic_tasks($anvil) if not $anvil->data->{sys}{mapping_network}; handle_periodic_tasks($anvil);
}
else
{
# No databases available, we'll update the state file in case this host is having it's
# network mapped and the interface used to talk to the databases went down. That's all we
# can do though.
update_state_file($anvil);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0202"});
} }
# Exit if 'run-once' selected. # Exit if 'run-once' selected.
@ -312,85 +303,6 @@ sub check_ram
return(0); return(0);
} }
# Check to see if we're mapping the network on this host.
sub check_if_mapping
{
my ($anvil) = @_;
$anvil->data->{sys}{mapping_network} = 0;
if ($anvil->data->{sys}{database}{connections})
{
my ($map_network_value, $map_network_uuid, $map_network_mtime, $map_network_modified_date) = $anvil->Database->read_variable({
debug => 3,
variable_name => "config::map_network",
variable_source_table => "hosts",
variable_source_uuid => $anvil->data->{sys}{host_uuid},
});
# We'll run for a day (should be cancelled by the program when the user's done, so this
# shouldn't fire in practice).
my $expire_age = 86400;
my $map_network_age = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:map_network_value' => $map_network_value,
's2:map_network_mtime' => $map_network_mtime,
's3:map_network_modified_date' => $map_network_modified_date,
's4:map_network_uuid' => $map_network_uuid,
}});
if ($map_network_uuid)
{
$map_network_age = time - $map_network_mtime;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { map_network_age => $map_network_age }});
}
if ($map_network_value)
{
# How long ago was it set?
$anvil->data->{switches}{'clear-mapping'} = "" if not defined $anvil->data->{switches}{'clear-mapping'};
if (($map_network_age >= $expire_age) or ($anvil->data->{switches}{'clear-mapping'}))
{
# Clear it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0470"});
$anvil->Database->insert_or_update_variables({
debug => 3,
variable_value => 0,
variable_uuid => $map_network_uuid,
update_value_only => 1,
});
}
else
{
# Mark it so we only track the network.
my $say_age = $anvil->Convert->add_commas({number => $expire_age});
my $timeout = $anvil->Convert->add_commas({number => ($expire_age - $map_network_age)});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0471", variables => {
age => $say_age,
timeout => $timeout,
}});
$anvil->data->{sys}{mapping_network} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::mapping_network" => $anvil->data->{sys}{mapping_network} }});
# Close any open ssh connections.
foreach my $ssh_fh_key (keys %{$anvil->data->{cache}{ssh_fh}})
{
my $ssh_fh = $anvil->data->{cache}{ssh_fh}{$ssh_fh_key};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
ssh_fh_key => $ssh_fh_key,
ssh_fh => $ssh_fh,
}});
if ($ssh_fh =~ /^Net::OpenSSH/)
{
$ssh_fh->disconnect();
}
delete $anvil->data->{cache}{ssh_fh}{$ssh_fh_key};
}
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "sys::mapping_network" => $anvil->data->{sys}{mapping_network} }});
return($anvil->data->{sys}{mapping_network});
}
# This decides if the local system will delay daily runs on start-up. # This decides if the local system will delay daily runs on start-up.
sub set_delay sub set_delay
{ {
@ -431,6 +343,7 @@ sub check_network
{ {
my ($anvil) = @_; my ($anvil) = @_;
### TODO: Remove this when EL8 support is dropped. This was an issue with the old ifcfg configured bonds
# The network sometimes doesn't come up, but we don't want to try recovering it too soon. As such, # The network sometimes doesn't come up, but we don't want to try recovering it too soon. As such,
# we'll start watching the network after the uptime is 2 minutes. # we'll start watching the network after the uptime is 2 minutes.
my $uptime = $anvil->Get->uptime; my $uptime = $anvil->Get->uptime;
@ -450,19 +363,11 @@ sub check_network
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { return_code => $return_code }});
} }
#$anvil->Network->check_network({heal => "all"});
$anvil->data->{sys}{network}{initial_checks} = 1; $anvil->data->{sys}{network}{initial_checks} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"sys::network::initial_checks" => $anvil->data->{sys}{network}{initial_checks}, "sys::network::initial_checks" => $anvil->data->{sys}{network}{initial_checks},
}}); }});
} }
else
{
### NOTE: This is constantly trying to "fix" healthy bonds, without a know way to
### trigger to debug. As such, disabling for now.
#$anvil->Network->check_network({heal => "down_only"});
}
check_firewall($anvil); check_firewall($anvil);
} }
@ -500,6 +405,27 @@ sub check_network
} }
} }
# Check that there's at least one entry in 'network_interfaces' and, if not, call scan-network.
if (1)
{
my $query = "SELECT COUNT(*) FROM network_interfaces WHERE network_interface_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
# Run scan-network
my $shell_call = $anvil->data->{path}{directories}{scan_agents}."/scan-network/scan-network".$anvil->Log->switches;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
}
return(0); return(0);
} }
@ -530,7 +456,7 @@ sub handle_periodic_tasks
# Check that the users we care about have ssh public keys and they're recorded in ssh_keys. # Check that the users we care about have ssh public keys and they're recorded in ssh_keys.
$anvil->System->check_ssh_keys({debug => 2}); $anvil->System->check_ssh_keys({debug => 2});
$anvil->System->update_hosts({debug => 3}); $anvil->System->update_hosts({debug => 2});
# Check if the files on disk have changed. Even if it is time to check, don't if a job is # Check if the files on disk have changed. Even if it is time to check, don't if a job is
# running. # running.
@ -560,9 +486,6 @@ sub handle_periodic_tasks
return_code => $return_code, return_code => $return_code,
}}); }});
# Scan the local network.
update_state_file($anvil);
# Check shared files. # Check shared files.
check_files($anvil); check_files($anvil);
@ -1100,6 +1023,9 @@ sub run_once
# Check journald is configured for persistent storage. # Check journald is configured for persistent storage.
check_journald($anvil); check_journald($anvil);
# Make sure root can ssh
chech_sshd($anvil);
if ($anvil->data->{switches}{'startup-only'}) if ($anvil->data->{switches}{'startup-only'})
{ {
$anvil->nice_exit({exit_code => 0}); $anvil->nice_exit({exit_code => 0});
@ -1108,6 +1034,50 @@ sub run_once
return(0); return(0);
} }
sub chech_sshd
{
my ($anvil) = @_;
# On EL8, the 'sshd_config.d' directory doesn't exist and root is enabled.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'path::directories::sshd_config.d' => $anvil->data->{path}{directories}{'sshd_config.d'} }});
if (not -d $anvil->data->{path}{directories}{'sshd_config.d'})
{
return(0);
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'path::configs::sshd_root_password' => $anvil->data->{path}{configs}{sshd_root_password} }});
if (not -f $anvil->data->{path}{configs}{sshd_root_password})
{
# Write it out
my $body = "# This file was added to enable root login by password, which is needed while
# forming the Anvil! cluster. Once the cluster is formed, passwordless SSH
# should be enabled and you can disable this feature. Please remove during a
# maintanence window or after testing in a lab environment.
PermitRootLogin yes
";
# Update the config
$anvil->Storage->write_file({
debug => 2,
secure => 0,
file => $anvil->data->{path}{configs}{sshd_root_password},
body => $body,
mode => "0644",
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0418", variables => { file => $anvil->data->{path}{configs}{sshd_root_password} }});
# Restart the journald service.
my $shell_call = $anvil->data->{path}{exe}{systemctl}." restart sshd.service";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
return(0);
}
sub check_journald sub check_journald
{ {
my ($anvil) = @_; my ($anvil) = @_;
@ -1200,7 +1170,7 @@ sub check_journald
return(0); return(0);
} }
# This creates, as needed, the setuid wrappers used by apache to make certain system calls. # This creates, as needed, the setuid wrappers used by striker-ui-api to make certain system calls.
sub check_setuid_wrappers sub check_setuid_wrappers
{ {
my ($anvil) = @_; my ($anvil) = @_;
@ -1432,7 +1402,7 @@ AND
} }
# Make sure /etc/hosts is updated. # Make sure /etc/hosts is updated.
$anvil->System->update_hosts(); $anvil->System->update_hosts({debug => 2});
# This handles weird bits for things like bug work-arounds. # This handles weird bits for things like bug work-arounds.
handle_special_cases($anvil); handle_special_cases($anvil);
@ -1443,14 +1413,6 @@ AND
# Check the firewall needs to be updated. # Check the firewall needs to be updated.
check_firewall($anvil); check_firewall($anvil);
# If we're a striker, check apache
my $host_type = $anvil->Get->host_type;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type eq "striker")
{
$anvil->Striker->check_httpd_conf({debug => 3});
}
return(0); return(0);
} }
@ -1541,7 +1503,7 @@ sub keep_running
my ($anvil) = @_; my ($anvil) = @_;
# Check for jobs that were running and now exited. # Check for jobs that were running and now exited.
if ((not $anvil->data->{sys}{mapping_network}) && (exists $anvil->data->{processes})) if (exists $anvil->data->{processes})
{ {
foreach my $job_uuid (%{$anvil->data->{jobs}{handles}}) foreach my $job_uuid (%{$anvil->data->{jobs}{handles}})
{ {
@ -1572,18 +1534,13 @@ sub keep_running
# If we're configured, write out the status JSON file. If we're not configured, Update hardware state files. # If we're configured, write out the status JSON file. If we're not configured, Update hardware state files.
my $configured = $anvil->System->check_if_configured; my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }});
if ((not $anvil->data->{sys}{mapping_network}) && ($configured)) if ($configured)
{ {
# Write out state information for all known Anvil! systems and the information from # Write out state information for all known Anvil! systems and the information from
# unconfigured nods and DR hosts, using just database data (hence, fast enough to run # unconfigured nods and DR hosts, using just database data (hence, fast enough to run
# constantly). # constantly).
$anvil->System->generate_state_json({debug => 2}); $anvil->System->generate_state_json({debug => 2});
} }
else
{
# Run this to monitor the network in real time.
update_state_file($anvil);
}
# Run any pending jobs by calling 'anvil-jobs' with the 'job_uuid' as a background process. # Run any pending jobs by calling 'anvil-jobs' with the 'job_uuid' as a background process.
run_jobs($anvil, 0); run_jobs($anvil, 0);
@ -1620,10 +1577,6 @@ sub run_jobs
# changed on disk. # changed on disk.
$anvil->data->{sys}{jobs_running} = 0; $anvil->data->{sys}{jobs_running} = 0;
# If we're not configured, we won't hold on starting jobs
my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }});
# We'll also update the jobs.json file. # We'll also update the jobs.json file.
my $jobs_file = "{\"jobs\":[\n"; my $jobs_file = "{\"jobs\":[\n";
@ -1676,11 +1629,16 @@ sub run_jobs
's12:job_status' => $job_status, 's12:job_status' => $job_status,
's13:started_seconds_ago' => $started_seconds_ago, 's13:started_seconds_ago' => $started_seconds_ago,
's14:updated_seconds_ago' => $updated_seconds_ago, 's14:updated_seconds_ago' => $updated_seconds_ago,
's15:sys::mapping_network' => $anvil->data->{sys}{mapping_network},
}}); }});
# If we're mapping, we'll only run 'anvil-configure-host' jobs on this host. # If we're not configured, we will only run the 'anvil-configure-host' job
next if (($anvil->data->{sys}{mapping_network}) && ($job_command !~ /anvil-configure-host/)); my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }});
if ((not $configured) && ($job_command !~ /anvil-configure-host/))
{
next;
}
# To minimize the chance of race conditions, any given command will be called only # To minimize the chance of race conditions, any given command will be called only
# once at a time. If two jobs of the same command exist, only one will be called. # once at a time. If two jobs of the same command exist, only one will be called.
@ -1793,9 +1751,9 @@ sub run_jobs
} }
# Convert the double-banged strings into a proper message. # Convert the double-banged strings into a proper message.
my $say_title = $job_title ? $anvil->Words->parse_banged_string({key_string => $job_title}) : ""; my $say_title = $job_title ? $anvil->Words->parse_banged_string({debug => 2, key_string => $job_title}) : "";
my $say_description = $job_description ? $anvil->Words->parse_banged_string({key_string => $job_description}) : ""; my $say_description = $job_description ? $anvil->Words->parse_banged_string({debug => 2, key_string => $job_description}) : "";
my $say_status = $job_status ? $anvil->Words->parse_banged_string({key_string => $job_status}) : ""; my $say_status = $job_status ? $anvil->Words->parse_banged_string({debug => 2, key_string => $job_status}) : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
job_title => $job_title, job_title => $job_title,
say_description => $say_description, say_description => $say_description,
@ -1963,8 +1921,8 @@ sub run_jobs
overwrite => 1, overwrite => 1,
backup => 0, backup => 0,
mode => "0644", mode => "0644",
user => "apache", user => "striker-ui-api",
group => "apache", group => "striker-ui-api",
}); });
return(0); return(0);
@ -2004,8 +1962,8 @@ sub check_files
{ {
my $failed = $anvil->Storage->make_directory({ my $failed = $anvil->Storage->make_directory({
directory => $directory, directory => $directory,
group => "apache", group => "striker-ui-api",
user => "apache", user => "striker-ui-api",
mode => "0777", mode => "0777",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { failed => $failed }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { failed => $failed }});
@ -2032,24 +1990,3 @@ sub check_files
return(0); return(0);
} }
# This calls 'anvil-update-states' which will scan the local machine's state (hardware and software) and
# record write it out to an HTML file
sub update_state_file
{
my ($anvil) = @_;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0480"});
#my $shell_call = $anvil->data->{path}{exe}{'anvil-update-states'}.$anvil->Log->switches;
my $shell_call = $anvil->data->{path}{exe}{'anvil-update-states'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($states_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
states_output => $states_output,
return_code => $return_code,
}});
return(0);
}

@ -222,8 +222,8 @@ sub download_file
debug => 2, debug => 2,
directory => $save_to, directory => $save_to,
mode => "0777", mode => "0777",
user => "apache", user => "striker-ui-api",
group => "apache", group => "striker-ui-api",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
} }
@ -233,8 +233,8 @@ sub download_file
debug => 2, debug => 2,
directory => $anvil->data->{path}{directories}{shared}{temp}, directory => $anvil->data->{path}{directories}{shared}{temp},
mode => "0777", mode => "0777",
user => "apache", user => "striker-ui-api",
group => "apache", group => "striker-ui-api",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
} }

@ -22,6 +22,7 @@ use Anvil::Tools;
use Data::Dumper; use Data::Dumper;
use String::ShellQuote; use String::ShellQuote;
use Text::Diff; use Text::Diff;
use NetAddr::IP;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
@ -54,6 +55,9 @@ if (not $anvil->data->{sys}{database}{connections})
# Get the job details # Get the job details
load_job($anvil); load_job($anvil);
# Make sure the hosts file has entries for all nets for both subnodes
wait_for_etc_hosts($anvil);
# Hold until both subnodes are marked as configured and not in maintenance mode. # Hold until both subnodes are marked as configured and not in maintenance mode.
wait_for_subnodes($anvil); wait_for_subnodes($anvil);
@ -63,6 +67,10 @@ update_passwords($anvil);
# Check if we need to change any IPs or our hostname. # Check if we need to change any IPs or our hostname.
check_local_network($anvil); check_local_network($anvil);
# Wait until we can ping our peer on all networks.
wait_for_access($anvil);
### TODO: Change corosync.conf to use IPs, including MN if it exists.
# (wait for out peer and) Configure pacemaker # (wait for out peer and) Configure pacemaker
configure_pacemaker($anvil); configure_pacemaker($anvil);
@ -98,6 +106,426 @@ $anvil->nice_exit({exit_code => 0});
# Functions # # Functions #
############################################################################################################# #############################################################################################################
# Make sure the hosts file has entries for all nets for both subnodes
sub wait_for_etc_hosts
{
my ($anvil) = @_;
my $anvil_uuid = $anvil->data->{sys}{anvil_uuid};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
my $manifest_uuid = $anvil->data->{sys}{manifest_uuid};
my $i_am = $anvil->data->{sys}{machine};
my $peer_is = $i_am eq "node1" ? "node2" : "node1";
my $peer_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{"anvil_".$peer_is."_host_uuid"};
my $peer_short_host_name = $anvil->data->{hosts}{host_uuid}{$peer_host_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:anvil_uuid' => $anvil_uuid,
's2:manifest_uuid' => $manifest_uuid,
's3:node1_host_uuid' => $node1_host_uuid,
's4:node2_host_uuid' => $node2_host_uuid,
's5:i_am' => $i_am,
's6:peer_is' => $peer_is,
's7:peer_host_uuid' => $peer_host_uuid,
's8:peer_short_host_name' => $peer_short_host_name,
}});
my $problem = $anvil->Striker->load_manifest({debug => 2, manifest_uuid => $manifest_uuid});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
manifest_uuid => $anvil->data->{sys}{manifest_uuid},
problem => $problem,
}});
if ($problem)
{
# Something went wrong, fatally. Abort the job.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "job_0076", variables => { uuid => $anvil->data->{sys}{manifest_uuid} }});
update_progress($anvil, 100, "job_0076,!!uuid!".$anvil->data->{sys}{manifest_uuid}."!!");
$anvil->nice_exit({exit_code => 2});
}
# Create the list of host names we need to see in /etc/hosts and the hostnames to use in corosync.
foreach my $machine (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}})
{
my $this_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{"anvil_".$machine."_host_uuid"};
my $this_short_host_name = $anvil->data->{hosts}{host_uuid}{$this_host_uuid}{short_host_name};
my $bcn_name = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { machine => $machine }});
foreach my $network_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}})
{
my $host_name = $this_short_host_name.".".$network_name;
my $ip_address = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}{$network_name}{ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:network_name' => $network_name,
's2:host_name' => $host_name,
's3:ip_address' => $ip_address,
}});
$anvil->data->{networks}{$host_name}{ip_address} = $ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:networks::${host_name}::ip_address" => $anvil->data->{networks}{$host_name}{ip_address},
}});
# If this is the first BCN, record it's name (in case BCN1 isn't used here) and IP
# address, and add the short and full host names.
if (($network_name =~ /^bcn/) && (not $bcn_name))
{
$bcn_name = $network_name;
my $this_host_name = $anvil->data->{hosts}{host_uuid}{$this_host_uuid}{host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bcn_name => $bcn_name }});
$anvil->data->{networks}{$this_short_host_name}{ip_address} = $ip_address;
$anvil->data->{networks}{$this_host_name}{ip_address} = $ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:networks::${this_short_host_name}::ip_address" => $anvil->data->{networks}{$this_short_host_name}{ip_address},
"s2:networks::${this_host_name}::ip_address" => $anvil->data->{networks}{$this_host_name}{ip_address},
}});
}
}
}
my $waiting = 1;
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0477");
while($waiting)
{
# Update the /etc/hosts file. Note that this doesn't add hosts that are not yet trusted, so
# anything not found will be inserted here.
$anvil->System->update_hosts({debug => 2});
# Now lets see if all expected hosts names are in the /etc/hosts file yet.
my $ready = 1;
my $hosts_file = $anvil->Storage->read_file({
file => $anvil->data->{path}{configs}{hosts},
force_read => 1,
cache => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { hosts_file => $hosts_file }});
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{networks}})
{
my $found = 0;
my $ip_address = $anvil->data->{networks}{$host_name}{ip_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:host_name' => $host_name,
's2:ip_address' => $ip_address,
}});
foreach my $line (split/\n/, $hosts_file)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
$line =~ s/#.*$//;
if ($line =~ /^(\d.*?)\s+(.*)$/)
{
my $this_ip = $1;
my $hosts = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_ip => $this_ip,
hosts => $hosts,
}});
if ($anvil->Validate->ip({ip => $this_ip}))
{
foreach my $this_host (split/\s+/, $hosts)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_host => $this_host }});
if ($host_name eq $this_host)
{
my $variables = {
host_name => $host_name,
ip_address => $ip_address,
found_ip => $this_ip,
};
if ($ip_address eq $this_ip)
{
# Found it
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0830", variables => $variables });
$found = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }});
}
else
{
# Found the host, but the IP doesn't match.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0831", variables => $variables });
}
}
last if $found;
}
}
}
last if $found;
}
if (not $found)
{
$ready = 0;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0832", variables => { host_name => $host_name }});
# Add the IP to be added to /etc/hosts.
$anvil->data->{to_add}{$host_name} = $ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "to_add::${ip_address}" => $anvil->data->{to_add}{$host_name} }});
}
}
if ($ready)
{
# Ready!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0833"});
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
else
{
# Not ready, wait a bit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0834"});
# Add the values to /etc/hosts.
my $new_hosts_body = "";
foreach my $line (split/\n/, $hosts_file)
{
# See if this line needs to be modified.
if ($line =~ /^(\d.*?)\s+(.*)$/)
{
my $this_ip = $1;
my $hosts = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_ip => $this_ip,
hosts => $hosts,
}});
if ($anvil->Validate->ip({ip => $this_ip}))
{
my $changes = 0;
my $new_hosts = "";
my $comment = ($hosts =~ /(#.*)$/)[0];
$comment = "" if not defined $comment;
$hosts =~ s/#.*?//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
comment => $comment,
hosts => $hosts,
}});
foreach my $host_name (split/\s+/, $hosts)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if ((exists $anvil->data->{to_add}{$host_name}) &&
($anvil->data->{to_add}{$host_name}) &&
($this_ip ne $anvil->data->{to_add}{$host_name}))
{
# Remove this host.
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
delete $anvil->data->{to_add}{$host_name};
next;
}
$new_hosts .= $host_name." ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_hosts => $new_hosts }});
}
# Do we have any names to add to this IP?
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{to_add}})
{
if ($this_ip eq $anvil->data->{to_add}{$host_name})
{
# Add it.
$new_hosts .= $host_name." ";
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
delete $anvil->data->{to_add}{$host_name};
}
}
if ($changes)
{
$new_hosts_body .= $this_ip."\t".$new_hosts.$comment."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
next;
}
}
}
# If we're alive here, just add the old line.
$new_hosts_body .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_hosts_body => $new_hosts_body }});
}
# Add any hosts still not processed.
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{to_add}})
{
$new_hosts_body .= $anvil->data->{to_add}{$host_name}."\t".$host_name."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_hosts_body => $new_hosts_body }});
delete $anvil->data->{to_add}{$host_name};
}
# If there's a difference, write the new hosts file.
my $difference = diff \$new_hosts_body, \$hosts_file, { STYLE => 'Unified' };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
if ($difference)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "job_0112"});
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0112");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0835"});
my $failed = $anvil->Storage->write_file({
debug => 2,
overwrite => 1,
file => $anvil->data->{path}{configs}{hosts},
body => $new_hosts_body,
user => "root",
group => "root",
mode => "0644",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
}
sleep 1;
}
}
return(0);
}
sub wait_for_access
{
my ($anvil) = @_;
# NOTE: This logic is a copy of anvil-safe-start.
$anvil->Database->get_hosts();
$anvil->Database->get_anvils();
my $host_uuid = $anvil->Get->host_uuid();
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
my $peer_host_uuid = $anvil->data->{sys}{peer_host_uuid};
my $peer_short_host_name = $anvil->data->{hosts}{host_uuid}{$peer_host_uuid}{short_host_name};
my $peer_password = $anvil->data->{sys}{peer_password};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
short_host_name => $short_host_name,
peer_host_uuid => $peer_host_uuid,
peer_short_host_name => $peer_short_host_name,
peer_password => $anvil->Log->is_secure($peer_password),
}});
my $waiting = 1;
while ($waiting)
{
# This will get set back to '1' if
$waiting = 0;
# Load IPs (again, to catch changes that might be delaying startup)
$anvil->Network->load_ips({
clear => 1,
host => $short_host_name,
host_uuid => $host_uuid,
});
$anvil->Network->load_ips({
clear => 1,
host => $peer_short_host_name,
host_uuid => $peer_host_uuid,
});
# Loop through our interfaces and then loop our peers. Test access over them and set
# 'waiting' back to '1' if the connection fails.
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$short_host_name}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
waiting => $waiting,
}});
# Only care about our networks.
next if $waiting;
if (not $anvil->Network->is_our_interface({interface => $interface}))
{
# Not an interface we care about
next;
}
my $this_network = ($interface =~ /^(.*?)_/)[0];
my $ip_address = $anvil->data->{network}{$short_host_name}{interface}{$interface}{ip};
my $subnet_mask = $anvil->data->{network}{$short_host_name}{interface}{$interface}{subnet_mask};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:this_network' => $this_network,
's2:ip_address' => $ip_address,
's3:subnet_mask' => $subnet_mask,
}});
### NOTE: I know I could match interface names, but that's not certain enough. It's
### possible (if unlikely) that the network name+numbre differs on our peer. So
### this is safer.
# Loop through my peer's interfaces and see if we're sharing this one.
my $local_network = NetAddr::IP->new($ip_address."/".$subnet_mask);
my $peer_match_found = 0;
foreach my $peer_interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$peer_short_host_name}{interface}})
{
last if $peer_match_found;
my $peer_ip_address = $anvil->data->{network}{$peer_short_host_name}{interface}{$peer_interface}{ip};
my $peer_subnet_mask = $anvil->data->{network}{$peer_short_host_name}{interface}{$peer_interface}{subnet_mask};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
peer_interface => $peer_interface,
peer_ip_address => $peer_ip_address,
peer_subnet_mask => $peer_subnet_mask,
}});
# This the matching network?
next if $subnet_mask ne $peer_subnet_mask;
my $peer_network = NetAddr::IP->new($peer_ip_address."/".$peer_subnet_mask);
if ($peer_network->within($local_network))
{
# Match, test access.
$peer_match_found = 1;
my $access = $anvil->Remote->test_access({
target => $peer_ip_address,
password => $peer_password,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { access => $access }});
if ($access)
{
# This network is good.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0604", variables => {
peer => $peer_short_host_name,
network => $this_network,
peer_ip => $peer_ip_address,
}});
$anvil->data->{sys}{peer_target_ip} = $peer_ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sys::peer_target_ip" => $anvil->data->{sys}{peer_target_ip},
}});
}
else
{
# No access, wait and try it again.
$waiting = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "alert", key => "log_0605", variables => {
peer => $peer_short_host_name,
network => $this_network,
peer_ip => $peer_ip_address,
}});
}
}
}
}
if ($waiting)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "alert", key => "log_0606", variables => { peer => $peer_short_host_name }});
sleep 5;
}
}
# All networks are up.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "alert", key => "log_0607", variables => { peer => $peer_short_host_name }});
return(0);
}
# Configure DRBD # Configure DRBD
sub configure_drbd sub configure_drbd
{ {
@ -495,20 +923,52 @@ sub configure_pacemaker
} }
if (time > $start_again) if (time > $start_again)
{ {
# Call cluster start again. ### NOTE: We can't just call 'start --all' again anymore. Now we need to
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0272"}); ### stop -> start. Before we do this, make sure there are no servers
$start_again = time + 60; ### running.
my $shell_call = $anvil->data->{path}{exe}{pcs}." cluster start --all"; $start_again = time + 60;
my $restart = 1;
my $server_count = keys %{$anvil->data->{cib}{parsed}{data}{server}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
start_again => $start_again, start_again => $start_again,
shell_call => $shell_call, server_count => $server_count,
}}); }});
foreach my $server (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{data}{server}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cib::parsed::data::server::${server}::active" => $anvil->data->{cib}{parsed}{data}{server}{$server}{active},
}});
if ($anvil->data->{cib}{parsed}{data}{server}{$server}{active})
{
$restart = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { restart => $restart }});
}
}
my ($output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { restart => $restart }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { if ($restart)
output => $output, {
return_code => $return_code, # Call cluster start again.
}}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0272"});
my $shell_call = $anvil->data->{path}{exe}{pcs}." cluster stop --all";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
start_again => $start_again,
shell_call => $shell_call,
}});
my ($output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{pcs}." cluster start --all";
($output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
} }
sleep 5 if not $both_online; sleep 5 if not $both_online;
} }
@ -1155,7 +1615,7 @@ sub configure_pacemaker
} }
} }
# Update (if needed) corosync.conf to use the BCN1 and SN1 as knet networks. # Update (if needed) corosync.conf to use the BCN1, MN1 and SN1 as knet networks.
if ($machine eq "node1") if ($machine eq "node1")
{ {
update_progress($anvil, ($anvil->data->{job}{progress} += 1), "job_0344"); update_progress($anvil, ($anvil->data->{job}{progress} += 1), "job_0344");
@ -1189,6 +1649,7 @@ sub check_corosync
my $new_password = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password}; my $new_password = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password};
while ($waiting) while ($waiting)
{ {
### TODO: Add MN where appropriate
my $problem = $anvil->Cluster->parse_cib({debug => 3}); my $problem = $anvil->Cluster->parse_cib({debug => 3});
my $peer_ready = $anvil->data->{cib}{parsed}{peer}{ready}; my $peer_ready = $anvil->data->{cib}{parsed}{peer}{ready};
my $peer_name = $anvil->data->{cib}{parsed}{peer}{name}; my $peer_name = $anvil->data->{cib}{parsed}{peer}{name};
@ -2258,11 +2719,6 @@ sub check_local_network
} }
} }
# Update the hosts file.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "job_0112"});
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0112");
$anvil->System->update_hosts({debug => 3});
# Configure SSH by adding ours and our peer's SSH keys to ~/.ssh/known_hosts # Configure SSH by adding ours and our peer's SSH keys to ~/.ssh/known_hosts
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "job_0113"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "job_0113"});
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0113"); update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0113");

@ -1945,7 +1945,7 @@ sub process_remove
### If we're here, we can now update the resource config file to remove the DR host. ### If we're here, we can now update the resource config file to remove the DR host.
# Refresh the IP info (usually scrubbed by this point) # Refresh the IP info (usually scrubbed by this point)
$anvil->Database->get_ip_addresses(); $anvil->Database->get_ip_addresses({debug => 2});
# First loop to build the node sections, then we'll loop to build the connections # First loop to build the node sections, then we'll loop to build the connections
my $node1_volumes = ""; my $node1_volumes = "";
@ -2901,7 +2901,7 @@ sub process_protect
} }
# Refresh the IP info (usually scrubbed by this point) # Refresh the IP info (usually scrubbed by this point)
$anvil->Database->get_ip_addresses(); $anvil->Database->get_ip_addresses({debug => 2});
# The connections. Node 1 to 2 always uses the BCN, Either node to DR needs # The connections. Node 1 to 2 always uses the BCN, Either node to DR needs
my $storage_network = "sn1"; my $storage_network = "sn1";

@ -29,12 +29,9 @@ $anvil->Get->switches({list => [
"auto-grow-pv", "auto-grow-pv",
"check-configured", "check-configured",
"check-database", "check-database",
"check-network-mapping",
"confirm", "confirm",
"database-active", "database-active",
"database-inactive", "database-inactive",
"disable-network-mapping",
"enable-network-mapping",
"mark-configured", "mark-configured",
"mark-unconfigured", "mark-unconfigured",
"resync-database"], man => $THIS_FILE}); "resync-database"], man => $THIS_FILE});
@ -58,10 +55,6 @@ elsif (($anvil->data->{switches}{'database-active'}) or ($anvil->data->{switches
{ {
update_database($anvil); update_database($anvil);
} }
elsif (($anvil->data->{switches}{'enable-network-mapping'}) or ($anvil->data->{switches}{'disable-network-mapping'}) or ($anvil->data->{switches}{'check-network-mapping'}))
{
update_network_mapping($anvil);
}
elsif ($anvil->data->{switches}{'age-out-database'}) elsif ($anvil->data->{switches}{'age-out-database'})
{ {
age_out_data($anvil); age_out_data($anvil);
@ -279,118 +272,6 @@ sub update_database
return(0); return(0);
} }
sub update_network_mapping
{
my ($anvil) = @_;
my $variable_name = "config::map_network";
my ($map_network_value, $map_network_uuid, $map_network_mtime, $map_network_modified_date) = $anvil->Database->read_variable({
variable_name => $variable_name,
variable_source_table => "hosts",
variable_source_uuid => $anvil->data->{sys}{host_uuid},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:variable_name' => $variable_name,
's2:map_network_value' => $map_network_value,
's3:map_network_mtime' => $map_network_mtime,
's4:map_network_modified_date' => $map_network_modified_date,
's5:map_network_uuid' => $map_network_uuid,
}});
if ($anvil->data->{switches}{'check-network-mapping'})
{
# We'll run for a day (should be cancelled by the program when the user's done, so this
# shouldn't fire in practice).
my $expire_age = 86400;
my $map_network_age = 0;
if ($map_network_uuid)
{
$map_network_age = time - $map_network_mtime;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { map_network_age => $map_network_age }});
}
if ($map_network_value)
{
# How long ago was it set?
$anvil->data->{switches}{'clear-mapping'} = "" if not defined $anvil->data->{switches}{'clear-mapping'};
if (($map_network_age >= $expire_age) or ($anvil->data->{switches}{'clear-mapping'}))
{
# Clear it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0470"});
$anvil->Database->insert_or_update_variables({
debug => 3,
variable_value => 0,
variable_uuid => $map_network_uuid,
update_value_only => 1,
});
}
else
{
# Mark it so we only track the network.
my $say_age = $anvil->Convert->add_commas({number => $expire_age});
my $timeout = $anvil->Convert->add_commas({number => ($expire_age - $map_network_age)});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0471", variables => {
age => $say_age,
timeout => $timeout,
}});
}
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0820"});
}
return(0);
}
if ($anvil->data->{switches}{'enable-network-mapping'})
{
if ($map_network_value)
{
# Nothing to do.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0353"});
}
else
{
# Enable network configuring.
my $variable_uuid = $anvil->Database->insert_or_update_variables({
variable_name => $variable_name,
variable_value => 1,
variable_default => "",
variable_description => "striker_0202",
variable_section => "config",
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0354"});
}
}
if ($anvil->data->{switches}{'disable-network-mapping'})
{
if ($map_network_value)
{
# Disable network configuring.
my $variable_uuid = $anvil->Database->insert_or_update_variables({
variable_name => $variable_name,
variable_value => 0,
variable_default => "",
variable_description => "striker_0202",
variable_section => "config",
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0356"});
}
else
{
# Nothing to do.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0355"});
}
}
return(0);
}
sub update_config sub update_config
{ {
my ($anvil) = @_; my ($anvil) = @_;

@ -0,0 +1,505 @@
#!/usr/bin/perl
#
# This daemon watches for network interface link change (unplugged or plugged in network cables).
#
# At this point, the only thing this does is call 'scan-network' when a change is detected.
#
# NOTE: This is designed to be minimal overhead, so there is no attempt to connect to the database. As such,
# be mindful of what this daemon is used for.
#
use strict;
use warnings;
use Data::Dumper;
use Text::Diff;
use Anvil::Tools;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
$| = 1;
my $anvil = Anvil::Tools->new();
# Read switches
$anvil->Get->switches({list => [], man => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Calculate my sum so that we can exit if it changes later.
$anvil->Storage->record_md5sums;
my $next_md5sum_check = time + 30;
my $directory = "/sys/class/net";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
# Now go into the main loop
while(1)
{
### NOTE: A lot of this logic comes from scan-network
my $scan_time = time;
my $trigger = 0;
# Look for interfaces.
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
next if $file eq "lo";
my $full_path = $directory."/".$file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }});
if (-d $full_path)
{
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
my $interface = $file;
my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
$link_state =~ s/\n$//;
my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
$mtu =~ s/\n$//;
my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
$duplex =~ s/\n$//;
my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
$operational =~ s/\n$//;
my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
$modalias =~ s/\n$//;
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
$speed =~ s/\n$//;
my $media = "unknown";
my $type = "interface";
my $driver = "";
my $tx_bytes = 0; # How many bytes transmitted
my $rx_bytes = 0; # How many bytes received
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
link_state => $link_state,
mtu => $mtu,
duplex => $duplex,
operational => $operational,
speed => $speed,
modalias => $modalias,
}});
# Get the MAC address
my $mac_address = "";
my $shell_call = $anvil->data->{path}{exe}{ethtool}." -P ".$interface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if ($output =~ /(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)$/)
{
$mac_address = lc($1);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
else
{
# Get it by reading the address file.
if (-e $full_path."/bonding_slave/perm_hwaddr")
{
$mac_address = $anvil->Storage->read_file({file => $full_path."/bonding_slave/perm_hwaddr"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
elsif (-e $full_path."/address")
{
$mac_address = $anvil->Storage->read_file({file => $full_path."/address"});
$mac_address =~ s/\n//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
}
# These are variables that will be needed if this is a bond interface.
my $ip_address = "";
my $subnet_mask = "";
my $bond_mode = "";
my $primary_interface = "";
my $primary_reselect = "";
my $active_interface = "";
my $mii_polling_interval = "";
my $up_delay = "";
my $down_delay = "";
my $bond_parent = "";
# These are variables that will be needed if this is a bridge interface
my $bridge_id = "";
my $bridge_stp_enabled = "";
# If this interface is already a bond slave, the real mac address will be in a
# sub-directory.
my $mac_bond_file = $directory."/".$file."/bonding_slave/perm_hwaddr";
if (-e $mac_bond_file)
{
# It's a slave.
$mac_address = $anvil->Storage->read_file({file => $mac_bond_file});
$mac_address =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
# Pick out our driver.
if ($modalias =~ /^virtio:/)
{
$driver = "virtio";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { driver => $driver }});
}
# If this is a virtual interface, set some fake values that don't actually exist on
# the system for the sake of a cleaner display.
if (($mac_address =~ /^52:54:00/) or ($driver eq "virtio"))
{
### Set some fake values.
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
if ((not $speed) or ($speed eq "-1"))
{
$speed = 10000;
}
if ((not $duplex) or ($duplex eq "unknown"))
{
$duplex = "full";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
speed => $speed,
duplex => $duplex,
}});
}
# If the state is 'down', set the speed to '0'.
if (not $link_state)
{
$speed = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }});
}
# Is this a bond interface?
if (-e "/proc/net/bonding/".$interface)
{
# Yup, we'll neet to dig into the bond proc files to get the proper slaved
# interface MAC addresses.
$type = "bond";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
# Read the bond mode.
$bond_mode = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/mode"});
$bond_mode =~ s/\s.*//;
$bond_mode =~ s/\n$//;
$primary_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary"});
$primary_interface =~ s/\n$//;
$primary_reselect = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary_reselect"});
$primary_reselect =~ s/\s.*//;
$primary_reselect =~ s/\n$//;
$active_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/active_slave"});
$active_interface =~ s/\n$//;
$mii_polling_interval = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/miimon"});
$mii_polling_interval =~ s/\n$//;
$up_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/updelay"});
$up_delay =~ s/\n$//;
$down_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/downdelay"});
$down_delay =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
active_interface => $active_interface,
bond_mode => $bond_mode,
mii_polling_interval => $mii_polling_interval,
primary_reselect => $primary_reselect,
primary_interface => $primary_interface,
type => $type,
}});
}
elsif ((-e $full_path."/master") && ($interface !~ /^vnet/))
{
# We're in a bond.
my $target = readlink($full_path."/master");
$bond_parent = ($target =~ /^.*\/(.*)$/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
target => $target,
bond_parent => $bond_parent,
}});
}
elsif (-d $full_path."/bridge")
{
# It's a bridge
$type = "bridge";
$bridge_id = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/bridge_id"});
$bridge_id =~ s/\n$//;
$bridge_stp_enabled = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/stp_state"});
$bridge_stp_enabled =~ s/\n$//;
$speed = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
type => $type,
bridge_id => $bridge_id,
bridge_stp_enabled => $bridge_stp_enabled,
}});
if ($bridge_stp_enabled eq "0")
{
$bridge_stp_enabled = "disabled";
}
elsif ($bridge_stp_enabled eq "1")
{
$bridge_stp_enabled = "enabled_kernel";
}
elsif ($bridge_stp_enabled eq "2")
{
$bridge_stp_enabled = "enabled_userland";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_stp_enabled => $bridge_stp_enabled }});
}
# If this is a 'vnet' device, set 'operational' to up
if ($interface =~ /^vnet/)
{
### TODO: We can't assume this, we need to detect virsh net up/down
$operational = "up";
$media = "virtual";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
operational => $operational,
media => $media,
}});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
active_interface => $active_interface,
bond_parent => $bond_parent,
bond_mode => $bond_mode,
bridge_id => $bridge_id,
bridge_stp_enabled => $bridge_stp_enabled,
down_delay => $down_delay,
duplex => $duplex,
interface => $interface,
mac_address => $mac_address,
mii_polling_interval => $mii_polling_interval,
mtu => $mtu,
operational => $operational,
primary_reselect => $primary_reselect,
primary_interface => $primary_interface,
speed => $speed,
subnet_mask => $subnet_mask,
type => $type,
up_delay => $up_delay,
}});
# Find the media, if possible.
(my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." ".$interface});
foreach my $line (split/\n/, $ethtool)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /Supported ports: \[ (.*?) \]/i)
{
$media = lc($1);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
# This can be 'tp mii', which breaks json.
if ($media =~ /\t/)
{
$media =~ s/\t/,/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
}
last;
}
}
# Trigger?
if (not exists $anvil->data->{last_scan}{$interface})
{
print "The interface: [".$interface."] has been found. We will now monitor it for changes.\n";
$trigger = 1;
}
else
{
# Now look for differences.
if ($anvil->data->{last_scan}{$interface}{active_interface} ne $active_interface)
{
print "The ".$type.": [".$interface."] has a different active interface: [".$anvil->data->{last_scan}{$interface}{active_interface}."] -> [".$active_interface."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{bond_mode} ne $bond_mode)
{
print "The ".$type.": [".$interface."] mode has changed from: [".$anvil->data->{last_scan}{$interface}{bond_mode}."] -> [".$bond_mode."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{bond_parent} ne $bond_parent)
{
print "The ".$type.": [".$interface."] bond parent has changed from: [".$anvil->data->{last_scan}{$interface}{bond_parent}."] -> [".$bond_parent."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{bridge_id} ne $bridge_id)
{
print "The ".$type.": [".$interface."] bridge ID has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_id}."] -> [".$bridge_id."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{bridge_stp_enabled} ne $bridge_stp_enabled)
{
print "The ".$type.": [".$interface."] spanning tree protocol (STP) setting has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_stp_enabled}."] -> [".$bridge_stp_enabled."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{down_delay} ne $down_delay)
{
print "The ".$type.": [".$interface."] down delay has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_stp_enabled}."ms] -> [".$bridge_stp_enabled."ms].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{up_delay} ne $up_delay)
{
print "The ".$type.": [".$interface."] up delay has changed from: [".$anvil->data->{last_scan}{$interface}{up_delay}."ms] -> [".$up_delay."ms].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{duplex} ne $duplex)
{
print "The ".$type.": [".$interface."] duplex has changed from: [".$anvil->data->{last_scan}{$interface}{duplex}."] -> [".$duplex."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{ip_address} ne $ip_address)
{
print "The ".$type.": [".$interface."] ip address has changed from: [".$anvil->data->{last_scan}{$interface}{ip_address}."] -> [".$ip_address."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{subnet_mask} ne $subnet_mask)
{
print "The ".$type.": [".$interface."] subnet_mask has changed from: [".$anvil->data->{last_scan}{$interface}{subnet_mask}."] -> [".$subnet_mask."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{link_state} ne $link_state)
{
print "The ".$type.": [".$interface."] link status has changed from: [".$anvil->data->{last_scan}{$interface}{link_state}."] -> [".$link_state."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{mac_address} ne $mac_address)
{
print "The ".$type.": [".$interface."] MAC address has changed from: [".$anvil->data->{last_scan}{$interface}{mac_address}."] -> [".$mac_address."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{media} ne $media)
{
print "The ".$type.": [".$interface."] media has changed from: [".$anvil->data->{last_scan}{$interface}{media}."] -> [".$media."]. (Excuse me, how?!)\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{mii_polling_interval} ne $mii_polling_interval)
{
print "The ".$type.": [".$interface."] media independent interface (mii) polling interval has changed from: [".$anvil->data->{last_scan}{$interface}{mii_polling_interval}."ms] -> [".$mii_polling_interval."ms].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{mtu} ne $mtu)
{
print "The ".$type.": [".$interface."] maximum transmission unit (mtu) has changed from: [".$anvil->data->{last_scan}{$interface}{mtu}." bytes] -> [".$mtu." bytes].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{operational} ne $operational)
{
print "The ".$type.": [".$interface."] operational status has changed from: [".$anvil->data->{last_scan}{$interface}{operational}."] -> [".$operational."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{primary_reselect} ne $primary_reselect)
{
print "The ".$type.": [".$interface."] primary reselect policy has changed from: [".$anvil->data->{last_scan}{$interface}{primary_reselect}."] -> [".$primary_reselect."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{primary_interface} ne $primary_interface)
{
print "The ".$type.": [".$interface."] primary interface has changed from: [".$anvil->data->{last_scan}{$interface}{primary_interface}."] -> [".$primary_interface."].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{speed} ne $speed)
{
print "The ".$type.": [".$interface."] speed has changed from: [".$anvil->data->{last_scan}{$interface}{speed}." Mbps] -> [".$speed." Mbps].\n";
$trigger = 1;
}
if ($anvil->data->{last_scan}{$interface}{type} ne $type)
{
print "The device: [".$interface."] type has changed from: [".$anvil->data->{last_scan}{$interface}{type}."] -> [".$type."].\n";
$trigger = 1;
}
}
# We'll use this to determine when an interface has disappeared.
$anvil->data->{last_scan}{$interface}{seen} = $scan_time;
# Store new information we found.
$anvil->data->{last_scan}{$interface}{active_interface} = $active_interface;
$anvil->data->{last_scan}{$interface}{bond_mode} = $bond_mode;
$anvil->data->{last_scan}{$interface}{bond_parent} = $bond_parent;
$anvil->data->{last_scan}{$interface}{bridge_id} = $bridge_id;
$anvil->data->{last_scan}{$interface}{bridge_stp_enabled} = $bridge_stp_enabled;
$anvil->data->{last_scan}{$interface}{down_delay} = $down_delay;
$anvil->data->{last_scan}{$interface}{duplex} = $duplex;
$anvil->data->{last_scan}{$interface}{ip_address} = $ip_address;
$anvil->data->{last_scan}{$interface}{link_state} = $link_state;
$anvil->data->{last_scan}{$interface}{mac_address} = $mac_address;
$anvil->data->{last_scan}{$interface}{media} = $media;
$anvil->data->{last_scan}{$interface}{mii_polling_interval} = $mii_polling_interval;
$anvil->data->{last_scan}{$interface}{mtu} = $mtu;
$anvil->data->{last_scan}{$interface}{operational} = $operational;
$anvil->data->{last_scan}{$interface}{primary_reselect} = $primary_reselect;
$anvil->data->{last_scan}{$interface}{primary_interface} = $primary_interface;
$anvil->data->{last_scan}{$interface}{speed} = $speed;
$anvil->data->{last_scan}{$interface}{subnet_mask} = $subnet_mask;
$anvil->data->{last_scan}{$interface}{type} = $type;
$anvil->data->{last_scan}{$interface}{up_delay} = $up_delay;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"last_scan::${interface}::seen" => $anvil->data->{last_scan}{$interface}{seen},
"last_scan::${interface}::active_interface" => $anvil->data->{last_scan}{$interface}{active_interface},
"last_scan::${interface}::bond_mode" => $anvil->data->{last_scan}{$interface}{bond_mode},
"last_scan::${interface}::bond_parent" => $anvil->data->{last_scan}{$interface}{bond_parent},
"last_scan::${interface}::bridge_id" => $anvil->data->{last_scan}{$interface}{bridge_id},
"last_scan::${interface}::bridge_stp_enabled" => $anvil->data->{last_scan}{$interface}{bridge_stp_enabled},
"last_scan::${interface}::down_delay" => $anvil->data->{last_scan}{$interface}{down_delay},
"last_scan::${interface}::duplex" => $anvil->data->{last_scan}{$interface}{duplex},
"last_scan::${interface}::ip_address" => $anvil->data->{last_scan}{$interface}{ip_address},
"last_scan::${interface}::link_state" => $anvil->data->{last_scan}{$interface}{link_state},
"last_scan::${interface}::mac_address" => $anvil->data->{last_scan}{$interface}{mac_address},
"last_scan::${interface}::media" => $anvil->data->{last_scan}{$interface}{media},
"last_scan::${interface}::mii_polling_interval" => $anvil->data->{last_scan}{$interface}{mii_polling_interval},
"last_scan::${interface}::mtu" => $anvil->data->{last_scan}{$interface}{mtu},
"last_scan::${interface}::operational" => $anvil->data->{last_scan}{$interface}{operational},
"last_scan::${interface}::primary_reselect" => $anvil->data->{last_scan}{$interface}{primary_reselect},
"last_scan::${interface}::primary_interface" => $anvil->data->{last_scan}{$interface}{primary_interface},
"last_scan::${interface}::speed" => $anvil->data->{last_scan}{$interface}{speed},
"last_scan::${interface}::subnet_mask" => $anvil->data->{last_scan}{$interface}{subnet_mask},
"last_scan::${interface}::type" => $anvil->data->{last_scan}{$interface}{type},
"last_scan::${interface}::up_delay" => $anvil->data->{last_scan}{$interface}{up_delay},
}});
}
}
closedir(DIRECTORY);
# Now look for interfaces that disappeared.
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{last_scan}})
{
next if $anvil->data->{last_scan}{$interface}{seen} == $scan_time;
print "The device: [".$interface."] appears to have disappeared!\n";
delete $anvil->data->{last_scan}{$interface};
$trigger = 1;
}
# Trigger?
if ($trigger)
{
my $shell_call = $anvil->data->{path}{directories}{scan_agents}."/scan-network/scan-network".$anvil->Log->switches;
print "Triggering the call to run: [".$shell_call."]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
if (time > $next_md5sum_check)
{
$next_md5sum_check = time + 30;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { next_md5sum_check => $next_md5sum_check }});
if ($anvil->Storage->check_md5sums)
{
# NOTE: We exit with '0' to prevent systemctl from showing a scary red message.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "message_0014"});
$anvil->nice_exit({exit_code => 0});
}
}
sleep 2;
}

@ -91,8 +91,8 @@ sub refresh_unified_metadata
backup => 0, backup => 0,
file => $anvil->data->{path}{data}{fences_unified_metadata}, file => $anvil->data->{path}{data}{fences_unified_metadata},
body => $anvil->data->{fences}{unified_xml}, body => $anvil->data->{fences}{unified_xml},
user => "apache", user => "striker-ui-api",
group => "apache", group => "striker-ui-api",
mode => "0666", mode => "0666",
}); });
} }

@ -321,8 +321,11 @@ sub run_jobs
# Make sure the VNC port is open. # Make sure the VNC port is open.
$anvil->Network->manage_firewall(); $anvil->Network->manage_firewall();
# Add the server to the cluster. # If we're not the peer, add the server to the cluster.
add_server_to_cluster($anvil); if (not $anvil->data->{job}{peer_mode})
{
add_server_to_cluster($anvil);
}
# Update the database by calling select scan agents # Update the database by calling select scan agents
$anvil->Job->update_progress({ $anvil->Job->update_progress({
@ -368,8 +371,9 @@ sub add_server_to_cluster
# Is our peer in the cluster? For that matter, are we? # Is our peer in the cluster? For that matter, are we?
my $problem = $anvil->Cluster->add_server({ my $problem = $anvil->Cluster->add_server({
debug => 2, debug => 2,
server_name => $anvil->data->{job}{server_name}, server_name => $anvil->data->{job}{server_name},
ok_if_exists => 1,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem) if ($problem)

@ -44,6 +44,11 @@ $anvil->Get->switches({list => [], man => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
### TODO: Remove before PR!
# Force up the logging.
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
# Make sure we're running as 'root' # Make sure we're running as 'root'
# $< == real UID, $> == effective UID # $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0)) if (($< != 0) && ($> != 0))
@ -94,7 +99,7 @@ if (not $anvil->data->{sys}{database}{connections})
# Check to see if we should run. Also checks/sets enable/disable requests. # Check to see if we should run. Also checks/sets enable/disable requests.
prerun_checks($anvil); prerun_checks($anvil);
# Wait until I can ping the peer on all three networks. This will not return until access is available on all # Wait until I can ping the peer on all networks. This will not return until access is available on all
# networks. There is no timeout. # networks. There is no timeout.
wait_for_access($anvil); wait_for_access($anvil);
@ -343,7 +348,7 @@ sub start_pacemaker
while ($waiting) while ($waiting)
{ {
$waiting = 0; $waiting = 0;
my ($problem) = $anvil->Cluster->parse_cib({debug => 3}); my ($problem) = $anvil->Cluster->parse_cib({debug => 2});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem) if ($problem)
{ {

@ -483,7 +483,7 @@ sub process_incoming_file
$anvil->nice_exit({exit_code => 1}); $anvil->nice_exit({exit_code => 1});
} }
# Change the owner as it'll be apache, which won't be a valid users on anvil members. # Change the owner as it'll be striker-ui-api, which won't be a valid users on anvil members.
$anvil->Storage->change_owner({ $anvil->Storage->change_owner({
debug => 2, debug => 2,
path => $target_file, path => $target_file,

File diff suppressed because it is too large Load Diff

@ -63,12 +63,17 @@ sub striker_checks
{ {
my ($anvil) = @_; my ($anvil) = @_;
# This checks to make sure that the new dr_links table exists, and that existing anvil_dr1_host_uuid # This checks to make sure that the new network manager columns are in place
# entries are copied. update_network_interfaces($anvil);
update_dr_links($anvil); update_bonds($anvil);
update_bridges($anvil);
# This checks to make sure that the new 'file_locations' -> 'file_location_ready' column exists. # This checks to make sure that the new 'file_locations' -> 'file_location_ready' column exists.
update_file_location_ready($anvil); update_file_location_ready($anvil);
# This checks to make sure that the new dr_links table exists, and that existing anvil_dr1_host_uuid
# entries are copied.
update_dr_links($anvil);
# This replaces anvil_uuid with host_uuid to support more granular location info to support the new # This replaces anvil_uuid with host_uuid to support more granular location info to support the new
# multi-target DR system # multi-target DR system
@ -243,12 +248,300 @@ CREATE TRIGGER trigger_dr_links
return(0); return(0);
} }
sub update_bridges
{
my ($anvil) = @_;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{
my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'bridges' AND column_name = 'bridge_nm_uuid';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, uuid => $uuid, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
my $queries = [];
push @{$queries}, "ALTER TABLE public.bridges ADD COLUMN bridge_nm_uuid uuid;";
push @{$queries}, "ALTER TABLE history.bridges ADD COLUMN bridge_nm_uuid uuid;";
push @{$queries}, "DROP FUNCTION history_bridges() CASCADE;";
push @{$queries}, q|CREATE FUNCTION history_bridges() RETURNS trigger
AS $$
DECLARE
history_bridges RECORD;
BEGIN
SELECT INTO history_bridges * FROM bridges WHERE bridge_uuid = new.bridge_uuid;
INSERT INTO history.bridges
(bridge_uuid,
bridge_host_uuid,
bridge_nm_uuid,
bridge_name,
bridge_id,
bridge_mac_address,
bridge_mtu,
bridge_stp_enabled,
modified_date)
VALUES
(history_bridges.bridge_uuid,
history_bridges.bridge_host_uuid,
history_bridges.bridge_nm_uuid,
history_bridges.bridge_name,
history_bridges.bridge_id,
history_bridges.bridge_mac_address,
history_bridges.bridge_mtu,
history_bridges.bridge_stp_enabled,
history_bridges.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_bridges() OWNER TO admin;
CREATE TRIGGER trigger_bridges
AFTER INSERT OR UPDATE ON bridges
FOR EACH ROW EXECUTE PROCEDURE history_bridges();
|;
foreach my $query (@{$queries})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
}
$anvil->Database->write({debug => 2, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
}
}
return(0);
}
sub update_bonds
{
my ($anvil) = @_;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{
my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'bonds' AND column_name = 'bond_nm_uuid';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, uuid => $uuid, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
my $queries = [];
push @{$queries}, "ALTER TABLE public.bonds ADD COLUMN bond_nm_uuid uuid;";
push @{$queries}, "ALTER TABLE history.bonds ADD COLUMN bond_nm_uuid uuid;";
push @{$queries}, "DROP FUNCTION history_bonds() CASCADE;";
push @{$queries}, q|CREATE FUNCTION history_bonds() RETURNS trigger
AS $$
DECLARE
history_bonds RECORD;
BEGIN
SELECT INTO history_bonds * FROM bonds WHERE bond_uuid = new.bond_uuid;
INSERT INTO history.bonds
(bond_uuid,
bond_host_uuid,
bond_nm_uuid,
bond_name,
bond_mode,
bond_mtu,
bond_primary_interface,
bond_primary_reselect,
bond_active_interface,
bond_mii_polling_interval,
bond_up_delay,
bond_down_delay,
bond_mac_address,
bond_operational,
bond_bridge_uuid,
modified_date)
VALUES
(history_bonds.bond_uuid,
history_bonds.bond_host_uuid,
history_bonds.bond_nm_uuid,
history_bonds.bond_name,
history_bonds.bond_mode,
history_bonds.bond_mtu,
history_bonds.bond_primary_interface,
history_bonds.bond_primary_reselect,
history_bonds.bond_active_interface,
history_bonds.bond_mii_polling_interval,
history_bonds.bond_up_delay,
history_bonds.bond_down_delay,
history_bonds.bond_mac_address,
history_bonds.bond_operational,
history_bonds.bond_bridge_uuid,
history_bonds.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_bonds() OWNER TO admin;
CREATE TRIGGER trigger_bonds
AFTER INSERT OR UPDATE ON bonds
FOR EACH ROW EXECUTE PROCEDURE history_bonds();
|;
foreach my $query (@{$queries})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
}
$anvil->Database->write({debug => 2, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
}
}
return(0);
}
sub update_network_interfaces
{
my ($anvil) = @_;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{
my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'network_interfaces' AND column_name = 'network_interface_device';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, uuid => $uuid, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
my $queries = [];
push @{$queries}, "ALTER TABLE public.network_interfaces ADD COLUMN network_interface_device text not null DEFAULT '';";
push @{$queries}, "ALTER TABLE history.network_interfaces ADD COLUMN network_interface_device text;";
push @{$queries}, "DROP FUNCTION history_network_interfaces() CASCADE;";
push @{$queries}, q|CREATE FUNCTION history_network_interfaces() RETURNS trigger
AS $$
DECLARE
history_network_interfaces RECORD;
BEGIN
SELECT INTO history_network_interfaces * FROM network_interfaces WHERE network_interface_uuid = new.network_interface_uuid;
INSERT INTO history.network_interfaces
(network_interface_uuid,
network_interface_host_uuid,
network_interface_nm_uuid,
network_interface_mac_address,
network_interface_name,
network_interface_device,
network_interface_speed,
network_interface_mtu,
network_interface_link_state,
network_interface_operational,
network_interface_duplex,
network_interface_medium,
network_interface_bond_uuid,
network_interface_bridge_uuid,
modified_date)
VALUES
(history_network_interfaces.network_interface_uuid,
history_network_interfaces.network_interface_host_uuid,
history_network_interfaces.network_interface_nm_uuid,
history_network_interfaces.network_interface_mac_address,
history_network_interfaces.network_interface_name,
history_network_interfaces.network_interface_device,
history_network_interfaces.network_interface_speed,
history_network_interfaces.network_interface_mtu,
history_network_interfaces.network_interface_link_state,
history_network_interfaces.network_interface_operational,
history_network_interfaces.network_interface_duplex,
history_network_interfaces.network_interface_medium,
history_network_interfaces.network_interface_bond_uuid,
history_network_interfaces.network_interface_bridge_uuid,
history_network_interfaces.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_network_interfaces() OWNER TO admin;
CREATE TRIGGER trigger_network_interfaces
AFTER INSERT OR UPDATE ON network_interfaces
FOR EACH ROW EXECUTE PROCEDURE history_network_interfaces();
|;
foreach my $query (@{$queries})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
}
$anvil->Database->write({debug => 2, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
}
$query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'network_interfaces' AND column_name = 'network_interface_nm_uuid';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$count = $anvil->Database->query({query => $query, uuid => $uuid, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
my $queries = [];
push @{$queries}, "ALTER TABLE public.network_interfaces ADD COLUMN network_interface_nm_uuid uuid;";
push @{$queries}, "ALTER TABLE history.network_interfaces ADD COLUMN network_interface_nm_uuid uuid;";
push @{$queries}, "DROP FUNCTION history_network_interfaces() CASCADE;";
push @{$queries}, q|CREATE FUNCTION history_network_interfaces() RETURNS trigger
AS $$
DECLARE
history_network_interfaces RECORD;
BEGIN
SELECT INTO history_network_interfaces * FROM network_interfaces WHERE network_interface_uuid = new.network_interface_uuid;
INSERT INTO history.network_interfaces
(network_interface_uuid,
network_interface_host_uuid,
network_interface_nm_uuid,
network_interface_mac_address,
network_interface_name,
network_interface_device,
network_interface_speed,
network_interface_mtu,
network_interface_link_state,
network_interface_operational,
network_interface_duplex,
network_interface_medium,
network_interface_bond_uuid,
network_interface_bridge_uuid,
modified_date)
VALUES
(history_network_interfaces.network_interface_uuid,
history_network_interfaces.network_interface_host_uuid,
history_network_interfaces.network_interface_nm_uuid,
history_network_interfaces.network_interface_mac_address,
history_network_interfaces.network_interface_name,
history_network_interfaces.network_interface_device,
history_network_interfaces.network_interface_speed,
history_network_interfaces.network_interface_mtu,
history_network_interfaces.network_interface_link_state,
history_network_interfaces.network_interface_operational,
history_network_interfaces.network_interface_duplex,
history_network_interfaces.network_interface_medium,
history_network_interfaces.network_interface_bond_uuid,
history_network_interfaces.network_interface_bridge_uuid,
history_network_interfaces.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_network_interfaces() OWNER TO admin;
CREATE TRIGGER trigger_network_interfaces
AFTER INSERT OR UPDATE ON network_interfaces
FOR EACH ROW EXECUTE PROCEDURE history_network_interfaces();
|;
foreach my $query (@{$queries})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
}
$anvil->Database->write({debug => 2, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
}
}
return(0);
}
# This checks to make sure that the new 'file_locations' -> 'file_location_ready' column exists. # This checks to make sure that the new 'file_locations' -> 'file_location_ready' column exists.
sub update_file_location_ready sub update_file_location_ready
{ {
my ($anvil) = @_; my ($anvil) = @_;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}}) foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{ {
my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'file_locations' AND column_name = 'file_location_ready';"; my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'file_locations' AND column_name = 'file_location_ready';";

@ -132,7 +132,7 @@ sub show_status
if ($anvil->data->{switches}{watch}) if ($anvil->data->{switches}{watch})
{ {
my $date = $anvil->Get->date_and_time(); my $date = $anvil->Get->date_and_time();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0382", variables => { date => $date }}); print $anvil->Words->string({key => "message_0382", variables => { date => $date }})."\n";
} }
print $anvil->data->{display}{status}; print $anvil->data->{display}{status};

@ -192,19 +192,19 @@ sub create_constraint
my $rule_found = 0; my $rule_found = 0;
my $rule_name = "drbd-fenced_".$target_server; my $rule_name = "drbd-fenced_".$target_server;
my $shell_call = $conf->{path}{exe}{pcs}." constraint location config show ".$target_server; my $shell_call = $conf->{path}{exe}{pcs}." constraint location config show ".$target_server;
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open (my $file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open (my $file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
if ($line =~ /Expression: $rule_name /) if ($line =~ /Expression: $rule_name /)
{ {
$rule_found = 1; $rule_found = 1;
to_log($conf, {message => "rule_found: [".$rule_found."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "rule_found: [".$rule_found."]", 'line' => __LINE__, level => 1});
last; last;
} }
} }
@ -220,14 +220,14 @@ sub create_constraint
# Set the node attribute # Set the node attribute
my $rule_set = 0; my $rule_set = 0;
$shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --update 1"; $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --update 1";
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
} }
close $file_handle; close $file_handle;
@ -235,19 +235,19 @@ sub create_constraint
$rule_set = 0; $rule_set = 0;
my $rule_output = ""; my $rule_output = "";
$shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query"; $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query";
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
if (($line =~ /name=$rule_name/) && ($line =~ /value=1/)) if (($line =~ /name=$rule_name/) && ($line =~ /value=1/))
{ {
$rule_set = 1; $rule_set = 1;
to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 1});
last; last;
} }
else else

@ -91,8 +91,10 @@ $anvil->Storage->record_md5sums();
# Connect to DBs. # Connect to DBs.
wait_for_database($anvil); wait_for_database($anvil);
### NOTE: We need to collect data from the start. Once confirmed this isn't introducing old problems, remove
### this function
# If we're not configured, sleep. # If we're not configured, sleep.
wait_until_configured($anvil); #wait_until_configured($anvil);
# Startup tasks. # Startup tasks.
startup_tasks($anvil); startup_tasks($anvil);
@ -141,7 +143,7 @@ while(1)
if ($anvil->data->{sys}{database}{connections}) if ($anvil->data->{sys}{database}{connections})
{ {
# Run the normal tasks # Run the normal tasks
$anvil->ScanCore->call_scan_agents(); $anvil->ScanCore->call_scan_agents({debug => 2});
# Do post-scan analysis. # Do post-scan analysis.
$anvil->ScanCore->post_scan_analysis({debug => 2}); $anvil->ScanCore->post_scan_analysis({debug => 2});

@ -1288,6 +1288,7 @@ fi;
remote_user => "root", remote_user => "root",
}}); }});
my ($host_uuid, $error, $return_code) = $anvil->Remote->call({ my ($host_uuid, $error, $return_code) = $anvil->Remote->call({
debug => 2,
shell_call => $shell_call, shell_call => $shell_call,
target => $ip, target => $ip,
password => $anvil->data->{base}{password}{desired}, password => $anvil->data->{base}{password}{desired},

@ -353,12 +353,13 @@ sub collect_remote_data
# Copying the file # Copying the file
print "Done! Copying to here... "; print "Done! Copying to here... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/journalctl-previous-boot.log", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/journalctl-previous-boot.log",
destination => $target_directory."/", destination => $target_directory."/",
}); });
my $test_file = $target_directory."/tmp/journalctl-previous-boot.log"; my $test_file = $target_directory."/tmp/journalctl-previous-boot.log";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -392,12 +393,13 @@ sub collect_remote_data
# Copying the file # Copying the file
print "Done! Copying to here... "; print "Done! Copying to here... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/journalctl-current-boot.log", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/journalctl-current-boot.log",
destination => $target_directory."/", destination => $target_directory."/",
}); });
$test_file = $target_directory."/journalctl-current-boot.log"; $test_file = $target_directory."/journalctl-current-boot.log";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -431,12 +433,13 @@ sub collect_remote_data
{ {
print "- Grabbing cloud-init logs... "; print "- Grabbing cloud-init logs... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/var/log/cloud-init*", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/var/log/cloud-init*",
destination => $target_directory."/", destination => $target_directory."/",
}); });
$test_file = $target_directory."/cloud-init.log"; $test_file = $target_directory."/cloud-init.log";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -499,12 +502,13 @@ sub collect_remote_data
print "- Grabbing hosts file... "; print "- Grabbing hosts file... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/etc/hosts", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/etc/hosts",
destination => $target_directory."/", destination => $target_directory."/",
}); });
$test_file = $target_directory."/hosts"; $test_file = $target_directory."/hosts";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -522,12 +526,13 @@ sub collect_remote_data
print "- Grabbing Anvil! log... "; print "- Grabbing Anvil! log... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/var/log/anvil.log", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/var/log/anvil.log",
destination => $target_directory."/", destination => $target_directory."/",
}); });
$test_file = $target_directory."/anvil.log"; $test_file = $target_directory."/anvil.log";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -559,12 +564,13 @@ sub collect_remote_data
# Copying the file # Copying the file
print "Done! Copying to here... "; print "Done! Copying to here... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/cib.xml", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/tmp/cib.xml",
destination => $target_directory."/", destination => $target_directory."/",
}); });
my $test_file = $target_directory."/cib.xml"; my $test_file = $target_directory."/cib.xml";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
if (not -e $test_file) if (-e $test_file)
{ {
print "Done.\n"; print "Done.\n";
} }
@ -586,6 +592,7 @@ sub collect_remote_data
{ {
print "- Collecting server definitions... "; print "- Collecting server definitions... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/mnt/shared/definitions", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/mnt/shared/definitions",
destination => $target_directory."/", destination => $target_directory."/",
}); });
@ -593,6 +600,7 @@ sub collect_remote_data
print "- Collecting replicated storage config... "; print "- Collecting replicated storage config... ";
$anvil->Storage->rsync({ $anvil->Storage->rsync({
debug => 2,
source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/etc/drbd.d", source => "root\@".$anvil->data->{peer}{$short_host_name}{access}{ip}.":/etc/drbd.d",
destination => $target_directory."/", destination => $target_directory."/",
}); });

@ -163,7 +163,7 @@ sub add_databases
$anvil->Network->get_ips({debug => 3}); $anvil->Network->get_ips({debug => 3});
$anvil->Network->get_ips({ $anvil->Network->get_ips({
debug => 3, debug => 2,
target => $target, target => $target,
remote_user => "root", remote_user => "root",
password => $anvil->data->{data}{password}, password => $anvil->data->{data}{password},
@ -171,7 +171,7 @@ sub add_databases
}); });
my $local_host = $anvil->Get->short_host_name(); my $local_host = $anvil->Get->short_host_name();
my ($match) = $anvil->Network->find_matches({ my ($match) = $anvil->Network->find_matches({
debug => 3, debug => 2,
first => $local_host, first => $local_host,
second => $target, second => $target,
source => $THIS_FILE, source => $THIS_FILE,
@ -283,6 +283,7 @@ sub add_databases
# Find a match between the target and the peer. # Find a match between the target and the peer.
my ($match) = $anvil->Network->find_matches({ my ($match) = $anvil->Network->find_matches({
debug => 2,
first => $target, first => $target,
second => $uuid, second => $uuid,
source => $THIS_FILE, source => $THIS_FILE,

@ -709,7 +709,7 @@ sub setup_boot_environment
{ {
# Updated # Updated
$anvil->Storage->change_mode({path => $kickstart_file, mode => "0664"}); $anvil->Storage->change_mode({path => $kickstart_file, mode => "0664"});
$anvil->Storage->change_owner({path => $kickstart_file, user => "apache", group => "apache" }); $anvil->Storage->change_owner({path => $kickstart_file, user => "striker-ui-api", group => "striker-ui-api" });
print $anvil->Words->string({key => "message_0097", variables => { file => $kickstart_file }})."\n"; print $anvil->Words->string({key => "message_0097", variables => { file => $kickstart_file }})."\n";
update_progress($anvil, $progress, "message_0097,!!file!".$kickstart_file."!!"); update_progress($anvil, $progress, "message_0097,!!file!".$kickstart_file."!!");

@ -475,7 +475,7 @@ if ($local_uuid)
##################################################################################################### #####################################################################################################
### TODO: This will need to set the proper SELinux context. ### TODO: This will need to set the proper SELinux context.
# Apache run scripts can't call the system UUID, so we'll write it to a text file. # striker-ui-api run scripts can't call the system UUID, so we'll write it to a text file.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "path::data::host_uuid" => $anvil->data->{path}{data}{host_uuid} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "path::data::host_uuid" => $anvil->data->{path}{data}{host_uuid} }});
if (not -e $anvil->data->{path}{data}{host_uuid}) if (not -e $anvil->data->{path}{data}{host_uuid})
{ {
@ -483,8 +483,8 @@ if ($local_uuid)
debug => 3, debug => 3,
file => $anvil->data->{path}{data}{host_uuid}, file => $anvil->data->{path}{data}{host_uuid},
body => $anvil->Get->host_uuid, body => $anvil->Get->host_uuid,
user => "apache", user => "striker-ui-api",
group => "apache", group => "striker-ui-api",
mode => "0666", mode => "0666",
overwrite => 0, overwrite => 0,
}); });

@ -158,19 +158,19 @@ sub remove_constraint
my $rule_found = 0; my $rule_found = 0;
my $rule_output = ""; my $rule_output = "";
my $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query"; my $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query";
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open (my $file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open (my $file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
if (($line =~ /name=$rule_name/) && ($line =~ /value=0/)) if (($line =~ /name=$rule_name/) && ($line =~ /value=0/))
{ {
$rule_set = 0; $rule_set = 0;
to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 1});
last; last;
} }
else else
@ -189,33 +189,33 @@ sub remove_constraint
# Clear the node attribute # Clear the node attribute
$shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --update 0"; $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --update 0";
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 3}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
} }
close $file_handle; close $file_handle;
# Check that the rule was set. # Check that the rule was set.
$rule_output = ""; $rule_output = "";
$shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query"; $shell_call = $conf->{path}{exe}{crm_attribute}." --type nodes --node ".$target_node." --name ".$rule_name." --query";
to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Calling: [".$shell_call."]", 'line' => __LINE__, level => 1});
open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n"; open ($file_handle, $shell_call." 2>&1 |") or die "Failed to call: [".$shell_call."]. The error was: $!\n";
while(<$file_handle>) while(<$file_handle>)
{ {
# This should not generate output. # This should not generate output.
chomp; chomp;
my $line = $_; my $line = $_;
to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "Output: [".$line."]", 'line' => __LINE__, level => 1});
if (($line =~ /name=$rule_name/) && ($line =~ /value=0/)) if (($line =~ /name=$rule_name/) && ($line =~ /value=0/))
{ {
$rule_set = 0; $rule_set = 0;
to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 2}); to_log($conf, {message => "rule_set: [".$rule_set."]", 'line' => __LINE__, level => 1});
last; last;
} }
else else

@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in
servicedir = $(SYSTEMD_UNIT_DIR) servicedir = $(SYSTEMD_UNIT_DIR)
dist_service_DATA = \ dist_service_DATA = \
anvil-daemon.service \ anvil-daemon.service \
anvil-monitor-network.service \
anvil-safe-start.service \ anvil-safe-start.service \
scancore.service \ scancore.service \
striker-ui-api.service striker-ui-api.service

@ -0,0 +1,12 @@
[Unit]
Description=Anvil! Intelligent Availability Platform - Network Monitor Daemon
Wants=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/anvil-monitor-network
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always
[Install]
WantedBy=multi-user.target
Loading…
Cancel
Save