Removed anvil-update-states

* Created new anvil-monitor-network daemon to trigger scan-server via
  anvil-monitor-network on network events.
* Moved functionality into scan-network

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 12 months ago
parent a27773a69d
commit cad524db9d
  1. 1
      Anvil/Tools.pm
  2. 1
      Anvil/Tools/Database.pm
  3. 6
      anvil.spec.in
  4. 9
      man/anvil-manage-host.8
  5. 81
      scancore-agents/scan-network/scan-network
  6. 1
      tools/Makefile.am
  7. 664
      tools/anvil-configure-host
  8. 131
      tools/anvil-daemon
  9. 119
      tools/anvil-manage-host
  10. 1336
      tools/anvil-monitor-network
  11. 1161
      tools/anvil-update-states
  12. 1
      units/Makefile.am
  13. 12
      units/anvil-monitor-network.service

@ -1170,7 +1170,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",

@ -18591,7 +18591,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)
{ {

@ -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,timestamp,mac_address,speed,link_state,operational,nm_uuid,nm_device\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,67 @@ $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 ($interface, $timestamp, $mac_address, $speed, $link_state, $operational, $nm_uuid, $nm_device) = (split/,/, $line);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
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 => $interface,
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
{ {
@ -460,7 +536,6 @@ sub collect_data
{ {
my ($anvil) = @_; my ($anvil) = @_;
# 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}); $anvil->Network->get_ips({debug => 2});
my $local_host = $anvil->Get->short_host_name(); my $local_host = $anvil->Get->short_host_name();
@ -890,7 +965,7 @@ 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->data->{cache}{new_file} .= $interface.",".$anvil->Database->refresh_timestamp.",".$mac_address.",".$speed.",".$link_state.",".$operational.",".$nm_uuid.",".$nm_device."\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},
}}); }});
@ -1409,7 +1484,7 @@ sub collect_data_ifcfg
# 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->data->{cache}{new_file} .= $interface.",".$anvil->Database->refresh_timestamp.",".$mac_address.",".$speed.",".$link_state.",".$operational.",NULL,NULL\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},
}}); }});

@ -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 \

@ -149,11 +149,13 @@ sub update_passwords
my ($anvil) = @_; my ($anvil) = @_;
# Have we been asked to set a password? # Have we been asked to set a password?
$anvil->data->{variables}{form}{config_step2}{striker_password}{value} = "" if not defined $anvil->data->{variables}{form}{config_step2}{striker_password}{value}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => {
if ($anvil->data->{variables}{form}{config_step2}{striker_password}{value}) "config::striker_password" => $anvil->data->{config}{striker_password},
}});
if ($anvil->data->{config}{striker_password})
{ {
# Set the passwords # Set the passwords
my $password = $anvil->data->{variables}{form}{config_step2}{striker_password}{value}; my $password = $anvil->data->{config}{striker_password};
my $temp_file = "/tmp/anvil-".$anvil->Get->uuid; my $temp_file = "/tmp/anvil-".$anvil->Get->uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { password => $password }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { password => $password }});
@ -235,17 +237,17 @@ sub reconfigure_network
{ {
my ($anvil) = @_; my ($anvil) = @_;
my $local_host = $anvil->Get->short_host_name();
my $reboot_needed = 0; my $reboot_needed = 0;
my $prefix = exists $anvil->data->{variables}{form}{config_step1}{prefix}{value} ? $anvil->data->{variables}{form}{config_step1}{prefix}{value} : ""; my $local_host = $anvil->Get->short_host_name();
my $sequence = exists $anvil->data->{variables}{form}{config_step1}{sequence}{value} ? $anvil->data->{variables}{form}{config_step1}{sequence}{value} : ""; my $prefix = $anvil->data->{config}{prefix};
my $domain = exists $anvil->data->{variables}{form}{config_step1}{domain}{value} ? $anvil->data->{variables}{form}{config_step1}{domain}{value} : ""; my $sequence = $anvil->data->{config}{sequence};
my $organization = exists $anvil->data->{variables}{form}{config_step1}{organization}{value} ? $anvil->data->{variables}{form}{config_step1}{organization}{value} : ""; my $domain = $anvil->data->{config}{domain};
my $bcn_count = exists $anvil->data->{variables}{form}{config_step1}{bcn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{bcn_count}{value} : 1; my $new_host_name = $anvil->data->{config}{host_name};
my $sn_count = exists $anvil->data->{variables}{form}{config_step1}{sn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{sn_count}{value} : 0; my $organization = $anvil->data->{config}{organization};
my $mn_count = exists $anvil->data->{variables}{form}{config_step1}{mn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{mn_count}{value} : 0; my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = exists $anvil->data->{variables}{form}{config_step1}{ifn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{ifn_count}{value} : 1; my $ifn_count = $anvil->data->{config}{ifn_count};
my $new_host_name = exists $anvil->data->{variables}{form}{config_step2}{host_name}{value} ? $anvil->data->{variables}{form}{config_step2}{host_name}{value} : ""; my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type(); my $type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
prefix => $prefix, prefix => $prefix,
@ -260,18 +262,6 @@ sub reconfigure_network
type => $type, type => $type,
}}); }});
# Clear the network mapping flag.
$anvil->Database->insert_or_update_variables({
debug => 2,
variable_name => "config::map_network",
variable_value => 0,
variable_default => "",
variable_description => "striker_0202",
variable_section => "config",
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
# If we're configuring a dashboard and no host name was given, generate it. # If we're configuring a dashboard and no host name was given, generate it.
if (($type eq "striker") && (not $new_host_name)) if (($type eq "striker") && (not $new_host_name))
{ {
@ -349,7 +339,7 @@ sub reconfigure_network
} }
# Now configure the network. # Now configure the network.
my $dns = defined $anvil->data->{variables}{form}{config_step2}{dns}{value} ? [split/,/, $anvil->data->{variables}{form}{config_step2}{dns}{value}] : []; my $dns = $anvil->data->{config}{dns} ? [split/,/, $anvil->data->{config}{dns}] : [];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { dns => $dns }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { dns => $dns }});
for (my $i = 0; $i < @{$dns}; $i++) for (my $i = 0; $i < @{$dns}; $i++)
{ {
@ -357,8 +347,8 @@ sub reconfigure_network
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "dns->[$i]" => $dns->[$i] }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "dns->[$i]" => $dns->[$i] }});
} }
my $gateway = defined $anvil->data->{variables}{form}{config_step2}{gateway}{value} ? $anvil->data->{variables}{form}{config_step2}{gateway}{value} : ""; my $gateway = $anvil->data->{config}{gateway};
my $gateway_interface = defined $anvil->data->{variables}{form}{config_step2}{gateway_interface}{value} ? $anvil->data->{variables}{form}{config_step2}{gateway_interface}{value} : ""; my $gateway_interface = $anvil->data->{config}{gateway_interface};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
gateway => $gateway, gateway => $gateway,
gateway_interface => $gateway_interface, gateway_interface => $gateway_interface,
@ -384,7 +374,8 @@ sub reconfigure_network
{ {
my $ip_key = $network_type.$network_count."_ip"; my $ip_key = $network_type.$network_count."_ip";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip_key => $ip_key }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip_key => $ip_key }});
if ((exists $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}) && ($anvil->data->{variables}{form}{config_step2}{$ip_key}{value} eq "dhcp"))
if ((exists $anvil->data->{config}{$ip_key}) && ($anvil->data->{config}{$ip_key} eq "dhcp"))
{ {
$gateway_interface = $network_type.$network_count; $gateway_interface = $network_type.$network_count;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway_interface => $gateway_interface }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway_interface => $gateway_interface }});
@ -490,11 +481,390 @@ ORDER BY
# This will be set to '1' if we make a change. # This will be set to '1' if we make a change.
my $changes = 0; my $changes = 0;
my $new_interfaces = []; my $new_interfaces = [];
my $network_type = $anvil->System->check_network_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
if ($network_type eq "ifcfg")
{
foreach my $network_type ("bcn", "sn", "mn", "ifn") foreach my $network_type ("bcn", "sn", "mn", "ifn")
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
=cut # This is the old type of network config
configure_ifcfg_network($anvil, $network_type);
}
}
else
{
# Configure the network using Network Manager
reconfigure_bridges($anvil);
reconfigure_bonds($anvil);
reconfigure_interfaces($anvil);
reconfigure_ip_addresses($anvil);
}
# If we should reset, do so now.
if ($anvil->data->{sys}{reboot})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0687", variables => { reason => "#!string!log_0631!#" }});
do_reboot($anvil);
}
if ($changes)
{
# In an attempt to make network changes more reliable, we'll just reboot. This shouldn't
# actually be hit anymore as any change should have triggered the reboot above.
$anvil->data->{sys}{reboot} = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0687", variables => { reason => "#!string!log_0631!#" }});
do_reboot($anvil);
# Re-read the config
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0463"});
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection reload";
$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});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Give a couple seconds for the reload
sleep 2;
# Now check the bonds
my $repaired = $anvil->Network->check_network({heal => "all"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { repaired => $repaired }});
if ($repaired)
{
# It can take a bit for the bonds to allow traffic, so sleep for a bit.
sleep 30;
}
}
# Wait for a DB connection. We'll wait up to 130 seconds, as sometimes it takes a while for the network
# to start routing traffic.
my $wait_until = time + 130;
until ($anvil->data->{sys}{database}{connections})
{
$anvil->refresh();
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
if (time > $wait_until)
{
# Failed to reconnect, reboot. Hopefully the network comes up cleanly
# next time..
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0107"});
do_reboot($anvil);
}
# No databases, sleep and then try again.
sleep 10;
}
}
# We're half-way there.
$anvil->Job->update_progress({
progress => 50,
job_uuid => $anvil->data->{job}{uuid},
});
# If any virtio bridges exist, remove it/them.
my $start = 0;
my ($bridges, $return_code) = $anvil->System->call({debug => 2, shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-list"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridges => $bridges, return_code => $return_code }});
if ($return_code)
{
### NOTE: We're doing a bunch of deletes, so to be safe we statically define the directory
### here.
# Libvirtd isn't running, check the directory directly.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0478"});
my $directory = "/etc/libvirt/qemu/networks/autostart";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
if (-d $directory)
{
# Delete all files.
local(*DIRECTORY);
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
my $full_path = $directory."/".$file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
file => $file,
full_path => $full_path,
}});
if (-l $full_path)
{
# It's a symlink, remove it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0479", variables => { 'symlink' => $full_path }});
unlink $full_path;
if (-l $full_path)
{
# It didn't work...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 0, priority => "err", key => "error_0132", variables => { 'symlink' => $full_path }});;
}
}
}
closedir(DIRECTORY);
}
}
else
{
foreach my $line (split/\n/, $bridges)
{
$line = $anvil->Words->clean_spaces({string => $line});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /^----------/)
{
$start = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { start => $start }});
next;
}
next if not $start;
my $bridge = ($line =~ /(.*?)\s/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge => $bridge }});
$anvil->data->{virsh}{bridge}{$bridge} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "virsh::bridge::$bridge" => $anvil->data->{virsh}{bridge}{$bridge} }});
}
foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{virsh}{bridge}})
{
# Destroy (stop) it.
my ($destroy, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-destroy ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { destroy => $destroy, return_code => $return_code }});
# Disable it from auto-start.
(my $disable, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-autostart ".$bridge." --disable"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disable => $disable, return_code => $return_code }});
# Undefine (delete)
(my $undefine, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-undefine ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { undefine => $undefine, return_code => $return_code }});
}
}
$anvil->Job->update_progress({
progress => 75,
job_uuid => $anvil->data->{job}{uuid},
});
return(0);
}
sub reconfigure_interfaces
{
my ($anvil) = @_;
foreach my $network_type ("bcn", "sn", "mn", "ifn")
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
# This is the old type of network config
configure_ifcfg_network($anvil, $network_type);
}
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{reconfigure}})
{
my $uuid = $anvil->data->{network_manager}{reconfigure}{$wanted_interface}{from_uuid};
my $old_device = $anvil->data->{interface}{uuid}{$uuid}{device};
my $name = $anvil->data->{interface}{uuid}{$uuid}{'connection.id'};
my $mac_address = $anvil->data->{interface}{uuid}{$uuid}{mac_address};
my $type = $anvil->data->{interface}{uuid}{$uuid}{type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:wanted_interface' => $wanted_interface,
's2:uuid' => $uuid,
's3:old_device' => $old_device,
's4:name' => $name,
's5:mac_address' => $mac_address,
's6:type' => $type,
}});
print "Renaming old device/name: [".$old_device."/".$name."] with MAC: [".$mac_address."] to: [".$wanted_interface."] using UUID: [".$uuid."]\n";
# Read persistent-net and see if it needs to be updated.
my $new_persistent_net = "";
my $old_persistent_net = "";
if (-e $anvil->data->{path}{configs}{'persistent-net'})
{
$old_persistent_net = $anvil->Storage->read_file({debug => 2, file => $anvil->data->{path}{configs}{'persistent-net'}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_persistent_net => $old_persistent_net }});
}
foreach my $line (split/\n/, $old_persistent_net)
{
# If this MAC or device name exists already, delete the line.
if (($line =~ /"$mac_address"/) or ($line =~ /"$wanted_interface"/))
{
next;
}
$new_persistent_net .= $line."\n";
}
$new_persistent_net .= "SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"".$mac_address."\",ATTR{type}==\"".$type."\",NAME=\"".$wanted_interface."\"\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_persistent_net => $new_persistent_net }});
my $difference = diff \$old_persistent_net, \$new_persistent_net, { STYLE => 'Unified' };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
# Write the new file.
if ($difference)
{
print "- Updating the udev file: [".$anvil->data->{path}{configs}{'persistent-net'}."]\n";
my $problem = $anvil->Storage->write_file({
file => $anvil->data->{path}{configs}{'persistent-net'},
body => $new_persistent_net,
overwrite => 1,
user => "admin",
group => "admin",
mode => "0644",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{
print "[ Error ] - Failed to write the new: [".$anvil->data->{path}{configs}{'persistent-net'}."] file, aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
}
# Update the connection.interface-name
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connection_interface_name => $connection_interface_name }});
if ($connection_interface_name)
{
print "- Removing the old 'connection.interface-name': [".$connection_interface_name."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.interface-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,
}});
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.interface-name connection show ".$uuid;
$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,
}});
if ($output)
{
# This should have been blank
print "[ Error ] - Failed to delete the 'connection.interface-name', got: [".$output."] and it should bhave been blank, aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
}
# We'll log what it was, and change it anyway
my $match_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_interface_name => $match_interface_name }});
if (1)
{
print "- Matching the new interface name: [".$wanted_interface."] to the bios device name: [".$old_device."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." match.interface-name \"".$wanted_interface." ".$old_device."\"";
$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,
}});
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values match.interface-name connection show ".$uuid;
$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,
}});
if (($output ne $wanted_interface.",".$old_device) && ($output ne $old_device.",".$wanted_interface))
{
# This should have been blank
print "[ Error ] - Failed to create the 'match.interface-name' value. Expected: [".$wanted_interface.",".$old_device."], got: [".$output."], aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
# Set the connection.id to the old name.
print "- Setting the connection.id to the bios device name: [".$old_device."]\n";
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.id \"".$old_device."\"";
$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,
}});
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.id connection show ".$uuid;
$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,
}});
}
# Set the reboot flag.
$anvil->data->{sys}{reboot_needed} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::reboot_needed" => $anvil->data->{sys}{reboot_needed} }});
}
if ($anvil->data->{sys}{reboot_needed})
{
print "Reboot needed.\n";
print "- Regenerating dracute initrd image, this can take a moment...\n";
my $shell_call = $anvil->data->{path}{exe}{dracut}." --force";
$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,
}});
print "- New initrd image created.\n";
print "[ Note ] - Reboot needed. Re-run this after the reboot to complete setup.\n";
print "- Rebooting in 60 seconds (press 'ctrl + c' to abort).\n";
my $timeout = 60;
while($timeout)
{
if ($timeout % 10)
{
print "."
}
else
{
print $timeout;
}
sleep 1;
$timeout--;
}
print "0\n";
print "Rebooting NOW!\n";
$shell_call = $anvil->data->{path}{exe}{systemctl}." reboot";
$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, 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 configure_ifcfg_network
{
my ($anvil, $network_type) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
my $count = 0; my $count = 0;
if ($network_type eq "bcn") { $count = $bcn_count; } if ($network_type eq "bcn") { $count = $bcn_count; }
elsif ($network_type eq "sn") { $count = $sn_count; } elsif ($network_type eq "sn") { $count = $sn_count; }
@ -514,18 +884,19 @@ ORDER BY
link1_key => $link1_key, link1_key => $link1_key,
}}); }});
next if not exists $anvil->data->{variables}{form}{config_step2}{$link1_key};
next if not $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}; next if not exists $anvil->data->{config}{$link1_key};
next if not $anvil->data->{config}{$link1_key};
my $link2_key = $this_network."_link2_mac_to_set"; my $link2_key = $this_network."_link2_mac_to_set";
my $subnet_mask_key = $this_network."_subnet_mask"; my $subnet_mask_key = $this_network."_subnet_mask";
my $ip_key = $this_network."_ip"; my $ip_key = $this_network."_ip";
my $bridge_key = $this_network."_create_bridge"; my $bridge_key = $this_network."_create_bridge";
my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}; my $link1_mac = $anvil->data->{config}{$link1_key};
my $is_gateway = $this_network eq $gateway_interface ? 1 : 0; my $is_gateway = $this_network eq $gateway_interface ? 1 : 0;
my $link2_mac = defined $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} : ""; my $link2_mac = defined $anvil->data->{config}{$link2_key} ? $anvil->data->{config}{$link2_key} : "";
my $old_link1_iface = $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} : ""; my $old_link1_iface = $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} : "";
my $old_link2_iface = defined $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} : ""; my $old_link2_iface = defined $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} : "";
my $bridge = defined $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} : 0; my $bridge = defined $anvil->data->{config}{$bridge_key} ? $anvil->data->{config}{$bridge_key} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ip_key => $ip_key, ip_key => $ip_key,
is_gateway => $is_gateway, is_gateway => $is_gateway,
@ -572,30 +943,30 @@ ORDER BY
} }
# Skip if this doesn't exist or isn't a valid IPv4 address. # Skip if this doesn't exist or isn't a valid IPv4 address.
if (not exists $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}) if (not exists $anvil->data->{config}{$ip_key})
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0176", variables => { ip_key => $ip_key }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0176", variables => { ip_key => $ip_key }});
next; next;
} }
else else
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "variables::form::config_step2::${ip_key}::value" => $anvil->data->{variables}{form}{config_step2}{$ip_key}{value} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "config::${ip_key}" => $anvil->data->{config}{$ip_key} }});
} }
if (($anvil->data->{variables}{form}{config_step2}{$ip_key}{value}) && if (($anvil->data->{config}{$ip_key}) &&
($anvil->data->{variables}{form}{config_step2}{$ip_key}{value} ne "dhcp") && ($anvil->data->{config}{$ip_key} ne "dhcp") &&
(not $anvil->Validate->ipv4({ip => $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}}))) (not $anvil->Validate->ipv4({ip => $anvil->data->{config}{$ip_key}})))
{ {
# Something was set, but it isn't valid. # Something was set, but it isn't valid.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "log_0148", variables => { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "log_0148", variables => {
network => $this_network, network => $this_network,
ip => $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}, ip => $anvil->data->{config}{$ip_key},
}}); }});
next; next;
} }
# The IP could be 'dhcp', we'll handle that in a bit. # The IP could be 'dhcp', we'll handle that in a bit.
my $ip_address = $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}; my $ip_address = $anvil->data->{config}{$ip_key};
my $subnet_mask = defined $anvil->data->{variables}{form}{config_step2}{$subnet_mask_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$subnet_mask_key}{value} : ""; my $subnet_mask = defined $anvil->data->{config}{$subnet_mask_key} ? $anvil->data->{config}{$subnet_mask_key} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ip_address => $ip_address, ip_address => $ip_address,
subnet_mask => $subnet_mask, subnet_mask => $subnet_mask,
@ -1166,13 +1537,13 @@ ORDER BY
}}); }});
} }
} }
elsif ((exists $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}) && ($anvil->Validate->mac({mac => $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}}))) elsif ((exists $anvil->data->{config}{$link1_key}) && ($anvil->Validate->mac({mac => $anvil->data->{config}{$link1_key}})))
{ {
### NOTE: This only applies when configuring Striker dashboards. They can't ### NOTE: This only applies when configuring Striker dashboards. They can't
### be 'dhcp', either, so no checks are made for those cases. Likewise, ### be 'dhcp', either, so no checks are made for those cases. Likewise,
### bridges are not used. ### bridges are not used.
# Single interface, set it up # Single interface, set it up
my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}; my $link1_mac = $anvil->data->{config}{$link1_key};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_mac => $link1_mac }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_mac => $link1_mac }});
my $say_network = ""; my $say_network = "";
@ -1356,160 +1727,6 @@ ORDER BY
next; next;
} }
} }
=cut
}
die;
# If we should reset, do so now.
if ($anvil->data->{sys}{reboot})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0687", variables => { reason => "#!string!log_0631!#" }});
do_reboot($anvil);
}
if ($changes)
{
# In an attempt to make network changes more reliable, we'll just reboot. This shouldn't
# actually be hit anymore as any change should have triggered the reboot above.
$anvil->data->{sys}{reboot} = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0687", variables => { reason => "#!string!log_0631!#" }});
do_reboot($anvil);
# # Re-read the config
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0463"});
#
# my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection reload";
# $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});
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
# output => $output,
# return_code => $return_code,
# }});
#
# # Give a couple seconds for the reload
# sleep 2;
#
# # Now check the bonds
# my $repaired = $anvil->Network->check_network({heal => "all"});
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { repaired => $repaired }});
# if ($repaired)
# {
# # It can take a bit for the bonds to allow traffic, so sleep for a bit.
# sleep 30;
# }
}
# Wait for a DB connection. We'll wait up to 130 seconds, as sometimes it takes a while for the network
# to start routing traffic.
# my $wait_until = time + 130;
# until ($anvil->data->{sys}{database}{connections})
# {
# $anvil->refresh();
# $anvil->Database->connect();
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0132"});
# if (not $anvil->data->{sys}{database}{connections})
# {
# if (time > $wait_until)
# {
# # Failed to reconnect, reboot. Hopefully the network comes up cleanly
# # next time..
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0107"});
# do_reboot($anvil);
# }
#
# # No databases, sleep and then try again.
# sleep 10;
# }
# }
# We're half-way there.
$anvil->Job->update_progress({
progress => 50,
job_uuid => $anvil->data->{job}{uuid},
});
# If any virtio bridges exist, remove it/them.
my $start = 0;
my ($bridges, $return_code) = $anvil->System->call({debug => 2, shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-list"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridges => $bridges, return_code => $return_code }});
if ($return_code)
{
### NOTE: We're doing a bunch of deletes, so to be safe we statically define the directory
### here.
# Libvirtd isn't running, check the directory directly.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0478"});
my $directory = "/etc/libvirt/qemu/networks/autostart";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
if (-d $directory)
{
# Delete all files.
local(*DIRECTORY);
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
my $full_path = $directory."/".$file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
file => $file,
full_path => $full_path,
}});
if (-l $full_path)
{
# It's a symlink, remove it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0479", variables => { 'symlink' => $full_path }});
unlink $full_path;
if (-l $full_path)
{
# It didn't work...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 0, priority => "err", key => "error_0132", variables => { 'symlink' => $full_path }});;
}
}
}
closedir(DIRECTORY);
}
}
else
{
foreach my $line (split/\n/, $bridges)
{
$line = $anvil->Words->clean_spaces({string => $line});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /^----------/)
{
$start = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { start => $start }});
next;
}
next if not $start;
my $bridge = ($line =~ /(.*?)\s/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge => $bridge }});
$anvil->data->{virsh}{bridge}{$bridge} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "virsh::bridge::$bridge" => $anvil->data->{virsh}{bridge}{$bridge} }});
}
foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{virsh}{bridge}})
{
# Destroy (stop) it.
my ($destroy, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-destroy ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { destroy => $destroy, return_code => $return_code }});
# Disable it from auto-start.
(my $disable, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-autostart ".$bridge." --disable"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disable => $disable, return_code => $return_code }});
# Undefine (delete)
(my $undefine, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-undefine ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { undefine => $undefine, return_code => $return_code }});
}
}
$anvil->Job->update_progress({
progress => 75,
job_uuid => $anvil->data->{job}{uuid},
});
return(0); return(0);
} }
@ -1633,9 +1850,26 @@ sub pickup_job_details
}}); }});
} }
### These are the new variables
$anvil->data->{config}{striker_password} = "";
$anvil->data->{config}{prefix} = "";
$anvil->data->{config}{sequence} = "";
$anvil->data->{config}{domain} = "";
$anvil->data->{config}{host_name} = "";
$anvil->data->{config}{organization} = "";
$anvil->data->{config}{bcn_count} = 1;
$anvil->data->{config}{ifn_count} = 1;
$anvil->data->{config}{sn_count} = 0;
$anvil->data->{config}{mn_count} = 0;
$anvil->data->{config}{dns} = "";
$anvil->data->{config}{gateway} = "";
$anvil->data->{config}{gateway_interface} = "";
### TODO: Remove this later
# This will store the variables from the database # This will store the variables from the database
$anvil->data->{variables} = {}; $anvil->data->{variables} = {};
### TODO: Remove this, it shouldn't be needed once we confirm everything is in the job_data.
# If we're still alive, pick up the details. # If we're still alive, pick up the details.
my $query = " my $query = "
SELECT SELECT
@ -1673,6 +1907,7 @@ AND
$anvil->_make_hash_reference($anvil->data->{variables}, $this_variable, $this_value); $anvil->_make_hash_reference($anvil->data->{variables}, $this_variable, $this_value);
} }
### TODO: This is the only way we should do it, but the variable names need to change to be more sensible.
# Overwrite variables with job data. # Overwrite variables with job data.
foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) foreach my $line (split/\n/, $anvil->data->{jobs}{job_data})
{ {
@ -1684,6 +1919,37 @@ AND
}}); }});
$anvil->_make_hash_reference($anvil->data->{variables}, $1, $2); $anvil->_make_hash_reference($anvil->data->{variables}, $1, $2);
} }
elsif ($line =~ /^(.*?)=(.*)$/)
{
my $variable = $1;
my $value = $2;
my $secure = $variable =~ /passw/ ? 1 : 0;
$anvil->data->{config}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:variable' => $variable,
's2:value' => $anvil->Log->is_secure($value),
"s3:config::${variable}" => $anvil->Log->is_secure($anvil->data->{config}{$variable}),
}});
}
}
### TODO: Remove this when no longer needed.
# Convert old variables to new ones.
foreach my $config_step (sort {$a cmp $b} keys %{$anvil->data->{variables}{form}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { config_step => $config_step }});
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{variables}{form}{$config_step}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable }});
if (exists $anvil->data->{variables}{form}{$config_step}{$variable}{value})
{
$anvil->data->{config}{$variable} = $anvil->data->{variables}{form}{$config_step}{$variable}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"config::${variable}" => $anvil->data->{config}{$variable},
}});
}
}
} }
# Clear previous data # Clear previous data

@ -201,7 +201,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});
@ -210,25 +210,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.
@ -313,85 +301,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
{ {
@ -556,9 +465,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);
@ -1537,7 +1443,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}})
{ {
@ -1568,18 +1474,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);
@ -1672,11 +1573,10 @@ 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 mapping, we'll only run 'anvil-configure-host' jobs on this host.
next if (($anvil->data->{sys}{mapping_network}) && ($job_command !~ /anvil-configure-host/)); next if $job_command !~ /anvil-configure-host/;
# 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.
@ -2028,24 +1928,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);
}

@ -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) = @_;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -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