From 8a2822b33dc91cca176cbeee98e7655deb0ba310 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 16 Nov 2012 02:18:43 +0100 Subject: [PATCH] feature #1617: Add Datastore TYPE. There are three types IMAGE (stores disk images), SYSTEM (stores disks of running VMs) and FILE (store context/kernel/initrd files) --- include/Datastore.h | 44 +++++++-- src/cli/etc/onedatastore.yaml | 16 ++-- src/cli/one_helper/onedatastore_helper.rb | 10 ++- src/datastore/Datastore.cc | 103 +++++++++++++--------- src/datastore/DatastorePool.cc | 17 ++-- src/oca/ruby/OpenNebula/Datastore.rb | 22 +++++ src/rm/RequestManagerAllocate.cc | 50 +++++------ src/rm/RequestManagerVirtualMachine.cc | 2 +- 8 files changed, 176 insertions(+), 88 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 2b03953032..fe134af97e 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -29,6 +29,38 @@ class Datastore : public PoolObjectSQL, ObjectCollection, public Clusterable { public: + /** + * Type of Datastore + */ + enum DatastoreType + { + IMAGE_DS = 0, /** < Standard datastore for disk images */ + SYSTEM_DS = 1, /** < System datastore for disks of running VMs */ + FILE_DS = 2 /** < File datastore for context, kernel, initrd files */ + }; + + /** + * Return the string representation of an DatastoreType + * @param ob the type + * @return the string + */ + static string type_to_str(DatastoreType ob) + { + switch (ob) + { + case IMAGE_DS: return "IMAGE_DS" ; break; + case SYSTEM_DS: return "SYSTEM_DS" ; break; + case FILE_DS: return "FILE_DS" ; break; + default: return ""; + } + }; + + /** + * Return the string representation of an DatastoreType + * @param str_type string representing the DatastoreTypr + * @return the ImageType (defaults to IMAGE_DS) + */ + static DatastoreType str_to_type(string& str_type); /** * Function to print the Datastore object into a string in XML format @@ -93,12 +125,12 @@ public: }; /** - * Returns true if this is a system datastore - * @return true if this is a system datastore + * Returns the datastore type + * @return datastore type */ - bool is_system() const + DatastoreType get_type() const { - return system_ds == 1; + return type; }; /** @@ -145,9 +177,9 @@ private: string base_path; /** - * 1 if this is a system DS + * The datastore type */ - int system_ds; + DatastoreType type; /** * Disk types for the Images created in this datastore diff --git a/src/cli/etc/onedatastore.yaml b/src/cli/etc/onedatastore.yaml index 4a1e5b89f8..ee1fe3be79 100644 --- a/src/cli/etc/onedatastore.yaml +++ b/src/cli/etc/onedatastore.yaml @@ -1,23 +1,28 @@ ---- -:ID: +--- +:ID: :desc: ONE identifier for the Datastore :size: 4 -:NAME: +:NAME: :desc: Name of the Datastore :size: 25 :left: true -:CLUSTER: +:CLUSTER: :desc: Name of the Cluster :size: 15 :left: true -:IMAGES: +:IMAGES: :desc: Number of Images :size: 6 :TYPE: + :desc: Datastore type + :size: 4 + :left: true + +:DS: :desc: Datastore driver :size: 8 :left: true @@ -33,5 +38,6 @@ - :CLUSTER - :IMAGES - :TYPE +- :DS - :TM diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index d8495bfa71..3123cf18f0 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -60,7 +60,12 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper end end - column :TYPE, "Datastore driver", :left, :size=>8 do |d| + column :TYPE, "Datastore type", :left, :size=>4 do |d| + type = Datastore::DATASTORE_TYPES[d["TYPE"].to_i] + Datastore::SHORT_DATASTORE_TYPES[type] + end + + column :DS, "Datastore driver", :left, :size=>8 do |d| d["DS_MAD"] end @@ -68,7 +73,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper d["TM_MAD"] end - default :ID, :NAME, :CLUSTER, :IMAGES, :TYPE, :TM + default :ID, :NAME, :CLUSTER, :IMAGES, :TYPE, :DS, :TM end table @@ -101,6 +106,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["GROUP", datastore['GNAME']] puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(datastore['CLUSTER'])] + puts str % ["TYPE", datastore.type_str] puts str % ["DS_MAD", datastore['DS_MAD']] puts str % ["TM_MAD", datastore['TM_MAD']] puts str % ["BASE PATH",datastore['BASE_PATH']] diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index bfed67afaa..22993decf2 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -50,7 +50,7 @@ Datastore::Datastore( ds_mad(""), tm_mad(""), base_path(""), - system_ds(0) + type(IMAGE_DS) { group_u = 1; @@ -92,6 +92,33 @@ int Datastore::disk_attribute(VectorAttribute * disk) /* Datastore :: Database Access Functions */ /* ************************************************************************ */ +Datastore::DatastoreType Datastore::str_to_type(string& str_type) +{ + Datastore::DatastoreType dst = FILE_DS; + + if (str_type.empty()) + { + return dst; + } + + TO_UPPER(str_type); + + if ( str_type == "IMAGE_DS" ) + { + dst = IMAGE_DS; + } + else if ( str_type == "SYSTEM_DS" ) + { + dst = SYSTEM_DS; + } + else if ( str_type == "FILE_DS" ) + { + dst = FILE_DS; + } + + return dst; +} + /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -100,25 +127,22 @@ int Datastore::insert(SqlDB *db, string& error_str) int rc; ostringstream oss; string s_disk_type; - string s_system_ds; + string s_ds_type; Nebula& nd = Nebula::instance(); - // --------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Check default datastore attributes - // --------------------------------------------------------------------- + // ------------------------------------------------------------------------- - erase_template_attribute("NAME", name); - // NAME is checked in DatastorePool::allocate + erase_template_attribute("NAME", name);//DatastorePool::allocate checks NAME get_template_attribute("DS_MAD", ds_mad); - get_template_attribute("SYSTEM", s_system_ds); + get_template_attribute("TYPE", s_ds_type); - TO_UPPER(s_system_ds); + type = str_to_type(s_ds_type); - system_ds = (s_system_ds == "YES"); - - if ( system_ds == 1 ) + if ( type == SYSTEM_DS ) { if ( !ds_mad.empty() ) { @@ -143,19 +167,20 @@ int Datastore::insert(SqlDB *db, string& error_str) base_path = oss.str(); - get_template_attribute("DISK_TYPE", s_disk_type); + disk_type = Image::FILE; - if (s_disk_type == "BLOCK") + if ( type == IMAGE_DS ) { - disk_type = Image::BLOCK; - } - else if (s_disk_type == "CDROM") - { - disk_type = Image::CD_ROM; - } - else - { - disk_type = Image::FILE; + get_template_attribute("DISK_TYPE", s_disk_type); + + if (s_disk_type == "BLOCK") + { + disk_type = Image::BLOCK; + } + else if (s_disk_type == "CDROM") + { + disk_type = Image::CD_ROM; + } } if ( tm_mad.empty() == true ) @@ -295,7 +320,7 @@ string& Datastore::to_xml(string& xml) const "" << ds_mad << "" << "" << tm_mad << "" << "" << base_path << "" << - "" << system_ds << "" << + "" << type << "" << "" << disk_type << "" << "" << cluster_id << "" << "" << cluster << "" << @@ -315,6 +340,7 @@ int Datastore::from_xml(const string& xml) { int rc = 0; int int_disk_type; + int int_ds_type; vector content; // Initialize the internal XML object @@ -330,7 +356,7 @@ int Datastore::from_xml(const string& xml) rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found"); rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); - rc += xpath(system_ds, "/DATASTORE/SYSTEM", -1); + rc += xpath(int_ds_type, "/DATASTORE/TYPE", -1); rc += xpath(int_disk_type,"/DATASTORE/DISK_TYPE", -1); rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); @@ -340,6 +366,7 @@ int Datastore::from_xml(const string& xml) rc += perms_from_xml(); disk_type = static_cast(int_disk_type); + type = static_cast(int_ds_type); // Get associated classes ObjectXML::get_nodes("/DATASTORE/IMAGES", content); @@ -382,7 +409,7 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str) { string new_ds_mad; string new_tm_mad; - string s_system_ds; + string s_ds_type; int rc; @@ -394,29 +421,23 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str) } get_template_attribute("DS_MAD", new_ds_mad); - get_template_attribute("SYSTEM", s_system_ds); + get_template_attribute("TYPE", s_ds_type); if ( oid == DatastorePool::SYSTEM_DS_ID ) { - system_ds = 1; - } - else if ( !s_system_ds.empty() ) - { - TO_UPPER(s_system_ds); - - system_ds = (s_system_ds == "YES"); - } - - if ( system_ds == 1 ) - { - replace_template_attribute("SYSTEM", "YES"); - - new_ds_mad = "-"; + type = SYSTEM_DS; } else { - obj_template->erase("SYSTEM"); + type = str_to_type(s_ds_type); + + replace_template_attribute("TYPE", type_to_str(type)); + } + + if ( type == SYSTEM_DS ) + { + new_ds_mad = "-"; } if ( !new_ds_mad.empty() ) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index c8639eca69..c2ef9efc3c 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -49,12 +49,12 @@ DatastorePool::DatastorePool(SqlDB * db): int rc; // --------------------------------------------------------------------- - // Create the system datastore + // Create the system datastore // --------------------------------------------------------------------- - oss << "NAME = " << SYSTEM_DS_NAME << endl - << "SYSTEM = YES" << endl - << "TM_MAD = shared"; + oss << "NAME = " << SYSTEM_DS_NAME << endl + << "TYPE = SYSTEM_DS" << endl + << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -80,13 +80,14 @@ DatastorePool::DatastorePool(SqlDB * db): } // --------------------------------------------------------------------- - // Create the default datastore + // Create the default datastore // --------------------------------------------------------------------- oss.str(""); - oss << "NAME = " << DEFAULT_DS_NAME << endl - << "DS_MAD = fs" << endl - << "TM_MAD = shared"; + oss << "NAME = " << DEFAULT_DS_NAME << endl + << "TYPE = IMAGE_DS" << endl + << "DS_MAD = fs" << endl + << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index 355d252c9a..fa1410203a 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -32,6 +32,14 @@ module OpenNebula :chmod => "datastore.chmod" } + DATASTORE_TYPES=%w{IMAGE SYSTEM FILE} + + SHORT_DATASTORE_TYPES = { + "IMAGE" => "img", + "SYSTEM"=> "sys", + "FILE" => "fil" + } + # Creates a Datastore description with just its identifier # this method should be used to create plain Datastore objects. # +id+ the id of the user @@ -57,6 +65,20 @@ module OpenNebula ####################################################################### # XML-RPC Methods for the Datastore Object ####################################################################### + # Returns the datastore type + def type + self['TYPE'].to_i + end + + # Returns the datastore type (string value) + def type_str + DATASTORE_TYPES[type] + end + + # Returns the datastore type (string value) + def short_type_str + SHORT_DATASTORE_TYPES[type_str] + end # Retrieves the information of the given Datastore. def info() diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index e376487176..2f590fb7b2 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -232,9 +232,9 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachineAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, +int VirtualMachineAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, Template * tmpl, - int& id, + int& id, string& error_str, RequestAttributes& att) { @@ -301,7 +301,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, DatastorePool * dspool = nd.get_dspool(); ImagePool * ipool = static_cast(pool); ImageManager * imagem = nd.get_imagem(); - + ImageTemplate * tmpl = new ImageTemplate; Template img_usage; @@ -332,7 +332,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, return; } - if ( ds->is_system() ) + if ( ds->get_type() == Datastore::SYSTEM_DS ) { ostringstream oss; @@ -361,8 +361,8 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, if ( rc == -1 ) { - failure_response(INTERNAL, - request_error("Cannot determine Image SIZE", size_str), + failure_response(INTERNAL, + request_error("Cannot determine Image SIZE", size_str), att); delete tmpl; return; @@ -373,18 +373,18 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, if ( iss.fail() ) { - failure_response(INTERNAL, - request_error("Cannot parse SIZE", size_str), + failure_response(INTERNAL, + request_error("Cannot parse SIZE", size_str), att); delete tmpl; - return; + return; } tmpl->erase("SIZE"); tmpl->add("SIZE", size_str); // ------------- Set authorization request for non-oneadmin's -------------- - + img_usage.add("DATASTORE", ds_id); img_usage.add("SIZE", size_str); @@ -435,19 +435,19 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, if ( quota_authorization(&img_usage, Quotas::DATASTORE, att) == false ) { delete tmpl; - return; + return; } } - rc = ipool->allocate(att.uid, - att.gid, - att.uname, - att.gname, - tmpl, - ds_id, + rc = ipool->allocate(att.uid, + att.gid, + att.uname, + att.gname, + tmpl, + ds_id, ds_name, ds_disk_type, - ds_data, + ds_data, -1, &id, error_str); @@ -476,9 +476,9 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int TemplateAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, +int TemplateAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, Template * tmpl, - int& id, + int& id, string& error_str, RequestAttributes& att) { @@ -517,9 +517,9 @@ int HostAllocate::pool_allocate( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int UserAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, +int UserAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, Template * tmpl, - int& id, + int& id, string& error_str, RequestAttributes& att) { @@ -540,7 +540,7 @@ int UserAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, if (driver.empty()) { - driver = UserPool::CORE_AUTH; + driver = UserPool::CORE_AUTH; } return upool->allocate(&id,ugid,uname,ugname,passwd,driver,true,error_str); @@ -566,9 +566,9 @@ void UserAllocate::log_xmlrpc_param( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int GroupAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, +int GroupAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, Template * tmpl, - int& id, + int& id, string& error_str, RequestAttributes& att) { diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index e7280cd27a..d0265e8356 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -172,7 +172,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid, return -1; } - if ( ds->is_system() == false ) + if ( ds->get_type() != Datastore::SYSTEM_DS ) { ostringstream oss;