From 20ff34756ccdbbab29f70c43e10f041ccce0366c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 5 Mar 2012 16:20:04 +0100 Subject: [PATCH] Feature #1112: Add automatic cluster placement requirements to new VMs --- include/VirtualMachine.h | 8 +++ src/datastore/Datastore.cc | 8 +++ src/vm/VirtualMachine.cc | 121 ++++++++++++++++++++++++++++++++++++- src/vnm/VirtualNetwork.cc | 15 ++++- 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8a7fa03708..3204de992b 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -865,6 +865,14 @@ private: */ int parse_requirements(string& error_str); + /** + * Adds automatic placement requirements: Datastore and Cluster + * + * @param error_str Returns the error reason, if any + * @return 0 on success + */ + int automatic_requirements(string& error_str); + /** * Parse the "GRAPHICS" attribute and generates a default PORT if not * defined diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 49da72cfaf..7a2aaa24df 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -72,6 +72,14 @@ int Datastore::disk_attribute(VectorAttribute * disk) disk->replace("DATASTORE_ID", oss.str()); disk->replace("TM_MAD", get_tm_mad()); + if ( get_cluster_id() != ClusterPool::NONE_CLUSTER_ID ) + { + oss.str(""); + oss << get_cluster_id(); + + disk->replace("CLUSTER_ID", oss.str()); + } + return 0; } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 759c4b89ce..1b509f4dac 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -289,6 +289,13 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) goto error_requirements; } + rc = automatic_requirements(error_str); + + if ( rc != 0 ) + { + goto error_requirements; + } + parse_graphics(); // ------------------------------------------------------------------------ @@ -519,6 +526,118 @@ int VirtualMachine::parse_requirements(string& error_str) /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ +int VirtualMachine::automatic_requirements(string& error_str) +{ + int num_vatts; + vector v_attributes; + VectorAttribute * vatt; + + ostringstream oss; + string requirements; + string cluster_id; + bool error = false; + + oss << "Incompatible cluster IDs."; + + // Get cluster id from all DISK vector attributes + + num_vatts = obj_template->get("DISK",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "DISK [" << i << "]: IMAGE [" + << vatt->vector_value("IMAGE_ID") << "] from DATASTORE [" + << vatt->vector_value("DATASTORE_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + + if ( cluster_id.empty() ) + { + cluster_id = vatt_cluster_id; + } + else if ( cluster_id != vatt_cluster_id ) + { + error = true; + } + } + } + + // Get cluster id from all NIC vector attributes + + v_attributes.clear(); + num_vatts = obj_template->get("NIC",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "NIC [" << i << "]: NETWORK [" + << vatt->vector_value("NETWORK_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + + if ( cluster_id.empty() ) + { + cluster_id = vatt_cluster_id; + } + else if ( cluster_id != vatt_cluster_id ) + { + error = true; + } + } + } + + if ( error == true ) + { + error_str = oss.str(); + + return -1; + } + + if ( !cluster_id.empty() ) + { + oss.str(""); + oss << "CLUSTER_ID = " << cluster_id; + + obj_template->get("REQUIREMENTS", requirements); + + if ( !requirements.empty() ) + { + oss << " & ( " << requirements << " )"; + } + + SingleAttribute * reqs_att; + + obj_template->erase("REQUIREMENTS"); + + reqs_att = new SingleAttribute("REQUIREMENTS",oss.str()); + obj_template->set(reqs_att); + } + + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str) { ostringstream oss; @@ -1412,4 +1531,4 @@ string VirtualMachine::get_system_dir() const oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid; return oss.str(); -}; \ No newline at end of file +}; diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 81faa2928c..ae6282be7f 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -24,6 +24,7 @@ #include "FixedLeases.h" #include "AuthManager.h" +#include "ClusterPool.h" #define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) @@ -626,10 +627,10 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) string ip; string mac; - ostringstream vnid; + ostringstream oss; ip = nic->vector_value("IP"); - vnid << oid; + oss << oid; //-------------------------------------------------------------------------- // GET NETWORK LEASE @@ -654,7 +655,7 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) //-------------------------------------------------------------------------- nic->replace("NETWORK" ,name); - nic->replace("NETWORK_ID",vnid.str()); + nic->replace("NETWORK_ID",oss.str()); nic->replace("BRIDGE" ,bridge); nic->replace("MAC" ,mac); nic->replace("IP" ,ip); @@ -678,6 +679,14 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) nic->replace("VLAN_ID", vlan_id); } + if ( get_cluster_id() != ClusterPool::NONE_CLUSTER_ID ) + { + oss.str(""); + oss << get_cluster_id(); + + nic->replace("CLUSTER_ID", oss.str()); + } + return 0; }