mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-25 02:50:08 +03:00
feature #3782: Flatten action for Images
This commit is contained in:
parent
0bbb99a240
commit
08356ed8c3
@ -496,6 +496,14 @@ public:
|
||||
return snapshots;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear all the snapshots in the list
|
||||
*/
|
||||
void clear_snapshots()
|
||||
{
|
||||
snapshots.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the snapshots for this image
|
||||
* @param snapshot list
|
||||
|
@ -217,6 +217,15 @@ public:
|
||||
*/
|
||||
int revert_snapshot(int iid, int sid, string& error);
|
||||
|
||||
/**
|
||||
* Flattens ths snapshot by commiting changes to base image.
|
||||
* @param iid id of image
|
||||
* @param sid id of the snapshot
|
||||
* @param error_str Error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int flatten_snapshot(int iid, int sid, string& error);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generic name for the Image driver
|
||||
|
@ -100,6 +100,19 @@ public:
|
||||
*/
|
||||
int active_snapshot(unsigned int id);
|
||||
|
||||
/**
|
||||
* Clear all the snapshots in the list
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
next_snapshot = 0;
|
||||
active = -1;
|
||||
disk_id = -1;
|
||||
|
||||
snapshot_template.clear();
|
||||
snapshot_pool.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the disk_id of the snapshot list
|
||||
*/
|
||||
|
@ -321,6 +321,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
snapshot_flatten_desc = <<-EOT.unindent
|
||||
Flattens the snapshot and removes all other snapshots in the image
|
||||
EOT
|
||||
|
||||
command :"snapshot-flatten", snapshot_flatten_desc, :imageid, :snapshot_id do
|
||||
helper.perform_action(args[0], options, "snapshot flattened") do |o|
|
||||
o.snapshot_flatten(args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists Images in the pool
|
||||
EOT
|
||||
|
@ -52,7 +52,8 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
:clone => "CLONE",
|
||||
:monitor => "MONITOR",
|
||||
:snap_delete => "SNAP_DELETE",
|
||||
:snap_revert => "SNAP_REVERT"
|
||||
:snap_revert => "SNAP_REVERT",
|
||||
:snap_flatten=> "SNAP_FLATTEN"
|
||||
}
|
||||
|
||||
# Register default actions for the protocol
|
||||
@ -69,7 +70,8 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
ACTION[:clone] => nil,
|
||||
ACTION[:monitor] => nil,
|
||||
ACTION[:snap_delete] => nil,
|
||||
ACTION[:snap_revert] => nil
|
||||
ACTION[:snap_revert] => nil,
|
||||
ACTION[:snap_flatten] => nil
|
||||
}
|
||||
}.merge!(options)
|
||||
|
||||
@ -93,6 +95,7 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
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"))
|
||||
register_action(ACTION[:snap_flatten].to_sym, method("snap_flatten"))
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -139,6 +142,11 @@ class DatastoreDriver < OpenNebulaDriver
|
||||
do_image_action(id, ds, :snap_revert, "#{drv_message} #{id}")
|
||||
end
|
||||
|
||||
def snap_flatten(id, drv_message)
|
||||
ds = get_ds_type(drv_message)
|
||||
do_image_action(id, ds, :snap_flatten, "#{drv_message} #{id}")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_available?(ds, id, action)
|
||||
|
@ -1129,3 +1129,99 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::flatten_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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Check action consistency: */
|
||||
/* state is READY */
|
||||
/* snapshot exists */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Image * img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
error = "Image does not exist";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (img->get_state() != Image::READY)
|
||||
{
|
||||
error = "Cannot flatten snapshot in state " + Image::state_to_str(img->get_state());
|
||||
img->unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const Snapshots& snaps = img->get_snapshots();
|
||||
|
||||
if (!snaps.exists(sid))
|
||||
{
|
||||
error = "Snapshot does not exist";
|
||||
|
||||
img->unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Get DS data for driver */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
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();
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Format message and send action to driver */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
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_flatten(iid, *drv_msg);
|
||||
|
||||
img->set_state(Image::LOCKED);
|
||||
|
||||
ipool->update(img);
|
||||
|
||||
img->unlock();
|
||||
|
||||
delete drv_msg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -815,6 +815,52 @@ static void snap_revert_action(istringstream& is,
|
||||
image->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void snap_flatten_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
ostringstream oss;
|
||||
string info;
|
||||
|
||||
Image * image = ipool->get(id, true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( result == "SUCCESS")
|
||||
{
|
||||
image->clear_snapshots();
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "Error flattening image snapshot";
|
||||
|
||||
getline(is, info);
|
||||
|
||||
if (!info.empty() && (info[0] != '-'))
|
||||
{
|
||||
oss << ": " << info;
|
||||
}
|
||||
|
||||
image->set_template_error_message(oss.str());
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
}
|
||||
|
||||
image->set_state(Image::READY);
|
||||
|
||||
image->clear_target_snapshot();
|
||||
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -898,6 +944,10 @@ void ImageManagerDriver::protocol(const string& message) const
|
||||
{
|
||||
snap_revert_action(is, ipool, id, result);
|
||||
}
|
||||
else if (action == "SNAP_FLATTEN")
|
||||
{
|
||||
snap_flatten_action(is, ipool, id, result);
|
||||
}
|
||||
else if (action == "LOG")
|
||||
{
|
||||
getline(is,info);
|
||||
|
@ -37,7 +37,8 @@ module OpenNebula
|
||||
:clone => "image.clone",
|
||||
:rename => "image.rename",
|
||||
:snapshotdelete => "image.snapshotdelete",
|
||||
:snapshotrevert => "image.snapshotrevert"
|
||||
:snapshotrevert => "image.snapshotrevert",
|
||||
:snapshotflatten=> "image.snapshotflatten"
|
||||
}
|
||||
|
||||
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR CLONE DELETE USED_PERS}
|
||||
@ -243,6 +244,14 @@ module OpenNebula
|
||||
return call(IMAGE_METHODS[:snapshotrevert], @pe_id, snap_id)
|
||||
end
|
||||
|
||||
# Flattens an image snapshot
|
||||
#
|
||||
# @param snap_id [Integet] ID of the snapshot to flatten
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success or Error
|
||||
def snapshot_flatten(snap_id)
|
||||
return call(IMAGE_METHODS[:snapshotflatten], @pe_id, snap_id)
|
||||
end
|
||||
#######################################################################
|
||||
# Helpers to get Image information
|
||||
#######################################################################
|
||||
|
@ -399,6 +399,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr image_clone(new ImageClone());
|
||||
xmlrpc_c::methodPtr image_snap_delete(new ImageSnapshotDelete());
|
||||
xmlrpc_c::methodPtr image_snap_revert(new ImageSnapshotRevert());
|
||||
xmlrpc_c::methodPtr image_snap_flatten(new ImageSnapshotFlatten());
|
||||
|
||||
// Datastore Methods
|
||||
xmlrpc_c::methodPtr datastore_enable(new DatastoreEnable());
|
||||
@ -657,6 +658,7 @@ void RequestManager::register_xml_methods()
|
||||
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.image.snapshotflatten", image_snap_flatten);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
||||
|
||||
|
@ -498,7 +498,6 @@ void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
success_response(id, att);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@ -528,3 +527,32 @@ void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
success_response(id, att);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void ImageSnapshotFlatten::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->flatten_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