* Updated Network->load_interfces() to only assign a 'changed_order' to real interfaces.

* Fixed a bug in System->generate_state_json() where interfaces connected to a bridge were constantly having their 'network_interface_bond_uuid' cleared and reset.
* Finished (for now) the jquery code to update the network interface list when preparing the network interface configuration of a new node or DR host.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 0dfd2ddbf0
commit 90f5bf49d5
  1. 19
      Anvil/Tools/Network.pm
  2. 2
      Anvil/Tools/System.pm
  3. 12
      html/skins/alteeve/anvil.html
  4. 75
      html/skins/alteeve/anvil.js
  5. 15
      tools/anvil-daemon
  6. 197
      tools/anvil-update-states
  7. 19
      tools/test.pl

@ -994,7 +994,7 @@ AND
ORDER BY
modified_date DESC
;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -1017,6 +1017,15 @@ ORDER BY
my $network_interface_bridge_uuid = defined $row->[10] ? $row->[10] : "";
my $bond_name = "";
my $bridge_name = "";
my $this_change_orger = 0;
if (($network_interface_name =~ /^virbr/) or ($network_interface_name =~ /^vnet/))
{
# This isn't a physical NIC, so it doesn't get a changed order
}
else
{
$this_change_orger = $changed_order++;
}
if (($network_interface_bond_uuid) && (defined $anvil->data->{network}{$host}{bond_uuid}{$network_interface_bond_uuid}{name}))
{
$bond_name = $anvil->data->{network}{$host}{bond_uuid}{$network_interface_bond_uuid}{name};
@ -1048,10 +1057,9 @@ ORDER BY
network_interface_bond_uuid => $network_interface_bond_uuid,
network_interface_bridge_uuid => $network_interface_bridge_uuid,
bond_name => $bond_name,
changed_order => $changed_order,
changed_order => $this_change_orger,
}});
# We'll initially load empty strings for what would be the IP information. Any interface with IPs will be populated when we call
$anvil->data->{network}{$host}{interface}{$network_interface_name}{uuid} = $network_interface_uuid;
$anvil->data->{network}{$host}{interface}{$network_interface_name}{mac_address} = $network_interface_mac_address;
@ -1066,8 +1074,8 @@ ORDER BY
$anvil->data->{network}{$host}{interface}{$network_interface_name}{bridge_uuid} = $network_interface_bridge_uuid;
$anvil->data->{network}{$host}{interface}{$network_interface_name}{bridge_name} = $bridge_name;
$anvil->data->{network}{$host}{interface}{$network_interface_name}{type} = "interface";
$anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order} = $changed_order;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
$anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order} = $this_change_orger;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"network::${host}::interface::${network_interface_name}::uuid" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{uuid},
"network::${host}::interface::${network_interface_name}::mac_address" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{mac_address},
"network::${host}::interface::${network_interface_name}::speed" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{speed},
@ -1083,7 +1091,6 @@ ORDER BY
"network::${host}::interface::${network_interface_name}::type" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{type},
"network::${host}::interface::${network_interface_name}::changed_order" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order},
}});
$changed_order++;
}
# Load the IPs

@ -882,7 +882,7 @@ sub generate_state_json
my $mtu = $anvil->data->{network}{$host}{interface}{$interface}{mtu};
my $mac_address = $anvil->data->{network}{$host}{interface}{$interface}{mac_address};
my $iface_hash = {};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:interface" => $interface,
"s2:mac_address" => $mac_address,
"s3:type" => $type,

@ -179,7 +179,17 @@
</table>
</td>
<td width="25%" style="padding-left: 1em; vertical-align: top;">
<div id="network_interface_table" data-host-name="#!variable!host_name!#"/>
<div id="network_interface_table"
data-host-name="#!variable!host_name!#"
data-title="#!string!header_0001!#"
data-mac-address="#!string!header_0002!#"
data-name="#!string!header_0003!#"
data-state="#!string!header_0004!#"
data-speed="#!string!header_0005!#"
data-up-order="#!string!header_0006!#"
data-up="#!string!unit_0013!#"
data-down="#!string!unit_0014!#"
/>
</td>
</tr>
<tr>

@ -39,15 +39,15 @@ $( window ).on( "load", function()
// Open the table
var body = '<table id="unconfigured_hosts_table" class="data_table_nowrap">';
body += '<tr class="data_row">';
body += '<td class="column_header">'+say_unconfigured+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_type+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_accessible+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_at_ip+'</td>';
body += '</tr>';
body += '<tr class="data_row">';
body += '<td class="column_header">'+say_unconfigured+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_type+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_accessible+'</td>';
body += '<td class="column_header"> &nbsp; </td>';
body += '<td class="column_header">'+say_at_ip+'</td>';
body += '</tr>';
$.each(data.hosts, function(index, element) {
if (element.type === 'dashboard') {
// Skip
@ -138,19 +138,68 @@ $( window ).on( "load", function()
body += '</table>';
// clear + append can't be the best way to do this...
$( "#unconfigured_hosts" ).empty();
$( "#unconfigured_hosts" ).append(body);
$("#unconfigured_hosts").empty();
$("#unconfigured_hosts").append(body);
});
}, 1000);
};
// Run in we're showing a specific hosts' network.
if ($('#network_interface_table').length) {
var host_name = $('#network_interface_table').data('host-name');
var host_name = $('#network_interface_table').data('host-name');
var say_title = $('#network_interface_table').data('title');
var say_mac_address = $('#network_interface_table').data('mac-address');
var say_name = $('#network_interface_table').data('name');
var say_state = $('#network_interface_table').data('state');
var say_speed = $('#network_interface_table').data('speed');
var say_up_order = $('#network_interface_table').data('up-order');
var say_up = $('#network_interface_table').data('up');
var say_down = $('#network_interface_table').data('down');
//console.log('showing network info for: ['+host_name+']');
setInterval(function() {
$.getJSON('/status/all_status.json', function(data) {
//console.log('Reload: ['+host_name+']');
//console.log('read all_status.json: ['+data+']');
// Build the HTML
var body = '<table id="network_interface_table" class="data_table_nowrap">';
body += '<tr>';
body += '<td colspan="5" class="column_header">'+say_title+'</td>';
body += '</tr>';
body += '<tr class="data_row">';
body += '<td class="column_row_name">'+say_mac_address+'</td>';
body += '<td class="column_row_name">'+say_name+'</td>';
body += '<td class="column_row_name">'+say_state+'</td>';
body += '<td class="column_row_name">'+say_speed+'</td>';
body += '<td class="column_row_name">'+say_up_order+'</td>';
body += '</tr>';
$.each(data.hosts, function(i, host) {
//console.log('This is: ['+host.name+']');
if (host.name != host_name) {
// Skip
return true;
};
//console.log('Found it!');
$.each(host.network_interfaces, function(j, nic) {
// Only real interfaces have a 'changed_order' value.
if (nic.changed_order) {
var say_link_state = say_down;
if (nic.link_state) {
say_link_state = say_up;
}
body += '<tr class="data_row">';
body += '<td class="column_row_value_fixed">'+nic.mac_address+'</td>';
body += '<td class="column_row_value_fixed_centered">'+nic.name+'</td>';
body += '<td class="column_row_value_fixed_centered">'+say_link_state+'</td>';
body += '<td class="column_row_value_fixed_centered">'+nic.say_speed+'</td>';
body += '<td class="column_row_value_fixed_centered">'+nic.changed_order+'</td>';
body += '</tr>';
}
});
});
body += '</table>';
// clear + append can't be the best way to do this...
$("#network_interface_table").empty();
$("#network_interface_table").append(body);
});
}, 1000);
};

@ -1143,7 +1143,7 @@ sub keep_running
# 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);
$anvil->System->generate_state_json({debug => 3});
}
else
{
@ -1157,19 +1157,6 @@ sub keep_running
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.
$anvil->System->generate_state_json({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
# 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.

@ -347,8 +347,27 @@ sub update_network
}
closedir(DIRECTORY);
# We need to record bonds first so that their UUIDs are available when recording interfaces.
foreach my $processing ("bond", "interface", "bridge")
# Find what interfaces are connected to which bridges
$anvil->Network->bridge_info({debug => 3});
delete $anvil->data->{interface_to_bridge} if exists $anvil->data->{interface_to_bridge};
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_name => $bridge_name }});
foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface_name => $interface_name }});
$anvil->data->{interface_to_bridge}{$interface_name} = $bridge_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"interface_to_bridge::${interface_name}" => $anvil->data->{interface_to_bridge}{$interface_name},
}});
}
}
# We need to record bridges first so we know their UUIDs when looking at bonds and interfaces that
# might be connected to them. Then we need to look at bonds so that their UUIDs are available when
# recording interfaces.
foreach my $processing ("bridge", "bond", "interface")
{
$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}})
@ -409,10 +428,53 @@ sub update_network
up_delay => $up_delay,
}});
if (($type eq $processing) && ($type eq "bridge"))
{
my $bridge_uuid = $anvil->Database->insert_or_update_bridges({
debug => 3,
file => $THIS_FILE,
line => __LINE__,
bridge_name => $interface,
bridge_id => $bridge_id,
bridge_mac_address => $mac_address,
bridge_mtu => $mtu,
bridge_stp_enabled => $bridge_stp_enabled,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_uuid => $bridge_uuid }});
$anvil->data->{bridge_by_name}{$interface} = $bridge_uuid;
$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))
{
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
file => $THIS_FILE,
line => __LINE__,
ip_address_on_type => $type,
ip_address_on_uuid => $bridge_uuid,
ip_address_address => $ip_address,
ip_address_subnet_mask => $subnet_mask,
ip_address_gateway => $gateway,
ip_address_default_gateway => $default_gateway,
ip_address_dns => $dns,
ip_address_note => "",
});
}
}
if (($type eq $processing) && ($type eq "bond"))
{
# Is this bond connected to a bridge?
my $bond_bridge_uuid = "";
my $bond_on_bridge = exists $anvil->data->{interface_to_bridge}{$interface} ? $anvil->data->{interface_to_bridge}{$interface} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_on_bridge => $bond_on_bridge }});
if ($bond_on_bridge)
{
$bond_bridge_uuid = $anvil->data->{bridge_by_name}{$bond_on_bridge};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_bridge_uuid => $bond_bridge_uuid }});
}
my $bond_uuid = $anvil->Database->insert_or_update_bonds({
debug => 3,
debug => 2,
file => $THIS_FILE,
line => __LINE__,
bond_name => $interface,
@ -427,6 +489,7 @@ sub update_network
bond_mii_polling_interval => $mii_polling_interval,
bond_up_delay => $up_delay,
bond_down_delay => $down_delay,
bond_bridge_uuid => $bond_bridge_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_uuid => $bond_uuid }});
@ -452,6 +515,16 @@ sub update_network
if (($type eq $processing) && ($type eq "interface"))
{
# Is this interface connected to a bridge?
my $network_interface_bridge_uuid = "";
my $network_interface_on_bridge = exists $anvil->data->{interface_to_bridge}{$interface} ? $anvil->data->{interface_to_bridge}{$interface} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_on_bridge => $network_interface_on_bridge }});
if ($network_interface_on_bridge)
{
$network_interface_bridge_uuid = $anvil->data->{bridge_by_name}{$network_interface_on_bridge};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_bridge_uuid => $network_interface_bridge_uuid }});
}
my $say_bond_uuid = "";
$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}))
@ -463,10 +536,11 @@ sub update_network
}});
}
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
debug => 3,
debug => 2,
file => $THIS_FILE,
line => __LINE__,
network_interface_bond_uuid => $say_bond_uuid,
network_interface_bridge_uuid => $network_interface_bridge_uuid,
network_interface_name => $interface,
network_interface_duplex => $duplex,
network_interface_link_state => $link_state,
@ -496,39 +570,6 @@ sub update_network
});
}
}
if (($type eq $processing) && ($type eq "bridge"))
{
my $bridge_uuid = $anvil->Database->insert_or_update_bridges({
debug => 3,
file => $THIS_FILE,
line => __LINE__,
bridge_name => $interface,
bridge_id => $bridge_id,
bridge_mac_address => $mac_address,
bridge_mtu => $mtu,
bridge_stp_enabled => $bridge_stp_enabled,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_uuid => $bridge_uuid }});
$anvil->data->{bridge_by_name}{$interface} = $bridge_uuid;
$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))
{
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
file => $THIS_FILE,
line => __LINE__,
ip_address_on_type => $type,
ip_address_on_uuid => $bridge_uuid,
ip_address_address => $ip_address,
ip_address_subnet_mask => $subnet_mask,
ip_address_gateway => $gateway,
ip_address_default_gateway => $default_gateway,
ip_address_dns => $dns,
ip_address_note => "",
});
}
}
}
}
@ -842,88 +883,6 @@ WHERE
$network_xml .= " <ip address=\"$ip_address_address\" on=\"$say_on\" subnet_mask=\"$ip_address_subnet_mask\" gateway=\"$ip_address_gateway\" default_gateway=\"$ip_address_default_gateway\" dns=\"$ip_address_dns\" />\n";
}
# Now verify that the interface is connected to this bridge
$anvil->Network->bridge_info({debug => 3});
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}})
{
my $bridge_uuid = $anvil->data->{bridge_by_name}{$bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
bridge_name => $bridge_name,
bridge_uuid => $bridge_uuid,
}});
foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}})
{
my $interface_uuid = exists $anvil->data->{interface_by_name}{$interface_name} ? $anvil->data->{interface_by_name}{$interface_name} : "";
my $bond_uuid = exists $anvil->data->{bond_by_name}{$interface_name} ? $anvil->data->{bond_by_name}{$interface_name} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:interface_name' => $interface_name,
's2:interface_uuid' => $interface_uuid,
's3:bond_uuid' => $bond_uuid,
}});
# Is this interface a bond or an interface?
if ($interface_uuid)
{
# Read the interface_bridge_uuid and, if it doesn't match, update it.
my $query = "SELECT network_interface_bridge_uuid FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($interface_uuid).";";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { 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 => 2, list => {
results => $results,
count => $count,
}});
my $interface_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface_bridge_uuid => $interface_bridge_uuid }});
if (($bridge_uuid) && ($interface_bridge_uuid ne $bridge_uuid))
{
# Update it.
my $query = "
UPDATE
network_interfaces
SET
network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
network_interface_uuid = ".$anvil->Database->quote($interface_uuid)."
;" ;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__});
}
}
elsif ($bond_uuid)
{
# Read the interface_bridge_uuid and, if it doesn't match, update it.
my $query = "SELECT bond_bridge_uuid FROM bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { 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 => 2, list => {
results => $results,
count => $count,
}});
my $bond_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_bridge_uuid => $bond_bridge_uuid }});
if (($bridge_uuid) && ($bond_bridge_uuid ne $bridge_uuid))
{
# Update it.
my $query = "
UPDATE
bonds
SET
bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
bond_uuid = ".$anvil->Database->quote($bond_uuid)."
;" ;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__});
}
}
}
}
$network_json =~ s/,$//s;
$network_json .= "]}\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_json => $network_json }});

@ -27,11 +27,24 @@ $anvil->Log->level({set => 2});
$anvil->Database->connect({debug => 3, check_if_configured => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
$anvil->System->generate_state_json({debug => 3});
$anvil->Striker->parse_all_status_json({debug => 3});
my $interface_uuid = "ffd6d29b-100c-452f-be4f-51cbc94eb069";
my $query = "SELECT network_interface_bridge_uuid FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($interface_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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 => 2, list => {
results => $results,
count => $count,
}});
my $network_interface_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_bridge_uuid => $network_interface_bridge_uuid }});
#$anvil->System->generate_state_json({debug => 3});
#$anvil->Striker->parse_all_status_json({debug => 3});
#print Dumper $anvil->data->{json}{all_status}{hosts}{'el8-a01n01.digimer.ca'};
#die;
die;
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}})
{

Loading…
Cancel
Save