* Updated the RPM spec file to generate '/etc/anvil/type.X' files to directly indicate the machine type. Updated System->get_host_type() to check for these files directly, falling back to parsing the host name if they don't exist.

* Created Database->get_hosts_info() (though it's not at all finished) that will write out a unified JSON file contain all data known about all hosts/Anvil! systems. This will be later used to create the WebUI parts.
* Also created, but also not finished, Network->load_interfces() that will work sort of like ->load_ups, but include all interfaces regardless of if they have an IP or not.
* Fixed a bug where the new bridge_interface_note parameter didn't exist in the Database->insert_or_update_bridge_interfaces() method.
* Updated anvil-update-states() to only write out the JSON/XML files if it's running on a dashboard. For nodes and DR hosts, it just needs to update the database.
* Created a new hook in anvil-daemon that will call tasks on a machine that is configured.
* As per RHEL 8.1 release notes, changed the package 'dnf-utils' to 'yum-utils' in the packages to load for install target repos.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 077977ad9c
commit 628f7faa45
  1. 3
      Anvil/Tools.pm
  2. 114
      Anvil/Tools/Database.pm
  3. 73
      Anvil/Tools/Network.pm
  4. 23
      Anvil/Tools/System.pm
  5. 67
      rpm/SPECS/anvil.spec
  6. 2
      share/words.xml
  7. 28
      tools/anvil-daemon
  8. 134
      tools/anvil-update-states
  9. 3
      tools/striker-initialize-host
  10. 3
      tools/striker-manage-install-target

@ -1022,6 +1022,9 @@ sub _set_paths
'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",
ssh_config => "/etc/ssh/ssh_config", ssh_config => "/etc/ssh/ssh_config",
'type.dashboard' => "/etc/anvil/type.dashboard",
'type.dr' => "/etc/anvil/type.dr",
'type.node' => "/etc/anvil/type.node",
}, },
data => { data => {
'.htpasswd' => "/etc/httpd/.htpasswd", '.htpasswd' => "/etc/httpd/.htpasswd",

@ -23,6 +23,7 @@ my $THIS_FILE = "Database.pm";
# get_alert_recipients # get_alert_recipients
# get_host_from_uuid # get_host_from_uuid
# get_hosts # get_hosts
# get_hosts_info
# get_job_details # get_job_details
# get_jobs # get_jobs
# get_local_uuid # get_local_uuid
@ -1533,6 +1534,94 @@ FROM
return($return); return($return);
} }
=head2 get_hosts_info
This gathers up all the known information about all known hosts.
=cut
sub get_hosts_info
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_hosts()" }});
my $query = "
SELECT
host_uuid,
host_name,
host_type,
host_key
FROM
hosts
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $host_uuid = $row->[0];
my $host_name = $row->[1];
my $host_type = $row->[2];
my $host_key = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
host_key => $host_key,
}});
$anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_name} = $host_name;
$anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_type} = $host_type;
$anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_key} = $host_key;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"machine::host_uuid::${host_uuid}::hosts::host_name" => $anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_name},
"machine::host_uuid::${host_uuid}::hosts::host_type" => $anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_type},
"machine::host_uuid::${host_uuid}::hosts::host_key" => $anvil->data->{machine}{host_uuid}{$host_uuid}{hosts}{host_key},
}});
# Read in the variables.
my $query = "
SELECT
variable_name,
variable_value
FROM
variables
WHERE
variable_source_uuid = ".$anvil->Database->quote($host_uuid)."
AND
variable_source_table = 'hosts'
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $variable_name = $row->[0];
my $variable_value = $row->[1];
$anvil->data->{machine}{host_uuid}{$host_uuid}{variables}{$variable_name} = $variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"machine::host_uuid::${host_uuid}::hosts::variables::${variable_name}" => $anvil->data->{machine}{host_uuid}{$host_uuid}{variables}{$variable_name},
}});
}
# Read in the IP addresses and network information.
}
return(0);
}
=head2 get_job_details =head2 get_job_details
This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in. This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in.
@ -2004,22 +2093,26 @@ If set, this is the file name logged as the source of any INSERTs or UPDATEs.
If set, this is the file line number logged as the source of any INSERTs or UPDATEs. If set, this is the file line number logged as the source of any INSERTs or UPDATEs.
=head2 bridge_interface_uuid (optional) =head3 bridge_interface_uuid (optional)
If not passed, a check will be made to see if an existing entry is found for C<< bridge_interface_bridge_uuid >> and C<< bridge_interface_network_interface_uuid >>. If found, that entry will be updated. If not found, a new record will be inserted. If not passed, a check will be made to see if an existing entry is found for C<< bridge_interface_bridge_uuid >> and C<< bridge_interface_network_interface_uuid >>. If found, that entry will be updated. If not found, a new record will be inserted.
=head2 bridge_interface_host_uuid (optional) =head3 bridge_interface_host_uuid (optional)
This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address). This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address).
=head2 bridge_interface_bridge_uuid (required) =head3 bridge_interface_bridge_uuid (required)
This is the C<< bridges -> bridge_uuid >> of the bridge that this interface is connected to. This is the C<< bridges -> bridge_uuid >> of the bridge that this interface is connected to.
=head2 bridge_interface_network_interface_uuid (required) =head3 bridge_interface_network_interface_uuid (required)
This is the C<< network_interfaces -> network_interface_uuid >> if the interface connected to the specified bridge. This is the C<< network_interfaces -> network_interface_uuid >> if the interface connected to the specified bridge.
=head3 bridge_interface_note (optional)
When this is set to C<< DELETED >>, the interface will be flagged as removed by the system
=cut =cut
sub insert_or_update_bridge_interfaces sub insert_or_update_bridge_interfaces
{ {
@ -2036,6 +2129,7 @@ sub insert_or_update_bridge_interfaces
my $bridge_interface_host_uuid = defined $parameter->{bridge_interface_host_uuid} ? $parameter->{bridge_interface_host_uuid} : $anvil->data->{sys}{host_uuid}; my $bridge_interface_host_uuid = defined $parameter->{bridge_interface_host_uuid} ? $parameter->{bridge_interface_host_uuid} : $anvil->data->{sys}{host_uuid};
my $bridge_interface_bridge_uuid = defined $parameter->{bridge_interface_bridge_uuid} ? $parameter->{bridge_interface_bridge_uuid} : ""; my $bridge_interface_bridge_uuid = defined $parameter->{bridge_interface_bridge_uuid} ? $parameter->{bridge_interface_bridge_uuid} : "";
my $bridge_interface_network_interface_uuid = defined $parameter->{bridge_interface_network_interface_uuid} ? $parameter->{bridge_interface_network_interface_uuid} : ""; my $bridge_interface_network_interface_uuid = defined $parameter->{bridge_interface_network_interface_uuid} ? $parameter->{bridge_interface_network_interface_uuid} : "";
my $bridge_interface_note = defined $parameter->{bridge_interface_note} ? $parameter->{bridge_interface_note} : "";
$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,
@ -2044,6 +2138,7 @@ sub insert_or_update_bridge_interfaces
bridge_interface_host_uuid => $bridge_interface_host_uuid, bridge_interface_host_uuid => $bridge_interface_host_uuid,
bridge_interface_bridge_uuid => $bridge_interface_bridge_uuid, bridge_interface_bridge_uuid => $bridge_interface_bridge_uuid,
bridge_interface_network_interface_uuid => $bridge_interface_network_interface_uuid, bridge_interface_network_interface_uuid => $bridge_interface_network_interface_uuid,
bridge_interface_note => $bridge_interface_note,
}}); }});
if (not $bridge_interface_bridge_uuid) if (not $bridge_interface_bridge_uuid)
@ -2125,12 +2220,14 @@ INSERT INTO
bridge_interface_host_uuid, bridge_interface_host_uuid,
bridge_interface_bridge_uuid, bridge_interface_bridge_uuid,
bridge_interface_network_interface_uuid, bridge_interface_network_interface_uuid,
bridge_interface_note,
modified_date modified_date
) VALUES ( ) VALUES (
".$anvil->Database->quote($bridge_interface_uuid).", ".$anvil->Database->quote($bridge_interface_uuid).",
".$anvil->Database->quote($bridge_interface_host_uuid).", ".$anvil->Database->quote($bridge_interface_host_uuid).",
".$anvil->Database->quote($bridge_interface_bridge_uuid).", ".$anvil->Database->quote($bridge_interface_bridge_uuid).",
".$anvil->Database->quote($bridge_interface_network_interface_uuid).", ".$anvil->Database->quote($bridge_interface_network_interface_uuid).",
".$anvil->Database->quote($bridge_interface_note).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
); );
"; ";
@ -2144,7 +2241,8 @@ INSERT INTO
SELECT SELECT
bridge_interface_host_uuid, bridge_interface_host_uuid,
bridge_interface_bridge_uuid, bridge_interface_bridge_uuid,
bridge_interface_network_interface_uuid bridge_interface_network_interface_uuid,
bridge_interface_note
FROM FROM
bridge_interfaces bridge_interfaces
WHERE WHERE
@ -2169,16 +2267,19 @@ WHERE
my $old_bridge_interface_host_uuid = $row->[0]; my $old_bridge_interface_host_uuid = $row->[0];
my $old_bridge_interface_bridge_uuid = $row->[1]; my $old_bridge_interface_bridge_uuid = $row->[1];
my $old_bridge_interface_network_interface_uuid = $row->[2]; my $old_bridge_interface_network_interface_uuid = $row->[2];
my $old_bridge_interface_note = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_bridge_interface_host_uuid => $old_bridge_interface_host_uuid, old_bridge_interface_host_uuid => $old_bridge_interface_host_uuid,
old_bridge_interface_bridge_uuid => $old_bridge_interface_bridge_uuid, old_bridge_interface_bridge_uuid => $old_bridge_interface_bridge_uuid,
old_bridge_interface_network_interface_uuid => $old_bridge_interface_network_interface_uuid, old_bridge_interface_network_interface_uuid => $old_bridge_interface_network_interface_uuid,
old_bridge_interface_note => $old_bridge_interface_note,
}}); }});
# Anything change? # Anything change?
if (($old_bridge_interface_host_uuid ne $bridge_interface_host_uuid) or if (($old_bridge_interface_host_uuid ne $bridge_interface_host_uuid) or
($old_bridge_interface_bridge_uuid ne $bridge_interface_bridge_uuid) or ($old_bridge_interface_bridge_uuid ne $bridge_interface_bridge_uuid) or
($old_bridge_interface_network_interface_uuid ne $bridge_interface_network_interface_uuid)) ($old_bridge_interface_network_interface_uuid ne $bridge_interface_network_interface_uuid) or
($old_bridge_interface_note ne $bridge_interface_note))
{ {
# Something changed, save. # Something changed, save.
my $query = " my $query = "
@ -2188,6 +2289,7 @@ SET
bridge_interface_host_uuid = ".$anvil->Database->quote($bridge_interface_host_uuid).", bridge_interface_host_uuid = ".$anvil->Database->quote($bridge_interface_host_uuid).",
bridge_interface_bridge_uuid = ".$anvil->Database->quote($bridge_interface_bridge_uuid).", bridge_interface_bridge_uuid = ".$anvil->Database->quote($bridge_interface_bridge_uuid).",
bridge_interface_network_interface_uuid = ".$anvil->Database->quote($bridge_interface_network_interface_uuid).", bridge_interface_network_interface_uuid = ".$anvil->Database->quote($bridge_interface_network_interface_uuid).",
bridge_interface_note = ".$anvil->Database->quote($bridge_interface_note).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE WHERE
bridge_interface_uuid = ".$anvil->Database->quote($bridge_interface_uuid)." bridge_interface_uuid = ".$anvil->Database->quote($bridge_interface_uuid)."

@ -19,6 +19,7 @@ my $THIS_FILE = "Network.pm";
# get_ips # get_ips
# get_network # get_network
# is_local # is_local
# load_interfces
# load_ips # load_ips
# ping # ping
@ -725,6 +726,70 @@ sub find_matches
return($match); return($match);
} }
=head2 load_interfces
This loads all network information for the given host UUID.
The main difference from C<< ->load_ips() >> is that this method loads information about all interfaces, regardless of if they have an IP, as well as their link state and link information.
The loaded data will be stored as:
* C<< machine::<target>::interface::<iface_name>::
Parameters;
=head3 clear (optional, default '1')
When set, any previously known information is cleared. Specifically, the C<< network::<target>> >> hash is deleted prior to the load. To prevent this, set this to C<< 0 >>.
=head3 host (optional, default is 'host_uuid' value)
This is the optional C<< target >> string to use in the hash where the data is stored.
=head3 host_uuid (optional, default 'sys::host_uuid')
This is the C<< host_uuid >> of the hosts whose IP and interface data that you want to load. The default is to load the local machine's data.
=cut
sub load_interfces
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->find_matches()" }});
my $clear = defined $parameter->{clear} ? $parameter->{clear} : 1;
my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->data->{sys}{host_uuid};
my $host = defined $parameter->{host} ? $parameter->{host} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
clear => $clear,
host => $host,
host_uuid => $host_uuid,
}});
if (not $host_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->get_network()", parameter => "ip" }});
return("");
}
if (not $host)
{
$host = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host => $host }});
}
if (($clear) && (exists $anvil->data->{network}{$host}))
{
delete $anvil->data->{network}{$host};
}
my $query = "";
return(0);
}
=head2 load_ips =head2 load_ips
This method loads and stores the same data as the C<< get_ips >> method, but does so by loading data from the database, instead of collecting it directly from the host. As such, it can also be used by C<< find_matches >>. This method loads and stores the same data as the C<< get_ips >> method, but does so by loading data from the database, instead of collecting it directly from the host. As such, it can also be used by C<< find_matches >>.
@ -742,6 +807,10 @@ The loaded data will be stored as:
Parameters; Parameters;
=head3 clear (optional, default '1')
When set, any previously known information is cleared. Specifically, the C<< network::<target>> >> hash is deleted prior to the load. To prevent this, set this to C<< 0 >>.
=head3 host (optional, default is 'host_uuid' value) =head3 host (optional, default is 'host_uuid' value)
This is the optional C<< target >> string to use in the hash where the data is stored. This is the optional C<< target >> string to use in the hash where the data is stored.
@ -759,9 +828,11 @@ sub load_ips
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 => "Network->find_matches()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->find_matches()" }});
my $clear = defined $parameter->{clear} ? $parameter->{clear} : 1;
my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->data->{sys}{host_uuid}; my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->data->{sys}{host_uuid};
my $host = defined $parameter->{host} ? $parameter->{host} : ""; my $host = defined $parameter->{host} ? $parameter->{host} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
clear => $clear,
host => $host, host => $host,
host_uuid => $host_uuid, host_uuid => $host_uuid,
}}); }});
@ -778,7 +849,7 @@ sub load_ips
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host => $host }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host => $host }});
} }
if (exists $anvil->data->{network}{$host}) if (($clear) && (exists $anvil->data->{network}{$host}))
{ {
delete $anvil->data->{network}{$host}; delete $anvil->data->{network}{$host};
} }

@ -931,7 +931,9 @@ This method tries to determine the host type and returns a value suitable for us
First, it looks to see if C<< sys::host_type >> is set and, if so, uses that string as it is. First, it looks to see if C<< sys::host_type >> is set and, if so, uses that string as it is.
If that isn't set, it then looks at the short host name. The following rules are used, in order; If that isn't set, it then looks to see if the file C<< /etc/anvil/type.X >> exists, where C<< X >> is C<< node >>, C<< dashboard >> or C<< dr >>. If found, the appropriate type is returned.
If that file doesn't exist, then it looks at the short host name. The following rules are used, in order;
1. If the host name ends in C<< n<digits> >> or C<< node<digits> >>, C<< node >> is returned. 1. If the host name ends in C<< n<digits> >> or C<< node<digits> >>, C<< node >> is returned.
2. If the host name ends in C<< striker<digits> >> or C<< dashboard<digits> >>, C<< dashboard >> is returned. 2. If the host name ends in C<< striker<digits> >> or C<< dashboard<digits> >>, C<< dashboard >> is returned.
@ -959,6 +961,24 @@ sub get_host_type
$host_type = $anvil->data->{sys}{host_type}; $host_type = $anvil->data->{sys}{host_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
} }
else
{
# Can I determine it by seeing a file?
if (-e $anvil->data->{path}{configs}{'type.node'})
{
$host_type = "node";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
}
elsif (-e $anvil->data->{path}{configs}{'type.dashboard'})
{
$host_type = "dashboard";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
}
elsif (-e $anvil->data->{path}{configs}{'type.dr'})
{
$host_type = "dr";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
}
elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/) or ($host_name =~ /new-node+$/)) elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/) or ($host_name =~ /new-node+$/))
{ {
$host_type = "node"; $host_type = "node";
@ -974,6 +994,7 @@ sub get_host_type
$host_type = "dr"; $host_type = "dr";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
} }
}
return($host_type); return($host_type);
} }

@ -225,6 +225,18 @@ echo "Preparing the database"
striker-prep-database striker-prep-database
anvil-update-states anvil-update-states
# Touch the system type file.
echo "Touching the system type file"
if [ -e '/etc/anvil/type.node' ]
then
rm -f /etc/anvil/type.node
elif [ -e '/etc/anvil/type.dr' ]
then
rm -f /etc/anvil/type.dr
fi
touch /etc/anvil/type.dashboard
### TODO: I don't think we need this anymore ### TODO: I don't think we need this anymore
# Open access for Striker. The database will be opened after initial setup. # Open access for Striker. The database will be opened after initial setup.
echo "Opening the web and postgresql ports." echo "Opening the web and postgresql ports."
@ -237,6 +249,35 @@ firewall-cmd --add-service=postgresql --permanent
%pre node %pre node
%post node
# Touch the system type file.
echo "Touching the system type file"
if [ -e '/etc/anvil/type.dashboard' ]
then
rm -f /etc/anvil/type.dashboard
elif [ -e '/etc/anvil/type.dr' ]
then
rm -f /etc/anvil/type.dr
fi
touch /etc/anvil/type.node
%pre dr
%post dr
# Touch the system type file.
echo "Touching the system type file"
if [ -e '/etc/anvil/type.dashboard' ]
then
rm -f /etc/anvil/type.dashboard
elif [ -e '/etc/anvil/type.node' ]
then
rm -f /etc/anvil/type.node
fi
touch /etc/anvil/type.dr
### Remove stuff - Disabled for now, messes things up during upgrades ### Remove stuff - Disabled for now, messes things up during upgrades
%postun core %postun core
## This is breaking on upgrades - (note: switch back to single percent sign ## This is breaking on upgrades - (note: switch back to single percent sign
@ -263,6 +304,26 @@ firewall-cmd --add-service=postgresql --permanent
# systemctl disable postgresql.service # systemctl disable postgresql.service
# systemctl stop postgresql.service # systemctl stop postgresql.service
# Remove the system type file.
if [ -e '/etc/anvil/type.dashboard' ]
then
rm -f /etc/anvil/type.dashboard
fi
%postun node
# Remove the system type file.
if [ -e '/etc/anvil/type.node' ]
then
rm -f /etc/anvil/type.node
fi
%postun dr
# Remove the system type file.
if [ -e '/etc/anvil/type.dr' ]
then
rm -f /etc/anvil/type.dr
fi
%files core %files core
%doc README.md notes %doc README.md notes
@ -287,8 +348,10 @@ firewall-cmd --add-service=postgresql --permanent
%changelog %changelog
* tbd Madison Kelly <mkelly@alteeve.ca> 3.0-29 * Wed Nov 6 2019 Madison Kelly <mkelly@alteeve.ca> 3.0-29
- - Added '/etc/anvil/type.X' file creation to more directly mark a system as a
specific type, rather than divining by name.
- Updated source.
* Mon Oct 28 2019 Madison Kelly <mkelly@alteeve.ca> 3.0-28 * Mon Oct 28 2019 Madison Kelly <mkelly@alteeve.ca> 3.0-28
- Updated source - Updated source

@ -776,7 +776,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a
#!variable!section!# #!variable!section!#
==== ====
</key> </key>
<key name="log_0445">[ Note ] - We're about to do a ping scan of: [#!variable!range!#]. This could take a long time, please be patient! If you think this process is hung, please run 'pgrep nmap' on the host. If a process is returned, this is still running. We go slow to avoid upsetting network security devices or admin.</key> <key name="log_0445"><![CDATA[[ Note ] - We're about to do a ping scan of: [#!variable!range!#]. This could take a long time, please be patient!<br />If you think this process is hung, please run 'pgrep nmap' on the host. If a process is returned, this is still running. We go slow to avoid upsetting network security devices or admin.]]></key>
<key name="log_0446">Found the network device: [#!variable!mac!#] usingt the IP address: [#!variable!ip!#].</key> <key name="log_0446">Found the network device: [#!variable!mac!#] usingt the IP address: [#!variable!ip!#].</key>
<key name="log_0447">About to download: [#!variable!url!#] and save it to: [#!variable!file!#].</key> <key name="log_0447">About to download: [#!variable!url!#] and save it to: [#!variable!file!#].</key>
<key name="log_0448">Ready to parse: [#!variable!file!#].</key> <key name="log_0448">Ready to parse: [#!variable!file!#].</key>

@ -1133,11 +1133,19 @@ sub keep_running
} }
} }
# Update hardware state files if the system isn't configured. Running it always is too intensive. # If we're confiugured, 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 $configured) if ($configured)
{
# 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
# constantly).
update_striker_json($anvil);
}
else
{ {
# Run this to monitor the network in real time.
update_state_file($anvil); update_state_file($anvil);
} }
@ -1147,6 +1155,22 @@ sub keep_running
return(0); return(0);
} }
# This writes out the main JSON file used by Striker to display information about unconfigured nodes/dr
# hosts, and known Anvil! / node / server states.
sub update_striker_json
{
my ($anvil) = @_;
# Start by recording information about currently unconfigured nodes and DR hosts.
my $striker_json_body = "{\"unconfigured\":[\n";
# Collect data on unconfigured hosts.
my ($hosts) = $anvil->Database->get_hosts({debug => 3});
return(0);
}
# This will check for any jobs that aren't at 100%. For each found, if 'picked_up_by' is set, a check is made # This will check for any jobs that aren't at 100%. For each found, if 'picked_up_by' is set, a check is made
# to see if the PID is still alive. If it isn't, or if 'picked_up_by' is not set, the appropriate tool is # to see if the PID is still alive. If it isn't, or if 'picked_up_by' is not set, the appropriate tool is
# invoked to handle it. # invoked to handle it.

@ -20,10 +20,10 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
my $anvil = Anvil::Tools->new(); my $anvil = Anvil::Tools->new();
$anvil->Log->level({set => 2}); $anvil->Log->level({set => 2});
$anvil->Log->secure({set => 0}); $anvil->Log->secure({set => 0});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Database->connect({debug => 3}); $anvil->Database->connect({debug => 3});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections}) if (not $anvil->data->{sys}{database}{connections})
{ {
# No databases, exit. # No databases, exit.
@ -52,7 +52,7 @@ sub update_network
# * 'network::local::interface::<iface_name>::ip' - If an IP address is set # * 'network::local::interface::<iface_name>::ip' - If an IP address is set
# * 'network::local::interface::<iface_name>::subnet' - If an IP is set # * 'network::local::interface::<iface_name>::subnet' - If an IP is set
my $directory = "/sys/class/net"; my $directory = "/sys/class/net";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { directory => $directory }});
# We'll need to know what interfaces to remove, if any. This will store the interfaces we've seen and # We'll need to know what interfaces to remove, if any. This will store the interfaces we've seen and
# any others will be removed. # any others will be removed.
@ -65,16 +65,15 @@ sub update_network
# 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 => 3, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory); opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY)) while(my $file = readdir(DIRECTORY))
{ {
next if $file eq "."; next if $file eq ".";
next if $file eq ".."; next if $file eq "..";
next if $file eq "lo"; next if $file eq "lo";
next if $file =~ /virbr\d/;
my $full_path = "$directory/$file"; my $full_path = "$directory/$file";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { full_path => $full_path }});
if (-d $full_path) if (-d $full_path)
{ {
# 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.
@ -95,7 +94,7 @@ sub update_network
$duplex =~ s/\n$//; $duplex =~ s/\n$//;
$operational =~ s/\n$//; $operational =~ s/\n$//;
$speed =~ s/\n$//; $speed =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
interface => $interface, interface => $interface,
speed => $speed, speed => $speed,
mac_address => $mac_address, mac_address => $mac_address,
@ -123,7 +122,7 @@ sub update_network
$ip_address = defined $anvil->data->{network}{'local'}{interface}{$interface}{ip} ? $anvil->data->{network}{'local'}{interface}{$interface}{ip} : ""; $ip_address = defined $anvil->data->{network}{'local'}{interface}{$interface}{ip} ? $anvil->data->{network}{'local'}{interface}{$interface}{ip} : "";
$subnet_mask = defined $anvil->data->{network}{'local'}{interface}{$interface}{subnet} ? $anvil->data->{network}{'local'}{interface}{$interface}{subnet} : ""; $subnet_mask = defined $anvil->data->{network}{'local'}{interface}{$interface}{subnet} ? $anvil->data->{network}{'local'}{interface}{$interface}{subnet} : "";
$type = defined $anvil->data->{network}{'local'}{interface}{$interface}{type} ? $anvil->data->{network}{'local'}{interface}{$interface}{type} : "interface"; $type = defined $anvil->data->{network}{'local'}{interface}{$interface}{type} ? $anvil->data->{network}{'local'}{interface}{$interface}{type} : "interface";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
ip_address => $ip_address, ip_address => $ip_address,
subnet_mask => $subnet_mask, subnet_mask => $subnet_mask,
type => $type, type => $type,
@ -138,7 +137,7 @@ sub update_network
# It's a slave. # It's a slave.
$mac_address = $anvil->Storage->read_file({file => $mac_bond_file}); $mac_address = $anvil->Storage->read_file({file => $mac_bond_file});
$mac_address =~ s/\n$//; $mac_address =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { mac_address => $mac_address }});
} }
# If this is a virtual interface, set some fake values that don't actually exist on # If this is a virtual interface, set some fake values that don't actually exist on
@ -149,7 +148,7 @@ sub update_network
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary. # Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
$speed = 100000 if ((not $speed) or ($speed eq "-1")); $speed = 100000 if ((not $speed) or ($speed eq "-1"));
$duplex = "full" if not $duplex; $duplex = "full" if not $duplex;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
speed => $speed, speed => $speed,
duplex => $duplex, duplex => $duplex,
}}); }});
@ -158,7 +157,7 @@ sub update_network
if (not $link_state) if (not $link_state)
{ {
$speed = 0; $speed = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { speed => $speed }});
} }
# Is this a bond interface? # Is this a bond interface?
@ -185,7 +184,7 @@ sub update_network
$mii_polling_interval =~ s/\n$//; $mii_polling_interval =~ s/\n$//;
$up_delay =~ s/\n$//; $up_delay =~ s/\n$//;
$down_delay =~ s/\n$//; $down_delay =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
active_slave => $active_slave, active_slave => $active_slave,
bond_mode => $bond_mode, bond_mode => $bond_mode,
mii_polling_interval => $mii_polling_interval, mii_polling_interval => $mii_polling_interval,
@ -199,7 +198,7 @@ sub update_network
# No, but it's slaved to one. # No, but it's slaved to one.
my $target = readlink($full_path."/master"); my $target = readlink($full_path."/master");
$bond_master = ($target =~ /^.*\/(.*)$/)[0]; $bond_master = ($target =~ /^.*\/(.*)$/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
target => $target, target => $target,
bond_master => $bond_master, bond_master => $bond_master,
}}); }});
@ -212,7 +211,7 @@ sub update_network
$bridge_stp_enabled = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/stp_state"}); $bridge_stp_enabled = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/stp_state"});
$bridge_id =~ s/\n$//; $bridge_id =~ s/\n$//;
$bridge_stp_enabled =~ s/\n$//; $bridge_stp_enabled =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
bridge_id => $bridge_id, bridge_id => $bridge_id,
bridge_stp_enabled => $bridge_stp_enabled, bridge_stp_enabled => $bridge_stp_enabled,
type => $type, type => $type,
@ -229,10 +228,10 @@ sub update_network
{ {
$bridge_stp_enabled = "enabled_userland"; $bridge_stp_enabled = "enabled_userland";
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_stp_enabled => $bridge_stp_enabled }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_stp_enabled => $bridge_stp_enabled }});
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
active_slave => $active_slave, active_slave => $active_slave,
bond_master => $bond_master, bond_master => $bond_master,
bond_mode => $bond_mode, bond_mode => $bond_mode,
@ -267,31 +266,31 @@ sub update_network
# NOTE: This is probably 0 now... Though someday >100 Gbps will be reasonable # NOTE: This is probably 0 now... Though someday >100 Gbps will be reasonable
# and we'll need to change this. # and we'll need to change this.
$speed = 0; $speed = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { speed => $speed }});
} }
# 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 => 3, list => { line => $line }});
if ($line =~ /Supported ports: \[ (.*?) \]/i) if ($line =~ /Supported ports: \[ (.*?) \]/i)
{ {
$media = lc($1); $media = lc($1);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { media => $media }});
last; last;
} }
} }
# Record this interface # Record this interface
$anvil->data->{seen}{$type}{$interface} = 1; $anvil->data->{seen}{$type}{$interface} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "seen::${type}::${interface}" => $anvil->data->{seen}{$type}{$interface} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "seen::${type}::${interface}" => $anvil->data->{seen}{$type}{$interface} }});
# Record the IP, if set. # Record the IP, if set.
if ($ip_address) if ($ip_address)
{ {
$anvil->data->{seen}{ip}{$ip_address} = $interface; $anvil->data->{seen}{ip}{$ip_address} = $interface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "seen::ip::${ip_address}" => $anvil->data->{seen}{ip}{$ip_address} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "seen::ip::${ip_address}" => $anvil->data->{seen}{ip}{$ip_address} }});
} }
# Store new information we found. # Store new information we found.
@ -315,7 +314,7 @@ sub update_network
$anvil->data->{network}{'local'}{interface}{$interface}{subnet} = $subnet_mask; $anvil->data->{network}{'local'}{interface}{$interface}{subnet} = $subnet_mask;
$anvil->data->{network}{'local'}{interface}{$interface}{type} = $type; $anvil->data->{network}{'local'}{interface}{$interface}{type} = $type;
$anvil->data->{network}{'local'}{interface}{$interface}{up_delay} = $up_delay; $anvil->data->{network}{'local'}{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 => 3, list => {
"network::local::interface::${interface}::active_slave" => $anvil->data->{network}{'local'}{interface}{$interface}{active_slave}, "network::local::interface::${interface}::active_slave" => $anvil->data->{network}{'local'}{interface}{$interface}{active_slave},
"network::local::interface::${interface}::bond_mode" => $anvil->data->{network}{'local'}{interface}{$interface}{bond_mode}, "network::local::interface::${interface}::bond_mode" => $anvil->data->{network}{'local'}{interface}{$interface}{bond_mode},
"network::local::interface::${interface}::bond_master" => $anvil->data->{network}{'local'}{interface}{$interface}{bond_master}, "network::local::interface::${interface}::bond_master" => $anvil->data->{network}{'local'}{interface}{$interface}{bond_master},
@ -345,13 +344,13 @@ sub update_network
# We need to record bonds first so that their UUIDs are available when recording interfaces. # We need to record bonds first so that their UUIDs are available when recording interfaces.
foreach my $processing ("bond", "interface", "bridge") foreach my $processing ("bond", "interface", "bridge")
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { processing => $processing }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { processing => $processing }});
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}}) foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{ {
# Skip if this isn't the device type we're working on. # Skip if this isn't the device type we're working on.
next if not defined $anvil->data->{network}{'local'}{interface}{$interface}{type}; next if not defined $anvil->data->{network}{'local'}{interface}{$interface}{type};
my $type = $anvil->data->{network}{'local'}{interface}{$interface}{type}; my $type = $anvil->data->{network}{'local'}{interface}{$interface}{type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
's1:interface' => $interface, 's1:interface' => $interface,
's2:type' => $type, 's2:type' => $type,
's3:processing' => $processing, 's3:processing' => $processing,
@ -380,7 +379,7 @@ sub update_network
my $default_gateway = $anvil->data->{network}{'local'}{interface}{$interface}{default_gateway}; my $default_gateway = $anvil->data->{network}{'local'}{interface}{$interface}{default_gateway};
my $gateway = $anvil->data->{network}{'local'}{interface}{$interface}{gateway}; my $gateway = $anvil->data->{network}{'local'}{interface}{$interface}{gateway};
my $dns = $anvil->data->{network}{'local'}{interface}{$interface}{dns}; my $dns = $anvil->data->{network}{'local'}{interface}{$interface}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
active_slave => $active_slave, active_slave => $active_slave,
bond_mode => $bond_mode, bond_mode => $bond_mode,
bond_master => $bond_master, bond_master => $bond_master,
@ -423,10 +422,10 @@ sub update_network
bond_up_delay => $up_delay, bond_up_delay => $up_delay,
bond_down_delay => $down_delay, bond_down_delay => $down_delay,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_uuid => $bond_uuid }});
$anvil->data->{bond_by_name}{$interface} = $bond_uuid; $anvil->data->{bond_by_name}{$interface} = $bond_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "bond_by_name::${interface}" => $anvil->data->{bond_by_name}{$interface} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "bond_by_name::${interface}" => $anvil->data->{bond_by_name}{$interface} }});
if (($bond_uuid) && ($ip_address)) if (($bond_uuid) && ($ip_address))
{ {
@ -448,11 +447,11 @@ sub update_network
if (($type eq $processing) && ($type eq "interface")) if (($type eq $processing) && ($type eq "interface"))
{ {
my $say_bond_uuid = ""; my $say_bond_uuid = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_master => $bond_master }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_master => $bond_master }});
if (($bond_master) && ($anvil->data->{bond_by_name}{$bond_master})) if (($bond_master) && ($anvil->data->{bond_by_name}{$bond_master}))
{ {
$say_bond_uuid = $anvil->data->{bond_by_name}{$bond_master}; $say_bond_uuid = $anvil->data->{bond_by_name}{$bond_master};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"bond_by_name::${bond_master}" => $anvil->data->{bond_by_name}{$bond_master}, "bond_by_name::${bond_master}" => $anvil->data->{bond_by_name}{$bond_master},
say_bond_uuid => $say_bond_uuid, say_bond_uuid => $say_bond_uuid,
}}); }});
@ -471,10 +470,10 @@ sub update_network
network_interface_mtu => $mtu, network_interface_mtu => $mtu,
network_interface_speed => $speed, network_interface_speed => $speed,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_uuid => $network_interface_uuid }});
$anvil->data->{interface_by_name}{$interface} = $network_interface_uuid; $anvil->data->{interface_by_name}{$interface} = $network_interface_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "interface_by_name::${interface}" => $anvil->data->{interface_by_name}{$interface} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "interface_by_name::${interface}" => $anvil->data->{interface_by_name}{$interface} }});
if (($network_interface_uuid) && ($ip_address)) if (($network_interface_uuid) && ($ip_address))
{ {
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({ my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
@ -504,10 +503,10 @@ sub update_network
bridge_mtu => $mtu, bridge_mtu => $mtu,
bridge_stp_enabled => $bridge_stp_enabled, bridge_stp_enabled => $bridge_stp_enabled,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_uuid => $bridge_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_uuid => $bridge_uuid }});
$anvil->data->{bridge_by_name}{$interface} = $bridge_uuid; $anvil->data->{bridge_by_name}{$interface} = $bridge_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "bridge_by_name::${interface}" => $anvil->data->{bridge_by_name}{$interface} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "bridge_by_name::${interface}" => $anvil->data->{bridge_by_name}{$interface} }});
if (($bridge_uuid) && ($ip_address)) if (($bridge_uuid) && ($ip_address))
{ {
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({ my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
@ -550,10 +549,10 @@ WHERE
AND AND
bond_mode != 'DELETED' bond_mode != 'DELETED'
;"; ;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results}; my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
results => $results, results => $results,
count => $count, count => $count,
}}); }});
@ -574,7 +573,7 @@ AND
bond_mac_address => $row->[10], bond_mac_address => $row->[10],
bond_operational => $row->[11], bond_operational => $row->[11],
}; };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"bonds::${bond_uuid}::bond_name" => $anvil->data->{bonds}{$bond_uuid}{bond_name}, "bonds::${bond_uuid}::bond_name" => $anvil->data->{bonds}{$bond_uuid}{bond_name},
"bonds::${bond_uuid}::bond_mode" => $anvil->data->{bonds}{$bond_uuid}{bond_mode}, "bonds::${bond_uuid}::bond_mode" => $anvil->data->{bonds}{$bond_uuid}{bond_mode},
"bonds::${bond_uuid}::bond_mtu" => $anvil->data->{bonds}{$bond_uuid}{bond_mtu}, "bonds::${bond_uuid}::bond_mtu" => $anvil->data->{bonds}{$bond_uuid}{bond_mtu},
@ -615,10 +614,10 @@ WHERE
AND AND
bridge_id != 'DELETED' bridge_id != 'DELETED'
;"; ;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results}; $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
results => $results, results => $results,
count => $count, count => $count,
}}); }});
@ -637,7 +636,7 @@ AND
bridge_mtu => $bridge_mtu, bridge_mtu => $bridge_mtu,
bridge_stp_enabled => $bridge_stp_enabled, bridge_stp_enabled => $bridge_stp_enabled,
}; };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"bridges::${bridge_uuid}::bridge_name" => $anvil->data->{bridges}{$bridge_uuid}{bridge_name}, "bridges::${bridge_uuid}::bridge_name" => $anvil->data->{bridges}{$bridge_uuid}{bridge_name},
"bridges::${bridge_uuid}::bridge_id" => $anvil->data->{bridges}{$bridge_uuid}{bridge_id}, "bridges::${bridge_uuid}::bridge_id" => $anvil->data->{bridges}{$bridge_uuid}{bridge_id},
"bridges::${bridge_uuid}::bridge_mac" => $anvil->data->{bridges}{$bridge_uuid}{bridge_mac}, "bridges::${bridge_uuid}::bridge_mac" => $anvil->data->{bridges}{$bridge_uuid}{bridge_mac},
@ -650,13 +649,14 @@ AND
{ {
# Mark it as deleted. # Mark it as deleted.
my $query = "UPDATE bridges SET bridge_id = 'DELETED' WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";"; my $query = "UPDATE bridges SET bridge_id = 'DELETED' WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
$anvil->Database->write({debug => 2, query => $query, source => $THIS_FILE, line => __LINE__}); $anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__});
# Remove it from the hash so we don't add it to the .json and .xml files. # Remove it from the hash so we don't add it to the .json and .xml files.
delete $anvil->data->{bridges}{$bridge_uuid}; delete $anvil->data->{bridges}{$bridge_uuid};
} }
} }
# Process interfaces
$query = " $query = "
SELECT SELECT
network_interface_uuid, network_interface_uuid,
@ -674,18 +674,18 @@ FROM
network_interfaces network_interfaces
WHERE WHERE
network_interface_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})." network_interface_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})."
AND
network_interface_operational != 'DELETED'
ORDER BY ORDER BY
modified_date DESC modified_date DESC
;"; ;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results}; $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
query => $query,
results => $results, results => $results,
count => $count, count => $count,
}}); }});
# The order will track the order the interfaces were last modified, which is a way to determine when # The order will track the order the interfaces were last modified, which is a way to determine when
# they came up. # they came up.
my $network_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; my $network_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
@ -708,7 +708,7 @@ ORDER BY
network_interface_bond_uuid => defined $row->[9] ? $row->[9] : 'NULL', network_interface_bond_uuid => defined $row->[9] ? $row->[9] : 'NULL',
network_interface_bridge_uuid => defined $row->[10] ? $row->[10] : 'NULL', network_interface_bridge_uuid => defined $row->[10] ? $row->[10] : 'NULL',
}; };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"network_interfaces::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_mac_address}, "network_interfaces::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_mac_address},
"network_interfaces::${network_interface_uuid}::network_interface_name" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_name}, "network_interfaces::${network_interface_uuid}::network_interface_name" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_name},
"network_interfaces::${network_interface_uuid}::network_interface_speed" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_speed}, "network_interfaces::${network_interface_uuid}::network_interface_speed" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_speed},
@ -723,14 +723,14 @@ ORDER BY
}}); }});
# Make sure I've seen this interface in this scan and, if not, update this entry to remove it. # Make sure I've seen this interface in this scan and, if not, update this entry to remove it.
if ((not exists $anvil->data->{seen}{interface}{$network_interface_name}) or (not $anvil->data->{seen}{interface}{$network_interface_name})) if (not exists $anvil->data->{network}{'local'}{interface}{$network_interface_name})
{ {
# Mark it as deleted. # Mark it as deleted.
my $query = "UPDATE network_interfaces SET network_interface_operational = 'DELETED' WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";"; my $query = "UPDATE network_interfaces SET network_interface_operational = 'DELETED' WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";";
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); $anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__});
# Remove it from the hash so we don't add it to the .json and .xml files. # Remove it from the hash so we don't add it to the .json and .xml files.
delete $anvil->data->{interfaces}{$network_interface_uuid}; delete $anvil->data->{interface}{$network_interface_uuid};
# Loop so we don't try to process any further. # Loop so we don't try to process any further.
next; next;
@ -775,10 +775,10 @@ FROM
WHERE WHERE
ip_address_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})." ip_address_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})."
;"; ;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results}; $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
results => $results, results => $results,
count => $count, count => $count,
}}); }});
@ -793,7 +793,7 @@ WHERE
my $ip_address_default_gateway = $row->[6]; my $ip_address_default_gateway = $row->[6];
my $ip_address_dns = $row->[7]; my $ip_address_dns = $row->[7];
my $ip_address_note = $row->[8]; my $ip_address_note = $row->[8];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
ip_address_on_type => $ip_address_on_type, ip_address_on_type => $ip_address_on_type,
ip_address_on_uuid => $ip_address_on_uuid, ip_address_on_uuid => $ip_address_on_uuid,
ip_address_address => $ip_address_address, ip_address_address => $ip_address_address,
@ -820,17 +820,17 @@ WHERE
if ($ip_address_on_type eq "interface") if ($ip_address_on_type eq "interface")
{ {
$say_on = $anvil->data->{network_interfaces}{$ip_address_on_uuid}{network_interface_name}; $say_on = $anvil->data->{network_interfaces}{$ip_address_on_uuid}{network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_on => $say_on }});
} }
elsif ($ip_address_on_type eq "bond") elsif ($ip_address_on_type eq "bond")
{ {
$say_on = $anvil->data->{bonds}{$ip_address_on_uuid}{bond_name}; $say_on = $anvil->data->{bonds}{$ip_address_on_uuid}{bond_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_on => $say_on }});
} }
elsif ($ip_address_on_type eq "bridge") elsif ($ip_address_on_type eq "bridge")
{ {
$say_on = $anvil->data->{bridges}{$ip_address_on_uuid}{bridge_name}; $say_on = $anvil->data->{bridges}{$ip_address_on_uuid}{bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_on => $say_on }});
} }
$network_json .= " { \"address\":\"$ip_address_address\", \"on\":\"$say_on\", \"subnet\":\"$ip_address_subnet_mask\", \"gateway\":\"$ip_address_gateway\", \"default_gateway\":\"$ip_address_default_gateway\", \"dns\":\"$ip_address_dns\" },\n"; $network_json .= " { \"address\":\"$ip_address_address\", \"on\":\"$say_on\", \"subnet\":\"$ip_address_subnet_mask\", \"gateway\":\"$ip_address_gateway\", \"default_gateway\":\"$ip_address_default_gateway\", \"dns\":\"$ip_address_dns\" },\n";
@ -838,11 +838,11 @@ WHERE
} }
# Now record the interfaces on bridges. # Now record the interfaces on bridges.
$anvil->Network->bridge_info({debug => 2}); $anvil->Network->bridge_info({debug => 3});
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}}) foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}})
{ {
my $bridge_uuid = $anvil->data->{bridge_by_name}{$bridge_name}; my $bridge_uuid = $anvil->data->{bridge_by_name}{$bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
bridge_name => $bridge_name, bridge_name => $bridge_name,
bridge_uuid => $bridge_uuid, bridge_uuid => $bridge_uuid,
}}); }});
@ -850,19 +850,19 @@ WHERE
foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}}) foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}})
{ {
my $interface_uuid = exists $anvil->data->{bond_by_name}{$interface_name} ? $anvil->data->{bond_by_name}{$interface_name} : $anvil->data->{interface_by_name}{$interface_name}; my $interface_uuid = exists $anvil->data->{bond_by_name}{$interface_name} ? $anvil->data->{bond_by_name}{$interface_name} : $anvil->data->{interface_by_name}{$interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
interface_name => $interface_name, interface_name => $interface_name,
interface_uuid => $interface_uuid, interface_uuid => $interface_uuid,
}}); }});
my $bridge_interfaces_uuid = $anvil->Database->insert_or_update_bridge_interfaces({ my $bridge_interfaces_uuid = $anvil->Database->insert_or_update_bridge_interfaces({
debug => 2, debug => 3,
file => $THIS_FILE, file => $THIS_FILE,
line => __LINE__, line => __LINE__,
bridge_interface_bridge_uuid => $bridge_uuid, bridge_interface_bridge_uuid => $bridge_uuid,
bridge_interface_network_interface_uuid => $interface_uuid, bridge_interface_network_interface_uuid => $interface_uuid,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
bridge_interfaces_uuid => $bridge_interfaces_uuid, bridge_interfaces_uuid => $bridge_interfaces_uuid,
}}); }});
} }
@ -870,15 +870,19 @@ WHERE
$network_json =~ s/,$//s; $network_json =~ s/,$//s;
$network_json .= "]}\n"; $network_json .= "]}\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_json => $network_json }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_json => $network_json }});
$network_xml .= "</network>\n"; $network_xml .= "</network>\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_xml => $network_xml }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_xml => $network_xml }});
# Write the JSON file. # Write the JSON file, if we're a dashboard. Nodes and DR hosts don't have a WebUI, so they're not
# needed.
if ($anvil->System->get_host_type eq "dashboard")
{
my $output_json = $anvil->data->{path}{directories}{html}."/status/network.json"; my $output_json = $anvil->data->{path}{directories}{html}."/status/network.json";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output_xml => $output_json }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output_xml => $output_json }});
$anvil->Storage->write_file({ $anvil->Storage->write_file({
backup => 0,
file => $output_json, file => $output_json,
body => $network_json, body => $network_json,
overwrite => 1, overwrite => 1,
@ -889,8 +893,9 @@ WHERE
# Write the XML file. # Write the XML file.
my $output_xml = $anvil->data->{path}{directories}{html}."/status/network.xml"; my $output_xml = $anvil->data->{path}{directories}{html}."/status/network.xml";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output_xml => $output_xml }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output_xml => $output_xml }});
$anvil->Storage->write_file({ $anvil->Storage->write_file({
backup => 0,
file => $output_xml, file => $output_xml,
body => $network_xml, body => $network_xml,
overwrite => 1, overwrite => 1,
@ -898,6 +903,7 @@ WHERE
user => "apache", user => "apache",
group => "apache" group => "apache"
}); });
}
return(0); return(0);
} }

@ -56,6 +56,7 @@ wait_for_access($anvil);
#set_host_name($anvil); #set_host_name($anvil);
#add_repos($anvil); #add_repos($anvil);
add_databases($anvil); add_databases($anvil);
update_progress($anvil, 100, "job_0047");
$anvil->nice_exit({code => 0}); $anvil->nice_exit({code => 0});
@ -201,7 +202,7 @@ sub add_databases
} }
else else
{ {
# Success! We're done@ # Success! We're done!
update_progress($anvil, 100, "job_0047"); update_progress($anvil, 100, "job_0047");
} }
} }

@ -1251,7 +1251,7 @@ sub load_packages
"dnf-data.noarch", "dnf-data.noarch",
"dnf-plugin-subscription-manager.x86_64", "dnf-plugin-subscription-manager.x86_64",
"dnf-plugins-core.noarch", "dnf-plugins-core.noarch",
"dnf-utils.noarch", #"dnf-utils.noarch",
"dnf.noarch", "dnf.noarch",
"dnsmasq.x86_64", "dnsmasq.x86_64",
"dracut-config-rescue.x86_64", "dracut-config-rescue.x86_64",
@ -2264,6 +2264,7 @@ sub load_packages
'y' => [ 'y' => [
"yajl.x86_64", "yajl.x86_64",
"yum.noarch", "yum.noarch",
"yum-utils.noarch",
"zenity.x86_64", "zenity.x86_64",
], ],
z => [ z => [

Loading…
Cancel
Save