1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-13 12:58:17 +03:00

Bug #4314 Feature #4320: VMs get IP6 context with ULA only addresses.

Re-design of update logic to work as other update methods
This commit is contained in:
Ruben S. Montero 2016-05-06 12:17:31 +02:00
parent a1adb24bbc
commit 20b84754ee
3 changed files with 52 additions and 100 deletions

View File

@ -1908,23 +1908,19 @@ private:
* Parse and generate the ETH_ network attributed of a NIC
* @param context attribute
* @param nic attribute
* @param replace attributes if the exist
*
* @return 0 on success
*/
void parse_nic_context(VectorAttribute * context, VectorAttribute * nic,
bool replace);
void parse_nic_context(VectorAttribute * context, VectorAttribute * nic);
/**
* Generate the NETWORK related CONTEXT setions, i.e. ETH_*. This function
* is invoked when ever the context is prepared for the VM to capture
* netowrking updates.
* @param context attribute of the VM
* @param replace attributes if the exist
* @return true if the net context was generated.
*/
bool generate_network_context(VectorAttribute * context, bool replace);
bool generate_network_context(VectorAttribute * context);
/**
* Generate the ONE_GATE token & url

View File

@ -928,61 +928,37 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Updates the configuration of a VM. The VM cannot be in a active (running)
state, valid states are: pending, failure, poweroff, undeploy, hold or
clonning.
Examples:
- Update boot order:
This command accepts a template file or opens an editor, the full list of
configuration attributes are:
onevm updateconf myvm --boot disk2,nic0
- Change arch and add vnc:
onevm updateconf myvm --arch x86_64 --vnc
- Change the DNS for ETH0 device and add PASSWORD:
onevm updateconf myvm --context 'ETH0_DNS="8.8.8.8", PASSWORD="$USER[PASSWORD]"'
This command also accepts a template, the full list of configuration
attributes are (not all supported via options):
OS = ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT"]
FEATURES = ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT"]
INPUT = ["TYPE", "BUS"]
GRAPHICS = ["TYPE", "LISTEN", "PASSWD", "KEYMAP" ]
RAW = ["DATA", "DATA_VMX", "TYPE"]
CONTEXT (any value, **variable substitution will be made**)
*NOTE* Update will replace or add attributes, to remove an existing one
add an empty value.
EOT
command :updateconf, updateconf_desc, :vmid, [:file, nil], :options =>
OpenNebulaHelper::UPDATECONF_OPTIONS_VM do
if args[1] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts "You can not use both a file and update options."
exit -1
end
command :updateconf, updateconf_desc, :vmid, [:file, nil] do
template = ""
begin
if args[1]
template=File.read(args[1])
else
res = OpenNebulaHelper.create_template(options)
if res.first != 0
STDERR.puts res.last
exit -1
end
template = res.last
end
template=File.read(args[1]) if args[1]
rescue Exception => e
STDERR.puts "Error reading template."
exit -1
end
helper.perform_action(args[0], options, "Updating VM configuration") do |vm|
if template.empty?
vm.info
template = vm.template_like_str('TEMPLATE', true,
'OS | FEATURES | INPUT | GRAPHICS | RAW | CONTEXT')
template = OpenNebulaHelper::editor_input(template)
end
vm.updateconf(template)
end
end

View File

@ -151,11 +151,12 @@ const int VirtualMachine::NUM_NETWORK_CONTEXT = 10;
const char* VirtualMachine::NETWORK6_CONTEXT[][2] = {
{"IP6", "IP6_GLOBAL"},
{"IP6_ULA", "IP6_ULA"},
{"GATEWAY6", "GATEWAY6"},
{"CONTEXT_FORCE_IPV4", "CONTEXT_FORCE_IPV4"},
{"VROUTER_IP6", "VROUTER_IP6_GLOBAL"}};
const int VirtualMachine::NUM_NETWORK6_CONTEXT = 4;
const int VirtualMachine::NUM_NETWORK6_CONTEXT = 5;
const char* VirtualMachine::VROUTER_ATTRIBUTES[] = {
"VROUTER_ID",
@ -1021,7 +1022,7 @@ int VirtualMachine::parse_context(string& error_str)
// -------------------------------------------------------------------------
// Add network context and parse variables
// -------------------------------------------------------------------------
generate_network_context(context, false);
generate_network_context(context);
if (parse_context_variables(&context, error_str) == -1)
{
@ -3305,7 +3306,7 @@ int VirtualMachine::generate_context(string &files, int &disk_id,
}
//Generate dynamic context attributes
if ( generate_network_context(context, false) )
if ( generate_network_context(context) )
{
string error;
@ -4702,7 +4703,7 @@ void VirtualMachine::delete_non_persistent_disk_snapshots(Template **vm_quotas,
/* -------------------------------------------------------------------------- */
static void parse_context_network(const char* vars[][2], int num_vars,
VectorAttribute * context, VectorAttribute * nic, bool replace)
VectorAttribute * context, VectorAttribute * nic)
{
string nic_id = nic->vector_value("NIC_ID");
@ -4714,12 +4715,6 @@ static void parse_context_network(const char* vars[][2], int num_vars,
cvar << "ETH" << nic_id << "_" << vars[i][0];
cval = context->vector_value(cvar.str().c_str());
if (!cval.empty() && !replace)
{
continue;
}
cval = nic->vector_value(vars[i][1]); //Check the NIC
if (cval.empty()) //Will check the AR and VNET
@ -4736,20 +4731,15 @@ static void parse_context_network(const char* vars[][2], int num_vars,
/* -------------------------------------------------------------------------- */
void VirtualMachine::parse_nic_context(VectorAttribute * c, VectorAttribute * n,
bool rpl)
void VirtualMachine::parse_nic_context(VectorAttribute * c, VectorAttribute * n)
{
parse_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT, c, n, rpl);
if (!n->vector_value("IP6_GLOBAL").empty())
{
parse_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT, c, n, rpl);
}
parse_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT, c, n);
parse_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT, c, n);
}
/* -------------------------------------------------------------------------- */
bool VirtualMachine::generate_network_context(VectorAttribute * context, bool r)
bool VirtualMachine::generate_network_context(VectorAttribute * context)
{
bool net_context;
@ -4760,13 +4750,15 @@ bool VirtualMachine::generate_network_context(VectorAttribute * context, bool r)
return net_context;
}
context->remove("NETWORK");
vector<VectorAttribute *> vatts;
int num_vatts = obj_template->get("NIC", vatts);
for(int i=0; i<num_vatts; i++)
{
parse_nic_context(context, vatts[i], r);
parse_nic_context(context, vatts[i]);
}
return net_context;
@ -4786,6 +4778,8 @@ int VirtualMachine::generate_token_context(VectorAttribute * context, string& e)
return 0;
}
context->remove("TOKEN");
Nebula::instance().get_configuration_attribute("ONEGATE_ENDPOINT", ep);
if ( ep.empty() )
@ -4815,29 +4809,21 @@ static void replace_vector_values(Template *old_tmpl, Template *new_tmpl,
string value;
VectorAttribute * new_attr = new_tmpl->get(name);
VectorAttribute * old_attr = old_tmpl->get(name);
if ( new_attr == 0 )
{
return;
old_tmpl->erase(name);
}
VectorAttribute * old_attr = old_tmpl->get(name);
if ( old_attr == 0 )
else if ( old_attr == 0 )
{
old_attr = new VectorAttribute(name);
old_tmpl->set(old_attr);
old_tmpl->set(new_attr->clone());
}
if ( num > 0 && vnames != 0 )
else
{
for (int i=0; i < num; i++)
{
if ( new_attr->vector_value(vnames[i], value) == -1 )
{
continue;
}
else if (value.empty())
{
old_attr->remove(vnames[i]);
}
@ -4847,23 +4833,6 @@ static void replace_vector_values(Template *old_tmpl, Template *new_tmpl,
}
}
}
else //replace all
{
const map<string, string> contents = new_attr->value();
map<string, string>::const_iterator it;
for ( it = contents.begin() ; it != contents.end() ; ++it )
{
if ( it->second.empty() )
{
old_attr->remove(it->first);
}
else
{
old_attr->replace(it->first, it->second);
}
}
}
};
/* -------------------------------------------------------------------------- */
@ -4965,18 +4934,29 @@ int VirtualMachine::updateconf(VirtualMachineTemplate& tmpl, string &err)
// -------------------------------------------------------------------------
// Update CONTEXT: any value
// -------------------------------------------------------------------------
VectorAttribute * context = obj_template->get("CONTEXT");
VectorAttribute * context_bck = obj_template->get("CONTEXT");
VectorAttribute * context_new = tmpl.get("CONTEXT");
if ( context != 0 )
if ( context_bck == 0 && context_new != 0 )
{
VectorAttribute * context_bck = context->clone();
err = "Virtual machine does not have context, cannot add a new one.";
replace_vector_values(obj_template, &tmpl, "CONTEXT", 0, -1);
return -1;
}
else if ( context_bck != 0 && context_new != 0 )
{
context_new = context_new->clone();
generate_network_context(context, true);
context_new->replace("TARGET", context_bck->vector_value("TARGET"));
context_new->replace("DISK_ID", context_bck->vector_value("DISK_ID"));
if ( generate_token_context(context, err) != 0 ||
parse_context_variables(&context, err) )
obj_template->remove(context_bck);
obj_template->set(context_new);
generate_network_context(context_new);
if ( generate_token_context(context_new, err) != 0 ||
parse_context_variables(&context_new, err) )
{
obj_template->erase("CONTEXT");
obj_template->set(context_bck);