1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +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); 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 * Replace the value of the given vector attribute
*/ */

View File

@ -1051,6 +1051,12 @@ public:
*/ */
int get_network_leases(string &error_str); 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 * Releases all network leases taken by this Virtual Machine
*/ */
@ -1266,28 +1272,34 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Collects information about VM DISKS * Gets info about the new NIC to attach
* @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
* *
* @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 * added to the template), 0 in case of error
*/ */
static VectorAttribute * set_up_attach_nic( VectorAttribute * get_attach_nic_info(
int vm_id,
VirtualMachineTemplate * tmpl, 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 max_nic_id,
int uid, int uid,
int& network_id,
string& error_str); string& error_str);
/** /**
@ -1596,6 +1608,13 @@ private:
*/ */
int parse_os(string& error_str); 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 * Parse the "CONTEXT" attribute of the template by substituting
* $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE] * $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; 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 max_nic_id;
int uid; int uid;
int oid; int oid;
int network_id; int rc;
VectorAttribute * nic; VectorAttribute * nic;
@ -1387,7 +1387,15 @@ int DispatchManager::attach_nic(
return -1; 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); vm->set_state(VirtualMachine::HOTPLUG_NIC);
@ -1400,17 +1408,19 @@ int DispatchManager::attach_nic(
vm->unlock(); vm->unlock();
nic = VirtualMachine::set_up_attach_nic(oid, rc = VirtualMachine::set_up_attach_nic(oid,
tmpl, nic,
max_nic_id, max_nic_id,
uid, uid,
network_id, error_str);
error_str);
vm = vmpool->get(vid, true); vm = vmpool->get(vid, true);
if ( vm == 0 ) 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 oss << "Could not attach a new NIC to VM " << vid
<< ", VM does not exist after setting its state to HOTPLUG." ; << ", VM does not exist after setting its state to HOTPLUG." ;
@ -1421,7 +1431,7 @@ int DispatchManager::attach_nic(
return -1; return -1;
} }
if ( nic == 0 ) if ( rc != 0 )
{ {
vm->set_state(VirtualMachine::RUNNING); vm->set_state(VirtualMachine::RUNNING);

View File

@ -332,6 +332,17 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
goto error_os; goto error_os;
} }
// ------------------------------------------------------------------------
// Parse the defaults to merge
// ------------------------------------------------------------------------
rc = parse_defaults(error_str);
if ( rc != 0 )
{
goto error_defaults;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Get network leases // Get network leases
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -433,6 +444,7 @@ error_memory:
goto error_common; goto error_common;
error_os: error_os:
error_defaults:
error_name: error_name:
error_common: error_common:
NebulaLog::log("ONE",Log::ERROR, error_str); NebulaLog::log("ONE",Log::ERROR, error_str);
@ -612,6 +624,67 @@ int VirtualMachine::parse_os(string& error_str)
return 0; 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; vector<Attribute *> nics;
VectorAttribute * nic; VectorAttribute * nic;
@ -2129,6 +2205,10 @@ void VirtualMachine::get_nic_info(int& max_nic_id)
int nic_id; int nic_id;
int num_nics; int num_nics;
// -------------------------------------------------------------------------
// Get the highest NIC_ID
// -------------------------------------------------------------------------
max_nic_id = -1; max_nic_id = -1;
num_nics = obj_template->get("NIC", nics); 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; 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 ) if ( tmpl->get("NIC", nics) != 1 )
{ {
error_str = "The template must contain one NIC attribute"; error_str = "The template must contain one NIC attribute";
return 0; 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"; error_str = "Internal error parsing NIC attribute";
return 0; 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 // 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 if ( rc == -1 ) //-2 is not using a pre-defined network
{ {
delete new_nic; delete new_nic;
return 0; return -1;
} }
return new_nic; return 0;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -2554,6 +2634,8 @@ int VirtualMachine::get_network_leases(string& estr)
continue; continue;
} }
merge_nic_defaults(nic);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr); rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
if (rc == -1) 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() void VirtualMachine::release_network_leases()
{ {
string vnid; string vnid;