From 8e0e51544c6c6a8188db0240b7bb25ddd3240a1a Mon Sep 17 00:00:00 2001 From: digimer Date: Wed, 22 Mar 2023 22:57:26 -0400 Subject: [PATCH] * Continued work on anvil-manage-server-storage. * Created the new Database->get_lvm_data to compile LVM data from scan-lvm * Updated DRBD->parse_resource to call Database->get_lvm_data if needed, and to track backing devices to Storage Groups. Signed-off-by: digimer --- Anvil/Tools/DRBD.pm | 153 +++++++---------- Anvil/Tools/Database.pm | 277 ++++++++++++++++++++++++++++-- Anvil/Tools/Get.pm | 4 +- notes | 1 - tools/anvil-manage-server-storage | 230 ++++++++++++++++++++++--- 5 files changed, 534 insertions(+), 131 deletions(-) diff --git a/Anvil/Tools/DRBD.pm b/Anvil/Tools/DRBD.pm index cb175545..39d45562 100644 --- a/Anvil/Tools/DRBD.pm +++ b/Anvil/Tools/DRBD.pm @@ -2405,86 +2405,12 @@ sub parse_resource } else { + if (not exists $anvil->data->{lvm}{host_name}) + { + $anvil->Database->get_lvm_data({debug => $debug}); + } + # Successful parse! -=cut - - - - /dev/drbd_srv01-fs37_0 - /dev/cs_vm-a01n01/srv01-fs37_0 - internal - - - /dev/drbd_srv01-fs37_1 - /dev/cs_vm-a01n01/srv01-fs37_1 - internal - -
(null)
-
- - - /dev/drbd_srv01-fs37_0 - /dev/cs_vm-a01n02/srv01-fs37_0 - internal - - - /dev/drbd_srv01-fs37_1 - /dev/cs_vm-a01n02/srv01-fs37_1 - internal - -
(null)
-
- - - /dev/drbd_srv01-fs37_0 - /dev/cs_vm-a01dr01/srv01-fs37_0 - internal - - - /dev/drbd_srv01-fs37_1 - /dev/cs_vm-a01dr01/srv01-fs37_1 - internal - -
(null)
-
- -
10.101.10.1
-
10.101.10.2
-
-
-
-
-
- -
10.201.10.1
-
10.201.10.3
-
-
-
-
-
- -
10.201.10.2
-
10.201.10.3
-
-
-
-
-
-
-=cut foreach my $name ($dom->findnodes('/resource')) { my $resource = $name->{name}; @@ -2505,22 +2431,67 @@ sub parse_resource 's2:meta_disk' => $meta_disk, }}); - my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $this_host_name}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }}); + my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $this_host_name}); + my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + host_uuid => $host_uuid, + short_host_name => $short_host_name, + }}); - $anvil->data->{new}{resource}{$resource}{host_name}{$this_host_name}{host_uuid} = $host_uuid; - $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_path} = $volume_vnr->findvalue('./device'); - $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{backing_disk} = $volume_vnr->findvalue('./disk'); - $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_minor} = $volume_vnr->findvalue('./device/@minor'); - $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{meta_disk} = $meta_disk; - $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{size} = 0; + $anvil->data->{new}{resource}{$resource}{host_name}{$this_host_name}{host_uuid} = $host_uuid; + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_path} = $volume_vnr->findvalue('./device'); + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{backing_disk} = $volume_vnr->findvalue('./disk'); + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_minor} = $volume_vnr->findvalue('./device/@minor'); + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{meta_disk} = $meta_disk; + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{size} = 0; + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{storage_group_uuid} = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "s1:new::resource::${resource}::host_name::${this_host_name}::host_uuid" => $anvil->data->{new}{resource}{$resource}{host_name}{$this_host_name}{host_uuid}, - "s2:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::device_path" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_path}, - "s3:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::backing_disk" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{backing_disk}, - "s4:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::device_minor" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_minor}, - "s5:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::meta_disk" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{meta_disk}, + "s2:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::device_path" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_path}, + "s3:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::backing_disk" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{backing_disk}, + "s4:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::device_minor" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{device_minor}, + "s5:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::meta_disk" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{meta_disk}, + "s6:new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::storage_group_uuid" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{storage_group_uuid}, }}); + + # What Storage Group is this in? + foreach my $this_scan_lvm_lv_name (sort {$a cmp $b} keys %{$anvil->data->{lvm}{host_name}{$short_host_name}{lv}}) + { + my $this_scan_lvm_lv_path = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_path}; + my $this_scan_lvm_lv_on_vg = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_on_vg}; + my $this_scan_lvm_lv_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:this_scan_lvm_lv_name' => $this_scan_lvm_lv_name, + 's2:this_scan_lvm_lv_path' => $this_scan_lvm_lv_path, + 's3:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + 's4:this_scan_lvm_lv_uuid' => $this_scan_lvm_lv_uuid, + }}); + if ($anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{backing_disk} eq $this_scan_lvm_lv_path) + { + # What's the VG's UUID? + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:short_host_name' => $short_host_name, + 's2:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + }}); + if (exists $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}) + { + my $scan_lvm_vg_internal_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}{scan_lvm_vg_internal_uuid}; + my $storage_group_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}{storage_group_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:scan_lvm_vg_internal_uuid' => $scan_lvm_vg_internal_uuid, + 's2:storage_group_uuid' => $storage_group_uuid, + }}); + + if ($storage_group_uuid) + { + $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{storage_group_uuid} = $storage_group_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "new::resource::${resource}::host_uuid::${host_uuid}::volume_number::${volume}::storage_group_uuid" => $anvil->data->{new}{resource}{$resource}{host_uuid}{$host_uuid}{volume_number}{$volume}{storage_group_uuid}, + }}); + } + } + } + } } } foreach my $connection ($name->findnodes('./connection')) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 48a7e29f..84422565 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -42,6 +42,7 @@ my $THIS_FILE = "Database.pm"; # get_job_details # get_jobs # get_local_uuid +# get_lvm_data # get_mail_servers # get_manifests # get_recipients @@ -4549,6 +4550,264 @@ sub get_local_uuid } +=head2 get_lvm_data + +This loads all of the LVM data into the following hashes; + + +This method takes no parameters. + +=cut +sub get_lvm_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->get_lvm_data()" }}); + + # Load Storage Group data + $anvil->Database->get_storage_group_data({debug => $debug}); + + # Load PVs + my $query = " +SELECT + scan_lvm_pv_uuid, + scan_lvm_pv_host_uuid, + scan_lvm_pv_internal_uuid, + scan_lvm_pv_name, + scan_lvm_pv_used_by_vg, + scan_lvm_pv_attributes, + scan_lvm_pv_size, + scan_lvm_pv_free, + scan_lvm_pv_sector_size +FROM + scan_lvm_pvs +;"; + $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_pv_uuid = $row->[0]; + my $scan_lvm_pv_host_uuid = $row->[1]; + my $scan_lvm_pv_internal_uuid = $row->[2]; + my $scan_lvm_pv_name = $row->[3]; + my $scan_lvm_pv_used_by_vg = $row->[4]; + my $scan_lvm_pv_attributes = $row->[5]; + my $scan_lvm_pv_size = $row->[6]; + my $scan_lvm_pv_free = $row->[7]; + my $scan_lvm_pv_sector_size = $row->[8]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + scan_lvm_pv_uuid => $scan_lvm_pv_uuid, + scan_lvm_pv_host_uuid => $scan_lvm_pv_host_uuid, + scan_lvm_pv_internal_uuid => $scan_lvm_pv_internal_uuid, + scan_lvm_pv_name => $scan_lvm_pv_name, + scan_lvm_pv_used_by_vg => $scan_lvm_pv_used_by_vg, + scan_lvm_pv_attributes => $scan_lvm_pv_attributes, + scan_lvm_pv_size => $scan_lvm_pv_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_size}).")", + scan_lvm_pv_free => $scan_lvm_pv_free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_free}).")", + scan_lvm_pv_sector_size => $scan_lvm_pv_sector_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_sector_size}).")", + }}); + + if (not exists $anvil->data->{hosts}{host_uuid}{$scan_lvm_pv_host_uuid}) + { + $anvil->Database->get_hosts({debug => $debug}); + } + my $short_host_name = $anvil->data->{hosts}{host_uuid}{$scan_lvm_pv_host_uuid}{short_host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { short_host_name => $short_host_name }}); + + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_uuid} = $scan_lvm_pv_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_internal_uuid} = $scan_lvm_pv_internal_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_used_by_vg} = $scan_lvm_pv_used_by_vg; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_attributes} = $scan_lvm_pv_attributes; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_size} = $scan_lvm_pv_size; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_free} = $scan_lvm_pv_free; + $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_sector_size} = $scan_lvm_pv_sector_size; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_uuid}, + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_internal_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_internal_uuid}, + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_used_by_vg" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_used_by_vg}, + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_attributes" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_attributes}, + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_size" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_size}}).")", + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_free" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_free}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_free}}).")", + "lvm::host_name::${short_host_name}::pv::${scan_lvm_pv_name}::scan_lvm_pv_sector_size" => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_sector_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{pv}{$scan_lvm_pv_name}{scan_lvm_pv_sector_size}}).")", + }}); + } + + # Load VGs + $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 => $debug, list => { query => $query }}); + + $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + $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_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 $short_host_name = $anvil->data->{hosts}{host_uuid}{$scan_lvm_vg_host_uuid}{short_host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_extent_size}).")", + scan_lvm_vg_size => $scan_lvm_vg_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}).")", + scan_lvm_vg_free => $scan_lvm_vg_free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free}).")", + short_host_name => $short_host_name, + }}); + + my $storage_group_uuid = ""; + if (exists $anvil->data->{storage_groups}{vg_uuid}{$scan_lvm_vg_internal_uuid}) + { + $storage_group_uuid = $anvil->data->{storage_groups}{vg_uuid}{$scan_lvm_vg_internal_uuid}{storage_group_uuid}; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { storage_group_uuid => $storage_group_uuid }}); + + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_uuid} = $scan_lvm_vg_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_internal_uuid} = $scan_lvm_vg_internal_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_attributes} = $scan_lvm_vg_attributes; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_extent_size} = $scan_lvm_vg_extent_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_extent_size}).")"; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_size} = $scan_lvm_vg_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}).")"; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_free} = $scan_lvm_vg_free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free}).")"; + $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{storage_group_uuid} = $storage_group_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_uuid}, + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_internal_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_internal_uuid}, + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_attributes" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_attributes}, + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_extent_size" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_extent_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_extent_size}}).")", + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_size" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_size}}).")", + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::scan_lvm_vg_free" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_free}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{scan_lvm_vg_free}}).")", + "lvm::host_name::${short_host_name}::vg::${scan_lvm_vg_name}::storage_group_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$scan_lvm_vg_name}{storage_group_uuid}, + }}); + } + + # LVs + $query = " +SELECT + scan_lvm_lv_uuid, + scan_lvm_lv_host_uuid, + scan_lvm_lv_internal_uuid, + scan_lvm_lv_name, + scan_lvm_lv_attributes, + scan_lvm_lv_on_vg, + scan_lvm_lv_size, + scan_lvm_lv_path, + scan_lvm_lv_on_pvs +FROM + scan_lvm_lvs +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $scan_lvm_lv_uuid = $row->[0]; + my $scan_lvm_lv_host_uuid = $row->[1]; + my $scan_lvm_lv_internal_uuid = $row->[2]; + my $scan_lvm_lv_name = $row->[3]; + my $scan_lvm_lv_attributes = $row->[4]; + my $scan_lvm_lv_on_vg = $row->[5]; + my $scan_lvm_lv_size = $row->[6]; + my $scan_lvm_lv_path = $row->[7]; + my $scan_lvm_lv_on_pvs = $row->[8]; + my $short_host_name = $anvil->data->{hosts}{host_uuid}{$scan_lvm_lv_host_uuid}{short_host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + scan_lvm_lv_uuid => $scan_lvm_lv_uuid, + scan_lvm_lv_host_uuid => $scan_lvm_lv_host_uuid, + scan_lvm_lv_internal_uuid => $scan_lvm_lv_internal_uuid, + scan_lvm_lv_name => $scan_lvm_lv_name, + scan_lvm_lv_attributes => $scan_lvm_lv_attributes, + scan_lvm_lv_on_vg => $scan_lvm_lv_on_vg, + scan_lvm_lv_size => $scan_lvm_lv_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_lv_size}).")", + scan_lvm_lv_path => $scan_lvm_lv_path, + scan_lvm_lv_on_pvs => $scan_lvm_lv_on_pvs, + short_host_name => $short_host_name, + }}); + + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_uuid} = $scan_lvm_lv_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_internal_uuid} = $scan_lvm_lv_internal_uuid; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_attributes} = $scan_lvm_lv_attributes; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_on_vg} = $scan_lvm_lv_on_vg; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_size} = $scan_lvm_lv_size; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_path} = $scan_lvm_lv_path; + $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_on_pvs} = $scan_lvm_lv_on_pvs; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_uuid}, + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_internal_uuid" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_internal_uuid}, + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_attributes" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_attributes}, + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_on_vg" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_on_vg}, + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_size" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_size}}).")", + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_path" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_path}, + "lvm::host_name::${short_host_name}::lv::${scan_lvm_lv_name}::scan_lvm_lv_on_pvs" => $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$scan_lvm_lv_name}{scan_lvm_lv_on_pvs}, + }}); + } + + # Map LVs to Storage groups + 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 $anvil_uuid = $anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "s1:host_name" => $host_name, + "s2:host_uuid" => $host_uuid, + "s3:anvil_uuid" => $anvil_uuid, + }}); + next if not $anvil_uuid; + + foreach my $storage_group_uuid (keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}}) + { + my $storage_group_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{group_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "s1:storage_group_uuid" => $storage_group_uuid, + "s2:storage_group_name" => $storage_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}{storage_group_member_uuid}; + my $storage_group_member_vg_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_internal_uuid}; + my $vg_size = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_size}; + my $vg_free = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_free}; + 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}; + } + } + + return(0); +} + + =head2 get_mail_servers This gets the list of configured mail servers. @@ -5426,12 +5685,10 @@ WHERE my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name}; my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}; - my $dr1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { anvil_name => $anvil_name, node1_host_uuid => $node1_host_uuid, node2_host_uuid => $node2_host_uuid, - dr1_host_uuid => $dr1_host_uuid, }}); foreach my $storage_group_uuid (keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}}) { @@ -5444,7 +5701,6 @@ WHERE my $size_to_match = 0; my $node1_seen = 0; my $node2_seen = 0; - my $dr1_seen = $dr1_host_uuid ? 0 : 1; # Only set to '0' if DR exists. foreach my $this_host_uuid (keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}}) { my $storage_group_member_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$this_host_uuid}{storage_group_member_uuid}; @@ -5477,11 +5733,6 @@ WHERE $node2_seen = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { node2_seen => $node2_seen }}); } - elsif (($dr1_host_uuid) && ($this_host_uuid eq $dr1_host_uuid)) - { - $dr1_seen = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { dr1_seen => $dr1_seen }}); - } else { # This host doesn't belong in this group anymore. Delete it. @@ -5502,15 +5753,9 @@ WHERE } if ((not $node1_seen) or - (not $node2_seen) or - (not $dr1_seen)) + (not $node2_seen)) { - my $hosts = [$node1_host_uuid, $node2_host_uuid]; - if ($dr1_host_uuid) - { - push @{$hosts}, $dr1_host_uuid; - } - + my $hosts = [$node1_host_uuid, $node2_host_uuid]; my $reload = 0; foreach my $this_host_uuid (@{$hosts}) { diff --git a/Anvil/Tools/Get.pm b/Anvil/Tools/Get.pm index 3327e392..50432e6a 100644 --- a/Anvil/Tools/Get.pm +++ b/Anvil/Tools/Get.pm @@ -795,8 +795,8 @@ ORDER BY }}); # Make it easy to sort by group name - my $storage_group_name = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{group_name}; - $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid} = $storage_group_uuid; + my $storage_group_name = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{group_name}; + $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid} = $storage_group_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "anvil_resources::${anvil_uuid}::storage_group_name::${storage_group_name}::storage_group_uuid" => $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid}, }}); diff --git a/notes b/notes index 12425c87..27fcdbb5 100644 --- a/notes +++ b/notes @@ -1,4 +1,3 @@ - Common queries; * SELECT a.job_uuid, b.host_name, a.job_command, a.job_data, a.job_progress, a.job_status FROM jobs a, hosts b WHERE a.job_host_uuid = b.host_uuid AND a.job_progress != 100; * SELECT a.host_name, b.file_name, c.file_location_active FROM hosts a, files b, file_locations c WHERE a.host_uuid = c.file_location_host_uuid AND b.file_uuid = c.file_location_file_uuid ORDER BY b.file_name ASC, a.host_name ASC; diff --git a/tools/anvil-manage-server-storage b/tools/anvil-manage-server-storage index 0c850f88..8fadf9a7 100755 --- a/tools/anvil-manage-server-storage +++ b/tools/anvil-manage-server-storage @@ -160,6 +160,90 @@ sub manage_disk } } + $anvil->Database->get_lvm_data({debug => 2}); + + # Load DRBD resource data so that we can map DRBD resources / volumes to volume groups. + my $drbd_resource = ""; + foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{device}}) + { + my $on_lv = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{on_lv}; + $drbd_resource = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{resource}; + my $device_target = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{target}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:device_path' => $device_path, + 's2:on_lv' => $on_lv, + 's3:drbd_resource' => $drbd_resource, + 's4:device_target' => $device_target, + }}); + } + # There should only ever be one, but it's not impossible for there to be multiple. + foreach my $drbd_resource (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{drbd}{resource}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_resource => $drbd_resource }}); + + # Get the DRBD volume data + load_drbd_data($anvil, $drbd_resource); + } + foreach my $host_type ("node", "dr") + { + foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}}) + { + my $host_uuid = $anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}{$short_host_name}{host_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:short_host_name' => $short_host_name, + 's2:host_uuid' => $host_uuid, + }}); + foreach my $volume_number (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}}) + { + my $device_path = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_path}; + my $device_minor = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_minor}; + my $volume_size = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{volume_size}; + my $backing_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{backing_disk}; + my $meta_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{meta_disk}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:volume_number' => $volume_number, + 's2:device_path' => $device_path, + 's3:device_minor' => $device_minor, + 's4:volume_size' => $volume_size, + 's5:backing_disk' => $backing_disk, + 's6:meta_disk' => $meta_disk, + }}); + + # Which volume group is the backing device in? + foreach my $this_scan_lvm_lv_name (sort {$a cmp $b} keys %{$anvil->data->{lvm}{host_name}{$short_host_name}{lv}}) + { + my $this_scan_lvm_lv_path = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_path}; + my $this_scan_lvm_lv_on_vg = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_on_vg}; + my $this_scan_lvm_lv_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:this_scan_lvm_lv_name' => $this_scan_lvm_lv_name, + 's2:this_scan_lvm_lv_path' => $this_scan_lvm_lv_path, + 's3:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + 's4:this_scan_lvm_lv_uuid' => $this_scan_lvm_lv_uuid, + }}); + + if ($backing_disk eq $this_scan_lvm_lv_path) + { + # What's the VG's UUID? + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:short_host_name' => $short_host_name, + 's2:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + }}); + if (exists $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}) + { + my $scan_lvm_vg_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_name}{scan_lvm_vg_uuid}; + my $storage_group_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_name}{storage_group_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:scan_lvm_vg_uuid' => $scan_lvm_vg_uuid, + 's2:storage_group_uuid' => $storage_group_uuid, + }}); + } + } + } + } + } + } + my $device_target = $anvil->data->{switches}{disk}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }}); @@ -202,7 +286,6 @@ sub manage_disk my $volume = ""; print "Sub-Nodes:\n"; - my $drbd_resource = ""; foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{device}}) { my $on_lv = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{on_lv}; @@ -388,15 +471,32 @@ sub get_definition_source { my ($anvil) = @_; - my $short_host_name = $anvil->Get->short_host_name; - my $server_name = $anvil->data->{switches}{server_name}; - my $from_source = ""; + my $short_host_name = $anvil->Get->short_host_name; + my $server_name = $anvil->data->{switches}{server_name}; + my $server_uuid = $anvil->data->{switches}{server_uuid}; + my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; + my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; + my $from_source = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_host_name => $short_host_name, server_name => $server_name, + server_uuid => $server_uuid, + server_state => $server_state, from_source => $from_source, }}); - if (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}) + + $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}; + $anvil->data->{server}{$short_host_name}{$server_name}{from_disk} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}; + $anvil->data->{server}{$short_host_name}{$server_name}{from_db} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_db}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "server::${short_host_name}::${server_name}::from_virsh" => $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}, + "server::${short_host_name}::${server_name}::from_disk" => $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}, + "server::${short_host_name}::${server_name}::from_db" => $anvil->data->{server}{$short_host_name}{$server_name}{from_db}, + }}); + + if (($server_state eq "running") && + ($server_host_uuid eq $anvil->Get->host_uuid()) && + (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh})) { $from_source = "from_virsh"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); @@ -426,6 +526,16 @@ sub show_server_details 's2:server_name' => $server_name, }}); + # We need to know which volume groups the disks are on so that we can report how much free space is + # available for either growing or adding a disk. + $anvil->Get->available_resources({ + debug => 2, + anvil_uuid => $anvil->data->{switches}{anvil_uuid}, + }); + + # Load LVM and Storage Group data + $anvil->Database->get_lvm_data({debug => 2}); + my $from_source = get_definition_source($anvil); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); foreach my $device ("disk", "cdrom") @@ -480,6 +590,11 @@ sub show_server_details 's6:driver_cache' => $driver_cache, }}); print "- Target: [".$device_target."], boot: [".$say_boot."], path: [".$device_path."], cache: [".$driver_cache."], driver type: [".$driver_type."]\n"; + + # Get the backing LV from the DRBD resource. + + + #if ($anvil->data->{storage_groups}{vg_uuid}{$vg_uuid}{storage_group_uuid}) } else { @@ -613,6 +728,8 @@ sub show_volume { my ($anvil, $drbd_resource, $host_type) = @_; + my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }}); foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}}) { my $host_uuid = $anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}{$short_host_name}{host_uuid}; @@ -623,20 +740,73 @@ sub show_volume print " |- Name: [".$short_host_name."], UUID: [".$host_uuid."]\n"; foreach my $volume_number (sort {$a cmp $b} keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}}) { - my $device_path = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_path}; - my $device_minor = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_minor}; - my $volume_size = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{volume_size}; - my $backing_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{backing_disk}; - my $meta_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{meta_disk}; + my $device_path = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_path}; + my $device_minor = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{device_minor}; + my $volume_size = $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{volume_size}; + my $backing_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{backing_disk}; + my $meta_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{meta_disk}; + my $storage_group_uuid = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$volume_number}{storage_group_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:volume_number' => $volume_number, + 's2:device_path' => $device_path, + 's3:device_minor' => $device_minor, + 's4:volume_size' => $volume_size, + 's5:backing_disk' => $backing_disk, + 's6:meta_disk' => $meta_disk, + 's7:storage_group_uuid' => $storage_group_uuid, + }}); + my $storage_group_name = ""; + my $storage_group_size = 0; + my $storage_group_free_space = 0; + if (($storage_group_uuid) && ($anvil_uuid) && (exists $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid})) + { + $storage_group_name = $anvil->data->{storage_groups}{storage_group_uuid}{$storage_group_uuid}{storage_group_name}; + $storage_group_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size}; + $storage_group_free_space = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{free_size}; + } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:volume_number' => $volume_number, - 's2:device_path' => $device_path, - 's3:device_minor' => $device_minor, - 's4:volume_size' => $volume_size, - 's5:backing_disk' => $backing_disk, - 's6:meta_disk' => $meta_disk, + 's1:storage_group_size' => $storage_group_size, + 's2:storage_group_free_space' => $storage_group_free_space, }}); - print " ^- Volume: [".$volume_number."], backing device: [".$backing_disk."], DRBD minor: [".$device_minor."], size: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $volume_size})."]\n"; + print " |- Volume: [".$volume_number."], backing device: [".$backing_disk."], DRBD minor: [".$device_minor."], size: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $volume_size})."]\n"; + print " ^- In storage group: [".$storage_group_name."], size: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $storage_group_size})."], free: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $storage_group_free_space})."]\n"; + + # How much space is available in the storage group this volume is in? + foreach my $this_scan_lvm_lv_name (sort {$a cmp $b} keys %{$anvil->data->{lvm}{host_name}{$short_host_name}{lv}}) + { + my $this_scan_lvm_lv_path = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_path}; + my $this_scan_lvm_lv_on_vg = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_on_vg}; + my $this_scan_lvm_lv_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$this_scan_lvm_lv_name}{scan_lvm_lv_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:this_scan_lvm_lv_name' => $this_scan_lvm_lv_name, + 's2:this_scan_lvm_lv_path' => $this_scan_lvm_lv_path, + 's3:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + 's4:this_scan_lvm_lv_uuid' => $this_scan_lvm_lv_uuid, + }}); + if ($backing_disk eq $this_scan_lvm_lv_path) + { + # What's the VG's UUID? + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:short_host_name' => $short_host_name, + 's2:this_scan_lvm_lv_on_vg' => $this_scan_lvm_lv_on_vg, + }}); + if (exists $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}) + { + my $scan_lvm_vg_internal_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}{scan_lvm_vg_internal_uuid}; + my $storage_group_uuid = $anvil->data->{lvm}{host_name}{$short_host_name}{vg}{$this_scan_lvm_lv_on_vg}{storage_group_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:scan_lvm_vg_internal_uuid' => $scan_lvm_vg_internal_uuid, + 's2:storage_group_uuid' => $storage_group_uuid, + }}); + + if ($storage_group_uuid) + { + my $vg_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size}; + my $free_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{free_size}; + } + } + } + } } } @@ -680,6 +850,7 @@ sub validate_server my $server_definition = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}; my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; + my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:short_host_name' => $short_host_name, 's2:server_name' => $server_name, @@ -687,7 +858,21 @@ sub validate_server 's4:server_definition' => $server_definition, 's5:server_host_uuid' => $server_host_uuid, 's6:server_state' => $server_state, + 's7:anvil_uuid' => $anvil_uuid, }}); + if (not $anvil->data->{switches}{anvil_uuid}) + { + $anvil->data->{switches}{anvil_uuid} = $anvil_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:switches::anvil_uuid' => $anvil->data->{switches}{anvil_uuid}, + }}); + } + + if ($server_state eq "DELETED") + { + print "The server: [".$server_name."] has been deleted.\n"; + $anvil->nice_exit({exit_code => 1}); + } # Parse the definition. $anvil->Server->parse_definition({ @@ -710,7 +895,7 @@ sub validate_server # The server isn't actually running... Not here anyway. if ($server_state eq "running") { - my $server_host_name = $anvil->Get->get_host_from_uuid({ + my $server_host_name = $anvil->Database->get_host_from_uuid({ short => 1, host_uuid => $server_host_uuid, }); @@ -943,11 +1128,14 @@ sub show_server_list { foreach my $server_name (sort {$a cmp $b} keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}}) { - my $server_uuid = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid}; + my $server_uuid = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid}; + my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server_name => $server_name, - server_uuid => $server_uuid, + server_name => $server_name, + server_uuid => $server_uuid, + server_state => $server_state, }}); + next if $server_state eq "DELETED"; print "^- Server: [".$server_name."], UUID: [".$server_uuid."]\n"; } }