mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-22 22:03:39 +03:00
bug #295: Adding persistence to images
This commit is contained in:
parent
61e49edc1e
commit
3ed14a9f68
@ -108,6 +108,15 @@ public:
|
||||
{
|
||||
return (public_img == 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the image is persistent
|
||||
* @return true if the image is persistent
|
||||
*/
|
||||
bool isPersistent()
|
||||
{
|
||||
return (persistent_img == 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set enum type
|
||||
@ -183,16 +192,51 @@ public:
|
||||
* @param pub true to publish the image
|
||||
* @return 0 on success
|
||||
*/
|
||||
void publish(bool pub)
|
||||
bool publish(bool pub)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (pub == true)
|
||||
{
|
||||
public_img = 1;
|
||||
if (!isPersistent())
|
||||
{
|
||||
public_img = 1;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
public_img = 0;
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/Unset an image as persistant
|
||||
* @param persistent true to make an image persistant
|
||||
* @return 0 on success
|
||||
*/
|
||||
bool persistent(bool persis)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (persis == true)
|
||||
{
|
||||
if (!isPublic() && running_vms == 0)
|
||||
{
|
||||
persistent_img = 1;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
persistent_img = 0;
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,6 +353,11 @@ private:
|
||||
* Public scope of the Image
|
||||
*/
|
||||
int public_img;
|
||||
|
||||
/**
|
||||
* Persistency of the Image
|
||||
*/
|
||||
int persistent_img;
|
||||
|
||||
/**
|
||||
* Registration time
|
||||
@ -402,12 +451,13 @@ protected:
|
||||
NAME = 2, /* Image name */
|
||||
TYPE = 3, /* 0) OS 1) CDROM 2) DATABLOCK */
|
||||
PUBLIC = 4, /* Public scope (YES OR NO) */
|
||||
REGTIME = 5, /* Time of registration */
|
||||
SOURCE = 6, /* Path to the image */
|
||||
STATE = 7, /* 0) INIT 1) ALLOCATED */
|
||||
PERSISTENT = 5, /* Peristency (YES OR NO) */
|
||||
REGTIME = 6, /* Time of registration */
|
||||
SOURCE = 7, /* Path to the image */
|
||||
STATE = 8, /* 0) INIT 1) ALLOCATED */
|
||||
/* 2) READY 3) USED */
|
||||
RUNNING_VMS = 8, /* Number of VMs using the img */
|
||||
LIMIT = 9
|
||||
RUNNING_VMS = 9, /* Number of VMs using the img */
|
||||
LIMIT = 10
|
||||
};
|
||||
|
||||
static const char * db_names;
|
||||
|
@ -1156,6 +1156,31 @@ private:
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class ImagePersistent: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
ImagePersistent(ImagePool * _ipool,
|
||||
UserPool * _upool):
|
||||
ipool(_ipool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:sib";
|
||||
_help="Make an Image (non)persistent";
|
||||
};
|
||||
|
||||
~ImagePersistent(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
ImagePool * ipool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class ImageEnable: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
|
@ -71,7 +71,7 @@ const char * Image::db_names = "(oid, uid, name, type, public, regtime, "
|
||||
|
||||
const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool ("
|
||||
"oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(128), "
|
||||
"type INTEGER, public INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
|
||||
"type INTEGER, public INTEGER, persistent INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
|
||||
"running_vms INTEGER, UNIQUE(name) )";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -84,6 +84,7 @@ int Image::select_cb(void * nil, int num, char **values, char ** names)
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[PUBLIC]) ||
|
||||
(!values[PERSISTENT]) ||
|
||||
(!values[REGTIME]) ||
|
||||
(!values[SOURCE]) ||
|
||||
(!values[STATE]) ||
|
||||
@ -98,9 +99,10 @@ int Image::select_cb(void * nil, int num, char **values, char ** names)
|
||||
|
||||
name = values[NAME];
|
||||
|
||||
type = static_cast<ImageType>(atoi(values[TYPE]));
|
||||
public_img = atoi(values[PUBLIC]);
|
||||
regtime = static_cast<time_t>(atoi(values[REGTIME]));
|
||||
type = static_cast<ImageType>(atoi(values[TYPE]));
|
||||
public_img = atoi(values[PUBLIC]);
|
||||
persistent_img = atoi(values[PERSISTENT]);
|
||||
regtime = static_cast<time_t>(atoi(values[REGTIME]));
|
||||
|
||||
source = values[SOURCE];
|
||||
|
||||
@ -159,6 +161,7 @@ int Image::insert(SqlDB *db)
|
||||
string source_att;
|
||||
string type_att;
|
||||
string public_attr;
|
||||
string persistent_attr;
|
||||
string dev_prefix;
|
||||
|
||||
ostringstream tmp_hashstream;
|
||||
@ -203,6 +206,23 @@ int Image::insert(SqlDB *db)
|
||||
(int(*)(int))toupper);
|
||||
|
||||
public_img = (public_attr == "YES");
|
||||
|
||||
// ------------ PERSISTENT --------------------
|
||||
|
||||
get_template_attribute("PERSISTENT", persistent_attr);
|
||||
image_template->erase("PERSISTENT");
|
||||
|
||||
transform (persistent_attr.begin(), persistent_attr.end(), persistent_attr.begin(),
|
||||
(int(*)(int))toupper);
|
||||
|
||||
persistent_img = (persistent_attr == "YES");
|
||||
|
||||
// An image cannot be public and persistent simultaneously
|
||||
|
||||
if ( public_img && persistent_img )
|
||||
{
|
||||
goto error_public_and_persistent;
|
||||
}
|
||||
|
||||
// ------------ PREFIX --------------------
|
||||
|
||||
@ -263,6 +283,10 @@ error_name:
|
||||
error_type:
|
||||
NebulaLog::log("IMG", Log::ERROR, "Incorrect TYPE in image template");
|
||||
goto error_common;
|
||||
|
||||
error_public_and_persistent:
|
||||
NebulaLog::log("IMG", Log::ERROR, "Image cannot be public and persistant");
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
return -1;
|
||||
@ -321,6 +345,7 @@ int Image::insert_replace(SqlDB *db, bool replace)
|
||||
<< "'" << sql_name << "',"
|
||||
<< type << ","
|
||||
<< public_img << ","
|
||||
<< persistent_img << ","
|
||||
<< regtime << ","
|
||||
<< "'" << sql_source << "',"
|
||||
<< state << ","
|
||||
@ -349,6 +374,7 @@ int Image::dump(ostringstream& oss, int num, char **values, char **names)
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[PUBLIC]) ||
|
||||
(!values[PERSISTENT]) ||
|
||||
(!values[REGTIME]) ||
|
||||
(!values[SOURCE]) ||
|
||||
(!values[STATE]) ||
|
||||
@ -366,6 +392,7 @@ int Image::dump(ostringstream& oss, int num, char **values, char **names)
|
||||
"<NAME>" << values[NAME] << "</NAME>" <<
|
||||
"<TYPE>" << values[TYPE] << "</TYPE>" <<
|
||||
"<PUBLIC>" << values[PUBLIC] << "</PUBLIC>" <<
|
||||
"<PERSISTENT>" << values[PERSISTENT] << "</PERSISTENT>" <<
|
||||
"<REGTIME>" << values[REGTIME] << "</REGTIME>" <<
|
||||
"<SOURCE>" << values[SOURCE] << "</SOURCE>" <<
|
||||
"<STATE>" << values[STATE] << "</STATE>" <<
|
||||
@ -426,20 +453,19 @@ string& Image::to_xml(string& xml) const
|
||||
string template_xml;
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
|
||||
oss <<
|
||||
"<IMAGE>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<PUBLIC>" << public_img << "</PUBLIC>" <<
|
||||
"<REGTIME>" << regtime << "</REGTIME>" <<
|
||||
"<SOURCE>" << source << "</SOURCE>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
|
||||
image_template->to_xml(template_xml) <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<PUBLIC>" << public_img << "</PUBLIC>" <<
|
||||
"<PERSISTENT>" << persistent_img << "</PERSISTENT>" <<
|
||||
"<REGTIME>" << regtime << "</REGTIME>" <<
|
||||
"<SOURCE>" << source << "</SOURCE>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
|
||||
image_template->to_xml(template_xml) <<
|
||||
"</IMAGE>";
|
||||
|
||||
xml = oss.str();
|
||||
@ -457,15 +483,16 @@ string& Image::to_str(string& str) const
|
||||
ostringstream os;
|
||||
|
||||
os <<
|
||||
"ID = " << oid << endl <<
|
||||
"UID = " << uid << endl <<
|
||||
"NAME = " << name << endl <<
|
||||
"TYPE = " << type << endl <<
|
||||
"PUBLIC = " << public_img << endl <<
|
||||
"REGTIME = " << regtime << endl <<
|
||||
"SOURCE = " << source << endl <<
|
||||
"STATE = " << state << endl <<
|
||||
"RUNNING_VMS = " << running_vms << endl <<
|
||||
"ID = " << oid << endl <<
|
||||
"UID = " << uid << endl <<
|
||||
"NAME = " << name << endl <<
|
||||
"TYPE = " << type << endl <<
|
||||
"PUBLIC = " << public_img << endl <<
|
||||
"PERSISTENT = " << persistent_img << endl <<
|
||||
"REGTIME = " << regtime << endl <<
|
||||
"SOURCE = " << source << endl <<
|
||||
"STATE = " << state << endl <<
|
||||
"RUNNING_VMS = " << running_vms << endl <<
|
||||
"TEMPLATE" << endl
|
||||
<< image_template->to_str(template_str)
|
||||
<< endl;
|
||||
@ -491,7 +518,14 @@ int Image::acquire_image()
|
||||
break;
|
||||
|
||||
case USED:
|
||||
running_vms++;
|
||||
if (persistent_img)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
running_vms++;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISABLED:
|
||||
@ -589,8 +623,18 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
// TYPE, READONLY, CLONE, and SAVE attributes
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
if ( persistent_img )
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","NO"));
|
||||
new_disk.insert(make_pair("SAVE","YES"));
|
||||
|
||||
new_disk.insert(make_pair("SAVE_AS", iid.str())); // Tells the hook to overwrite
|
||||
}
|
||||
else
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
|
@ -312,6 +312,9 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr image_publish(new
|
||||
RequestManager::ImagePublish(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_persistent(new
|
||||
RequestManager::ImagePersistent(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_enable(new
|
||||
RequestManager::ImageEnable(ipool, upool));
|
||||
|
||||
@ -368,15 +371,16 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
/* Image related methods*/
|
||||
|
||||
RequestManagerRegistry.addMethod("one.image.allocate",image_allocate);
|
||||
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
|
||||
RequestManagerRegistry.addMethod("one.image.info", image_info);
|
||||
RequestManagerRegistry.addMethod("one.image.update", image_update);
|
||||
RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute);
|
||||
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
|
||||
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
|
||||
RequestManagerRegistry.addMethod("one.image.allocate", image_allocate);
|
||||
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
|
||||
RequestManagerRegistry.addMethod("one.image.info", image_info);
|
||||
RequestManagerRegistry.addMethod("one.image.update", image_update);
|
||||
RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute);
|
||||
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
|
||||
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent);
|
||||
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
||||
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
||||
|
||||
};
|
||||
|
||||
|
157
src/rm/RequestManagerImagePersistent.cc
Normal file
157
src/rm/RequestManagerImagePersistent.cc
Normal file
@ -0,0 +1,157 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "RequestManager.h"
|
||||
|
||||
#include "NebulaLog.h"
|
||||
#include "Nebula.h"
|
||||
|
||||
#include "AuthManager.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImagePersistent::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
bool persistent_flag;
|
||||
int uid;
|
||||
|
||||
int image_owner;
|
||||
bool is_persistent;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
bool response;
|
||||
|
||||
const string method_name = "ImagePersistent";
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImagePersistent invoked");
|
||||
|
||||
session = xmlrpc_c::value_string (paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
persistent_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
|
||||
// First, we need to authenticate the user
|
||||
uid = ImagePersistent::upool->authenticate(session);
|
||||
|
||||
if ( uid == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImagePersistent::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
image_owner = image->get_uid();
|
||||
is_persistent = image->isPersistent();
|
||||
|
||||
image->unlock();
|
||||
|
||||
//Authorize the operation
|
||||
if ( uid != 0 ) // uid == 0 means oneadmin
|
||||
{
|
||||
AuthRequest ar(uid);
|
||||
|
||||
ar.add_auth(AuthRequest::IMAGE,
|
||||
iid,
|
||||
AuthRequest::MANAGE,
|
||||
image_owner,
|
||||
false);
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
goto error_authorize;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the image locked again
|
||||
image = ImagePersistent::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
response = image->persistent(persistent_flag);
|
||||
|
||||
if (response)
|
||||
{
|
||||
goto error_persistent;
|
||||
}
|
||||
|
||||
ImagePersistent::ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss.str(get_error(method_name, "IMAGE", iid));
|
||||
goto error_common;
|
||||
|
||||
error_authorize:
|
||||
oss.str(authorization_error(method_name, "MANAGE", "IMAGE", uid, iid));
|
||||
goto error_common;
|
||||
|
||||
error_persistent:
|
||||
oss << action_error(method_name, "MANAGE", "IMAGE", iid, -1)
|
||||
<< ". Is the image public? An Image cannot be public and persistent.";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
@ -38,6 +38,8 @@ void RequestManager::ImagePublish::execute(
|
||||
bool is_public;
|
||||
|
||||
Image * image;
|
||||
|
||||
bool response;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
@ -99,7 +101,12 @@ void RequestManager::ImagePublish::execute(
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
image->publish(publish_flag);
|
||||
response = image->publish(publish_flag);
|
||||
|
||||
if (!response)
|
||||
{
|
||||
goto error_publish;
|
||||
}
|
||||
|
||||
ImagePublish::ipool->update(image);
|
||||
|
||||
@ -128,6 +135,11 @@ error_authorize:
|
||||
oss.str(authorization_error(method_name, "MANAGE", "IMAGE", uid, iid));
|
||||
goto error_common;
|
||||
|
||||
error_publish:
|
||||
oss << action_error(method_name, "MANAGE", "IMAGE", iid, -1)
|
||||
<< ". Is the image persistent? An Image cannot be public and persistent.";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
@ -41,6 +41,7 @@ source_files=[
|
||||
'RequestManagerImageUpdate.cc',
|
||||
'RequestManagerImageRemoveAttribute.cc',
|
||||
'RequestManagerImagePublish.cc',
|
||||
'RequestManagerImagePersistent.cc',
|
||||
'RequestManagerImageEnable.cc',
|
||||
'RequestManagerImagePoolInfo.cc',
|
||||
'RequestManagerClusterAdd.cc',
|
||||
|
Loading…
x
Reference in New Issue
Block a user