mirror of
https://github.com/OpenNebula/one.git
synced 2025-02-26 09:57:23 +03:00
feature #3654: Add retry option to the recover API calls and onevm command
This commit is contained in:
parent
1b0f23e17d
commit
b5da40364f
@ -129,6 +129,12 @@ public:
|
||||
*/
|
||||
void recover(VirtualMachine * vm, bool success);
|
||||
|
||||
/**
|
||||
* Retries the last VM operation that lead to a failure. The underlying
|
||||
* driver actions may be invoked and should be "re-entrant".
|
||||
*/
|
||||
void retry(VirtualMachine * vm);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Thread id for the Virtual Machine Manager
|
||||
@ -270,8 +276,6 @@ private:
|
||||
|
||||
void restart_action(int vid);
|
||||
|
||||
void retry_action(int vid);
|
||||
|
||||
void delete_action(int vid);
|
||||
|
||||
void clean_action(int vid);
|
||||
|
@ -349,7 +349,7 @@ public:
|
||||
VirtualMachineRecover():
|
||||
RequestManagerVirtualMachine("VirtualMachineRecover",
|
||||
"Recovers a virtual machine",
|
||||
"A:sib")
|
||||
"A:sii")
|
||||
{
|
||||
auth_op = AuthRequest::ADMIN;
|
||||
};
|
||||
|
@ -91,6 +91,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
:description => "Recover a VM by failing the pending action"
|
||||
}
|
||||
|
||||
RETRY={
|
||||
:name => "retry",
|
||||
:large => "--retry",
|
||||
:description => "Recover a VM by retrying the last failed action"
|
||||
}
|
||||
|
||||
CLONETEMPLATE={
|
||||
:name => "clonetemplate",
|
||||
:short => "-c",
|
||||
@ -530,27 +536,31 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
recover_desc = <<-EOT.unindent
|
||||
Recovers a stuck VM that is waiting for a driver operation. The recovery
|
||||
may be done by failing or succeeding the pending operation. YOU NEED
|
||||
may be done by failing, succeeding or retrying the current operation. YOU NEED
|
||||
TO MANUALLY CHECK THE VM STATUS ON THE HOST, to decide if the operation
|
||||
was successful or not.
|
||||
was successful or not, or if it can be retried.
|
||||
|
||||
Example: A VM is stuck in "migrate" because of a hardware failure. You
|
||||
need to check if the VM is running in the new host or not to recover
|
||||
the vm with --success or --failure, respectively.
|
||||
|
||||
States: Any ACTIVE state.
|
||||
States for success/failure recovers: Any ACTIVE state.
|
||||
States for a retry recover: Any *FAILURE state
|
||||
EOT
|
||||
|
||||
command :recover, recover_desc, [:range,:vmid_list],
|
||||
:options => [SUCCESS, FAILURE] do
|
||||
:options => [SUCCESS, FAILURE, RETRY] do
|
||||
if !options[:success].nil?
|
||||
result = true
|
||||
result = 1
|
||||
elsif !options[:failure].nil?
|
||||
result = false
|
||||
result = 0
|
||||
elsif !options[:retry].nil?
|
||||
result = 2
|
||||
else
|
||||
STDERR.puts "Need to specify the result of the pending action."
|
||||
STDERR.puts "\t--success recover the VM by succeeding the missing action."
|
||||
STDERR.puts "\t--failure recover the VM by failing the missing action."
|
||||
STDERR.puts "\t--retry recover the VM by retrying the last failed action."
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
@ -658,147 +658,6 @@ void LifeCycleManager::cancel_action(int vid)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void LifeCycleManager::retry_action(int vid)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
TransferManager * tm = nd.get_tm();
|
||||
VirtualMachineManager * vmm = nd.get_vmm();
|
||||
|
||||
VirtualMachine * vm;
|
||||
|
||||
vm = vmpool->get(vid,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vm->get_state() != VirtualMachine::ACTIVE )
|
||||
{
|
||||
vm->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualMachine::LcmState state = vm->get_lcm_state();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case VirtualMachine::BOOT_FAILURE:
|
||||
vm->set_state(VirtualMachine::BOOT);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is BOOT");
|
||||
|
||||
vmm->trigger(VirtualMachineManager::DEPLOY, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::BOOT_MIGRATE_FAILURE:
|
||||
vm->set_state(VirtualMachine::BOOT_MIGRATE);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is BOOT_MIGRATE");
|
||||
|
||||
vmm->trigger(VirtualMachineManager::RESTORE, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::PROLOG_MIGRATE_FAILURE:
|
||||
vm->set_state(VirtualMachine::PROLOG_MIGRATE);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is PROLOG_MIGRATE");
|
||||
|
||||
tm->trigger(TransferManager::PROLOG_MIGR, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::PROLOG_FAILURE:
|
||||
vm->set_state(VirtualMachine::PROLOG);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is PROLOG.");
|
||||
|
||||
tm->trigger(TransferManager::PROLOG,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_STOP_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG_STOP);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG_STOP");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG_STOP,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_UNDEPLOY_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG_UNDEPLOY);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG_UNDEPLOY");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG_STOP,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::LCM_INIT:
|
||||
case VirtualMachine::BOOT:
|
||||
case VirtualMachine::BOOT_MIGRATE:
|
||||
case VirtualMachine::BOOT_POWEROFF:
|
||||
case VirtualMachine::BOOT_SUSPENDED:
|
||||
case VirtualMachine::BOOT_STOPPED:
|
||||
case VirtualMachine::BOOT_UNDEPLOY:
|
||||
case VirtualMachine::BOOT_UNKNOWN:
|
||||
case VirtualMachine::CANCEL:
|
||||
case VirtualMachine::CLEANUP_RESUBMIT:
|
||||
case VirtualMachine::CLEANUP_DELETE:
|
||||
case VirtualMachine::EPILOG:
|
||||
case VirtualMachine::EPILOG_STOP:
|
||||
case VirtualMachine::EPILOG_UNDEPLOY:
|
||||
case VirtualMachine::HOTPLUG:
|
||||
case VirtualMachine::HOTPLUG_NIC:
|
||||
case VirtualMachine::HOTPLUG_SNAPSHOT:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_EPILOG_POWEROFF:
|
||||
case VirtualMachine::PROLOG:
|
||||
case VirtualMachine::PROLOG_MIGRATE:
|
||||
case VirtualMachine::PROLOG_RESUME:
|
||||
case VirtualMachine::PROLOG_UNDEPLOY:
|
||||
case VirtualMachine::MIGRATE:
|
||||
case VirtualMachine::RUNNING:
|
||||
case VirtualMachine::SAVE_STOP:
|
||||
case VirtualMachine::SAVE_SUSPEND:
|
||||
case VirtualMachine::SAVE_MIGRATE:
|
||||
case VirtualMachine::SHUTDOWN:
|
||||
case VirtualMachine::SHUTDOWN_POWEROFF:
|
||||
case VirtualMachine::SHUTDOWN_UNDEPLOY:
|
||||
case VirtualMachine::UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void LifeCycleManager::restart_action(int vid)
|
||||
{
|
||||
@ -1419,3 +1278,134 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void LifeCycleManager::retry(VirtualMachine * vm)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
TransferManager * tm = nd.get_tm();
|
||||
VirtualMachineManager * vmm = nd.get_vmm();
|
||||
|
||||
int vid = vm->get_oid();
|
||||
|
||||
if ( vm->get_state() != VirtualMachine::ACTIVE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualMachine::LcmState state = vm->get_lcm_state();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case VirtualMachine::BOOT_FAILURE:
|
||||
vm->set_state(VirtualMachine::BOOT);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is BOOT");
|
||||
|
||||
vmm->trigger(VirtualMachineManager::DEPLOY, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::BOOT_MIGRATE_FAILURE:
|
||||
vm->set_state(VirtualMachine::BOOT_MIGRATE);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is BOOT_MIGRATE");
|
||||
|
||||
vmm->trigger(VirtualMachineManager::RESTORE, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::PROLOG_MIGRATE_FAILURE:
|
||||
vm->set_state(VirtualMachine::PROLOG_MIGRATE);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is PROLOG_MIGRATE");
|
||||
|
||||
tm->trigger(TransferManager::PROLOG_MIGR, vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::PROLOG_FAILURE:
|
||||
vm->set_state(VirtualMachine::PROLOG);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is PROLOG.");
|
||||
|
||||
tm->trigger(TransferManager::PROLOG,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_STOP_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG_STOP);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG_STOP");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG_STOP,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::EPILOG_UNDEPLOY_FAILURE:
|
||||
vm->set_state(VirtualMachine::EPILOG_UNDEPLOY);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "New VM state is EPILOG_UNDEPLOY");
|
||||
|
||||
tm->trigger(TransferManager::EPILOG_STOP,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::LCM_INIT:
|
||||
case VirtualMachine::BOOT:
|
||||
case VirtualMachine::BOOT_MIGRATE:
|
||||
case VirtualMachine::BOOT_POWEROFF:
|
||||
case VirtualMachine::BOOT_SUSPENDED:
|
||||
case VirtualMachine::BOOT_STOPPED:
|
||||
case VirtualMachine::BOOT_UNDEPLOY:
|
||||
case VirtualMachine::BOOT_UNKNOWN:
|
||||
case VirtualMachine::CANCEL:
|
||||
case VirtualMachine::CLEANUP_RESUBMIT:
|
||||
case VirtualMachine::CLEANUP_DELETE:
|
||||
case VirtualMachine::EPILOG:
|
||||
case VirtualMachine::EPILOG_STOP:
|
||||
case VirtualMachine::EPILOG_UNDEPLOY:
|
||||
case VirtualMachine::HOTPLUG:
|
||||
case VirtualMachine::HOTPLUG_NIC:
|
||||
case VirtualMachine::HOTPLUG_SNAPSHOT:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_EPILOG_POWEROFF:
|
||||
case VirtualMachine::PROLOG:
|
||||
case VirtualMachine::PROLOG_MIGRATE:
|
||||
case VirtualMachine::PROLOG_RESUME:
|
||||
case VirtualMachine::PROLOG_UNDEPLOY:
|
||||
case VirtualMachine::MIGRATE:
|
||||
case VirtualMachine::RUNNING:
|
||||
case VirtualMachine::SAVE_STOP:
|
||||
case VirtualMachine::SAVE_SUSPEND:
|
||||
case VirtualMachine::SAVE_MIGRATE:
|
||||
case VirtualMachine::SHUTDOWN:
|
||||
case VirtualMachine::SHUTDOWN_POWEROFF:
|
||||
case VirtualMachine::SHUTDOWN_UNDEPLOY:
|
||||
case VirtualMachine::UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -483,12 +483,13 @@ public class VirtualMachine extends PoolElement{
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The virtual machine id (vid) of the target instance.
|
||||
* @param success recover by succeeding the missing transaction if true.
|
||||
* @param operation to recover the VM: (0) failure, (1) success or (2)
|
||||
* retry
|
||||
* @return If an error occurs the error message contains the reason.
|
||||
*/
|
||||
public static OneResponse recover(Client client, int id, boolean success)
|
||||
public static OneResponse recover(Client client, int id, int operation)
|
||||
{
|
||||
return client.call(RECOVER, id, success);
|
||||
return client.call(RECOVER, id, operation);
|
||||
}
|
||||
|
||||
// =================================
|
||||
|
@ -596,7 +596,8 @@ module OpenNebula
|
||||
|
||||
# Recovers an ACTIVE VM
|
||||
#
|
||||
# @param result [Boolean] Recover with success (true) or failure (false)
|
||||
# @param result [Integer] Recover with failure (0), success (1) or
|
||||
# retry (2)
|
||||
# @param result [info] Additional information needed to recover the VM
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
|
@ -2249,8 +2249,8 @@ void VirtualMachineDetachNic::request_execute(
|
||||
void VirtualMachineRecover::request_execute(
|
||||
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
|
||||
{
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
bool success = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int op = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
VirtualMachine * vm;
|
||||
|
||||
@ -2277,7 +2277,26 @@ void VirtualMachineRecover::request_execute(
|
||||
return;
|
||||
}
|
||||
|
||||
lcm->recover(vm, success);
|
||||
switch (op)
|
||||
{
|
||||
case 0:
|
||||
lcm->recover(vm, false);
|
||||
break;
|
||||
case 1:
|
||||
lcm->recover(vm, true);
|
||||
break;
|
||||
case 2:
|
||||
lcm->retry(vm);
|
||||
break;
|
||||
|
||||
default:
|
||||
failure_response(ACTION,
|
||||
request_error("Wrong recovery operation code",""),
|
||||
att);
|
||||
|
||||
vm->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user