mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-02 10:50:07 +03:00
Feature #4400: New param to clone templates recursively
This commit is contained in:
parent
f6bd738af2
commit
01a0079f0c
@ -213,10 +213,19 @@ public:
|
||||
* Gets the IDs of the images associated to a set of disks
|
||||
* @param dsk a vector with the DISK attributes
|
||||
* @param ids set of image ids
|
||||
* @param uid effective user id makeing the call
|
||||
* @param uid effective user id making the call
|
||||
*/
|
||||
void get_image_ids(vector<VectorAttribute *>& dsk, set<int>& ids, int uid);
|
||||
|
||||
/**
|
||||
* Gets the IDs of the images associated to a set of disks
|
||||
* @param disk DISK attribute
|
||||
* @param ids the image id, if found
|
||||
* @param uid effective user id making the call
|
||||
* @return 0 if the disk uses an image, -1 otherwise
|
||||
*/
|
||||
int get_image_id(VectorAttribute * disk, int &id, int uid);
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------------
|
||||
// Configuration Attributes for Images
|
||||
|
@ -299,6 +299,26 @@ protected:
|
||||
bool basic_authorization(int oid, AuthRequest::Operation op,
|
||||
RequestAttributes& att);
|
||||
|
||||
/**
|
||||
* Performs a basic authorization for this request using the uid/gid
|
||||
* from the request. The function gets the object from the pool to get
|
||||
* the public attribute and its owner. The authorization is based on
|
||||
* object and type of operation for the request.
|
||||
* @param pool object pool
|
||||
* @param oid of the object, can be -1 for objects to be created, or
|
||||
* pools.
|
||||
* @param op operation of the request.
|
||||
* @param att the specific request attributes
|
||||
*
|
||||
* @return SUCCESS if the user is authorized.
|
||||
*/
|
||||
static ErrorCode basic_authorization(
|
||||
PoolSQL* pool,
|
||||
int oid,
|
||||
AuthRequest::Operation op,
|
||||
PoolObjectSQL::ObjectType auth_object,
|
||||
RequestAttributes& att);
|
||||
|
||||
/**
|
||||
* Performs a basic quota check for this request using the uid/gid
|
||||
* from the request. Usage counters are updated for the user/group.
|
||||
|
@ -42,6 +42,12 @@ protected:
|
||||
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
||||
ErrorCode clone(
|
||||
int source_id,
|
||||
const string &name,
|
||||
int &new_id,
|
||||
RequestAttributes& att);
|
||||
|
||||
virtual Template * clone_template(PoolObjectSQL* obj) = 0;
|
||||
|
||||
virtual int pool_allocate(
|
||||
@ -59,7 +65,8 @@ class VMTemplateClone : public RequestManagerClone
|
||||
public:
|
||||
VMTemplateClone():
|
||||
RequestManagerClone("VMTemplateClone",
|
||||
"Clone an existing virtual machine template")
|
||||
"Clone an existing virtual machine template",
|
||||
"A:sisb")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_tpool();
|
||||
@ -72,6 +79,9 @@ public:
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void request_execute(
|
||||
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
|
||||
|
||||
Template * clone_template(PoolObjectSQL* obj)
|
||||
{
|
||||
return static_cast<VMTemplate*>(obj)->clone_template();
|
||||
|
@ -107,6 +107,8 @@ public:
|
||||
|
||||
void request_execute(
|
||||
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
|
||||
|
||||
static ErrorCode request_execute(int oid, bool recursive, RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -80,6 +80,11 @@ public:
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
||||
static ErrorCode request_execute(
|
||||
int id,
|
||||
bool persistent_flag,
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -117,6 +122,13 @@ public:
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
||||
static ErrorCode clone_img(
|
||||
int clone_id,
|
||||
const string &name,
|
||||
int ds_id,
|
||||
int &new_id,
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -88,6 +88,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces the current DISK attributes with the given ones. The objects
|
||||
// must NOT be deleted by the calling function
|
||||
void replace_disks(vector<VectorAttribute *>& disks)
|
||||
{
|
||||
vector<VectorAttribute *>::iterator i;
|
||||
|
||||
obj_template->erase("DISK");
|
||||
|
||||
for (i = disks.begin(); i != disks.end(); i++)
|
||||
{
|
||||
obj_template->set(*i);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Virtual Router
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -550,7 +550,6 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
|
||||
ar->add_auth(AuthRequest::USE, perm);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -559,36 +558,52 @@ void ImagePool::get_image_ids(vector<VectorAttribute *>& disks, set<int>& ids,
|
||||
{
|
||||
vector<VectorAttribute *>::iterator i;
|
||||
|
||||
int id;
|
||||
|
||||
for ( i = disks.begin() ; i != disks.end(); ++i )
|
||||
{
|
||||
if ( get_image_id(*i, id, uid) == 0 )
|
||||
{
|
||||
ids.insert(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::get_image_id(VectorAttribute * disk, int &id, int uid)
|
||||
{
|
||||
int iid;
|
||||
string iname;
|
||||
|
||||
Image * img = 0;
|
||||
|
||||
for ( i = disks.begin() ; i != disks.end(); ++i )
|
||||
if ( disk->vector_value("IMAGE_ID", iid) == 0 )
|
||||
{
|
||||
if ( (*i)->vector_value("IMAGE_ID", iid) == 0 )
|
||||
{
|
||||
ids.insert(iid);
|
||||
}
|
||||
else if ( (*i)->vector_value("IMAGE", iname) == 0 )
|
||||
{
|
||||
int uiid = get_disk_uid(*i, uid);
|
||||
|
||||
if ( uiid == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
img = get(iname, uiid, true);
|
||||
|
||||
if ( img != 0 )
|
||||
{
|
||||
ids.insert(img->get_oid());
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
}
|
||||
id = iid;
|
||||
return 0;
|
||||
}
|
||||
else if ( disk->vector_value("IMAGE", iname) == 0 )
|
||||
{
|
||||
int uiid = get_disk_uid(disk, uid);
|
||||
|
||||
if ( uiid == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
img = get(iname, uiid, true);
|
||||
|
||||
if ( img != 0 )
|
||||
{
|
||||
id = img->get_oid();
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -302,6 +302,29 @@ void Request::execute(
|
||||
bool Request::basic_authorization(int oid,
|
||||
AuthRequest::Operation op,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
ErrorCode ec = basic_authorization(pool, oid, op, auth_object, att);
|
||||
|
||||
if (ec == SUCCESS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_response(ec, att);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode Request::basic_authorization(
|
||||
PoolSQL* pool,
|
||||
int oid,
|
||||
AuthRequest::Operation op,
|
||||
PoolObjectSQL::ObjectType auth_object,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
PoolObjectSQL * object;
|
||||
PoolObjectAuth perms;
|
||||
@ -313,14 +336,14 @@ bool Request::basic_authorization(int oid,
|
||||
if ( object == 0 )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return false;
|
||||
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
if ( att.uid == 0 )
|
||||
{
|
||||
object->unlock();
|
||||
return true;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
object->get_permissions(perms);
|
||||
@ -331,7 +354,7 @@ bool Request::basic_authorization(int oid,
|
||||
{
|
||||
if ( att.uid == 0 )
|
||||
{
|
||||
return true;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
perms.obj_type = auth_object;
|
||||
@ -344,12 +367,11 @@ bool Request::basic_authorization(int oid,
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
att.resp_msg = ar.message;
|
||||
failure_response(AUTHORIZATION, att);
|
||||
|
||||
return false;
|
||||
return AUTHORIZATION;
|
||||
}
|
||||
|
||||
return true;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -15,6 +15,8 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "RequestManagerClone.h"
|
||||
#include "RequestManagerImage.h"
|
||||
#include "RequestManagerDelete.h"
|
||||
#include "PoolObjectAuth.h"
|
||||
#include "Nebula.h"
|
||||
|
||||
@ -28,7 +30,30 @@ void RequestManagerClone::request_execute(
|
||||
int source_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
string name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
|
||||
int rc, new_id;
|
||||
int new_id;
|
||||
|
||||
ErrorCode ec = clone(source_id, name, new_id, att);
|
||||
|
||||
if ( ec == SUCCESS )
|
||||
{
|
||||
success_response(new_id, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_response(ec, att);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode RequestManagerClone::clone(
|
||||
int source_id,
|
||||
const string &name,
|
||||
int &new_id,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int rc;
|
||||
|
||||
PoolObjectAuth perms;
|
||||
|
||||
@ -40,8 +65,7 @@ void RequestManagerClone::request_execute(
|
||||
if ( source_obj == 0 )
|
||||
{
|
||||
att.resp_id = source_id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
tmpl = clone_template(source_obj);
|
||||
@ -68,10 +92,9 @@ void RequestManagerClone::request_execute(
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
att.resp_msg = ar.message;
|
||||
failure_response(AUTHORIZATION, att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return AUTHORIZATION;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +102,174 @@ void RequestManagerClone::request_execute(
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
failure_response(ALLOCATE, att);
|
||||
return;
|
||||
return ALLOCATE;
|
||||
}
|
||||
|
||||
success_response(new_id, att);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMTemplateClone::request_execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int source_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
string name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
bool recursive = false;
|
||||
|
||||
if (paramList.size() > 3)
|
||||
{
|
||||
recursive = xmlrpc_c::value_boolean(paramList.getBoolean(3));
|
||||
}
|
||||
|
||||
int new_id;
|
||||
VMTemplate * vmtmpl;
|
||||
VMTemplatePool* tpool = static_cast<VMTemplatePool*>(pool);
|
||||
ErrorCode ec;
|
||||
ostringstream oss;
|
||||
|
||||
vector<VectorAttribute *> disks;
|
||||
vector<int> new_img_ids;
|
||||
vector<int>::iterator i;
|
||||
|
||||
RequestAttributes img_att(att);
|
||||
img_att.resp_obj = PoolObjectSQL::IMAGE;
|
||||
|
||||
ec = clone(source_id, name, new_id, att);
|
||||
|
||||
if ( ec != SUCCESS )
|
||||
{
|
||||
failure_response(ec, att);
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImagePool* ipool = nd.get_ipool();
|
||||
|
||||
int img_id;
|
||||
int new_img_id;
|
||||
|
||||
vmtmpl = tpool->get(new_id, true);
|
||||
|
||||
if (vmtmpl == 0)
|
||||
{
|
||||
att.resp_msg = object_name(PoolObjectSQL::TEMPLATE) +
|
||||
" was cloned, but it was deleted before the disks could also be cloned.";
|
||||
|
||||
failure_response(ACTION, att);
|
||||
return;
|
||||
}
|
||||
|
||||
vmtmpl->get_disks(disks);
|
||||
|
||||
vmtmpl->unlock();
|
||||
|
||||
int ndisk = 0;
|
||||
|
||||
for (vector<VectorAttribute*>::iterator it = disks.begin(); it != disks.end(); it++)
|
||||
{
|
||||
if (ipool->get_image_id(*it, img_id, att.uid) == 0)
|
||||
{
|
||||
oss.str("");
|
||||
|
||||
oss << name << "-disk-" << ndisk;
|
||||
|
||||
ec = ImageClone::clone_img(img_id, oss.str(), -1, new_img_id, img_att);
|
||||
|
||||
if ( ec == SUCCESS)
|
||||
{
|
||||
ec = ImagePersistent::request_execute(new_img_id, true, img_att);
|
||||
|
||||
if (ec != SUCCESS)
|
||||
{
|
||||
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, img_att));
|
||||
|
||||
ImageDelete::delete_img(img_id, img_att);
|
||||
|
||||
att.resp_msg = "Failure while making the cloned "
|
||||
"images persistent. "+img_att.resp_msg;
|
||||
|
||||
goto error_images;
|
||||
}
|
||||
|
||||
(*it)->remove("IMAGE");
|
||||
(*it)->remove("IMAGE_UNAME");
|
||||
(*it)->remove("IMAGE_UID");
|
||||
|
||||
(*it)->replace("IMAGE_ID", new_img_id);
|
||||
|
||||
new_img_ids.push_back(new_img_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, img_att));
|
||||
|
||||
att.resp_msg = "Failure while cloning the "
|
||||
"template images. "+img_att.resp_msg;
|
||||
|
||||
goto error_images;
|
||||
}
|
||||
}
|
||||
|
||||
ndisk++;
|
||||
}
|
||||
|
||||
vmtmpl = tpool->get(new_id, true);
|
||||
|
||||
if (vmtmpl == 0)
|
||||
{
|
||||
att.resp_msg = "The template was cloned, but it was deleted "
|
||||
"before the disks could also be cloned.";
|
||||
|
||||
goto error_template;
|
||||
}
|
||||
|
||||
vmtmpl->replace_disks(disks);
|
||||
|
||||
tpool->update(vmtmpl);
|
||||
|
||||
vmtmpl->unlock();
|
||||
}
|
||||
|
||||
success_response(new_id, att);
|
||||
|
||||
return;
|
||||
|
||||
error_images:
|
||||
|
||||
ec = TemplateDelete::request_execute(new_id, false, att);
|
||||
|
||||
if (ec != SUCCESS)
|
||||
{
|
||||
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, att));
|
||||
}
|
||||
|
||||
goto error_template;
|
||||
|
||||
error_template:
|
||||
|
||||
for (i = new_img_ids.begin(); i != new_img_ids.end(); i++)
|
||||
{
|
||||
ec = ImageDelete::delete_img(*i, att);
|
||||
|
||||
if (ec != SUCCESS)
|
||||
{
|
||||
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, img_att));
|
||||
}
|
||||
}
|
||||
|
||||
for (vector<VectorAttribute *>::iterator i = disks.begin() ;
|
||||
i != disks.end() ; i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -154,7 +154,33 @@ void TemplateDelete::request_execute(
|
||||
int oid = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
bool recursive = false;
|
||||
|
||||
VMTemplate * object;
|
||||
if (paramList.size() > 2)
|
||||
{
|
||||
recursive = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
}
|
||||
|
||||
ErrorCode ec = request_execute(oid, recursive, att);
|
||||
|
||||
if ( ec == SUCCESS )
|
||||
{
|
||||
success_response(oid, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_response(ec, att);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode TemplateDelete::request_execute(
|
||||
int oid, bool recursive, RequestAttributes& att)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
AclManager * aclm = nd.get_aclm();
|
||||
VMTemplatePool * pool = nd.get_tpool();
|
||||
VMTemplate * object;
|
||||
|
||||
string error_msg;
|
||||
set<int> error_ids;
|
||||
@ -163,26 +189,19 @@ void TemplateDelete::request_execute(
|
||||
|
||||
vector<VectorAttribute *> disks;
|
||||
|
||||
if (paramList.size() > 2)
|
||||
{
|
||||
recursive = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
}
|
||||
|
||||
ec = delete_authorization(pool, oid, auth_op, att);
|
||||
ec = delete_authorization(pool, oid, AuthRequest::MANAGE, att);
|
||||
|
||||
if ( ec != SUCCESS )
|
||||
{
|
||||
failure_response(ec, att);
|
||||
return;
|
||||
return ec;
|
||||
}
|
||||
|
||||
object = static_cast<VMTemplatePool*>(pool)->get(oid, true);
|
||||
object = pool->get(oid, true);
|
||||
|
||||
if ( object == 0 )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
int rc = pool->drop(object, error_msg);
|
||||
@ -196,16 +215,14 @@ void TemplateDelete::request_execute(
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
att.resp_msg = "Cannot delete " + object_name(auth_object) + ". " + error_msg;
|
||||
failure_response(ACTION, att);
|
||||
return;
|
||||
att.resp_msg = "Cannot delete " + object_name(PoolObjectSQL::TEMPLATE) + ". " + error_msg;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
aclm->del_resource_rules(oid, auth_object);
|
||||
aclm->del_resource_rules(oid, PoolObjectSQL::TEMPLATE);
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImagePool* ipool = nd.get_ipool();
|
||||
|
||||
ipool->get_image_ids(disks, img_ids, att.uid);
|
||||
@ -214,7 +231,7 @@ void TemplateDelete::request_execute(
|
||||
{
|
||||
if ( ImageDelete::delete_img(*it, att) != SUCCESS )
|
||||
{
|
||||
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, att));
|
||||
NebulaLog::log("ReM", Log::ERROR, att.resp_msg);
|
||||
|
||||
error_ids.insert(*it);
|
||||
rc = -1;
|
||||
@ -234,13 +251,10 @@ void TemplateDelete::request_execute(
|
||||
": " + one_util::join<set<int>::iterator>(error_ids.begin(),
|
||||
error_ids.end(), ',');
|
||||
|
||||
failure_response(ACTION, att);
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
success_response(oid, att);
|
||||
|
||||
return;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -64,30 +64,56 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
{
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
bool persistent_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
|
||||
ErrorCode ec = request_execute(id, persistent_flag, att);
|
||||
|
||||
if ( ec == SUCCESS )
|
||||
{
|
||||
success_response(id, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_response(ec, att);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode ImagePersistent::request_execute(
|
||||
int id,
|
||||
bool persistent_flag,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int rc;
|
||||
|
||||
int ds_id;
|
||||
int ds_persistent_only;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImagePool * ipool = nd.get_ipool();
|
||||
DatastorePool * dspool = nd.get_dspool();
|
||||
|
||||
Datastore * ds;
|
||||
Image * image;
|
||||
|
||||
if ( basic_authorization(id, att) == false )
|
||||
ErrorCode ec;
|
||||
|
||||
ec = basic_authorization(ipool, id,
|
||||
AuthRequest::MANAGE, PoolObjectSQL::IMAGE, att);
|
||||
|
||||
if ( ec != SUCCESS)
|
||||
{
|
||||
return;
|
||||
return ec;
|
||||
}
|
||||
|
||||
image = static_cast<Image *>(pool->get(id,true));
|
||||
image = ipool->get(id,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
att.resp_id = id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
ds_id = image->get_ds_id();
|
||||
@ -99,23 +125,21 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
if ( ds == 0 )
|
||||
{
|
||||
att.resp_msg = "Datastore no longer exists.";
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
return;
|
||||
return INTERNAL;
|
||||
}
|
||||
|
||||
ds_persistent_only = ds->is_persistent_only();
|
||||
|
||||
ds->unlock();
|
||||
|
||||
image = static_cast<Image *>(pool->get(id,true));
|
||||
image = ipool->get(id,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
att.resp_id = id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
switch (image->get_type())
|
||||
@ -129,19 +153,19 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
case Image::RAMDISK:
|
||||
case Image::CONTEXT:
|
||||
att.resp_msg = "KERNEL, RAMDISK and CONTEXT must be non-persistent";
|
||||
failure_response(ACTION, att);
|
||||
image->unlock();
|
||||
return;
|
||||
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
/* Check if datastore allows the operation */
|
||||
if ( ds_persistent_only && persistent_flag == false )
|
||||
{
|
||||
att.resp_msg = "This Datastore only accepts persistent images.";
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
image->unlock();
|
||||
return;
|
||||
|
||||
return INTERNAL;
|
||||
}
|
||||
|
||||
rc = image->persistent(persistent_flag, att.resp_msg);
|
||||
@ -157,17 +181,16 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
att.resp_msg = "Could not make image non-persistent: " + att.resp_msg;
|
||||
}
|
||||
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
image->unlock();
|
||||
return;
|
||||
|
||||
return INTERNAL;
|
||||
}
|
||||
|
||||
pool->update(image);
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
success_response(id, att);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -261,8 +284,39 @@ void ImageClone::request_execute(
|
||||
int clone_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
string name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
|
||||
int new_id;
|
||||
|
||||
int ds_id = -1;
|
||||
|
||||
if (paramList.size() > 3)
|
||||
{
|
||||
ds_id = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
}
|
||||
|
||||
ErrorCode ec = clone_img(clone_id, name, ds_id, new_id, att);
|
||||
|
||||
if ( ec == SUCCESS )
|
||||
{
|
||||
success_response(new_id, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_response(ec, att);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode ImageClone::clone_img(
|
||||
int clone_id,
|
||||
const string& name,
|
||||
int ds_id,
|
||||
int &new_id,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
long long avail, size;
|
||||
int rc, new_id, ds_id_orig, ds_id = -1;
|
||||
int rc, ds_id_orig;
|
||||
string ds_name, ds_data, ds_mad;
|
||||
bool ds_check;
|
||||
|
||||
@ -277,12 +331,8 @@ void ImageClone::request_execute(
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
DatastorePool * dspool = nd.get_dspool();
|
||||
ImagePool * ipool = static_cast<ImagePool *>(pool);
|
||||
ImagePool * ipool = nd.get_ipool();
|
||||
|
||||
if (paramList.size() > 3)
|
||||
{
|
||||
ds_id = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
}
|
||||
|
||||
// ------------------------- Get source Image info -------------------------
|
||||
|
||||
@ -291,8 +341,7 @@ void ImageClone::request_execute(
|
||||
if ( img == 0 )
|
||||
{
|
||||
att.resp_id = clone_id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
switch (img->get_type())
|
||||
@ -306,9 +355,8 @@ void ImageClone::request_execute(
|
||||
case Image::RAMDISK:
|
||||
case Image::CONTEXT:
|
||||
att.resp_msg = "KERNEL, RAMDISK and CONTEXT cannot be cloned.";
|
||||
failure_response(ACTION, att);
|
||||
img->unlock();
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
const Snapshots& snaps = img->get_snapshots();
|
||||
@ -316,9 +364,8 @@ void ImageClone::request_execute(
|
||||
if (snaps.size () > 0)
|
||||
{
|
||||
att.resp_msg = "Cannot clone images with snapshots";
|
||||
failure_response(ACTION, att);
|
||||
img->unlock();
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
tmpl = img->clone_template(name);
|
||||
@ -344,21 +391,19 @@ void ImageClone::request_execute(
|
||||
{
|
||||
att.resp_obj = PoolObjectSQL::DATASTORE;
|
||||
att.resp_id = ds_id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
if ( ds->get_type() != Datastore::IMAGE_DS )
|
||||
{
|
||||
att.resp_msg = "Clone only supported for IMAGE_DS Datastores";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
ds->get_permissions(ds_perms);
|
||||
@ -381,32 +426,29 @@ void ImageClone::request_execute(
|
||||
{
|
||||
att.resp_obj = PoolObjectSQL::DATASTORE;
|
||||
att.resp_id = ds_id_orig;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return NO_EXISTS;
|
||||
}
|
||||
|
||||
if (ds->get_type() != Datastore::IMAGE_DS)
|
||||
{
|
||||
att.resp_msg = "Clone only supported for IMAGE_DS Datastores";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
if (ds->get_ds_mad() != ds_mad)
|
||||
{
|
||||
att.resp_msg = "Clone only supported to same DS_MAD Datastores";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
ds->get_permissions(ds_perms_orig);
|
||||
@ -422,10 +464,9 @@ void ImageClone::request_execute(
|
||||
if (ds_check && (size > avail))
|
||||
{
|
||||
att.resp_msg = "Not enough space in datastore";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return ACTION;
|
||||
}
|
||||
|
||||
if ( att.uid != 0 )
|
||||
@ -437,7 +478,7 @@ void ImageClone::request_execute(
|
||||
|
||||
tmpl->to_xml(tmpl_str);
|
||||
|
||||
ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str); // CREATE IMAGE
|
||||
ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, tmpl_str); // CREATE IMAGE
|
||||
|
||||
ar.add_auth(AuthRequest::USE, ds_perms); // USE DATASTORE
|
||||
|
||||
@ -449,18 +490,17 @@ void ImageClone::request_execute(
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
att.resp_msg = ar.message;
|
||||
failure_response(AUTHORIZATION, att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
return AUTHORIZATION;
|
||||
}
|
||||
|
||||
// -------------------------- Check Quotas ----------------------------
|
||||
|
||||
if ( quota_authorization(&img_usage, Quotas::DATASTORE, att) == false )
|
||||
if ( quota_authorization(&img_usage, Quotas::DATASTORE, att, att.resp_msg) == false )
|
||||
{
|
||||
delete tmpl;
|
||||
return;
|
||||
return AUTHORIZATION;
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,8 +523,7 @@ void ImageClone::request_execute(
|
||||
{
|
||||
quota_rollback(&img_usage, Quotas::DATASTORE, att);
|
||||
|
||||
failure_response(ALLOCATE, att);
|
||||
return;
|
||||
return ALLOCATE;
|
||||
}
|
||||
|
||||
ds = dspool->get(ds_id, true);
|
||||
@ -498,7 +537,7 @@ void ImageClone::request_execute(
|
||||
ds->unlock();
|
||||
}
|
||||
|
||||
success_response(new_id, att);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
Loading…
x
Reference in New Issue
Block a user