diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index fcec70e7..087ef049 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -2620,23 +2620,25 @@ Get a list of hosts from the c<< hosts >> table, returned as an array of hash re Each anonymous hash is structured as: - host_uuid => $host_uuid, - host_name => $host_name, - host_type => $host_type, - host_key => $host_key, - host_ipmi => $host_ipmi, - host_status => $host_status, - modified_date => $modified_date, + host_uuid => $host_uuid, + host_name => $host_name, + short_host_name => $short_host_name, + host_type => $host_type, + host_key => $host_key, + host_ipmi => $host_ipmi, + host_status => $host_status, + modified_date => $modified_date, It also sets the variables; - hosts::host_uuid::::host_name = ; - hosts::host_uuid::::host_type = - hosts::host_uuid::::host_key = - hosts::host_uuid::::host_ipmi = - hosts::host_uuid::::host_status = - hosts::host_uuid::::anvil_name = - hosts::host_uuid::::anvil_uuid = + hosts::host_uuid::::host_name = ; + hosts::host_uuid::::short_host_name = ; + hosts::host_uuid::::host_type = + hosts::host_uuid::::host_key = + hosts::host_uuid::::host_ipmi = + hosts::host_uuid::::host_status = + hosts::host_uuid::::anvil_name = + hosts::host_uuid::::anvil_uuid = And to simplify look-ups by UUID or name; @@ -2779,10 +2781,9 @@ WHERE } -### TODO: Why does this method exist? =head2 get_hosts_info -This gathers up all the known information about all known hosts. +This gathers up all the known information about all known hosts, inlcuding information from the C<< variables >> table linked to each host. This method takes no parameters. diff --git a/cgi-bin/Makefile.am b/cgi-bin/Makefile.am index 306463f0..1528e4bd 100644 --- a/cgi-bin/Makefile.am +++ b/cgi-bin/Makefile.am @@ -8,6 +8,7 @@ dist_cgibin_SCRIPTS = \ get_cpu \ get_memory \ get_replicated_storage \ + get_servers \ get_shared_storage \ get_status \ set_membership \ diff --git a/cgi-bin/get_servers b/cgi-bin/get_servers new file mode 100755 index 00000000..64c86f60 --- /dev/null +++ b/cgi-bin/get_servers @@ -0,0 +1,140 @@ +#!/usr/bin/perl +# +# This prints JSON formated data reporting the status of servers on an Anvil! system. +# + +use strict; +use warnings; +use Anvil::Tools; +use Data::Dumper; +use JSON; + +$| = 1; + +my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; +my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; +if (($running_directory =~ /^\./) && ($ENV{PWD})) +{ + $running_directory =~ s/^\./$ENV{PWD}/; +} + +my $anvil = Anvil::Tools->new(); + +$anvil->Get->switches; + +$anvil->Database->connect; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); +if (not $anvil->data->{sys}{database}{connections}) +{ + # No databases, exit. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"}); + $anvil->nice_exit({exit_code => 1}); +} + +# Read in any CGI variables, if needed. +$anvil->Get->cgi(); + +$anvil->Database->get_hosts(); +$anvil->Database->get_anvils(); + +print $anvil->Template->get({file => "shared.html", name => "json_headers", show_name => 0})."\n"; + +my $hash = {}; +my $anvil_uuid = ""; +if ($anvil->data->{cgi}{anvil_uuid}{value}) +{ + $anvil_uuid = $anvil->data->{cgi}{anvil_uuid}{value}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }}); +} +elsif ($anvil->data->{switches}{'anvil-uuid'}) +{ + $anvil_uuid = $anvil->data->{switches}{'anvil-uuid'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }}); +} +if ((not $anvil_uuid) or (not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid})) +{ + $anvil->data->{anvil_status}{anvil_name} = "!!invalid!anvil_uuid!!"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'anvil_status::anvil_name' => $anvil->data->{anvil_status}{anvil_name} }}); +} +else +{ + my $node1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; + my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{short_host_name}; + my $node2_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}; + my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{short_host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + node1_uuid => $node1_uuid, + node1_host_name => $node1_host_name, + node2_uuid => $node2_uuid, + node2_host_name => $node2_host_name, + }}); + + $hash->{servers} = []; + + # For each node, check to see if it's "online" and, if so, if the node is in the cluster. + $anvil->Database->get_hosts_info(); + + my $query = " +SELECT + server_uuid, + server_name, + server_state, + server_host_uuid +FROM + servers +WHERE + server_anvil_uuid = ".$anvil->Database->quote($anvil_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, + }}); + foreach my $row (@{$results}) + { + # How online is it? + my $server_uuid = $row->[0]; + my $server_name = $row->[1]; + my $server_state = $row->[2]; + my $server_host_uuid = $row->[3]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + server_uuid => $server_uuid, + server_name => $server_name, + server_state => $server_state, + server_host_uuid => $server_host_uuid, + }}); + + # Ignore deleted servers. + next if $server_state eq "DELETED"; + + my $server_host_index = undef; + if ($server_state ne "shut off") + { + if ($server_host_uuid eq $node1_uuid) + { + $server_host_index = 0; + } + elsif ($server_host_uuid eq $node2_uuid) + { + $server_host_index = 1; + } + else + { + # Is it on DR? + } + } + + push @{$hash->{servers}}, { + server_uuid => $server_uuid, + server_name => $server_name, + server_state => $server_state, + server_host_uuid => $server_state eq "shut off" ? undef : $server_host_uuid, + server_host_index => $server_host_index, + }; + } +} + +print JSON->new->utf8->encode($hash)."\n"; + \ No newline at end of file diff --git a/cgi-bin/get_status b/cgi-bin/get_status index 051a71a4..f4e9d9fb 100755 --- a/cgi-bin/get_status +++ b/cgi-bin/get_status @@ -60,111 +60,127 @@ else { my $node1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; my $node2_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}; - my $dr1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node1_uuid => $node1_uuid, node2_uuid => $node2_uuid, - dr1_uuid => $dr1_uuid, }}); - my $query = " -SELECT - -FROM - hosts a, - scan_filesystems b -WHERE - a.host_uuid = b.scan_filesystem_host_uuid -AND - ( - a.host_uuid = ".$anvil->Database->quote($node1_uuid)." - OR - a.host_uuid = ".$anvil->Database->quote($node2_uuid); - if ($dr1_uuid) - { - $query .= " - OR - a.host_uuid = ".$anvil->Database->quote($dr1_uuid); - } - $query .= " - ) -ORDER BY - a.host_name ASC, - b.scan_filesystem_mount_point DESC -;"; - $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}; + # For each node, check to see if it's "online" and, if so, if the node is in the cluster. + $anvil->Database->get_hosts_info(); + + # Read in the + my $node1_status = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{host_status}; + my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{short_host_name}; + my $node2_status = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{host_status}; + my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{short_host_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - results => $results, - count => $count, + node1_status => $node1_status, + node1_host_name => $node1_host_name, + node2_status => $node2_status, + node2_host_name => $node2_host_name, }}); - foreach my $row (@{$results}) + + # Array index 0 is node 1, index 1 is node 2. + $hash->{anvil_state} = "optimal"; + $hash->{nodes}->[0] = { + host_uuid => $node1_uuid, + 'state' => "offline", + state_percent => 0, + state_message => "message_0222,!!host_name!".$node1_host_name."!!", + maintenance_mode => 'undefined', + }; + $hash->{nodes}->[1] = { + host_uuid => $node2_uuid, + 'state' => "offline", + state_percent => 0, + state_message => "message_0222,!!host_name!".$node2_host_name."!!", + maintenance_mode => 'undefined', + }; + + foreach my $i (0..1) { - my $host_uuid = $row->[0]; - my $host_name = $row->[1]; - my $mount_point = $row->[2]; - my $size = $row->[3]; - my $used = $row->[4]; - my $free = $size - $used; + my $host_uuid = $hash->{nodes}->[$i]->{host_uuid}; + my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name}; + my $host_status = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - host_uuid => $host_uuid, - host_name => $host_name, - mount_point => $mount_point, - size => $anvil->Convert->add_commas({number => $size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size}).")",, - used => $anvil->Convert->add_commas({number => $used})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $used}).")",, - free => $anvil->Convert->add_commas({number => $free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free}).")",, + 's1:short_host_name' => $short_host_name, + 's2:host_uuid' => $host_uuid, + 's3:host_status' => $host_status, }}); - $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name} = $host_name; - $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total} = $size; - $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free} = $free; + # If the node is not "online", nothing else matters. + next if $host_status ne "online"; + + my $query = " +SELECT + scan_cluster_node_in_ccm, + scan_cluster_node_crmd_member, + scan_cluster_node_cluster_member, + scan_cluster_node_maintenance_mode +FROM + scan_cluster_nodes +WHERE + scan_cluster_node_host_uuid = ".$anvil->Database->quote($host_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 => { - "raw::file_systems::${mount_point}::nodes::${host_uuid}::host_name" => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name}, - "raw::file_systems::${mount_point}::nodes::${host_uuid}::total" => $anvil->Convert->add_commas({number => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}}).")",, - "raw::file_systems::${mount_point}::nodes::${host_uuid}::free" => $anvil->Convert->add_commas({number => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}}).")",, + results => $results, + count => $count, }}); - } - - $anvil->data->{file_systems} = []; - - foreach my $mount_point (sort {$a cmp $b} keys %{$anvil->data->{raw}{file_systems}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mount_point => $mount_point }}); - $hash->{mount_point} = $mount_point; - $hash->{nodes} = []; - my $nodes = [$node1_uuid, $node2_uuid]; - if ($dr1_uuid) + + if (not $count) { - push @{$nodes}, $dr1_uuid; + # Weird, looks like this host isn't a node. + next; } - foreach my $host_uuid (@{$nodes}) + foreach my $row (@{$results}) { - my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}; + # How online is it? + my $scan_cluster_node_in_ccm = $row->[0]; + my $scan_cluster_node_crmd_member = $row->[1]; + my $scan_cluster_node_cluster_member = $row->[2]; + my $scan_cluster_node_maintenance_mode = $row->[3]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - host_uuid => $host_uuid, - host_name => $host_name, + scan_cluster_node_in_ccm => $scan_cluster_node_in_ccm, + scan_cluster_node_crmd_member => $scan_cluster_node_crmd_member, + scan_cluster_node_cluster_member => $scan_cluster_node_cluster_member, + scan_cluster_node_maintenance_mode => $scan_cluster_node_maintenance_mode, }}); - if (exists $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}) + + $hash->{nodes}->[$i]->{maintenance_mode} = $scan_cluster_node_maintenance_mode ? 1 : 0; + if ($scan_cluster_node_cluster_member) { - push @{$hash->{nodes}}, { - host_uuid => $host_uuid, - host_name => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name}, - is_mounted => 1, - total => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}, - free => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}, - } + $hash->{nodes}->[$i]->{'state'} = "online"; + $hash->{nodes}->[$i]->{state_percent} = 100; + $hash->{nodes}->[$i]->{state_message} = "message_0223,!!host_name!".$node2_host_name."!!", + } + elsif ($scan_cluster_node_crmd_member) + { + $hash->{nodes}->[$i]->{'state'} = "crmd"; + $hash->{nodes}->[$i]->{state_percent} = 75; + $hash->{nodes}->[$i]->{state_message} = "message_0224,!!host_name!".$node2_host_name."!!", + } + elsif ($scan_cluster_node_in_ccm) + { + $hash->{nodes}->[$i]->{'state'} = "in_ccm"; + $hash->{nodes}->[$i]->{state_percent} = 50; + $hash->{nodes}->[$i]->{state_message} = "message_0225,!!host_name!".$node2_host_name."!!", } else { - push @{$hash->{nodes}}, { - host_uuid => $host_uuid, - host_name => $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}, - is_mounted => 0, - total => 0, - free => 0, - } + $hash->{nodes}->[$i]->{'state'} = "booted"; + $hash->{nodes}->[$i]->{state_percent} = 25; + $hash->{nodes}->[$i]->{state_message} = "message_0226,!!host_name!".$node2_host_name."!!", } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "hash->{nodes}->[".$i."]->{state}" => $hash->{nodes}->[$i]->{'state'}, + "hash->{nodes}->[".$i."]->{state_percent}" => $hash->{nodes}->[$i]->{state_percent}, + "hash->{nodes}->[".$i."]->{state_message}" => $hash->{nodes}->[$i]->{state_message}, + "hash->{nodes}->[".$i."]->{maintenance_mode}" => $hash->{nodes}->[$i]->{maintenance_mode}, + }}); } } } diff --git a/share/words.xml b/share/words.xml index eb253c63..c83f24eb 100644 --- a/share/words.xml +++ b/share/words.xml @@ -1757,6 +1757,11 @@ Are you sure that you want to delete the server: [#!variable!server_name!#]? [Ty - #!variable!server_name!# (Current state: [#!variable!server_state!#]) - * #!variable!server_name!# (Deleted, name can be reused) We're Striker: [#!variable!striker!#], and we're now configured, so we're done. Striker 1 will finish configuration. + The node: [#!variable!host_name!#] is in an unknown state. + The node: [#!variable!host_name!#] is a full cluster member. + The node: [#!variable!host_name!#] is coming online; the cluster resource manager is running. (step 2/3) + The node: [#!variable!host_name!#] is coming online; the node is a consensus cluster member. (step 1/3) + The node: [#!variable!host_name!#] has booted, but it is not (yet) joining the cluster. Saved the mail server information successfully!