store OVS network ports at database as type instance:ovs 59/1059/1
authortierno <alfonso.tiernosepulveda@telefonica.com>
Wed, 1 Feb 2017 15:28:11 +0000 (16:28 +0100)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Wed, 1 Feb 2017 15:28:11 +0000 (16:28 +0100)
Change-Id: Ib407ff375df730eec8cc61f8cc9639f7cf9c78bd
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
database_utils/migrate_vim_db.sh
host_thread.py
httpserver.py
openvimd.py
vim_db.py

index e008478..a8a7741 100755 (executable)
@@ -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
 
 
index bb3a433..2e02ede 100644 (file)
@@ -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']
index 718758b..cf26544 100644 (file)
@@ -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':
index 1651df7..eb6c2f0 100755 (executable)
@@ -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
index 386f29f..f2e448d 100644 (file)
--- 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