* This commit introduces a new concept called "Storage Groups". Given that LVs back DRBD resources in M3, there needed to be a way to determine which VGs would be used when creating the backing DRBD resources, and how large those LVs could be (based on the minimum free space of the VGs in a group). A new, as yet incomplete Get->available_resources() method will handle determining what resources are available to grow exist

ing or create new servers.
* Created Database->insert_or_update_storage_groups() and ->insert_or_update_storage_group_members() to manage the new associated tables. Together, these tables create storage groups and track the VGs that are members of the group.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 1d03a386d3
commit 4f33eeef2e
  1. 483
      Anvil/Tools/Database.pm
  2. 313
      Anvil/Tools/Get.pm
  3. 16
      Anvil/Tools/Storage.pm
  4. 2
      Anvil/Tools/Words.pm
  5. 2
      scancore-agents/scan-lvm/scan-lvm
  6. 2
      scancore-agents/scan-lvm/scan-lvm.sql
  7. 101
      share/anvil.sql
  8. 3
      share/words.xml

@ -66,6 +66,8 @@ my $THIS_FILE = "Database.pm";
# insert_or_update_sessions # insert_or_update_sessions
# insert_or_update_ssh_keys # insert_or_update_ssh_keys
# insert_or_update_states # insert_or_update_states
# insert_or_update_storage_groups
# insert_or_update_storage_group_members
# insert_or_update_temperature # insert_or_update_temperature
# insert_or_update_updated # insert_or_update_updated
# insert_or_update_upses # insert_or_update_upses
@ -3851,6 +3853,95 @@ FROM
} }
=head2 storage_group_data
This loads the C<< storage_groups >> and C<< storage_group_members >> data.
The group name is stored as:
* storage_groups::anvil_uuid::<anvil_uuid>::storage_group_uuid::<storage_group_uuid>::group_name
And group members are stored as:
* storage_groups::anvil_uuid::<anvil_uuid>::storage_group_uuid::<storage_group_uuid>::host_uuid::<host_uuid>::vg_uuid::<vg_uuid>::storage_group_member_uuid
B<< Note >>: The C<< vg_uuid >> is the UUID stored in the volume group itself. This is called a 'UUID', but it is not a valid UUID format string. So be sure to treat it as a unique text string, and not a UUID proper.
To simplify finding if a VG is in a group, the following hash is also set;
* storage_groups::vg_uuid::<vg_uuid>::storage_group_uuid
This method takes no parameters.
=cut
sub storage_group_data
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->storage_group_data()" }});
my $query = "
SELECT
a.storage_group_uuid,
a.storage_group_anvil_uuid,
a.storage_group_name,
b.storage_group_member_uuid,
b.storage_group_member_host_uuid,
b.storage_group_member_vg_uuid
FROM
storage_groups a,
storage_group_members b
WHERE
a.storage_group_uuid = b.storage_group_member_storage_group_uuid
ORDER BY
a.storage_group_anvil_uuid ASC
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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 => $debug, 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];
my $storage_group_member_uuid = $row->[3];
my $storage_group_member_host_uuid = $row->[4];
my $storage_group_member_vg_uuid = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $storage_group_anvil_uuid,
storage_group_name => $storage_group_name,
storage_group_member_uuid => $storage_group_member_uuid,
storage_group_member_host_uuid => $storage_group_member_host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
}});
# 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}{host_uuid}{$storage_group_member_host_uuid}{vg_uuid}{$storage_group_member_vg_uuid}{storage_group_member_uuid} = $storage_group_member_uuid;
$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}::host_uuid::${storage_group_member_host_uuid}::vg_uuid::${storage_group_member_vg_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_uuid}{$storage_group_member_vg_uuid}{storage_group_member_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->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"storage_groups::vg_uuid::${storage_group_member_vg_uuid}::storage_group_uuid" => $anvil->data->{storage_groups}{vg_uuid}{$storage_group_member_vg_uuid}{storage_group_uuid},
}});
}
return(0);
}
=head2 get_ssh_keys =head2 get_ssh_keys
This loads all known user's SSH public keys and all known machine's public keys into the data hash. On success, this method returns C<< 0 >>. If any problems occur, C<< 1 >> is returned. This loads all known user's SSH public keys and all known machine's public keys into the data hash. On success, this method returns C<< 0 >>. If any problems occur, C<< 1 >> is returned.
@ -10795,6 +10886,398 @@ WHERE
} }
=head2 insert_or_update_storage_groups
This method creates or renames a storage group. On success, the new C<< storage_group_uuid >> is returned. If there is a problem, C<< !!error!! >> is returned.
B<< Note >>: If C<< storage_group_name >> is set to C<< IGNORE >>. the storage group is not shown during server provisioning.
Parameters;
=head3 storage_group_anvil_uuid (required)
This is the Anvil! UUID that the storage group belongs to.
=head3 storage_group_name (optional)
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.
If this is set and the given name is already in use, C<< !!error!! >> is returned.
=head3 storage_group_uuid (optional)
If set, the specific storage group will be updated.
=cut
sub insert_or_update_storage_groups
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_storage_groups()" }});
# Check my parameters.
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : "";
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $storage_group_anvil_uuid = defined $parameter->{storage_group_anvil_uuid} ? $parameter->{storage_group_anvil_uuid} : "";
my $storage_group_name = defined $parameter->{storage_group_name} ? $parameter->{storage_group_name} : "";
my $storage_group_uuid = defined $parameter->{storage_group_uuid} ? $parameter->{storage_group_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
file => $file,
line => $line,
storage_group_anvil_uuid => $storage_group_anvil_uuid,
storage_group_name => $storage_group_name,
storage_group_uuid => $storage_group_uuid,
}});
if (not $storage_group_anvil_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_storage_groups()", parameter => "storage_group_anvil_uuid" }});
return('!!error!!');
}
if ($storage_group_name)
{
# Make sure the name isn't already used.
my $query = "
SELECT
storage_group_uuid
FROM
storage_groups
WHERE
storage_group_anvil_uuid = ".$anvil->Database->quote($storage_group_anvil_uuid)."
AND
storage_group_name = ".$anvil->Database->quote($storage_group_name)."
;";
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
# Name collision
my $storage_group_uuid = $results->[0]->[0];
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "warning_0071", variables => {
name => $storage_group_name,
uuid => $storage_group_uuid,
}});
return('!!error!!');
}
}
else
{
my $vg_group_number = 0;
my $storage_group_name = "";
until ($storage_group_name)
{
$vg_group_number++;
my $test_name = $anvil->Words->string({debug => $debug, key => "striker_0280", variables => { number => $vg_group_number }});
my $query = "
SELECT
COUNT(*)
FROM
storage_groups
WHERE
storage_group_anvil_uuid = ".$anvil->Database->quote($storage_group_anvil_uuid)."
AND
storage_group_name = ".$anvil->Database->quote($test_name)."
;";
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }});
if (not $count)
{
# We can use this name.
$storage_group_name = $test_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_name => $storage_group_name }});
}
}
}
# INSERT or UPDATE?
if (not $storage_group_uuid)
{
# INSERT
$storage_group_uuid = $anvil->Get->uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_uuid => $storage_group_uuid }});
my $query = "
INSERT INTO
storage_groups
(
storage_group_uuid,
storage_group_anvil_uuid,
storage_group_name,
modified_date
) VALUES (
".$anvil->Database->quote($storage_group_uuid).",
".$anvil->Database->quote($storage_group_anvil_uuid).",
".$anvil->Database->quote($storage_group_name).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
);";
$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->data->{storage_groups}{anvil_uuid}{$storage_group_anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name} = $storage_group_name;
$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},
}});
}
else
{
# UPDATE, if the name has changed.
my $query = "
SELECT
storage_group_name
FROM
storage_groups
WHERE
storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid)."
;";
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
my $old_storage_group_name = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_storage_group_name => $old_storage_group_name }});
if ($old_storage_group_name ne $storage_group_name)
{
# It's changed, update it.
my $query = "
UPDATE
storage_groups
SET
storage_group_name = ".$anvil->Database->quote($storage_group_name).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
storage_group_uuid = ".$anvil->Database->quote($storage_group_uuid)."
;";
$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__});
}
}
return($storage_group_uuid);
}
=head2 insert_or_update_storage_group_members
This adds a volume group on a given host to a storage group on it's Anvil!.
If there is a problem, C<< !!error!! >> is returned. Otherwise, the C<< storage_group_member_uuid >> is returned.
Parameters;
=head3 delete (optional, default 0)
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.
=head3 storage_group_member_uuid (optional)
If set, a specific storage group member is updated or deleted.
=head3 storage_group_member_storage_group_uuid (required, unless delete is set)
This is the storage group the VG will belong to.
=head3 storage_group_member_host_uuid (required, unless delete is set)
This is the host UUID this VG is on.
=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).
=cut
sub insert_or_update_storage_group_members
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_storage_group_members()" }});
# Check my parameters.
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : "";
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $delete = defined $parameter->{'delete'} ? $parameter->{'delete'} : 0;
my $storage_group_member_uuid = defined $parameter->{storage_group_member_uuid} ? $parameter->{storage_group_member_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_vg_uuid = defined $parameter->{storage_group_member_vg_uuid} ? $parameter->{storage_group_member_vg_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
file => $file,
line => $line,
'delete' => $delete,
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,
}});
if ($delete)
{
if (not $storage_group_member_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_storage_group_members()", parameter => "storage_group_member_uuid" }});
return('!!error!!');
}
else
{
my $query = "
UPDATE
storage_group_members
SET
storage_group_member_vg_uuid = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
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->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
$query = "DELETE FROM storage_group_members WHERE 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->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
}
else
{
if (not $storage_group_member_storage_group_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_storage_group_members()", parameter => "storage_group_member_storage_group_uuid" }});
return('!!error!!');
}
if (not $storage_group_member_host_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_storage_group_members()", parameter => "storage_group_member_host_uuid" }});
return('!!error!!');
}
if (not $storage_group_member_vg_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_storage_group_members()", parameter => "storage_group_member_vg_uuid" }});
return('!!error!!');
}
}
if (not $storage_group_member_uuid)
{
# See if we've seen this VG by searching for it's UUID.
my $query = "
SELECT
storage_group_member_uuid
FROM
storage_group_members
WHERE
storage_group_member_vg_uuid = ".$anvil->Database->quote($storage_group_member_vg_uuid)."
;";
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
$storage_group_member_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }});
}
}
# INSERT or UPDATE?
if (not $storage_group_member_uuid)
{
# INSERT
my $storage_group_member_uuid = $anvil->Get->uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }});
my $query = "
INSERT INTO
storage_group_members
(
storage_group_member_uuid,
storage_group_member_storage_group_uuid,
storage_group_member_host_uuid,
storage_group_member_vg_uuid,
modified_date
) VALUES (
".$anvil->Database->quote($storage_group_member_uuid).",
".$anvil->Database->quote($storage_group_member_storage_group_uuid).",
".$anvil->Database->quote($storage_group_member_host_uuid).",
".$anvil->Database->quote($storage_group_member_vg_uuid).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
};";
$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__});
}
else
{
# UPDATE, if something has changed.
my $query = "
SELECT
storage_group_member_storage_group_uuid,
storage_group_member_host_uuid,
storage_group_member_vg_uuid
FROM
storage_group_members
WHERE
storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid)."
;";
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
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_vg_uuid = $results->[0]->[2];
$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_host_uuid => $old_storage_group_member_host_uuid,
old_storage_group_member_vg_uuid => $old_storage_group_member_vg_uuid,
}});
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_vg_uuid ne $storage_group_member_vg_uuid))
{
# Something changed, UPDATE
my $query = "
UPDATE
storage_group_members
SET
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_vg_uuid = ".$anvil->Database->quote($storage_group_member_vg_uuid).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
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->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
}
return($storage_group_member_uuid);
}
=head2 insert_or_update_temperature =head2 insert_or_update_temperature
This inserts or updates a value in the special c<< temperature >> table. This inserts or updates a value in the special c<< temperature >> table.

@ -365,10 +365,6 @@ WHERE
return("!!error!!"); return("!!error!!");
} }
# Load data
$anvil->Database->get_hosts({debug => $debug});
$anvil->Database->get_bridges({debug => $debug});
# Get the details. # Get the details.
my $anvil_name = $results->[0]->[0]; my $anvil_name = $results->[0]->[0];
my $node1_host_uuid = $results->[0]->[1]; my $node1_host_uuid = $results->[0]->[1];
@ -381,8 +377,223 @@ WHERE
dr1_host_uuid => $dr1_host_uuid, dr1_host_uuid => $dr1_host_uuid,
}}); }});
# Make sure scancore has run. We do this by looking for the 'scan_lvm_vg_groups' table.
undef $query;
undef $count;
$query = "SELECT COUNT(*) FROM pg_catalog.pg_tables WHERE tablename='scan_lvm_vg_groups' AND schemaname='public';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$count = $anvil->Database->query({debug => $debug, query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }});
if ($count < 1)
{
# Not ready yes.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0070", variables => { anvil_name => $anvil_name }});
return('!!error!!');
}
# Load hosts, Network bridge, and Storages group data
$anvil->Database->get_hosts({debug => $debug});
$anvil->Database->get_bridges({debug => $debug});
$anvil->Database->storage_group_data({debug => $debug});
# This will store the available resources based on the least of the nodes.
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores} = 0;
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads} = 0;
$anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware} = 0;
# Before we see how much disk space is available, look for ungrouped VGs and see if we can group them
# by matching identical sizes together.
foreach my $host_uuid ($node1_host_uuid, $node2_host_uuid, $dr1_host_uuid) foreach my $host_uuid ($node1_host_uuid, $node2_host_uuid, $dr1_host_uuid)
{ {
# If DR isn't defined, it'll be blank.
next if not $host_uuid;
my $this_is = "node1";
if ($host_uuid eq $node2_host_uuid) { $this_is = "node2"; }
elsif ($host_uuid eq $dr1_host_uuid) { $this_is = "dr1"; }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { this_is => $this_is }});
$anvil->data->{ungrouped_vg_count}{$this_is} = 0;
my $query = "
SELECT
scan_lvm_vg_uuid,
scan_lvm_vg_name,
scan_lvm_vg_extent_size,
scan_lvm_vg_size,
scan_lvm_vg_free,
scan_lvm_vg_internal_uuid
FROM
scan_lvm_vgs
WHERE
scan_lvm_vg_host_uuid = ".$anvil->Database->quote($host_uuid)."
ORDER BY
scan_lvm_vg_size ASC;
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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 => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_lvm_vg_size = $row->[3];
my $scan_lvm_vg_internal_uuid = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
scan_lvm_vg_size => $scan_lvm_vg_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}).")",
scan_lvm_vg_internal_uuid => $scan_lvm_vg_internal_uuid,
}});
# Skip VGs that are in a group already.
if ((exists $anvil->data->{storage_groups}{vg_uuid}{$scan_lvm_vg_internal_uuid}) &&
($anvil->data->{storage_groups}{vg_uuid}{$scan_lvm_vg_internal_uuid}{storage_group_uuid}))
{
# Already in a group, we can skip it. We log this data for debugging reasons
# only.
my $storage_group_uuid = $anvil->data->{storage_groups}{vg_uuid}{$scan_lvm_vg_internal_uuid}{storage_group_uuid};
my $group_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name};
my $storage_group_member_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_uuid}{$scan_lvm_vg_internal_uuid}{storage_group_member_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
anvil_uuid => $anvil_uuid,
host_uuid => $host_uuid,
storage_group_uuid => $storage_group_uuid,
scan_lvm_vg_internal_uuid => $scan_lvm_vg_internal_uuid,
storage_group_member_uuid => $storage_group_member_uuid,
}});
next;
}
$anvil->data->{ungrouped_vg_count}{$this_is}++;
$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_uuid} = $row->[0];
$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_name} = $row->[1];
$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_extent_size} = $row->[2];
$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_free} = $row->[3];
$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_internal_uuid} = $row->[4];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"ungrouped_vg_count::${this_is}" => $anvil->data->{ungrouped_vg_count}{$this_is},
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::count" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{count},
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::vg_uuid" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_uuid},
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::vg_name" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_name},
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::vg_extent_size" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_extent_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_extent_size}}).")",
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::vg_free" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_free}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_free}}).")",
"ungrouped_vgs::${scan_lvm_vg_size}::host_uuid::${host_uuid}::vg_internal_uuid" => $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_internal_uuid},
}});
}
}
# Fing ungrouped VGs and see if we can pair them
my $reload_storage_groups = 0;
foreach my $scan_lvm_vg_size (sort {$a cmp $b} keys %{$anvil->data->{ungrouped_vgs}})
{
# If there are two or three VGs, we can create a group.
my $count = keys %{$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}};
if (($count == 2) or ($count == 3))
{
# Create the volume group ... group. First we need a group number
my $storage_group_uuid = $anvil->Database->create_storage_group({
debug => $debug,
storage_group_anvil_uuid => $anvil_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_uuid => $storage_group_uuid }});
foreach my $host_uuid (keys %{$anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}})
{
my $this_is = "node1";
if ($host_uuid eq $node2_host_uuid) { $this_is = "node2"; }
elsif ($host_uuid eq $dr1_host_uuid) { $this_is = "dr1"; }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { this_is => $this_is }});
my $storage_group_member_vg_uuid = $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_internal_uuid};
my $storage_group_member_uuid = $anvil->Database->insert_or_update_storage_group_members({
debug => $debug,
storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
});
$anvil->data->{ungrouped_vg_count}{$this_is}--;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"ungrouped_vg_count::${this_is}" => $anvil->data->{ungrouped_vg_count}{$this_is},
}});
}
# Reload storage group data
$reload_storage_groups = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { reload_storage_groups => $reload_storage_groups }});
}
}
# If there's only one VG on each node that is ungrouped, group them even though they're not the same
# size. If DR also has only 1 VG ungrouped, it'll be added, too.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"ungrouped_vg_count::node1" => $anvil->data->{ungrouped_vg_count}{node1},
"ungrouped_vg_count::node2" => $anvil->data->{ungrouped_vg_count}{node2},
"ungrouped_vg_count::dr1" => $anvil->data->{ungrouped_vg_count}{dr1},
}});
if (($anvil->data->{ungrouped_vg_count}{node1} == 1) && ($anvil->data->{ungrouped_vg_count}{node2} == 1))
{
# We do!
my $storage_group_uuid = $anvil->Database->create_storage_group({
debug => $debug,
storage_group_anvil_uuid => $anvil_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_uuid => $storage_group_uuid }});
my $hosts = [$node1_host_uuid, $node2_host_uuid];
if ($anvil->data->{ungrouped_vg_count}{dr1} == 1)
{
push @{$hosts}, $dr1_host_uuid;
}
foreach my $host_uuid (@{$hosts})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }});
# I need to find the size of VG UUID without knowing it's size.
my $storage_group_member_vg_uuid = "";
foreach my $scan_lvm_vg_size (sort {$a cmp $b} keys %{$anvil->data->{ungrouped_vgs}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
scan_lvm_vg_size => $scan_lvm_vg_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}).")",
}});
if ((exists $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}) &&
($anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_internal_uuid}))
{
# Found it.
$storage_group_member_vg_uuid = $anvil->data->{ungrouped_vgs}{$scan_lvm_vg_size}{host_uuid}{$host_uuid}{vg_internal_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_vg_uuid => $storage_group_member_vg_uuid }});
}
}
my $storage_group_member_uuid = $anvil->Database->insert_or_update_storage_group_members({
debug => $debug,
storage_group_member_storage_group_uuid => $storage_group_uuid,
storage_group_member_host_uuid => $host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_member_uuid => $storage_group_member_uuid }});
# Reload storage group data
$reload_storage_groups = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { reload_storage_groups => $reload_storage_groups }});
}
}
if ($reload_storage_groups)
{
$anvil->Database->storage_group_data({debug => $debug});
}
foreach my $host_uuid ($node1_host_uuid, $node2_host_uuid, $dr1_host_uuid)
{
# If DR isn't defined, it'll be blank.
next if not $host_uuid;
my $this_is = "node1";
if ($host_uuid eq $node2_host_uuid) { $this_is = "node2"; }
elsif ($host_uuid eq $dr1_host_uuid) { $this_is = "dr1"; }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { this_is => $this_is }});
# Start collecting data. # Start collecting data.
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}; my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -407,6 +618,100 @@ WHERE
} }
# Get the CPU and RAM data # Get the CPU and RAM data
my $query = "
SELECT
scan_hardware_cpu_cores,
scan_hardware_cpu_threads,
scan_hardware_ram_total
FROM
scan_hardware
WHERE
scan_hardware_host_uuid = ".$anvil->Database->quote($host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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 => $debug, list => {
results => $results,
count => $count,
}});
if (not $count)
{
# Looks like scan-hardware hasn't run. We can't use this host yet.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0169", variables => { host_name => $host_name }});
next;
}
my $scan_hardware_cpu_cores = $results->[0]->[0];
my $scan_hardware_cpu_threads = $results->[0]->[1];
my $scan_hardware_ram_total = $results->[0]->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
scan_hardware_cpu_cores => $scan_hardware_cpu_cores,
scan_hardware_cpu_threads => $scan_hardware_cpu_threads,
scan_hardware_ram_total => $scan_hardware_ram_total,
}});
$anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{cpu}{cores} = $scan_hardware_cpu_cores;
$anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{cpu}{threads} = $scan_hardware_cpu_threads;
$anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{ram}{hardware} = $scan_hardware_ram_total;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"anvil_resources::${anvil_uuid}::host_uuid::${host_uuid}::cpu::cores" => $anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{cpu}{cores},
"anvil_resources::${anvil_uuid}::host_uuid::${host_uuid}::cpu::threads" => $anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{cpu}{threads},
"anvil_resources::${anvil_uuid}::host_uuid::${host_uuid}::ram::hardware" => $anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{ram}{hardware}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{ram}{hardware}}).")",
}});
# For available resources, we only care about nodes.
if ($this_is !~ /^dr/)
{
# How many cores?
if ((not $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores}) or
($scan_hardware_cpu_cores < $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores}))
{
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores} = $scan_hardware_cpu_cores;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"anvil_resources::${anvil_uuid}::cpu::cores" => $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores},
}});
}
if ((not $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}) or
($scan_hardware_cpu_threads < $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}))
{
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads} = $scan_hardware_cpu_threads;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"anvil_resources::${anvil_uuid}::cpu::threads" => $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads},
}});
}
if ((not $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware}) or
($scan_hardware_cpu_threads < $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware}))
{
$anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware} = $scan_hardware_cpu_threads;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"anvil_resources::${anvil_uuid}::ram::hardware" => $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware}}).")",
}});
}
}
# Now read in the LVM VG data.
undef $query;
undef $results;
undef $count;
# TODO: Left off here; We'll now look for unassigned VGs. Ones that aren't, if we find a
# matching size one on both nodes / DR, we'll group them automatically. If only one VG
# is unassigned on each node / dr host, they will be grouped as well.
# After this, we'll look at groups and track which has the least free space per group,
# ignoring DR for now as it's feasible a user builds a lesser-spec'ed DR for a subset
# of VMs
}
foreach my $storage_group_uuid (keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}})
{
my $group_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name};
foreach my $host_uuid (keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}})
{
#$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_uuid}{$vg_uuid}{storage_group_member_uuid} = $storage_group_member_uuid;
}
} }
return(0); return(0);

@ -1247,22 +1247,6 @@ fi";
return(0); return(0);
} }
=head2 create_lv
This creates a logical volume on the local host.
=cut
sub create_lv
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->create_lv()" }});
return(0);
}
=head2 find =head2 find

@ -313,7 +313,7 @@ sub language_list
} }
} }
return(9); return(0);
} }
=head2 load_agent_strings =head2 load_agent_strings

@ -1048,8 +1048,6 @@ WHERE
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_on_pvs" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_pvs}, "sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_on_pvs" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_pvs},
}}); }});
} }
undef $count;
undef $results;
return(0); return(0);
} }

@ -204,5 +204,3 @@ ALTER FUNCTION history_scan_lvm_lvs() OWNER TO admin;
CREATE TRIGGER trigger_scan_lvm_lvs CREATE TRIGGER trigger_scan_lvm_lvs
AFTER INSERT OR UPDATE ON scan_lvm_lvs AFTER INSERT OR UPDATE ON scan_lvm_lvs
FOR EACH ROW EXECUTE PROCEDURE history_scan_lvm_lvs(); FOR EACH ROW EXECUTE PROCEDURE history_scan_lvm_lvs();

@ -1642,6 +1642,107 @@ CREATE TRIGGER trigger_upses
FOR EACH ROW EXECUTE PROCEDURE history_upses(); FOR EACH ROW EXECUTE PROCEDURE history_upses();
-- This stores information on which LVM VGs across nodes (and dr hosts) are "grouped". Specifically, when a
-- DRBD resource is to be created, the linked VGs are checked to see how much free space is available to
-- offer up. Generally, a "VG Group" should be matched in size and storage technology.
CREATE TABLE storage_groups (
storage_group_uuid uuid not null primary key,
storage_group_anvil_uuid uuid not null, -- The Anvil! this group belongs to.
storage_group_name text not null, -- This is a field that can be set to indicate the storage tech, purpose or other string a user finds useful.
modified_date timestamp with time zone not null,
FOREIGN KEY(storage_group_anvil_uuid) REFERENCES anvils(anvil_uuid)
);
ALTER TABLE storage_groups OWNER TO admin;
CREATE TABLE history.storage_groups (
history_id bigserial,
storage_group_uuid uuid,
storage_group_anvil_uuid uuid,
storage_group_name text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.storage_groups OWNER TO admin;
CREATE FUNCTION history_storage_groups() RETURNS trigger
AS $$
DECLARE
history_storage_groups RECORD;
BEGIN
SELECT INTO history_storage_groups * FROM storage_groups WHERE storage_group_uuid = new.storage_group_uuid;
INSERT INTO history.storage_groups
(storage_group_uuid,
storage_group_anvil_uuid,
storage_group_name,
modified_date)
VALUES
(history_storage_groups.storage_group_uuid,
history_storage_groups.storage_group_anvil_uuid,
history_storage_groups.storage_group_name,
history_storage_groups.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_storage_groups() OWNER TO admin;
CREATE TRIGGER trigger_storage_groups
AFTER INSERT OR UPDATE ON storage_groups
FOR EACH ROW EXECUTE PROCEDURE history_storage_groups();
-- This links specific VGs with a give storage group
CREATE TABLE storage_group_members (
storage_group_member_uuid uuid not null primary key,
storage_group_member_storage_group_uuid uuid
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'.
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_anvil_uuid) REFERENCES anvils(anvil_uuid)
);
ALTER TABLE storage_group_members OWNER TO admin;
CREATE TABLE history.storage_group_members (
history_id bigserial,
storage_group_member_uuid uuid,
storage_group_member_storage_group_uuid uuid
storage_group_member_host_uuid uuid,
storage_group_member_vg_uuid text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.storage_group_members OWNER TO admin;
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,
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.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();
-- This is used to indicate the power state of UPSes. It is used to determine when the system needs to be -- This is used to indicate the power state of UPSes. It is used to determine when the system needs to be
-- powered off. All UPS-type scan agents must use this table. The linkage between this and the 'upses' table -- powered off. All UPS-type scan agents must use this table. The linkage between this and the 'upses' table
-- will be sorted out automatically based on the scan agent used and the UPS host name / IP address. -- will be sorted out automatically based on the scan agent used and the UPS host name / IP address.

@ -1683,6 +1683,7 @@ If you are comfortable that the target has changed for a known reason, you can s
<key name="striker_0277">No UPSes</key> <key name="striker_0277">No UPSes</key>
<key name="striker_0278">This is a condition record, used by programs like scan agents to track how long a condition has existed for.</key> <key name="striker_0278">This is a condition record, used by programs like scan agents to track how long a condition has existed for.</key>
<key name="striker_0279">This indicated why a machine was powered off. This is used by ScanCore to decide if or when to power up the target host.</key> <key name="striker_0279">This indicated why a machine was powered off. This is used by ScanCore to decide if or when to power up the target host.</key>
<key name="striker_0280">Storage Pool #!variable!number!#</key> <!-- This is used for auto-generated VG groups -->
<!-- These are generally units and appended to numbers --> <!-- These are generally units and appended to numbers -->
<key name="suffix_0001">#!variable!number!#/sec</key> <key name="suffix_0001">#!variable!number!#/sec</key>
@ -1933,6 +1934,8 @@ Read UUID: .... [#!variable!read_uuid!#]
======== ========
</key> </key>
<key name="warning_0069">[ Warning ] - Checking the mail queue appears to have failed. Output received was: [#!variable!output!#].</key> <key name="warning_0069">[ Warning ] - Checking the mail queue appears to have failed. Output received was: [#!variable!output!#].</key>
<key name="warning_0070">[ Warning ] - Unable to report the available resources for the Anvil! [#!variable!anvil_name!#] as it looks like ScanCore has not yet run. Please try again after starting the 'scancore' daemon on the nodes.</key>
<key name="warning_0071">[ Warning ] - We were asked to create a new storage group called: [#!variable!name!#] but that name is already used by the group with UUID: [#!variable!uuid!#].</key>
</language> </language>
<!-- 日本語 --> <!-- 日本語 -->

Loading…
Cancel
Save