Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

692 lines
33 KiB

#!/usr/bin/perl
#
# This allows users to link volume groups across machines into storage groups.
#
# NOTE: This will be expanded on much more later. For now, it's "enough".
#
# Exit codes;
# 0 = Normal exit.
# 1 = Any problem that causes an early exit.
#
# Examples;
# - TODO: Write the man page!
# - anvil-manage-storage-groups -vv --log-secure --anvil mk-anvil-07 --rename --group "Storage group 2" --new-name "HDD Group 1"
# - anvil-manage-storage-groups -vv --log-secure --anvil mk-anvil-07 --add --group "HDD Group 1" --member xidRiS-KT4K-cmVN-MRbK-tI2c-jhK6-VCCLau
use strict;
use warnings;
use Anvil::Tools;
require POSIX;
use Term::Cap;
use Text::Diff;
use Data::Dumper;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
$| = 1;
my $anvil = Anvil::Tools->new();
$anvil->Get->switches({list => [
"add",
"anvil",
"remove",
"rename",
"group",
"host",
"member",
"new-name",
"show",
"vg"], man => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try
# again after we exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0306"});
sleep 10;
$anvil->nice_exit({exit_code => 1});
}
$anvil->Database->get_hosts({include_deleted => 1});
$anvil->Database->get_anvils();
$anvil->Database->get_storage_group_data({debug => 2});
get_vg_data($anvil);
get_storage_data($anvil);
if ($anvil->data->{switches}{show})
{
show_data($anvil);
$anvil->nice_exit({exit_code => 0});
}
if ($anvil->data->{switches}{member})
{
manage_group_member($anvil);
}
if ($anvil->data->{switches}{group})
{
manage_group($anvil);
}
show_data($anvil);
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
sub manage_group
{
my ($anvil) = @_;
my $group = $anvil->data->{switches}{group};
my $new_name = $anvil->data->{switches}{'new-name'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
group => $group,
new_name => $new_name
}});
if ($group eq "#!SET!#")
{
print "When adding, removing or renaming a group, '--group' needs to be set to the (new) group name.\n";
$anvil->nice_exit({exit_code => 1});
}
# If both are set, what?
if ((($anvil->data->{switches}{add}) && ($anvil->data->{switches}{remove})) or
(($anvil->data->{switches}{add}) && ($anvil->data->{switches}{'rename'})) or
(($anvil->data->{switches}{remove}) && ($anvil->data->{switches}{'rename'})))
{
print "You can only use '--add', '--remove' or '--rename', please use only one at a time.\n";
$anvil->nice_exit({exit_code => 1});
}
my $anvil_uuid = $anvil->Database->get_anvil_uuid_from_string({string => $anvil->data->{switches}{anvil}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
if (not $anvil_uuid)
{
if ($anvil->data->{switches}{anvil})
{
print "The Anvil! node: [".$anvil->data->{switches}{anvil}."] was not found.\n";
}
else
{
print "When managing a storage group, '--anvil <name or UUID>' is required as storage group names are not globally unique.\n";
}
$anvil->nice_exit({exit_code => 1});
}
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_name => $anvil_name }});
# If the group is 'DELETED', um, what the fuck?
if (($group eq "DELETED") or ($new_name eq "DELETED"))
{
print "You want to name your group 'DELETED'? Well that's cheaky... Exiting.\n";
$anvil->nice_exit({exit_code => 1});
}
my $storage_group_uuid = "";
my $storage_group_name = "";
if (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$group})
{
$storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$group}{storage_group_uuid};
$storage_group_name = $group;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_name => $storage_group_name,
}});
}
elsif (exists $anvil->data->{storage_groups}{storage_group_uuid}{$group})
{
$storage_group_uuid = $group;
$storage_group_name = $anvil->data->{storage_groups}{storage_group_uuid}{$group}{anvil_uuid}{$anvil_uuid}{storage_group_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_name => $storage_group_name,
}});
}
if ($anvil->data->{switches}{add})
{
# Does it already exist?
if ($storage_group_uuid)
{
print "The storage group: [".$storage_group_name."] on the Anvil! node: [".$anvil_name."] already exists, nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
# Add it.
$storage_group_uuid = $anvil->Database->insert_or_update_storage_groups({
debug => 2,
storage_group_anvil_uuid => $anvil_uuid,
storage_group_name => $storage_group_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_uuid => $storage_group_uuid }});
print "The storage group: [".$storage_group_name."] on the Anvil! node: [".$anvil_name."] has been created with the UUID: [".$storage_group_uuid."].\n";
$anvil->nice_exit({exit_code => 0});
}
elsif ($anvil->data->{switches}{remove})
{
# Does it exist?
if (not $storage_group_uuid)
{
print "The storage group: [".$group."] wasn't found on the Anvil! node: [".$anvil_name."], nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
# Remove it.
$storage_group_uuid = $anvil->Database->insert_or_update_storage_groups({
debug => 2,
storage_group_anvil_uuid => $anvil_uuid,
storage_group_name => "DELETED",
storage_group_name => $storage_group_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_uuid => $storage_group_uuid }});
print "The storage group: [".$storage_group_name."] on the Anvil! node: [".$anvil_name."] has been deleted.\n";
$anvil->nice_exit({exit_code => 0});
}
elsif ($anvil->data->{switches}{'rename'})
{
# Do we have a new name?
if (not $new_name)
{
print "The storage group: [".$storage_group_name."] exists on the Anvil! node: [".$anvil_name."], but no new name was given via '--new-name <name>' nothing to do.\n";
$anvil->nice_exit({exit_code => 1});
}
# Has the name changed?
if (($storage_group_name) eq ($new_name))
{
print "The storage group: [".$new_name."] already has the desired name on the: [".$anvil_name."], nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
# Rename it.
$storage_group_uuid = $anvil->Database->insert_or_update_storage_groups({
debug => 2,
storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $anvil_uuid,
storage_group_name => $new_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_uuid => $storage_group_uuid }});
print "The storage group: [".$storage_group_name."] on the Anvil! node: [".$anvil_name."] has been renamed to: [".$new_name."].\n";
$anvil->nice_exit({exit_code => 0});
}
return(0);
}
sub manage_group_member
{
my ($anvil) = @_;
my $group = $anvil->data->{switches}{group};
my $anvil_uuid = $anvil->Database->get_anvil_uuid_from_string({string => $anvil->data->{switches}{anvil}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
if (not $anvil_uuid)
{
if ($anvil->data->{switches}{anvil})
{
print "The Anvil! node: [".$anvil->data->{switches}{anvil}."] was not found.\n";
}
else
{
print "When managing a storage group members, '--anvil <name or UUID>' is required as storage group names are not globally unique.\n";
}
$anvil->nice_exit({exit_code => 1});
}
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_name => $anvil_name }});
my $storage_group_uuid = "";
my $storage_group_name = "";
foreach my $this_storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}})
{
my $this_storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$this_storage_group_name}{storage_group_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_storage_group_name => $this_storage_group_name,
this_storage_group_uuid => $this_storage_group_uuid,
}});
if (($group eq $this_storage_group_name) or ($group eq $this_storage_group_uuid))
{
# Found it.
$storage_group_uuid = $this_storage_group_uuid;
$storage_group_name = $this_storage_group_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_name => $storage_group_name,
}});
last;
}
}
if (not $storage_group_uuid)
{
# Group not found.
print "The storage group: [".$group."] was not found on the Anvil! node: [".$anvil_name."].\n";
print "Call with '--show' to see Anvil! nodes, DR hosts and existing storage groups.\n";
$anvil->nice_exit({exit_code => 1});
}
my $internal_vg_uuid = "";
my $host_uuid = "";
my $short_host_name = "";
my $lvm_vg_name = "";
if (($anvil->data->{switches}{add}) or ($anvil->data->{switches}{remove}))
{
# If both are set, what?
if (($anvil->data->{switches}{add}) && ($anvil->data->{switches}{remove}))
{
print "Both '--add' and '--remove' specified, please use only one at a time.\n";
$anvil->nice_exit({exit_code => 1});
}
# These need to be valid VG internal UUID
my $member_vg_uuid = $anvil->data->{switches}{member};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { member_vg_uuid => $member_vg_uuid }});
# Find the VG internal UUID.
if (not exists $anvil->data->{vgs}{scan_lvm_vg_internal_uuid}{$member_vg_uuid})
{
print "The volume group with the internal UUID: [".$member_vg_uuid."] was not found.\n";
print "Call with '--show' to see Anvil! nodes, DR hosts and existing storage groups.\n";
$anvil->nice_exit({exit_code => 1});
}
# Now that we have an VG internal UUID, is it a node in the Anvil!, or a DR host?
$internal_vg_uuid = $member_vg_uuid;
$host_uuid = $anvil->data->{vgs}{scan_lvm_vg_internal_uuid}{$member_vg_uuid}{host_uuid};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
$short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
my $host_key = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_key};
my $host_anvil_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name};
my $host_anvil_uuid = $anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_uuid};
$lvm_vg_name = $anvil->data->{vgs}{host_uuid}{$host_uuid}{scan_lvm_vg_internal_uuid}{$internal_vg_uuid}{scan_lvm_vg_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
internal_vg_uuid => $internal_vg_uuid,
lvm_vg_name => $lvm_vg_name,
host_uuid => $host_uuid,
host_type => $host_type,
short_host_name => $short_host_name,
host_key => $host_key,
host_anvil_name => $host_anvil_name,
host_anvil_uuid => $host_anvil_uuid,
}});
if ($host_key eq "DELETED")
{
print "The volume group: [".$lvm_vg_name."] is on the deleted host: [".$host_name."]\n";
print "Call with '--show' to see Anvil! nodes, DR hosts and existing storage groups.\n";
$anvil->nice_exit({exit_code => 1});
}
if ($host_type eq "striker")
{
print "The volume group: [".$lvm_vg_name."] is on the Striker dashboard: [".$host_name."].\n";
print "There's no point in a Striker being part of a storage group.\n";
print "Call with '--show' to see Anvil! nodes, DR hosts and existing storage groups.\n";
$anvil->nice_exit({exit_code => 1});
}
if (($host_type eq "node") && ($anvil_uuid ne $host_anvil_uuid))
{
print "The volume group: [".$lvm_vg_name."] is on the sub node: [".$host_name."]. This is part of\n";
print "the Anvil! node: [".$host_anvil_name."], but: [".$anvil_name."] was specified with '--anvil'.\n";
$anvil->nice_exit({exit_code => 1});
}
}
# Add needs to be the internal UUID
if ($anvil->data->{switches}{add})
{
# Add the VG, if needed.
if (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid})
{
# If the note is not 'DELETED', we don't need to add it.
my $storage_group_member_note = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{storage_group_member_note};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_member_note => $storage_group_member_note }});
if ($storage_group_member_note ne "DELETED")
{
# Nothing to do.
print "The volume group: [".$lvm_vg_name."] on the host: [".$short_host_name."] is already a member of the storage group: [".$storage_group_name."]. Nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
}
# Still here? Add or update!
my $storage_group_member_uuid = $anvil->Database->insert_or_update_storage_group_members({
debug => 2,
storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $internal_vg_uuid,
storage_group_member_note => "user-created",
});
print "Added the volume group: [".$lvm_vg_name."] on the host: [".$short_host_name."] to the storage group: [".$storage_group_name."]. The new member UUID is: [".$storage_group_member_uuid."].\n";
$anvil->nice_exit({exit_code => 0});
}
else
{
# If there's no existing entry, there's nothing to remove.
if (not exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid})
{
# Nothing to do.
print "The volume group: [".$lvm_vg_name."] on the host: [".$short_host_name."] has never been a member of the storage group: [".$storage_group_name."]. Nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
# If the note is not 'DELETED', we don't need to add it.
if ($anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{storage_group_member_note} eq "DELETED")
{
# Nothing to do.
print "The volume group: [".$lvm_vg_name."] on the host: [".$short_host_name."] has already been removed from the storage group: [".$storage_group_name."]. Nothing to do.\n";
$anvil->nice_exit({exit_code => 0});
}
# Still here? update!
my $storage_group_member_uuid = $anvil->Database->insert_or_update_storage_group_members({
debug => 2,
storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $internal_vg_uuid,
storage_group_member_note => "DELETED",
});
print "Added the volume group: [".$lvm_vg_name."] on the host: [".$short_host_name."] has been removed from storage group: [".$storage_group_name."].\n";
$anvil->nice_exit({exit_code => 0});
}
return(0);
}
sub show_data
{
my ($anvil) = @_;
my $show_anvil_uuid = $anvil->Database->get_anvil_uuid_from_string({string => $anvil->data->{switches}{anvil}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { show_anvil_uuid => $show_anvil_uuid }});
foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}})
{
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid};
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description};
my $anvil_node1_host_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_node1_host_uuid};
my $anvil_node2_host_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_node2_host_uuid};
if (($show_anvil_uuid) && ($anvil_uuid ne $show_anvil_uuid))
{
next;
}
print "Anvil Node: [".$anvil_name."] - ".$anvil_description."\n";
foreach my $node_host_uuid ($anvil_node1_host_uuid, $anvil_node2_host_uuid)
{
my $node_host_name = $anvil->data->{hosts}{host_uuid}{$node_host_uuid}{short_host_name};
print "- Subnode: [".$node_host_name."] volume groups;\n";
foreach my $scan_lvm_vg_name (sort {$a cmp $b} keys %{$anvil->data->{vgs}{host_uuid}{$node_host_uuid}{scan_lvm_vg_name}})
{
my $scan_lvm_vg_internal_uuid = $anvil->data->{vgs}{host_uuid}{$node_host_uuid}{scan_lvm_vg_name}{$scan_lvm_vg_name}{scan_lvm_vg_internal_uuid};
my $scan_lvm_vg_size = $anvil->data->{vgs}{host_uuid}{$node_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size};
my $scan_lvm_vg_free = $anvil->data->{vgs}{host_uuid}{$node_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free};
my $say_size_hr = $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size});
my $say_free_hr = $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free});
print " - [".$scan_lvm_vg_name."], size: [".$say_size_hr."], free: [".$say_free_hr."], internal UUID: [".$scan_lvm_vg_internal_uuid."]\n";
}
}
foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}})
{
my $storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid};
print "- Storage group: [".$storage_group_name."], UUID: [".$storage_group_uuid."]\n";
foreach my $member_short_host_name (sort {$a cmp $b} keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{short_host_name}})
{
my $member_host_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{short_host_name}{$member_short_host_name}{host_uuid};
my $storage_group_member_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$member_host_uuid}{storage_group_member_uuid};
my $vg_internal_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$member_host_uuid}{vg_internal_uuid};
my $vg_name = $anvil->data->{vgs}{host_uuid}{$member_host_uuid}{scan_lvm_vg_internal_uuid}{$vg_internal_uuid}{scan_lvm_vg_name};
print " - [".$member_short_host_name."]:[".$vg_name."]\n";
}
}
print "\n";
}
# Show DR hosts and their VGs
print "Disaster Recovery Hosts:\n";
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{sys}{hosts}{by_name}})
{
my $host_uuid = $anvil->data->{sys}{hosts}{by_name}{$host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
short_host_name => $short_host_name,
}});
next if $host_type ne "dr";
print "- DR Host: [".$short_host_name."] VGs:\n";
foreach my $vg_name (sort {$a cmp $b} keys %{$anvil->data->{vgs}{host_uuid}{$host_uuid}{scan_lvm_vg_name}})
{
my $vg_internal_uuid = $anvil->data->{vgs}{host_uuid}{$host_uuid}{scan_lvm_vg_name}{$vg_name}{scan_lvm_vg_internal_uuid};
my $vg_size = $anvil->data->{vgs}{host_uuid}{$host_uuid}{scan_lvm_vg_internal_uuid}{$vg_internal_uuid}{scan_lvm_vg_size};
my $vg_free = $anvil->data->{vgs}{host_uuid}{$host_uuid}{scan_lvm_vg_internal_uuid}{$vg_internal_uuid}{scan_lvm_vg_free};
my $say_size_hr = $anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size});
my $say_free_hr = $anvil->Convert->bytes_to_human_readable({'bytes' => $vg_free});
print " - [".$vg_name."], size: [".$say_size_hr."], free: [".$say_free_hr."], internal UUID: [".$vg_internal_uuid."]\n";
}
}
print "\n";
return(0);
}
sub get_vg_data
{
my ($anvil) = @_;
my $query = "
SELECT
scan_lvm_vg_uuid,
scan_lvm_vg_host_uuid,
scan_lvm_vg_internal_uuid,
scan_lvm_vg_name,
scan_lvm_vg_attributes,
scan_lvm_vg_extent_size,
scan_lvm_vg_size,
scan_lvm_vg_free
FROM
scan_lvm_vgs
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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 => 3, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_lvm_vg_uuid = $row->[0];
my $scan_lvm_vg_host_uuid = $row->[1];
my $scan_lvm_vg_internal_uuid = $row->[2];
my $scan_lvm_vg_name = $row->[3];
my $scan_lvm_vg_attributes = $row->[4];
my $scan_lvm_vg_extent_size = $row->[5];
my $scan_lvm_vg_size = $row->[6];
my $scan_lvm_vg_free = $row->[7];
my $host_name = $anvil->data->{hosts}{host_uuid}{$scan_lvm_vg_host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$scan_lvm_vg_host_uuid}{host_type};
my $host_key = $anvil->data->{hosts}{host_uuid}{$scan_lvm_vg_host_uuid}{host_key};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
scan_lvm_vg_uuid => $scan_lvm_vg_uuid,
scan_lvm_vg_host_uuid => $scan_lvm_vg_host_uuid,
scan_lvm_vg_internal_uuid => $scan_lvm_vg_internal_uuid,
scan_lvm_vg_name => $scan_lvm_vg_name,
scan_lvm_vg_attributes => $scan_lvm_vg_attributes,
scan_lvm_vg_extent_size => $scan_lvm_vg_extent_size,
scan_lvm_vg_size => $scan_lvm_vg_size,
scan_lvm_vg_free => $scan_lvm_vg_free,
host_name => $host_name,
host_type => $host_type,
host_key => $host_type,
}});
next if $host_key eq "DELETED";
next if $host_type eq "striker";
$anvil->data->{vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{host_uuid} = $scan_lvm_vg_host_uuid;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_name}{$scan_lvm_vg_name}{scan_lvm_vg_internal_uuid} = $scan_lvm_vg_internal_uuid;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid} = $scan_lvm_vg_uuid;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name} = $scan_lvm_vg_name;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_attributes} = $scan_lvm_vg_attributes;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size} = $scan_lvm_vg_extent_size;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size} = $scan_lvm_vg_size;
$anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free} = $scan_lvm_vg_free;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::host_uuid" => $anvil->data->{vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{host_uuid},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_name::${scan_lvm_vg_name}::scan_lvm_vg_internal_uuid" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_name}{$scan_lvm_vg_name}{scan_lvm_vg_internal_uuid},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_uuid" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_name" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_attributes" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_attributes},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_extent_size" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_size" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size},
"vgs::host_uuid::${scan_lvm_vg_host_uuid}::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_free" => $anvil->data->{vgs}{host_uuid}{$scan_lvm_vg_host_uuid}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free},
}});
}
}
sub get_storage_data
{
my ($anvil) = @_;
if (exists $anvil->data->{duplicate_check})
{
delete $anvil->data->{duplicate_check};
}
my $query = "
SELECT
storage_group_uuid,
storage_group_anvil_uuid,
storage_group_name
FROM
storage_groups
;";
$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})
{
my $storage_group_uuid = $row->[0];
my $storage_group_anvil_uuid = $row->[1];
my $storage_group_name = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $storage_group_anvil_uuid,
storage_group_name => $storage_group_name,
}});
# Check for duplicate groups.
if (exists $anvil->data->{duplicate_check}{$storage_group_name})
{
# Pick one to delete. Does one of the groups have DR and the other doesn't?
my $other_storage_group_uuid = $anvil->data->{duplicate_check}{$storage_group_name}{storage_group_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { other_storage_group_uuid => $other_storage_group_uuid }});
my $this_query = "SELECT COUNT(*) FROM storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid).";";
my $other_query = "SELECT COUNT(*) FROM storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($other_storage_group_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_query => $this_query,
other_query => $other_query,
}});
my $this_member_count = $anvil->Database->query({query => $this_query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
my $other_member_count = $anvil->Database->query({query => $other_query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_member_count => $this_member_count,
other_member_count => $other_member_count,
}});
# We'll delete this storage group uuid, UNLESS we've got more members.
if ($this_member_count > $other_member_count)
{
# We have more members, we need to delete the other.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0158", variables => {
group_name => $storage_group_name,
keep_uuid => $storage_group_uuid,
delete_uuid => $other_storage_group_uuid,
}});
my $queries = [];
push @{$queries}, "DELETE FROM history.storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($other_storage_group_uuid).";";
push @{$queries}, "DELETE FROM storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($other_storage_group_uuid).";";
push @{$queries}, "DELETE FROM history.storage_groups WHERE storage_group_uuid = ".$anvil->Database->quote($other_storage_group_uuid).";";
push @{$queries}, "DELETE FROM storage_groups WHERE storage_group_uuid = ".$anvil->Database->quote($other_storage_group_uuid).";";
foreach my $query (@{$queries})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, list => { query => $query }});
}
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
}
else
{
# Delete this one.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "alert", key => "warning_0158", variables => {
group_name => $storage_group_name,
keep_uuid => $other_storage_group_uuid,
delete_uuid => $storage_group_uuid,
}});
my $queries = [];
push @{$queries}, "DELETE FROM history.storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid).";";
push @{$queries}, "DELETE FROM storage_group_members WHERE storage_group_member_storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid).";";
push @{$queries}, "DELETE FROM history.storage_groups WHERE storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid).";";
push @{$queries}, "DELETE FROM storage_groups WHERE storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid).";";
foreach my $query (@{$queries})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
}
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
# We don't want to clobber the previously read data, so move on to the next group now.
next;
}
}
# Used to check for duplicates. We can't use the real data as it could have been loaded before here.
$anvil->data->{duplicate_check}{$storage_group_name}{storage_group_uuid} = $storage_group_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"duplicate_check::${storage_group_name}::storage_group_uuid" => $anvil->data->{duplicate_check}{$storage_group_name}{storage_group_uuid},
}});
# Store the real data
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid} = $storage_group_uuid;
$anvil->data->{storage_groups}{storage_group_uuid}{$storage_group_uuid}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_name} = $storage_group_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_name::${storage_group_name}::storage_group_uuid" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid},
"storage_groups::storage_group_uuid::${storage_group_uuid}::storage_group_anvil_uuid::${storage_group_anvil_uuid}::storage_group_name" => $anvil->data->{storage_groups}{storage_group_uuid}{$storage_group_uuid}{storage_group_anvil_uuid}{$storage_group_anvil_uuid}{storage_group_name},
}});
}
delete $anvil->data->{duplicate_check};
return(0);
}