This is thread that interact with the host and the libvirt to manage VM
One thread will be launched per host
'''
-__author__="Pablo Montes, Alfonso Tierno"
-__date__ ="$10-jul-2014 12:07:15$"
-
+__author__ = "Pablo Montes, Alfonso Tierno, Leonardo Mirabal"
+__date__ = "$10-jul-2014 12:07:15$"
import json
import yaml
#TODO: insert a logging system
-global lvirt_module
-lvirt_module=None #libvirt module is charged only if not in test mode
+
+#global lvirt_module
+#lvirt_module=None #libvirt module is charged only if not in test mode
class host_thread(threading.Thread):
+ lvirt_module = None
def __init__(self, name, host, user, db, db_lock, test, image_path, host_id, version, develop_mode, develop_bridge_iface):
'''Init a thread.
Arguments:
self.db = db
self.db_lock = db_lock
self.test = test
- if not test:
+
+ if not test and not host_thread.lvirt_module:
try:
- lvirt_module = imp.find_module("libvirt")
+ module_info = imp.find_module("libvirt")
+ host_thread.lvirt_module = imp.load_module("libvirt", *module_info)
except (IOError, ImportError) as e:
raise ImportError("Cannot import python-libvirt. Openvim not properly installed" +str(e))
self.queueLock = threading.Lock()
self.taskQueue = Queue.Queue(2000)
-
+ self.ssh_conn = None
+
def ssh_connect(self):
try:
#Connect SSH
except paramiko.ssh_exception.SSHException as e:
text = e.args[0]
print self.name, ": load_localinfo ssh Exception:", text
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
print self.name, ": load_localinfo libvirt Exception:", text
except yaml.YAMLError as exc:
except paramiko.ssh_exception.SSHException as e:
text = e.args[0]
print self.name, ": load_hostinfo ssh Exception:", text
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
print self.name, ": load_hostinfo libvirt Exception:", text
except yaml.YAMLError as exc:
print self.name, ": save_localinfo ssh Exception:", text
if "SSH session not active" in text:
self.ssh_connect()
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
print self.name, ": save_localinfo libvirt Exception:", text
except yaml.YAMLError as exc:
elif task[0] == 'restore-iface':
print self.name, ": processing task restore-iface %s mac=%s" % (task[1], task[2])
self.restore_iface(task[1], task[2])
+ elif task[0] == 'new-ovsbridge':
+ print self.name, ": Creating compute OVS bridge"
+ self.create_ovs_bridge()
+ break
+ elif task[0] == 'new-vxlan':
+ print self.name, ": Creating vxlan tunnel=" + task[1] + ", remote ip=" + task[2]
+ self.create_ovs_vxlan_tunnel(task[1], task[2])
+ break
+ elif task[0] == 'del-ovsbridge':
+ print self.name, ": Deleting OVS bridge"
+ self.delete_ovs_bridge()
+ break
+ elif task[0] == 'del-vxlan':
+ print self.name, ": Deleting vxlan " + task[1] + " tunnel"
+ self.delete_ovs_vxlan_tunnel(task[1])
+ break
+ elif task[0] == 'create-ovs-bridge-port':
+ print self.name, ": Adding port ovim-" + task[1] + " to OVS bridge"
+ self.create_ovs_bridge_port(task[1])
+ elif task[0] == 'del-ovs-port':
+ self.delete_bridge_port_attached_to_ovs(task[1], task[2])
else:
print self.name, ": unknown task", task
self.tab() + "<alias name='net" + str(net_nb)+ "'/>"
elif model==None:
model = "virtio"
+ elif content[0]['provider'][0:3] == "OVS":
+ vlan = content[0]['provider'].replace('OVS:', '')
+ text += self.tab() + "<interface type='bridge'>" + \
+ self.inc_tab() + "<source bridge='ovim-" + vlan + "'/>"
else:
return -1, 'Unknown Bridge net provider ' + content[0]['provider']
if model!=None:
"""Decrement and return indentation according to xml_level"""
self.xml_level -= 1
return self.tab()
-
+
+ def create_ovs_bridge(self):
+ """
+ Create a bridge in compute OVS to allocate VMs
+ :return: True if success
+ """
+ command = 'sudo ovs-vsctl --may-exist add-br br-int -- set Bridge br-int stp_enable=true'
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def delete_port_to_ovs_bridge(self, vlan, net_uuid):
+ """
+ Delete linux bridge port attched to a OVS bridge, if port is not free the port is not removed
+ :param vlan: vlan port id
+ :param net_uuid: network id
+ :return:
+ """
+
+ command = 'sudo ovs-vsctl del-port br-int ovim-' + vlan
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def is_port_free(self, vlan, net_uuid):
+ """
+ Check if por is free before delete from the compute.
+ :param vlan: vlan port id
+ :param net_uuid: network id
+ :return: True if is not free
+ """
+ self.db_lock.acquire()
+ result, content = self.db.get_table(
+ FROM='ports as p join instances as i on p.instance_id=i.uuid',
+ WHERE={"i.host_id": self.host_id, 'p.type': 'instance:bridge', 'p.net_id': net_uuid}
+ )
+ self.db_lock.release()
+
+ if content > 0:
+ return False
+ else:
+ return True
+
+ def add_port_to_ovs_bridge(self, vlan):
+ """
+ Add a bridge linux as a port to a OVS bridge and set a vlan for an specific linux bridge
+ :param vlan: vlan port id
+ :return:
+ """
+ command = 'sudo ovs-vsctl add-port br-int ovim-' + vlan + ' tag=' + vlan
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def delete_bridge_port_attached_to_ovs(self, vlan, net_uuid):
+ """
+ Delete from an existing OVS bridge a linux bridge port attached and the linux bridge itself.
+ :param vlan:
+ :param net_uuid:
+ :return: True if success
+ """
+ if not self.is_port_free(vlan, net_uuid):
+ return True
+ self.delete_port_to_ovs_bridge(vlan, net_uuid)
+ self.delete_linux_bridge(vlan)
+ return True
+
+ def delete_linux_bridge(self, vlan):
+ """
+ Delete a linux bridge in a scpecific compute.
+ :param vlan: vlan port id
+ :return: True if success
+ """
+ command = 'sudo ifconfig ovim-' + vlan + ' down && sudo brctl delbr ovim-' + vlan
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def create_ovs_bridge_port(self, vlan):
+ """
+ Generate a linux bridge and attache the port to a OVS bridge
+ :param vlan: vlan port id
+ :return:
+ """
+ self.create_linux_bridge(vlan)
+ self.add_port_to_ovs_bridge(vlan)
+
+ def create_linux_bridge(self, vlan):
+ """
+ Create a linux bridge with STP active
+ :param vlan: netowrk vlan id
+ :return:
+ """
+ command = 'sudo brctl addbr ovim-' + vlan + ' && sudo ifconfig ovim-' + vlan + ' up'
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+
+ if len(content) != 0:
+ return False
+
+ command = 'sudo brctl stp ovim-' + vlan + ' on'
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def create_ovs_vxlan_tunnel(self, vxlan_interface, remote_ip):
+ """
+ Create a vlxn tunnel between to computes with an OVS installed. STP is also active at port level
+ :param vxlan_interface: vlxan inteface name.
+ :param remote_ip: tunnel endpoint remote compute ip.
+ :return:
+ """
+ command = 'sudo ovs-vsctl add-port br-int ' + vxlan_interface + \
+ ' -- set Interface ' + vxlan_interface + ' type=vxlan options:remote_ip=' + remote_ip + \
+ ' -- set Port ' + vxlan_interface + ' other_config:stp-path-cost=10'
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ print content
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def delete_ovs_vxlan_tunnel(self, vxlan_interface):
+ """
+ Delete a vlxan tunnel port from a OVS brdige.
+ :param vxlan_interface: vlxan name to be delete it.
+ :return: True if success.
+ """
+ command = 'sudo ovs-vsctl del-port br-int ' + vxlan_interface
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ print content
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
+ def delete_ovs_bridge(self):
+ """
+ Delete a OVS bridge from a compute.
+ :return: True if success
+ """
+ command = 'sudo ovs-vsctl del-br br-int'
+ print self.name, ': command:', command
+ (_, stdout, _) = self.ssh_conn.exec_command(command)
+ content = stdout.read()
+ if len(content) == 0:
+ return True
+ else:
+ return False
+
def get_file_info(self, path):
command = 'ls -lL --time-style=+%Y-%m-%dT%H:%M:%S ' + path
print self.name, ': command:', command
print self.name, ": create xml server error:", xml
return -2, xml
print self.name, ": create xml:", xml
- atribute = lvirt_module.VIR_DOMAIN_START_PAUSED if paused == "yes" else 0
+ atribute = host_thread.lvirt_module.VIR_DOMAIN_START_PAUSED if paused == "yes" else 0
#4 Start the domain
if not rebuild: #ensures that any pending destroying server is done
self.server_forceoff(True)
print self.name, ": launch_server(%s) ssh Exception: %s" %(server_id, text)
if "SSH session not active" in text:
self.ssh_connect()
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
print self.name, ": launch_server(%s) libvirt Exception: %s" %(server_id, text)
except Exception as e:
return
try:
- conn = lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
+ conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
domains= conn.listAllDomains()
domain_dict={}
for domain in domains:
uuid = domain.UUIDString() ;
libvirt_status = domain.state()
#print libvirt_status
- if libvirt_status[0] == lvirt_module.VIR_DOMAIN_RUNNING or libvirt_status[0] == lvirt_module.VIR_DOMAIN_SHUTDOWN:
+ if libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_RUNNING or libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_SHUTDOWN:
new_status = "ACTIVE"
- elif libvirt_status[0] == lvirt_module.VIR_DOMAIN_PAUSED:
+ elif libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_PAUSED:
new_status = "PAUSED"
- elif libvirt_status[0] == lvirt_module.VIR_DOMAIN_SHUTOFF:
+ elif libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_SHUTOFF:
new_status = "INACTIVE"
- elif libvirt_status[0] == lvirt_module.VIR_DOMAIN_CRASHED:
+ elif libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_CRASHED:
new_status = "ERROR"
else:
new_status = None
domain_dict[uuid] = new_status
- conn.close
- except lvirt_module.libvirtError as e:
+ conn.close()
+ except host_thread.lvirt_module.libvirtError as e:
print self.name, ": get_state() Exception '", e.get_error_message()
return
self.create_image(None, req)
else:
try:
- conn = lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
+ conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
try:
dom = conn.lookupByUUIDString(server_id)
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
if 'LookupByUUIDString' in text or 'Domain not found' in text or 'No existe un dominio coincidente' in text:
dom = None
else:
new_status = 'ACTIVE'
elif 'start' in req['action']:
- #La instancia está sólo en la base de datos pero no en la libvirt. es necesario crearla
- rebuild = True if req['action']['start']=='rebuild' else False
+ # The instance is only create in DB but not yet at libvirt domain, needs to be create
+ rebuild = True if req['action']['start'] == 'rebuild' else False
r = self.launch_server(conn, req, rebuild, dom)
if r[0] <0:
new_status = 'ERROR'
conn.close()
- except lvirt_module.libvirtError as e:
- if conn is not None: conn.close
+ except host_thread.lvirt_module.libvirtError as e:
+ if conn is not None: conn.close()
text = e.get_error_message()
new_status = "ERROR"
last_error = text
return 0, None
try:
if not lib_conn:
- conn = lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
+ conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
else:
conn = lib_conn
iface.destroy()
iface.create()
print self.name, ": restore_iface '%s' %s" % (name, mac)
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
error_text = e.get_error_message()
print self.name, ": restore_iface '%s' '%s' libvirt exception: %s" %(name, mac, error_text)
ret=-1
finally:
if lib_conn is None and conn is not None:
- conn.close
+ conn.close()
return ret, error_text
try:
conn=None
- conn = lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
+ conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
dom = conn.lookupByUUIDString(port["instance_id"])
if old_net:
text="\n".join(xml)
print self.name, ": edit_iface detaching SRIOV interface", text
- dom.detachDeviceFlags(text, flags=lvirt_module.VIR_DOMAIN_AFFECT_LIVE)
+ dom.detachDeviceFlags(text, flags=host_thread.lvirt_module.VIR_DOMAIN_AFFECT_LIVE)
if new_net:
xml[-1] =" <vlan> <tag id='" + str(port['vlan']) + "'/> </vlan>"
self.xml_level = 1
xml.append('</interface>')
text="\n".join(xml)
print self.name, ": edit_iface attaching SRIOV interface", text
- dom.attachDeviceFlags(text, flags=lvirt_module.VIR_DOMAIN_AFFECT_LIVE)
+ dom.attachDeviceFlags(text, flags=host_thread.lvirt_module.VIR_DOMAIN_AFFECT_LIVE)
- except lvirt_module.libvirtError as e:
+ except host_thread.lvirt_module.libvirtError as e:
text = e.get_error_message()
print self.name, ": edit_iface(",port["instance_id"],") libvirt exception:", text
finally:
- if conn is not None: conn.close
+ if conn is not None: conn.close()
def create_server(server, db, db_lock, only_of_ports):
Two thread will be launched, with normal and administrative permissions.
'''
-__author__="Alfonso Tierno"
-__date__ ="$10-jul-2014 12:07:15$"
+__author__ = "Alfonso Tierno, Leonardo Mirabal"
+__date__ = "$10-jul-2014 12:07:15$"
import bottle
import urlparse
@bottle.route(url_base + '/hosts', method='GET')
def http_get_hosts():
- select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_host,
- ('id','name','description','status','admin_state_up') )
+ return format_out(get_hosts())
+
+
+def get_hosts():
+ select_, where_, limit_ = filter_query_string(bottle.request.query, http2db_host,
+ ('id', 'name', 'description', 'status', 'admin_state_up', 'ip_name'))
myself = config_dic['http_threads'][ threading.current_thread().name ]
result, content = myself.db.get_table(FROM='hosts', SELECT=select_, WHERE=where_, LIMIT=limit_)
for row in content:
row['links'] = ( {'href': myself.url_preffix + '/hosts/' + str(row['id']), 'rel': 'bookmark'}, )
data={'hosts' : content}
- return format_out(data)
+ return data
@bottle.route(url_base + '/hosts/<host_id>', method='GET')
def http_get_host_id(host_id):
thread.start()
config_dic['host_threads'][ content['uuid'] ] = thread
+ if config_dic['network_type'] == 'ovs':
+ # create bridge
+ config_dic['host_threads'][content['uuid']].insert_task("new-ovsbridge")
+ # check if more host exist
+ create_vxlan_mesh(content['uuid'])
+
#return host data
change_keys_http2db(content, http2db_host, reverse=True)
if len(warning_text)>0:
bottle.abort(HTTP_Bad_Request, content)
return
+
+def create_vxlan_mesh(host_id):
+ existing_hosts = get_hosts()
+ if len(existing_hosts['hosts']) > 1:
+ computes_available = existing_hosts['hosts']
+
+ # TUNEL openvim controller
+
+ for count, compute_owner in enumerate(computes_available):
+ for compute in computes_available:
+ if compute_owner['id'] == compute['id']:
+ pass
+ else:
+ vxlan_interface_name = get_vxlan_interface(compute_owner['id'][:8])
+ config_dic['host_threads'][compute['id']].insert_task("new-vxlan",
+ vxlan_interface_name,
+ compute_owner['ip_name'])
+
+
+def delete_vxlan_mesh(host_id):
+ """
+ Create a task for remove a specific compute of the vlxan mesh
+ :param host_id: host id to be deleted.
+ """
+ existing_hosts = get_hosts()
+ computes_available = existing_hosts['hosts']
+ vxlan_interface_name = get_vxlan_interface(host_id[:8])
+
+ for compute in computes_available:
+ if host_id == compute['id']:
+ pass
+ else:
+ config_dic['host_threads'][compute['id']].insert_task("del-vxlan",vxlan_interface_name)
+
+
+def get_vxlan_interface(local_uuid):
+ """
+ Genearte a vxlan interface name
+ :param local_uuid: host id
+ :return: vlxan-8digits
+ """
+ return 'vxlan-' + local_uuid[:8]
+
+
@bottle.route(url_base + '/hosts/<host_id>', method='PUT')
def http_put_host_id(host_id):
'''modify a host into the database. All resources are got and inserted'''
change_keys_http2db(content, http2db_host, reverse=True)
data={'host' : content}
+ if config_dic['network_type'] == 'ovs':
+ delete_vxlan_mesh(host_id)
+ config_dic['host_threads'][host_id].insert_task("del-ovsbridge")
+
#reload thread
config_dic['host_threads'][host_id].name = content.get('name',content['ip_name'])
config_dic['host_threads'][host_id].user = content['user']
config_dic['host_threads'][host_id].host = content['ip_name']
config_dic['host_threads'][host_id].insert_task("reload")
+ if config_dic['network_type'] == 'ovs':
+ # create mesh with new host data
+ config_dic['host_threads'][host_id].insert_task("new-ovsbridge")
+ create_vxlan_mesh(host_id)
+
#print data
return format_out(data)
else:
result, content = my.db.delete_row('hosts', host_id)
if result == 0:
bottle.abort(HTTP_Not_Found, content)
- elif result >0:
- #terminate thread
+ elif result > 0:
+ if config_dic['network_type'] == 'ovs':
+ delete_vxlan_mesh(host_id)
+ # terminate thread
if host_id in config_dic['host_threads']:
+ if config_dic['network_type'] == 'ovs':
+ config_dic['host_threads'][host_id].insert_task("del-ovsbridge")
config_dic['host_threads'][host_id].insert_task("exit")
#return data
data={'result' : content}
#Start server
server['uuid'] = new_instance
- #server_start = server.get('start', 'yes')
+ # server_start = server.get('start', 'yes')
+ if config_dic['network_type'] == 'ovs':
+ server_net = get_network_id(c2[0]['net_id'])
+ vlan = str(server_net['network']['provider:vlan'])
+ config_dic['host_threads'][server['host_id']].insert_task("create-ovs-bridge-port", vlan)
if server_start != 'no':
server['paused'] = True if server_start == 'paused' else False
server['action'] = {"start":None}
if new_status != None and new_status == 'DELETING':
nets=[]
ports_to_free=[]
- #look for dhcp ip address
+
+ net_ovs_list = []
+ #look for dhcp ip address
r2, c2 = my.db.get_table(FROM="ports", SELECT=["mac", "net_id"], WHERE={"instance_id": server_id})
- r,c = my.db.delete_instance(server_id, tenant_id, nets, ports_to_free, "requested by http")
+ r, c = my.db.delete_instance(server_id, tenant_id, nets, ports_to_free, net_ovs_list, "requested by http")
for port in ports_to_free:
r1,c1 = config_dic['host_threads'][ server['host_id'] ].insert_task( 'restore-iface',*port )
if r1 < 0:
#print "dhcp insert del task"
if r < 0:
print ':http_post_servers ERROR UPDATING dhcp_server !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c
-
+ if config_dic['network_type'] == 'ovs':
+ # delete ovs-port and linux bridge
+ for net in net_ovs_list:
+ server_net = get_network_id(net)
+ vlan = str(server_net['network']['provider:vlan'])
+ config_dic['host_threads'][server['host_id']].insert_task('del-ovs-port', vlan, server_net['network']['id'])
return format_out(data)
@bottle.route(url_base + '/networks/<network_id>', method='GET')
def http_get_network_id(network_id):
- my = config_dic['http_threads'][ threading.current_thread().name ]
- #obtain data
+ data = get_network_id(network_id)
+ return format_out(data)
+
+def get_network_id(network_id):
+ my = config_dic['http_threads'][threading.current_thread().name]
+ # obtain data
where_ = bottle.request.query
where_['uuid'] = network_id
result, content = my.db.get_table(FROM='nets', WHERE=where_, LIMIT=100)
content[0]['ports'] = ports
delete_nulls(content[0])
data={'network' : content[0]}
- return format_out(data)
+ return data
@bottle.route(url_base + '/networks', method='POST')
def http_post_networks():
net_type='bridge_man'
if net_provider != None:
- if net_provider[:7]=='bridge:':
- #check it is one of the pre-provisioned bridges
+ if net_provider[:7] == 'bridge:':
bridge_net_name = net_provider[7:]
for brnet in config_dic['bridge_nets']:
if brnet[0]==bridge_net_name: # free
# if bridge_net==None:
# bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
# return
- elif net_type=='bridge_data' or net_type=='bridge_man':
+ elif config_dic['network_type'] == 'bridge' and net_type =='bridge_data' or net_type == 'bridge_man' :
#look for a free precreated nets
for brnet in config_dic['bridge_nets']:
if brnet[3]==None: # free
print "using net", bridge_net
net_provider = "bridge:"+bridge_net[0]
net_vlan = bridge_net[1]
- if net_vlan==None and (net_type=="data" or net_type=="ptp"):
+ elif net_type == 'bridge_data' or net_type == 'bridge_man' and config_dic['network_type'] == 'ovs':
+ net_provider = 'OVS'
+ if not net_vlan and (net_type == "data" or net_type == "ptp" or net_provider == "OVS"):
net_vlan = my.db.get_free_net_vlan()
if net_vlan < 0:
bottle.abort(HTTP_Internal_Server_Error, "Error getting an available vlan")
return
-
+ if config_dic['network_type'] == 'ovs':
+ net_provider = 'OVS' + ":" + str(net_vlan)
+
network['provider'] = net_provider
network['type'] = net_type
network['vlan'] = net_vlan
if bridge_net!=None:
bridge_net[3] = content
- if config_dic.get("dhcp_server"):
+ if config_dic.get("dhcp_server") and config_dic['network_type'] == 'bridge':
if network["name"] in config_dic["dhcp_server"].get("nets", () ):
config_dic["dhcp_nets"].append(content)
print "dhcp_server: add new net", content