From e059b35d559bab04d227525b52baf752d4d7225c Mon Sep 17 00:00:00 2001 From: "Carlos Martin and Ruben S. Montero" Date: Thu, 13 May 2010 23:05:28 +0200 Subject: [PATCH] feature #206: Initial refactor of Scheduler code --- src/scheduler/ObjectXML.h | 185 --------------- src/scheduler/SConstruct | 64 ++---- src/scheduler/SchedulerHost.cc | 177 --------------- src/scheduler/SchedulerHost.h | 140 ------------ src/scheduler/SchedulerVirtualMachine.cc | 206 ----------------- src/scheduler/SchedulerVirtualMachine.h | 190 ---------------- src/scheduler/include/ObjectXML.h | 96 ++++++++ src/scheduler/{ => include}/RankPolicy.h | 0 src/scheduler/{ => include}/Scheduler.h | 0 src/scheduler/{ => include}/SchedulerPolicy.h | 0 src/scheduler/{ => src/sched}/Scheduler.cc | 0 src/scheduler/{ => src/sched}/mm_sched.cc | 0 src/scheduler/src/xml/ObjectXML.cc | 214 ++++++++++++++++++ src/scheduler/src/xml/SConstruct | 26 +++ .../{ => src/xml}/test/ObjectXMLTest.cc | 53 ++++- src/scheduler/{ => src/xml}/test/SConstruct | 9 +- 16 files changed, 407 insertions(+), 953 deletions(-) delete mode 100644 src/scheduler/ObjectXML.h delete mode 100644 src/scheduler/SchedulerHost.cc delete mode 100644 src/scheduler/SchedulerHost.h delete mode 100644 src/scheduler/SchedulerVirtualMachine.cc delete mode 100644 src/scheduler/SchedulerVirtualMachine.h create mode 100644 src/scheduler/include/ObjectXML.h rename src/scheduler/{ => include}/RankPolicy.h (100%) rename src/scheduler/{ => include}/Scheduler.h (100%) rename src/scheduler/{ => include}/SchedulerPolicy.h (100%) rename src/scheduler/{ => src/sched}/Scheduler.cc (100%) rename src/scheduler/{ => src/sched}/mm_sched.cc (100%) create mode 100644 src/scheduler/src/xml/ObjectXML.cc create mode 100644 src/scheduler/src/xml/SConstruct rename src/scheduler/{ => src/xml}/test/ObjectXMLTest.cc (69%) rename src/scheduler/{ => src/xml}/test/SConstruct (93%) diff --git a/src/scheduler/ObjectXML.h b/src/scheduler/ObjectXML.h deleted file mode 100644 index 2a68f71a43..0000000000 --- a/src/scheduler/ObjectXML.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* 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. */ -/* -------------------------------------------------------------------------- */ - - -#ifndef OBJECT_XML_H_ -#define OBJECT_XML_H_ - -#include -#include - -#include -#include -#include -#include - -using namespace std; - -class ObjectXML -{ -public: - ObjectXML(const string &xml_doc):xml(0),ctx(0) - { - xml = xmlParseMemory (xml_doc.c_str(),xml_doc.length()); - - if (xml == 0) - { - throw("Error parsing XML Document"); - } - - ctx = xmlXPathNewContext(xml); - - if (ctx == 0) - { - xmlFreeDoc(xml); - throw("Unable to create new XPath context"); - } - }; - - ObjectXML(const xmlNodePtr node):xml(0),ctx(0) - { - xml = xmlNewDoc(reinterpret_cast("1.0")); - - if (xml == 0) - { - throw("Error allocating XML Document"); - } - - ctx = xmlXPathNewContext(xml); - - if (ctx == 0) - { - xmlFreeDoc(xml); - throw("Unable to create new XPath context"); - } - - xmlNodePtr root_node = xmlDocCopyNode(node,xml,1); - - if (root_node == 0) - { - xmlXPathFreeContext(ctx); - xmlFreeDoc(xml); - throw("Unable to allocate node"); - } - - xmlDocSetRootElement(xml, root_node); - }; - - virtual ~ObjectXML() - { - if (xml != 0) - { - xmlFreeDoc(xml); - } - - if ( ctx != 0) - { - xmlXPathFreeContext(ctx); - } - }; - - vector operator[] (const char * xpath_expr) - { - xmlXPathObjectPtr obj; - vector content; - - obj = xmlXPathEvalExpression( - reinterpret_cast(xpath_expr), ctx); - - if (obj == 0 || obj->nodesetval == 0) - { - return content; - } - - xmlNodeSetPtr ns = obj->nodesetval; - int size = ns->nodeNr; - xmlNodePtr cur; - xmlChar * str_ptr; - - for(int i = 0; i < size; ++i) - { - cur = ns->nodeTab[i]; - - if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) - { - continue; - } - - str_ptr = xmlNodeGetContent(cur); - - if (str_ptr != 0) - { - string element_content = reinterpret_cast(str_ptr); - - content.push_back(element_content); - - xmlFree(str_ptr); - } - } - - xmlXPathFreeObject(obj); - - return content; - }; - - int get_nodes (const char * xpath_expr, vector& content) - { - xmlXPathObjectPtr obj; - - obj = xmlXPathEvalExpression( - reinterpret_cast(xpath_expr), ctx); - - if (obj == 0 || obj->nodesetval == 0) - { - return 0; - } - - xmlNodeSetPtr ns = obj->nodesetval; - int size = ns->nodeNr; - int num_nodes = 0; - xmlNodePtr cur; - - for(int i = 0; i < size; ++i) - { - cur = ns->nodeTab[i]; - - if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) - { - continue; - } - - content.push_back(cur); - num_nodes++; - } - - xmlXPathFreeObject(obj); - - return num_nodes; - }; - -private: - /** - * XML representation of the Object - */ - xmlDocPtr xml; - - /** - * XPath Context to access Object elements - */ - xmlXPathContextPtr ctx; -}; - -#endif /*OBJECT_XML_H_*/ diff --git a/src/scheduler/SConstruct b/src/scheduler/SConstruct index df6fbf4699..167715495c 100644 --- a/src/scheduler/SConstruct +++ b/src/scheduler/SConstruct @@ -34,7 +34,12 @@ add_bison(main_env) # Include dirs main_env.Append(CPPPATH=[ - cwd+'./', + cwd+'/include/', +]) + +# Library dirs +main_env.Append(LIBPATH=[ + cwd+'/src/xml', ]) # Compile flags @@ -79,55 +84,14 @@ else: main_env.ParseConfig('xml2-config --libs --cflags') +################################################################################ +# SCONS scripts to build +################################################################################ - - - - - - - - -Import('env') - -cwd=os.getcwd() -env.Append(LIBPATH=cwd) - -lib_name='nebula_scheduler' - -# Sources to generate the library -source_files=[ - 'Scheduler.cc', - 'SchedulerHost.cc', - 'SchedulerVirtualMachine.cc', +build_scripts=[ + 'src/xml/SConstruct', ] -scheduler_names=[ - 'mm_sched' -] - -# Build library -env.StaticLibrary(lib_name, source_files) - -env.Append(LIBS=[ - lib_name, - 'nebula_core', - 'nebula_host', - 'nebula_vm', - 'nebula_vnm', - 'nebula_pool', - 'nebula_template', - 'nebula_common', - 'nebula_um', - 'sqlite3', - 'crypto', -]) - - -if not env.GetOption('clean'): - env.ParseConfig('../../share/scons/get_xmlrpc_config client') - - -# Build tests -for sched in scheduler_names: - env.Program(sched, sched+'.cc') +for script in build_scripts: + env=main_env.Clone() + SConscript(script, exports='env') diff --git a/src/scheduler/SchedulerHost.cc b/src/scheduler/SchedulerHost.cc deleted file mode 100644 index 7b1b167a41..0000000000 --- a/src/scheduler/SchedulerHost.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* 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 -#include - -#include -#include - -#include "SchedulerHost.h" -#include "Scheduler.h" - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void SchedulerHost::get_capacity(int& cpu, int& memory, int threshold) -{ - int total_cpu; - - memory = get_share_free_mem(); - cpu = get_share_free_cpu(); - - total_cpu = get_share_max_cpu(); - - /* eg. 96.7 >= 0.9 * 100, We need to round */ - if ( cpu >= threshold * total_cpu ) - { - cpu = (int) ceil((float)cpu/100.0) * 100; - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerHost::insert(SqliteDB *db) -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not insert hosts in database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerHost::update(SqliteDB *db) -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not update hosts in database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerHost::drop(SqliteDB *db) -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not delete hosts from database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerHostPool::allocate( - PoolObjectSQL *objsql) -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not allocate hosts in database"); - - return -1; -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void SchedulerHostPool::bootstrap() -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not bootstrap database"); -} - -/* ************************************************************************** */ -/* SchedulerHostPool */ -/* ************************************************************************** */ - -extern "C" -{ - static int set_up_cb ( - void * _hids, - int num, - char ** values, - char ** names) - { - vector * hids; - - hids = static_cast *>(_hids); - - if ((hids==0)||(num<=0)||(values[0]==0)) - { - return -1; - } - - hids->push_back(atoi(values[0])); - - return 0; - }; -} - -/* -------------------------------------------------------------------------- */ - -int SchedulerHostPool::set_up() -{ - ostringstream oss; - int rc; - - // ------------------------------------------------------------------------- - // Clean the pool to get updated data from db - // ------------------------------------------------------------------------- - - clean(); - - hids.clear(); - - // ------------------------------------------------------------------------- - // Load the ids (to get an updated list of hosts) - // ------------------------------------------------------------------------- - - lock(); - - oss << "SELECT oid FROM " << Host::table - << " WHERE state != " << Host::DISABLED - << " AND state != " << Host::ERROR; - - rc = db->exec(oss,set_up_cb,(void *) &hids); - - if ( rc != 0 ) - { - unlock(); - - return -1; - } - - oss.str(""); - oss << "Discovered Hosts (enabled):"; - - for (unsigned int i=0 ; i < hids.size() ; i++) - { - oss << " " << hids[i]; - } - - Scheduler::log("HOST",Log::DEBUG,oss); - - unlock(); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - diff --git a/src/scheduler/SchedulerHost.h b/src/scheduler/SchedulerHost.h deleted file mode 100644 index 5d3c548c66..0000000000 --- a/src/scheduler/SchedulerHost.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* 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. */ -/* -------------------------------------------------------------------------- */ - -#ifndef SCHEDULER_HOST_H_ -#define SCHEDULER_HOST_H_ - -#include "Host.h" - -using namespace std; - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -/** - * The SchedulerHost class. It represents the scheduler version of the host, - * only read operations to the pool are allowed for the SchedulerHost class - */ -class SchedulerHost : public Host -{ - -public: - - SchedulerHost(){}; - - ~SchedulerHost(){}; - - /** - * Gets the current host capacity - * @param cpu the host free cpu, scaled according to a given threshold - * @param memory the host free memory - * @param threshold to consider the host totally free - */ - void get_capacity(int& cpu, int& memory, int threshold); - -private: - - // ---------------------------------------- - // Friends - // ---------------------------------------- - friend class SchedulerHostPool; - - // ---------------------------------------- - // SQL functions do not modify the DB! - // ---------------------------------------- - int insert(SqliteDB *db); - - int update(SqliteDB *db); - - int drop(SqliteDB *db); - -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -/** - * The SchedulerHost class. It represents the scheduler version of the host, - * read only operation to the pool are allowed for the SchedulerHost class - */ -class SchedulerHostPool : public PoolSQL -{ -public: - - //-------------------------------------------------------------------------- - // Constructor - //-------------------------------------------------------------------------- - - SchedulerHostPool(SqliteDB *db):PoolSQL(db){}; - - ~SchedulerHostPool(){}; - - /** - * Implements the Pool interface, just prints an error message. This - * class DOES NOT modify the database. - */ - int allocate( - PoolObjectSQL *objsql); - - /** - * Gets an ScheulerHost from the pool (if needed the object is loaded from - * the database). - * @param oid the object unique identifier - * @param lock locks the object if true - * - * @return a pointer to the object, 0 in case of failure - */ - SchedulerHost * get( - int oid, - bool lock) - { - return static_cast(PoolSQL::get(oid,lock)); - }; - - /** - * Set ups the host pool by performing the following actions: - * - All the objects stored in the pool are flushed - * - The ids of the hosts in the database are loaded - * @return 0 on success - */ - int set_up(); - -private: - friend class Scheduler; - - /** - * Hosts ids - */ - vector hids; - - /** - * Factory method for the PoolSQL class - * @return a pointer to a new SchedulerHost object - */ - PoolObjectSQL * create() - { - return new SchedulerHost; - }; - - /** - * Bootstrap method from the PoolSQL interface. It just prints - * an error message as this class MUST not modify the DB. - */ - void bootstrap(); -}; - -#endif /*SCHEDULER_HOST_H_*/ diff --git a/src/scheduler/SchedulerVirtualMachine.cc b/src/scheduler/SchedulerVirtualMachine.cc deleted file mode 100644 index 5897d7a096..0000000000 --- a/src/scheduler/SchedulerVirtualMachine.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* 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 -#include - -#include -#include - -#include "SchedulerHost.h" -#include "Scheduler.h" - -/* ************************************************************************** */ -/* SchedulerVirtualMachine */ -/* ************************************************************************** */ - -int SchedulerVirtualMachine::insert(SqliteDB *db) -{ - Scheduler::log("VM",Log::ERROR, - "Scheduler can not insert VMs in database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerVirtualMachine::update(SqliteDB *db) -{ - Scheduler::log("VM",Log::ERROR, - "Scheduler can not update VMs in database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerVirtualMachine::drop(SqliteDB *db) -{ - Scheduler::log("VM",Log::ERROR, - "Scheduler can not delete VMs in database"); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void SchedulerVirtualMachine::set_priorities(vector& total) -{ - if ( hosts.size() != total.size() ) - { - Scheduler::log("VM",Log::ERROR,"Wrong size for priority vector"); - return; - } - - for (unsigned int i=0; ipriority = total[i]; - } - - //Sort the shares using the priority - - sort(hosts.begin(),hosts.end(),SchedulerVirtualMachine::host_cmp); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerVirtualMachine::get_host( - int& hid, - SchedulerHostPool * hpool) -{ - vector::reverse_iterator i; - - vector::iterator j; - SchedulerHost * host; - - int cpu; - int mem; - int dsk; - - get_requirements(cpu,mem,dsk); - - for (i=hosts.rbegin();i!=hosts.rend();i++) - { - host = hpool->get((*i)->hid,false); - - if ( host == 0 ) - { - continue; - } - - if (host->test_capacity(cpu,mem,dsk)==true) - { - host->add_capacity(cpu,mem,dsk); - hid = (*i)->hid; - - return 0; - } - } - - hid = -1; - - return -1; -} - -/* ************************************************************************** */ -/* Scheuler Virtual Machine :: Misc */ -/* ************************************************************************** */ - -ostream& operator<<(ostream& os, SchedulerVirtualMachine& vm) -{ - vector::reverse_iterator i; - vector::iterator j; - - for (i=vm.hosts.rbegin();i!=vm.hosts.rend();i++) - { - os << "\t" << (*i)->priority << "\t" << (*i)->hid << endl; - } - - return os; -}; - -/* ************************************************************************** */ -/* SchedulerVirtualMachinePool */ -/* ************************************************************************** */ - -int SchedulerVirtualMachinePool::allocate( - PoolObjectSQL *objsql) -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not allocate VMs in database"); - - return -1; -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void SchedulerVirtualMachinePool::bootstrap() -{ - Scheduler::log("HOST",Log::ERROR, - "Scheduler can not bootstrap database"); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int SchedulerVirtualMachinePool::set_up() -{ - ostringstream oss; - string where; - int rc; - - // ------------------------------------------------------------------------- - // Clean the pool to get updated data from db - // ------------------------------------------------------------------------- - - clean(); - - pending_vms.clear(); - - // ------------------------------------------------------------------------- - // Load an updated list of pending VMs - // ------------------------------------------------------------------------- - - oss << "state == " << VirtualMachine::PENDING; - - where = oss.str(); - - rc = PoolSQL::search( - pending_vms, - VirtualMachine::table, - where); - - oss.str(""); - oss << "Pending virtual machines :"; - - - for (unsigned int i=0 ; i < pending_vms.size() ; i++) - { - oss << " " << pending_vms[i]; - } - - Scheduler::log("VM",Log::DEBUG,oss); - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ diff --git a/src/scheduler/SchedulerVirtualMachine.h b/src/scheduler/SchedulerVirtualMachine.h deleted file mode 100644 index 674d37f7c7..0000000000 --- a/src/scheduler/SchedulerVirtualMachine.h +++ /dev/null @@ -1,190 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* 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. */ -/* -------------------------------------------------------------------------- */ - -#ifndef SCHEDULER_VIRTUAL_MACHINE_H_ -#define SCHEDULER_VIRTUAL_MACHINE_H_ - -#include "VirtualMachine.h" -#include "SchedulerHost.h" - -using namespace std; - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -/** - * The SchedulerHost class. It represents the scheduler version of the host, - * only read operations to the pool are allowed for the SchedulerHost class - */ -class SchedulerVirtualMachine : public VirtualMachine -{ - -public: - - SchedulerVirtualMachine(){}; - - ~SchedulerVirtualMachine() - { - vector::iterator jt; - - for (jt=hosts.begin();jt!=hosts.end();jt++) - { - delete *jt; - } - }; - - /** - * Adds a new share to the map of suitable shares to start this VM - * @param hid of the selected host - * @param hsid of the selected host share - */ - void add_host(int hid) - { - SchedulerVirtualMachine::Host * ss; - - ss = new SchedulerVirtualMachine::Host(hid); - - hosts.push_back(ss); - }; - - /** - * Gets the matching hosts ids - * @param mh vector with the hids of the matching hosts - */ - void get_matching_hosts(vector& mh) - { - vector::iterator i; - - for(i=hosts.begin();i!=hosts.end();i++) - { - mh.push_back((*i)->hid); - } - }; - - /** - * Sets the priorities for each matching host - */ - void set_priorities(vector& total); - - /** - * - */ - int get_host(int& hid, SchedulerHostPool * hpool); - - /** - * Function to write a Virtual Machine in an output stream - */ - friend ostream& operator<<(ostream& os, SchedulerVirtualMachine& vm); - -private: - - // ------------------------------------------------------------------------- - // Friends - // ------------------------------------------------------------------------- - friend class SchedulerVirtualMachinePool; - - //-------------------------------------------------------------------------- - - struct Host - { - int hid; - float priority; - - Host(int _hid): - hid(_hid), - priority(0){}; - - ~Host(){}; - - bool operator<(const Host& b) const { //Sort by priority - return priority < b.priority; - } - }; - - static bool host_cmp (const Host * a, const Host * b ) - { - return (*a < *b ); - }; - - //-------------------------------------------------------------------------- - - /** - * Matching hosts - */ - vector hosts; - - // ------------------------------------------------------------------------- - // SQL functions do not modify the DB! - // ------------------------------------------------------------------------- - - int insert(SqliteDB *db); - - int update(SqliteDB *db); - - int drop(SqliteDB *db); -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -/** - * The SchedulerHost class. It represents the scheduler version of the host, - * read only operation to the pool are allowed for the SchedulerHost class - */ -class SchedulerVirtualMachinePool : public PoolSQL -{ -public: - - SchedulerVirtualMachinePool(SqliteDB * db):PoolSQL(db){}; - - ~SchedulerVirtualMachinePool(){}; - - int allocate( - PoolObjectSQL *objsql); - - SchedulerVirtualMachine * get( - int oid, - bool lock) - { - return static_cast(PoolSQL::get(oid,lock)); - }; - - /** - * Set ups the VM pool by performing the following actions: - * - All the objects stored in the pool are flushed - * - The ids of the pendings VMs in the database are loaded - * @return 0 on success - */ - int set_up(); - -private: - friend class Scheduler; - - /** - * The ids of the pending VMs - */ - vector pending_vms; - - PoolObjectSQL * create() - { - return new SchedulerVirtualMachine; - }; - - void bootstrap(); -}; - -#endif /*SCHEDULER_VIRTUAL_MACHINE_H_*/ diff --git a/src/scheduler/include/ObjectXML.h b/src/scheduler/include/ObjectXML.h new file mode 100644 index 0000000000..f37708d3d4 --- /dev/null +++ b/src/scheduler/include/ObjectXML.h @@ -0,0 +1,96 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + + +#ifndef OBJECT_XML_H_ +#define OBJECT_XML_H_ + +#include +#include + +#include +#include +#include +#include + +using namespace std; + +/** + * This class represents a generic Object supported by a xml document. + * The class provides basic methods to query attributes, and get xml nodes + */ +class ObjectXML +{ +public: + + // ---------------------- Constructors ------------------------------------ + + ObjectXML():xml(0),ctx(0){}; + + /** + * Constructs an object using a XML document + */ + ObjectXML(const string &xml_doc); + + /** + * Constructs an object using a XML Node. The node is copied to the new + * object + */ + ObjectXML(const xmlNodePtr node); + + virtual ~ObjectXML(); + + /** + * Access Object elements using Xpath + * @param xpath_expr the Xpath of the element + * @return a vector with the elements + */ + vector operator[] (const char * xpath_expr); + + /** + * Get xml nodes by Xpath + * @param xpath_expr the Xpath for the elements + * @param content nodes for the given Xpath expression. The nodes are + * returned as pointers to the object nodes. + * @return the number of nodes found + */ + int get_nodes (const char * xpath_expr, vector& content); + + /** + * Updates the object representation with a new XML document. Previous + * XML resources are freed + * @param xml_doc the new xml document + */ + int update(const string &xml_doc); + +private: + /** + * XML representation of the Object + */ + xmlDocPtr xml; + + /** + * XPath Context to access Object elements + */ + xmlXPathContextPtr ctx; + + /** + * Parse a XML documents and initializes XPath contexts + */ + void xml_parse(const string &xml_doc); +}; + +#endif /*OBJECT_XML_H_*/ diff --git a/src/scheduler/RankPolicy.h b/src/scheduler/include/RankPolicy.h similarity index 100% rename from src/scheduler/RankPolicy.h rename to src/scheduler/include/RankPolicy.h diff --git a/src/scheduler/Scheduler.h b/src/scheduler/include/Scheduler.h similarity index 100% rename from src/scheduler/Scheduler.h rename to src/scheduler/include/Scheduler.h diff --git a/src/scheduler/SchedulerPolicy.h b/src/scheduler/include/SchedulerPolicy.h similarity index 100% rename from src/scheduler/SchedulerPolicy.h rename to src/scheduler/include/SchedulerPolicy.h diff --git a/src/scheduler/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc similarity index 100% rename from src/scheduler/Scheduler.cc rename to src/scheduler/src/sched/Scheduler.cc diff --git a/src/scheduler/mm_sched.cc b/src/scheduler/src/sched/mm_sched.cc similarity index 100% rename from src/scheduler/mm_sched.cc rename to src/scheduler/src/sched/mm_sched.cc diff --git a/src/scheduler/src/xml/ObjectXML.cc b/src/scheduler/src/xml/ObjectXML.cc new file mode 100644 index 0000000000..ebbe1cc48c --- /dev/null +++ b/src/scheduler/src/xml/ObjectXML.cc @@ -0,0 +1,214 @@ +/* -------------------------------------------------------------------------- */ +/* 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 +#include + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +ObjectXML::ObjectXML(const string &xml_doc):xml(0),ctx(0) +{ + try + { + xml_parse(xml_doc); + } + catch(runtime_error& re) + { + throw; + } +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +ObjectXML::ObjectXML(const xmlNodePtr node):xml(0),ctx(0) +{ + xml = xmlNewDoc(reinterpret_cast("1.0")); + + if (xml == 0) + { + throw("Error allocating XML Document"); + } + + ctx = xmlXPathNewContext(xml); + + if (ctx == 0) + { + xmlFreeDoc(xml); + throw("Unable to create new XPath context"); + } + + xmlNodePtr root_node = xmlDocCopyNode(node,xml,1); + + if (root_node == 0) + { + xmlXPathFreeContext(ctx); + xmlFreeDoc(xml); + throw("Unable to allocate node"); + } + + xmlDocSetRootElement(xml, root_node); +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +ObjectXML::~ObjectXML() +{ + if (xml != 0) + { + xmlFreeDoc(xml); + } + + if ( ctx != 0) + { + xmlXPathFreeContext(ctx); + } +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +vector ObjectXML::operator[] (const char * xpath_expr) +{ + xmlXPathObjectPtr obj; + vector content; + + obj = xmlXPathEvalExpression( + reinterpret_cast(xpath_expr), ctx); + + if (obj == 0 || obj->nodesetval == 0) + { + return content; + } + + xmlNodeSetPtr ns = obj->nodesetval; + int size = ns->nodeNr; + xmlNodePtr cur; + xmlChar * str_ptr; + + for(int i = 0; i < size; ++i) + { + cur = ns->nodeTab[i]; + + if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) + { + continue; + } + + str_ptr = xmlNodeGetContent(cur); + + if (str_ptr != 0) + { + string element_content = reinterpret_cast(str_ptr); + + content.push_back(element_content); + + xmlFree(str_ptr); + } + } + + xmlXPathFreeObject(obj); + + return content; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ObjectXML::get_nodes (const char * xpath_expr, vector& content) +{ + xmlXPathObjectPtr obj; + + obj = xmlXPathEvalExpression( + reinterpret_cast(xpath_expr), ctx); + + if (obj == 0 || obj->nodesetval == 0) + { + return 0; + } + + xmlNodeSetPtr ns = obj->nodesetval; + int size = ns->nodeNr; + int num_nodes = 0; + xmlNodePtr cur; + + for(int i = 0; i < size; ++i) + { + cur = ns->nodeTab[i]; + + if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) + { + continue; + } + + content.push_back(cur); + num_nodes++; + } + + xmlXPathFreeObject(obj); + + return num_nodes; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ObjectXML::update(const string &xml_doc) +{ + if (xml != 0) + { + xmlFreeDoc(xml); + } + + if ( ctx != 0) + { + xmlXPathFreeContext(ctx); + } + + try + { + xml_parse(xml_doc); + } + catch(runtime_error& re) + { + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void ObjectXML::xml_parse(const string &xml_doc) +{ + xml = xmlParseMemory (xml_doc.c_str(),xml_doc.length()); + + if (xml == 0) + { + throw("Error parsing XML Document"); + } + + ctx = xmlXPathNewContext(xml); + + if (ctx == 0) + { + xmlFreeDoc(xml); + throw("Unable to create new XPath context"); + } +} diff --git a/src/scheduler/src/xml/SConstruct b/src/scheduler/src/xml/SConstruct new file mode 100644 index 0000000000..7624e662ba --- /dev/null +++ b/src/scheduler/src/xml/SConstruct @@ -0,0 +1,26 @@ +# SConstruct for src/pool + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +Import('env') + +lib_name='scheduler_xml' + +source_files=['ObjectXML.cc'] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/scheduler/test/ObjectXMLTest.cc b/src/scheduler/src/xml/test/ObjectXMLTest.cc similarity index 69% rename from src/scheduler/test/ObjectXMLTest.cc rename to src/scheduler/src/xml/test/ObjectXMLTest.cc index 50ee236e6d..1a69c23f13 100644 --- a/src/scheduler/test/ObjectXMLTest.cc +++ b/src/scheduler/src/xml/test/ObjectXMLTest.cc @@ -39,6 +39,7 @@ class ObjectXMLTest : public CppUnit::TestFixture CPPUNIT_TEST( xpath_access ); CPPUNIT_TEST( node_constructor ); + CPPUNIT_TEST( doc_update ); CPPUNIT_TEST_SUITE_END (); @@ -57,7 +58,6 @@ public: ~ObjectXMLTest(){}; - /* ********************************************************************* */ /* ********************************************************************* */ @@ -118,7 +118,36 @@ public: } }; + void doc_update() + { + try + { + ObjectXML obj(xml_history_dump); + vector hostnames; + + hostnames = obj["/VM_POOL/VM/HISTORY/HOSTNAME"]; + + CPPUNIT_ASSERT(hostnames.size() == 2); + CPPUNIT_ASSERT(hostnames[0] == "A_hostname"); + CPPUNIT_ASSERT(hostnames[1] == "C_hostname"); + + obj.update(xml_history_dump2); + + hostnames = obj["/VM_POOL/VM/HISTORY/HOSTNAME"]; + + CPPUNIT_ASSERT(hostnames.size() == 2); + CPPUNIT_ASSERT(hostnames[0] == "0_hostname"); + CPPUNIT_ASSERT(hostnames[1] == "1_hostname"); + } + catch(runtime_error& re) + { + cerr << re.what() << endl; + CPPUNIT_ASSERT(1 == 0); + } + }; + static const string xml_history_dump; + static const string xml_history_dump2; }; /* ************************************************************************* */ @@ -155,4 +184,26 @@ const string ObjectXMLTest::xml_history_dump = "C_hostname200" "0000" "000" + ""; + +const string ObjectXMLTest::xml_history_dump2 = + "00one_user_test" + "VM one01" + "000000000000" + "000" + "010" + "one_user_testSecond VM0" + "200000000000" + "000" + "000" + "0_hostname000" + "0000" + "0002" + "0one_user_testVM one" + "020" + "000000000000" + "0001" + "1_hostname200" + "0000" + "000" ""; \ No newline at end of file diff --git a/src/scheduler/test/SConstruct b/src/scheduler/src/xml/test/SConstruct similarity index 93% rename from src/scheduler/test/SConstruct rename to src/scheduler/src/xml/test/SConstruct index e4242e9fa9..d05e73f0a3 100644 --- a/src/scheduler/test/SConstruct +++ b/src/scheduler/src/xml/test/SConstruct @@ -17,7 +17,7 @@ import os import sys import shutil -sys.path.append("../../../share/scons") +sys.path.append("../../../../../share/scons") # This is the absolute path where the project is located cwd=os.getcwd() @@ -28,7 +28,7 @@ main_env['ENV']['PATH']=os.environ['PATH'] # Include dirs main_env.Append(CPPPATH=[ - cwd+'/../', + cwd+'/../../../include', '/usr/include/cppunit/' ]) @@ -48,7 +48,8 @@ main_env.Append(LDFLAGS=["-g"]) # Libraries main_env.Append(LIBS=[ - 'cppunit' + 'cppunit', + 'scheduler_xml' ]) main_env.Program('test_xml','ObjectXMLTest.cc') @@ -67,7 +68,7 @@ if xmlrpc_dir!='none': main_env.Append(LIBPATH=[xmlrpc_dir+"/lib"]) main_env.Append(CPPPATH=[xmlrpc_dir+"/include"]) -main_env.ParseConfig('../../../share/scons/get_xmlrpc_config client') +main_env.ParseConfig('../../../../../share/scons/get_xmlrpc_config client') #------------------------------------------------------------------------------- # build lex/bison