You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by di...@apache.org on 2013/09/09 17:32:20 UTC
svn commit: r1521161 -
/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
Author: dimach
Date: Mon Sep 9 15:32:20 2013
New Revision: 1521161
URL: http://svn.apache.org/r1521161
Log:
VCL-722: change the way one.pm sends shutdown to a VM
Modified:
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm?rev=1521161&r1=1521160&r2=1521161&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm Mon Sep 9 15:32:20 2013
@@ -182,9 +182,9 @@ sub load {
# Check if SWAP disk needed, format: DISK=[DEV_PREFIX="vd",TYPE="swap",SIZE="4096"]
my $swap_disk = '';
- my $swap_size = $self->get_image_tag_value("SWAP");
+ my $swap_size = $self->one_get_image_tag_value("SWAP");
if (defined($swap_size)) {
- if ($self->get_image_tag_value("DEV_PREFIX") eq "vd") {
+ if ($self->one_get_image_tag_value("DEV_PREFIX") eq "vd") {
$swap_disk = 'DISK=[DEV_PREFIX="vd",TYPE="swap",SIZE="'.$swap_size.'"]';
} else {
$swap_disk = 'DISK=[TYPE="swap",SIZE="'.$swap_size.'"]';
@@ -400,10 +400,6 @@ sub one_get_object_id {
sub one_delete_vm {
my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
- return;
- }
my $vmid = shift;
my @reply;
@@ -460,11 +456,10 @@ sub capture {
notify($ERRORS{'CRITICAL'}, 0, "Couldn't find vmid for $computer_name. Abort.");
return 0;
}
- # check for new image to be READY (1)
- # Call the OS module's pre_capture() subroutine, this will shutdown the VM at the end
+ # Call the OS module's pre_capture() subroutine (don't shutdown at the end)
if ($self->os->can("pre_capture")) {
- if (!$self->os->pre_capture({end_state => 'off'})) {
+ if (!$self->os->pre_capture({end_state => 'on'})) {
notify($ERRORS{'CRITICAL'}, 0, "failed to complete OS module's pre_capture tasks");
return;
} else {
@@ -474,25 +469,100 @@ sub capture {
notify($ERRORS{'CRITICAL'}, 0, "OS module doesn't implement pre_capture(). Abort.");
return;
}
+
+ # pre_capture was called with {end_state => 'on'}. Need to shutdown VM via ACPI.
+ if(!$self->power_off()) {
+ notify($ERRORS{'CRITICAL'}, 0, "Couldn't shutdown $computer_name with power_off()");
+ return 0;
+ } else {
+ # notify($ERRORS{'DEBUG'}, 0, "Sent 'shutdown' to computer $computer_name via provisioning module");
+ # make sure VM enters STATE=ACTIVE (3) & LCM_STATE=EPILOG(11)
+ # if VM doesn't reach EPILOG, wait for ACTIVE/RUNNING (3/3) and then send 'shutdown-hard', check for EPILOG again.
+ my $sleep = 5;
+ my $wait_time = 5 * 60; # how long to wait for LCM_STATE = EPILOG
+ my $flag = 0;
+ my $state;
+ my $lcm_state;
+
+ notify($ERRORS{'OK'}, 0, "Wait for the VM $vmid to enter ACTIVE/EPILOG (3/11) state...");
+ while (1) {
+ $state = $self->one_get_vm_state($vmid);
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state state");
+ if ($state == 3) {
+ $lcm_state = $self->one_get_vm_lcm_state($vmid);
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $lcm_state lcm_state");
+ if ($lcm_state == 11) {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in EPILOG state. OK");
+ last;
+ } else {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state / $lcm_state state...");
+ }
+ } else {
+ notify($ERRORS{'DEBUG'}, 0, "VM $vmid should be in ACTIVE (3) state, but it's in $state state");
+ return 0;
+ }
+ sleep $sleep;
+ $wait_time = $wait_time - $sleep;
+ notify($ERRORS{'OK'}, 0, "Waiting for VM $vmid to enter ACTIVE/EPILOG state, $wait_time sec left ...");
+
+ if ($wait_time <= 0) {
+ notify($ERRORS{'DEBUG'}, 0, "VM $vmid never reached EPILOG state. Wait for ACTIVE/RUNNING (3/3) and send 'shutdown-hard'");
+ my $sleep = 15;
+ my $wait_time = 20 * 60; #how long to wait for ACTIVE/RUNNING (3/3)
+
+ while (1) {
+ $state = $self->one_get_vm_state($vmid);
+ if ($state == 3) {
+ $lcm_state = $self->one_get_vm_lcm_state($vmid);
+ if ($lcm_state == 3) {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state / $lcm_state state. Wait $sleep sec and send 'shutdown-hard'");
+ sleep $sleep;
+ if (!$self->power_off('hard')) {
+ notify($ERRORS{'CRITICAL'}, 0, "Couldn't shutdown $computer_name with power_off('hard')");
+ return 0;
+ }
+ last;
+ } else {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state / $lcm_state state...");
+ }
+ } else {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state state...");
+ }
+ sleep $sleep;
+ $wait_time = $wait_time - $sleep;
+ notify($ERRORS{'OK'}, 0, "Waiting for VM $vmid to enter ACTIVE/RUNNING state, $wait_time sec left ...");
+ if ($wait_time <= 0) {
+ notify($ERRORS{'CRITICAL'}, 0, "VM $vmid is in $state / $lcm_state after $wait_time sec ... Fail!");
+ return 0;
+ }
+ }
+
+ }
+ }
+ }
- my $attempt = 0;
- my $sleep = 15;
+ #
+
+ # Check that we have new_image_name created on ONE (it will be in LOCKED state until disk_save is done).
+ # just procation, image stub should be created already.
+ my $sleep = 5;
+ my $wait_time = 20 * 60; # in min * 60 = seconds
while (1) {
- $attempt++;
$one_new_image_id = $self->one_get_object_id("image",$image_name);
last if ($one_new_image_id);
- if ($attempt > 20) {
- notify($ERRORS{'CRITICAL'}, 0, "ONE could not locate new disk id for $image_name");
+ $wait_time = $wait_time - $sleep;
+ if ($wait_time <= 0) {
+ notify($ERRORS{'CRITICAL'}, 0, "Could not locate new disk id for $image_name. disk_save wasn't successfull.");
last;
}
sleep $sleep;
}
- $attempt = 0;
- my $total_attempts = 120;
+ # wait until disk_save is done
+
+ $wait_time = 30 * 60; # in min * 60 = seconds
while (1) {
- $attempt++;
- notify($ERRORS{'OK'}, 0, "check status for new image id $one_new_image_id, attempt $attempt / $total_attempts");
+ notify($ERRORS{'OK'}, 0, "check status for new image id $one_new_image_id, $wait_time sec left...");
my $one_image_state = $self->one_get_image_state($one_new_image_id);
if ($one_image_state == 4) {
notify($ERRORS{'OK'}, 0, "disk save in pregress, image id $one_new_image_id is LOCKED");
@@ -505,11 +575,12 @@ sub capture {
notify($ERRORS{'OK'}, 0, "disk save OK, image id $one_new_image_id is READY");
return 1;
}
- if ( $attempt > $total_attempts ) {
- notify($ERRORS{'CRITICAL'}, 0, "disk save failed, image id $one_new_image_id is not READY after $total_attempts attempts");
+ if ( $wait_time <= 0 ) {
+ notify($ERRORS{'CRITICAL'}, 0, "disk save failed, image id $one_new_image_id is NOT READY. Fail.");
return 0;
}
sleep $sleep;
+ $wait_time = $wait_time - $sleep;
}
return 0;
@@ -535,16 +606,9 @@ sub one_get_image_state {
}
-=head2 opennebula
- Description : returns 1. Yes, it's opennebula module.
-=cut
-sub opennebula {
- return 1;
-}
-
=head2 power_off
- Parameters :
+ Parameters : 'hard' (optional), execute shutdown-hard
Returns :
Description : send 'shutdown' to VM via controller.
* need to add check if VM is OFF. Sometimes VM won't power off *
@@ -558,15 +622,20 @@ sub power_off {
return;
}
+ my $action = shift;
my $computer_name = $self->data->get_computer_hostname();
my $vmid = $self->one_get_object_id("computer",$computer_name);
my @poweroff = $one{'server'}->call('one.vm.action', $one{'auth'},'shutdown',$vmid);
+ if (defined($action) and $action eq 'hard') {
+ @poweroff = $one{'server'}->call('one.vm.action', $one{'auth'},'shutdown-hard',$vmid);
+ }
+
if ( $poweroff[0][0]->value() ) {
notify($ERRORS{'OK'}, 0, "Sent shutdown signal to VM $vmid");
return 1;
} else {
- notify($ERRORS{'CRITICAL'}, 0, $poweroff[0][1]);
+ notify($ERRORS{'DEBUG'}, 0, $poweroff[0][1]);
return 0;
}
@@ -624,7 +693,7 @@ sub one_wait_for_vm_state {
if (!$num_state) {
- notify($ERRORS{'CRITICAL'}, 0, "Unknown vm_state: $state requested");
+ notify($ERRORS{'CRITICAL'}, 0, "Unknown vm_state $state requested");
return 0;
}
@@ -650,13 +719,9 @@ sub one_wait_for_vm_state {
} ## end sub one_wait_for_vm_status
+#
sub one_get_vm_state {
my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
- return;
- }
- # one.vm.info
my $vmid = shift;
my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
@@ -669,6 +734,28 @@ sub one_get_vm_state {
}
}
+# gets LCM_STATE values, this sub-state is relevant only when STATE is ACTIVE (3)
+sub one_get_vm_lcm_state {
+ my $self = shift;
+ my $vmid = shift;
+
+ my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
+ if ( $result[0][0]->value() ) {
+ my $data = $xml->XMLin($result[0][1]);
+ if ($data->{STATE} == 3) {
+ return $data->{LCM_STATE};
+ } else {
+ notify($ERRORS{'DEBUG'}, 0, "Cannot return LCM_STATE of VM $vmid, VM's STATE is not ACTIVE");
+ return;
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
+ return 0;
+ }
+}
+
+
+
#/////////////////////////////////////////////////////////////////////////////
=head2 power_status
@@ -746,7 +833,7 @@ sub get_image_size {
return;
}
- return $self->get_image_tag_value("SIZE");
+ return $self->one_get_image_tag_value("SIZE");
#
# my $image_name = $self->data->get_image_name();
#
@@ -761,15 +848,9 @@ sub get_image_size {
# }
}
-sub get_image_tag_value {
+sub one_get_image_tag_value {
my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
- return;
- }
-
my $tag = shift;
-
my $image_name = $self->data->get_image_name();
my $imid = $self->one_get_object_id("image",$image_name);