1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Feature #3009: New VM attribute NIC_DEFAULT

This commit is contained in:
Carlos Martín 2014-07-10 16:24:25 +02:00
parent cff331d078
commit 370a5c27b2
5 changed files with 219 additions and 53 deletions

View File

@ -355,6 +355,14 @@ public:
*/
void replace(const map<string,string>& attr);
/**
* The attributes from vattr will be copied to this vector
* @param attr Vector attribute to merge
* @param replace True to replace existing values, false to copy values
* only if they don't exist in this vector attribute
*/
void merge(VectorAttribute* vattr, bool replace);
/**
* Replace the value of the given vector attribute
*/

View File

@ -1051,6 +1051,12 @@ public:
*/
int get_network_leases(string &error_str);
/**
* Merges NIC_DEFAULT with the given NIC
* @param nic NIC to process
*/
void merge_nic_defaults(VectorAttribute* nic);
/**
* Releases all network leases taken by this Virtual Machine
*/
@ -1266,28 +1272,34 @@ public:
// ------------------------------------------------------------------------
/**
* Collects information about VM DISKS
* @param max_disk_id of the VM
*/
void get_nic_info(int& max_nic_id);
/**
* Generates a NIC attribute to be attached to the VM.
* @param tmpl Template containing a single NIC vector attribute.
* @param max_nic_id Max NIC/NIC_ID of the VM
* @param uid of the VM owner
* @param network_id returns the id of the acquired network
* @param error_str describes the error
* Gets info about the new NIC to attach
*
* @return a new VectorAttribute with the DISK (should be freed if not
* @param tmpl Template containing a single NIC vector attribute.
* @param max_nic_id Returns the max NIC_ID of the VM
* @param error_str error reason, if any
* @return a new VectorAttribute with the NIC (should be freed if not
* added to the template), 0 in case of error
*/
static VectorAttribute * set_up_attach_nic(
int vm_id,
VectorAttribute * get_attach_nic_info(
VirtualMachineTemplate * tmpl,
int& max_nic_id,
string& error_str);
/**
* Setups the new NIC attribute to be attached to the VM.
*
* @param vm_id Id of the VM where this nic will be attached
* @param new_nic New NIC vector attribute, obtained from get_attach_nic_info
* @param max_nic_id Max NIC/NIC_ID of the VM
* @param uid of the VM owner
* @param error_str error reason, if any
* @return 0 on success, -1 otherwise
*/
static int set_up_attach_nic(
int vm_id,
VectorAttribute * new_nic,
int max_nic_id,
int uid,
int& network_id,
string& error_str);
/**
@ -1596,6 +1608,13 @@ private:
*/
int parse_os(string& error_str);
/**
* Parse the "NIC_DEFAULT" attribute
* @param error_str Returns the error reason, if any
* @return 0 on success
*/
int parse_defaults(string& error_str);
/**
* Parse the "CONTEXT" attribute of the template by substituting
* $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE]

View File

@ -172,6 +172,24 @@ void VectorAttribute::replace(const map<string,string>& attr)
{
attribute_value = attr;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VectorAttribute::merge(VectorAttribute* vattr, bool replace)
{
map<string, string>::const_iterator it;
map<string, string> source_values;
source_values = vattr->value();
for(it=source_values.begin(); it!=source_values.end(); it++)
{
if(replace || attribute_value.find(it->first) == attribute_value.end())
{
attribute_value.insert(make_pair(it->first,it->second));
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -1355,7 +1355,7 @@ int DispatchManager::attach_nic(
int max_nic_id;
int uid;
int oid;
int network_id;
int rc;
VectorAttribute * nic;
@ -1387,7 +1387,15 @@ int DispatchManager::attach_nic(
return -1;
}
vm->get_nic_info(max_nic_id);
nic = vm->get_attach_nic_info(tmpl, max_nic_id, error_str);
if ( nic == 0 )
{
vm->unlock();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_NIC);
@ -1400,17 +1408,19 @@ int DispatchManager::attach_nic(
vm->unlock();
nic = VirtualMachine::set_up_attach_nic(oid,
tmpl,
max_nic_id,
uid,
network_id,
error_str);
rc = VirtualMachine::set_up_attach_nic(oid,
nic,
max_nic_id,
uid,
error_str);
vm = vmpool->get(vid, true);
if ( vm == 0 )
{
VirtualMachine::release_network_leases(nic, vid);
if ( rc == 0 )
{
VirtualMachine::release_network_leases(nic, vid);
}
oss << "Could not attach a new NIC to VM " << vid
<< ", VM does not exist after setting its state to HOTPLUG." ;
@ -1421,7 +1431,7 @@ int DispatchManager::attach_nic(
return -1;
}
if ( nic == 0 )
if ( rc != 0 )
{
vm->set_state(VirtualMachine::RUNNING);

View File

@ -332,6 +332,17 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
goto error_os;
}
// ------------------------------------------------------------------------
// Parse the defaults to merge
// ------------------------------------------------------------------------
rc = parse_defaults(error_str);
if ( rc != 0 )
{
goto error_defaults;
}
// ------------------------------------------------------------------------
// Get network leases
// ------------------------------------------------------------------------
@ -433,6 +444,7 @@ error_memory:
goto error_common;
error_os:
error_defaults:
error_name:
error_common:
NebulaLog::log("ONE",Log::ERROR, error_str);
@ -612,6 +624,67 @@ int VirtualMachine::parse_os(string& error_str)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::parse_defaults(string& error_str)
{
int num;
vector<Attribute *> attr;
VectorAttribute* vatt = 0;
vector<Attribute *>::iterator it;
num = user_obj_template->remove("NIC_DEFAULT", attr);
if ( num == 0 )
{
return 0;
}
for (it=attr.begin(); it != attr.end(); it++)
{
obj_template->set(*it);
}
if ( num > 1 )
{
error_str = "Only one NIC_DEFAULT attribute can be defined.";
return -1;
}
vatt = dynamic_cast<VectorAttribute *>(attr[0]);
if ( vatt == 0 )
{
error_str = "Wrong format for NIC_DEFAULT attribute.";
return -1;
}
// To avoid authorization bypass and inconsistencies
string att_names[] =
{"NETWORK_ID", "NETWORK", "NETWORK_UID", "NETWORK_UNAME"};
for (int i=0; i<4; i++)
{
if(vatt->vector_value(att_names[i].c_str()) != "")
{
ostringstream oss;
oss << "Attribute " << att_names[i]
<< " is not allowed inside NIC_DEFAULT.";
error_str = oss.str();
return -1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -2121,7 +2194,10 @@ long long VirtualMachine::get_volatile_disk_size(Template * tmpl)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::get_nic_info(int& max_nic_id)
VectorAttribute * VirtualMachine::get_attach_nic_info(
VirtualMachineTemplate * tmpl,
int& max_nic_id,
string& error_str)
{
vector<Attribute *> nics;
VectorAttribute * nic;
@ -2129,6 +2205,10 @@ void VirtualMachine::get_nic_info(int& max_nic_id)
int nic_id;
int num_nics;
// -------------------------------------------------------------------------
// Get the highest NIC_ID
// -------------------------------------------------------------------------
max_nic_id = -1;
num_nics = obj_template->get("NIC", nics);
@ -2149,46 +2229,46 @@ void VirtualMachine::get_nic_info(int& max_nic_id)
max_nic_id = nic_id;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::set_up_attach_nic(
int vm_id,
VirtualMachineTemplate * tmpl,
int max_nic_id,
int uid,
int& network_id,
string& error_str)
{
vector<Attribute *> nics;
VectorAttribute * new_nic;
Nebula& nd = Nebula::instance();
VirtualNetworkPool* vnpool = nd.get_vnpool();
network_id = -1;
// -------------------------------------------------------------------------
// Get the NIC attribute from the template
// Get the new NIC attribute from the template
// -------------------------------------------------------------------------
nics.clear();
if ( tmpl->get("NIC", nics) != 1 )
{
error_str = "The template must contain one NIC attribute";
return 0;
}
new_nic = dynamic_cast<VectorAttribute * >(nics[0]);
nic = dynamic_cast<VectorAttribute * >(nics[0]);
if ( new_nic == 0 )
if ( nic == 0 )
{
error_str = "Internal error parsing NIC attribute";
return 0;
}
new_nic = new_nic->clone();
nic = nic->clone();
merge_nic_defaults(nic);
return nic;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_up_attach_nic(
int vm_id,
VectorAttribute * new_nic,
int max_nic_id,
int uid,
string& error_str)
{
Nebula& nd = Nebula::instance();
VirtualNetworkPool* vnpool = nd.get_vnpool();
// -------------------------------------------------------------------------
// Acquire the new network lease
@ -2199,10 +2279,10 @@ VectorAttribute * VirtualMachine::set_up_attach_nic(
if ( rc == -1 ) //-2 is not using a pre-defined network
{
delete new_nic;
return 0;
return -1;
}
return new_nic;
return 0;
}
/* -------------------------------------------------------------------------- */
@ -2554,6 +2634,8 @@ int VirtualMachine::get_network_leases(string& estr)
continue;
}
merge_nic_defaults(nic);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
if (rc == -1)
@ -2568,6 +2650,35 @@ int VirtualMachine::get_network_leases(string& estr)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::merge_nic_defaults(VectorAttribute* nic)
{
vector<Attribute *> nics_def;
VectorAttribute * nic_def = 0;
int num;
num = obj_template->get("NIC_DEFAULT", nics_def);
if (num == 0)
{
return;
}
else
{
nic_def = dynamic_cast<VectorAttribute * >(nics_def[0]);
if ( nic_def == 0 )
{
return;
}
}
nic->merge(nic_def, false);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::release_network_leases()
{
string vnid;