1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

feature #476: abstraction class for network management in hooks

This commit is contained in:
Jaime Melis 2011-04-29 16:52:12 +02:00
parent df3829ffb9
commit c6a0fbb8e8
3 changed files with 195 additions and 116 deletions

View File

@ -0,0 +1,195 @@
#!/usr/bin/env ruby
require 'rexml/document'
CONF = {
:start_vlan => 2
}
COMMANDS = {
:ebtables => "sudo /sbin/ebtables",
:brctl => "/usr/sbin/brctl",
:virsh => "virsh -c qemu:///system",
:xm => "sudo /usr/sbin/xm",
:ovs_vsctl => "sudo /usr/local/bin/ovs-vsctl",
:lsmod => "/bin/lsmod"
}
class Nics < Array
# finds nics that match 'args'
# 'args' can be a Hash, or an array
# args example:
# {:mac => "02:00:C0:A8:01:01", :bridge => "br0"}
# :mac, "02:00:C0:A8:01:01"
def get(*args)
if args.length == 2
dict = Hash.new
dict[args[0]] = args[1]
elsif args.length == 1
dict = args[0]
else
return nil
end
matching = Array.new
self.each do |e|
e_filter = Hash.new
dict.each_key{|k| e_filter[k] = e[k]}
if e_filter == dict
matching << e
end
end
if matching.empty?
nil
else
matching
end
end
end
class Nic < Hash
def initialize(hypervisor)
@hypervisor = hypervisor
end
def get_tap(vm)
case vm.hypervisor
when "kvm"
get_tap_kvm(vm)
when "xen"
get_tap_xen(vm)
end
end
def get_tap_kvm(vm)
dumpxml = vm.vm_info[:dumpxml]
dumpxml_root = REXML::Document.new(dumpxml).root
xpath = "devices/interface[@type='bridge']/"
xpath << "mac[@address='#{self[:mac]}']/../target"
tap = dumpxml_root.elements[xpath]
if tap
self[:tap] = tap.attributes['dev']
end
self
end
#TODO:
#def get_tap_xen(nic)
#end
end
class OpenNebulaVLAN
attr_reader :vm_info, :hypervisor
def initialize(vm_tpl, hypervisor=nil)
@vm_root = REXML::Document.new(vm_tpl).root
@vm_info = Hash.new
if !hypervisor
hypervisor = detect_hypervisor
end
@hypervisor = hypervisor
@deploy_id = @vm_root.elements['DEPLOY_ID'].text
case hypervisor
when "kvm"
@vm_info[:dumpxml] = `#{COMMANDS[:virsh]} dumpxml #{@deploy_id}`
when "xen"
end
@nics = get_nics
@filtered_nics = @nics
end
def filter(*filter)
@filtered_nics = @nics.get(*filter)
self
end
def unfilter
@filtered_nics = @nics
self
end
def process(&block)
if @filtered_nics
@filtered_nics.each do |n|
yield(n)
end
end
end
def detect_hypervisor
uname_a = `uname -a`
lsmod = `#{COMMANDS[:lsmod]}`
if uname_a.match(/xen/i)
"xen"
elsif lsmod.match(/kvm/)
"kvm"
end
end
def get_nics
nics = Nics.new
@vm_root.elements.each("TEMPLATE/NIC") do |nic_element|
nic = Nic.new(@hypervisor)
nic_element.elements.each('*') do |nic_attribute|
key = nic_attribute.xpath.split('/')[-1].downcase.to_sym
nic[key] = nic_attribute.text
end
nic.get_tap(self)
nics << nic
end
nics
end
def get_interfaces
bridges = Hash.new
brctl_exit =`#{COMMANDS[:brctl]} show`
cur_bridge = ""
brctl_exit.split("\n")[1..-1].each do |l|
l = l.split
if l.length > 1
cur_bridge = l[0]
bridges[cur_bridge] = Array.new
bridges[cur_bridge] << l[3]
else
bridges[cur_bridge] << l[0]
end
end
bridges
end
end
class OpenvSwitchVLAN < OpenNebulaVLAN
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
end
def activate
process do |nic|
cmd = "#{COMMANDS[:ovs_vsctl]} set Port #{nic[:tap]} "
cmd << "tap=#{nic[:network_id].to_i+CONF[:start_vlan]}"
#TODO: execute command
puts cmd
#system(cmd)
end
end
end
class EbtablesVLAN < OpenNebulaVLAN
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
end
end

View File

@ -1,48 +0,0 @@
<domain type='kvm' id='3'>
<name>one-1</name>
<uuid>95502733-f45a-aa1e-7a46-d40d0a1c88c6</uuid>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc-0.14'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/home/jmelis/work/git/one/one/var//1/images/disk.0'/>
<target dev='sda' bus='scsi'/>
<alias name='scsi0-0-0'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='scsi' index='0'>
<alias name='scsi0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='02:00:ac:10:00:64'/>
<source bridge='br0'/>
<target dev='vnet0'/>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</interface>
<interface type='bridge'>
<mac address='02:00:ac:10:00:65'/>
<source bridge='br1'/>
<target dev='vnet1'/>
<alias name='net1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</interface>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</memballoon>
</devices>
</domain>

View File

@ -1,68 +0,0 @@
<VM>
<ID>1</ID>
<ID>11</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>ttylinux</NAME>
<LAST_POLL>1304001042</LAST_POLL>
<STATE>3</STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1304000879</STIME>
<ETIME>1304000887</ETIME>
<DEPLOY_ID>one-1</DEPLOY_ID>
<MEMORY>65536</MEMORY>
<CPU>97</CPU>
<NET_TX>0</NET_TX>
<NET_RX>1236</NET_RX>
<TEMPLATE>
<CPU><![CDATA[0.1]]></CPU>
<DISK>
<DISK_ID><![CDATA[0]]></DISK_ID>
<READONLY><![CDATA[no]]></READONLY>
<SOURCE><![CDATA[/home/jmelis/work/git/one/files/templates/ttylinux/ttylinux.img]]></SOURCE>
<TARGET><![CDATA[sda]]></TARGET>
<TYPE><![CDATA[file]]></TYPE>
</DISK>
<ERROR>
<MESSAGE><![CDATA[Error deploying virtual machine: Could not create domain from /home/jmelis/work/git/one/one/var//1/images/deployment.0]]></MESSAGE>
<TIMESTAMP><![CDATA[Thu Apr 28 16:28:07 2011]]></TIMESTAMP>
</ERROR>
<FEATURES>
<ACPI><![CDATA[no]]></ACPI>
</FEATURES>
<MEMORY><![CDATA[64]]></MEMORY>
<NAME><![CDATA[ttylinux]]></NAME>
<NIC>
<BRIDGE><![CDATA[br0]]></BRIDGE>
<IP><![CDATA[172.16.0.100]]></IP>
<MAC><![CDATA[02:00:ac:10:00:64]]></MAC>
<NETWORK><![CDATA[Small network]]></NETWORK>
<NETWORK_ID><![CDATA[0]]></NETWORK_ID>
</NIC>
<NIC>
<BRIDGE><![CDATA[br1]]></BRIDGE>
<IP><![CDATA[172.16.0.101]]></IP>
<MAC><![CDATA[02:00:ac:10:00:65]]></MAC>
<NETWORK><![CDATA[Small network]]></NETWORK>
<NETWORK_ID><![CDATA[1]]></NETWORK_ID>
</NIC>
<VMID><![CDATA[1]]></VMID>
</TEMPLATE>
<HISTORY>
<SEQ>1</SEQ>
<HOSTNAME>localhost</HOSTNAME>
<VM_DIR>/home/jmelis/work/git/one/one/var/</VM_DIR>
<HID>2</HID>
<STIME>1304000924</STIME>
<ETIME>0</ETIME>
<VMMMAD>vmm_kvm</VMMMAD>
<TMMAD>tm_nfs</TMMAD>
<PSTIME>1304000924</PSTIME>
<PETIME>1304000924</PETIME>
<RSTIME>1304000924</RSTIME>
<RETIME>0</RETIME>
<ESTIME>0</ESTIME>
<EETIME>0</EETIME>
<REASON>0</REASON>
</HISTORY>
</VM>