Tha major point of this commit is to add the new 'anvil-manage-storage-groups' program that, well, manages storage groups.

* Updated the storage_group_members table to add the 'storage_group_member_note' that can be set to 'DELETED' to track when a member is deleted. Updated anvil-version-changes to check for and add this column as needed. Updated the anvil.sql schema for the same.
* Updated Cluster->insert_or_update_storage_group_members to add the new column.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 2 years ago
parent 355e5c2c0a
commit e012d6016c
  1. 9
      Anvil/Tools/Cluster.pm
  2. 60
      Anvil/Tools/Database.pm
  3. 0
      man/anvil-manage-storage-groups.8
  4. 8
      share/anvil.sql
  5. 604
      tools/anvil-manage-storage-groups
  6. 63
      tools/anvil-version-changes

@ -461,7 +461,8 @@ ORDER BY
debug => 2, debug => 2,
storage_group_member_storage_group_uuid => $storage_group_uuid, storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid, storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid, storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
storage_group_member_note => "auto-created",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }});
@ -525,6 +526,7 @@ ORDER BY
storage_group_member_storage_group_uuid => $storage_group_uuid, storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid, storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid, storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
storage_group_member_note => "auto-created",
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }});
@ -537,6 +539,11 @@ ORDER BY
if ($reload_storage_groups) if ($reload_storage_groups)
{ {
$anvil->Database->get_storage_group_data({debug => $debug}); $anvil->Database->get_storage_group_data({debug => $debug});
my $storage_group_uuid = $anvil->Database->insert_or_update_storage_groups({
debug => 2,
storage_group_anvil_uuid => $anvil_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_uuid => $storage_group_uuid }});
} }
return(0); return(0);

@ -5305,7 +5305,8 @@ SELECT
a.storage_group_name, a.storage_group_name,
b.storage_group_member_uuid, b.storage_group_member_uuid,
b.storage_group_member_host_uuid, b.storage_group_member_host_uuid,
b.storage_group_member_vg_uuid b.storage_group_member_vg_uuid,
b.storage_group_member_note
FROM FROM
storage_groups a, storage_groups a,
storage_group_members b storage_group_members b
@ -5330,6 +5331,8 @@ ORDER BY
my $storage_group_member_uuid = $row->[3]; my $storage_group_member_uuid = $row->[3];
my $storage_group_member_host_uuid = $row->[4]; my $storage_group_member_host_uuid = $row->[4];
my $storage_group_member_vg_uuid = $row->[5]; # This is the VG's internal UUID my $storage_group_member_vg_uuid = $row->[5]; # This is the VG's internal UUID
my $storage_group_member_note = $row->[6]; # If this is 'DELETED', the link isn't used anymore
my $storage_group_member_host_name = $anvil->data->{hosts}{host_uuid}{$storage_group_member_host_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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,
@ -5337,21 +5340,27 @@ ORDER BY
storage_group_member_uuid => $storage_group_member_uuid, storage_group_member_uuid => $storage_group_member_uuid,
storage_group_member_host_uuid => $storage_group_member_host_uuid, storage_group_member_host_uuid => $storage_group_member_host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid, storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
storage_group_member_note => $storage_group_member_note,
storage_group_member_host_name => $storage_group_member_host_name,
}}); }});
# Store the data # Store the data
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name} = $storage_group_name; $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name} = $storage_group_name;
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{short_host_name}{$storage_group_member_host_name}{host_uuid} = $storage_group_member_host_uuid;
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_uuid} = $storage_group_member_uuid; $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_uuid} = $storage_group_member_uuid;
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_internal_uuid} = $storage_group_member_vg_uuid; $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_internal_uuid} = $storage_group_member_vg_uuid;
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size} = 0; $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size} = 0;
$anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free} = 0; $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free} = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_note} = $storage_group_member_note;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::group_name" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name}, "storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::group_name" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name},
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::short_host_name::${storage_group_member_host_name}::host_uuid" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{short_host_name}{$storage_group_member_host_name}{host_uuid},
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::storage_group_member_uuid" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_uuid}, "storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::storage_group_member_uuid" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_uuid},
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::vg_size" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size}}).")", "storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::vg_size" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_size}}).")",
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::vg_free" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free}}).")", "storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::vg_free" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{vg_free}}).")",
"storage_groups::anvil_uuid::${storage_group_anvil_uuid}::storage_group_uuid::${storage_group_uuid}::host_uuid::${storage_group_member_host_uuid}::storage_group_member_note" => $anvil->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$storage_group_member_host_uuid}{storage_group_member_note},
}}); }});
# Make it easier to use the VG UUID to find the storage_group_uuid. # Make it easier to use the VG UUID to find the storage_group_uuid.
$anvil->data->{storage_groups}{vg_uuid}{$storage_group_member_vg_uuid}{storage_group_uuid} = $storage_group_uuid; $anvil->data->{storage_groups}{vg_uuid}{$storage_group_member_vg_uuid}{storage_group_uuid} = $storage_group_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -13058,6 +13067,8 @@ This is the Anvil! UUID that the storage group belongs to.
This is the name of the new storage group, as shown to the user when they provision servers. If this is not set, the word string 'striker_0280' is used with increasing integer until a unique name is found. This is the name of the new storage group, as shown to the user when they provision servers. If this is not set, the word string 'striker_0280' is used with increasing integer until a unique name is found.
This is set to C<< DELETED >> if the group is deleted.
If this is set and the given name is already in use, C<< !!error!! >> is returned. If this is set and the given name is already in use, C<< !!error!! >> is returned.
=head3 storage_group_uuid (optional) =head3 storage_group_uuid (optional)
@ -13272,6 +13283,10 @@ This will remove the VG from the storage group.
If set, C<< storage_group_member_uuid >> is required and it is the only required attribute. If set, C<< storage_group_member_uuid >> is required and it is the only required attribute.
=head3 storage_group_member_note (optional)
This is a note that can be placed about this member. When the member is deleted, this is set to C<< DELETED >>.
=head3 storage_group_member_uuid (optional) =head3 storage_group_member_uuid (optional)
If set, a specific storage group member is updated or deleted. If set, a specific storage group member is updated or deleted.
@ -13286,7 +13301,7 @@ This is the host UUID this VG is on.
=head3 storage_group_member_vg_uuid (required, unless delete is set) =head3 storage_group_member_vg_uuid (required, unless delete is set)
This is the volume group's B<< internal >> UUID (which, to be clear, isn't a valid UUID formatted string, so it's treated as a string internally). This is the volume group's B<< internal >> UUID (which, to be clear, isn't a valid UUID formatted string, so it's treated as a string internally).
=cut =cut
sub insert_or_update_storage_group_members sub insert_or_update_storage_group_members
@ -13306,13 +13321,15 @@ sub insert_or_update_storage_group_members
my $storage_group_member_storage_group_uuid = defined $parameter->{storage_group_member_storage_group_uuid} ? $parameter->{storage_group_member_storage_group_uuid} : ""; my $storage_group_member_storage_group_uuid = defined $parameter->{storage_group_member_storage_group_uuid} ? $parameter->{storage_group_member_storage_group_uuid} : "";
my $storage_group_member_host_uuid = defined $parameter->{storage_group_member_host_uuid} ? $parameter->{storage_group_member_host_uuid} : ""; my $storage_group_member_host_uuid = defined $parameter->{storage_group_member_host_uuid} ? $parameter->{storage_group_member_host_uuid} : "";
my $storage_group_member_vg_uuid = defined $parameter->{storage_group_member_vg_uuid} ? $parameter->{storage_group_member_vg_uuid} : ""; my $storage_group_member_vg_uuid = defined $parameter->{storage_group_member_vg_uuid} ? $parameter->{storage_group_member_vg_uuid} : "";
my $storage_group_member_note = defined $parameter->{storage_group_member_note} ? $parameter->{storage_group_member_note} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid, uuid => $uuid,
file => $file, file => $file,
line => $line, line => $line,
'delete' => $delete, 'delete' => $delete,
storage_group_member_uuid => $storage_group_member_uuid, storage_group_member_uuid => $storage_group_member_uuid,
storage_group_member_storage_group_uuid => $storage_group_member_storage_group_uuid, storage_group_member_note => $storage_group_member_note,
storage_group_member_storage_group_uuid => $storage_group_member_storage_group_uuid,
storage_group_member_host_uuid => $storage_group_member_host_uuid, storage_group_member_host_uuid => $storage_group_member_host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid, storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
}}); }});
@ -13330,10 +13347,10 @@ sub insert_or_update_storage_group_members
UPDATE UPDATE
storage_group_members storage_group_members
SET SET
storage_group_member_vg_uuid = 'DELETED', storage_group_member_note = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE WHERE
storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)." storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)."
;"; ;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
@ -13402,13 +13419,15 @@ INSERT INTO
storage_group_member_uuid, storage_group_member_uuid,
storage_group_member_storage_group_uuid, storage_group_member_storage_group_uuid,
storage_group_member_host_uuid, storage_group_member_host_uuid,
storage_group_member_vg_uuid, storage_group_member_vg_uuid,
storage_group_member_note,
modified_date modified_date
) VALUES ( ) VALUES (
".$anvil->Database->quote($storage_group_member_uuid).", ".$anvil->Database->quote($storage_group_member_uuid).",
".$anvil->Database->quote($storage_group_member_storage_group_uuid).", ".$anvil->Database->quote($storage_group_member_storage_group_uuid).",
".$anvil->Database->quote($storage_group_member_host_uuid).", ".$anvil->Database->quote($storage_group_member_host_uuid).",
".$anvil->Database->quote($storage_group_member_vg_uuid).", ".$anvil->Database->quote($storage_group_member_vg_uuid).",
".$anvil->Database->quote($storage_group_member_note).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)." ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);"; );";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
@ -13421,8 +13440,9 @@ INSERT INTO
SELECT SELECT
storage_group_member_storage_group_uuid, storage_group_member_storage_group_uuid,
storage_group_member_host_uuid, storage_group_member_host_uuid,
storage_group_member_vg_uuid storage_group_member_vg_uuid,
FROM storage_group_member_note
FROM
storage_group_members storage_group_members
WHERE WHERE
storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)." storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)."
@ -13436,15 +13456,18 @@ WHERE
my $old_storage_group_member_storage_group_uuid = $results->[0]->[0]; my $old_storage_group_member_storage_group_uuid = $results->[0]->[0];
my $old_storage_group_member_host_uuid = $results->[0]->[1]; my $old_storage_group_member_host_uuid = $results->[0]->[1];
my $old_storage_group_member_vg_uuid = $results->[0]->[2]; my $old_storage_group_member_vg_uuid = $results->[0]->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { my $old_storage_group_member_note = $results->[0]->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_storage_group_member_storage_group_uuid => $old_storage_group_member_storage_group_uuid, old_storage_group_member_storage_group_uuid => $old_storage_group_member_storage_group_uuid,
old_storage_group_member_host_uuid => $old_storage_group_member_host_uuid, old_storage_group_member_host_uuid => $old_storage_group_member_host_uuid,
old_storage_group_member_vg_uuid => $old_storage_group_member_vg_uuid, old_storage_group_member_vg_uuid => $old_storage_group_member_vg_uuid,
old_storage_group_member_note => $old_storage_group_member_note,
}}); }});
if (($old_storage_group_member_storage_group_uuid ne $storage_group_member_storage_group_uuid) or if (($old_storage_group_member_storage_group_uuid ne $storage_group_member_storage_group_uuid) or
($old_storage_group_member_host_uuid ne $storage_group_member_host_uuid) or ($old_storage_group_member_host_uuid ne $storage_group_member_host_uuid) or
($old_storage_group_member_vg_uuid ne $storage_group_member_vg_uuid)) ($old_storage_group_member_vg_uuid ne $storage_group_member_vg_uuid) or
($old_storage_group_member_note ne $storage_group_member_note))
{ {
# Something changed, UPDATE # Something changed, UPDATE
my $query = " my $query = "
@ -13453,8 +13476,9 @@ UPDATE
SET SET
storage_group_member_storage_group_uuid = ".$anvil->Database->quote($storage_group_member_storage_group_uuid).", storage_group_member_storage_group_uuid = ".$anvil->Database->quote($storage_group_member_storage_group_uuid).",
storage_group_member_host_uuid = ".$anvil->Database->quote($storage_group_member_host_uuid).", storage_group_member_host_uuid = ".$anvil->Database->quote($storage_group_member_host_uuid).",
storage_group_member_vg_uuid = ".$anvil->Database->quote($storage_group_member_vg_uuid).", storage_group_member_vg_uuid = ".$anvil->Database->quote($storage_group_member_vg_uuid).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." storage_group_member_note = ".$anvil->Database->quote($storage_group_member_note).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE WHERE
storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)." storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)."
;"; ;";

@ -1742,7 +1742,8 @@ CREATE TABLE storage_group_members (
storage_group_member_storage_group_uuid uuid not null, storage_group_member_storage_group_uuid uuid not null,
storage_group_member_host_uuid uuid not null, -- The host this VG comes from. storage_group_member_host_uuid uuid not null, -- The host this VG comes from.
storage_group_member_vg_uuid text not null, -- This is the VG's internal "uuid". It's not a valid UUID string format, but it's what LVM calls a 'uuid'. storage_group_member_vg_uuid text not null, -- This is the VG's internal "uuid". It's not a valid UUID string format, but it's what LVM calls a 'uuid'.
modified_date timestamp with time zone not null, storage_group_member_note text not null, -- This is set to DELETED when the link is removed.
modified_date timestamp with time zone not null,
FOREIGN KEY(storage_group_member_storage_group_uuid) REFERENCES storage_groups(storage_group_uuid), FOREIGN KEY(storage_group_member_storage_group_uuid) REFERENCES storage_groups(storage_group_uuid),
FOREIGN KEY(storage_group_member_host_uuid) REFERENCES hosts(host_uuid) FOREIGN KEY(storage_group_member_host_uuid) REFERENCES hosts(host_uuid)
@ -1755,7 +1756,8 @@ CREATE TABLE history.storage_group_members (
storage_group_member_storage_group_uuid uuid, storage_group_member_storage_group_uuid uuid,
storage_group_member_host_uuid uuid, storage_group_member_host_uuid uuid,
storage_group_member_vg_uuid text, storage_group_member_vg_uuid text,
modified_date timestamp with time zone not null storage_group_member_note text,
modified_date timestamp with time zone not null
); );
ALTER TABLE history.storage_group_members OWNER TO admin; ALTER TABLE history.storage_group_members OWNER TO admin;
@ -1770,12 +1772,14 @@ BEGIN
storage_group_member_storage_group_uuid, storage_group_member_storage_group_uuid,
storage_group_member_host_uuid, storage_group_member_host_uuid,
storage_group_member_vg_uuid, storage_group_member_vg_uuid,
storage_group_member_note,
modified_date) modified_date)
VALUES VALUES
(history_storage_group_members.storage_group_member_uuid, (history_storage_group_members.storage_group_member_uuid,
history_storage_group_members.storage_group_member_storage_group_uuid, history_storage_group_members.storage_group_member_storage_group_uuid,
history_storage_group_members.storage_group_member_host_uuid, history_storage_group_members.storage_group_member_host_uuid,
history_storage_group_members.storage_group_member_vg_uuid, history_storage_group_members.storage_group_member_vg_uuid,
history_storage_group_members.storage_group_member_note,
history_storage_group_members.modified_date); history_storage_group_members.modified_date);
RETURN NULL; RETURN NULL;
END; END;

@ -0,0 +1,604 @@
#!/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.
#
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();
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";
}
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";
}
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: [".$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 "- Node: [".$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) = @_;
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 => 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 $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 => 3, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $storage_group_anvil_uuid,
storage_group_name => $storage_group_name,
}});
$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 => 3, 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},
}});
}
return(0);
}

@ -65,7 +65,10 @@ sub striker_checks
# This converts the old/broken 'notifications' tables with the more appropriately named 'alert-override' # This converts the old/broken 'notifications' tables with the more appropriately named 'alert-override'
update_notifications($anvil); update_notifications($anvil);
# This adds notes to storage_group_members
update_storage_group_members($anvil);
### NOTE: Disabled until review complete ### NOTE: Disabled until review complete
# This checks to make sure that the 'audits' table exists (added late into M3.0 pre-release) # This checks to make sure that the 'audits' table exists (added late into M3.0 pre-release)
#update_audits($anvil); #update_audits($anvil);
@ -304,6 +307,64 @@ CREATE TRIGGER trigger_audits
return(0); return(0);
} }
sub update_storage_group_members
{
my ($anvil) = @_;
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
{
my $query = "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'storage_group_members' AND column_name = 'storage_group_member_note';";
$anvil->Log->variables({source => $THIS_FILE, uuid => $uuid, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
my $queries = [];
push @{$queries}, "ALTER TABLE public.storage_group_members ADD COLUMN storage_group_member_note text not null DEFAULT '';";
push @{$queries}, "ALTER TABLE history.storage_group_members ADD COLUMN storage_group_member_note text not null DEFAULT '';";
push @{$queries}, "DROP FUNCTION history_storage_group_members() CASCADE;";
push @{$queries}, q|CREATE FUNCTION history_storage_group_members() RETURNS trigger
AS $$
DECLARE
history_storage_group_members RECORD;
BEGIN
SELECT INTO history_storage_group_members * FROM storage_group_members WHERE storage_group_member_uuid = new.storage_group_member_uuid;
INSERT INTO history.storage_group_members
(storage_group_member_uuid,
storage_group_member_storage_group_uuid,
storage_group_member_host_uuid,
storage_group_member_vg_uuid,
storage_group_member_note,
modified_date)
VALUES
(history_storage_group_members.storage_group_member_uuid,
history_storage_group_members.storage_group_member_storage_group_uuid,
history_storage_group_members.storage_group_member_host_uuid,
history_storage_group_members.storage_group_member_vg_uuid,
history_storage_group_members.storage_group_member_note,
history_storage_group_members.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_storage_group_members() OWNER TO admin;
CREATE TRIGGER trigger_storage_group_members
AFTER INSERT OR UPDATE ON storage_group_members
FOR EACH ROW EXECUTE PROCEDURE history_storage_group_members();|;
foreach my $query (@{$queries})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
}
$anvil->Database->write({debug => 2, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
}
}
return(0);
}
# This converts the old/broken 'notifications' tables with the more appropriately named 'alert-override' # This converts the old/broken 'notifications' tables with the more appropriately named 'alert-override'
sub update_notifications sub update_notifications
{ {

Loading…
Cancel
Save