1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Merge branch 'feature-1691'

This commit is contained in:
Ruben S. Montero 2013-03-07 01:43:28 +01:00
commit d156f41b07
39 changed files with 1583 additions and 133 deletions

View File

@ -259,8 +259,8 @@ public:
* @return 0 on success, -1 otherwise
*/
int attach(
int vid,
VirtualMachineTemplate * tmpl,
int vid,
VirtualMachineTemplate * tmpl,
string& error_str);
/**
@ -276,6 +276,31 @@ public:
int disk_id,
string& error_str);
/**
* Starts the attach NIC action.
* @param vid VirtualMachine identification
* @param tmpl Template containing the new NIC attribute.
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int attach_nic(
int vid,
VirtualMachineTemplate * tmpl,
string& error_str);
/**
* Starts the detach NIC action.
* @param vid VirtualMachine identification
* @param nic_id NIC to detach
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int detach_nic(
int id,
int nic_id,
string& error_str);
/**
* Starts the snapshot create action
*

View File

@ -62,6 +62,10 @@ public:
ATTACH_FAILURE, /**< Sent by the VMM when an attach action fails */
DETACH_SUCCESS, /**< Sent by the VMM when a detach action succeeds */
DETACH_FAILURE, /**< Sent by the VMM when a detach action fails */
ATTACH_NIC_SUCCESS,/**< Sent by the VMM when an attach nic action succeeds */
ATTACH_NIC_FAILURE,/**< Sent by the VMM when an attach nic action fails */
DETACH_NIC_SUCCESS,/**< Sent by the VMM when a detach nic action succeeds */
DETACH_NIC_FAILURE,/**< Sent by the VMM when a detach nic action fails */
CLEANUP_SUCCESS, /**< Sent by the VMM when a cleanup action succeeds */
CLEANUP_FAILURE, /**< Sent by the VMM when a cleanup action fails */
SNAPSHOT_CREATE_SUCCESS, /**< Sent by the VMM on snap. create success */
@ -193,6 +197,14 @@ private:
void detach_failure_action(int vid);
void attach_nic_success_action(int vid);
void attach_nic_failure_action(int vid);
void detach_nic_success_action(int vid);
void detach_nic_failure_action(int vid);
void cleanup_callback_action(int vid);
void snapshot_create_success(int vid);

View File

@ -177,8 +177,6 @@ public:
~VirtualMachineMonitoring(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
@ -220,6 +218,40 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineAttachNic : public RequestManagerVirtualMachine
{
public:
VirtualMachineAttachNic():
RequestManagerVirtualMachine("VirtualMachineAttachNic",
"Attaches a new NIC to the virtual machine",
"A:sis"){};
~VirtualMachineAttachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDetachNic : public RequestManagerVirtualMachine
{
public:
VirtualMachineDetachNic():
RequestManagerVirtualMachine("VirtualMachineDetachNic",
"Detaches a NIC from a virtual machine",
"A:sii"){};
~VirtualMachineDetachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineResize : public RequestManagerVirtualMachine
{
public:

View File

@ -90,7 +90,8 @@ public:
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25
};
// -------------------------------------------------------------------------
@ -810,6 +811,16 @@ public:
*/
void release_network_leases();
/**
* Releases the network lease taken by this NIC
*
* @param nic NIC to be released
* @param vmid Virtual Machine oid
*
* @return 0 on success, -1 otherwise
*/
static int release_network_leases(VectorAttribute const * nic, int vmid);
/**
* Get all disk images for this Virtual Machine
* @param error_str Returns the error reason, if any
@ -872,7 +883,7 @@ public:
VirtualMachineTemplate *tmpl);
// ------------------------------------------------------------------------
// Hotplug related functions
// Disk Hotplug related functions
// ------------------------------------------------------------------------
/**
@ -883,15 +894,15 @@ public:
void get_disk_info(int& max_disk_id, set<string>& used_targets);
/**
* Generate a DISK attributed to be attached to the VM.
* Generate a DISK attribute to be attached to the VM.
* @param tmpl Template containing a single DISK vector attribute.
* @param used_targets targets in use by current DISKS
* @param max_disk_id Max DISK/DISK_ID of the VM
* @param uid of the VM owner
* @param image_id returns the id of the aquired image
* @param image_id returns the id of the acquired image
* @param error_str describes the error
*
* @return a new vectorattribute with the DISK (should be freed if not
* @return a new VectorAttribute with the DISK (should be freed if not
* added to the template), 0 in case of error;
*/
static VectorAttribute * set_up_attach_disk(
@ -940,19 +951,65 @@ public:
*/
int set_attach_disk(int disk_id);
/**
* Cleans the ATTACH = YES attribute from the disks
*
* @return 0 on success, -1 otherwise
*/
int detach_success();
// ------------------------------------------------------------------------
// NIC Hotplug related functions
// ------------------------------------------------------------------------
/**
* Cleans the ATTACH = YES attribute from the disks
*
* @return 0 on success, -1 otherwise
* Collects information about VM DISKS
* @param max_disk_id of the VM
*/
int detach_failure();
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
* added to the template), 0 in case of error
*/
static VectorAttribute * set_up_attach_nic(
int vm_id,
VirtualMachineTemplate * tmpl,
int max_nic_id,
int uid,
int& network_id,
string& error_str);
/**
* Cleans the ATTACH = YES attribute from the NICs
*/
void clear_attach_nic();
/**
* Deletes the NIC that was in the process of being attached
*
* @return the deleted NIC or 0 if none was deleted
*/
VectorAttribute * delete_attach_nic();
/**
* Adds a new NIC to the virtual machine template. The NIC should be
* generated by the build_attach_nic
* @param new_nic must be allocated in the heap
*/
void set_attach_nic(VectorAttribute * new_nic)
{
new_nic->replace("ATTACH", "YES");
obj_template->set(new_nic);
}
/**
* Sets the attach attribute to the given NIC
* @param nic_id of the NIC
* @return 0 if the nic_id was found, -1 otherwise
*/
int set_attach_nic(int nic_id);
// ------------------------------------------------------------------------

View File

@ -62,6 +62,8 @@ public:
FINALIZE,
ATTACH,
DETACH,
ATTACH_NIC,
DETACH_NIC,
SNAPSHOT_CREATE,
SNAPSHOT_REVERT,
SNAPSHOT_DELETE
@ -335,6 +337,22 @@ private:
void detach_action(
int vid);
/**
* Attaches a new NIC to a VM. The VM must have a NIC with the
* attribute ATTACH = YES
* @param vid the id of the VM.
*/
void attach_nic_action(
int vid);
/**
* Detaches a NIC from a VM. The VM must have a NIC with the
* attribute ATTACH = YES
* @param vid the id of the VM.
*/
void detach_nic_action(
int vid);
/**
* Creates a new system snapshot. The VM must have a snapshot with the
* attribute ACTIVE = YES

View File

@ -275,7 +275,7 @@ private:
}
/**
* Sends an attach request to the MAD: "ATTACH ID XML_DRV_MSG"
* Sends an attach request to the MAD: "ATTACHDISK ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
@ -287,7 +287,7 @@ private:
}
/**
* Sends a detach request to the MAD: "DETACH ID XML_DRV_MSG"
* Sends a detach request to the MAD: "DETACHDISK ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
@ -298,6 +298,30 @@ private:
write_drv("DETACHDISK", oid, drv_msg);
}
/**
* Sends an attach NIC request to the MAD: "ATTACHNIC ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void attach_nic (
const int oid,
const string& drv_msg) const
{
write_drv("ATTACHNIC", oid, drv_msg);
}
/**
* Sends a detach request to the MAD: "DETACHNIC ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void detach_nic (
const int oid,
const string& drv_msg) const
{
write_drv("DETACHNIC", oid, drv_msg);
}
/**
* Sends a snapshot create request to the MAD:
* "SNAPSHOTCREATE ID XML_DRV_MSG"
@ -337,15 +361,6 @@ private:
write_drv("SNAPSHOTDELETE", oid, drv_msg);
}
void write_drv(const char * aname, const int oid, const string& msg) const
{
ostringstream os;
os << aname << " " << oid << " " << msg << endl;
write(os);
}
/**
* Gets VM information from the driver answer
* @param monitor_str from the driver
@ -364,10 +379,21 @@ private:
long long &net_rx,
char &state,
map<string,string> &custom);
/**
*
*/
void write_drv(const char * aname, const int oid, const string& msg) const
{
ostringstream os;
os << aname << " " << oid << " " << msg << endl;
write(os);
}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif /*VIRTUAL_MACHINE_MANAGER_DRIVER_H_*/

View File

@ -101,13 +101,20 @@ public:
* Generates a NIC attribute for VM templates using the VirtualNetwork
* metadata
* @param nic the nic attribute to be generated
* @param nic_id the id for this NIC
* @param uid of the VM owner
* @param vid of the VM requesting the lease
* @param error_str string describing the error
* @return 0 on success,
* -1 error,
* -2 not using the pool
*/
int nic_attribute(VectorAttribute * nic, int uid, int vid, string& error_str);
int nic_attribute(
VectorAttribute* nic,
int nic_id,
int uid,
int vid,
string& error_str);
/**
* Generates an Authorization token for a NIC attribute

View File

@ -759,6 +759,8 @@ VMM_EXEC_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \
src/vmm_mad/remotes/kvm/poll_ganglia \
src/vmm_mad/remotes/kvm/attach_disk \
src/vmm_mad/remotes/kvm/detach_disk \
src/vmm_mad/remotes/kvm/attach_nic \
src/vmm_mad/remotes/kvm/detach_nic \
src/vmm_mad/remotes/kvm/snapshot_create \
src/vmm_mad/remotes/kvm/snapshot_revert \
src/vmm_mad/remotes/kvm/snapshot_delete \
@ -780,6 +782,8 @@ VMM_EXEC_XEN3_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
src/vmm_mad/remotes/xen/poll_ganglia \
src/vmm_mad/remotes/xen/attach_disk \
src/vmm_mad/remotes/xen/detach_disk \
src/vmm_mad/remotes/xen/attach_nic \
src/vmm_mad/remotes/xen/detach_nic \
src/vmm_mad/remotes/xen/snapshot_create \
src/vmm_mad/remotes/xen/snapshot_revert \
src/vmm_mad/remotes/xen/snapshot_delete \
@ -797,6 +801,8 @@ VMM_EXEC_XEN4_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
src/vmm_mad/remotes/xen/poll_ganglia \
src/vmm_mad/remotes/xen/attach_disk \
src/vmm_mad/remotes/xen/detach_disk \
src/vmm_mad/remotes/xen/attach_nic \
src/vmm_mad/remotes/xen/detach_nic \
src/vmm_mad/remotes/xen/snapshot_create \
src/vmm_mad/remotes/xen/snapshot_revert \
src/vmm_mad/remotes/xen/snapshot_delete \
@ -808,6 +814,8 @@ VMM_EXEC_XEN4_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \
src/vmm_mad/remotes/vmware/attach_disk \
src/vmm_mad/remotes/vmware/detach_disk \
src/vmm_mad/remotes/vmware/attach_nic \
src/vmm_mad/remotes/vmware/detach_nic \
src/vmm_mad/remotes/vmware/snapshot_create \
src/vmm_mad/remotes/vmware/snapshot_revert \
src/vmm_mad/remotes/vmware/snapshot_delete \

View File

@ -107,7 +107,8 @@
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>

View File

@ -69,7 +69,8 @@
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>

View File

@ -37,6 +37,17 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
}
}
NETWORK = {
:name => "network",
:short => "-n id|name",
:large => "--network id|name" ,
:description => "Selects the virtual network",
:format => String,
:proc => lambda { |o, options|
OpenNebulaHelper.rname_to_id(o, "VNET")
}
}
FILE = {
:name => "file",
:short => "-f file",
@ -325,52 +336,48 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
if vm.has_elements?("/VM/TEMPLATE/NIC")
CLIHelper.print_header(str_h1 % "VM NICS",false)
vm_nics = vm.to_hash['VM']['TEMPLATE']['NIC']
vm_nics = [vm.to_hash['VM']['TEMPLATE']['NIC']].flatten
nic_default = {"NETWORK" => "-",
"IP" => "-",
"MAC"=> "-",
"VLAN"=>"no",
"BRIDGE"=>"-"}
nic_id = 0
array_id = 0
vm_nics.each {|nic|
next if nic.has_key?("NIC_ID")
nic["NIC_ID"] = nic_id
next if nic.has_key?("CLI_DONE")
if nic.has_key?("IP6_LINK")
ip6_link = {"IP" => nic.delete("IP6_LINK"),
"NIC_ID" => nic_id,
"DOUBLE_ENTRY"=> true}
ip6_link = {"IP" => nic.delete("IP6_LINK"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
if nic.has_key?("IP6_SITE")
ip6_link = {"IP" => nic.delete("IP6_SITE"),
"NIC_ID" => nic_id,
"DOUBLE_ENTRY"=> true}
ip6_link = {"IP" => nic.delete("IP6_SITE"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
if nic.has_key?("IP6_GLOBAL")
ip6_link = {"IP" => nic.delete("IP6_GLOBAL"),
"NIC_ID" => nic_id,
"DOUBLE_ENTRY"=> true}
ip6_link = {"IP" => nic.delete("IP6_GLOBAL"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
nic.merge!(nic_default) {|k,v1,v2| v1}
nic_id += 1
array_id += 1
}
@ -419,7 +426,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
end
end
end.show([vm_nics].flatten,{})
end.show(vm_nics,{})
while vm.has_elements?("/VM/TEMPLATE/NIC")
vm.delete_element("/VM/TEMPLATE/NIC")

View File

@ -56,6 +56,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:description => "Device where the image will be attached"
}
IP={
:name => "ip",
:short => "-i ip",
:large => "--ip ip",
:format => String,
:description => "IP address for the new NIC"
}
CACHE={
:name => "cache",
:large => "--cache cache_mode",
@ -575,6 +583,53 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
attachnic_desc = <<-EOT.unindent
Attaches a NIC to a running VM
States: RUNNING
EOT
command :attachnic, attachnic_desc, :vmid,
:options => [OneVMHelper::FILE, OneVMHelper::NETWORK, IP] do
if options[:file].nil? and options[:network].nil?
STDERR.puts "Provide a template file or a network:"
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit -1
end
if options[:file]
template = File.read(options[:file])
else
network_id = options[:network]
ip = options[:ip]
if ip
template = "NIC = [ NETWORK_ID = #{network_id}, IP = #{ip} ]"
else
template = "NIC = [ NETWORK_ID = #{network_id} ]"
end
end
helper.perform_action(args[0],options,"Attach NIC") do |vm|
vm.attachnic(template)
end
end
detachnic_desc = <<-EOT.unindent
Detaches a NIC from a running VM
States: RUNNING
EOT
command :detachnic, detachnic_desc, :vmid, :nicid do
nicid = args[1].to_i
helper.perform_action(args[0],options,"Detach NIC") do |vm|
vm.detachnic(nicid)
end
end
chgrp_desc = <<-EOT.unindent
Changes the VM group
EOT

View File

@ -905,7 +905,6 @@ int DispatchManager::resubmit(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::attach(int vid,
VirtualMachineTemplate * tmpl,
string & error_str)
@ -1022,7 +1021,6 @@ int DispatchManager::detach(
int disk_id,
string& error_str)
{
ostringstream oss;
Nebula& nd = Nebula::instance();
@ -1270,3 +1268,168 @@ int DispatchManager::snapshot_delete(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::attach_nic(
int vid,
VirtualMachineTemplate* tmpl,
string & error_str)
{
ostringstream oss;
int max_nic_id;
int uid;
int oid;
int network_id;
VectorAttribute * nic;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not add a new NIC to VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not add a new NIC to VM " << vid << ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->get_nic_info(max_nic_id);
vm->set_state(VirtualMachine::HOTPLUG_NIC);
vm->set_resched(false);
uid = vm->get_uid();
oid = vm->get_oid();
vmpool->update(vm);
vm->unlock();
nic = VirtualMachine::set_up_attach_nic(oid,
tmpl,
max_nic_id,
uid,
network_id,
error_str);
vm = vmpool->get(vid, true);
if ( vm == 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." ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( nic == 0 )
{
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
else
{
vm->set_attach_nic(nic);
}
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::ATTACH_NIC,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::detach_nic(
int vid,
int nic_id,
string& error_str)
{
ostringstream oss;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "VirtualMachine " << vid << " no longer exists";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not detach NIC from VM " << vid << ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
if ( vm->set_attach_nic(nic_id) == -1 )
{
oss << "Could not detach NIC with NIC_ID " << nic_id
<< ", it does not exist.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_NIC);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::DETACH_NIC,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -739,6 +739,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose)
case VirtualMachine::CANCEL:
case VirtualMachine::HOTPLUG:
case VirtualMachine::HOTPLUG_SNAPSHOT:
case VirtualMachine::HOTPLUG_NIC:
vm->set_running_etime(the_time);
vmpool->update_history(vm);

View File

@ -145,6 +145,21 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "DETACH_FAILURE";
break;
case ATTACH_NIC_SUCCESS:
aname = "ATTACH_NIC_SUCCESS";
break;
case ATTACH_NIC_FAILURE:
aname = "ATTACH_NIC_FAILURE";
break;
case DETACH_NIC_SUCCESS:
aname = "DETACH_NIC_SUCCESS";
break;
case DETACH_NIC_FAILURE:
aname = "DETACH_NIC_FAILURE";
case CLEANUP_SUCCESS:
aname = "CLEANUP_SUCCESS";
break;
@ -330,6 +345,22 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
detach_failure_action(vid);
}
else if (action == "ATTACH_NIC_SUCCESS")
{
attach_nic_success_action(vid);
}
else if (action == "ATTACH_NIC_FAILURE")
{
attach_nic_failure_action(vid);
}
else if (action == "DETACH_NIC_SUCCESS")
{
detach_nic_success_action(vid);
}
else if (action == "DETACH_NIC_FAILURE")
{
detach_nic_failure_action(vid);
}
else if (action == "CLEANUP_SUCCESS")
{
cleanup_callback_action(vid);

View File

@ -1382,3 +1382,99 @@ void LifeCycleManager::snapshot_delete_failure(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::attach_nic_success_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
vm->clear_attach_nic();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"attach_nic_success_action, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::attach_nic_failure_action(int vid)
{
VirtualMachine * vm;
VectorAttribute * nic;
int uid;
int gid;
int oid;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
nic = vm->delete_attach_nic();
uid = vm->get_uid();
gid = vm->get_gid();
oid = vm->get_oid();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
if ( nic != 0 )
{
Template tmpl;
tmpl.set(nic);
Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl);
VirtualMachine::release_network_leases(nic, oid);
}
}
else
{
vm->log("LCM",Log::ERROR,"attach_nic_failure_action, VM in a wrong state");
vm->unlock();
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::detach_nic_success_action(int vid)
{
attach_nic_failure_action(vid);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::detach_nic_failure_action(int vid)
{
attach_nic_success_action(vid);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -30,22 +30,24 @@ class VirtualMachineDriver < OpenNebulaDriver
# Virtual Machine Driver Protocol constants
ACTION = {
:deploy => "DEPLOY",
:shutdown => "SHUTDOWN",
:reboot => "REBOOT",
:reset => "RESET",
:cancel => "CANCEL",
:save => "SAVE",
:restore => "RESTORE",
:migrate => "MIGRATE",
:poll => "POLL",
:log => "LOG",
:attach_disk => "ATTACHDISK",
:detach_disk => "DETACHDISK",
:deploy => "DEPLOY",
:shutdown => "SHUTDOWN",
:reboot => "REBOOT",
:reset => "RESET",
:cancel => "CANCEL",
:save => "SAVE",
:restore => "RESTORE",
:migrate => "MIGRATE",
:poll => "POLL",
:log => "LOG",
:attach_disk => "ATTACHDISK",
:detach_disk => "DETACHDISK",
:snapshot_create => "SNAPSHOTCREATE",
:snapshot_revert => "SNAPSHOTREVERT",
:snapshot_delete => "SNAPSHOTDELETE",
:cleanup => "CLEANUP"
:cleanup => "CLEANUP",
:attach_nic => "ATTACHNIC",
:detach_nic => "DETACHNIC"
}
POLL_ATTRIBUTE = {
@ -100,6 +102,8 @@ class VirtualMachineDriver < OpenNebulaDriver
register_action(ACTION[:snapshot_delete].to_sym,
method("snapshot_delete"))
register_action(ACTION[:cleanup].to_sym, method("cleanup"))
register_action(ACTION[:attach_nic].to_sym, method("attach_nic"))
register_action(ACTION[:detach_nic].to_sym, method("detach_nic"))
end
# Decodes the encoded XML driver message received from the core
@ -179,6 +183,16 @@ class VirtualMachineDriver < OpenNebulaDriver
send_message(ACTION[:detach_disk],RESULT[:failure],id,error)
end
def attach_nic(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:attach_nic],RESULT[:failure],id,error)
end
def detach_nic(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:detach_nic],RESULT[:failure],id,error)
end
def snapshot_create(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:snapshot_create],RESULT[:failure],id,error)

View File

@ -26,8 +26,8 @@ import org.w3c.dom.Node;
* It also offers static XML-RPC call wrappers.
*/
public class VirtualMachine extends PoolElement{
private static final String METHOD_PREFIX = "vm.";
private static final String ALLOCATE = METHOD_PREFIX + "allocate";
private static final String INFO = METHOD_PREFIX + "info";
private static final String DEPLOY = METHOD_PREFIX + "deploy";
@ -42,6 +42,8 @@ public class VirtualMachine extends PoolElement{
private static final String RENAME = METHOD_PREFIX + "rename";
private static final String UPDATE = METHOD_PREFIX + "update";
private static final String RESIZE = METHOD_PREFIX + "resize";
private static final String ATTACHNIC = METHOD_PREFIX + "attachnic";
private static final String DETACHNIC = METHOD_PREFIX + "detachnic";
private static final String[] VM_STATES =
{
@ -93,7 +95,8 @@ public class VirtualMachine extends PoolElement{
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT" };
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC" };
private static final String[] SHORT_LCM_STATES =
{
@ -314,7 +317,7 @@ public class VirtualMachine extends PoolElement{
}
/**
* Detaches a disk to a running VM
* Detaches a disk from a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
@ -327,6 +330,34 @@ public class VirtualMachine extends PoolElement{
return client.call(DETACH, id, diskId);
}
/**
* Attaches a NIC to a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
* @param nicTemplate Template containing the new NIC definition
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse attachnic(Client client, int id,
String nicTemplate)
{
return client.call(ATTACHNIC, id, nicTemplate);
}
/**
* Detaches a NIC from a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
* @param nicId The NIC_ID of the NIC to detach
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse detachnic(Client client, int id,
int nicId)
{
return client.call(DETACHNIC, id, nicId);
}
/**
* Renames this VM
*
@ -561,7 +592,7 @@ public class VirtualMachine extends PoolElement{
}
/**
* Detaches a disk to a running VM
* Detaches a disk from a running VM
*
* @param diskId The DISK_ID of the disk to detach
* @return If an error occurs the error message contains the reason.
@ -571,6 +602,28 @@ public class VirtualMachine extends PoolElement{
return detachdisk(client, id, diskId);
}
/**
* Attaches a NIC to a running VM
*
* @param nicTemplate Template containing the new NIC definition
* @return If an error occurs the error message contains the reason.
*/
public OneResponse attachnic(String nicTemplate)
{
return attachnic(client, id, nicTemplate);
}
/**
* Detaches a NIC from a running VM
*
* @param nicId The NIC_ID of the NIC to detach
* @return If an error occurs the error message contains the reason.
*/
public OneResponse detachnic(int nicId)
{
return detachnic(client, id, nicId);
}
/**
* Renames this VM
*

View File

@ -23,7 +23,6 @@ module OpenNebula
# Constants and Class Methods
#######################################################################
VM_METHODS = {
:info => "vm.info",
:allocate => "vm.allocate",
@ -41,7 +40,9 @@ module OpenNebula
:resize => "vm.resize",
:snapshotcreate => "vm.snapshotcreate",
:snapshotrevert => "vm.snapshotrevert",
:snapshotdelete => "vm.snapshotdelete"
:snapshotdelete => "vm.snapshotdelete",
:attachnic => "vm.attachnic",
:detachnic => "vm.detachnic"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
@ -51,7 +52,7 @@ module OpenNebula
SAVE_MIGRATE PROLOG_MIGRATE PROLOG_RESUME EPILOG_STOP EPILOG
SHUTDOWN CANCEL FAILURE CLEANUP_RESUBMIT UNKNOWN HOTPLUG SHUTDOWN_POWEROFF
BOOT_UNKNOWN BOOT_POWEROFF BOOT_SUSPENDED BOOT_STOPPED CLEANUP_DELETE
HOTPLUG_SNAPSHOT}
HOTPLUG_SNAPSHOT HOTPLUG_NIC}
SHORT_VM_STATES={
"INIT" => "init",
@ -89,7 +90,8 @@ module OpenNebula
"BOOT_SUSPENDED" => "boot",
"BOOT_STOPPED" => "boot",
"CLEANUP_DELETE" => "clea",
"HOTPLUG_SNAPSHOT" => "snap"
"HOTPLUG_SNAPSHOT" => "snap",
"HOTPLUG_NIC" => "hotp"
}
MIGRATE_REASON=%w{NONE ERROR STOP_RESUME USER CANCEL}
@ -249,23 +251,39 @@ module OpenNebula
end
# Attaches a disk to a running VM
def attachdisk(disk)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:attach], @pe_id, disk)
rc = nil if !OpenNebula.is_error?(rc)
return rc
#
# @param disk_template [String] Template containing a DISK element
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def attachdisk(disk_template)
return call(VM_METHODS[:attach], @pe_id, disk_template)
end
# Detaches a disk from a running VM
def detachdisk(disk)
return Error.new('ID not defined') if !@pe_id
#
# @param disk_id [Integer] Id of the disk to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def detachdisk(disk_id)
return call(VM_METHODS[:detach], @pe_id, disk_id)
end
rc = @client.call(VM_METHODS[:detach], @pe_id, disk)
rc = nil if !OpenNebula.is_error?(rc)
# Attaches a NIC to a running VM
#
# @param nic_template [String] Template containing a NIC element
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def attachnic(nic_template)
return call(VM_METHODS[:attachnic], @pe_id, nic_template)
end
return rc
# Detaches a NIC from a running VM
#
# @param disk_id [Integer] Id of the NIC to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def detachnic(nic_id)
return call(VM_METHODS[:detachnic], @pe_id, nic_id)
end
# Deletes a VM from the pool

View File

@ -321,7 +321,6 @@ module Migrator
@db.run "DROP TABLE old_group_pool;"
########################################################################
# Bug #1694: SYSTEM_DS is now set with the method adddatastore
########################################################################
@ -501,6 +500,44 @@ module Migrator
@db.run "DROP TABLE old_template_pool;"
########################################################################
# Feature #1691 Add new attribute NIC/NIC_ID
########################################################################
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
@db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);"
@db.fetch("SELECT * FROM old_vm_pool") do |row|
if ( row[:state] != 6 ) # DONE
doc = Document.new(row[:body])
nic_id = 0
doc.root.each_element("TEMPLATE/NIC") { |e|
e.delete_element("NIC_ID")
e.add_element("NIC_ID").text = (nic_id).to_s
nic_id += 1
}
row[:body] = doc.root.to_s
end
@db[:vm_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => row[:body],
:uid => row[:uid],
:gid => row[:gid],
:last_poll => row[:last_poll],
:state => row[:state],
:lcm_state => row[:lcm_state],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_vm_pool;"
########################################################################
#

View File

@ -103,7 +103,8 @@ var oZones = {
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT"][value]);
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC"][value]);
break;
case "IMAGE":
case "image":

View File

@ -254,10 +254,13 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring());
xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach());
xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach());
xmlrpc_c::methodPtr vm_attachnic(new VirtualMachineAttachNic());
xmlrpc_c::methodPtr vm_detachnic(new VirtualMachineDetachNic());
xmlrpc_c::methodPtr vm_resize(new VirtualMachineResize());
xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate());
xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert());
xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete());
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring());
@ -399,6 +402,8 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.monitoring", vm_monitoring);
RequestManagerRegistry.addMethod("one.vm.attach", vm_attach);
RequestManagerRegistry.addMethod("one.vm.detach", vm_detach);
RequestManagerRegistry.addMethod("one.vm.attachnic", vm_attachnic);
RequestManagerRegistry.addMethod("one.vm.detachnic", vm_detachnic);
RequestManagerRegistry.addMethod("one.vm.rename", vm_rename);
RequestManagerRegistry.addMethod("one.vm.resize", vm_resize);
RequestManagerRegistry.addMethod("one.vm.update", vm_update);

View File

@ -1510,3 +1510,124 @@ void VirtualMachineSnapshotDelete::request_execute(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineAttachNic::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachineTemplate tmpl;
PoolObjectAuth host_perms;
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
// -------------------------------------------------------------------------
// Parse NIC template
// -------------------------------------------------------------------------
rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
return;
}
// -------------------------------------------------------------------------
// Authorize the operation, restricted attributes & check quotas
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, &tmpl, att, 0, 0, auth_op) == false )
{
return;
}
if (att.uid != UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
string aname;
if (tmpl.check(aname))
{
ostringstream oss;
oss << "NIC includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
return;
}
}
if ( quota_authorization(&tmpl, Quotas::NETWORK, att) == false )
{
return;
}
rc = dm->attach_nic(id, &tmpl, error_str);
if ( rc != 0 )
{
quota_rollback(&tmpl, Quotas::NETWORK, att);
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDetachNic::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int nic_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->detach_nic(id, nic_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -111,7 +111,8 @@ var OpenNebula = {
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT"][value]);
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC"][value]);
break;
case "IMAGE":
case "image":

View File

@ -50,7 +50,7 @@ var vm_graphs = [
];
var VNCstates=["RUNNING","SHUTDOWN","SHUTDOWN_POWEROFF","UNKNOWN","HOTPLUG","CANCEL","MIGRATE", "HOTPLUG_SNAPSHOT"];
var VNCstates=["RUNNING","SHUTDOWN","SHUTDOWN_POWEROFF","UNKNOWN","HOTPLUG","CANCEL","MIGRATE", "HOTPLUG_SNAPSHOT", "HOTPLUG_NIC"];
//Permanent storage for last value of aggregated network usage
//Used to calculate bandwidth

View File

@ -1597,7 +1597,7 @@ void VirtualMachine::get_disk_info(int& max_disk_id,
int disk_id;
int num_disks;
max_disk_id = 0;
max_disk_id = -1;
num_disks = obj_template->get("DISK", disks);
@ -1740,7 +1740,6 @@ VectorAttribute * VirtualMachine::set_up_attach_disk(
int VirtualMachine::set_attach_disk(int disk_id)
{
int num_disks;
int d_id;
@ -1858,6 +1857,175 @@ VectorAttribute * VirtualMachine::delete_attach_disk()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::get_nic_info(int& max_nic_id)
{
vector<Attribute *> nics;
VectorAttribute * nic;
int nic_id;
int num_nics;
max_nic_id = -1;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
nic->vector_value("NIC_ID", nic_id);
if ( nic_id > 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
// -------------------------------------------------------------------------
if ( tmpl->get("NIC", nics) != 1 )
{
error_str = "The template must contain one NIC attribute";
return 0;
}
new_nic = new VectorAttribute(*(dynamic_cast<VectorAttribute * >(nics[0])));
// -------------------------------------------------------------------------
// Acquire the new network lease
// -------------------------------------------------------------------------
int rc = vnpool->nic_attribute(new_nic, max_nic_id+1, uid, vm_id, error_str);
if ( rc == -1 ) //-2 is not using a pre-defined network
{
delete new_nic;
return 0;
}
return new_nic;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::clear_attach_nic()
{
int num_nics;
vector<Attribute *> nics;
VectorAttribute * nic;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
if ( nic->vector_value("ATTACH") == "YES" )
{
nic->remove("ATTACH");
return;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::delete_attach_nic()
{
vector<Attribute *> nics;
VectorAttribute * nic;
int num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
if ( nic->vector_value("ATTACH") == "YES" )
{
return static_cast<VectorAttribute * >(obj_template->remove(nic));
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_attach_nic(int nic_id)
{
int num_nics;
int n_id;
vector<Attribute *> nics;
VectorAttribute * nic;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
nic->vector_value("NIC_ID", n_id);
if ( n_id == nic_id )
{
nic->replace("ATTACH", "YES");
return 0;
}
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::release_disk_images()
{
int iid;
@ -2114,7 +2282,7 @@ int VirtualMachine::get_network_leases(string& estr)
continue;
}
rc = vnpool->nic_attribute(nic, uid, oid, estr);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
if (rc == -1)
{
@ -2130,63 +2298,71 @@ int VirtualMachine::get_network_leases(string& estr)
void VirtualMachine::release_network_leases()
{
Nebula& nd = Nebula::instance();
VirtualNetworkPool * vnpool = nd.get_vnpool();
string vnid;
string ip;
int num_nics;
vector<Attribute const * > nics;
VirtualNetwork * vn;
num_nics = get_template_attribute("NIC",nics);
num_nics = get_template_attribute("NIC",nics);
for(int i=0; i<num_nics; i++)
{
VectorAttribute const * nic =
dynamic_cast<VectorAttribute const * >(nics[i]);
if ( nic == 0 )
{
continue;
}
vnid = nic->vector_value("NETWORK_ID");
if ( vnid.empty() )
{
continue;
}
ip = nic->vector_value("IP");
if ( ip.empty() )
{
continue;
}
vn = vnpool->get(atoi(vnid.c_str()),true);
if ( vn == 0 )
{
continue;
}
if (vn->is_owner(ip,oid))
{
vn->release_lease(ip);
vnpool->update(vn);
}
vn->unlock();
release_network_leases(nic, oid);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::release_network_leases(VectorAttribute const * nic, int vmid)
{
VirtualNetworkPool* vnpool = Nebula::instance().get_vnpool();
VirtualNetwork* vn;
int vnid;
string ip;
if ( nic == 0 )
{
return -1;
}
if ( nic->vector_value("NETWORK_ID", vnid) != 0 )
{
return -1;
}
ip = nic->vector_value("IP");
if ( ip.empty() )
{
return -1;
}
vn = vnpool->get(vnid, true);
if ( vn == 0 )
{
return -1;
}
if (vn->is_owner(ip,vmid))
{
vn->release_lease(ip);
vnpool->update(vn);
}
vn->unlock();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::generate_context(string &files, int &disk_id)
{
ofstream file;

View File

@ -183,6 +183,14 @@ void VirtualMachineManager::trigger(Actions action, int _vid)
aname = "DETACH";
break;
case ATTACH_NIC:
aname = "ATTACH_NIC";
break;
case DETACH_NIC:
aname = "DETACH_NIC";
break;
case SNAPSHOT_CREATE:
aname = "SNAPSHOT_CREATE";
break;
@ -194,6 +202,7 @@ void VirtualMachineManager::trigger(Actions action, int _vid)
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
default:
delete vid;
return;
@ -290,6 +299,14 @@ void VirtualMachineManager::do_action(const string &action, void * arg)
{
detach_action(vid);
}
else if (action == "ATTACH_NIC")
{
attach_nic_action(vid);
}
else if (action == "DETACH_NIC")
{
detach_nic_action(vid);
}
else if (action == "SNAPSHOT_CREATE")
{
snapshot_create_action(vid);
@ -2015,6 +2032,163 @@ error_common:
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::attach_nic_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os, error_os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
// Invoke driver method
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->attach_nic(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "attach_nic_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "attach_nic_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::ATTACH_NIC_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::detach_nic_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string * drv_msg;
string opennebula_hostname;
string error_str;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
// Invoke driver method
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->detach_nic(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "detach_nic_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "detach_nic_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::DETACH_NIC_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -396,6 +396,44 @@ void VirtualMachineManagerDriver::protocol(
lcm->trigger(LifeCycleManager::DETACH_FAILURE, id);
}
}
else if ( action == "ATTACHNIC" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM", Log::ERROR, "VM NIC Successfully attached.");
lcm->trigger(LifeCycleManager::ATTACH_NIC_SUCCESS, id);
}
else
{
log_error(vm, os, is, "Error attaching new VM NIC");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::ATTACH_NIC_FAILURE, id);
}
}
else if ( action == "DETACHNIC" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM",Log::ERROR,"VM NIC Successfully detached.");
lcm->trigger(LifeCycleManager::DETACH_NIC_SUCCESS, id);
}
else
{
log_error(vm,os,is,"Error detaching VM NIC");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::DETACH_NIC_FAILURE, id);
}
}
else if ( action == "SNAPSHOTCREATE" )
{
Nebula &ne = Nebula::instance();

View File

@ -128,6 +128,18 @@ class DummyDriver < VirtualMachineDriver
send_message(ACTION[:detach_disk],result,id)
end
def attach_nic(id, drv_message)
result = retrieve_result("attach_nic")
send_message(ACTION[:attach_nic],result,id)
end
def detach_nic(id, drv_message)
result = retrieve_result("detach_nic")
send_message(ACTION[:detach_nic],result,id)
end
def snapshot_create(id, drv_message)
result = retrieve_result("snapshot_create")

View File

@ -734,6 +734,96 @@ class ExecDriver < VirtualMachineDriver
action.run(steps)
end
#
# ATTACHNIC action to attach a new nic interface
#
def attach_nic(id, drv_message)
xml_data = decode(drv_message)
begin
source = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/BRIDGE"]
mac = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MAC"]
source = source.text.strip
mac = mac.text.strip
rescue
send_message(action, RESULT[:failure], id,
"Error in #{ACTION[:attach_nic]}, BRIDGE and MAC needed in NIC")
return
end
model = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MODEL"]
model = model.text if !model.nil?
model = model.strip if !model.nil?
model = "-" if model.nil?
action = VmmAction.new(self, id, :attach_nic, drv_message)
steps=[
# Execute pre-attach networking setup
{
:driver => :vnm,
:action => :pre
},
# Attach the new NIC
{
:driver => :vmm,
:action => :attach_nic,
:parameters => [:deploy_id, mac, source, model]
},
# Execute post-boot networking setup
{
:driver => :vnm,
:action => :post,
:parameters => [:deploy_info],
:fail_actions => [
{
:driver => :vmm,
:action => :detach_nic,
:parameters => [:deploy_id, mac]
}
]
}
]
action.run(steps)
end
#
# DETACHNIC action to detach a nic interface
#
def detach_nic(id, drv_message)
xml_data = decode(drv_message)
begin
mac = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MAC"]
mac = mac.text.strip
rescue
send_message(action, RESULT[:failure], id,
"Error in #{ACTION[:detach_nic]}, MAC needed in NIC")
return
end
action = VmmAction.new(self, id, :detach_nic, drv_message)
steps=[
# Detach the NIC
{
:driver => :vmm,
:action => :detach_nic,
:parameters => [:deploy_id, mac]
},
# Clean networking setup
{
:driver => :vnm,
:action => :clean
}
]
action.run(steps)
end
private
def ensure_xpath(xml_data, id, action, xpath)

View File

@ -0,0 +1,34 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
SOURCE=$3
MODEL=$4
ATTACH_ARGS="--domain $DOMAIN --type bridge --source $SOURCE --mac $MAC"
if [ "$MODEL" != "-" ]; then
ATTACH_ARGS="$ATTACH_ARGS --model $MODEL"
fi
exec_and_log "virsh --connect $LIBVIRT_URI attach-interface $ATTACH_ARGS" \
"Could not attach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
DETACH_ARGS="--domain $DOMAIN --type bridge --mac $MAC"
exec_and_log "virsh --connect $LIBVIRT_URI detach-interface $DETACH_ARGS" \
"Could not detach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,21 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Attach network interface is not yet supported for VMware."
exit 1

View File

@ -0,0 +1,21 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Detach network interface is not yet supported for VMware."
exit 1

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
SOURCE=$3
MODEL=$4
exec_and_log "$XM_ATTACH_NIC $DOMAIN bridge=$SOURCE mac=$MAC" \
"Could not attach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
ID=`$XM_NETWORK_LIST $DOMAIN | grep -i $MAC | cut -d' ' -f1`
exec_and_log "$XM_DETACH_NIC $DOMAIN $ID" \
"Could not detach NIC ($MAC) to $DOMAIN"

View File

@ -30,6 +30,9 @@ export XM_SHUTDOWN="sudo $XM_PATH shutdown"
export XM_POLL="sudo /usr/sbin/xentop -bi2"
export XM_ATTACH_DISK="sudo $XM_PATH block-attach"
export XM_DETACH_DISK="sudo $XM_PATH block-detach"
export XM_ATTACH_NIC="sudo $XM_PATH network-attach"
export XM_DETACH_NIC="sudo $XM_PATH network-detach"
export XM_NETWORK_LIST="sudo $XM_PATH network-list"
# In xen 4.1 the credit scheduler command is called sched-credit,
# uncomment this line if you are using this version

View File

@ -30,6 +30,9 @@ export XM_SHUTDOWN="sudo $XM_PATH shutdown"
export XM_POLL="sudo /usr/sbin/xentop -bi2"
export XM_ATTACH_DISK="sudo $XM_PATH block-attach"
export XM_DETACH_DISK="sudo $XM_PATH block-detach"
export XM_ATTACH_NIC="sudo $XM_PATH network-attach"
export XM_DETACH_NIC="sudo $XM_PATH network-detach"
export XM_NETWORK_LIST="sudo $XM_PATH network-list"
# In xen 4.1 the credit scheduler command is called sched-credit,
# uncomment this line if you are using this version

View File

@ -237,6 +237,7 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_id(const string& id_s,
}
int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
int nic_id,
int uid,
int vid,
string& error)
@ -267,6 +268,8 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
if ( rc == 0 )
{
update(vnet);
nic->replace("NIC_ID", nic_id);
}
else
{
@ -275,6 +278,7 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
vnet->unlock();
return rc;
}