1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-08 21:17:43 +03:00

feature #4217: Base classes for MarketPlace pool

This commit is contained in:
Ruben S. Montero 2015-12-01 16:09:31 +01:00
parent 5e0af5fc44
commit 5a0b3d357c
8 changed files with 892 additions and 17 deletions

View File

@ -85,6 +85,7 @@ main_env.Append(LIBPATH=[
cwd+'/src/secgroup',
cwd+'/src/vdc',
cwd+'/src/vrouter',
cwd+'/src/market'
])
# Compile flags
@ -246,6 +247,7 @@ build_scripts=[
'src/secgroup/SConstruct',
'src/vdc/SConstruct',
'src/vrouter/SConstruct',
'src/market/SConstruct',
'share/man/SConstruct',
'src/sunstone/public/locale/languages/SConstruct',
'src/sunstone/public/SConstruct',

243
include/MarketPlace.h Normal file
View File

@ -0,0 +1,243 @@
/* ------------------------------------------------------------------------ */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------*/
#ifndef MARKETPLACE_H_
#define MARKETPLACE_H_
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "MarketPlaceTemplate.h"
/**
* The MarketPlace class. It represents an abstract container for OpenNebula
* objects (Image, VM Templates or Flows)
*/
class MarketPlace : public PoolObjectSQL, ObjectCollection
{
public:
/**
* MarketPlace container types
*/
enum MarketPlaceType
{
UNKNOWN = 0, /** < Unknown types */
IMAGE_MP = 1, /** < Image MarketPlace */
VMTEMPLATE_MP = 2, /** < VM Template MarketPlace */
FLOW_MP = 3 /** < Flow MarketPlace */
};
/**
* Return the string representation of a MarketPlaceType
* @param ob the type
* @return the string
*/
static string type_to_str(MarketPlaceType ob)
{
switch (ob)
{
case IMAGE_MP: return "IMAGE_MP"; break;
case VMTEMPLATE_MP: return "VMTEMPLATE_MP"; break;
case FLOW_MP: return "FLOW_MP"; break;
default: return "";
}
};
/**
* Return the string representation of a MarketPlaceType, By default it will
* return IMAGE_MP.
* @param str_type string representing the type
* @return the MarketPlaceType
*/
static MarketPlaceType str_to_type(string& str_type);
/**
* Function to print the MarketPlace object into a string in XML format
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
/**
* Rebuilds the object from an xml formatted string
* @param xml_str The xml-formatted string
*
* @return 0 on success, -1 otherwise
*/
int from_xml(const string &xml_str);
/**
* Adds this image's ID to the set.
* @param id of the app to be added to the MarketPlace
* @return 0 on success
*/
int add_mpapp(int id)
{
return add_collection_id(id);
};
/**
* Deletes this image's ID from the set.
* @param id of the image to be deleted from the MarketPlace
* @return 0 on success
*/
int del_mpapp(int id)
{
return del_collection_id(id);
};
/**
* Returns a copy of the Image IDs set
*/
set<int> get_mpapp_ids()
{
return get_collection_copy();
}
/**
* Retrieves marketplace mad name
* @return string mp mad name
*/
const string& get_mp_mad() const
{
return mp_mad;
};
/**
* Returns the marketplace type
* @return marketplace type
*/
MarketPlaceType get_type() const
{
return type;
};
/**
* Set monitor information for the MarketPlace
* @param total_mb
* @param free_mb
* @param used_mb
*/
void update_monitor(long long total, long long free, long long used)
{
total_mb = total;
free_mb = free;
used_mb = used;
}
private:
friend class MarketPlacePool;
// *************************************************************************
// MarketPlace Attributes
// *************************************************************************
/**
* Name of the marketplace driver used to import apps
*/
string mp_mad;
/**
* The marketplace type
*/
MarketPlaceType type;
/**
* Total capacity in MB
*/
long long total_mb;
/**
* Available capacity in MB
*/
long long free_mb;
/**
* Used capacity in MB
*/
long long used_mb;
// *************************************************************************
// Constructor
// *************************************************************************
MarketPlace(
int uid,
int gid,
const string& uname,
const string& gname,
int umask,
MarketPlaceTemplate* ds_template);
virtual ~MarketPlace();
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
/**
* Execute an INSERT or REPLACE Sql query.
* @param db The SQL DB
* @param replace Execute an INSERT or a REPLACE
* @param error_str Returns the error reason, if any
* @return 0 one success
*/
int insert_replace(SqlDB *db, bool replace, string& error_str);
/**
* Bootstraps the database table(s) associated to the MarketPlace
* @return 0 on success
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss(db_bootstrap);
return db->exec(oss);
};
/**
* Writes the MarketPlace in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str);
/**
* Writes/updates the MarketPlace's data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
string error_str;
return insert_replace(db, true, error_str);
}
/**
* Child classes can process the new template set with replace_template or
* append_template with this method
* @param error string describing the error if any
* @return 0 on success
*/
int post_update_template(string& error);
};
#endif /*MARKETPLACE_H*/

170
include/MarketPlacePool.h Normal file
View File

@ -0,0 +1,170 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef MARKETPLACE_POOL_H_
#define MARKETPLACE_POOL_H_
#include "Marketplace.h"
#include "SqlDB.h"
class SqlDB;
class MarketPlacePool : public PoolSQL
{
public:
MarketPlacePool(SqlDB * db):PoolSQL(db, MarketPlace::table, true, true){};
~MarketPlacePool(){};
/* ---------------------------------------------------------------------- */
/* Methods for DB management */
/* ---------------------------------------------------------------------- */
/**
* Allocates a new Datastore, writing it in the pool database. No memory is
* allocated for the object.
* @param uid the user id of the Datastore owner
* @param gid the id of the group this object is assigned to
* @param uname name of the user
* @param gname name of the group
* @param umask permissions umask
* @param mp_template MarketPlace definition template
* @param oid the id assigned to the MarketPlace
* @param error_str Returns the error reason, if any
*
* @return the oid assigned to the object, -1 in case of failure
*/
int allocate(
int uid,
int gid,
const std::string& uname,
const std::string& gname,
int umask,
MarketPlaceTemplate * mp_template,
int * oid,
std::string& error_str);
/**
* Function to get a MarketPlace from the pool, the object is loaded if not
* in memory
* @param oid Datastore unique id
* @param lock locks the MarketPlace mutex
* @return a pointer to the MarketPlace, 0 if not loaded
*/
MarketPlace * get(int oid, bool lock)
{
return static_cast<MarketPlace *>(PoolSQL::get(oid,lock));
};
/**
* Gets an object from the pool (if needed the object is loaded from the
* database).
* @param name of the object
* @param lock locks the object if true
*
* @return a pointer to the object, 0 in case of failure
*/
Datastore * get(const std::string& name, bool lock)
{
return static_cast<Datastore *>(PoolSQL::get(name,-1,lock));
};
/**
* Generate an index key for the object
* @param name of the object
* @param uid owner of the object, only used if needed
*
* @return the key, a string
*/
string key(const std::string& name, int uid)
{
return name;
};
/** Update a particular Datastore
* @param user pointer to Datastore
* @return 0 on success
*/
int update(Datastore * datastore)
{
return datastore->update(db);
};
/**
* Drops the MarketPlac data in the data base. The object mutex SHOULD be
* locked.
* @param objsql a pointer to the Datastore object
* @param error_msg Error reason, if any
* @return 0 on success, -1 DB error
* -3 Datastore's Image IDs set is not empty
*/
int drop(PoolObjectSQL * objsql, std::string& error_msg)
{
MarketPlace *mp = static_cast<MarketPlace *>(objsql);
if( mp->get_collection_size() > 0 )
{
std::ostringstream oss;
oss << "MarketPlace " << datastore->get_oid() << " is not empty.";
error_msg = oss.str();
NebulaLog::log("MARKETPLACE", Log::ERROR, error_msg);
return -3;
}
return PoolSQL::drop(objsql, error_msg);
}
/**
* Bootstraps the database table(s) associated to the Datastore pool
* @return 0 on success
*/
static int bootstrap(SqlDB * _db)
{
return MarketPlace::bootstrap(_db);
};
/**
* Dumps the MarketPlace pool in XML format. A filter can be also added to
* the query
* @param oss the output stream to dump the pool contents
* @param where filter for the objects, defaults to all
* @param limit parameters used for pagination
*
* @return 0 on success
*/
int dump(std::ostringstream& oss, const std::string& where,
const std::string& limit)
{
return PoolSQL::dump(oss, "MARKETPLACE_POOL", MarketPlace::table, where,
limit);
};
private:
/**
* Factory method to produce objects
* @return a pointer to the new object
*/
PoolObjectSQL * create()
{
return new MarketPlace(-1,-1,"","", 0, 0);
};
};
#endif /*MARKETPLACE_POOL_H_*/

View File

@ -0,0 +1,37 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef MARKETPLACE_TEMPLATE_H_
#define MARKETPLACE_TEMPLATE_H_
#include "Template.h"
/**
* Datastore Template class
*/
class MarketPlaceTemplate : public Template
{
public:
MarketPlaceTemplate():
Template(false,'=',"TEMPLATE"){};
~MarketPlaceTemplate(){};
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif /*MARKETPLACE_TEMPLATE_H_*/

View File

@ -159,6 +159,33 @@ namespace one_util
*/
std::string float_to_str(const float &num);
/**
* Returns a scaped version of a value in the from "<op><val><cl>"
* @param v the value to be escaped
* @param op the opening escape string
* @param cl the closing escape string
*/
template <typename ValueType> inline
std::string escape(const ValueType& v, const char * op, const char * cl)
{
std::ostringstream oss;
oss << op << v << cl;
return oss.str();
}
template <typename ValueType> inline
std::string escape_xml(const ValueType &v)
{
return escape(v, "<![CDATA[", "]]>");
}
template <typename ValueType> inline
std::string escape_xml_attr(const ValueType &v)
{
return escape(v, "'", "'");
}
/**
* Checks if a strings matches a regular expression
*

View File

@ -63,29 +63,31 @@ public:
ZONE = 0x0000800000000000LL,
SECGROUP = 0x0001000000000000LL,
VDC = 0x0002000000000000LL,
VROUTER = 0x0004000000000000LL
VROUTER = 0x0004000000000000LL,
MARKETPLACE = 0x0008000000000000LL
};
static string type_to_str(ObjectType ob)
{
switch (ob)
{
case VM: return "VM" ; break;
case HOST: return "HOST" ; break;
case NET: return "NET" ; break;
case IMAGE: return "IMAGE" ; break;
case USER: return "USER" ; break;
case TEMPLATE: return "TEMPLATE" ; break;
case GROUP: return "GROUP" ; break;
case ACL: return "ACL" ; break;
case DATASTORE: return "DATASTORE" ; break;
case CLUSTER: return "CLUSTER" ; break;
case DOCUMENT: return "DOCUMENT" ; break;
case ZONE: return "ZONE" ; break;
case SECGROUP: return "SECGROUP" ; break;
case VDC: return "VDC" ; break;
case VROUTER: return "VROUTER" ; break;
default: return "";
case VM: return "VM" ; break;
case HOST: return "HOST" ; break;
case NET: return "NET" ; break;
case IMAGE: return "IMAGE" ; break;
case USER: return "USER" ; break;
case TEMPLATE: return "TEMPLATE" ; break;
case GROUP: return "GROUP" ; break;
case ACL: return "ACL" ; break;
case DATASTORE: return "DATASTORE" ; break;
case CLUSTER: return "CLUSTER" ; break;
case DOCUMENT: return "DOCUMENT" ; break;
case ZONE: return "ZONE" ; break;
case SECGROUP: return "SECGROUP" ; break;
case VDC: return "VDC" ; break;
case VROUTER: return "VROUTER" ; break;
case MARKETPLACE: return "MARKETPLACE" ; break;
default: return "";
}
};

365
src/market/MarketPlace.cc Normal file
View File

@ -0,0 +1,365 @@
/* ------------------------------------------------------------------------ */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* 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 <sstream>
#include "MarketPlace.h"
#include "NebulaLog.h"
#include "NebulaUtil.h"
/* ************************************************************************ */
/* MarketPlace:: Database Definition */
/* ************************************************************************ */
const char * MarketPlace::table = "marketplace_pool";
const char * MarketPlace::db_names =
"oid, name, body, uid, gid, owner_u, group_u, other_u";
const char * MarketPlace::db_bootstrap =
"CREATE TABLE IF NOT EXISTS marketplace_pool (oid INTEGER PRIMARY KEY, "
"name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, "
"owner_u INTEGER, group_u INTEGER, other_u INTEGER)";
/* ************************************************************************ */
/* MarketPlace:: Constructor / Destructor */
/* ************************************************************************ */
MarketPlace::MarketPlace(
int uid,
int gid,
const std::string& uname,
const std::string& gname,
int umask,
MarketPlaceTemplate* mp_template):
PoolObjectSQL(-1, MARKETPLACE, "", uid, gid, uname, gname, table),
ObjectCollection("MARKETPLACEAPPS"),
mp_mad(""),
type(IMAGE_MP),
total_mb(0),
free_mb(0),
used_mb(0)
{
if (mp_template != 0)
{
obj_template = mp_template;
}
else
{
obj_template = new MarketPlaceTemplate;
}
set_umask(umask);
};
MarketPlace::~MarketPlace()
{
delete obj_template;
};
/* *************************************************************************** */
/* MartketPlace :: Database Access Functions */
/* *************************************************************************** */
int MarketPlace::insert(SqlDB *db, string& error_str)
{
std::ostringstream oss;
std::string s_mp_type;
// -------------------------------------------------------------------------
// Check default marketplace attributes
// -------------------------------------------------------------------------
//MarketPlacePool::allocate checks NAME
erase_template_attribute("NAME", name);
get_template_attribute("MP_MAD", mp_mad);
if ( mp_mad.empty() == true )
{
goto error_mad;
}
erase_template_attribute("TYPE", s_mp_type);
type = str_to_type(s_mp_type);
if ( type == UNKNOWN )
{
goto error_type;
}
add_template_attribute("TYPE", type_to_str(type));
//--------------------------------------------------------------------------
return insert_replace(db, false, error_str);
error_mad:
error_str = "No MarketPlace driver (MP_MAD) in template.";
goto error_common;
error_type:
error_str = "Unknown MarketPlace type: " + s_mp_type;
goto error_common;
error_common:
NebulaLog::log("MARKETPLACE", Log::ERROR, error_str);
return -1;
}
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
int MarketPlace::insert_replace(SqlDB *db, bool replace, string& error_str)
{
std::ostringstream oss;
int rc;
std::string xml_body;
char * sql_name;
char * sql_xml;
sql_name = db->escape_str(name.c_str());
if ( sql_name == 0 )
{
goto error_name;
}
sql_xml = db->escape_str(to_xml(xml_body).c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if ( validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
<< oid << ","
<< "'" << sql_name << "',"
<< "'" << sql_xml << "',"
<< uid << ","
<< gid << ","
<< owner_u << ","
<< group_u << ","
<< other_u << ")";
rc = db->exec(oss);
db->free_str(sql_name);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_name);
db->free_str(sql_xml);
error_str = "Error transforming the MarketPlace to XML.";
goto error_common;
error_body:
db->free_str(sql_name);
goto error_generic;
error_name:
goto error_generic;
error_generic:
error_str = "Error inserting MarketPlace in DB.";
error_common:
return -1;
}
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
/* *************************************************************************** */
/* MartketPlace :: Template Functions */
/* *************************************************************************** */
std::string& MarketPlace::to_xml(std::string& xml) const
{
std::ostringstream oss;
std::string template_xml;
std::string collection_xml;
std::string perm_str;
ObjectCollection::to_xml(collection_xml);
oss << "<MARKETPLACE>"
"<ID>" << oid << "</ID>" <<
"<UID>" << uid << "</UID>" <<
"<GID>" << gid << "</GID>" <<
"<UNAME>" << uname << "</UNAME>" <<
"<GNAME>" << gname << "</GNAME>" <<
"<NAME>" << name << "</NAME>" <<
"<MP_MAD>"<< one_util::escape_xml(mp_mad) << "</MP_MAD>" <<
"<TOTAL_MB>" << total_mb << "</TOTAL_MB>" <<
"<FREE_MB>" << free_mb << "</FREE_MB>" <<
"<USED_MB>" << used_mb << "</USED_MB>" <<
collection_xml <<
perms_to_xml(perm_str) <<
obj_template->to_xml(template_xml) <<
"</MARKETPLACE>";
xml = oss.str();
return xml;
}
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
int MarketPlace::from_xml(const std::string &xml_str)
{
int rc = 0;
int itype;
std::vector<xmlNodePtr> content;
// Initialize the internal XML object
update_from_str(xml_str);
// ----- MARKETPLACE base attributes -----
rc += xpath(oid, "/MARKETPLACE/ID", -1);
rc += xpath(uid, "/MARKETPLACE/UID", -1);
rc += xpath(gid, "/MARKETPLACE/GID", -1);
rc += xpath(uname, "/MARKETPLACE/UNAME", "not_found");
rc += xpath(gname, "/MARKETPLACE/GNAME", "not_found");
rc += xpath(name, "/MARKETPLACE/NAME", "not_found");
rc += xpath(mp_mad, "/MARKETPLACE/MP_MAD", "not_found");
rc += xpath(itype, "/MARKETPLACE/TYPE", -1);
rc += xpath(total_mb, "/MARKETPLACE/TOTAL_MB", 0);
rc += xpath(free_mb, "/MARKETPLACE/FREE_MB", 0);
rc += xpath(used_mb, "/MARKETPLACE/USED_MB", 0);
type = static_cast<MarketPlace::MarketPlaceType>(itype);
// ----- Permissions -----
rc += perms_from_xml();
// ----- MARKETPLACEAPP Collection -----
ObjectXML::get_nodes("/MARKETPLACE/MARKETPLACEAPPS", content);
if (content.empty())
{
return -1;
}
rc += ObjectCollection::from_xml_node(content[0]);
ObjectXML::free_nodes(content);
content.clear();
// ----- TEMPLATE -----
ObjectXML::get_nodes("/MARKETPLACE/TEMPLATE", content);
if (content.empty())
{
return -1;
}
rc += obj_template->from_xml_node(content[0]);
ObjectXML::free_nodes(content);
if (rc != 0)
{
return -1;
}
return 0;
}
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
int MarketPlace::post_update_template(string& error)
{
std::string new_s_type;
std::string new_mp_mad;
MarketPlaceType new_type;
// -------------------------------------------------------------------------
// Sanitize TYPE and MP_MAD attributes
// -------------------------------------------------------------------------
erase_template_attribute("TYPE", new_s_type);
new_type = str_to_type(new_s_type);
if ( new_type == UNKNOWN )
{
error = "Unknown MarketPlace type: " + new_s_type;
return -1;
}
type = new_type;
add_template_attribute("TYPE", type_to_str(type));
erase_template_attribute("MP_MAD", new_mp_mad);
if (!new_mp_mad.empty())
{
mp_mad = new_mp_mad;
}
add_template_attribute("MP_MAD", mp_mad);
return 0;
}
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
MarketPlace::MarketPlaceType MarketPlace::str_to_type(string& str_type)
{
one_util::toupper(str_type);
if ( str_type == "IMAGE_MP" )
{
return IMAGE_MP;
}
else if ( str_type == "VMTEMPLATE_MP" )
{
return VMTEMPLATE_MP;
}
else if ( str_type == "FLOW_MP" )
{
return FLOW_MP;
}
return UNKNOWN;
}

29
src/market/SConstruct Normal file
View File

@ -0,0 +1,29 @@
# SConstruct for src/datastore
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
# #
# 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. #
#--------------------------------------------------------------------------- #
Import('env')
lib_name='nebula_marketplace'
# Sources to generate the library
source_files=[
'MarketPlace.cc'
]
# Build library
env.StaticLibrary(lib_name, source_files)