1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-26 06:50:09 +03:00

feature #1696: Clone now supports a target datastore for images

This commit is contained in:
Ruben S. Montero 2014-06-26 02:13:34 +02:00
parent 752888b043
commit 3fb497730d
4 changed files with 85 additions and 17 deletions

View File

@ -114,6 +114,15 @@ public:
return tm_mad;
};
/**
* Retrieves DS mad name
* @return string ds mad name
*/
const string& get_ds_mad() const
{
return ds_mad;
};
/**
* Retrieves the base path
* @return base path string

View File

@ -161,9 +161,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Creates a new Image from an existing one
EOT
command :clone, clone_desc, :imageid, :name do
command :clone, clone_desc, :imageid, :name,
:options=>[OneDatastoreHelper::DATASTORE] do
helper.perform_action(args[0],options,"cloned") do |image|
res = image.clone(args[1])
ds_id = options[:datastore] || -1 # -1 clones to self
res = image.clone(args[1], ds_id)
if !OpenNebula.is_error?(res)
puts "ID: #{res}"

View File

@ -206,10 +206,10 @@ module OpenNebula
#
# @return [Integer, OpenNebula::Error] The new Image ID in case
# of success, Error otherwise
def clone(name)
def clone(name, target_ds=-1)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(IMAGE_METHODS[:clone], @pe_id, name)
rc = @client.call(IMAGE_METHODS[:clone], @pe_id, name, target_ds)
return rc
end

View File

@ -230,12 +230,12 @@ void ImageClone::request_execute(
string name = xmlrpc_c::value_string(paramList.getString(2));
long long avail, size;
int rc, new_id, ds_id;
string error_str, ds_name, ds_data;
int rc, new_id, ds_id_orig, ds_id = -1;
string error_str, ds_name, ds_data, ds_mad;
bool ds_check;
Image::DiskType disk_type;
PoolObjectAuth perms, ds_perms;
PoolObjectAuth perms, ds_perms, ds_perms_orig;
ImageTemplate * tmpl;
Template img_usage;
@ -247,6 +247,11 @@ void ImageClone::request_execute(
DatastorePool * dspool = nd.get_dspool();
ImagePool * ipool = static_cast<ImagePool *>(pool);
if (paramList.size() > 3)
{
ds_id = xmlrpc_c::value_int(paramList.getInt(3));
}
// ------------------------- Get source Image info -------------------------
img = ipool->get(clone_id, true);
@ -281,13 +286,18 @@ void ImageClone::request_execute(
img->get_permissions(perms);
ds_id = img->get_ds_id();
ds_name = img->get_ds_name();
size = img->get_size();
if (ds_id == -1) //Target Datastore not set, use the current one
{
ds_id = img->get_ds_id();
}
ds_id_orig = img->get_ds_id();
size = img->get_size();
img->unlock();
// ------------------------- Get Datastore info ----------------------------
// ----------------------- Get target Datastore info -----------------------
ds = dspool->get(ds_id, true);
@ -301,15 +311,14 @@ void ImageClone::request_execute(
return;
}
if ( ds->get_type() == Datastore::FILE_DS )
if ( ds->get_type() != Datastore::IMAGE_DS )
{
failure_response(ACTION, "Clone not supported for FILE_DS Datastores",
att);
delete tmpl;
failure_response(ACTION,
request_error("Clone only supported for IMAGE_DS Datastores",""),att);
ds->unlock();
delete tmpl;
return;
}
@ -320,9 +329,51 @@ void ImageClone::request_execute(
ds->to_xml(ds_data);
ds_check = ds->get_avail_mb(avail);
ds_name = ds->get_name();
ds_mad = ds->get_ds_mad();
ds->unlock();
if (ds_id != ds_id_orig) //check same DS_MAD
{
ds = dspool->get(ds_id_orig, true);
if (ds == 0)
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE),ds_id_orig),att);
delete tmpl;
return;
}
if (ds->get_type() != Datastore::IMAGE_DS)
{
failure_response(ACTION, request_error(
"Clone only supported for IMAGE_DS Datastores",""), att);
ds->unlock();
delete tmpl;
return;
}
if (ds->get_ds_mad() != ds_mad)
{
failure_response(ACTION, request_error(
"Clone only supported to same DS_MAD Datastores",""), att);
ds->unlock();
delete tmpl;
return;
}
ds->get_permissions(ds_perms_orig);
ds->unlock();
}
// ------------- Set authorization request ---------------------------------
img_usage.add("DATASTORE", ds_id);
@ -330,7 +381,8 @@ void ImageClone::request_execute(
if (ds_check && (size > avail))
{
failure_response(ACTION, "Not enough space in datastore", att);
failure_response(ACTION,
request_error("Not enough space in datastore",""), att);
delete tmpl;
return;
@ -349,6 +401,11 @@ void ImageClone::request_execute(
ar.add_auth(AuthRequest::USE, ds_perms); // USE DATASTORE
if (ds_id != ds_id_orig) // USE (original) DATASTORE
{
ar.add_auth(AuthRequest::USE, ds_perms_orig); // USE DATASTORE
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,