* Fixed a bug in DRBD->get_next_resource() where reserved minor numbers were not being released. Also added a new parameter, "minor_only", that returns the next minor number but doesn't bother processing TCP ports.

* Did more work on adding support for adding new disk drives to servers in anvil-manage-server-storage.
* Updated anvil-manage-storage-groups To check for / delete duplicate storage groups with the same name.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 2 years ago
parent 65af56d5bd
commit ea95d26cc5
  1. 48
      Anvil/Tools/DRBD.pm
  2. 5
      share/words.xml
  3. 4
      tools/anvil-manage-dr
  4. 173
      tools/anvil-manage-server-storage
  5. 89
      tools/anvil-manage-storage-groups
  6. 2
      tools/anvil-watch-drbd

@ -1757,6 +1757,10 @@ If set, the 'free_port' returned will be a comma-separated pair of TCP ports. Th
If set, the 'free_port' returned will be a comma-separated list of seven TCP ports needed for a full B<< Long Throw >> configuration. If set, the 'free_port' returned will be a comma-separated list of seven TCP ports needed for a full B<< Long Throw >> configuration.
=head3 minor_only (optional, default '0')
When set to C<< 1 >>, only a new minor number is returned. The tcp number will be an empty string.
=head3 resource_name (optional) =head3 resource_name (optional)
If this is set, and the resource is found to already exist, the first DRBD minor number and first used TCP port are returned. Alternatively, if C<< force_unique >> is set to C<< 1 >>, and the resource is found to exist, empty strings are returned. If this is set, and the resource is found to already exist, the first DRBD minor number and first used TCP port are returned. Alternatively, if C<< force_unique >> is set to C<< 1 >>, and the resource is found to exist, empty strings are returned.
@ -1780,12 +1784,14 @@ sub get_next_resource
my $anvil_uuid = defined $parameter->{anvil_uuid} ? $parameter->{anvil_uuid} : ""; my $anvil_uuid = defined $parameter->{anvil_uuid} ? $parameter->{anvil_uuid} : "";
my $dr_tcp_ports = defined $parameter->{dr_tcp_ports} ? $parameter->{dr_tcp_ports} : ""; my $dr_tcp_ports = defined $parameter->{dr_tcp_ports} ? $parameter->{dr_tcp_ports} : "";
my $long_throw_ports = defined $parameter->{long_throw_ports} ? $parameter->{long_throw_ports} : ""; my $long_throw_ports = defined $parameter->{long_throw_ports} ? $parameter->{long_throw_ports} : "";
my $minor_only = defined $parameter->{minor_only} ? $parameter->{minor_only} : "";
my $resource_name = defined $parameter->{resource_name} ? $parameter->{resource_name} : ""; my $resource_name = defined $parameter->{resource_name} ? $parameter->{resource_name} : "";
my $force_unique = defined $parameter->{force_unique} ? $parameter->{force_unique} : 0; my $force_unique = defined $parameter->{force_unique} ? $parameter->{force_unique} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
anvil_uuid => $anvil_uuid, anvil_uuid => $anvil_uuid,
dr_tcp_ports => $dr_tcp_ports, dr_tcp_ports => $dr_tcp_ports,
long_throw_ports => $long_throw_ports, long_throw_ports => $long_throw_ports,
minor_only => $minor_only,
resource_name => $resource_name, resource_name => $resource_name,
force_unique => $force_unique, force_unique => $force_unique,
}}); }});
@ -1931,8 +1937,13 @@ ORDER BY
# If I'm here, We'll look for the next minor number for this host. # If I'm here, We'll look for the next minor number for this host.
my $looking = 1; my $looking = 1;
my $free_minor = 0; my $free_minor = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
looking => $looking,
free_minor => $free_minor,
}});
while($looking) while($looking)
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { free_minor => $free_minor }});
if (exists $anvil->data->{drbd}{used_resources}{minor}{$free_minor}) if (exists $anvil->data->{drbd}{used_resources}{minor}{$free_minor})
{ {
$free_minor++; $free_minor++;
@ -1952,7 +1963,8 @@ ORDER BY
's3:variable_uuid' => $variable_uuid, 's3:variable_uuid' => $variable_uuid,
}}); }});
if (($variable_value) && ($variable_value !~ /^\d+$/)) # If the value set, a digit, and older than the current time?
if (($variable_value) && (($variable_value !~ /^\d+$/) or (time > $variable_value)))
{ {
# Bad value, clear it. # Bad value, clear it.
$variable_uuid = $anvil->Database->insert_or_update_variables({ $variable_uuid = $anvil->Database->insert_or_update_variables({
@ -1961,7 +1973,11 @@ ORDER BY
variable_value => "0", variable_value => "0",
update_value_only => "", update_value_only => "",
}); });
$variable_value = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_uuid => $variable_uuid }});
# Clear the variable UUID for the next step.
$variable_uuid = "";
$variable_value = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
variable_uuid => $variable_uuid, variable_uuid => $variable_uuid,
variable_value => $variable_value variable_value => $variable_value
@ -1969,32 +1985,12 @@ ORDER BY
} }
if ($variable_uuid) if ($variable_uuid)
{
my $now_time = time;
my $age = $now_time - $variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
age => $age,
now_time => $now_time,
}});
if (($variable_value) && ($now_time > $variable_value))
{ {
# This is being held, move on. # This is being held, move on.
$free_minor++; $free_minor++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { free_minor => $free_minor }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { free_minor => $free_minor }});
next; next;
} }
else
{
# Either the hold is stale or invalid, delete it.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_uuid => $variable_uuid,
variable_value => "0",
update_value_only => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_uuid => $variable_uuid }});
}
}
# To prevent race conditions, put a one minute hold on the minor number. # To prevent race conditions, put a one minute hold on the minor number.
$variable_uuid = $anvil->Database->insert_or_update_variables({ $variable_uuid = $anvil->Database->insert_or_update_variables({
@ -2014,6 +2010,14 @@ ORDER BY
} }
} }
# If they're only asking for a minor number, like adding a disk, we're done.
if ($minor_only)
{
# We're done.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { free_minor => $free_minor }});
return($free_minor, "");
}
# I need to find the next free TCP port. # I need to find the next free TCP port.
$looking = 1; $looking = 1;
my $check_port = 7788; my $check_port = 7788;

@ -466,7 +466,7 @@ Giving up.
<key name="error_0340"><![CDATA[Please specify the server to manager using '--server <name or uuid>'. Exiting.]]></key> <key name="error_0340"><![CDATA[Please specify the server to manager using '--server <name or uuid>'. Exiting.]]></key>
<key name="error_0341">Failed to find the server: [#!variable!server!#] by name or UUID? Exiting.</key> <key name="error_0341">Failed to find the server: [#!variable!server!#] by name or UUID? Exiting.</key>
<key name="error_0342">The protocol: [#!variable!protocol!#] is invalid. Please use '--help' for more information.</key> <key name="error_0342">The protocol: [#!variable!protocol!#] is invalid. Please use '--help' for more information.</key>
<key name="error_0343">The DR host: [#!variable!host_name!#] doesn't appear to be storage group: [#!variable!storage_group!#]. Unable to proceed.</key> <key name="error_0343">The DR host: [#!variable!host_name!#] doesn't appear to be in the storage group: [#!variable!storage_group!#]. Unable to proceed.</key>
<key name="error_0344">We need: [#!variable!space_needed!# (#!variable!space_needed_bytes!# Bytes)] from the storage group: [#!variable!storage_group!#], but only: [#!variable!space_on_dr!# (#!variable!space_on_dr_bytes!# bytes)] is available on DR. Unable to proceed.</key> <key name="error_0344">We need: [#!variable!space_needed!# (#!variable!space_needed_bytes!# Bytes)] from the storage group: [#!variable!storage_group!#], but only: [#!variable!space_on_dr!# (#!variable!space_on_dr_bytes!# bytes)] is available on DR. Unable to proceed.</key>
<key name="error_0345">[ Error ] - The check appears to have failed. Expected a return code of '0', but got: [#!variable!return_code!#] <key name="error_0345">[ Error ] - The check appears to have failed. Expected a return code of '0', but got: [#!variable!return_code!#]
The output, if any, was The output, if any, was
@ -2418,7 +2418,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="message_0018">What would you like the new password to be?</key> <key name="message_0018">What would you like the new password to be?</key>
<key name="message_0019">Please enter the password again to confirm.</key> <key name="message_0019">Please enter the password again to confirm.</key>
<key name="message_0020">About to update the local passwords (shell users, database and web interface).</key> <key name="message_0020">About to update the local passwords (shell users, database and web interface).</key>
<key name="message_0021">Proceed? [y/N]</key> <!-- Default Yes is at message_0206 --> <key name="message_0021">Proceed? [y/N]</key> <!-- Default No is at message_0206 -->
<key name="message_0022">Aborting.</key> <key name="message_0022">Aborting.</key>
<key name="message_0023">Auto-approved by command line switch, proceeding.</key> <key name="message_0023">Auto-approved by command line switch, proceeding.</key>
<key name="message_0024">Updating the Striker user: [#!variable!user!#] password... </key> <key name="message_0024">Updating the Striker user: [#!variable!user!#] password... </key>
@ -3625,6 +3625,7 @@ We will wait: [#!variable!waiting!#] seconds and then try again. We'll give up i
<key name="warning_0155">[ Warning ] - The file: [#!variable!file_path!#] needed to provision the server: [#!variable!server_name!#] was not found in the database as being on this host yet.</key> <key name="warning_0155">[ Warning ] - The file: [#!variable!file_path!#] needed to provision the server: [#!variable!server_name!#] was not found in the database as being on this host yet.</key>
<key name="warning_0156">[ Warning ] - The file: [#!variable!file_path!#] needed to provision the server: [#!variable!server_name!#] was found, but it's not ready yet.</key> <key name="warning_0156">[ Warning ] - The file: [#!variable!file_path!#] needed to provision the server: [#!variable!server_name!#] was found, but it's not ready yet.</key>
<key name="warning_0157">[ Warning ] - Waiting for a bit, and then will check if files are ready.</key> <key name="warning_0157">[ Warning ] - Waiting for a bit, and then will check if files are ready.</key>
<key name="warning_0158">[ Warning ] - There is a duplicate storage group named: [#!variable!group_name!#]. Keeping the group with UUID: [#!variable!keep_uuid!#], and deleting the group with the UUID: [#!variable!delete_uuid!#]</key>
</language> </language>
<!-- 日本語 --> <!-- 日本語 -->

@ -2221,10 +2221,6 @@ sub process_protect
this_size => $anvil->Convert->add_commas({number => $this_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $this_size}).")", this_size => $anvil->Convert->add_commas({number => $this_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $this_size}).")",
}}); }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_size => $anvil->Convert->add_commas({number => $this_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $this_size}).")",
}});
if ((not exists $anvil->data->{server}{drbd}{$resource}{$volume}{size}) or (not $anvil->data->{server}{drbd}{$resource}{$volume}{size})) if ((not exists $anvil->data->{server}{drbd}{$resource}{$volume}{size}) or (not $anvil->data->{server}{drbd}{$resource}{$volume}{size}))
{ {
$anvil->data->{server}{drbd}{$resource}{$volume}{size} = $this_size; $anvil->data->{server}{drbd}{$resource}{$volume}{size} = $this_size;

@ -54,6 +54,7 @@ $anvil->Get->switches({list => [
"insert", "insert",
"optical", "optical",
"server", "server",
"storage-group",
], man => $THIS_FILE}); ], man => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); $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->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
@ -270,6 +271,8 @@ sub manage_disk
} }
} }
if (($anvil->data->{switches}{grow}) or ($anvil->data->{switches}{remove}))
{
my $device_target = $anvil->data->{switches}{disk}; my $device_target = $anvil->data->{switches}{disk};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }});
@ -331,60 +334,149 @@ sub manage_disk
#print "- Target: [".$device_target."], boot: [".$say_boot."], path: [".$device_path."], cache: [".$driver_cache."], driver type: [".$driver_type."]\n"; #print "- Target: [".$device_target."], boot: [".$say_boot."], path: [".$device_path."], cache: [".$driver_cache."], driver type: [".$driver_type."]\n";
print "- Target: [".$device_target."], boot: [".$say_boot."], path: [".$device_path."], Available space: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space})."]\n"; print "- Target: [".$device_target."], boot: [".$say_boot."], path: [".$device_path."], Available space: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space})."]\n";
=cut # What are we doing?
my $volume = ""; if ($anvil->data->{switches}{grow})
print "Sub-Nodes:\n";
foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{device}})
{ {
my $on_lv = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{on_lv}; manage_disk_grow($anvil, $drbd_resource, $drbd_volume, $max_free_space);
$drbd_resource = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{resource};
my $device_target = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{target};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:device_path' => $device_path,
's2:on_lv' => $on_lv,
's3:drbd_resource' => $drbd_resource,
's4:device_target' => $device_target,
}});
} }
foreach my $drbd_resource (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{drbd}{resource}}) }
elsif ($anvil->data->{switches}{add})
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_resource => $drbd_resource }}); manage_disk_add($anvil, $drbd_resource);
} }
foreach my $host_type ("node", "dr")
return(0);
}
sub manage_disk_add
{
my ($anvil, $drbd_resource) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_resource => $drbd_resource }});
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_anvil_uuid();
my $short_host_name = $anvil->Get->short_host_name;
my $server_name = $anvil->data->{switches}{server_name};
my $from_source = get_definition_source($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
short_host_name => $short_host_name,
server_name => $server_name,
from_source => $from_source,
}});
# Are they asking for an available amount of space?
my $error_note = q|
[ Note ] - The size can be in percent, ie: '50%' or '100%', a number in bytes, or a human-readable size.
- Human readable sizes must NOT have a space between the number and letter suffix. Also, base2
- vs base10 notation! Ie: '1GiB' = 1,073,741,824 bytes', '1GB' == '1,000,000,000 bytes'. A single
- letter used to denote size will be interpreted as base2. ie: '1G == 1GiB'.
|;
# Do we have a storage group?
if (not $anvil->data->{switches}{'storage-group'})
{ {
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}}) print "Please specify a storage group to use to add the new drive to.\n";
short_storage_groups($anvil, $anvil_uuid);
$anvil->nice_exit({exit_code => 1});
}
# Make sure that the passed
my $storage_group_switch = $anvil->data->{switches}{'storage-group'};
my $storage_group_uuid = "";
my $storage_group_name = "";
if (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_switch})
{ {
my $host_uuid = $anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}{$short_host_name}{host_uuid}; $storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_switch}{storage_group_uuid};
$storage_group_name = $storage_group_switch;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:short_host_name' => $short_host_name, storage_group_uuid => $storage_group_uuid,
's2:host_uuid' => $host_uuid, storage_group_name => $storage_group_name,
}}); }});
print " |- Name: [".$short_host_name."], UUID: [".$host_uuid."]\n"; }
foreach my $volume_number (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}}) elsif (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_switch})
{ {
my $device_path = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_path}; $storage_group_uuid = $storage_group_switch;
my $device_minor = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_minor}; $storage_group_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_switch}{group_name};
my $volume_size = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{volume_size};
my $backing_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{backing_disk};
my $meta_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{meta_disk};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:volume_number' => $volume_number, storage_group_uuid => $storage_group_uuid,
's2:device_path' => $device_path, storage_group_name => $storage_group_name,
's3:device_minor' => $device_minor,
's4:volume_size' => $volume_size,
's5:backing_disk' => $backing_disk,
's6:meta_disk' => $meta_disk,
}}); }});
print " ^- Volume: [".$volume_number."], backing device: [".$backing_disk."], DRBD minor: [".$device_minor."], size: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $volume_size})."]\n";
} }
# Did we get a valid disk size?
my $free_space = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{free_space};
my $add_size = $anvil->data->{switches}{add};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
if ($add_size =~ /^(\d+)%$/)
{
# This is valid
my $percent = ".".$1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { percent => $percent }});
$add_size = int($free_space * $percent);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
}
elsif ($add_size !~ /\d/)
{
# No digits, probably didn't set a value at all.
print "\n[ Error ] - Please specify the size you would like to grow this disk by. The maximum size is: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_space})."].\n";
print $error_note."\n";
$anvil->nice_exit({exit_code => 1});
} }
elsif ($add_size !~ /^\d+$/)
{
# Size is not in bytes, try to convert it.
my $bytes = $anvil->Convert->human_readable_to_bytes({
debug => 2,
size => $add_size,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'bytes' => $bytes }});
if ($bytes =~ /^\d+$/)
{
$add_size = $bytes;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
} }
=cut else
# What are we doing?
if ($anvil->data->{switches}{grow})
{ {
# Not a valid size.
print "\n[ Error ] - The requested size: [".$add_size."] could not be interpreted.\n";
print $error_note."\n";
$anvil->nice_exit({exit_code => 1});
}
}
# Get the next free minor number
my ($free_minor, undef) = $anvil->DRBD->get_next_resource({
debug => 2,
minor_only => 1,
anvil_uuid => $anvil_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { free_minor => $free_minor }});
return(0);
}
sub manage_disk_grow
{
my ($anvil, $drbd_resource, $drbd_volume, $max_free_space) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:drbd_resource' => $drbd_resource,
's2:drbd_volume' => $drbd_volume,
's3:max_free_space' => $max_free_space,
}});
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_anvil_uuid();
my $short_host_name = $anvil->Get->short_host_name;
my $server_name = $anvil->data->{switches}{server_name};
my $from_source = get_definition_source($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
short_host_name => $short_host_name,
server_name => $server_name,
from_source => $from_source,
}});
# Are they asking for an available amount of space? # Are they asking for an available amount of space?
my $error_note = q| my $error_note = q|
[ Note ] - The size can be in percent, ie: '50%' or '100%', a number in bytes, or a human-readable size. [ Note ] - The size can be in percent, ie: '50%' or '100%', a number in bytes, or a human-readable size.
@ -486,7 +578,7 @@ sub manage_disk
print "- Preparing to grow the storage by: [".$hr_size."]...\n"; print "- Preparing to grow the storage by: [".$hr_size."]...\n";
if (not $anvil->data->{switches}{confirm}) if (not $anvil->data->{switches}{confirm})
{ {
print $anvil->Words->string({key => "message_0059"})." "; print $anvil->Words->string({key => "message_0021"})." ";
my $answer = <STDIN>; my $answer = <STDIN>;
chomp($answer); chomp($answer);
if ($answer !~ /^y/i) if ($answer !~ /^y/i)
@ -667,7 +759,6 @@ sub manage_disk
print "[ Note ] - Depending on your OS, you may need to power the server off, and then power it back on\n"; print "[ Note ] - Depending on your OS, you may need to power the server off, and then power it back on\n";
print "[ Note ] - for the new space to be visible. Typically, powering off the server from the guest OS\n"; print "[ Note ] - for the new space to be visible. Typically, powering off the server from the guest OS\n";
print "[ Note ] - and waiting for the Anvil! to boot it back up will do the job nicely.\n"; print "[ Note ] - and waiting for the Anvil! to boot it back up will do the job nicely.\n";
}
return(0); return(0);
} }

@ -569,6 +569,11 @@ sub get_storage_data
{ {
my ($anvil) = @_; my ($anvil) = @_;
if (exists $anvil->data->{duplicate_check})
{
delete $anvil->data->{duplicate_check};
}
my $query = " my $query = "
SELECT SELECT
storage_group_uuid, storage_group_uuid,
@ -577,11 +582,11 @@ SELECT
FROM FROM
storage_groups storage_groups
;"; ;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); $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 $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results}; my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results, results => $results,
count => $count, count => $count,
}}); }});
@ -590,19 +595,95 @@ FROM
my $storage_group_uuid = $row->[0]; my $storage_group_uuid = $row->[0];
my $storage_group_anvil_uuid = $row->[1]; my $storage_group_anvil_uuid = $row->[1];
my $storage_group_name = $row->[2]; my $storage_group_name = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
storage_group_uuid => $storage_group_uuid, storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $storage_group_anvil_uuid, storage_group_anvil_uuid => $storage_group_anvil_uuid,
storage_group_name => $storage_group_name, 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}{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->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 => 3, list => { $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::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}, "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); return(0);
} }

@ -27,7 +27,7 @@ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list
our $t = Term::Cap->Tgetent; our $t = Term::Cap->Tgetent;
# One shot or continuous? # One shot or continuous?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'switches::watch' => $anvil->data->{switches}{watch}, 'switches::watch' => $anvil->data->{switches}{watch},
}}); }});
if ($anvil->data->{switches}{watch}) if ($anvil->data->{switches}{watch})

Loading…
Cancel
Save