Modify openvim code structure, improve py package
[osm/openvim.git] / host_thread.py
diff --git a/host_thread.py b/host_thread.py
deleted file mode 100644 (file)
index d8bca2e..0000000
+++ /dev/null
@@ -1,2274 +0,0 @@
-# -*- coding: utf-8 -*-
-
-##
-# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
-# This file is part of openvim
-# All Rights Reserved.
-#
-# 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.
-#
-# For those usages not covered by the Apache License, Version 2.0 please
-# contact with: nfvlabs@tid.es
-##
-
-'''
-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, Leonardo Mirabal"
-__date__ = "$10-jul-2014 12:07:15$"
-
-import json
-import yaml
-import threading
-import time
-import Queue
-import paramiko
-from jsonschema import validate as js_v, exceptions as js_e
-#import libvirt
-import imp
-from vim_schema import localinfo_schema, hostinfo_schema
-import random
-import os
-
-#TODO: insert a logging system
-
-# from logging import Logger
-# import auxiliary_functions as af
-
-# TODO: insert a logging system
-
-
-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:
-            'id' number of thead
-            'name' name of thread
-            'host','user':  host ip or name to manage and user
-            'db', 'db_lock': database class and lock to use it in exclusion
-        '''
-        threading.Thread.__init__(self)
-        self.name = name
-        self.host = host
-        self.user = user
-        self.db = db
-        self.db_lock = db_lock
-        self.test = test
-
-        if not test and not host_thread.lvirt_module:
-            try:
-                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.develop_mode = develop_mode
-        self.develop_bridge_iface = develop_bridge_iface
-        self.image_path = image_path
-        self.host_id = host_id
-        self.version = version
-        
-        self.xml_level = 0
-        #self.pending ={}
-        
-        self.server_status = {} #dictionary with pairs server_uuid:server_status 
-        self.pending_terminate_server =[] #list  with pairs (time,server_uuid) time to send a terminate for a server being destroyed
-        self.next_update_server_status = 0 #time when must be check servers status
-        
-        self.hostinfo = None 
-        
-        self.queueLock = threading.Lock()
-        self.taskQueue = Queue.Queue(2000)
-        self.ssh_conn = None
-
-    def ssh_connect(self):
-        try:
-            #Connect SSH
-            self.ssh_conn = paramiko.SSHClient()
-            self.ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-            self.ssh_conn.load_system_host_keys()
-            self.ssh_conn.connect(self.host, username=self.user, timeout=10) #, None)
-        except paramiko.ssh_exception.SSHException as e:
-            text = e.args[0]
-            print self.name, ": ssh_connect ssh Exception:", text
-        
-    def load_localinfo(self):
-        if not self.test:
-            try:
-                #Connect SSH
-                self.ssh_connect()
-    
-                command = 'mkdir -p ' +  self.image_path
-                #print self.name, ': command:', command
-                (_, stdout, stderr) = self.ssh_conn.exec_command(command)
-                content = stderr.read()
-                if len(content) > 0:
-                    print self.name, ': command:', command, "stderr:", content
-
-                command = 'cat ' +  self.image_path + '/.openvim.yaml'
-                #print self.name, ': command:', command
-                (_, stdout, stderr) = self.ssh_conn.exec_command(command)
-                content = stdout.read()
-                if len(content) == 0:
-                    print self.name, ': command:', command, "stderr:", stderr.read()
-                    raise paramiko.ssh_exception.SSHException("Error empty file ")
-                self.localinfo = yaml.load(content)
-                js_v(self.localinfo, localinfo_schema)
-                self.localinfo_dirty=False
-                if 'server_files' not in self.localinfo:
-                    self.localinfo['server_files'] = {}
-                print self.name, ': localinfo load from host'
-                return
-    
-            except paramiko.ssh_exception.SSHException as e:
-                text = e.args[0]
-                print self.name, ": load_localinfo ssh Exception:", text
-            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:
-                text = ""
-                if hasattr(exc, 'problem_mark'):
-                    mark = exc.problem_mark
-                    text = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
-                print self.name, ": load_localinfo yaml format Exception", text
-            except js_e.ValidationError as e:
-                text = ""
-                if len(e.path)>0: text=" at '" + ":".join(map(str, e.path))+"'"
-                print self.name, ": load_localinfo format Exception:", text, e.message 
-            except Exception as e:
-                text = str(e)
-                print self.name, ": load_localinfo Exception:", text
-        
-        #not loaded, insert a default data and force saving by activating dirty flag
-        self.localinfo = {'files':{}, 'server_files':{} } 
-        #self.localinfo_dirty=True
-        self.localinfo_dirty=False
-
-    def load_hostinfo(self):
-        if self.test:
-            return;
-        try:
-            #Connect SSH
-            self.ssh_connect()
-
-
-            command = 'cat ' +  self.image_path + '/hostinfo.yaml'
-            #print self.name, ': command:', command
-            (_, stdout, stderr) = self.ssh_conn.exec_command(command)
-            content = stdout.read()
-            if len(content) == 0:
-                print self.name, ': command:', command, "stderr:", stderr.read()
-                raise paramiko.ssh_exception.SSHException("Error empty file ")
-            self.hostinfo = yaml.load(content)
-            js_v(self.hostinfo, hostinfo_schema)
-            print self.name, ': hostlinfo load from host', self.hostinfo
-            return
-
-        except paramiko.ssh_exception.SSHException as e:
-            text = e.args[0]
-            print self.name, ": load_hostinfo ssh Exception:", text
-        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:
-            text = ""
-            if hasattr(exc, 'problem_mark'):
-                mark = exc.problem_mark
-                text = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
-            print self.name, ": load_hostinfo yaml format Exception", text
-        except js_e.ValidationError as e:
-            text = ""
-            if len(e.path)>0: text=" at '" + ":".join(map(str, e.path))+"'"
-            print self.name, ": load_hostinfo format Exception:", text, e.message 
-        except Exception as e:
-            text = str(e)
-            print self.name, ": load_hostinfo Exception:", text
-        
-        #not loaded, insert a default data 
-        self.hostinfo = None 
-        
-    def save_localinfo(self, tries=3):
-        if self.test:
-            self.localinfo_dirty = False
-            return
-        
-        while tries>=0:
-            tries-=1
-            
-            try:
-                command = 'cat > ' +  self.image_path + '/.openvim.yaml'
-                print self.name, ': command:', command
-                (stdin, _, _) = self.ssh_conn.exec_command(command)
-                yaml.safe_dump(self.localinfo, stdin, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
-                self.localinfo_dirty = False
-                break #while tries
-    
-            except paramiko.ssh_exception.SSHException as e:
-                text = e.args[0]
-                print self.name, ": save_localinfo ssh Exception:", text
-                if "SSH session not active" in text:
-                    self.ssh_connect()
-            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:
-                text = ""
-                if hasattr(exc, 'problem_mark'):
-                    mark = exc.problem_mark
-                    text = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
-                print self.name, ": save_localinfo yaml format Exception", text
-            except Exception as e:
-                text = str(e)
-                print self.name, ": save_localinfo Exception:", text
-
-    def load_servers_from_db(self):
-        self.db_lock.acquire()
-        r,c = self.db.get_table(SELECT=('uuid','status', 'image_id'), FROM='instances', WHERE={'host_id': self.host_id})
-        self.db_lock.release()
-
-        self.server_status = {}
-        if r<0:
-            print self.name, ": Error getting data from database:", c
-            return
-        for server in c:
-            self.server_status[ server['uuid'] ] = server['status']
-            
-            #convert from old version to new one
-            if 'inc_files' in self.localinfo and server['uuid'] in self.localinfo['inc_files']:
-                server_files_dict = {'source file': self.localinfo['inc_files'][ server['uuid'] ] [0],  'file format':'raw' }
-                if server_files_dict['source file'][-5:] == 'qcow2':
-                    server_files_dict['file format'] = 'qcow2'
-                    
-                self.localinfo['server_files'][ server['uuid'] ] = { server['image_id'] : server_files_dict }
-        if 'inc_files' in self.localinfo:
-            del self.localinfo['inc_files']
-            self.localinfo_dirty = True
-    
-    def delete_unused_files(self):
-        '''Compares self.localinfo['server_files'] content with real servers running self.server_status obtained from database
-        Deletes unused entries at self.loacalinfo and the corresponding local files.
-        The only reason for this mismatch is the manual deletion of instances (VM) at database
-        ''' 
-        if self.test:
-            return
-        for uuid,images in self.localinfo['server_files'].items():
-            if uuid not in self.server_status:
-                for localfile in images.values():
-                    try:
-                        print self.name, ": deleting file '%s' of unused server '%s'" %(localfile['source file'], uuid)
-                        self.delete_file(localfile['source file'])
-                    except paramiko.ssh_exception.SSHException as e:
-                        print self.name, ": Exception deleting file '%s': %s" %(localfile['source file'], str(e))
-                del self.localinfo['server_files'][uuid]
-                self.localinfo_dirty = True
-   
-    def insert_task(self, task, *aditional):
-        try:
-            self.queueLock.acquire()
-            task = self.taskQueue.put( (task,) + aditional, timeout=5) 
-            self.queueLock.release()
-            return 1, None
-        except Queue.Full:
-            return -1, "timeout inserting a task over host " + self.name
-
-    def run(self):
-        while True:
-            self.load_localinfo()
-            self.load_hostinfo()
-            self.load_servers_from_db()
-            self.delete_unused_files()
-            while True:
-                self.queueLock.acquire()
-                if not self.taskQueue.empty():
-                    task = self.taskQueue.get()
-                else:
-                    task = None
-                self.queueLock.release()
-    
-                if task is None:
-                    now=time.time()
-                    if self.localinfo_dirty:
-                        self.save_localinfo()
-                    elif self.next_update_server_status < now:
-                        self.update_servers_status()
-                        self.next_update_server_status = now + 5
-                    elif len(self.pending_terminate_server)>0 and self.pending_terminate_server[0][0]<now:
-                        self.server_forceoff()
-                    else:
-                        time.sleep(1)
-                    continue        
-    
-                if task[0] == 'instance':
-                    print self.name, ": processing task instance", task[1]['action']
-                    retry=0
-                    while retry <2:
-                        retry += 1
-                        r=self.action_on_server(task[1], retry==2)
-                        if r>=0: 
-                            break
-                elif task[0] == 'image':
-                    pass
-                elif task[0] == 'exit':
-                    print self.name, ": processing task exit"
-                    self.terminate()
-                    return 0
-                elif task[0] == 'reload':
-                    print self.name, ": processing task reload terminating and relaunching"
-                    self.terminate()
-                    break
-                elif task[0] == 'edit-iface':
-                    print self.name, ": processing task edit-iface port=%s, old_net=%s, new_net=%s" % (task[1], task[2], task[3])
-                    self.edit_iface(task[1], task[2], task[3])
-                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()
-                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])
-                elif task[0] == 'del-ovsbridge':
-                    print self.name, ": Deleting OVS bridge"
-                    self.delete_ovs_bridge()
-                elif task[0] == 'del-vxlan':
-                    print self.name, ": Deleting vxlan " + task[1] + " tunnel"
-                    self.delete_ovs_vxlan_tunnel(task[1])
-                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':
-                    print self.name, ": Delete bridge attached to ovs port vlan {} net {}".format(task[1], task[2])
-                    self.delete_bridge_port_attached_to_ovs(task[1], task[2])
-                else:
-                    print self.name, ": unknown task", task
-                
-    def server_forceoff(self, wait_until_finished=False):
-        while len(self.pending_terminate_server)>0:
-            now = time.time()
-            if self.pending_terminate_server[0][0]>now:
-                if wait_until_finished:
-                    time.sleep(1)
-                    continue
-                else:
-                    return
-            req={'uuid':self.pending_terminate_server[0][1],
-                'action':{'terminate':'force'},
-                'status': None
-            }
-            self.action_on_server(req)
-            self.pending_terminate_server.pop(0)
-    
-    def terminate(self):
-        try:
-            self.server_forceoff(True)
-            if self.localinfo_dirty:
-                self.save_localinfo()
-            if not self.test:
-                self.ssh_conn.close()
-        except Exception as e:
-            text = str(e)
-            print self.name, ": terminate Exception:", text
-        print self.name, ": exit from host_thread" 
-
-    def get_local_iface_name(self, generic_name):
-        if self.hostinfo != None and "iface_names" in self.hostinfo and generic_name in self.hostinfo["iface_names"]:
-            return self.hostinfo["iface_names"][generic_name]
-        return generic_name
-        
-    def create_xml_server(self, server, dev_list, server_metadata={}):
-        """Function that implements the generation of the VM XML definition.
-        Additional devices are in dev_list list
-        The main disk is upon dev_list[0]"""
-        
-    #get if operating system is Windows        
-        windows_os = False
-        os_type = server_metadata.get('os_type', None)
-        if os_type == None and 'metadata' in dev_list[0]:
-            os_type = dev_list[0]['metadata'].get('os_type', None)
-        if os_type != None and os_type.lower() == "windows":
-            windows_os = True
-    #get type of hard disk bus  
-        bus_ide = True if windows_os else False   
-        bus = server_metadata.get('bus', None)
-        if bus == None and 'metadata' in dev_list[0]:
-            bus = dev_list[0]['metadata'].get('bus', None)
-        if bus != None:
-            bus_ide = True if bus=='ide' else False
-            
-        self.xml_level = 0
-
-        text = "<domain type='kvm'>"
-    #get topology
-        topo = server_metadata.get('topology', None)
-        if topo == None and 'metadata' in dev_list[0]:
-            topo = dev_list[0]['metadata'].get('topology', None)
-    #name
-        name = server.get('name','') + "_" + server['uuid']
-        name = name[:58]  #qemu impose a length  limit of 59 chars or not start. Using 58
-        text += self.inc_tab() + "<name>" + name+ "</name>"
-    #uuid
-        text += self.tab() + "<uuid>" + server['uuid'] + "</uuid>" 
-        
-        numa={}
-        if 'extended' in server and server['extended']!=None and 'numas' in server['extended']:
-            numa = server['extended']['numas'][0]
-    #memory
-        use_huge = False
-        memory = int(numa.get('memory',0))*1024*1024 #in KiB
-        if memory==0:
-            memory = int(server['ram'])*1024;
-        else:
-            if not self.develop_mode:
-                use_huge = True
-        if memory==0:
-            return -1, 'No memory assigned to instance'
-        memory = str(memory)
-        text += self.tab() + "<memory unit='KiB'>" +memory+"</memory>" 
-        text += self.tab() + "<currentMemory unit='KiB'>" +memory+ "</currentMemory>"
-        if use_huge:
-            text += self.tab()+'<memoryBacking>'+ \
-                self.inc_tab() + '<hugepages/>'+ \
-                self.dec_tab()+ '</memoryBacking>'
-
-    #cpu
-        use_cpu_pinning=False
-        vcpus = int(server.get("vcpus",0))
-        cpu_pinning = []
-        if 'cores-source' in numa:
-            use_cpu_pinning=True
-            for index in range(0, len(numa['cores-source'])):
-                cpu_pinning.append( [ numa['cores-id'][index], numa['cores-source'][index] ] )
-                vcpus += 1
-        if 'threads-source' in numa:
-            use_cpu_pinning=True
-            for index in range(0, len(numa['threads-source'])):
-                cpu_pinning.append( [ numa['threads-id'][index], numa['threads-source'][index] ] )
-                vcpus += 1
-        if 'paired-threads-source' in numa:
-            use_cpu_pinning=True
-            for index in range(0, len(numa['paired-threads-source'])):
-                cpu_pinning.append( [numa['paired-threads-id'][index][0], numa['paired-threads-source'][index][0] ] )
-                cpu_pinning.append( [numa['paired-threads-id'][index][1], numa['paired-threads-source'][index][1] ] )
-                vcpus += 2
-        
-        if use_cpu_pinning and not self.develop_mode:
-            text += self.tab()+"<vcpu placement='static'>" +str(len(cpu_pinning)) +"</vcpu>" + \
-                self.tab()+'<cputune>'
-            self.xml_level += 1
-            for i in range(0, len(cpu_pinning)):
-                text += self.tab() + "<vcpupin vcpu='" +str(cpu_pinning[i][0])+ "' cpuset='" +str(cpu_pinning[i][1]) +"'/>"
-            text += self.dec_tab()+'</cputune>'+ \
-                self.tab() + '<numatune>' +\
-                self.inc_tab() + "<memory mode='strict' nodeset='" +str(numa['source'])+ "'/>" +\
-                self.dec_tab() + '</numatune>'
-        else:
-            if vcpus==0:
-                return -1, "Instance without number of cpus"
-            text += self.tab()+"<vcpu>" + str(vcpus)  + "</vcpu>"
-
-    #boot
-        boot_cdrom = False
-        for dev in dev_list:
-            if dev['type']=='cdrom' :
-                boot_cdrom = True
-                break
-        text += self.tab()+ '<os>' + \
-            self.inc_tab() + "<type arch='x86_64' machine='pc'>hvm</type>"
-        if boot_cdrom:
-            text +=  self.tab() + "<boot dev='cdrom'/>" 
-        text +=  self.tab() + "<boot dev='hd'/>" + \
-            self.dec_tab()+'</os>'
-    #features
-        text += self.tab()+'<features>'+\
-            self.inc_tab()+'<acpi/>' +\
-            self.tab()+'<apic/>' +\
-            self.tab()+'<pae/>'+ \
-            self.dec_tab() +'</features>'
-        if topo == "oneSocket:hyperthreading":
-            if vcpus % 2 != 0:
-                return -1, 'Cannot expose hyperthreading with an odd number of vcpus'
-            text += self.tab() + "<cpu mode='host-model'> <topology sockets='1' cores='%d' threads='2' /> </cpu>" % vcpus/2
-        elif windows_os or topo == "oneSocket":
-            text += self.tab() + "<cpu mode='host-model'> <topology sockets='1' cores='%d' threads='1' /> </cpu>" % vcpus
-        else:
-            text += self.tab() + "<cpu mode='host-model'></cpu>"
-        text += self.tab() + "<clock offset='utc'/>" +\
-            self.tab() + "<on_poweroff>preserve</on_poweroff>" + \
-            self.tab() + "<on_reboot>restart</on_reboot>" + \
-            self.tab() + "<on_crash>restart</on_crash>"
-        text += self.tab() + "<devices>" + \
-            self.inc_tab() + "<emulator>/usr/libexec/qemu-kvm</emulator>" + \
-            self.tab() + "<serial type='pty'>" +\
-            self.inc_tab() + "<target port='0'/>" + \
-            self.dec_tab() + "</serial>" +\
-            self.tab() + "<console type='pty'>" + \
-            self.inc_tab()+ "<target type='serial' port='0'/>" + \
-            self.dec_tab()+'</console>'
-        if windows_os:
-            text += self.tab() + "<controller type='usb' index='0'/>" + \
-                self.tab() + "<controller type='ide' index='0'/>" + \
-                self.tab() + "<input type='mouse' bus='ps2'/>" + \
-                self.tab() + "<sound model='ich6'/>" + \
-                self.tab() + "<video>" + \
-                self.inc_tab() + "<model type='cirrus' vram='9216' heads='1'/>" + \
-                self.dec_tab() + "</video>" + \
-                self.tab() + "<memballoon model='virtio'/>" + \
-                self.tab() + "<input type='tablet' bus='usb'/>" #TODO revisar
-
-#>             self.tab()+'<alias name=\'hostdev0\'/>\n' +\
-#>             self.dec_tab()+'</hostdev>\n' +\
-#>             self.tab()+'<input type=\'tablet\' bus=\'usb\'/>\n'
-        if windows_os:
-            text += self.tab() + "<graphics type='vnc' port='-1' autoport='yes'/>"
-        else:
-            #If image contains 'GRAPH' include graphics
-            #if 'GRAPH' in image:
-            text += self.tab() + "<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>" +\
-                self.inc_tab() + "<listen type='address' address='0.0.0.0'/>" +\
-                self.dec_tab() + "</graphics>"
-
-        vd_index = 'a'
-        for dev in dev_list:
-            bus_ide_dev = bus_ide
-            if dev['type']=='cdrom' or dev['type']=='disk':
-                if dev['type']=='cdrom':
-                    bus_ide_dev = True
-                text += self.tab() + "<disk type='file' device='"+dev['type']+"'>"
-                if 'file format' in dev:
-                    text += self.inc_tab() + "<driver name='qemu' type='"  +dev['file format']+ "' cache='writethrough'/>"
-                if 'source file' in dev:
-                    text += self.tab() + "<source file='" +dev['source file']+ "'/>"
-                #elif v['type'] == 'block':
-                #    text += self.tab() + "<source dev='" + v['source'] + "'/>"
-                #else:
-                #    return -1, 'Unknown disk type ' + v['type']
-                vpci = dev.get('vpci',None)
-                if vpci == None:
-                    vpci = dev['metadata'].get('vpci',None)
-                text += self.pci2xml(vpci)
-               
-                if bus_ide_dev:
-                    text += self.tab() + "<target dev='hd" +vd_index+ "' bus='ide'/>"   #TODO allows several type of disks
-                else:
-                    text += self.tab() + "<target dev='vd" +vd_index+ "' bus='virtio'/>" 
-                text += self.dec_tab() + '</disk>'
-                vd_index = chr(ord(vd_index)+1)
-            elif dev['type']=='xml':
-                dev_text = dev['xml']
-                if 'vpci' in dev:
-                    dev_text = dev_text.replace('__vpci__', dev['vpci'])
-                if 'source file' in dev:
-                    dev_text = dev_text.replace('__file__', dev['source file'])
-                if 'file format' in dev:
-                    dev_text = dev_text.replace('__format__', dev['source file'])
-                if '__dev__' in dev_text:
-                    dev_text = dev_text.replace('__dev__', vd_index)
-                    vd_index = chr(ord(vd_index)+1)
-                text += dev_text
-            else:
-                return -1, 'Unknown device type ' + dev['type']
-
-        net_nb=0
-        bridge_interfaces = server.get('networks', [])
-        for v in bridge_interfaces:
-            #Get the brifge name
-            self.db_lock.acquire()
-            result, content = self.db.get_table(FROM='nets', SELECT=('provider',),WHERE={'uuid':v['net_id']} )
-            self.db_lock.release()
-            if result <= 0:
-                print "create_xml_server ERROR getting nets",result, content
-                return -1, content
-            #ALF: Allow by the moment the 'default' bridge net because is confortable for provide internet to VM
-            #I know it is not secure    
-            #for v in sorted(desc['network interfaces'].itervalues()):
-            model = v.get("model", None)
-            if content[0]['provider']=='default':
-                text += self.tab() + "<interface type='network'>" + \
-                    self.inc_tab() + "<source network='" +content[0]['provider']+ "'/>"
-            elif content[0]['provider'][0:7]=='macvtap':
-                text += self.tab()+"<interface type='direct'>" + \
-                    self.inc_tab() + "<source dev='" + self.get_local_iface_name(content[0]['provider'][8:]) + "' mode='bridge'/>" + \
-                    self.tab() + "<target dev='macvtap0'/>"
-                if windows_os:
-                    text += self.tab() + "<alias name='net" + str(net_nb) + "'/>"
-                elif model==None:
-                    model = "virtio"
-            elif content[0]['provider'][0:6]=='bridge':
-                text += self.tab() + "<interface type='bridge'>" +  \
-                    self.inc_tab()+"<source bridge='" +self.get_local_iface_name(content[0]['provider'][7:])+ "'/>"
-                if windows_os:
-                    text += self.tab() + "<target dev='vnet" + str(net_nb)+ "'/>" +\
-                        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:
-                text += self.tab() + "<model type='" +model+ "'/>"
-            if v.get('mac_address', None) != None:
-                text+= self.tab() +"<mac address='" +v['mac_address']+ "'/>"
-            text += self.pci2xml(v.get('vpci',None))
-            text += self.dec_tab()+'</interface>'
-            
-            net_nb += 1
-
-        interfaces = numa.get('interfaces', [])
-
-        net_nb=0
-        for v in interfaces:
-            if self.develop_mode: #map these interfaces to bridges
-                text += self.tab() + "<interface type='bridge'>" +  \
-                    self.inc_tab()+"<source bridge='" +self.develop_bridge_iface+ "'/>"
-                if windows_os:
-                    text += self.tab() + "<target dev='vnet" + str(net_nb)+ "'/>" +\
-                        self.tab() + "<alias name='net" + str(net_nb)+ "'/>"
-                else:
-                    text += self.tab() + "<model type='e1000'/>" #e1000 is more probable to be supported than 'virtio'
-                if v.get('mac_address', None) != None:
-                    text+= self.tab() +"<mac address='" +v['mac_address']+ "'/>"
-                text += self.pci2xml(v.get('vpci',None))
-                text += self.dec_tab()+'</interface>'
-                continue
-                
-            if v['dedicated'] == 'yes':  #passthrought
-                text += self.tab() + "<hostdev mode='subsystem' type='pci' managed='yes'>" + \
-                    self.inc_tab() + "<source>"
-                self.inc_tab()
-                text += self.pci2xml(v['source'])
-                text += self.dec_tab()+'</source>'
-                text += self.pci2xml(v.get('vpci',None))
-                if windows_os:
-                    text += self.tab() + "<alias name='hostdev" + str(net_nb) + "'/>"
-                text += self.dec_tab()+'</hostdev>'
-                net_nb += 1
-            else:        #sriov_interfaces
-                #skip not connected interfaces
-                if v.get("net_id") == None:
-                    continue
-                text += self.tab() + "<interface type='hostdev' managed='yes'>"
-                self.inc_tab()
-                if v.get('mac_address', None) != None:
-                    text+= self.tab() + "<mac address='" +v['mac_address']+ "'/>"
-                text+= self.tab()+'<source>'
-                self.inc_tab()
-                text += self.pci2xml(v['source'])
-                text += self.dec_tab()+'</source>'
-                if v.get('vlan',None) != None:
-                    text += self.tab() + "<vlan>   <tag id='" + str(v['vlan']) + "'/>   </vlan>"
-                text += self.pci2xml(v.get('vpci',None))
-                if windows_os:
-                    text += self.tab() + "<alias name='hostdev" + str(net_nb) + "'/>"
-                text += self.dec_tab()+'</interface>'
-
-            
-        text += self.dec_tab()+'</devices>'+\
-        self.dec_tab()+'</domain>'
-        return 0, text
-    
-    def pci2xml(self, pci):
-        '''from a pci format text XXXX:XX:XX.X generates the xml content of <address>
-        alows an empty pci text'''
-        if pci is None:
-            return ""
-        first_part = pci.split(':')
-        second_part = first_part[2].split('.')
-        return self.tab() + "<address type='pci' domain='0x" + first_part[0] + \
-                    "' bus='0x" + first_part[1] + "' slot='0x" + second_part[0] + \
-                    "' function='0x" + second_part[1] + "'/>" 
-    
-    def tab(self):
-        """Return indentation according to xml_level"""
-        return "\n" + ('  '*self.xml_level)
-    
-    def inc_tab(self):
-        """Increment and return indentation according to xml_level"""
-        self.xml_level += 1
-        return self.tab()
-    
-    def dec_tab(self):
-        """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
-        """
-        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)
-        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:
-        """
-
-        if self.test:
-            return
-
-        port_name = 'ovim-' + vlan
-        command = 'sudo ovs-vsctl del-port br-int ' + port_name
-        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_dhcp_server(self, vlan, net_uuid, dhcp_path):
-        """
-        Delete dhcp server process lining in namespace
-        :param vlan: segmentation id
-        :param net_uuid: network uuid
-        :param dhcp_path: conf fiel path that live in namespace side
-        :return:
-        """
-        if self.test:
-            return
-        if not self.is_dhcp_port_free(vlan, net_uuid):
-            return True
-
-        net_namespace = 'ovim-' + vlan
-        dhcp_path = os.path.join(dhcp_path, net_namespace)
-        pid_file = os.path.join(dhcp_path, 'dnsmasq.pid')
-
-        command = 'sudo ip netns exec ' + net_namespace + ' cat ' + pid_file
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip netns exec ' + net_namespace + ' kill -9 ' + content
-        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_dhcp_port_free(self, host_id, net_uuid):
-        """
-        Check if any port attached to the a net in a vxlan mesh across computes nodes
-        :param host_id: host id
-        :param net_uuid: network id
-        :return: True if is not free
-        """
-        self.db_lock.acquire()
-        result, content = self.db.get_table(
-            FROM='ports',
-            WHERE={'p.type': 'instance:ovs', 'p.net_id': net_uuid}
-        )
-        self.db_lock.release()
-
-        if len(content) > 0:
-            return False
-        else:
-            return True
-
-    def is_port_free(self, host_id, net_uuid):
-        """
-        Check if there not ovs ports of a network in a compute host.
-        :param host_id:  host 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:ovs', 'p.net_id': net_uuid}
-        )
-        self.db_lock.release()
-
-        if len(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: True if success
-        """
-
-        if self.test:
-            return
-
-        port_name = 'ovim-' + vlan
-        command = 'sudo ovs-vsctl add-port br-int ' + port_name + ' 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_dhcp_port(self, vlan, net_uuid):
-        """
-        Delete from an existing OVS bridge a linux bridge port attached and the linux bridge itself.
-        :param vlan: segmentation id
-        :param net_uuid: network id
-        :return: True if success
-        """
-
-        if self.test:
-            return
-
-        if not self.is_dhcp_port_free(vlan, net_uuid):
-            return True
-        self.delete_dhcp_interfaces(vlan)
-        return True
-
-    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 self.test:
-            return
-
-        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
-        """
-
-        if self.test:
-            return
-
-        port_name = 'ovim-' + vlan
-        command = 'sudo ip link set dev veth0-' + vlan + ' down'
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-        #
-        # if len(content) != 0:
-        #     return False
-
-        command = 'sudo ifconfig ' + port_name + ' down &&  sudo brctl delbr ' + port_name
-        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:
-        """
-        if self.test:
-            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:
-        """
-
-        if self.test:
-            return
-
-        port_name = 'ovim-' + vlan
-        command = 'sudo brctl show | grep ' + port_name
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        # if exist nothing to create
-        # if len(content) == 0:
-        #     return False
-
-        command = 'sudo brctl addbr ' + port_name
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        # if len(content) == 0:
-        #     return True
-        # else:
-        #     return False
-
-        command = 'sudo brctl stp ' + port_name + ' 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
-        command = 'sudo ip link set dev ' + port_name + ' up'
-        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 set_mac_dhcp_server(self, ip, mac, vlan, netmask, dhcp_path):
-        """
-        Write into dhcp conf file a rule to assigned a fixed ip given to an specific MAC address
-        :param ip: IP address asigned to a VM
-        :param mac: VM vnic mac to be macthed with the IP received
-        :param vlan: Segmentation id
-        :param netmask: netmask value
-        :param path: dhcp conf file path that live in namespace side
-        :return: True if success
-        """
-
-        if self.test:
-            return
-
-        net_namespace = 'ovim-' + vlan
-        dhcp_path = os.path.join(dhcp_path, net_namespace)
-        dhcp_hostsdir = os.path.join(dhcp_path, net_namespace)
-
-        if not ip:
-            return False
-
-        ip_data = mac.upper() + ',' + ip
-
-        command = 'sudo  ip netns exec ' + net_namespace + ' touch ' + dhcp_hostsdir
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo  ip netns exec ' + net_namespace + ' sudo bash -ec "echo ' + ip_data + ' >> ' + dhcp_hostsdir + '"'
-
-        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_mac_dhcp_server(self, ip, mac, vlan, dhcp_path):
-        """
-        Delete into dhcp conf file the ip  assigned to a specific MAC address
-
-        :param ip: IP address asigned to a VM
-        :param mac:  VM vnic mac to be macthed with the IP received
-        :param vlan:  Segmentation id
-        :param dhcp_path: dhcp conf file path that live in namespace side
-        :return:
-        """
-
-        if self.test:
-            return
-
-        net_namespace = 'ovim-' + vlan
-        dhcp_path = os.path.join(dhcp_path, net_namespace)
-        dhcp_hostsdir = os.path.join(dhcp_path, net_namespace)
-
-        if not ip:
-            return False
-
-        ip_data = mac.upper() + ',' + ip
-
-        command = 'sudo  ip netns exec ' + net_namespace + ' sudo sed -i \'/' + ip_data + '/d\' ' + dhcp_hostsdir
-        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 launch_dhcp_server(self, vlan, ip_range, netmask, dhcp_path, gateway):
-        """
-        Generate a linux bridge and attache the port to a OVS bridge
-        :param self:
-        :param vlan: Segmentation id
-        :param ip_range: IP dhcp range
-        :param netmask: network netmask
-        :param dhcp_path: dhcp conf file path that live in namespace side
-        :param gateway: Gateway address for dhcp net
-        :return: True if success
-        """
-
-        if self.test:
-            return
-
-        interface = 'tap-' + vlan
-        net_namespace = 'ovim-' + vlan
-        dhcp_path = os.path.join(dhcp_path, net_namespace)
-        leases_path = os.path.join(dhcp_path, "dnsmasq.leases")
-        pid_file = os.path.join(dhcp_path, 'dnsmasq.pid')
-
-        dhcp_range = ip_range[0] + ',' + ip_range[1] + ',' + netmask
-
-        command = 'sudo ip netns exec ' + net_namespace + ' mkdir -p ' + dhcp_path
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        pid_path = os.path.join(dhcp_path, 'dnsmasq.pid')
-        command = 'sudo  ip netns exec ' + net_namespace + ' cat ' + pid_path
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-        # check if pid is runing
-        pid_status_path = content
-        if content:
-            command = "ps aux | awk '{print $2 }' | grep " + pid_status_path
-            print self.name, ': command:', command
-            (_, stdout, _) = self.ssh_conn.exec_command(command)
-            content = stdout.read()
-        if not content:
-            command = 'sudo  ip netns exec ' + net_namespace + ' /usr/sbin/dnsmasq --strict-order --except-interface=lo ' \
-              '--interface=' + interface + ' --bind-interfaces --dhcp-hostsdir=' + dhcp_path + \
-              ' --dhcp-range ' + dhcp_range + ' --pid-file=' + pid_file + ' --dhcp-leasefile=' + leases_path + \
-              '  --listen-address ' + gateway
-
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.readline()
-
-        if len(content) == 0:
-            return True
-        else:
-            return False
-
-    def delete_dhcp_interfaces(self, vlan):
-        """
-        Create a linux bridge with STP active
-        :param vlan: netowrk vlan id
-        :return:
-        """
-
-        if self.test:
-            return
-
-        net_namespace = 'ovim-' + vlan
-        command = 'sudo ovs-vsctl del-port br-int ovs-tap-' + vlan
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip netns exec ' + net_namespace + ' ip link set dev tap-' + vlan + ' down'
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip link set dev ovs-tap-' + vlan + ' down'
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-    def create_dhcp_interfaces(self, vlan, ip, netmask):
-        """
-        Create a linux bridge with STP active
-        :param vlan: segmentation id
-        :param ip: Ip included in the dhcp range for the tap interface living in namesapce side
-        :param netmask: dhcp net CIDR
-        :return: True if success
-        """
-
-        if self.test:
-            return
-
-        net_namespace = 'ovim-' + vlan
-        namespace_interface = 'tap-' + vlan
-
-        command = 'sudo ip netns add ' + net_namespace
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip link add tap-' + vlan + ' type veth peer name ovs-tap-' + vlan
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ovs-vsctl add-port br-int ovs-tap-' + vlan + ' tag=' + vlan
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip link set tap-' + vlan + ' netns ' + net_namespace
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip netns exec ' + net_namespace + ' ip link set dev tap-' + vlan + ' up'
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo ip link set dev ovs-tap-' + vlan + ' up'
-        print self.name, ': command:', command
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-
-        command = 'sudo  ip netns exec ' + net_namespace + ' ' + ' ifconfig  ' + namespace_interface \
-                  + ' ' + ip + ' netmask ' + netmask
-        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:
-        """
-        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'
-        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.
-        """
-        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)
-        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
-        """
-        if self.test:
-            return
-        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
-        (_, stdout, _) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-        if len(content) == 0:
-            return None # file does not exist
-        else:
-            return content.split(" ") #(permission, 1, owner, group, size, date, file)
-
-    def qemu_get_info(self, path):
-        command = 'qemu-img info ' + path
-        print self.name, ': command:', command
-        (_, stdout, stderr) = self.ssh_conn.exec_command(command)
-        content = stdout.read()
-        if len(content) == 0:
-            error = stderr.read()
-            print self.name, ": get_qemu_info error ", error
-            raise paramiko.ssh_exception.SSHException("Error getting qemu_info: " + error)
-        else:
-            try: 
-                return yaml.load(content)
-            except yaml.YAMLError as exc:
-                text = ""
-                if hasattr(exc, 'problem_mark'):
-                    mark = exc.problem_mark
-                    text = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
-                print self.name, ": get_qemu_info yaml format Exception", text
-                raise paramiko.ssh_exception.SSHException("Error getting qemu_info yaml format" + text)
-
-    def qemu_change_backing(self, inc_file, new_backing_file):
-        command = 'qemu-img rebase -u -b ' + new_backing_file + ' ' + inc_file 
-        print self.name, ': command:', command
-        (_, _, stderr) = self.ssh_conn.exec_command(command)
-        content = stderr.read()
-        if len(content) == 0:
-            return 0
-        else:
-            print self.name, ": qemu_change_backing error: ", content
-            return -1
-    
-    def get_notused_filename(self, proposed_name, suffix=''):
-        '''Look for a non existing file_name in the host
-            proposed_name: proposed file name, includes path
-            suffix: suffix to be added to the name, before the extention
-        '''
-        extension = proposed_name.rfind(".")
-        slash = proposed_name.rfind("/")
-        if extension < 0 or extension < slash: # no extension
-            extension = len(proposed_name)
-        target_name = proposed_name[:extension] + suffix + proposed_name[extension:]
-        info = self.get_file_info(target_name)
-        if info is None:
-            return target_name
-        
-        index=0
-        while info is not None:
-            target_name = proposed_name[:extension] + suffix +  "-" + str(index) + proposed_name[extension:]
-            index+=1
-            info = self.get_file_info(target_name) 
-        return target_name
-    
-    def get_notused_path(self, proposed_path, suffix=''):
-        '''Look for a non existing path at database for images
-            proposed_path: proposed file name, includes path
-            suffix: suffix to be added to the name, before the extention
-        '''
-        extension = proposed_path.rfind(".")
-        if extension < 0:
-            extension = len(proposed_path)
-        if suffix != None:
-            target_path = proposed_path[:extension] + suffix + proposed_path[extension:]
-        index=0
-        while True:
-            r,_=self.db.get_table(FROM="images",WHERE={"path":target_path})
-            if r<=0:
-                return target_path
-            target_path = proposed_path[:extension] + suffix +  "-" + str(index) + proposed_path[extension:]
-            index+=1
-
-    
-    def delete_file(self, file_name):
-        command = 'rm -f '+file_name
-        print self.name, ': command:', command
-        (_, _, stderr) = self.ssh_conn.exec_command(command)
-        error_msg = stderr.read()
-        if len(error_msg) > 0:
-            raise paramiko.ssh_exception.SSHException("Error deleting file: " + error_msg)
-
-    def copy_file(self, source, destination, perserve_time=True):
-        if source[0:4]=="http":
-            command = "wget --no-verbose -O '{dst}' '{src}' 2>'{dst_result}' || cat '{dst_result}' >&2 && rm '{dst_result}'".format(
-                dst=destination, src=source, dst_result=destination + ".result" )
-        else:
-            command = 'cp --no-preserve=mode'
-            if perserve_time:
-                command += ' --preserve=timestamps'
-            command +=  " '{}' '{}'".format(source, destination)
-        print self.name, ': command:', command
-        (_, _, stderr) = self.ssh_conn.exec_command(command)
-        error_msg = stderr.read()
-        if len(error_msg) > 0:
-            raise paramiko.ssh_exception.SSHException("Error copying image to local host: " + error_msg)
-
-    def copy_remote_file(self, remote_file, use_incremental):
-        ''' Copy a file from the repository to local folder and recursively 
-            copy the backing files in case the remote file is incremental
-            Read and/or modified self.localinfo['files'] that contain the
-            unmodified copies of images in the local path
-            params:
-                remote_file: path of remote file
-                use_incremental: None (leave the decision to this function), True, False
-            return:
-                local_file: name of local file
-                qemu_info: dict with quemu information of local file
-                use_incremental_out: True, False; same as use_incremental, but if None a decision is taken
-        '''
-        
-        use_incremental_out = use_incremental
-        new_backing_file = None
-        local_file = None
-        file_from_local = True
-
-        #in case incremental use is not decided, take the decision depending on the image
-        #avoid the use of incremental if this image is already incremental
-        if remote_file[0:4] == "http":
-            file_from_local = False
-        if file_from_local:
-            qemu_remote_info = self.qemu_get_info(remote_file)
-        if use_incremental_out==None:
-            use_incremental_out = not ( file_from_local and 'backing file' in qemu_remote_info)
-        #copy recursivelly the backing files
-        if  file_from_local and 'backing file' in qemu_remote_info:
-            new_backing_file, _, _ = self.copy_remote_file(qemu_remote_info['backing file'], True)
-        
-        #check if remote file is present locally
-        if use_incremental_out and remote_file in self.localinfo['files']:
-            local_file = self.localinfo['files'][remote_file]
-            local_file_info =  self.get_file_info(local_file)
-            if file_from_local:
-                remote_file_info = self.get_file_info(remote_file)
-            if local_file_info == None:
-                local_file = None
-            elif file_from_local and (local_file_info[4]!=remote_file_info[4] or local_file_info[5]!=remote_file_info[5]):
-                #local copy of file not valid because date or size are different. 
-                #TODO DELETE local file if this file is not used by any active virtual machine
-                try:
-                    self.delete_file(local_file)
-                    del self.localinfo['files'][remote_file]
-                except Exception:
-                    pass
-                local_file = None
-            else: #check that the local file has the same backing file, or there are not backing at all
-                qemu_info = self.qemu_get_info(local_file)
-                if new_backing_file != qemu_info.get('backing file'):
-                    local_file = None
-                
-
-        if local_file == None: #copy the file 
-            img_name= remote_file.split('/') [-1]
-            img_local = self.image_path + '/' + img_name
-            local_file = self.get_notused_filename(img_local)
-            self.copy_file(remote_file, local_file, use_incremental_out)
-
-            if use_incremental_out:
-                self.localinfo['files'][remote_file] = local_file
-            if new_backing_file:
-                self.qemu_change_backing(local_file, new_backing_file)
-            qemu_info = self.qemu_get_info(local_file)
-            
-        return local_file, qemu_info, use_incremental_out
-            
-    def launch_server(self, conn, server, rebuild=False, domain=None):
-        if self.test:
-            time.sleep(random.randint(20,150)) #sleep random timeto be make it a bit more real
-            return 0, 'Success'
-
-        server_id = server['uuid']
-        paused = server.get('paused','no')
-        try:
-            if domain!=None and rebuild==False:
-                domain.resume()
-                #self.server_status[server_id] = 'ACTIVE'
-                return 0, 'Success'
-
-            self.db_lock.acquire()
-            result, server_data = self.db.get_instance(server_id)
-            self.db_lock.release()
-            if result <= 0:
-                print self.name, ": launch_server ERROR getting server from DB",result, server_data
-                return result, server_data
-    
-        #0: get image metadata
-            server_metadata = server.get('metadata', {})
-            use_incremental = None
-             
-            if "use_incremental" in server_metadata:
-                use_incremental = False if server_metadata["use_incremental"]=="no" else True
-
-            server_host_files = self.localinfo['server_files'].get( server['uuid'], {})
-            if rebuild:
-                #delete previous incremental files
-                for file_ in server_host_files.values():
-                    self.delete_file(file_['source file'] )
-                server_host_files={}
-    
-        #1: obtain aditional devices (disks)
-            #Put as first device the main disk
-            devices = [  {"type":"disk", "image_id":server['image_id'], "vpci":server_metadata.get('vpci', None) } ] 
-            if 'extended' in server_data and server_data['extended']!=None and "devices" in server_data['extended']:
-                devices += server_data['extended']['devices']
-
-            for dev in devices:
-                if dev['image_id'] == None:
-                    continue
-                
-                self.db_lock.acquire()
-                result, content = self.db.get_table(FROM='images', SELECT=('path', 'metadata'),
-                                                    WHERE={'uuid': dev['image_id']})
-                self.db_lock.release()
-                if result <= 0:
-                    error_text = "ERROR", result, content, "when getting image", dev['image_id']
-                    print self.name, ": launch_server", error_text 
-                    return -1, error_text
-                if content[0]['metadata'] is not None:
-                    dev['metadata'] = json.loads(content[0]['metadata'])
-                else:
-                    dev['metadata'] = {}
-                
-                if dev['image_id'] in server_host_files:
-                    dev['source file'] = server_host_files[ dev['image_id'] ] ['source file'] #local path
-                    dev['file format'] = server_host_files[ dev['image_id'] ] ['file format'] # raw or qcow2
-                    continue
-                
-            #2: copy image to host
-                remote_file = content[0]['path']
-                use_incremental_image = use_incremental
-                if dev['metadata'].get("use_incremental") == "no":
-                    use_incremental_image = False
-                local_file, qemu_info, use_incremental_image = self.copy_remote_file(remote_file, use_incremental_image)
-                
-                #create incremental image
-                if use_incremental_image:
-                    local_file_inc = self.get_notused_filename(local_file, '.inc')
-                    command = 'qemu-img create -f qcow2 '+local_file_inc+ ' -o backing_file='+ local_file
-                    print 'command:', command
-                    (_, _, stderr) = self.ssh_conn.exec_command(command)
-                    error_msg = stderr.read()
-                    if len(error_msg) > 0:
-                        raise paramiko.ssh_exception.SSHException("Error creating incremental file: " + error_msg)
-                    local_file = local_file_inc
-                    qemu_info = {'file format':'qcow2'}
-                
-                server_host_files[ dev['image_id'] ] = {'source file': local_file, 'file format': qemu_info['file format']}
-
-                dev['source file'] = local_file 
-                dev['file format'] = qemu_info['file format']
-
-            self.localinfo['server_files'][ server['uuid'] ] = server_host_files
-            self.localinfo_dirty = True
-
-        #3 Create XML
-            result, xml = self.create_xml_server(server_data, devices, server_metadata)  #local_file
-            if result <0:
-                print self.name, ": create xml server error:", xml
-                return -2, xml
-            print self.name, ": create xml:", xml
-            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, ": launching instance" #, xml
-            conn.createXML(xml, atribute)
-            #self.server_status[server_id] = 'PAUSED' if paused == "yes" else 'ACTIVE'
-
-            return 0, 'Success'
-
-        except paramiko.ssh_exception.SSHException as e:
-            text = e.args[0]
-            print self.name, ": launch_server(%s) ssh Exception: %s" %(server_id, text)
-            if "SSH session not active" in text:
-                self.ssh_connect()
-        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:
-            text = str(e)
-            print self.name, ": launch_server(%s) Exception: %s"  %(server_id, text)
-        return -1, text
-    
-    def update_servers_status(self):
-                            # # virDomainState
-                            # VIR_DOMAIN_NOSTATE = 0
-                            # VIR_DOMAIN_RUNNING = 1
-                            # VIR_DOMAIN_BLOCKED = 2
-                            # VIR_DOMAIN_PAUSED = 3
-                            # VIR_DOMAIN_SHUTDOWN = 4
-                            # VIR_DOMAIN_SHUTOFF = 5
-                            # VIR_DOMAIN_CRASHED = 6
-                            # VIR_DOMAIN_PMSUSPENDED = 7   #TODO suspended
-    
-        if self.test or len(self.server_status)==0:
-            return            
-        
-        try:
-            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] == 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] == host_thread.lvirt_module.VIR_DOMAIN_PAUSED:
-                    new_status = "PAUSED"
-                elif libvirt_status[0] == host_thread.lvirt_module.VIR_DOMAIN_SHUTOFF:
-                    new_status = "INACTIVE"
-                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 host_thread.lvirt_module.libvirtError as e:
-            print self.name, ": get_state() Exception '", e.get_error_message()
-            return
-
-        for server_id, current_status in self.server_status.iteritems():
-            new_status = None
-            if server_id in domain_dict:
-                new_status = domain_dict[server_id]
-            else:
-                new_status = "INACTIVE"
-                            
-            if new_status == None or new_status == current_status:
-                continue
-            if new_status == 'INACTIVE' and current_status == 'ERROR':
-                continue #keep ERROR status, because obviously this machine is not running
-            #change status
-            print self.name, ": server ", server_id, "status change from ", current_status, "to", new_status
-            STATUS={'progress':100, 'status':new_status}
-            if new_status == 'ERROR':
-                STATUS['last_error'] = 'machine has crashed'
-            self.db_lock.acquire()
-            r,_ = self.db.update_rows('instances', STATUS, {'uuid':server_id}, log=False)
-            self.db_lock.release()
-            if r>=0:
-                self.server_status[server_id] = new_status
-                        
-    def action_on_server(self, req, last_retry=True):
-        '''Perform an action on a req
-        Attributes:
-            req: dictionary that contain:
-                server properties: 'uuid','name','tenant_id','status'
-                action: 'action'
-                host properties: 'user', 'ip_name'
-        return (error, text)  
-             0: No error. VM is updated to new state,  
-            -1: Invalid action, as trying to pause a PAUSED VM
-            -2: Error accessing host
-            -3: VM nor present
-            -4: Error at DB access
-            -5: Error while trying to perform action. VM is updated to ERROR
-        '''
-        server_id = req['uuid']
-        conn = None
-        new_status = None
-        old_status = req['status']
-        last_error = None
-        
-        if self.test:
-            if 'terminate' in req['action']:
-                new_status = 'deleted'
-            elif 'shutoff' in req['action'] or 'shutdown' in req['action'] or 'forceOff' in req['action']:
-                if req['status']!='ERROR':
-                    time.sleep(5)
-                    new_status = 'INACTIVE'
-            elif 'start' in req['action']  and req['status']!='ERROR':      new_status = 'ACTIVE'
-            elif 'resume' in req['action'] and req['status']!='ERROR' and req['status']!='INACTIVE' :     new_status = 'ACTIVE'
-            elif 'pause' in req['action']  and req['status']!='ERROR':      new_status = 'PAUSED'
-            elif 'reboot' in req['action'] and req['status']!='ERROR':     new_status = 'ACTIVE'
-            elif 'rebuild' in req['action']:
-                time.sleep(random.randint(20,150))
-                new_status = 'ACTIVE'
-            elif 'createImage' in req['action']:
-                time.sleep(5)
-                self.create_image(None, req)
-        else:
-            try:
-                conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
-                try:
-                    dom = conn.lookupByUUIDString(server_id)
-                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:
-                        print self.name, ": action_on_server(",server_id,") libvirt exception:", text
-                        raise e
-                
-                if 'forceOff' in req['action']:
-                    if dom == None:
-                        print self.name, ": action_on_server(",server_id,") domain not running" 
-                    else:
-                        try:
-                            print self.name, ": sending DESTROY to server", server_id 
-                            dom.destroy()
-                        except Exception as e:
-                            if "domain is not running" not in e.get_error_message():
-                                print self.name, ": action_on_server(",server_id,") Exception while sending force off:", e.get_error_message()
-                                last_error =  'action_on_server Exception while destroy: ' + e.get_error_message()
-                                new_status = 'ERROR'
-                
-                elif 'terminate' in req['action']:
-                    if dom == None:
-                        print self.name, ": action_on_server(",server_id,") domain not running" 
-                        new_status = 'deleted'
-                    else:
-                        try:
-                            if req['action']['terminate'] == 'force':
-                                print self.name, ": sending DESTROY to server", server_id 
-                                dom.destroy()
-                                new_status = 'deleted'
-                            else:
-                                print self.name, ": sending SHUTDOWN to server", server_id 
-                                dom.shutdown()
-                                self.pending_terminate_server.append( (time.time()+10,server_id) )
-                        except Exception as e:
-                            print self.name, ": action_on_server(",server_id,") Exception while destroy:", e.get_error_message() 
-                            last_error =  'action_on_server Exception while destroy: ' + e.get_error_message()
-                            new_status = 'ERROR'
-                            if "domain is not running" in e.get_error_message():
-                                try:
-                                    dom.undefine()
-                                    new_status = 'deleted'
-                                except Exception:
-                                    print self.name, ": action_on_server(",server_id,") Exception while undefine:", e.get_error_message() 
-                                    last_error =  'action_on_server Exception2 while undefine:', e.get_error_message()
-                            #Exception: 'virDomainDetachDevice() failed'
-                    if new_status=='deleted':
-                        if server_id in self.server_status:
-                            del self.server_status[server_id]
-                        if req['uuid'] in self.localinfo['server_files']:
-                            for file_ in self.localinfo['server_files'][ req['uuid'] ].values():
-                                try:
-                                    self.delete_file(file_['source file'])
-                                except Exception:
-                                    pass
-                            del self.localinfo['server_files'][ req['uuid'] ]
-                            self.localinfo_dirty = True
-
-                elif 'shutoff' in req['action'] or 'shutdown' in req['action']:
-                    try:
-                        if dom == None:
-                            print self.name, ": action_on_server(",server_id,") domain not running"
-                        else: 
-                            dom.shutdown()
-#                        new_status = 'INACTIVE'
-                        #TODO: check status for changing at database
-                    except Exception as e:
-                        new_status = 'ERROR'
-                        print self.name, ": action_on_server(",server_id,") Exception while shutdown:", e.get_error_message() 
-                        last_error =  'action_on_server Exception while shutdown: ' + e.get_error_message()
-    
-                elif 'rebuild' in req['action']:
-                    if dom != None:
-                        dom.destroy()
-                    r = self.launch_server(conn, req, True, None)
-                    if r[0] <0:
-                        new_status = 'ERROR'
-                        last_error = r[1]
-                    else:
-                        new_status = 'ACTIVE'
-                elif 'start' in req['action']:
-                    # 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'
-                        last_error = r[1]
-                    else:
-                        new_status = 'ACTIVE'
-                
-                elif 'resume' in req['action']:
-                    try:
-                        if dom == None:
-                            pass
-                        else:
-                            dom.resume()
-#                            new_status = 'ACTIVE'
-                    except Exception as e:
-                        print self.name, ": action_on_server(",server_id,") Exception while resume:", e.get_error_message() 
-                    
-                elif 'pause' in req['action']:
-                    try: 
-                        if dom == None:
-                            pass
-                        else:
-                            dom.suspend()
-#                            new_status = 'PAUSED'
-                    except Exception as e:
-                        print self.name, ": action_on_server(",server_id,") Exception while pause:", e.get_error_message() 
-    
-                elif 'reboot' in req['action']:
-                    try: 
-                        if dom == None:
-                            pass
-                        else:
-                            dom.reboot()
-                        print self.name, ": action_on_server(",server_id,") reboot:" 
-                        #new_status = 'ACTIVE'
-                    except Exception as e:
-                        print self.name, ": action_on_server(",server_id,") Exception while reboot:", e.get_error_message() 
-                elif 'createImage' in req['action']:
-                    self.create_image(dom, req)
-                        
-        
-                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
-                print self.name, ": action_on_server(",server_id,") Exception '", text
-                if 'LookupByUUIDString' in text or 'Domain not found' in text or 'No existe un dominio coincidente' in text:
-                    print self.name, ": action_on_server(",server_id,") Exception removed from host"
-        #end of if self.test
-        if new_status ==  None:
-            return 1
-
-        print self.name, ": action_on_server(",server_id,") new status", new_status, last_error
-        UPDATE = {'progress':100, 'status':new_status}
-        
-        if new_status=='ERROR':
-            if not last_retry:  #if there will be another retry do not update database 
-                return -1 
-            elif 'terminate' in req['action']:
-                #PUT a log in the database
-                print self.name, ": PANIC deleting server", server_id, last_error
-                self.db_lock.acquire()
-                self.db.new_row('logs', 
-                            {'uuid':server_id, 'tenant_id':req['tenant_id'], 'related':'instances','level':'panic',
-                             'description':'PANIC deleting server from host '+self.name+': '+last_error}
-                        )
-                self.db_lock.release()
-                if server_id in self.server_status:
-                    del self.server_status[server_id]
-                return -1
-            else:
-                UPDATE['last_error'] = last_error
-        if new_status != 'deleted' and (new_status != old_status or new_status == 'ERROR') :
-            self.db_lock.acquire()
-            self.db.update_rows('instances', UPDATE, {'uuid':server_id}, log=True)
-            self.server_status[server_id] = new_status
-            self.db_lock.release()
-        if new_status == 'ERROR':
-            return -1
-        return 1
-     
-    
-    def restore_iface(self, name, mac, lib_conn=None):
-        ''' make an ifdown, ifup to restore default parameter of na interface
-            Params:
-                mac: mac address of the interface
-                lib_conn: connection to the libvirt, if None a new connection is created
-            Return 0,None if ok, -1,text if fails
-        ''' 
-        conn=None
-        ret = 0
-        error_text=None
-        if self.test:
-            print self.name, ": restore_iface '%s' %s" % (name, mac)
-            return 0, None
-        try:
-            if not lib_conn:
-                conn = host_thread.lvirt_module.open("qemu+ssh://"+self.user+"@"+self.host+"/system")
-            else:
-                conn = lib_conn
-                
-            #wait to the pending VM deletion
-            #TODO.Revise  self.server_forceoff(True)
-
-            iface = conn.interfaceLookupByMACString(mac)
-            iface.destroy()
-            iface.create()
-            print self.name, ": restore_iface '%s' %s" % (name, mac)
-        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()
-        return ret, error_text
-
-        
-    def create_image(self,dom, req):
-        if self.test:
-            if 'path' in req['action']['createImage']:
-                file_dst = req['action']['createImage']['path']
-            else:
-                createImage=req['action']['createImage']
-                img_name= createImage['source']['path']
-                index=img_name.rfind('/')
-                file_dst = self.get_notused_path(img_name[:index+1] + createImage['name'] + '.qcow2')
-            image_status='ACTIVE'
-        else:
-            for retry in (0,1):
-                try:
-                    server_id = req['uuid']
-                    createImage=req['action']['createImage']
-                    file_orig = self.localinfo['server_files'][server_id] [ createImage['source']['image_id'] ] ['source file']
-                    if 'path' in req['action']['createImage']:
-                        file_dst = req['action']['createImage']['path']
-                    else:
-                        img_name= createImage['source']['path']
-                        index=img_name.rfind('/')
-                        file_dst = self.get_notused_filename(img_name[:index+1] + createImage['name'] + '.qcow2')
-                          
-                    self.copy_file(file_orig, file_dst)
-                    qemu_info = self.qemu_get_info(file_orig)
-                    if 'backing file' in qemu_info:
-                        for k,v in self.localinfo['files'].items():
-                            if v==qemu_info['backing file']:
-                                self.qemu_change_backing(file_dst, k)
-                                break
-                    image_status='ACTIVE'
-                    break
-                except paramiko.ssh_exception.SSHException as e:
-                    image_status='ERROR'
-                    error_text = e.args[0]
-                    print self.name, "': create_image(",server_id,") ssh Exception:", error_text
-                    if "SSH session not active" in error_text and retry==0:
-                        self.ssh_connect()
-                except Exception as e:
-                    image_status='ERROR'
-                    error_text = str(e)
-                    print self.name, "': create_image(",server_id,") Exception:", error_text
-        
-                #TODO insert a last_error at database
-        self.db_lock.acquire()
-        self.db.update_rows('images', {'status':image_status, 'progress': 100, 'path':file_dst}, 
-                {'uuid':req['new_image']['uuid']}, log=True)
-        self.db_lock.release()
-  
-    def edit_iface(self, port_id, old_net, new_net):
-        #This action imply remove and insert interface to put proper parameters
-        if self.test:
-            time.sleep(1)
-        else:
-        #get iface details
-            self.db_lock.acquire()
-            r,c = self.db.get_table(FROM='ports as p join resources_port as rp on p.uuid=rp.port_id',
-                                    WHERE={'port_id': port_id})
-            self.db_lock.release()
-            if r<0:
-                print self.name, ": edit_iface(",port_id,") DDBB error:", c
-                return
-            elif r==0:
-                print self.name, ": edit_iface(",port_id,") por not found"
-                return
-            port=c[0]
-            if port["model"]!="VF":
-                print self.name, ": edit_iface(",port_id,") ERROR model must be VF"
-                return
-            #create xml detach file
-            xml=[]
-            self.xml_level = 2
-            xml.append("<interface type='hostdev' managed='yes'>")
-            xml.append("  <mac address='" +port['mac']+ "'/>")
-            xml.append("  <source>"+ self.pci2xml(port['pci'])+"\n  </source>")
-            xml.append('</interface>')                
-
-            
-            try:
-                conn=None
-                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=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(self.pci2xml(port.get('vpci',None)) )
-                    xml.append('</interface>')                
-                    text="\n".join(xml)
-                    print self.name, ": edit_iface attaching SRIOV interface", text
-                    dom.attachDeviceFlags(text, flags=host_thread.lvirt_module.VIR_DOMAIN_AFFECT_LIVE)
-                    
-            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()
-
-
-def create_server(server, db, db_lock, only_of_ports):
-    #print "server"
-    #print "server"
-    #print server
-    #print "server"
-    #print "server"
-    #try:
-#            host_id = server.get('host_id', None)
-    extended = server.get('extended', None)
-    
-#             print '----------------------'
-#             print json.dumps(extended, indent=4)
-    
-    requirements={}
-    requirements['numa']={'memory':0, 'proc_req_type': 'threads', 'proc_req_nb':0, 'port_list':[], 'sriov_list':[]}
-    requirements['ram'] = server['flavor'].get('ram', 0)
-    if requirements['ram']== None:
-        requirements['ram'] = 0
-    requirements['vcpus'] = server['flavor'].get('vcpus', 0)
-    if requirements['vcpus']== None:
-        requirements['vcpus'] = 0
-    #If extended is not defined get requirements from flavor
-    if extended is None:
-        #If extended is defined in flavor convert to dictionary and use it
-        if 'extended' in server['flavor'] and  server['flavor']['extended'] != None:
-            json_acceptable_string = server['flavor']['extended'].replace("'", "\"")
-            extended = json.loads(json_acceptable_string)
-        else:
-            extended = None
-    #print json.dumps(extended, indent=4)
-    
-    #For simplicity only one numa VM are supported in the initial implementation
-    if extended != None:
-        numas = extended.get('numas', [])
-        if len(numas)>1:
-            return (-2, "Multi-NUMA VMs are not supported yet")
-        #elif len(numas)<1:
-        #    return (-1, "At least one numa must be specified")
-    
-        #a for loop is used in order to be ready to multi-NUMA VMs
-        request = []
-        for numa in numas:
-            numa_req = {}
-            numa_req['memory'] = numa.get('memory', 0)
-            if 'cores' in numa: 
-                numa_req['proc_req_nb'] = numa['cores']                     #number of cores or threads to be reserved
-                numa_req['proc_req_type'] = 'cores'                         #indicates whether cores or threads must be reserved
-                numa_req['proc_req_list'] = numa.get('cores-id', None)      #list of ids to be assigned to the cores or threads
-            elif 'paired-threads' in numa:
-                numa_req['proc_req_nb'] = numa['paired-threads']
-                numa_req['proc_req_type'] = 'paired-threads'
-                numa_req['proc_req_list'] = numa.get('paired-threads-id', None)
-            elif 'threads' in numa:
-                numa_req['proc_req_nb'] = numa['threads']
-                numa_req['proc_req_type'] = 'threads'
-                numa_req['proc_req_list'] = numa.get('threads-id', None)
-            else:
-                numa_req['proc_req_nb'] = 0 # by default
-                numa_req['proc_req_type'] = 'threads'
-
-            
-            
-            #Generate a list of sriov and another for physical interfaces 
-            interfaces = numa.get('interfaces', [])
-            sriov_list = []
-            port_list = []
-            for iface in interfaces:
-                iface['bandwidth'] = int(iface['bandwidth'])
-                if iface['dedicated'][:3]=='yes':
-                    port_list.append(iface)
-                else:
-                    sriov_list.append(iface)
-                    
-            #Save lists ordered from more restrictive to less bw requirements
-            numa_req['sriov_list'] = sorted(sriov_list, key=lambda k: k['bandwidth'], reverse=True)
-            numa_req['port_list'] = sorted(port_list, key=lambda k: k['bandwidth'], reverse=True)
-            
-            
-            request.append(numa_req)
-                
-    #                 print "----------\n"+json.dumps(request[0], indent=4)
-    #                 print '----------\n\n'
-            
-        #Search in db for an appropriate numa for each requested numa
-        #at the moment multi-NUMA VMs are not supported
-        if len(request)>0:
-            requirements['numa'].update(request[0])
-    if requirements['numa']['memory']>0:
-        requirements['ram']=0  #By the moment I make incompatible ask for both Huge and non huge pages memory
-    elif requirements['ram']==0:
-        return (-1, "Memory information not set neither at extended field not at ram")
-    if requirements['numa']['proc_req_nb']>0:
-        requirements['vcpus']=0 #By the moment I make incompatible ask for both Isolated and non isolated cpus
-    elif requirements['vcpus']==0:
-        return (-1, "Processor information not set neither at extended field not at vcpus")    
-
-
-    db_lock.acquire()
-    result, content = db.get_numas(requirements, server.get('host_id', None), only_of_ports)
-    db_lock.release()
-    
-    if result == -1:
-        return (-1, content)
-    
-    numa_id = content['numa_id']
-    host_id = content['host_id']
-
-    #obtain threads_id and calculate pinning
-    cpu_pinning = []
-    reserved_threads=[]
-    if requirements['numa']['proc_req_nb']>0:
-        db_lock.acquire()
-        result, content = db.get_table(FROM='resources_core', 
-                                       SELECT=('id','core_id','thread_id'),
-                                       WHERE={'numa_id':numa_id,'instance_id': None, 'status':'ok'} )
-        db_lock.release()
-        if result <= 0:
-            print content
-            return -1, content
-    
-        #convert rows to a dictionary indexed by core_id
-        cores_dict = {}
-        for row in content:
-            if not row['core_id'] in cores_dict:
-                cores_dict[row['core_id']] = []
-            cores_dict[row['core_id']].append([row['thread_id'],row['id']]) 
-           
-        #In case full cores are requested 
-        paired = 'N'
-        if requirements['numa']['proc_req_type'] == 'cores':
-            #Get/create the list of the vcpu_ids
-            vcpu_id_list = requirements['numa']['proc_req_list']
-            if vcpu_id_list == None:
-                vcpu_id_list = range(0,int(requirements['numa']['proc_req_nb']))
-            
-            for threads in cores_dict.itervalues():
-                #we need full cores
-                if len(threads) != 2:
-                    continue
-                
-                #set pinning for the first thread
-                cpu_pinning.append( [ vcpu_id_list.pop(0), threads[0][0], threads[0][1] ] )
-                
-                #reserve so it is not used the second thread
-                reserved_threads.append(threads[1][1])
-                
-                if len(vcpu_id_list) == 0:
-                    break
-                
-        #In case paired threads are requested
-        elif requirements['numa']['proc_req_type'] == 'paired-threads':
-            paired = 'Y'
-            #Get/create the list of the vcpu_ids
-            if requirements['numa']['proc_req_list'] != None:
-                vcpu_id_list = []
-                for pair in requirements['numa']['proc_req_list']:
-                    if len(pair)!=2:
-                        return -1, "Field paired-threads-id not properly specified"
-                        return
-                    vcpu_id_list.append(pair[0])
-                    vcpu_id_list.append(pair[1])
-            else:
-                vcpu_id_list = range(0,2*int(requirements['numa']['proc_req_nb']))
-                
-            for threads in cores_dict.itervalues():
-                #we need full cores
-                if len(threads) != 2:
-                    continue
-                #set pinning for the first thread
-                cpu_pinning.append([vcpu_id_list.pop(0), threads[0][0], threads[0][1]])
-                
-                #set pinning for the second thread
-                cpu_pinning.append([vcpu_id_list.pop(0), threads[1][0], threads[1][1]])
-                
-                if len(vcpu_id_list) == 0:
-                    break    
-        
-        #In case normal threads are requested
-        elif requirements['numa']['proc_req_type'] == 'threads':
-            #Get/create the list of the vcpu_ids
-            vcpu_id_list = requirements['numa']['proc_req_list']
-            if vcpu_id_list == None:
-                vcpu_id_list = range(0,int(requirements['numa']['proc_req_nb']))
-                                
-            for threads_index in sorted(cores_dict, key=lambda k: len(cores_dict[k])):
-                threads = cores_dict[threads_index]
-                #set pinning for the first thread
-                cpu_pinning.append([vcpu_id_list.pop(0), threads[0][0], threads[0][1]])
-                
-                #if exists, set pinning for the second thread
-                if len(threads) == 2 and len(vcpu_id_list) != 0:
-                    cpu_pinning.append([vcpu_id_list.pop(0), threads[1][0], threads[1][1]])
-                
-                if len(vcpu_id_list) == 0:
-                    break    
-    
-        #Get the source pci addresses for the selected numa
-        used_sriov_ports = []
-        for port in requirements['numa']['sriov_list']:
-            db_lock.acquire()
-            result, content = db.get_table(FROM='resources_port', SELECT=('id', 'pci', 'mac'),WHERE={'numa_id':numa_id,'root_id': port['port_id'], 'port_id': None, 'Mbps_used': 0} )
-            db_lock.release()
-            if result <= 0:
-                print content
-                return -1, content
-            for row in content:
-                if row['id'] in used_sriov_ports or row['id']==port['port_id']:
-                    continue
-                port['pci'] = row['pci']
-                if 'mac_address' not in port: 
-                    port['mac_address'] = row['mac']
-                del port['mac']
-                port['port_id']=row['id']
-                port['Mbps_used'] = port['bandwidth']
-                used_sriov_ports.append(row['id'])
-                break
-        
-        for port in requirements['numa']['port_list']:
-            port['Mbps_used'] = None
-            if port['dedicated'] != "yes:sriov":
-                port['mac_address'] = port['mac']
-                del port['mac']
-                continue
-            db_lock.acquire()
-            result, content = db.get_table(FROM='resources_port', SELECT=('id', 'pci', 'mac', 'Mbps'),WHERE={'numa_id':numa_id,'root_id': port['port_id'], 'port_id': None, 'Mbps_used': 0} )
-            db_lock.release()
-            if result <= 0:
-                print content
-                return -1, content
-            port['Mbps_used'] = content[0]['Mbps']
-            for row in content:
-                if row['id'] in used_sriov_ports or row['id']==port['port_id']:
-                    continue
-                port['pci'] = row['pci']
-                if 'mac_address' not in port: 
-                    port['mac_address'] = row['mac']  # mac cannot be set to passthrough ports 
-                del port['mac']
-                port['port_id']=row['id']
-                used_sriov_ports.append(row['id'])
-                break
-    
-    #             print '2. Physical ports assignation:'+json.dumps(requirements['port_list'], indent=4)
-    #             print '2. SR-IOV assignation:'+json.dumps(requirements['sriov_list'], indent=4)
-        
-    server['host_id'] = host_id
-        
-
-    #Generate dictionary for saving in db the instance resources
-    resources = {}
-    resources['bridged-ifaces'] = []
-    
-    numa_dict = {}
-    numa_dict['interfaces'] = []
-    
-    numa_dict['interfaces'] += requirements['numa']['port_list']
-    numa_dict['interfaces'] += requirements['numa']['sriov_list']
-  
-    #Check bridge information
-    unified_dataplane_iface=[]
-    unified_dataplane_iface += requirements['numa']['port_list']
-    unified_dataplane_iface += requirements['numa']['sriov_list']
-    
-    for control_iface in server.get('networks', []):
-        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', 'provider', 'enable_dhcp',
-                                                 'dhcp_first_ip', 'dhcp_last_ip', 'cidr'),
-                                       WHERE={'uuid': control_iface['net_id']})
-        db_lock.release()
-        if result < 0: 
-            pass
-        elif result==0:
-            return -1, "Error at field netwoks: Not found any network wit uuid %s" % control_iface['net_id']
-        else:
-            network=content[0]
-            if control_iface.get("type", 'virtual') == 'virtual':
-                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"]
-
-                if network.get("enable_dhcp") == 'true':
-                    control_iface["enable_dhcp"] = network.get("enable_dhcp")
-                    control_iface["dhcp_first_ip"] = network["dhcp_first_ip"]
-                    control_iface["dhcp_last_ip"] = network["dhcp_last_ip"]
-                    control_iface["cidr"] = network["cidr"]
-            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']
-                #dataplane interface, look for it in the numa tree and asign this network
-                iface_found=False
-                for dataplane_iface in numa_dict['interfaces']:
-                    if dataplane_iface['name'] == control_iface.get("name"):
-                        if (dataplane_iface['dedicated'] == "yes" and control_iface["type"] != "PF") or \
-                            (dataplane_iface['dedicated'] == "no" and control_iface["type"] != "VF") or \
-                            (dataplane_iface['dedicated'] == "yes:sriov" and control_iface["type"] != "VFnotShared") :
-                                return -1, "Error at field netwoks: mismatch at interface '%s' from flavor 'dedicated=%s' and networks 'type=%s'" % \
-                                    (control_iface.get("name"), dataplane_iface['dedicated'], control_iface["type"])
-                        dataplane_iface['uuid'] = control_iface['net_id']
-                        if dataplane_iface['dedicated'] == "no":
-                            dataplane_iface['vlan'] = network['vlan']
-                        if dataplane_iface['dedicated'] != "yes" and control_iface.get("mac_address"):
-                            dataplane_iface['mac_address'] = control_iface.get("mac_address")
-                        if control_iface.get("vpci"):
-                            dataplane_iface['vpci'] = control_iface.get("vpci")
-                        iface_found=True
-                        break
-                if not iface_found:
-                    return -1, "Error at field netwoks: interface name %s from network not found at flavor" % control_iface.get("name")
-        
-    resources['host_id'] = host_id
-    resources['image_id'] = server['image_id']
-    resources['flavor_id'] = server['flavor_id']
-    resources['tenant_id'] = server['tenant_id']
-    resources['ram'] = requirements['ram']
-    resources['vcpus'] = requirements['vcpus']
-    resources['status'] = 'CREATING'
-    
-    if 'description' in server: resources['description'] = server['description']
-    if 'name' in server: resources['name'] = server['name']
-    
-    resources['extended'] = {}                          #optional
-    resources['extended']['numas'] = []
-    numa_dict['numa_id'] = numa_id
-    numa_dict['memory'] = requirements['numa']['memory']
-    numa_dict['cores'] = []
-
-    for core in cpu_pinning:
-        numa_dict['cores'].append({'id': core[2], 'vthread': core[0], 'paired': paired})
-    for core in reserved_threads:
-        numa_dict['cores'].append({'id': core})
-    resources['extended']['numas'].append(numa_dict)
-    if extended!=None and 'devices' in extended:   #TODO allow extra devices without numa
-        resources['extended']['devices'] = extended['devices']
-    
-
-    print '===================================={'
-    print json.dumps(resources, indent=4)
-    print '====================================}'
-    
-    return 0, resources
-