mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-24 02:03:52 +03:00
feature #3782: Revert action for images
This commit is contained in:
parent
78c7bdbd5d
commit
9348a0d455
@ -201,13 +201,22 @@ public:
|
||||
|
||||
/**
|
||||
* Deletes the snapshot of an image
|
||||
* @param iid id of image
|
||||
* @param sid id of the snapshot
|
||||
* @param error_str Error reason, if any
|
||||
* @return 0 on success
|
||||
* @param iid id of image
|
||||
* @param sid id of the snapshot
|
||||
* @param error_str Error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int delete_snapshot(int iid, int sid, string& error);
|
||||
|
||||
/**
|
||||
* Reverts image state to a previous snapshot
|
||||
* @param iid id of image
|
||||
* @param sid id of the snapshot
|
||||
* @param error_str Error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int revert_snapshot(int iid, int sid, string& error);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generic name for the Image driver
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
ImageSnapshotRevert():
|
||||
RequestManagerImage("ImageSnapshotRevert",
|
||||
"Reverts image state to a previous snapshot",
|
||||
"A:sis"){};
|
||||
"A:sii"){};
|
||||
|
||||
~ImageSnapshotRevert(){};
|
||||
|
||||
|
@ -311,6 +311,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
snapshot_revert_desc = <<-EOT.unindent
|
||||
Reverts image state to a snapshot
|
||||
EOT
|
||||
|
||||
command :"snapshot-revert", snapshot_revert_desc, :imageid, :snapshot_id do
|
||||
helper.perform_action(args[0], options, "image state reverted") do |o|
|
||||
o.snapshot_revert(args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists Images in the pool
|
||||
EOT
|
||||
|
@ -51,7 +51,8 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
:stat => "STAT",
|
||||
:clone => "CLONE",
|
||||
:monitor => "MONITOR",
|
||||
:snap_delete => "SNAP_DELETE"
|
||||
:snap_delete => "SNAP_DELETE",
|
||||
:snap_revert => "SNAP_REVERT"
|
||||
}
|
||||
|
||||
# Register default actions for the protocol
|
||||
@ -67,7 +68,8 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
ACTION[:mkfs] => nil,
|
||||
ACTION[:clone] => nil,
|
||||
ACTION[:monitor] => nil,
|
||||
ACTION[:snap_delete] => nil
|
||||
ACTION[:snap_delete] => nil,
|
||||
ACTION[:snap_revert] => nil
|
||||
}
|
||||
}.merge!(options)
|
||||
|
||||
@ -90,6 +92,7 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
register_action(ACTION[:clone].to_sym, method("clone"))
|
||||
register_action(ACTION[:monitor].to_sym, method("monitor"))
|
||||
register_action(ACTION[:snap_delete].to_sym, method("snap_delete"))
|
||||
register_action(ACTION[:snap_revert].to_sym, method("snap_revert"))
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -131,6 +134,11 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
do_image_action(id, ds, :snap_delete, "#{drv_message} #{id}")
|
||||
end
|
||||
|
||||
def snap_revert(id, drv_message)
|
||||
ds = get_ds_type(drv_message)
|
||||
do_image_action(id, ds, :snap_revert, "#{drv_message} #{id}")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_available?(ds, id, action)
|
||||
|
@ -1015,4 +1015,78 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::revert_snapshot(int iid, int sid, string& error)
|
||||
{
|
||||
const ImageManagerDriver* imd = get();
|
||||
|
||||
if ( imd == 0 )
|
||||
{
|
||||
error = "Could not get datastore driver";
|
||||
NebulaLog::log("ImM",Log::ERROR, error);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Image * img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
error = "Image does not exist";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const Snapshots& snaps = img->get_snapshots();
|
||||
|
||||
if (snaps.get_active_id() == sid)
|
||||
{
|
||||
error = "Snapshot is already the active one";
|
||||
|
||||
img->unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ds_id = img->get_ds_id();
|
||||
|
||||
img->unlock();
|
||||
|
||||
string ds_data;
|
||||
|
||||
Datastore * ds = dspool->get(ds_id, true);
|
||||
|
||||
if ( ds == 0 )
|
||||
{
|
||||
error = "Datastore no longer exists";
|
||||
return -1;
|
||||
}
|
||||
|
||||
ds->to_xml(ds_data);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
error = "Image does not exist";
|
||||
return -1;
|
||||
}
|
||||
|
||||
img->set_target_snapshot(sid);
|
||||
|
||||
string img_tmpl;
|
||||
string * drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
|
||||
|
||||
imd->snapshot_revert(iid, *drv_msg);
|
||||
|
||||
ipool->update(img);
|
||||
|
||||
img->unlock();
|
||||
|
||||
delete drv_msg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -753,6 +753,60 @@ static void snap_delete_action(istringstream& is,
|
||||
image->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void snap_revert_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
ostringstream oss;
|
||||
string info;
|
||||
|
||||
Image * image = ipool->get(id, true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int snap_id = image->get_target_snapshot();
|
||||
|
||||
if (snap_id == -1)
|
||||
{
|
||||
NebulaLog::log("ImM", Log::ERROR, "No target snapshot in callback");
|
||||
|
||||
image->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( result == "SUCCESS")
|
||||
{
|
||||
image->revert_snapshot(snap_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "Error reverting image " << id << " to snapshot " << snap_id;
|
||||
|
||||
getline(is, info);
|
||||
|
||||
if (!info.empty() && (info[0] != '-'))
|
||||
{
|
||||
oss << ": " << info;
|
||||
}
|
||||
|
||||
image->set_template_error_message(oss.str());
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
}
|
||||
|
||||
image->clear_target_snapshot();
|
||||
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -832,6 +886,10 @@ void ImageManagerDriver::protocol(const string& message) const
|
||||
{
|
||||
snap_delete_action(is, ipool, id, result);
|
||||
}
|
||||
else if (action == "SNAP_REVERT")
|
||||
{
|
||||
snap_revert_action(is, ipool, id, result);
|
||||
}
|
||||
else if (action == "LOG")
|
||||
{
|
||||
getline(is,info);
|
||||
|
@ -24,7 +24,6 @@ module OpenNebula
|
||||
# Constants and Class Methods
|
||||
#######################################################################
|
||||
|
||||
|
||||
IMAGE_METHODS = {
|
||||
:info => "image.info",
|
||||
:allocate => "image.allocate",
|
||||
@ -37,7 +36,8 @@ module OpenNebula
|
||||
:chtype => "image.chtype",
|
||||
:clone => "image.clone",
|
||||
:rename => "image.rename",
|
||||
:snapshotdelete => "image.snapshotdelete"
|
||||
:snapshotdelete => "image.snapshotdelete",
|
||||
:snapshotrevert => "image.snapshotrevert"
|
||||
}
|
||||
|
||||
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR CLONE DELETE USED_PERS}
|
||||
@ -234,6 +234,15 @@ module OpenNebula
|
||||
return call(IMAGE_METHODS[:snapshotdelete], @pe_id, snap_id)
|
||||
end
|
||||
|
||||
# Reverts Image state to a previous snapshot
|
||||
#
|
||||
# @param snap_id [Integet] ID of the snapshot to delete
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success or Error
|
||||
def snapshot_revert(snap_id)
|
||||
return call(IMAGE_METHODS[:snapshotrevert], @pe_id, snap_id)
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Helpers to get Image information
|
||||
#######################################################################
|
||||
|
@ -398,6 +398,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr image_chtype(new ImageChangeType());
|
||||
xmlrpc_c::methodPtr image_clone(new ImageClone());
|
||||
xmlrpc_c::methodPtr image_snap_delete(new ImageSnapshotDelete());
|
||||
xmlrpc_c::methodPtr image_snap_revert(new ImageSnapshotRevert());
|
||||
|
||||
// Datastore Methods
|
||||
xmlrpc_c::methodPtr datastore_enable(new DatastoreEnable());
|
||||
@ -655,6 +656,7 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.image.clone", image_clone);
|
||||
RequestManagerRegistry.addMethod("one.image.rename", image_rename);
|
||||
RequestManagerRegistry.addMethod("one.image.snapshotdelete", image_snap_delete);
|
||||
RequestManagerRegistry.addMethod("one.image.snapshotrevert", image_snap_revert);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
||||
|
||||
|
@ -498,3 +498,33 @@ void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
success_response(id, att);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
if ( basic_authorization(id, att) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string err_msg;
|
||||
int rc = imagem->revert_snapshot(id, snap_id, err_msg);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
failure_response(ACTION, request_error(err_msg, ""), att);
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user