d9aa8aee74
Signed-off-by: digimer <mkelly@alteeve.ca>
3819 lines
164 KiB
Perl
Executable File
3819 lines
164 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# This program will manage servers; Changing RAM, CPU cores, Growing virtual disks, adding virtual disks,
|
|
# inserting and ejecting ISO images into virtual optical media.
|
|
#
|
|
# Exit codes;
|
|
# 0 = Normal exit.
|
|
# 1 = No database connection.
|
|
#
|
|
# TODO:
|
|
# - Update the target_ip search to use the new Network->find_target_ip().
|
|
#
|
|
# USAGE:
|
|
# - Show
|
|
# - anvil-manage-server-storage --server srv01-fs37
|
|
# - ISO
|
|
# - anvil-manage-server-storage --server srv01-fs37 --optical sda --insert /mnt/shared/files/CentOS-5.11-x86_64-bin-DVD-1of2.iso
|
|
# - anvil-manage-server-storage --server srv01-fs37 --optical sda --eject
|
|
# - Disk
|
|
# - anvil-manage-server-storage --server srv01-fs37 --disk vdb --grow {+10%,150GiB}
|
|
# - anvil-manage-server-storage --server srv01-fs37 --add 50G --storage-group "Storage group 1"
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Anvil::Tools;
|
|
require POSIX;
|
|
use Term::Cap;
|
|
use Text::Diff;
|
|
use Data::Dumper;
|
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
|
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
|
|
if (($running_directory =~ /^\./) && ($ENV{PWD}))
|
|
{
|
|
$running_directory =~ s/^\./$ENV{PWD}/;
|
|
}
|
|
|
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
|
|
$| = 1;
|
|
|
|
my $anvil = Anvil::Tools->new();
|
|
|
|
# Read switches
|
|
$anvil->Get->switches({list => [
|
|
"add",
|
|
"anvil",
|
|
"confirm",
|
|
"disk",
|
|
"eject",
|
|
"job-uuid",
|
|
"grow",
|
|
"insert",
|
|
"optical",
|
|
"server",
|
|
"storage-group",
|
|
], man => $THIS_FILE});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
|
|
|
|
# Connect to the database(s). If we have no connections, we'll proceed anyway as one of the 'run_once' tasks
|
|
# is to setup the database server.
|
|
$anvil->Database->connect();
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
|
|
if (not $anvil->data->{sys}{database}{connections})
|
|
{
|
|
# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try
|
|
# again after we exit.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0305"});
|
|
sleep 10;
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
if ($anvil->data->{switches}{'job-uuid'})
|
|
{
|
|
load_job($anvil);
|
|
}
|
|
|
|
$anvil->Database->get_hosts();
|
|
$anvil->Database->get_anvils();
|
|
$anvil->Database->get_servers();
|
|
|
|
if ($anvil->data->{switches}{anvil})
|
|
{
|
|
# Make sure they asked for a real anvil.
|
|
$anvil->Get->anvil_from_switch({string => $anvil->data->{switches}{anvil}});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::anvil_name" => $anvil->data->{switches}{anvil_name},
|
|
"switches::anvil_uuid" => $anvil->data->{switches}{anvil_uuid},
|
|
}});
|
|
}
|
|
|
|
if (not $anvil->data->{switches}{server})
|
|
{
|
|
# Show the list of servers.
|
|
show_server_list($anvil);
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0456"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0456",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
|
|
validate_server($anvil);
|
|
|
|
if (($anvil->data->{switches}{optical}) or ($anvil->data->{switches}{eject}))
|
|
{
|
|
manage_optical($anvil);
|
|
}
|
|
elsif (($anvil->data->{switches}{disk}) or ($anvil->data->{switches}{add}))
|
|
{
|
|
manage_disk($anvil);
|
|
}
|
|
else
|
|
{
|
|
show_server_details($anvil, 1);
|
|
}
|
|
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "job_0281",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
|
|
|
|
#############################################################################################################
|
|
# Functions #
|
|
#############################################################################################################
|
|
|
|
sub load_storage
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Host and server
|
|
my $short_host_name = $anvil->Get->short_host_name;
|
|
my $server_name = $anvil->data->{switches}{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});
|
|
|
|
# Load DRBD data from the database.
|
|
$anvil->Database->get_drbd_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);
|
|
}
|
|
|
|
return($drbd_resource);
|
|
}
|
|
|
|
sub manage_disk
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_anvil_uuid();
|
|
my $short_host_name = $anvil->Get->short_host_name;
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
my $from_source = get_definition_source($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
anvil_uuid => $anvil_uuid,
|
|
short_host_name => $short_host_name,
|
|
server_name => $server_name,
|
|
from_source => $from_source,
|
|
}});
|
|
if (not $anvil->data->{switches}{disk})
|
|
{
|
|
# If there's only one disk drive, select it automatically
|
|
my $count = keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
if ($count == 1)
|
|
{
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}})
|
|
{
|
|
$anvil->data->{switches}{disk} = $device_target;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::drive" => $anvil->data->{switches}{disk},
|
|
}});
|
|
last;
|
|
}
|
|
}
|
|
|
|
if (not $anvil->data->{switches}{disk})
|
|
{
|
|
# Can't proceed.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0457"});
|
|
show_server_details($anvil, 1);
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0457",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
my $drbd_resource = load_storage($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_resource => $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};
|
|
next if $device_path eq "DELETED";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:volume_number' => $volume_number,
|
|
's2:device_path' => $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:device_minor' => $device_minor,
|
|
's2:volume_size' => $volume_size,
|
|
's3:backing_disk' => $backing_disk,
|
|
's4: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}})
|
|
{
|
|
next if not $this_scan_lvm_lv_name;
|
|
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,
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
|
|
# How much space can this LV grow into (this factors DR is already protected).
|
|
$anvil->data->{server_name}{$server_name}{drbd_resource}{$drbd_resource}{volume}{$volume_number}{free_space} = get_max_free_space($anvil, $drbd_resource, $volume_number);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"server_name::${server_name}::drbd_resource::${drbd_resource}::volume::${volume_number}::free_space" => $anvil->data->{server_name}{$server_name}{drbd_resource}{$drbd_resource}{volume}{$volume_number}{free_space}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{server_name}{$server_name}{drbd_resource}{$drbd_resource}{volume}{$volume_number}{free_space}}).")",
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($anvil->data->{switches}{grow}) or ($anvil->data->{switches}{remove}))
|
|
{
|
|
my $device_target = $anvil->data->{switches}{disk};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }});
|
|
|
|
if (($anvil->data->{switches}{disk} eq "#!SET!#") or ($anvil->data->{switches}{disk} eq "1"))
|
|
{
|
|
# User didn't specify a device.
|
|
show_server_details($anvil, 1);
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0458"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0458",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
elsif (not exists $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}{$device_target})
|
|
{
|
|
# Invalid device target
|
|
show_server_details($anvil, 1);
|
|
my $variables = {
|
|
device_target => $device_target,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0459", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0459",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $device = "disk";
|
|
my $alias = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{alias};
|
|
my $boot_order = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{boot_order};
|
|
my $say_boot = $boot_order eq "99" ? "--" : sprintf("%02d", $boot_order);
|
|
my $type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{type};
|
|
my $address_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{type};
|
|
my $address_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{bus};
|
|
my $driver_name = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{name};
|
|
my $device_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{device_bus};
|
|
my $driver_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{type};
|
|
my $address_domain = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{domain};
|
|
my $address_slot = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{slot};
|
|
my $address_function = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{function};
|
|
my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path};
|
|
my $driver_io = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{io};
|
|
my $driver_cache = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{cache};
|
|
my $on_lv = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{on_lv};
|
|
my $drbd_volume = $anvil->data->{lvm}{host_name}{$short_host_name}{lv_path}{$on_lv}{drbd}{volume};
|
|
my $max_free_space = $anvil->data->{server_name}{$server_name}{drbd_resource}{$drbd_resource}{volume}{$drbd_volume}{free_space};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:device_target' => $device_target,
|
|
's02:alias' => $alias,
|
|
's03:boot_order' => $boot_order,
|
|
's04:say_boot' => $say_boot,
|
|
's05:type' => $type,
|
|
's06:address_type' => $address_type,
|
|
's07:address_bus' => $address_bus,
|
|
's08:driver_name' => $driver_name,
|
|
's09:device_bus' => $device_bus,
|
|
's10:driver_type' => $driver_type,
|
|
's11:address_domain' => $address_domain,
|
|
's12:address_slot' => $address_slot,
|
|
's13:address_function' => $address_function,
|
|
's14:device_path' => $device_path,
|
|
's15:driver_io' => $driver_io,
|
|
's16:driver_cache' => $driver_cache,
|
|
's17:on_lv' => $on_lv,
|
|
's18:drbd_volume' => $drbd_volume,
|
|
's19:max_free_space' => $max_free_space." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}).")",
|
|
}});
|
|
my $variables = {
|
|
device_target => $device_target,
|
|
say_boot => $say_boot,
|
|
device_path => $device_path,
|
|
max_free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}),
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0749", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 10,
|
|
message => "log_0749",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
# What are we doing?
|
|
if ($anvil->data->{switches}{grow})
|
|
{
|
|
manage_disk_grow($anvil, $drbd_resource, $drbd_volume, $max_free_space);
|
|
}
|
|
}
|
|
elsif ($anvil->data->{switches}{add})
|
|
{
|
|
manage_disk_add($anvil, $drbd_resource);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub manage_disk_add
|
|
{
|
|
my ($anvil, $drbd_resource) = @_;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_resource => $drbd_resource }});
|
|
|
|
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_anvil_uuid();
|
|
my $short_host_name = $anvil->Get->short_host_name;
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
my $from_source = get_definition_source($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
anvil_uuid => $anvil_uuid,
|
|
short_host_name => $short_host_name,
|
|
server_name => $server_name,
|
|
from_source => $from_source,
|
|
}});
|
|
|
|
# Are they asking for an available amount of space?
|
|
my $say_up = $anvil->Words->string({key => 'message_0331'});
|
|
my $say_down = $anvil->Words->string({key => 'message_0332'});
|
|
|
|
# Do we have a storage group?
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
'switches::storage-group' => $anvil->data->{switches}{'storage-group'},
|
|
}});
|
|
if (not $anvil->data->{switches}{'storage-group'})
|
|
{
|
|
print $anvil->Words->string({key => 'warning_0168'})."\n";
|
|
show_storage_groups($anvil);
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "warning_0168",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Make sure that the passed
|
|
my $storage_group_switch = $anvil->data->{switches}{'storage-group'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_switch => $storage_group_switch }});
|
|
|
|
my $storage_group_uuid = "";
|
|
my $storage_group_name = "";
|
|
if (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_switch})
|
|
{
|
|
$storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_switch}{storage_group_uuid};
|
|
$storage_group_name = $storage_group_switch;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
storage_group_uuid => $storage_group_uuid,
|
|
storage_group_name => $storage_group_name,
|
|
}});
|
|
}
|
|
elsif (exists $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_switch})
|
|
{
|
|
$storage_group_uuid = $storage_group_switch;
|
|
$storage_group_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_switch}{group_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
storage_group_uuid => $storage_group_uuid,
|
|
storage_group_name => $storage_group_name,
|
|
}});
|
|
}
|
|
else
|
|
{
|
|
# Bad storage group.
|
|
my $variables = { storage_group => $storage_group_switch };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0437", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0437",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Did we get a valid disk size?
|
|
my $free_space = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{free_space};
|
|
my $add_size = $anvil->data->{switches}{add};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
if ($add_size =~ /^(\d+)%$/)
|
|
{
|
|
# This is valid
|
|
my $percent = ".".$1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { percent => $percent }});
|
|
|
|
$add_size = int($free_space * $percent);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
elsif ($add_size !~ /\d/)
|
|
{
|
|
# No digits, probably didn't set a value at all.
|
|
my $variables = {
|
|
free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $free_space}),
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0423", variables => $variables});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "message_0330"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0423",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "message_0330",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
elsif ($add_size !~ /^\d+$/)
|
|
{
|
|
# Size is not in bytes, try to convert it.
|
|
my $bytes = $anvil->Convert->human_readable_to_bytes({
|
|
debug => 2,
|
|
size => $add_size,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'bytes' => $bytes }});
|
|
if ($bytes =~ /^\d+$/)
|
|
{
|
|
$add_size = $bytes;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
else
|
|
{
|
|
# Not a valid size.
|
|
my $variables = { add_size => $add_size };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0424", variables => $variables});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "message_0330"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0424",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "message_0330",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
# Still here? We're good to go.
|
|
my $lv_command_size = 0;
|
|
my $hr_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $add_size});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { hr_size => $hr_size }});
|
|
if ($add_size eq "100%")
|
|
{
|
|
# This is valid
|
|
$add_size = "-l +100\%FREE";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
else
|
|
{
|
|
$hr_size =~ s/\s+//g;
|
|
$add_size = "-L +".$hr_size;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
|
|
# What's the next free drive in the system, and what's the next free volume number?
|
|
my $new_device_target = "";
|
|
my $target_prefix = "";
|
|
my $disk_device_bus = "";
|
|
my $disk_cache = "";
|
|
my $disk_io_policy = "";
|
|
my $drive_letter = "a";
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }});
|
|
if (not $disk_device_bus)
|
|
{
|
|
$target_prefix = ($device_target =~ /^(\w+)\w$/)[0];
|
|
$disk_device_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}{$device_target}{device_bus};
|
|
$disk_io_policy = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}{$device_target}{driver}{io};
|
|
$disk_cache = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}{$device_target}{driver}{cache};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
target_prefix => $target_prefix,
|
|
disk_device_bus => $disk_device_bus,
|
|
disk_io_policy => $disk_io_policy,
|
|
disk_cache => $disk_cache,
|
|
}});
|
|
last;
|
|
}
|
|
}
|
|
for (0..25)
|
|
{
|
|
my $test_device = $target_prefix.$drive_letter;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_device => $test_device }});
|
|
if (not exists $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{disk}{target}{$test_device})
|
|
{
|
|
# Found a free one.
|
|
$new_device_target = $test_device;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_device_target => $new_device_target }});
|
|
last;
|
|
}
|
|
$drive_letter++;
|
|
}
|
|
|
|
if (not $new_device_target)
|
|
{
|
|
# Failed to find a new target device name
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0425"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0425",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $next_drbd_volume = "";
|
|
foreach my $this_host (sort {$a cmp $b} keys %{$anvil->data->{drbd}{drbd_node}})
|
|
{
|
|
my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $this_host});
|
|
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:this_host' => $this_host,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:short_host_name' => $short_host_name,
|
|
}});
|
|
|
|
if ($next_drbd_volume eq "")
|
|
{
|
|
my $test_drbd_volume = 0;
|
|
for (0..100)
|
|
{
|
|
if (not $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$test_drbd_volume}{device_path})
|
|
{
|
|
# This is free.
|
|
$next_drbd_volume = $test_drbd_volume;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { next_drbd_volume => $next_drbd_volume }});
|
|
last;
|
|
}
|
|
$test_drbd_volume++;
|
|
next;
|
|
}
|
|
}
|
|
|
|
if ($next_drbd_volume eq "")
|
|
{
|
|
# Failed to find a new DRBD volume to use.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0426"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0426",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
### TODO: Make this work without the peer node being online.
|
|
# The server is allowed to be running, but both nodes and any DR hosts this is replicating to
|
|
# needs to be online.
|
|
my $all_online = check_drbd_peer_access($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_online => $all_online }});
|
|
|
|
if (not $all_online)
|
|
{
|
|
# Adding a new disk requires all peers to be online. We'll exit with the progress under 100,
|
|
# so anvil-daemon will kick it back off in a minute.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0427"});
|
|
$anvil->Job->update_progress({
|
|
progress => 90,
|
|
message => "error_0427",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $progress = 80;
|
|
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{peer}})
|
|
{
|
|
# Record the access
|
|
my $say_access = $anvil->data->{peer}{$short_host_name}{access_ip} ? $say_up : $say_down;
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
access => $say_access,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0428", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ++$progress,
|
|
message => "error_0428",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Still alive? Ask the user to confirm.
|
|
my $progress = 20;
|
|
my $variables = {
|
|
new_device_target => $new_device_target,
|
|
hr_size => $hr_size,
|
|
disk_device_bus => $disk_device_bus,
|
|
disk_cache => $disk_cache,
|
|
disk_io_policy => $disk_io_policy,
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
storage_group_name => $storage_group_name,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0333", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "message_0333",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
if ((not $anvil->data->{switches}{confirm}) && (not $anvil->data->{switches}{'job-uuid'}))
|
|
{
|
|
print $anvil->Words->string({key => "message_0021"})." ";
|
|
my $answer = <STDIN>;
|
|
chomp($answer);
|
|
if ($answer !~ /^y/i)
|
|
{
|
|
print $anvil->Words->string({key => "message_0022"})."\n";
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
|
|
# Test that we've lost access while waiting for the answer.
|
|
my $all_online = check_drbd_peer_access($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_online => $all_online }});
|
|
|
|
if (not $all_online)
|
|
{
|
|
# It would appear that we've lost access to a peer while waiting for the answer.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0429"});
|
|
$anvil->Job->update_progress({
|
|
progress => 90,
|
|
message => "error_0429",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $progress = 90;
|
|
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{peer}})
|
|
{
|
|
# Record the access
|
|
my $say_access = $anvil->data->{peer}{$short_host_name}{access_ip} ? $say_up : $say_down;
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
access => $say_access,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0428", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ++$progress,
|
|
message => "error_0428",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "job_0471",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
# Get the next free minor number
|
|
my ($free_minor, undef) = $anvil->DRBD->get_next_resource({
|
|
debug => 2,
|
|
minor_only => 1,
|
|
anvil_uuid => $anvil_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { free_minor => $free_minor }});
|
|
|
|
# Create the new LVs
|
|
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};
|
|
my $vg_name = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_name};
|
|
my $vg_internal_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{host_uuid}{$host_uuid}{vg_internal_uuid};
|
|
my $new_lv_name = $server_name."_".$next_drbd_volume;
|
|
my $backing_disk = "/dev/".$vg_name."/".$new_lv_name;
|
|
my $shell_call = "if [ -e '".$backing_disk."' ]; then echo 'LV: [".$backing_disk."] already exists.'; else ".$anvil->data->{path}{exe}{lvcreate}." ".$add_size." -n ".$new_lv_name." ".$vg_name."; fi;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:vg_name' => $vg_name,
|
|
's4:vg_internal_uuid' => $vg_internal_uuid,
|
|
's5:new_lv_name' => $new_lv_name,
|
|
's6:backing_disk' => $backing_disk,
|
|
's7:shell_call' => $shell_call,
|
|
}});
|
|
|
|
# Record this for updating the DRBD resource.
|
|
$anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{minor} = $free_minor;
|
|
$anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{backing_disk} = $backing_disk;
|
|
$anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{seen} = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new_drbd::${short_host_name}::resource::${drbd_resource}::volume::${next_drbd_volume}::minor" => $anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{minor},
|
|
"new_drbd::${short_host_name}::resource::${drbd_resource}::volume::${next_drbd_volume}::backing_disk" => $anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{backing_disk},
|
|
"new_drbd::${short_host_name}::resource::${drbd_resource}::volume::${next_drbd_volume}::seen" => $anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{seen},
|
|
}});
|
|
|
|
# This lets us insert the new volume as needed.
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
}});
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
# Creating the new local LV
|
|
my $variables = { backing_disk => $backing_disk };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0748", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0748",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
backing_disk => $backing_disk,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0460", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0460",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $use_network = $anvil->data->{peer}{$short_host_name}{access}{network};
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
backing_disk => $backing_disk,
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0756", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0756",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
backing_disk => $backing_disk,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
error => $error,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0461", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0461",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Update the DRBD config file.
|
|
my $new_res_file = "";
|
|
my $drbd_res_file = $anvil->data->{path}{directories}{drbd_resources}."/".$drbd_resource.".res";
|
|
my $drbd_res_body = $anvil->Storage->read_file({file => $drbd_res_file});
|
|
my $in_on_host = "";
|
|
my $in_volume = "";
|
|
foreach my $line (split /\n/, $drbd_res_body)
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
if ($line =~ /on\s+(.*?)\s/)
|
|
{
|
|
$in_on_host = $1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
|
|
$new_res_file .= $line."\n";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_res_file => $new_res_file }});
|
|
next;
|
|
}
|
|
|
|
if (($in_on_host) && ($line =~ /volume\s+(\d+)\s/))
|
|
{
|
|
$in_volume = $1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_volume => $in_volume }});
|
|
|
|
$new_res_file .= $line."\n";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_res_file => $new_res_file }});
|
|
|
|
$anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$in_volume}{seen} = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new_drbd::${in_on_host}::resource::${drbd_resource}::volume::${in_volume}::seen" => $anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$in_volume}{seen},
|
|
}});
|
|
next;
|
|
}
|
|
|
|
if ($line =~ /}/)
|
|
{
|
|
if ($in_volume)
|
|
{
|
|
$in_volume = "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_volume => $in_volume }});
|
|
}
|
|
elsif ($in_on_host)
|
|
{
|
|
# This is where we insert the new volume, if we've not seen it yet.
|
|
if (not $anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{seen})
|
|
{
|
|
# Insert the line.
|
|
$new_res_file .= $line."
|
|
|
|
volume ".$next_drbd_volume." {
|
|
device /dev/drbd_".$drbd_resource."_".$next_drbd_volume." minor ".$anvil->data->{new_drbd}{$short_host_name}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{minor}.";
|
|
disk ".$anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{backing_disk}.";
|
|
meta-disk internal;
|
|
}
|
|
";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_res_file => $new_res_file }});
|
|
|
|
$anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$next_drbd_volume}{seen} = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new_drbd::${in_on_host}::resource::${drbd_resource}::volume::${in_volume}::seen" => $anvil->data->{new_drbd}{$in_on_host}{resource}{$drbd_resource}{volume}{$in_volume}{seen},
|
|
}});
|
|
next;
|
|
}
|
|
}
|
|
}
|
|
|
|
$new_res_file .= $line."\n";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_res_file => $new_res_file }});
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_res_file => $new_res_file }});
|
|
|
|
my $difference = diff \$drbd_res_body, \$new_res_file, { STYLE => 'Unified' };
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
|
|
|
|
# Write the file to a test file and verify it's sane,
|
|
my $test_file = $anvil->data->{path}{directories}{temp}."/test-".$drbd_resource.".res";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_file => $test_file }});
|
|
my ($problem) = $anvil->Storage->write_file({
|
|
debug => 2,
|
|
backup => 0,
|
|
overwrite => 1,
|
|
file => $test_file,
|
|
body => $new_res_file,
|
|
user => "root",
|
|
group => "root",
|
|
mode => "0644",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
|
|
# Validate.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0751"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0751",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." --config-to-test ".$test_file." --config-to-exclude ".$drbd_res_file." sh-nop";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
# Something went wrong.
|
|
my $variables = {
|
|
test_file => $test_file,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0430", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0430",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
# Success!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0752"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0752",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
# Remove the test file.
|
|
unlink $test_file;
|
|
|
|
# Backup the res file so we can tell the user where the current config was backed up to in
|
|
# case they need to restore it.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0757"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0757",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($backup_file) = $anvil->Storage->backup({file => $drbd_res_file});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { backup_file => $backup_file }});
|
|
|
|
# Write out the new file.
|
|
($problem) = $anvil->Storage->write_file({
|
|
debug => 2,
|
|
backup => 0,
|
|
overwrite => 1,
|
|
file => $drbd_res_file,
|
|
body => $new_res_file,
|
|
user => "root",
|
|
group => "root",
|
|
mode => "0644",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { backup_file => $backup_file }});
|
|
|
|
# Copy this to our peers.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0753"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0753",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
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};
|
|
next if $host_uuid eq $anvil->Get->host_uuid;
|
|
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $destination = "root\@".$use_ip.":".$anvil->data->{path}{directories}{drbd_resources}."/";
|
|
$destination =~ s/\/\//\//g;
|
|
my $variables = {
|
|
resource_file => $drbd_res_file,
|
|
host_name => $short_host_name,
|
|
destination => $destination,
|
|
use_ip => $use_ip,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0754", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0754",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
use_ip => $use_ip,
|
|
destination => $destination,
|
|
}});
|
|
|
|
my $failed = $anvil->Storage->rsync({
|
|
debug => 2,
|
|
destination => $destination,
|
|
source => $drbd_res_file,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
|
|
|
|
if ($failed)
|
|
{
|
|
# There was a problem copying the new config file!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0431"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0431",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
}
|
|
|
|
# Create the metadata.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0755"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0755",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
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};
|
|
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." --force create-md --max-peers=3 ".$drbd_resource."/".$next_drbd_volume;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:shell_call' => $shell_call,
|
|
}});
|
|
|
|
# Create the metadata, but don't exit on failure in case the metadata was created in
|
|
# a previous pass.
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
my $variables = { next_drbd_volume => $next_drbd_volume };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0758", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0758",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
### Return codes
|
|
# 0 == Success
|
|
# 1 == ?
|
|
# 3 == Configuration not found.
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "alert", key => "warning_0160", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "warning_0160",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Create the meta-data on the peer
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $use_network = $anvil->data->{peer}{$short_host_name}{access}{network};
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0759", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0759",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
error => $error,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "alert", key => "warning_0161", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "warning_0161",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### NOTE: The call to 'drbdadm adjust <res>' hangs, hard, until the same command is run on the peers.
|
|
### To deal with this, we register jobs to run 'anvil-special-operations' on the peers, then we
|
|
### call adjust here.
|
|
# Adjust to start/connect.
|
|
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};
|
|
my $shell_call = $anvil->data->{path}{exe}{'anvil-special-operations'}." --task refresh-drbd-resource --resource ".$drbd_resource.$anvil->Log->switches;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:shell_call' => $shell_call,
|
|
}});
|
|
next if $host_uuid eq $anvil->Get->host_uuid;
|
|
|
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
|
|
debug => 2,
|
|
job_command => $shell_call,
|
|
job_data => "adjust=".$drbd_resource,
|
|
job_name => "server::add_disk::rescan",
|
|
job_title => "job_0465",
|
|
job_description => "job_0466",
|
|
job_progress => 0,
|
|
job_host_uuid => $host_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
|
|
|
|
# Record that we registered the job to reload the resource
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
job_uuid => $job_uuid,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0760", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0760",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
|
|
# Warn the user to check that anvil-daemon is running in case this hangs.
|
|
$variables = { drbd_resource => $drbd_resource };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0761", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0761",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$shell_call = $anvil->data->{path}{exe}{drbdadm}." adjust ".$drbd_resource;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
($output, $return_code) = $anvil->System->call({
|
|
background => 1,
|
|
shell_call => $shell_call,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Find which node is currently Primary and use that host to force primary to start sync. If none,
|
|
# force here.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0762"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0762",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $waiting = 1;
|
|
my $wait_until = time + 300;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { wait_until => $wait_until }});
|
|
while ($waiting)
|
|
{
|
|
$anvil->DRBD->get_status({debug => 2});
|
|
my $peers_connected = 1;
|
|
my $disks_ready = 0;
|
|
my $drbd_peer_count = keys %{$anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_peer_count => $drbd_peer_count }});
|
|
if (not $drbd_peer_count)
|
|
{
|
|
$peers_connected = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peers_connected => $peers_connected }});
|
|
}
|
|
foreach my $this_host_name (sort {$a cmp $b} keys %{$anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}})
|
|
{
|
|
my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $this_host_name});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:this_host_name' => $this_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
}});
|
|
next if $host_uuid eq $anvil->Get->host_uuid;
|
|
|
|
my $connection_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$this_host_name}{'connection-state'};
|
|
my $node_id = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$this_host_name}{'peer-node-id'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:connection_state' => $connection_state,
|
|
's2:node_id' => $node_id,
|
|
}});
|
|
|
|
if (lc($connection_state) ne "connected")
|
|
{
|
|
$peers_connected = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peers_connected => $peers_connected }});
|
|
}
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peers_connected => $peers_connected }});
|
|
if ($peers_connected)
|
|
{
|
|
# Make sure all disks are attached.
|
|
$disks_ready = 1;
|
|
$anvil->data->{peers}{$short_host_name}{disk_state} = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{devices}{volume}{$next_drbd_volume}{'disk-state'};
|
|
$anvil->data->{peers}{$short_host_name}{role} = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{role};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"peers::${short_host_name}::disk_state" => $anvil->data->{peers}{$short_host_name}{disk_state},
|
|
"peers::${short_host_name}::role" => $anvil->data->{peers}{$short_host_name}{role},
|
|
}});
|
|
foreach my $peer_name (sort {$a cmp $b} keys %{$anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}})
|
|
{
|
|
next if not defined $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{volume}{$next_drbd_volume}{'peer-disk-state'};
|
|
my $peer_disk_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{volume}{$next_drbd_volume}{'peer-disk-state'};
|
|
my $replication_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{volume}{$next_drbd_volume}{'replication-state'};
|
|
my $role = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{'peer-role'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:peer_name' => $peer_name,
|
|
's2:peer_disk_state' => $peer_disk_state,
|
|
's3:replication_state' => $replication_state,
|
|
's4:role' => $role,
|
|
}});
|
|
|
|
# If the volume is 'Negotiating', disconnect and reconnect the peer.
|
|
if (lc($peer_disk_state) eq "negotiating")
|
|
{
|
|
print "- Problem!\n";
|
|
($peer_disk_state, $role, $progress) = reconnect_resource($anvil, $short_host_name, $peer_name, $drbd_resource, $next_drbd_volume, $progress);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
peer_disk_state => $peer_disk_state,
|
|
role => $role,
|
|
}});
|
|
|
|
$disks_ready = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
}
|
|
|
|
# If it's not established, keep waiting
|
|
if (lc($replication_state) ne "established")
|
|
{
|
|
$disks_ready = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
}
|
|
if ((not $peer_disk_state) or (lc($peer_disk_state) eq "diskless"))
|
|
{
|
|
$disks_ready = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
}
|
|
|
|
$anvil->data->{peers}{$peer_name}{disk_state} = $peer_disk_state;
|
|
$anvil->data->{peers}{$peer_name}{role} = $role;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"peers::${peer_name}::disk_state" => $anvil->data->{peers}{$peer_name}{disk_state},
|
|
}});
|
|
}
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
if ($disks_ready)
|
|
{
|
|
$waiting = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
|
|
}
|
|
else
|
|
{
|
|
if (time > $wait_until)
|
|
{
|
|
# The peers did not connect in the expected period of time.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0432"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0432",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
sleep 2;
|
|
}
|
|
}
|
|
|
|
# Peers are connected! Checking if the new volume requires initial sync.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0763"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0763",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $all_inconsistent = 1;
|
|
my $primary_on_host = "";
|
|
foreach my $peer_name (sort {$a cmp $b} keys %{$anvil->data->{peers}})
|
|
{
|
|
my $disk_state = $anvil->data->{peers}{$peer_name}{disk_state};
|
|
my $role = $anvil->data->{peers}{$peer_name}{role};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
peer_name => $peer_name,
|
|
disk_state => $disk_state,
|
|
role => $role,
|
|
}});
|
|
|
|
if (lc($disk_state) ne "inconsistent")
|
|
{
|
|
$all_inconsistent = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_inconsistent => $all_inconsistent }});
|
|
}
|
|
if (lc($role) eq "primary")
|
|
{
|
|
$primary_on_host = $peer_name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { primary_on_host => $primary_on_host }});
|
|
}
|
|
}
|
|
|
|
if ($all_inconsistent)
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0764"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0764",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." new-current-uuid --force-resync ".$drbd_resource."/".$next_drbd_volume;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
# Which node should be forced primary?
|
|
my $already_primary = 1;
|
|
if (not $primary_on_host)
|
|
{
|
|
# We'll make it primary.
|
|
$primary_on_host = $short_host_name;
|
|
$already_primary = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
primary_on_host => $primary_on_host,
|
|
already_primary => $already_primary,
|
|
}});
|
|
}
|
|
|
|
my $primary_on_host_uuid = $anvil->Get->host_uuid_from_name({host_name => $primary_on_host});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { primary_on_host_uuid => $primary_on_host_uuid }});
|
|
if ($primary_on_host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
# Forcing primary locally...
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0765"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0765",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $return_code) = $anvil->System->call({debug => 2, shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
# Return code of '0' is success.
|
|
if ($return_code)
|
|
{
|
|
# There was a problem trying to force the new volume to Primary.
|
|
my $variables = {
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0430", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0430",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Now demote it again.
|
|
$shell_call = $anvil->data->{path}{exe}{drbdadm}." secondary ".$drbd_resource;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
# Success!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0752"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0752",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $use_network = $anvil->data->{peer}{$short_host_name}{access}{network};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
}});
|
|
# The resource is primary on the peer, force Primary over there.
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0766", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0766",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0430", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0430",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Now demote it again.
|
|
$shell_call = $anvil->data->{path}{exe}{drbdadm}." secondary ".$drbd_resource;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
# Success!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0752"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0752",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Initial sync does not appear to be required.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0767"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0767",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
|
|
# Is the server running? If so, where.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0768"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0768",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $server_host = "";
|
|
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};
|
|
my $shell_call = $anvil->data->{path}{exe}{'anvil-special-operations'}." --task refresh-drbd-resource --resource ".$drbd_resource.$anvil->Log->switches;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:shell_call' => $shell_call,
|
|
}});
|
|
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
$anvil->Server->find();
|
|
}
|
|
else
|
|
{
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
$anvil->Server->find({target => $use_ip });
|
|
}
|
|
|
|
if ((exists $anvil->data->{server}{location}{$server_name}) &&
|
|
($anvil->data->{server}{location}{$server_name}{host_name}))
|
|
{
|
|
my $this_host = defined $anvil->data->{server}{location}{$server_name}{host_name} ? $anvil->data->{server}{location}{$server_name}{host_name} : "";
|
|
my $server_status = defined $anvil->data->{server}{location}{$server_name}{status} ? $anvil->data->{server}{location}{$server_name}{status} : "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
this_host => $this_host,
|
|
server_status => $server_status,
|
|
}});
|
|
if ($server_status eq "running")
|
|
{
|
|
# Found it.
|
|
$server_host = $this_host;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host => $server_host }});
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
# The server is running on this host, we'll attach the disk here.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0769"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0769",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# The server is running on the peer, we'll attach the disk there.
|
|
my $variables = { server_host => $server_host };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0770", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0770",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $offline = 0;
|
|
if (not $server_host)
|
|
{
|
|
# The server isn't running anywhere, we'll attach the disk offline on this host.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0771"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0771",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$server_host = $short_host_name;
|
|
$offline = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
server_host => $server_host,
|
|
offline => $offline,
|
|
}});
|
|
}
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." attach-disk ".$server_name." ";
|
|
$shell_call .= "/dev/drbd/by-res/".$drbd_resource."/".$next_drbd_volume." ".$new_device_target." ";
|
|
$shell_call .= "--persistent --targetbus ".$disk_device_bus." ";
|
|
$shell_call .= "--cache ".$disk_cache." ";
|
|
$shell_call .= "--io ".$disk_io_policy." ";
|
|
$shell_call .= "--sourcetype block --subdriver raw";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
offline => $offline,
|
|
shell_call => $shell_call,
|
|
}});
|
|
if ($offline)
|
|
{
|
|
# Define the VM, if needed, then add the drive, dump the config and push it out.
|
|
my $variables = { server_name => $server_name };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0772", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0772",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "define", "");
|
|
|
|
# Update the definition.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0773"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0773",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Updating the stored definition and undefining the server now...
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0774"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0774",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "undefine", "");
|
|
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
else
|
|
{
|
|
# Add the drive live, dump the new definition and push it out.
|
|
my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $server_host});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }});
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
# Do the add here.
|
|
update_definition($anvil, "define", "");
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0775"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0775",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
# Something went wrong.
|
|
my $variables = {
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0138", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0138",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Get the new XML
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0776"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0776",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
(my $virsh_definition, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
virsh_definition => $virsh_definition,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Make sure the $output is valid XML.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0777"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0777",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $problem = $anvil->Server->parse_definition({
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $virsh_definition,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
|
|
if ($problem)
|
|
{
|
|
# Failed?!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0434"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0434",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Update the stored definition and undefining the server
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0778"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0778",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "undefine", $virsh_definition);
|
|
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
else
|
|
{
|
|
# Do the add on the target.
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $variables = {
|
|
server_host => $server_host,
|
|
use_ip => $use_ip,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0779", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0779",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Get the updated definition file.
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
(my $virsh_definition, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
virsh_definition => $virsh_definition,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Make sure the $output is valid XML.
|
|
my $problem = $anvil->Server->parse_definition({
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $virsh_definition,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
|
|
if ($problem)
|
|
{
|
|
# Failed?!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0435"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0435",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
$anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml} = $virsh_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"server::${short_host_name}::${server_name}::from_virsh::xml" => $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml},
|
|
}});
|
|
|
|
# Updating the stored definition and undefining the server
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0780"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0780",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "undefine", $virsh_definition);
|
|
|
|
# Done!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub reconnect_resource
|
|
{
|
|
my ($anvil, $short_host_name, $peer_name, $drbd_resource, $next_drbd_volume, $progress) = @_;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
short_host_name => $short_host_name,
|
|
peer_name => $peer_name,
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
progress => $progress,
|
|
}});
|
|
|
|
my $peer_disk_state = "";
|
|
my $role = "";
|
|
|
|
# Log into the peer and disconnect, then reconnect. Then wait for the disk state to update, and
|
|
# return the disk state.
|
|
my $variables = { peer_name => $peer_name };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0781", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0781",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
my $use_ip = $anvil->data->{peer}{$peer_name}{access}{ip};
|
|
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." disconnect ".$drbd_resource;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
use_ip => $use_ip,
|
|
shell_call => $shell_call,
|
|
}});
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0782"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0782",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
sleep 1;
|
|
$shell_call = $anvil->data->{path}{exe}{drbdadm}." connect ".$drbd_resource;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
use_ip => $use_ip,
|
|
shell_call => $shell_call,
|
|
}});
|
|
($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
# Now wait
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0783"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0783",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $waiting = 1;
|
|
my $wait_until = time + 300;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { wait_until => $wait_until }});
|
|
while ($waiting)
|
|
{
|
|
$anvil->DRBD->get_status({debug => 2});
|
|
my $disks_ready = 1;
|
|
my $connection_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{'connection-state'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connection_state => $connection_state }});
|
|
if (lc($connection_state) eq "connected")
|
|
{
|
|
# Connected, what's the disk state for the new volume now?
|
|
my $variables = {
|
|
drbd_resource => $drbd_resource,
|
|
next_drbd_volume => $next_drbd_volume,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0784", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0784",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$peer_disk_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{volume}{$next_drbd_volume}{'peer-disk-state'};
|
|
my $replication_state = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{volume}{$next_drbd_volume}{'replication-state'};
|
|
$role = $anvil->data->{drbd}{status}{$short_host_name}{resource}{$drbd_resource}{connection}{$peer_name}{'peer-role'};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:peer_disk_state' => $peer_disk_state,
|
|
's2:replication_state' => $replication_state,
|
|
's3:role' => $role,
|
|
}});
|
|
|
|
if (lc($replication_state) ne "established")
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0785"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0785",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$disks_ready = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
}
|
|
elsif ((not $peer_disk_state) or (lc($peer_disk_state) eq "diskless"))
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0786"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0786",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$disks_ready = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disks_ready => $disks_ready }});
|
|
}
|
|
|
|
if ($disks_ready)
|
|
{
|
|
my $variables = { peer_disk_state => $peer_disk_state };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0787", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0787",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$waiting = 0;
|
|
$anvil->data->{peers}{$peer_name}{disk_state} = $peer_disk_state;
|
|
$anvil->data->{peers}{$peer_name}{role} = $role;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
waiting => 0,
|
|
"peers::${peer_name}::disk_state" => $anvil->data->{peers}{$peer_name}{disk_state},
|
|
"peers::${peer_name}::role" => $anvil->data->{peers}{$peer_name}{role},
|
|
}});
|
|
|
|
return($peer_disk_state, $role);
|
|
}
|
|
}
|
|
|
|
if (time > $wait_until)
|
|
{
|
|
# Timed out waiting for the peer to connect.
|
|
$waiting = 0;
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0788"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0788",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
return($peer_disk_state, $role, $progress);
|
|
}
|
|
sleep 3;
|
|
}
|
|
|
|
return($peer_disk_state, $role, $progress);
|
|
}
|
|
|
|
sub manage_disk_grow
|
|
{
|
|
my ($anvil, $drbd_resource, $drbd_volume, $max_free_space) = @_;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:drbd_resource' => $drbd_resource,
|
|
's2:drbd_volume' => $drbd_volume,
|
|
's3:max_free_space' => $max_free_space,
|
|
}});
|
|
|
|
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_anvil_uuid();
|
|
my $short_host_name = $anvil->Get->short_host_name;
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
my $from_source = get_definition_source($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
anvil_uuid => $anvil_uuid,
|
|
short_host_name => $short_host_name,
|
|
server_name => $server_name,
|
|
from_source => $from_source,
|
|
}});
|
|
|
|
# Are they asking for an available amount of space?
|
|
my $add_size = $anvil->data->{switches}{grow};
|
|
$add_size =~ s/^\+//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
if ($add_size =~ /^(\d+)%$/)
|
|
{
|
|
# This is valid
|
|
my $percent = ".".$1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { percent => $percent }});
|
|
|
|
$add_size = int($max_free_space * $percent);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
elsif ($add_size !~ /\d/)
|
|
{
|
|
# No digits, probably didn't set a value at all.
|
|
my $variables = {
|
|
max_free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}),
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0436", variables => $variables});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0789"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0436",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0789",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
elsif ($add_size !~ /^\d+$/)
|
|
{
|
|
# Size is not in bytes, try to convert it.
|
|
my $bytes = $anvil->Convert->human_readable_to_bytes({
|
|
debug => 2,
|
|
size => $add_size,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'bytes' => $bytes }});
|
|
if ($bytes =~ /^\d+$/)
|
|
{
|
|
$add_size = $bytes;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
else
|
|
{
|
|
# Not a valid size.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0424"});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0789"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0424",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0789",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
# Make sure they're asking for a reasonable size
|
|
if ($add_size < 4194304)
|
|
{
|
|
# Must be a typo, this is less than the size of a single extent.
|
|
my $variables = {
|
|
add_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $add_size}),
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0438", variables => $variables});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0789"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0438",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0789",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
elsif ($add_size > $max_free_space)
|
|
{
|
|
# Not enough space.
|
|
my $variables = {
|
|
add_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $add_size}),
|
|
max_free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}),
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0439", variables => $variables});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0789"});
|
|
$anvil->Job->update_progress({
|
|
progress => 99,
|
|
message => "error_0439",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0789",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Are they asking for an available amount of space?
|
|
my $say_up = $anvil->Words->string({key => 'message_0331'});
|
|
my $say_down = $anvil->Words->string({key => 'message_0332'});
|
|
|
|
### TODO: Make this work without the peer node being online.
|
|
# The server is allowed to be running, but both nodes and any DR hosts this is replicating to
|
|
# needs to be online.
|
|
my $all_online = check_drbd_peer_access($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_online => $all_online }});
|
|
|
|
if (not $all_online)
|
|
{
|
|
# All peers have to be online.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0440"});
|
|
$anvil->Job->update_progress({
|
|
progress => 90,
|
|
message => "error_0440",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $progress = 90;
|
|
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{peer}})
|
|
{
|
|
my $say_access = $anvil->data->{peer}{$short_host_name}{access_ip} ? $say_up : $say_down;
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
access => $say_access,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0428", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ++$progress,
|
|
message => "error_0428",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "job_0471",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Still here? We're good to go.
|
|
my $lv_command_size = 0;
|
|
my $hr_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $add_size});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { hr_size => $hr_size }});
|
|
if ($add_size eq "100%")
|
|
{
|
|
# This is valid
|
|
$add_size = "-l +100\%FREE";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
else
|
|
{
|
|
$hr_size =~ s/\s+//g;
|
|
$add_size = "-L +".$hr_size;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { add_size => $add_size }});
|
|
}
|
|
|
|
# Preparing to grow the storage
|
|
my $variables = { size => $hr_size };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0790", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 15,
|
|
message => "log_0790",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
if ((not $anvil->data->{switches}{confirm}) && (not $anvil->data->{switches}{'job-uuid'}))
|
|
{
|
|
print $anvil->Words->string({key => "message_0021"})." ";
|
|
my $answer = <STDIN>;
|
|
chomp($answer);
|
|
if ($answer !~ /^y/i)
|
|
{
|
|
# Abort
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0022"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "message_0022",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
|
|
# Test that we've lost access while waiting for the answer.
|
|
my $all_online = check_drbd_peer_access($anvil);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_online => $all_online }});
|
|
|
|
if (not $all_online)
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0441"});
|
|
$anvil->Job->update_progress({
|
|
progress => 90,
|
|
message => "error_0441",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $progress = 90;
|
|
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{peer}})
|
|
{
|
|
my $say_access = $anvil->data->{peer}{$short_host_name}{access_ip} ? $say_up : $say_down;
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
access => $say_access,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0428", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ++$progress,
|
|
message => "error_0428",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "job_0471",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
my $progress = 16;
|
|
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};
|
|
my $backing_disk = $anvil->data->{new}{resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$drbd_volume}{backing_disk};
|
|
my $shell_call = $anvil->data->{path}{exe}{lvextend}." ".$add_size." ".$backing_disk;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:backing_disk' => $backing_disk,
|
|
's4:shell_call' => $shell_call,
|
|
}});
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
my $variables = { backing_disk => $backing_disk };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0791", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0791",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
backing_disk => $backing_disk,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0442", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0442",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $use_network = $anvil->data->{peer}{$short_host_name}{access}{network};
|
|
my $variables = {
|
|
host_name => $short_host_name,
|
|
backing_disk => $backing_disk,
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0792", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0792",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
backing_disk => $backing_disk,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
error => $error,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0443", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0443",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Locally, we'll call DRBD to resize.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0793"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0793",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." resize ".$drbd_resource."/".$drbd_volume;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($return_code)
|
|
{
|
|
my $variables = {
|
|
drbd_resource => $drbd_resource,
|
|
drbd_volume => $drbd_volume,
|
|
shell_call => $shell_call,
|
|
return_code => $return_code,
|
|
output => $output,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0444", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0444",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
|
|
# Call scan-lvm and scan-drbd to make sure the databases are updated.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0794"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0794",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
foreach my $agent ("scan-drbd", "scan-lvm")
|
|
{
|
|
my $variables = { agent => $agent };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0740", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0740",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
my $shell_call = $anvil->data->{path}{directories}{scan_agents}."/".$agent."/".$agent.$anvil->Log->switches();
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
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,
|
|
}});
|
|
if ($host_uuid eq $anvil->Get->host_uuid)
|
|
{
|
|
my $variables = { agent => $agent };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0795", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0795",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
my $use_ip = $anvil->data->{peer}{$short_host_name}{access}{ip};
|
|
my $use_network = $anvil->data->{peer}{$short_host_name}{access}{network};
|
|
my $variables = {
|
|
agent => $agent,
|
|
host_name => $short_host_name,
|
|
use_ip => $use_ip,
|
|
use_network => $use_network,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0796", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0796",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
my ($output, $error, $return_code) = $anvil->Remote->call({
|
|
shell_call => $shell_call,
|
|
target => $use_ip,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
error => $error,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => ($progress += 2),
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Success!
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0797"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0797",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub manage_optical
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
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 $from_source = get_definition_source($anvil);
|
|
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
|
|
$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,
|
|
from_source => $from_source,
|
|
anvil_uuid => $anvil_uuid,
|
|
}});
|
|
|
|
if (not $anvil->data->{switches}{optical})
|
|
{
|
|
# If there's only one optical drive, select it automatically
|
|
my $count = keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
if ($count == 1)
|
|
{
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}})
|
|
{
|
|
$anvil->data->{switches}{optical} = $device_target;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::drive" => $anvil->data->{switches}{optical},
|
|
}});
|
|
last;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}})
|
|
{
|
|
my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{path};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
device_target => $device_target,
|
|
device_path => $device_path,
|
|
}});
|
|
}
|
|
}
|
|
|
|
if (not $anvil->data->{switches}{optical})
|
|
{
|
|
# Can't proceed.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0445"});
|
|
show_server_details($anvil, 1);
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0445",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
# If the device target isn't specified but there's only one disc drive, select it.
|
|
if ((not $anvil->data->{switches}{optical}) or ($anvil->data->{switches}{optical} eq "#!SET!#"))
|
|
{
|
|
my $device_count = keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_count => $device_count }});
|
|
|
|
if ($device_count == 1)
|
|
{
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}})
|
|
{
|
|
$anvil->data->{switches}{optical} = $device_target;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::optical" => $anvil->data->{switches}{optical},
|
|
}});
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
# If the user specified a disc to insert using just the file name, prepend the directory.
|
|
if ($anvil->data->{switches}{insert})
|
|
{
|
|
my $iso = $anvil->data->{switches}{insert};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { iso => $iso }});
|
|
if ($iso !~ /^\//)
|
|
{
|
|
foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}})
|
|
{
|
|
my $file_location_file_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}{$file_name}{file_uuid};
|
|
my $file_directory = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_directory};
|
|
my $full_path = $file_directory."/".$file_name;
|
|
my $file_size = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_size};
|
|
my $file_md5sum = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_md5sum};
|
|
my $file_type = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_type};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:file_name' => $file_name,
|
|
's2:file_directory' => $file_directory,
|
|
's3:full_path' => $full_path,
|
|
's4:file_size' => $file_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}).")",
|
|
's5:file_md5sum' => $file_md5sum,
|
|
's6:file_type' => $file_type,
|
|
}});
|
|
next if $iso ne $file_name;
|
|
next if $file_type ne "iso";
|
|
|
|
if (-f $full_path)
|
|
{
|
|
# Use this.
|
|
$anvil->data->{switches}{insert} = $full_path;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::insert" => $anvil->data->{switches}{insert},
|
|
}});
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $device_target = $anvil->data->{switches}{optical};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_target => $device_target }});
|
|
|
|
if ((not $anvil->data->{switches}{optical}) or ($anvil->data->{switches}{optical} eq "#!SET!#"))
|
|
{
|
|
# User didn't specify a device.
|
|
show_server_details($anvil, 0);
|
|
show_files($anvil);
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0446"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0446",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
elsif (not exists $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target})
|
|
{
|
|
# Invalid device target
|
|
show_server_details($anvil, 0);
|
|
show_files($anvil);
|
|
my $variables = { device_target => $device_target };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0447", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0447",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $eject_first = 0;
|
|
my $alias = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{alias};
|
|
my $boot_order = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{boot_order};
|
|
my $say_boot = $boot_order eq "99" ? "--" : sprintf("%02d", $boot_order);
|
|
my $type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{type};
|
|
my $address_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{address}{type};
|
|
my $address_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{address}{bus};
|
|
my $driver_name = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{driver}{name};
|
|
my $device_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{device_bus};
|
|
my $driver_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{driver}{type};
|
|
my $address_controller = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{address}{controller};
|
|
my $address_unit = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{address}{unit};
|
|
my $address_target = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{address}{target};
|
|
my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{cdrom}{target}{$device_target}{path};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:device_target' => $device_target,
|
|
's02:alias' => $alias,
|
|
's03:boot_order' => $boot_order,
|
|
's04:say_boot' => $say_boot,
|
|
's05:type' => $type,
|
|
's06:address_type' => $address_type,
|
|
's07:address_bus' => $address_bus,
|
|
's08:driver_name' => $driver_name,
|
|
's09:device_bus' => $device_bus,
|
|
's10:driver_type' => $driver_type,
|
|
's11:address_controller' => $address_controller,
|
|
's12:address_unit' => $address_unit,
|
|
's13:address_target' => $address_target,
|
|
's14:device_path' => $device_path,
|
|
}});
|
|
|
|
# Without a --source, the result is an eject.
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." change-media ".$server_name." --path ".$device_target." --update --live --config";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
if ($anvil->data->{switches}{insert})
|
|
{
|
|
# Make sure the new target exists.
|
|
my $iso = $anvil->data->{switches}{insert};
|
|
if (not -f $iso)
|
|
{
|
|
my $variables = { iso => $iso };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0448", variables => $variables});
|
|
update_definition($anvil, "undefine", "");
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0448",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
else
|
|
{
|
|
$shell_call .= " --source ".$anvil->data->{switches}{insert};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
}
|
|
}
|
|
|
|
# If the server is running, update the on-disk and in-DB definition.
|
|
my $variables = { server_name => $server_name };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0798", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 25,
|
|
message => "log_0798",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "define", "");
|
|
|
|
# Now we can modify the server using virsh.
|
|
if ($anvil->data->{switches}{insert})
|
|
{
|
|
# Inserting
|
|
my $variables = {
|
|
insert => $anvil->data->{switches}{insert},
|
|
device_target => $device_target,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0799", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 50,
|
|
message => "log_0799",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
elsif ($anvil->data->{switches}{eject})
|
|
{
|
|
# Ejecting
|
|
my $variables = {
|
|
device_path => $device_path,
|
|
device_target => $device_target,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0800", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 50,
|
|
message => "log_0800",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# Show the ISO in the drive.
|
|
if ($device_path)
|
|
{
|
|
# Disc is already in the drive
|
|
my $variables = {
|
|
device_target => $device_target,
|
|
device_path => $device_path,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0449", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0449",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# Drive has no disc in it.
|
|
my $variables = { device_target => $device_target };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0450", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0450",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
my ($output, $return_code) = $anvil->System->call({debug => 2, shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:output' => $output,
|
|
's2:return_code' => $return_code,
|
|
}});
|
|
|
|
# Updating the stored definition and undefining the server now
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0801"});
|
|
$anvil->Job->update_progress({
|
|
progress => 75,
|
|
message => "log_0801",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
update_definition($anvil, "undefine", "");
|
|
|
|
# Done
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0750"});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "log_0750",
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub get_definition_source
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
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,
|
|
}});
|
|
|
|
$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 }});
|
|
}
|
|
elsif (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk})
|
|
{
|
|
$from_source = "from_disk";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }});
|
|
}
|
|
else
|
|
{
|
|
$from_source = "from_db";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }});
|
|
}
|
|
|
|
return($from_source);
|
|
}
|
|
|
|
sub show_server_details
|
|
{
|
|
my ($anvil, $show_nodes) = @_;
|
|
|
|
my $short_host_name = $anvil->Get->short_host_name;
|
|
my $host_uuid = $anvil->Get->host_uuid;
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:server_name' => $server_name,
|
|
's4:show_nodes' => $show_nodes,
|
|
}});
|
|
|
|
# Load storage data
|
|
my $drbd_resource = load_storage($anvil);
|
|
|
|
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")
|
|
{
|
|
if ($device eq "disk")
|
|
{
|
|
# Disk drives
|
|
print "\n".$anvil->Words->string({key => "message_0334"})."\n";
|
|
}
|
|
else
|
|
{
|
|
# Optical drives
|
|
print "\n".$anvil->Words->string({key => "message_0335"})."\n";
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device => $device }});
|
|
next if $device ne "cdrom" && $device ne "disk";
|
|
foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}})
|
|
{
|
|
my $alias = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{alias};
|
|
my $boot_order = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{boot_order};
|
|
my $say_boot = $boot_order eq "99" ? "--" : sprintf("%02d", $boot_order);
|
|
my $type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{type};
|
|
my $address_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{type};
|
|
my $address_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{bus};
|
|
my $driver_name = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{name};
|
|
my $device_bus = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{device_bus};
|
|
my $driver_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{type};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:device_target' => $device_target,
|
|
's02:alias' => $alias,
|
|
's03:boot_order' => $boot_order,
|
|
's04:say_boot' => $say_boot,
|
|
's05:type' => $type,
|
|
's06:address_type' => $address_type,
|
|
's07:address_bus' => $address_bus,
|
|
's08:driver_name' => $driver_name,
|
|
's09:device_bus' => $device_bus,
|
|
's10:driver_type' => $driver_type,
|
|
}});
|
|
if ($device eq "disk")
|
|
{
|
|
my $address_domain = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{domain};
|
|
my $address_slot = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{slot};
|
|
my $address_function = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{function};
|
|
my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path};
|
|
my $driver_io = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{io};
|
|
my $driver_cache = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{driver}{cache};
|
|
my $on_lv = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{on_lv};
|
|
my $drbd_resource = $anvil->data->{server}{$short_host_name}{$server_name}{device}{$device_path}{resource};
|
|
my $drbd_volume = $anvil->data->{lvm}{host_name}{$short_host_name}{lv_path}{$on_lv}{drbd}{volume};
|
|
my $resource_size = $anvil->data->{drbd}{host_name}{$short_host_name}{resource_name}{$drbd_resource}{volume}{$drbd_volume}{volume_size};
|
|
my $lv_name = $anvil->data->{lvm}{host_name}{$short_host_name}{lv_path}{$on_lv}{scan_lvm_lv_name};
|
|
my $lv_size = $anvil->data->{lvm}{host_name}{$short_host_name}{lv}{$lv_name}{scan_lvm_lv_size};
|
|
my $metadata_size = $lv_size - $resource_size;
|
|
my $max_free_space = get_max_free_space($anvil, $drbd_resource, $drbd_volume);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:address_domain' => $address_domain,
|
|
's02:address_slot' => $address_slot,
|
|
's03:address_function' => $address_function,
|
|
's04:device_path' => $device_path,
|
|
's05:driver_io' => $driver_io,
|
|
's06:driver_cache' => $driver_cache,
|
|
's07:on_lv' => $on_lv,
|
|
's08:lv_name' => $lv_name,
|
|
's09:drbd_resource' => $drbd_resource,
|
|
's10:drbd_volume' => $drbd_volume,
|
|
's11:resource_size' => $anvil->Convert->bytes_to_human_readable({'bytes' => $resource_size})." (".$anvil->Convert->add_commas({number => $resource_size}).")",
|
|
's12:lv_size' => $anvil->Convert->bytes_to_human_readable({'bytes' => $lv_size})."] (".$anvil->Convert->add_commas({number => $lv_size}).")",
|
|
's13:metadata_size' => $anvil->Convert->bytes_to_human_readable({'bytes' => $metadata_size})."] (".$anvil->Convert->add_commas({number => $metadata_size}).")",
|
|
's14:max_free_space' => $max_free_space." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}).")",
|
|
}});
|
|
|
|
print $anvil->Words->string({key => "message_0336", variables => {
|
|
device_target => $device_target,
|
|
say_boot => $say_boot,
|
|
drbd_resource => $drbd_resource,
|
|
drbd_volume => $drbd_volume,
|
|
}})."\n";
|
|
print $anvil->Words->string({key => "message_0337", variables => {
|
|
resource_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $resource_size}),
|
|
lv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $lv_size}),
|
|
metadata_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $metadata_size}),
|
|
max_free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}),
|
|
}})."\n";
|
|
#print " |- Resource / LV / Metadata sizes: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $resource_size})." / ".$anvil->Convert->bytes_to_human_readable({'bytes' => $lv_size})." / ".$anvil->Convert->bytes_to_human_readable({'bytes' => $metadata_size})."], free space: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space})."], cache: [".$driver_cache."], IO Policy: [".$driver_io."]\n";
|
|
}
|
|
else
|
|
{
|
|
my $address_controller = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{controller};
|
|
my $address_unit = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{unit};
|
|
my $address_target = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{address}{target};
|
|
my $device_path = "<empty>";
|
|
if (defined $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path})
|
|
{
|
|
$device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path};
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:address_controller' => $address_controller,
|
|
's2:address_unit' => $address_unit,
|
|
's3:address_target' => $address_target,
|
|
's4:device_path' => $device_path,
|
|
}});
|
|
print $anvil->Words->string({key => "message_0338", variables => {
|
|
device_target => $device_target,
|
|
say_boot => $say_boot,
|
|
device_path => $device_path,
|
|
}})."\n";
|
|
}
|
|
}
|
|
}
|
|
print "\n";
|
|
|
|
if ($show_nodes)
|
|
{
|
|
print $anvil->Words->string({key => "message_0339"})."\n";
|
|
show_volume($anvil, $drbd_resource, "node");
|
|
|
|
my $dr_count = keys %{$anvil->data->{drbd_resource}{$drbd_resource}{host_type}{dr}{short_host_name}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dr_count => $dr_count }});
|
|
if ($dr_count)
|
|
{
|
|
print $anvil->Words->string({key => "message_0340"})."\n";
|
|
show_volume($anvil, $drbd_resource, "dr");
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub check_drbd_peer_access
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
my $all_online = 1;
|
|
foreach my $this_host (sort {$a cmp $b} keys %{$anvil->data->{drbd}{drbd_node}})
|
|
{
|
|
my $host_uuid = $anvil->Get->host_uuid_from_name({host_name => $this_host});
|
|
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:this_host' => $this_host,
|
|
's2:host_uuid' => $host_uuid,
|
|
's3:short_host_name' => $short_host_name,
|
|
}});
|
|
next if $host_uuid eq $anvil->Get->host_uuid;
|
|
|
|
# This is used to store the IP we used to access the peer. If no access is available, this
|
|
# shows which hosts are not available.
|
|
$anvil->data->{peer}{$short_host_name}{access_ip} = "";
|
|
$anvil->data->{peer}{$short_host_name}{access_network} = "";
|
|
|
|
my $access = 0;
|
|
my $matches = $anvil->Network->find_access({
|
|
debug => 2,
|
|
target => $this_host,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { matches => $matches }});
|
|
foreach my $preferred_network ("bcn", "mn", "ifn", "sn", "any")
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { preferred_network => $preferred_network }});
|
|
foreach my $network_name (sort {$a cmp $b} keys %{$anvil->data->{network_access}})
|
|
{
|
|
next if $access;
|
|
if (($network_name !~ /^$preferred_network/) && ($preferred_network ne "any"))
|
|
{
|
|
next;
|
|
}
|
|
my $target_ip = $anvil->data->{network_access}{$network_name}{target_ip_address};
|
|
my $test_access = $anvil->Remote->test_access({target => $target_ip});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:network_name' => $network_name,
|
|
's2:target_ip' => $target_ip,
|
|
's3:test_access' => $test_access,
|
|
}});
|
|
|
|
if ($test_access)
|
|
{
|
|
# We're good.
|
|
$access = 1;
|
|
$anvil->data->{peer}{$short_host_name}{access}{ip} = $target_ip;
|
|
$anvil->data->{peer}{$short_host_name}{access}{network} = $network_name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:access' => $access,
|
|
"s2:peer::${short_host_name}::access::ip" => $anvil->data->{peer}{$short_host_name}{access}{ip},
|
|
"s3:peer::${short_host_name}::access::network" => $anvil->data->{peer}{$short_host_name}{access}{network},
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (not $access)
|
|
{
|
|
$all_online = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_online => $all_online }});
|
|
}
|
|
}
|
|
|
|
return($all_online);
|
|
}
|
|
|
|
sub get_max_free_space
|
|
{
|
|
my ($anvil, $drbd_resource, $drbd_volume) = @_;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:drbd_resource' => $drbd_resource,
|
|
's02:drbd_volume' => $drbd_volume,
|
|
}});
|
|
|
|
my $max_free_space = 0;
|
|
foreach my $this_host (sort {$a cmp $b} keys %{$anvil->data->{drbd}{drbd_node}})
|
|
{
|
|
my $drbd_path = $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$drbd_resource}{volume}{$drbd_volume}{drbd_path};
|
|
my $drbd_path_by_res = $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$drbd_resource}{volume}{$drbd_volume}{drbd_path_by_res};
|
|
my $backing_lv = $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$drbd_resource}{volume}{$drbd_volume}{backing_lv};
|
|
my $lv_name = $anvil->data->{lvm}{host_name}{$this_host}{lv_path}{$backing_lv}{scan_lvm_lv_name} ? $anvil->data->{lvm}{host_name}{$this_host}{lv_path}{$backing_lv}{scan_lvm_lv_name} : "";
|
|
my $on_vg = $anvil->data->{lvm}{host_name}{$this_host}{lv}{$lv_name}{scan_lvm_lv_on_vg} ? $anvil->data->{lvm}{host_name}{$this_host}{lv}{$lv_name}{scan_lvm_lv_on_vg} : "";
|
|
my $vg_free_space = $anvil->data->{lvm}{host_name}{$this_host}{vg}{$on_vg}{scan_lvm_vg_free} ? $anvil->data->{lvm}{host_name}{$this_host}{vg}{$on_vg}{scan_lvm_vg_free} : 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's01:this_host' => $this_host,
|
|
's02:drbd_path' => $drbd_path,
|
|
's03:drbd_path_by_res' => $drbd_path_by_res,
|
|
's04:backing_lv' => $backing_lv,
|
|
's05:on_vg' => $on_vg,
|
|
's06:vg_free_space' => $vg_free_space." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_free_space}).")",
|
|
}});
|
|
if ((not $max_free_space) or ($vg_free_space < $max_free_space))
|
|
{
|
|
$max_free_space = $vg_free_space;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
max_free_space => $max_free_space." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $max_free_space}).")",
|
|
}});
|
|
}
|
|
}
|
|
|
|
return($max_free_space);
|
|
}
|
|
|
|
sub load_drbd_data
|
|
{
|
|
my ($anvil, $drbd_resource) = @_;
|
|
|
|
my $query = "
|
|
SELECT
|
|
a.host_uuid,
|
|
b.scan_drbd_resource_xml,
|
|
c.scan_drbd_volume_number,
|
|
c.scan_drbd_volume_device_path,
|
|
c.scan_drbd_volume_device_minor,
|
|
c.scan_drbd_volume_size
|
|
FROM
|
|
hosts a,
|
|
scan_drbd_resources b,
|
|
scan_drbd_volumes c
|
|
WHERE
|
|
a.host_uuid = b.scan_drbd_resource_host_uuid
|
|
AND
|
|
b.scan_drbd_resource_uuid = c.scan_drbd_volume_scan_drbd_resource_uuid
|
|
AND
|
|
b.scan_drbd_resource_name = ".$anvil->Database->quote($drbd_resource)."
|
|
;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
|
|
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
|
|
my $count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $host_uuid = $row->[0];
|
|
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
|
|
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
|
|
my $scan_drbd_volume_number = $row->[2];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:host_uuid' => $host_uuid,
|
|
's2:host_type' => $host_type,
|
|
's3:short_host_name' => $short_host_name,
|
|
's4:scan_drbd_volume_number' => $scan_drbd_volume_number,
|
|
}});
|
|
|
|
$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{device_path} = $row->[3];
|
|
$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{device_minor} = $row->[4];
|
|
$anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{volume_size} = $row->[5];
|
|
$anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}{$short_host_name}{host_uuid} = $host_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"s1:drbd_resource::${drbd_resource}::host_uuid::${host_uuid}::volume_number::${scan_drbd_volume_number}::device_path" => $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{device_path},
|
|
"s2:drbd_resource::${drbd_resource}::host_uuid::${host_uuid}::volume_number::${scan_drbd_volume_number}::device_minor" => $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{device_minor},
|
|
"s3:drbd_resource::${drbd_resource}::host_uuid::${host_uuid}::volume_number::${scan_drbd_volume_number}::volume_size" => $anvil->data->{drbd_resource}{$drbd_resource}{host_uuid}{$host_uuid}{volume_number}{$scan_drbd_volume_number}{volume_size},
|
|
"s4:drbd_resource::${drbd_resource}::host_type::${host_type}::short_host_name::${short_host_name}::host_uuid" => $anvil->data->{drbd_resource}{$drbd_resource}{host_type}{$host_type}{short_host_name}{$short_host_name}{host_uuid},
|
|
}});
|
|
|
|
if (not exists $anvil->data->{drbd_resource}{$drbd_resource}{xml})
|
|
{
|
|
$anvil->data->{drbd_resource}{$drbd_resource}{xml} = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"drbd_resource::${drbd_resource}::xml" => $anvil->data->{drbd_resource}{$drbd_resource}{xml},
|
|
}});
|
|
$anvil->DRBD->parse_resource({
|
|
debug => 2,
|
|
xml => $anvil->data->{drbd_resource}{$drbd_resource}{xml},
|
|
});
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub show_volume
|
|
{
|
|
my ($anvil, $drbd_resource, $host_type) = @_;
|
|
|
|
my $anvil_uuid = defined $anvil->data->{switches}{anvil_uuid} ? $anvil->data->{switches}{anvil_uuid} : $anvil->Cluster->get_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};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:host_uuid' => $host_uuid,
|
|
}});
|
|
print $anvil->Words->string({key => "message_0341", variables => {
|
|
host_name => $short_host_name,
|
|
host_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 $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 = "<unknown>";
|
|
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:storage_group_size' => $storage_group_size,
|
|
's2:storage_group_free_space' => $storage_group_free_space,
|
|
}});
|
|
print $anvil->Words->string({key => "message_0342", variables => {
|
|
volume_number => $volume_number,
|
|
backing_disk => $backing_disk,
|
|
device_minor => $device_minor,
|
|
volume_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $volume_size}),
|
|
storage_group_name => $storage_group_name,
|
|
storage_group_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $storage_group_size}),
|
|
storage_group_free_space => $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};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub validate_server
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
$anvil->Get->server_from_switch({
|
|
debug => 2,
|
|
string => $anvil->data->{switches}{server},
|
|
anvil_uuid => $anvil->data->{switches}{anvil_uuid},
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::server_name" => $anvil->data->{switches}{server_name},
|
|
"switches::server_uuid" => $anvil->data->{switches}{server_uuid},
|
|
}});
|
|
|
|
if (not $anvil->data->{switches}{server_uuid})
|
|
{
|
|
show_server_list($anvil);
|
|
my $variables = {
|
|
server => $anvil->data->{switches}{server},
|
|
anvil => $anvil->data->{switches}{anvil_name},
|
|
};
|
|
if ($anvil->data->{switches}{anvil_uuid})
|
|
{
|
|
# Not found on the requested Anvil! node.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0451", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0451",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
else
|
|
{
|
|
# Not found at all.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0452", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0452",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
}
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $variables = {
|
|
server_name => $anvil->data->{switches}{server_name},
|
|
server_uuid => $anvil->data->{switches}{server_uuid},
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0802", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 2,
|
|
message => "log_0802",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
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_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,
|
|
's3:server_uuid' => $server_uuid,
|
|
'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")
|
|
{
|
|
# The server has been deleted
|
|
my $variables = {
|
|
server => $server_name,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0453", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0453",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Parse the definition.
|
|
$anvil->Server->parse_definition({
|
|
debug => 3,
|
|
host => $short_host_name,
|
|
server => $server_name,
|
|
source => "from_db",
|
|
definition => $server_definition,
|
|
});
|
|
|
|
# Can we read the XML definition?
|
|
$anvil->Server->get_status({
|
|
debug => 2,
|
|
server => $server_name,
|
|
host => $short_host_name,
|
|
});
|
|
|
|
if (not $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml})
|
|
{
|
|
# The server isn't actually running... Not here anyway.
|
|
if ($server_state eq "running")
|
|
{
|
|
my $server_host_name = $anvil->Database->get_host_from_uuid({
|
|
short => 1,
|
|
host_uuid => $server_host_uuid,
|
|
});
|
|
|
|
my $variables = {
|
|
server => $server_name,
|
|
host_name => $server_host_name,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0454", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0454",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# Update the definition on disk and in the DB, and define or undefine if requested.
|
|
sub update_definition
|
|
{
|
|
my ($anvil, $task, $definition) = @_;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
task => $task,
|
|
definition => $definition,
|
|
}});
|
|
|
|
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_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 $definition_file = $anvil->data->{path}{directories}{shared}{definitions}."/".$server_name.".xml";
|
|
my $server_running_here = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:short_host_name' => $short_host_name,
|
|
's2:server_name' => $server_name,
|
|
's3:server_uuid' => $server_uuid,
|
|
's5:server_host_uuid' => $server_host_uuid,
|
|
's6:server_state' => $server_state,
|
|
's7:definition_file' => $definition_file,
|
|
}});
|
|
|
|
# See if the server is running locally
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." list --name";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({debug => 2, shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:output' => $output,
|
|
's2:return_code' => $return_code,
|
|
}});
|
|
foreach my $this_server (split/\n/, $output)
|
|
{
|
|
$this_server = $anvil->Words->clean_spaces({string => $this_server});
|
|
next if not $this_server;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_server => $this_server }});
|
|
|
|
if ($this_server eq $server_name)
|
|
{
|
|
$server_running_here = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_running_here => $server_running_here }});
|
|
last;
|
|
}
|
|
}
|
|
|
|
my $disk_definition = $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}{xml} ? $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}{xml} : "";
|
|
my $virsh_definition = $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml} ? $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml} : "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:disk_definition' => $disk_definition,
|
|
's2:virsh_definition' => $virsh_definition,
|
|
}});
|
|
my $use_definition = "";
|
|
if ($definition)
|
|
{
|
|
# Use the passed in definition.
|
|
$use_definition = $definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
}
|
|
else
|
|
{
|
|
$use_definition = $virsh_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
if (not $use_definition)
|
|
{
|
|
if (($server_running_here) or (($server_state eq "running") && ($virsh_definition)))
|
|
{
|
|
# Get the live definition
|
|
if ($server_running_here)
|
|
{
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($live_virsh_definition, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
live_virsh_definition => $live_virsh_definition,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
my ($problem) = $anvil->Server->parse_definition({
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $live_virsh_definition,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
if (not $problem)
|
|
{
|
|
$use_definition = $live_virsh_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
|
|
$anvil->Server->parse_definition({
|
|
debug => 3,
|
|
host => $short_host_name,
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $live_virsh_definition,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
$use_definition = $virsh_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
|
|
$anvil->Server->parse_definition({
|
|
debug => 3,
|
|
host => $short_host_name,
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $virsh_definition,
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$use_definition = $virsh_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
|
|
$anvil->Server->parse_definition({
|
|
debug => 3,
|
|
host => $short_host_name,
|
|
server => $server_name,
|
|
source => "from_virsh",
|
|
definition => $virsh_definition,
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$use_definition = $disk_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_definition => $use_definition }});
|
|
|
|
$anvil->Server->parse_definition({
|
|
debug => 3,
|
|
host => $short_host_name,
|
|
server => $server_name,
|
|
source => "from_disk",
|
|
definition => $virsh_definition,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (not $use_definition)
|
|
{
|
|
# What?!
|
|
my $variables = { server => $server_name };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0455", variables => $variables});
|
|
$anvil->Job->update_progress({
|
|
progress => 100,
|
|
message => "error_0455",
|
|
variables => $variables,
|
|
}) if $anvil->data->{switches}{'job-uuid'};
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# Update the stored definition
|
|
$anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml} = $use_definition;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"servers::server_uuid::${server_uuid}::server_definition_xml" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml},
|
|
}});
|
|
|
|
# Update the on-disk definition
|
|
my ($failed) = $anvil->Storage->write_file({
|
|
secure => 1,
|
|
file => $definition_file,
|
|
body => $use_definition,
|
|
overwrite => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
|
|
my $server_definition_uuid = $anvil->Database->insert_or_update_server_definitions({
|
|
debug => 2,
|
|
server_definition_xml => $use_definition,
|
|
server_definition_server_uuid => $server_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server_definition_uuid => $server_definition_uuid }});
|
|
|
|
if ($task eq "define")
|
|
{
|
|
# Define the server.
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." define ".$definition_file,
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
}
|
|
elsif ($task eq "undefine")
|
|
{
|
|
# Undefine the server.
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." undefine ".$server_name,
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({
|
|
debug => 2,
|
|
shell_call => $shell_call,
|
|
source => $THIS_FILE,
|
|
line => __LINE__,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub show_server_list
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Loop through all Anvil! nodes, then all server in that Anvil!
|
|
foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}})
|
|
{
|
|
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid};
|
|
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
anvil_name => $anvil_name,
|
|
anvil_uuid => $anvil_uuid,
|
|
anvil_description => $anvil_description,
|
|
}});
|
|
if (($anvil->data->{switches}{anvil_uuid}) && ($anvil->data->{switches}{anvil_uuid} ne $anvil_uuid))
|
|
{
|
|
next;
|
|
}
|
|
print "\n".$anvil->Words->string({key => "message_0343", variables => {
|
|
anvil_name => $anvil_name,
|
|
anvil_uuid => $anvil_uuid,
|
|
anvil_description => $anvil_description,
|
|
}})."\n";
|
|
|
|
my $server_count = 0;
|
|
if (exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name})
|
|
{
|
|
$server_count = keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_count => $server_count }});
|
|
}
|
|
if (not $server_count)
|
|
{
|
|
print $anvil->Words->string({key => "message_0344"})."\n";
|
|
}
|
|
else
|
|
{
|
|
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_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_state => $server_state,
|
|
}});
|
|
next if $server_state eq "DELETED";
|
|
print $anvil->Words->string({key => "message_0345", variables => {
|
|
server_name => $server_name,
|
|
server_uuid => $server_uuid,
|
|
}})."\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub show_files
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
my $server_uuid = $anvil->data->{switches}{server_uuid};
|
|
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
|
|
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:server_name' => $server_name,
|
|
's2:server_uuid' => $server_uuid,
|
|
's3:anvil_uuid' => $anvil_uuid,
|
|
's4:anvil_name' => $anvil_name,
|
|
}});
|
|
|
|
$anvil->Database->get_anvils;
|
|
|
|
# Show the files available on this node.
|
|
print $anvil->Words->string({key => 'message_0346'})."\n";
|
|
foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}})
|
|
{
|
|
my $file_location_file_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}{$file_name}{file_uuid};
|
|
my $file_size = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_size};
|
|
my $file_md5sum = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_md5sum};
|
|
my $file_type = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_location_file_uuid}{file_type};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:file_name' => $file_name,
|
|
's2:file_size' => $file_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}).")",
|
|
's3:file_md5sum' => $file_md5sum,
|
|
's4:file_type' => $file_type,
|
|
}});
|
|
next if $file_type ne "iso";
|
|
print $anvil->Words->string({key => 'message_0347', variables => {
|
|
file_name => $file_name,
|
|
file_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}),
|
|
md5sum => $file_md5sum,
|
|
}})."\n";
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub show_storage_groups
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
my $server_name = $anvil->data->{switches}{server_name};
|
|
my $server_uuid = $anvil->data->{switches}{server_uuid};
|
|
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
|
|
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:server_name' => $server_name,
|
|
's2:server_uuid' => $server_uuid,
|
|
's3:anvil_uuid' => $anvil_uuid,
|
|
's4:anvil_name' => $anvil_name,
|
|
}});
|
|
|
|
print $anvil->Words->string({key => 'message_0348'})."\n";
|
|
foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}})
|
|
{
|
|
my $storage_group_uuid = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid};
|
|
my $free_space = $anvil->data->{storage_groups}{anvil_uuid}{$anvil_uuid}{storage_group_uuid}{$storage_group_uuid}{free_space};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:storage_group_name' => $storage_group_name,
|
|
's2:storage_group_uuid' => $storage_group_uuid,
|
|
's3:free_space' => $free_space." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_space}).")",
|
|
}});
|
|
print $anvil->Words->string({key => 'message_0349', variables => {
|
|
storage_group_name => $storage_group_name,
|
|
storage_group_uuid => $storage_group_uuid,
|
|
free_space => $anvil->Convert->bytes_to_human_readable({'bytes' => $free_space}),
|
|
}})."\n";
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub load_job
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
$anvil->Job->clear({
|
|
debug => 2,
|
|
job_uuid => $anvil->data->{switches}{'job-uuid'},
|
|
});
|
|
$anvil->Job->get_job_details({
|
|
debug => 2,
|
|
job_uuid => $anvil->data->{switches}{'job-uuid'},
|
|
});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
'jobs::job_data' => $anvil->data->{jobs}{job_data},
|
|
}});
|
|
foreach my $line (split/\n/, $anvil->data->{jobs}{job_data})
|
|
{
|
|
my ($variable, $value) = ($line =~ /^(.*)=(.*)$/);
|
|
$value =~ s/^"(.*)\"/$1/;
|
|
$value =~ s/^'(.*)\'/$1/;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:line' => $line,
|
|
's2:variable' => $variable,
|
|
's3:value' => $value,
|
|
}});
|
|
|
|
$anvil->data->{switches}{$variable} = $value;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"switches::${variable}" => $anvil->data->{switches}{$variable},
|
|
}});
|
|
}
|
|
|
|
$anvil->Job->update_progress({
|
|
progress => 1,
|
|
job_picked_up_by => $$,
|
|
job_picked_up_at => time,
|
|
message => "message_0350",
|
|
});
|
|
|
|
return(0);
|
|
}
|