Add iperf VM/vhost creation 38/10438/2
authorJohn DeNisco <jdenisco@cisco.com>
Tue, 6 Feb 2018 20:23:05 +0000 (15:23 -0500)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 16 Feb 2018 08:09:27 +0000 (08:09 +0000)
Change-Id: I27a59203f406120558f73bfcc12dca8835ae6361
Signed-off-by: John DeNisco <jdenisco@cisco.com>
12 files changed:
extras/vpp_config/data/cloud-config.iso [new file with mode: 0644]
extras/vpp_config/data/iperf-centos.xml.template [new file with mode: 0644]
extras/vpp_config/data/iperf-ubuntu.xml.template [new file with mode: 0644]
extras/vpp_config/data/startup.conf.template
extras/vpp_config/scripts/clean.sh [changed mode: 0755->0644]
extras/vpp_config/scripts/cp-data.sh [changed mode: 0755->0644]
extras/vpp_config/scripts/dpdk-devbind.py [changed mode: 0755->0644]
extras/vpp_config/scripts/vpp-config [changed mode: 0755->0644]
extras/vpp_config/setup.py
extras/vpp_config/vpp_config.py [changed mode: 0755->0644]
extras/vpp_config/vpplib/AutoConfig.py
extras/vpp_config/vpplib/VPPUtil.py

diff --git a/extras/vpp_config/data/cloud-config.iso b/extras/vpp_config/data/cloud-config.iso
new file mode 100644 (file)
index 0000000..0c299fc
Binary files /dev/null and b/extras/vpp_config/data/cloud-config.iso differ
diff --git a/extras/vpp_config/data/iperf-centos.xml.template b/extras/vpp_config/data/iperf-centos.xml.template
new file mode 100644 (file)
index 0000000..9f585ec
--- /dev/null
@@ -0,0 +1,108 @@
+<domain type='kvm' id='54'>
+  <name>{vmname}</name>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <hugepages>
+      <page size='2048' unit='KiB'/>
+    </hugepages>
+  </memoryBacking>
+  <vcpu placement='static'>1</vcpu>
+  <resource>
+    <partition>/machine</partition>
+  </resource>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+  </features>
+  <cpu mode='host-model'>
+    <model fallback='allow'></model>
+  </cpu>
+  <clock offset='utc'>
+    <timer name='rtc' tickpolicy='catchup'/>
+    <timer name='pit' tickpolicy='delay'/>
+    <timer name='hpet' present='no'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <pm>
+    <suspend-to-mem enabled='no'/>
+    <suspend-to-disk enabled='no'/>
+  </pm>
+  <devices>
+    <emulator>/usr/libexec/qemu-kvm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='qcow2'/>
+      <source file='{imagename}'/>
+      <backingStore/>
+      <target dev='vda' bus='virtio'/>
+      <alias name='virtio-disk0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+    </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source file='{isoname}'/>
+      <backingStore/>
+      <target dev='hda' bus='ide'/>
+      <readonly/>
+      <alias name='ide0-0-0'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0' model='ich9-ehci1'>
+      <alias name='usb'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'>
+      <alias name='pci.0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <alias name='ide'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <alias name='virtio-serial0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </controller>
+    <interface type='network'>
+      <mac address='52:54:00:4c:47:f3'/>
+      <source network='default' bridge='virbr0'/>
+      <target dev='vnet0'/>
+      <model type='virtio'/>
+      <alias name='net0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <serial type='pty'>
+      <source path='/dev/pts/2'/>
+      <target port='0'/>
+      <alias name='serial0'/>
+    </serial>
+    <console type='pty' tty='/dev/pts/2'>
+      <source path='/dev/pts/2'/>
+      <target type='serial' port='0'/>
+      <alias name='serial0'/>
+    </console>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+    <memballoon model='virtio'>
+      <alias name='balloon0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
+    </memballoon>
+  </devices>
+  <seclabel type='dynamic' model='selinux' relabel='yes'>
+    <label>system_u:system_r:svirt_t:s0:c532,c551</label>
+    <imagelabel>system_u:object_r:svirt_image_t:s0:c532,c551</imagelabel>
+  </seclabel>
+  <seclabel type='dynamic' model='dac' relabel='yes'>
+    <label>+107:+107</label>
+    <imagelabel>+107:+107</imagelabel>
+  </seclabel>
+</domain>
+
diff --git a/extras/vpp_config/data/iperf-ubuntu.xml.template b/extras/vpp_config/data/iperf-ubuntu.xml.template
new file mode 100644 (file)
index 0000000..a48a134
--- /dev/null
@@ -0,0 +1,114 @@
+<domain type='kvm' id='54'>
+  <name>{vmname}</name>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <hugepages>
+      <page size='2048' unit='KiB'/>
+    </hugepages>
+  </memoryBacking>
+  <vcpu placement='static'>1</vcpu>
+  <resource>
+    <partition>/machine</partition>
+  </resource>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+  </features>
+  <cpu mode='host-model'>
+    <model fallback='allow'></model>
+    <numa>
+      <cell id='0' cpus='0' memory='262144' unit='KiB' memAccess='shared'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'>
+    <timer name='rtc' tickpolicy='catchup'/>
+    <timer name='pit' tickpolicy='delay'/>
+    <timer name='hpet' present='no'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <pm>
+    <suspend-to-mem enabled='no'/>
+    <suspend-to-disk enabled='no'/>
+  </pm>
+  <devices>
+    <emulator>/usr/bin/kvm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='qcow2'/>
+      <source file='{imagename}'/>
+      <backingStore/>
+      <target dev='vda' bus='virtio'/>
+      <alias name='virtio-disk0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+    </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source file='{isoname}'/>
+      <backingStore/>
+      <target dev='hda' bus='ide'/>
+      <readonly/>
+      <alias name='ide0-0-0'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0' model='ich9-ehci1'>
+      <alias name='usb'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'>
+      <alias name='pci.0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <alias name='ide'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <alias name='virtio-serial0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </controller>
+    <interface type='network'>
+      <mac address='52:54:00:4c:47:f3'/>
+      <source network='default' bridge='virbr0'/>
+      <target dev='vnet0'/>
+      <model type='virtio'/>
+      <alias name='net0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <interface type='vhostuser'>
+      <mac address='52:54:00:4c:47:f4'/>
+      <source type='unix' path='{vhostsocketname}' mode='client'/>
+      <model type='virtio'/>
+      <alias name='net1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+    </interface>
+    <serial type='pty'>
+      <source path='/dev/pts/2'/>
+      <target port='0'/>
+      <alias name='serial0'/>
+    </serial>
+    <console type='pty' tty='/dev/pts/2'>
+      <source path='/dev/pts/2'/>
+      <target type='serial' port='0'/>
+      <alias name='serial0'/>
+    </console>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+    <memballoon model='virtio'>
+      <alias name='balloon0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
+    </memballoon>
+  </devices>
+  <seclabel type='dynamic' model='apparmor' relabel='yes'>
+    <label>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</label>
+    <imagelabel>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</imagelabel>
+  </seclabel>
+</domain>
+
index 912bbc4..19a8454 100644 (file)
@@ -12,8 +12,8 @@ api-trace {{
 
 cpu {{
 {cpu}
-  scheduler-policy fifo
-  scheduler-priority 50
+  scheduler-policy fifo
+  scheduler-priority 50
 
         ## In the VPP there is one main thread and optionally the user can create worker(s)
        ## The main thread and worker thread(s) can be pinned to CPU core(s) manually or automatically
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index a0053dc..fa71661
@@ -64,11 +64,16 @@ sudo mkdir $ROOTDIR/vpp/vpp-config
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun
 sudo mkdir $ROOTDIR/vpp/vpp-config/scripts
 sudo mkdir $ROOTDIR/vpp/vpp-config/configs
+sudo mkdir $ROOTDIR/vpp/vpp-config/images
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/default
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/vpp
+sudo cp scripts/dpdk-devbind.py $ROOTDIR/vpp/vpp-config/scripts/.
 sudo cp data/auto-config.yaml $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/cloud-config.iso $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/iperf-centos.xml.template $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/iperf-ubuntu.xml.template $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/xenial-mod.img $ROOTDIR/vpp/vpp-config/images/.
+sudo cp data/80-vpp.conf.template $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d/.
 sudo cp data/grub.template $ROOTDIR/vpp/vpp-config/dryrun/default/.
 sudo cp data/startup.conf.template $ROOTDIR/vpp/vpp-config/dryrun/vpp/.
-sudo cp data/80-vpp.conf.template $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d/.
-sudo cp scripts/dpdk-devbind.py $ROOTDIR/vpp/vpp-config/scripts/.
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 6442f7c..c60162f 100644 (file)
@@ -1,7 +1,7 @@
 from setuptools import setup
 
 setup(name="vpp_config",
-      version="18.01.1",
+      version="18.01.4",
       author="John DeNisco",
       author_email="jdenisco@cisco.com",
       description="VPP Configuration Utility",
@@ -14,6 +14,9 @@ setup(name="vpp_config",
       scripts=['scripts/vpp-config'],
       data_files=[('vpp/vpp-config/scripts', ['scripts/dpdk-devbind.py']),
                   ('vpp/vpp-config/configs', ['data/auto-config.yaml']),
+                  ('vpp/vpp-config/configs', ['data/cloud-config.iso']),
+                  ('vpp/vpp-config/configs', ['data/iperf-centos.xml.template']),
+                  ('vpp/vpp-config/configs', ['data/iperf-ubuntu.xml.template']),
                   ('vpp/vpp-config/dryrun/sysctl.d', ['data/80-vpp.conf.template']),
                   ('vpp/vpp-config/dryrun/default', ['data/grub.template']),
                   ('vpp/vpp-config/dryrun/vpp', ['data/startup.conf.template']),
old mode 100755 (executable)
new mode 100644 (file)
index dc1bc51..d9d6584
@@ -464,14 +464,16 @@ def autoconfig_ipv4_setup():
     acfg.ipv4_interface_setup()
 
 
-def autoconfig_create_vm():
+def autoconfig_create_iperf_vm():
     """
     Setup IPv4 interfaces
 
     """
 
     acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
-    acfg.create_and_bridge_virtual_interfaces()
+    acfg.destroy_iperf_vm('iperf-server')
+    acfg.create_and_bridge_iperf_virtual_interface()
+    acfg.create_iperf_vm('iperf-server')
 
 
 def autoconfig_not_implemented():
@@ -491,12 +493,9 @@ def autoconfig_basic_test_menu():
 
     basic_menu_text = '\nWhat would you like to do?\n\n\
 1) List/Create Simple IPv4 Setup\n\
+2) Create an iperf VM and Connect to VPP an interface\n\
 9 or q) Back to main menu.'
 
-    # 1) List/Create Simple IPv4 Setup\n\
-    # 2) List/Create Create VM and Connect to VPP interfaces\n\
-    # 9 or q) Back to main menu.'
-
     print "{}".format(basic_menu_text)
 
     input_valid = False
@@ -534,8 +533,8 @@ def autoconfig_basic_test():
         answer = autoconfig_basic_test_menu()
         if answer == '1':
             autoconfig_ipv4_setup()
-        elif answer == '2':
-        #    autoconfig_create_vm()
+        elif answer == '2':
+            autoconfig_create_iperf_vm()
         elif answer == '9' or answer == 'q':
             return
         else:
@@ -664,6 +663,7 @@ def autoconfig_setup(ask_questions=True):
             raise RuntimeError('{} failed on node {} {}'. format(cmd, node['host'], stderr))
 
 
+# noinspection PyUnresolvedReferences
 def execute_with_args(args):
     """
     Execute the configuration utility with agruments.
index 26603e8..f435d18 100644 (file)
@@ -33,6 +33,10 @@ MIN_SYSTEM_CPUS = 2
 MIN_TOTAL_HUGE_PAGES = 1024
 MAX_PERCENT_FOR_HUGE_PAGES = 70
 
+IPERFVM_XML = 'configs/iperf-vm.xml'
+IPERFVM_IMAGE = 'images/xenial-mod.img'
+IPERFVM_ISO = 'configs/cloud-config.iso'
+
 
 class AutoConfig(object):
     """Auto Configuration Tools"""
@@ -56,6 +60,7 @@ class AutoConfig(object):
         self._hugepage_config = ""
         self._clean = clean
         self._loadconfig()
+        self._sockfilename = ""
 
     def get_nodes(self):
         """
@@ -551,7 +556,9 @@ class AutoConfig(object):
 
             # If total_vpp_cpus is 0 or is less than the numa nodes with ports
             #  then we shouldn't get workers
-            total_workers_node = total_vpp_cpus / len(ports_per_numa)
+            total_workers_node = 0
+            if len(ports_per_numa):
+                total_workers_node = total_vpp_cpus / len(ports_per_numa)
             total_main = 0
             if reserve_vpp_main_core:
                 total_main = 1
@@ -1637,16 +1644,20 @@ class AutoConfig(object):
             question = "Would you like connect this interface {} to the VM [Y/n]? ".format(name)
             answer = self._ask_user_yn(question, 'y')
             if answer == 'y':
-                sockfilename = '/var/run/vpp/sock{}.sock'.format(inum)
+                sockfilename = '/var/run/vpp/{}.sock'.format(name.replace('/', '_'))
                 if os.path.exists(sockfilename):
                     os.remove(sockfilename)
                 cmd = 'vppctl create vhost-user socket {} server'.format(sockfilename)
                 (ret, stdout, stderr) = vpputl.exec_command(cmd)
                 if ret != 0:
-                    raise RuntimeError("Create vhost failed on node {} {}."
-                                       .format(node['host'], stderr))
+                    raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
                 vintname = stdout.rstrip('\r\n')
 
+                cmd = 'chmod 777 {}'.format(sockfilename)
+                (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                if ret != 0:
+                    raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+
                 interface = {'name': name, 'virtualinterface': '{}'.format(vintname),
                              'bridge': '{}'.format(inum)}
                 inum += 1
@@ -1710,3 +1721,184 @@ class AutoConfig(object):
             print("\nA script as been created at {}".format(filename))
             print("This script can be run using the following:")
             print("vppctl exec {}\n".format(filename))
+
+    def _iperf_vm_questions(self, node):
+        """
+        Ask the user some questions and get a list of interfaces
+        and IPv4 addresses associated with those interfaces
+
+        :param node: Node dictionary.
+        :type node: dict
+        :returns: A list or interfaces with ip addresses
+        :rtype: list
+        """
+
+        vpputl = VPPUtil()
+        interfaces = vpputl.get_hardware(node)
+        if interfaces == {}:
+            return []
+
+        # First delete all the Virtual interfaces
+        for intf in sorted(interfaces.items()):
+            name = intf[0]
+            if name[:7] == 'Virtual':
+                cmd = 'vppctl delete vhost-user {}'.format(name)
+                (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                if ret != 0:
+                    logging.debug('{} failed on node {} {}'.format(
+                        cmd, node['host'], stderr))
+
+        # Create a virtual interface, for each interface the user wants to use
+        interfaces = vpputl.get_hardware(node)
+        if interfaces == {}:
+            return []
+        interfaces_with_virtual_interfaces = []
+        inum = 1
+
+        while True:
+            print '\nPlease pick one interface to connect to the iperf VM.'
+            for intf in sorted(interfaces.items()):
+                name = intf[0]
+                if name == 'local0':
+                    continue
+
+                question = "Would you like connect this interface {} to the VM [y/N]? ".format(name)
+                answer = self._ask_user_yn(question, 'n')
+                if answer == 'y':
+                    self._sockfilename = '/var/run/vpp/{}.sock'.format(name.replace('/', '_'))
+                    if os.path.exists(self._sockfilename):
+                        os.remove(self._sockfilename)
+                    cmd = 'vppctl create vhost-user socket {} server'.format(self._sockfilename)
+                    (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                    if ret != 0:
+                        raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+                    vintname = stdout.rstrip('\r\n')
+
+                    cmd = 'chmod 777 {}'.format(self._sockfilename)
+                    (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                    if ret != 0:
+                        raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+
+                    interface = {'name': name, 'virtualinterface': '{}'.format(vintname),
+                                 'bridge': '{}'.format(inum)}
+                    inum += 1
+                    interfaces_with_virtual_interfaces.append(interface)
+                    return interfaces_with_virtual_interfaces
+
+    def create_and_bridge_iperf_virtual_interface(self):
+        """
+        After asking the user some questions, and create and bridge a virtual interface
+        to be used with iperf VM
+
+        """
+
+        for i in self._nodes.items():
+            node = i[1]
+
+            # Show the current bridge and interface configuration
+            print "\nThis the current bridge configuration:"
+            ifaces = VPPUtil.show_bridge(node)
+            question = "\nWould you like to keep this configuration [Y/n]? "
+            answer = self._ask_user_yn(question, 'y')
+            if answer == 'y':
+                self._sockfilename = '/var/run/vpp/{}.sock'.format(ifaces[0]['name'].replace('/', '_'))
+                if os.path.exists(self._sockfilename):
+                    continue
+
+            # Create a script that builds a bridge configuration with physical interfaces
+            # and virtual interfaces
+            ints_with_vints = self._iperf_vm_questions(node)
+            content = ''
+            for intf in ints_with_vints:
+                vhoststr = 'comment { The following command creates the socket }\n'
+                vhoststr += 'comment { and returns a virtual interface }\n'
+                vhoststr += 'comment {{ create vhost-user socket /var/run/vpp/sock{}.sock server }}\n'. \
+                    format(intf['bridge'])
+
+                setintdnstr = 'set interface state {} down\n'.format(intf['name'])
+
+                setintbrstr = 'set interface l2 bridge {} {}\n'.format(intf['name'], intf['bridge'])
+                setvintbrstr = 'set interface l2 bridge {} {}\n'.format(intf['virtualinterface'], intf['bridge'])
+
+                # set interface state VirtualEthernet/0/0/0 up
+                setintvststr = 'set interface state {} up\n'.format(intf['virtualinterface'])
+
+                # set interface state VirtualEthernet/0/0/0 down
+                setintupstr = 'set interface state {} up\n'.format(intf['name'])
+
+                content += vhoststr + setintdnstr + setintbrstr + setvintbrstr + setintvststr + setintupstr
+
+            # Write the content to the script
+            rootdir = node['rootdir']
+            filename = rootdir + '/vpp/vpp-config/scripts/create_iperf_vm'
+            with open(filename, 'w+') as sfile:
+                sfile.write(content)
+
+            # Execute the script
+            cmd = 'vppctl exec {}'.format(filename)
+            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+            if ret != 0:
+                logging.debug(stderr)
+
+            print("\nA script as been created at {}".format(filename))
+            print("This script can be run using the following:")
+            print("vppctl exec {}\n".format(filename))
+
+    @staticmethod
+    def destroy_iperf_vm(name):
+        """
+        After asking the user some questions, create a VM and connect the interfaces
+        to VPP interfaces
+
+        :param name: The name of the VM to be be destroyed
+        :type name: str
+        """
+
+        cmd = 'virsh list'
+        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+        if ret != 0:
+            logging.debug(stderr)
+            raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
+
+        if re.findall(name, stdout):
+            cmd = 'virsh destroy {}'.format(name)
+            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+            if ret != 0:
+                logging.debug(stderr)
+                raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
+
+    def create_iperf_vm(self, vmname):
+        """
+        After asking the user some questions, create a VM and connect the interfaces
+        to VPP interfaces
+
+        """
+
+        # Read the iperf VM template file
+        distro = VPPUtil.get_linux_distro()
+        if distro[0] == 'Ubuntu':
+            tfilename = '{}/vpp/vpp-config/configs/iperf-ubuntu.xml.template'.format(self._rootdir)
+        else:
+            tfilename = '{}/vpp/vpp-config/configs/iperf-centos.xml.template'.format(self._rootdir)
+
+        with open(tfilename, 'r') as tfile:
+            tcontents = tfile.read()
+        tfile.close()
+
+        # Add the variables
+        imagename = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_IMAGE)
+        isoname = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_ISO)
+        tcontents = tcontents.format(vmname=vmname, imagename=imagename, isoname=isoname,
+                                     vhostsocketname=self._sockfilename)
+
+        # Write the xml
+        ifilename = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_XML)
+        with open(ifilename, 'w+') as ifile:
+            ifile.write(tcontents)
+        ifile.close()
+
+        cmd = 'virsh create {}'.format(ifilename)
+        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+        if ret != 0:
+            logging.debug(stderr)
+            raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
index 4ea9413..07d65b0 100644 (file)
@@ -753,8 +753,10 @@ class VPPUtil(object):
 
         :param node: VPP node.
         :type node: dict
+        :returns: A list of interfaces
         """
 
+        ifaces = []
         cmd = 'vppctl show bridge'
         (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
         if ret != 0:
@@ -766,7 +768,7 @@ class VPPUtil(object):
         for line in lines:
             if line == 'no bridge-domains in use':
                 print line
-                return
+                return ifaces
             if len(line) == 0:
                 continue
 
@@ -781,4 +783,13 @@ class VPPUtil(object):
                 raise RuntimeError('{} failed on node {} {} {}'.
                                    format(cmd, node['host'],
                                           stdout, stderr))
-            print stdout
+
+        lines = stdout.split('\r\n')
+        for line in lines:
+            iface = re.findall(r'[a-zA-z]+\d+/\d+/\d+', line)
+            if len(iface):
+                ifcidx ={'name': iface[0], 'index': line.split()[1] }
+                ifaces.append(ifcidx)
+
+        print stdout
+        return ifaces
\ No newline at end of file