1
0
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:
Tino Vázquez 2010-08-03 19:22:13 +02:00
parent 61e49edc1e
commit 3ed14a9f68
7 changed files with 337 additions and 44 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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)
{

View File

@ -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);
};

View 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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -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()));

View File

@ -41,6 +41,7 @@ source_files=[
'RequestManagerImageUpdate.cc',
'RequestManagerImageRemoveAttribute.cc',
'RequestManagerImagePublish.cc',
'RequestManagerImagePersistent.cc',
'RequestManagerImageEnable.cc',
'RequestManagerImagePoolInfo.cc',
'RequestManagerClusterAdd.cc',