1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-29 18:50:08 +03:00

Feature : New command onevm snapshot-delete

This commit is contained in:
Jaime Melis 2013-02-21 15:01:48 +01:00
parent e3380cba7f
commit d1b7fd1b8c
14 changed files with 377 additions and 6 deletions

@ -306,6 +306,20 @@ public:
int snap_id,
string& error_str);
/**
* Starts the snapshot delete action
*
* @param vid VirtualMachine identification
* @param snap_id Snapshot to be deleted
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int snapshot_delete(
int vid,
int snap_id,
string& error_str);
private:
/**
* Thread id for the Dispatch Manager

@ -68,6 +68,8 @@ public:
SNAPSHOT_CREATE_FAILURE, /**< Sent by the VMM on snap. create failure */
SNAPSHOT_REVERT_SUCCESS, /**< Sent by the VMM on snap. revert success */
SNAPSHOT_REVERT_FAILURE, /**< Sent by the VMM on snap. revert failure */
SNAPSHOT_DELETE_SUCCESS, /**< Sent by the VMM on snap. revert success */
SNAPSHOT_DELETE_FAILURE, /**< Sent by the VMM on snap. revert failure */
DEPLOY, /**< Sent by the DM to deploy a VM on a host */
SUSPEND, /**< Sent by the DM to suspend an running VM */
RESTORE, /**< Sent by the DM to restore a suspended VM */
@ -201,6 +203,10 @@ private:
void snapshot_revert_failure(int vid);
void snapshot_delete_success(int vid);
void snapshot_delete_failure(int vid);
void deploy_action(int vid);
void suspend_action(int vid);

@ -251,6 +251,23 @@ public:
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSnapshotDelete: public RequestManagerVirtualMachine
{
public:
VirtualMachineSnapshotDelete():
RequestManagerVirtualMachine("VirtualMachineSnapshotDelete",
"Deletes a virtual machine to a snapshot",
"A:sii"){};
~VirtualMachineSnapshotDelete(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

@ -63,7 +63,8 @@ public:
ATTACH,
DETACH,
SNAPSHOT_CREATE,
SNAPSHOT_REVERT
SNAPSHOT_REVERT,
SNAPSHOT_DELETE
};
/**
@ -350,6 +351,14 @@ private:
*/
void snapshot_revert_action(int vid);
/**
* Deletes a snapshot. The VM must have a snapshot with the
* attribute ACTIVE = YES
*
* @param vid the id of the VM.
*/
void snapshot_delete_action(int vid);
/**
* This function cancels the current driver operation
*/

@ -310,6 +310,19 @@ private:
write_drv("SNAPSHOTREVERT", oid, drv_msg);
}
/**
* Sends a snapshot delete request to the MAD:
* "SNAPSHOTDELETE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void snapshot_delete (
const int oid,
const string& drv_msg) const
{
write_drv("SNAPSHOTDELETE", oid, drv_msg);
}
void write_drv(const char * aname, const int oid, const string& msg) const
{
ostringstream os;

@ -652,6 +652,17 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
# TODO: Write a more complete description:
snapshot_delete_desc = <<-EOT.unindent
Delets a snapshot of a VM
EOT
command :"snapshot-delete", snapshot_delete_desc, :vmid, :snapshot_id do
helper.perform_action(args[0],options,"snapshot deleted") do |o|
o.snapshot_delete(args[1].to_i)
end
end
list_desc = <<-EOT.unindent
Lists VMs in the pool
EOT

@ -1172,9 +1172,6 @@ int DispatchManager::snapshot_revert(
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG);
vm->set_resched(false);
rc = vm->set_active_snapshot(snap_id);
@ -1190,6 +1187,10 @@ int DispatchManager::snapshot_revert(
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
@ -1201,3 +1202,71 @@ int DispatchManager::snapshot_revert(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::snapshot_delete(
int vid,
int snap_id,
string& error_str)
{
ostringstream oss;
int rc;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
rc = vm->set_active_snapshot(snap_id);
if ( rc == -1 )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", it does not exist.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::SNAPSHOT_DELETE,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

@ -169,6 +169,14 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "SNAPSHOT_REVERT_FAILURE";
break;
case SNAPSHOT_DELETE_SUCCESS:
aname = "SNAPSHOT_DELETE_SUCCESS";
break;
case SNAPSHOT_DELETE_FAILURE:
aname = "SNAPSHOT_DELETE_FAILURE";
break;
case DEPLOY:
aname = "DEPLOY";
break;
@ -346,6 +354,14 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
snapshot_revert_failure(vid);
}
else if (action == "SNAPSHOT_DELETE_SUCCESS")
{
snapshot_delete_success(vid);
}
else if (action == "SNAPSHOT_DELETE_FAILURE")
{
snapshot_delete_failure(vid);
}
else if (action == "DEPLOY")
{
deploy_action(vid);

@ -1322,3 +1322,62 @@ void LifeCycleManager::snapshot_revert_failure(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_delete_success(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG )
{
vm->delete_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_delete_success, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_delete_failure(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG )
{
vm->clear_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_delete_success, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

@ -39,7 +39,8 @@ module OpenNebula
:rename => "vm.rename",
:update => "vm.update",
:snapshotcreate => "vm.snapshotcreate",
:snapshotrevert => "vm.snapshotrevert"
:snapshotrevert => "vm.snapshotrevert",
:snapshotdelete => "vm.snapshotdelete"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
@ -424,7 +425,7 @@ module OpenNebula
return @client.call(VM_METHODS[:snapshotcreate], @pe_id, name)
end
# Creates a new VM snapshot
# Reverts to a snapshot
#
# @param snap_id [Integer] Id of the snapshot
#
@ -434,6 +435,16 @@ module OpenNebula
return call(VM_METHODS[:snapshotrevert], @pe_id, snap_id)
end
# Deletes a VM snapshot
#
# @param snap_id [Integer] Id of the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def snapshot_delete(snap_id)
return call(VM_METHODS[:snapshotdelete], @pe_id, snap_id)
end
#######################################################################
# Helpers to get VirtualMachine information
#######################################################################

@ -256,6 +256,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach());
xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate());
xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert());
xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete());
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring());
@ -401,6 +402,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.update", vm_update);
RequestManagerRegistry.addMethod("one.vm.snapshotcreate", vm_snap_create);
RequestManagerRegistry.addMethod("one.vm.snapshotrevert", vm_snap_revert);
RequestManagerRegistry.addMethod("one.vm.snapshotdelete", vm_snap_delete);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct);

@ -1139,3 +1139,44 @@ void VirtualMachineSnapshotRevert::request_execute(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineSnapshotDelete::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->snapshot_delete(id, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

@ -191,6 +191,9 @@ void VirtualMachineManager::trigger(Actions action, int _vid)
aname = "SNAPSHOT_REVERT";
break;
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
default:
delete vid;
return;
@ -295,6 +298,10 @@ void VirtualMachineManager::do_action(const string &action, void * arg)
{
snapshot_revert_action(vid);
}
else if (action == "SNAPSHOT_DELETE")
{
snapshot_delete_action(vid);
}
else if (action == ACTION_TIMER)
{
timer_action();
@ -1931,6 +1938,83 @@ error_common:
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::snapshot_delete_action(int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->snapshot_delete(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "snapshot_delete_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "snapshot_delete_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

@ -416,6 +416,25 @@ void VirtualMachineManagerDriver::protocol(
lcm->trigger(LifeCycleManager::SNAPSHOT_REVERT_FAILURE, id);
}
}
else if ( action == "SNAPSHOTDELETE" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM",Log::INFO,"VM Snapshot successfully deleted.");
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_SUCCESS, id);
}
else
{
log_error(vm,os,is,"Error deleting VM Snapshot");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_FAILURE, id);
}
}
else if ( action == "CLEANUP" )
{
Nebula &ne = Nebula::instance();