#!/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;
# - 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", 
	"confirm", 
	"dr", 
	"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});
}

# Pick up the job, if any.
if ($anvil->data->{switches}{'job-uuid'})
{
	$anvil->Job->get_job_details({debug => 2});
	$anvil->Job->clear({debug => 2});
	$anvil->Job->update_progress({
		progress  => $anvil->Job->bump_progress({steps => 1}), 
		message   => "message_0152", 
		'print'   => 1,
		log_level => 1,
		file      => $THIS_FILE, 
		line      => __LINE__,
	});
}

$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});
}
elsif ($anvil->data->{switches}{member})
{
	manage_group_member($anvil);
}
elsif ($anvil->data->{switches}{group})
{
	manage_group($anvil);
}
else
{
	show_data($anvil);
}

# We're done
$anvil->Job->update_progress({
	progress  => 100, 
	message   => "job_0281", 
	'print'   => 0,
	log_level => 2,
	file      => $THIS_FILE, 
	line      => __LINE__,
});
$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!#")
	{
		# When adding, removing or renaming a group, '--group' needs to be set to the (new) group name.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "error_0366", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
		});
		$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'})))
	{
		# You can only use '--add', '--remove' or '--rename', please use only one at a time.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "error_0399", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
		});
		$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})
		{
			# The Anvil! node was not found.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0433", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					anvil => $anvil->data->{switches}{anvil}, 
				}
			});
		}
		else
		{
			# When managing a storage group, '--anvil <name or UUID>' is required as storage group names are not globally unique.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0492", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
			});
		}
		$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"))
	{
		# They wanted to name the group 'DELETED', cheaky...
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "error_0493", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
		});
		$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,
		}});
	}
	elsif (($group) && ($anvil->data->{switches}{add}))
	{
		$storage_group_name = $group;
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_name => $storage_group_name }});
	}

	if ($anvil->data->{switches}{add})
	{
		# Does it already exist?
		if ($storage_group_uuid)
		{
			# The storage group already exists, nothing to do.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "message_0170", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__, 
				variables => {
					sg_name    => $storage_group_name, 
					anvil_name => $anvil_name, 
				},
			});
			$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,
			storage_group_name => $storage_group_name, 
		}});
		
		# The storage group on the Anvil! node has been created.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "message_0171", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__, 
			variables => {
				sg_name    => $storage_group_name, 
				sg_uuid    => $storage_group_uuid, 
				anvil_name => $anvil_name, 
			},
		});
		$anvil->nice_exit({exit_code => 0});
	}
	elsif ($anvil->data->{switches}{remove})
	{
		# Does it exist?
		if (not $storage_group_uuid)
		{
			# The storage group wasn't found on the Anvil! node, nothing to do.\n";
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "message_0172", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__, 
				variables => {
					group      => $group, 
					anvil_name => $anvil_name, 
				},
			});
			$anvil->nice_exit({exit_code => 0});
		}
		
		# Did the user confirm?
		if ((not $anvil->data->{switches}{confirm}) && (not $anvil->data->{switches}{'job-uuid'}))
		{
			print $anvil->Words->string({key => "message_0199", variables => {
				sg_name    => $storage_group_name, 
				anvil_name => $anvil_name, 
			}})."\n";
			print $anvil->Words->string({key => "message_0021"})." ";
			my $answer = <STDIN>;
			chomp($answer);
			if ($answer !~ /^y/i)
			{
				print $anvil->Words->string({key => "message_0022"})."\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_uuid       => $storage_group_uuid,
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_uuid => $storage_group_uuid }});
		# The storage group on the Anvil! node has been deleted.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "message_0173", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__, 
			variables => {
				sg_name    => $storage_group_name, 
				anvil_name => $anvil_name, 
			},
		});
		$anvil->nice_exit({exit_code => 0});
	}
	elsif ($anvil->data->{switches}{'rename'})
	{
		# Do we have a new name?
		if (not $new_name)
		{
			# The storage group exists on the Anvil! node, but no new name was given via '--new-name <name>' nothing to do.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0493", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__, 
				variables => {
					sg_name    => $storage_group_name, 
					anvil_name => $anvil_name, 
				},
			});
			$anvil->nice_exit({exit_code => 1});
		}

		# Has the name changed?
		if (($storage_group_name) eq ($new_name))
		{
			# The storage group already has the desired name on the Anvil! node, nothing to do.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "message_0174", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__, 
				variables => {
					new_name   => $new_name, 
					anvil_name => $anvil_name, 
				},
			});
			$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 }});
		# The storage group on the Anvil! node has been renamed.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "message_0176", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__, 
			variables => {
				sg_name    => $storage_group_name, 
				new_name   => $new_name, 
				anvil_name => $anvil_name, 
			},
		});
		$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})
		{
			# The Anvil! node was not found.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0324", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					anvil => $anvil->data->{switches}{anvil},
				},
			});
		}
		else
		{
			# Not called with '--anvil'
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0325", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
			});
		}
		$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 on the specified node
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "error_0326", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
			variables => {
				anvil => $anvil_name, 
				group => $group, 
			},
		});
		$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}))
		{
			# Can't use both at the same time.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0327", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
			});
			$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})
		{
			# VG internal UUID wasn't found
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0328", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_uuid => $member_vg_uuid, 
				},
			});
			$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")
		{
			# The host is deleted.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0329", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_name   => $lvm_vg_name, 
					host_name => $host_name, 
				},
			});
			$anvil->nice_exit({exit_code => 1});
		}

		if ($host_type eq "striker")
		{
			# Can't use VGs from strikers.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0330", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_name   => $lvm_vg_name, 
					host_name => $host_name, 
				},
			});
			$anvil->nice_exit({exit_code => 1});
		}

		if (($host_type eq "node") && ($anvil_uuid ne $host_anvil_uuid))
		{
			# VG is on a subnode in another node
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "error_0362", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_name      => $lvm_vg_name, 
					host_name    => $host_name, 
					node_name    => $anvil_name, 
					on_node_name => $host_anvil_name, 
				},
			});
			$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")
			{
				# Already a member, nothing to do.
				$anvil->Job->update_progress({
					progress  => 100, 
					message   => "message_0165", 
					'print'   => 1,
					log_level => 1,
					file      => $THIS_FILE, 
					line      => __LINE__,
					variables => {
						vg_name   => $lvm_vg_name, 
						host_name => $short_host_name, 
						sg_name   => $storage_group_name, 
					},
				});
				$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",
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_member_uuid => $storage_group_member_uuid }});
		
		# Tell the user
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "message_0166", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
			variables => {
				vg_name   => $lvm_vg_name, 
				host_name => $short_host_name, 
				sg_name   => $storage_group_name, 
				sg_uuid   => $storage_group_member_uuid, 
			},
		});
		$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})
		{
			# Never been a memberm nothing to do.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "message_0167", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_name   => $lvm_vg_name, 
					host_name => $short_host_name, 
					sg_name   => $storage_group_name, 
				},
			});
			$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")
		{
			# Already removed, nothing to do.
			$anvil->Job->update_progress({
				progress  => 100, 
				message   => "message_0168", 
				'print'   => 1,
				log_level => 1,
				file      => $THIS_FILE, 
				line      => __LINE__,
				variables => {
					vg_name   => $lvm_vg_name, 
					host_name => $short_host_name, 
					sg_name   => $storage_group_name, 
				},
			});
			$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",
		});
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_member_uuid => $storage_group_member_uuid }});
		
		# Tell them it's been removed.
		$anvil->Job->update_progress({
			progress  => 100, 
			message   => "message_0169", 
			'print'   => 1,
			log_level => 1,
			file      => $THIS_FILE, 
			line      => __LINE__,
			variables => {
				vg_name   => $lvm_vg_name, 
				host_name => $short_host_name, 
				sg_name   => $storage_group_name, 
			},
		});
		$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};
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
			"s1:anvil_name"            => $anvil_name, 
			"s2:anvil_uuid"            => $anvil_uuid, 
			"s3:anvil_description"     => $anvil_description, 
			"s4:anvil_node1_host_uuid" => $anvil_node1_host_uuid, 
			"s5:anvil_node2_host_uuid" => $anvil_node2_host_uuid, 
		}});
		if (($show_anvil_uuid) && ($anvil_uuid ne $show_anvil_uuid))
		{
			next;
		}
		
		# Show the Anvil! node and description
		print $anvil->Words->string({key => "message_0154", variables => { 
			name        => $anvil_name,
			description => $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};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				"s1:node_host_uuid" => $node_host_uuid, 
				"s2:node_host_name" => $node_host_name, 
			}});
			# Show the subnode
			print $anvil->Words->string({key => "message_0155", variables => { subnode => $node_host_name }})."\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});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					"s1:scan_lvm_vg_name"          => $scan_lvm_vg_name, 
					"s2:scan_lvm_vg_internal_uuid" => $scan_lvm_vg_internal_uuid, 
					"s3:scan_lvm_vg_size"          => $scan_lvm_vg_size, 
					"s4:scan_lvm_vg_free"          => $scan_lvm_vg_free, 
					"s5:say_size_hr"               => $say_size_hr, 
					"s6:say_free_hr"               => $say_free_hr, 
				}});
				next if $scan_lvm_vg_name eq "DELETED";
				
				# Show the volume group name
				print $anvil->Words->string({key => "message_0156", variables => { 
					vg_name => $scan_lvm_vg_name, 
					size    => $say_size_hr, 
					free    => $say_free_hr, 
					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};
			$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
				"s1:storage_group_name" => $storage_group_name, 
				"s2:storage_group_uuid" => $storage_group_uuid, 
			}});
			next if $storage_group_name eq "DELETED";
			
			# Show the storage group, if the members exist and aren't deleted.
			my $member_count = 0;
			print $anvil->Words->string({key => "message_0157", variables => { 
				sg_name => $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};
				my $member_note               = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$member_host_uuid}{storage_group_member_note};
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
					"s1:member_short_host_name"    => $member_short_host_name, 
					"s2:member_host_uuid"          => $member_host_uuid, 
					"s3:storage_group_member_uuid" => $storage_group_member_uuid, 
					"s4:vg_internal_uuid"          => $vg_internal_uuid, 
					"s5:vg_name"                   => $vg_name, 
					"s6:member_note"               => $member_note, 
				}});
				next if $vg_name     eq "DELETED";
				next if $member_note eq "DELETED";
				$member_count++;
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { member_count => $member_count }});
				
				# Show the member host name / VG name
				print $anvil->Words->string({key => "message_0158", variables => { 
					host_name => $member_short_host_name, 
					vg_name   => $vg_name, 
				}})."\n";
			}
			if (not $member_count)
			{
				print $anvil->Words->string({key => "message_0207"})."\n";
			}
		}
		print "\n";
	}

	# Show DR hosts and their VGs
	if ($anvil->data->{switches}{dr})
	{
		print $anvil->Words->string({key => "message_0163"})."\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 => {
				"s1:host_uuid"       => $host_uuid,
				"s2:host_name"       => $host_name,
				"s3:host_type"       => $host_type,
				"s4:short_host_name" => $short_host_name,
			}});
			next if $host_type ne "dr";
			
			# Show the DR host
			print $anvil->Words->string({key => "message_0164", variables => { host_name => $short_host_name }})."\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});
				$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
					"s1:vg_name"          => $vg_name,
					"s2:vg_internal_uuid" => $vg_internal_uuid,
					"s3:vg_size"          => $vg_size,
					"s4:vg_free"          => $vg_free,
					"s5:say_size_hr"      => $say_size_hr, 
					"s6:say_free_hr"      => $say_free_hr, 
				}});
				next if $vg_name eq "DELETED";
				
				# Show the VG
				print $anvil->Words->string({key => "message_0156", variables => { 
					vg_name => $short_host_name,
					size    => $say_size_hr, 
					free    => $say_free_hr, 
					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_anvil_uuid}{$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_anvil_uuid}{$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_anvil_uuid}{$storage_group_name}{storage_group_uuid} = $storage_group_uuid;
		$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
			"duplicate_check::${storage_group_anvil_uuid}::${storage_group_name}::storage_group_uuid" => $anvil->data->{duplicate_check}{$storage_group_anvil_uuid}{$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);
}
