From 181f17585738e6724b781cb1b371e8ac3c394cc1 Mon Sep 17 00:00:00 2001 From: tierno Date: Wed, 1 Feb 2017 16:28:11 +0100 Subject: [PATCH] store OVS network ports at database as type instance:ovs Change-Id: Ib407ff375df730eec8cc61f8cc9639f7cf9c78bd Signed-off-by: tierno --- database_utils/migrate_vim_db.sh | 15 ++++++++++++++- host_thread.py | 26 +++++++++++++++++++++++--- httpserver.py | 13 ++++++------- openvimd.py | 4 ++-- vim_db.py | 28 ++++++++++++++-------------- 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/database_utils/migrate_vim_db.sh b/database_utils/migrate_vim_db.sh index e008478..a8a7741 100755 --- a/database_utils/migrate_vim_db.sh +++ b/database_utils/migrate_vim_db.sh @@ -175,7 +175,8 @@ DATABASE_TARGET_VER_NUM=0 [ $OPENVIM_VER_NUM -ge 4001 ] && DATABASE_TARGET_VER_NUM=5 #0.4.1 => 5 [ $OPENVIM_VER_NUM -ge 4002 ] && DATABASE_TARGET_VER_NUM=6 #0.4.2 => 6 [ $OPENVIM_VER_NUM -ge 4005 ] && DATABASE_TARGET_VER_NUM=7 #0.4.5 => 7 -[ $OPENVIM_VER_NUM -ge 4010 ] && DATABASE_TARGET_VER_NUM=8 #0.4.10 => 8 +[ $OPENVIM_VER_NUM -ge 4010 ] && DATABASE_TARGET_VER_NUM=8 #0.4.10 => 8 +[ $OPENVIM_VER_NUM -ge 5002 ] && DATABASE_TARGET_VER_NUM=9 #0.5.2 => 9 #TODO ... put next versions here @@ -452,6 +453,18 @@ function downgrade_from_8(){ echo "DELETE FROM schema_version WHERE version_int = '8';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 } +function upgrade_to_9(){ + echo " upgrade database from version 0.8 to version 0.9" + echo " change types at 'ports'" + echo "ALTER TABLE ports CHANGE COLUMN type type ENUM('instance:bridge','instance:data','external','instance:ovs','controller:ovs') NOT NULL DEFAULT 'instance:bridge' AFTER status;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + echo "INSERT INTO schema_version (version_int, version, openvim_ver, comments, date) VALUES (9, '0.9', '0.5.2', 'add column checksum to images', '2016-09-30');"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 +} +function downgrade_from_9(){ + echo " downgrade database from version 0.9 to version 0.8" + echo " change back types at 'ports'" + echo "ALTER TABLE ports CHANGE COLUMN type type ENUM('instance:bridge','instance:data','external') NOT NULL DEFAULT 'instance:bridge' AFTER status;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + echo "DELETE FROM schema_version WHERE version_int = '9';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 +} #TODO ... put funtions here diff --git a/host_thread.py b/host_thread.py index bb3a433..2e02ede 100644 --- a/host_thread.py +++ b/host_thread.py @@ -712,6 +712,8 @@ class host_thread(threading.Thread): Create a bridge in compute OVS to allocate VMs :return: True if success """ + if self.test: + return 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) @@ -740,7 +742,7 @@ class host_thread(threading.Thread): def is_port_free(self, vlan, net_uuid): """ - Check if por is free before delete from the compute. + Check if there not ovs ports of a network in a compute host. :param vlan: vlan port id :param net_uuid: network id :return: True if is not free @@ -748,7 +750,7 @@ class host_thread(threading.Thread): 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} + WHERE={"i.host_id": self.host_id, 'p.type': 'instance:ovs', 'p.net_id': net_uuid} ) self.db_lock.release() @@ -779,6 +781,8 @@ class host_thread(threading.Thread): :param net_uuid: :return: True if success """ + if self.test: + return if not self.is_port_free(vlan, net_uuid): return True self.delete_port_to_ovs_bridge(vlan, net_uuid) @@ -806,6 +810,8 @@ class host_thread(threading.Thread): :param vlan: vlan port id :return: """ + if self.test: + return self.create_linux_bridge(vlan) self.add_port_to_ovs_bridge(vlan) @@ -840,6 +846,8 @@ class host_thread(threading.Thread): :param remote_ip: tunnel endpoint remote compute ip. :return: """ + if self.test: + 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' @@ -858,6 +866,8 @@ class host_thread(threading.Thread): :param vxlan_interface: vlxan name to be delete it. :return: True if success. """ + if self.test: + return command = 'sudo ovs-vsctl del-port br-int ' + vxlan_interface print self.name, ': command:', command (_, stdout, _) = self.ssh_conn.exec_command(command) @@ -873,6 +883,8 @@ class host_thread(threading.Thread): Delete a OVS bridge from a compute. :return: True if success """ + if self.test: + return command = 'sudo ovs-vsctl del-br br-int' print self.name, ': command:', command (_, stdout, _) = self.ssh_conn.exec_command(command) @@ -1847,7 +1859,9 @@ def create_server(server, db, db_lock, only_of_ports): control_iface['net_id']=control_iface.pop('uuid') #Get the brifge name db_lock.acquire() - result, content = db.get_table(FROM='nets', SELECT=('name','type', 'vlan'),WHERE={'uuid':control_iface['net_id']} ) + result, content = db.get_table(FROM = 'nets', + SELECT = ('name','type', 'vlan', 'provider'), + WHERE = {'uuid':control_iface['net_id']}) db_lock.release() if result < 0: pass @@ -1859,6 +1873,12 @@ def create_server(server, db, db_lock, only_of_ports): if network['type']!='bridge_data' and network['type']!='bridge_man': return -1, "Error at field netwoks: network uuid %s for control interface is not of type bridge_man or bridge_data" % control_iface['net_id'] resources['bridged-ifaces'].append(control_iface) + if network.get("provider") and network["provider"][0:3] == "OVS": + control_iface["type"] = "instance:ovs" + else: + control_iface["type"] = "instance:bridge" + if network.get("vlan"): + control_iface["vlan"] = network["vlan"] else: if network['type']!='data' and network['type']!='ptp': return -1, "Error at field netwoks: network uuid %s for dataplane interface is not of type data or ptp" % control_iface['net_id'] diff --git a/httpserver.py b/httpserver.py index 718758b..cf26544 100644 --- a/httpserver.py +++ b/httpserver.py @@ -1648,12 +1648,11 @@ def http_server_action(server_id, tenant_id, action): #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']) + # delete ovs-port and linux bridge, contains a list of tuple (net_id,vlan) + for net in net_ovs_list: + vlan = str(net[1]) + net_id = net[0] + config_dic['host_threads'][server['host_id']].insert_task('del-ovs-port', vlan, net_id) return format_out(data) @@ -2206,7 +2205,7 @@ def http_put_port_id(port_id): if new_net is not None: nets.append(new_net) #put first the new net, so that new openflow rules are created before removing the old ones if old_net is not None: nets.append(old_net) - if port['type'] == 'instance:bridge': + if port['type'] == 'instance:bridge' or port['type'] == 'instance:ovs': bottle.abort(HTTP_Forbidden, "bridge interfaces cannot be attached to a different net") return elif port['type'] == 'external': diff --git a/openvimd.py b/openvimd.py index 1651df7..eb6c2f0 100755 --- a/openvimd.py +++ b/openvimd.py @@ -30,9 +30,9 @@ and host controllers __author__="Alfonso Tierno" __date__ ="$10-jul-2014 12:07:15$" -__version__="0.5.1-r518" +__version__="0.5.2-r519" version_date="Jan 2017" -database_version="0.8" #expected database schema version +database_version="0.9" #expected database schema version import httpserver import auxiliary_functions as af diff --git a/vim_db.py b/vim_db.py index 386f29f..f2e448d 100644 --- a/vim_db.py +++ b/vim_db.py @@ -1027,15 +1027,16 @@ class vim_db(): with self.con: self.cur = self.con.cursor(mdb.cursors.DictCursor) #get INSTANCE - cmd = "SELECT uuid, name, description, progress, host_id, flavor_id, image_id, status, last_error, tenant_id, ram, vcpus, created_at \ - FROM instances WHERE uuid = '" + str(instance_id) +"'" + cmd = "SELECT uuid, name, description, progress, host_id, flavor_id, image_id, status, last_error, "\ + "tenant_id, ram, vcpus, created_at FROM instances WHERE uuid='{}'".format(instance_id) self.logger.debug(cmd) self.cur.execute(cmd) if self.cur.rowcount == 0 : return 0, "instance '" + str(instance_id) +"'not found." instance = self.cur.fetchone() #get networks - cmd = "SELECT uuid as iface_id, net_id, mac as mac_address, ip_address, name, Mbps as bandwidth, vpci, model \ - FROM ports WHERE type = 'instance:bridge' AND instance_id = '" + instance_id + "'" + cmd = "SELECT uuid as iface_id, net_id, mac as mac_address, ip_address, name, Mbps as bandwidth, "\ + "vpci, model FROM ports WHERE (type='instance:bridge' or type='instance:ovs') AND "\ + "instance_id= '{}'".format(instance_id) self.logger.debug(cmd) self.cur.execute(cmd) if self.cur.rowcount > 0 : @@ -1105,8 +1106,9 @@ class vim_db(): numa_dict['threads-source'] = thread_source #get dedicated ports and SRIOV - cmd = "SELECT port_id as iface_id, p.vlan as vlan, p.mac as mac_address, net_id, if(model='PF','yes',if(model='VF','no','yes:sriov')) as dedicated,\ - rp.Mbps as bandwidth, name, vpci, pci as source \ + cmd = "SELECT port_id as iface_id, p.vlan as vlan, p.mac as mac_address, net_id, if(model='PF',\ + 'yes',if(model='VF','no','yes:sriov')) as dedicated, rp.Mbps as bandwidth, name, vpci, \ + pci as source \ FROM resources_port as rp join ports as p on port_id=uuid WHERE p.instance_id = '%s' AND numa_id = '%s' and p.type='instance:data'" % (instance_id, numa_id) self.logger.debug(cmd) self.cur.execute(cmd) @@ -1395,7 +1397,7 @@ class vim_db(): self.cur.execute(cmd) #insert iface iface['instance_id'] = uuid - iface['type'] = 'instance:bridge' + # iface['type'] = 'instance:bridge' if 'name' not in iface: iface['name']="br"+str(nb_bridge_ifaces) iface['Mbps']=iface.pop('bandwidth', None) if 'mac_address' not in iface: @@ -1518,13 +1520,11 @@ class vim_db(): net_dataplane_list.append(net[0]) # get ovs manangement nets - cmd = "SELECT DISTINCT net_id from ports WHERE instance_id = " \ - "'%s' AND net_id is not Null AND type='instance:bridge'" % instance_id + cmd = "SELECT DISTINCT net_id, vlan FROM ports WHERE instance_id='{}' AND net_id is not Null AND "\ + "type='instance:ovs'".format(instance_id) self.logger.debug(cmd) self.cur.execute(cmd) - net_list__ = self.cur.fetchall() - for net in net_list__: - net_ovs_list.append(net[0]) + net_ovs_list += self.cur.fetchall() #get dataplane interfaces releases by this VM; both PF and VF with no other VF cmd="SELECT source_name, mac FROM (SELECT root_id, count(instance_id) as used FROM resources_port WHERE instance_id='%s' GROUP BY root_id ) AS A" % instance_id \ @@ -1635,8 +1635,8 @@ class vim_db(): if net['tenant_id']==tenant_id and net['shared']=='false': return -1, "needed admin privileges to attach to the net %s" % net_id #check types - if (net['type'] in ('p2p','data') and 'port_type' == 'instance:bridge') or \ - (net['type'] in ('bridge_data','bridge_man') and 'port_type' != 'instance:bridge') : + if (net['type'] in ('p2p','data') and port_type != 'instance:data') or \ + (net['type'] in ('bridge_data','bridge_man') and port_type not in ('instance:bridge', 'instance:ovs')): return -1, "can not attach a port of type %s into a net of type %s" % (port_type, net['type']) if net['type'] == 'ptp': #look how many -- 2.17.1