NFVBENCH-27 Search vm image under project folder
[nfvbench.git] / nfvbench / chain_clients.py
index 4be050f..c6df08a 100644 (file)
@@ -20,6 +20,7 @@ from log import LOG
 from neutronclient.neutron import client as neutronclient
 from novaclient.client import Client
 import os
+import re
 import time
 
 
@@ -35,6 +36,7 @@ class BasicStageClient(object):
     def __init__(self, config, cred):
         self.comp = None
         self.image_instance = None
+        self.image_name = None
         self.config = config
         self.cred = cred
         self.nets = []
@@ -48,7 +50,9 @@ class BasicStageClient(object):
         self.host_ips = None
 
     def _ensure_vms_active(self):
-        for _ in range(self.config.generic_retry_count):
+        retry_count = (self.config.check_traffic_time_sec +
+                       self.config.generic_poll_sec - 1) / self.config.generic_poll_sec
+        for _ in range(retry_count):
             for i, instance in enumerate(self.vms):
                 if instance.status == 'ACTIVE':
                     continue
@@ -78,11 +82,13 @@ class BasicStageClient(object):
         networks = self.neutron.list_networks(name=network_name)
         return networks['networks'][0] if networks['networks'] else None
 
-    def _create_net(self, name, subnet, cidr, network_type=None, segmentation_id=None):
+    def _create_net(self, name, subnet, cidr, network_type=None,
+                    segmentation_id=None, physical_network=None):
         network = self._lookup_network(name)
         if network:
-            phys_net = self.config.internal_networks.physical_network
-            if segmentation_id is not None and phys_net is not None:
+            # a network of same name already exists, we need to verify it has the same
+            # characteristics
+            if segmentation_id:
                 if network['provider:segmentation_id'] != segmentation_id:
                     raise StageClientException("Mismatch of 'segmentation_id' for reused "
                                                "network '{net}'. Network has id '{seg_id1}', "
@@ -91,13 +97,14 @@ class BasicStageClient(object):
                                                        seg_id1=network['provider:segmentation_id'],
                                                        seg_id2=segmentation_id))
 
-                if network['provider:physical_network'] != phys_net:
+            if physical_network:
+                if network['provider:physical_network'] != physical_network:
                     raise StageClientException("Mismatch of 'physical_network' for reused "
                                                "network '{net}'. Network has '{phys1}', "
                                                "configuration requires '{phys2}'."
                                                .format(net=name,
                                                        phys1=network['provider:physical_network'],
-                                                       phys2=phys_net))
+                                                       phys2=physical_network))
 
             LOG.info('Reusing existing network: ' + name)
             network['is_reuse'] = True
@@ -112,10 +119,10 @@ class BasicStageClient(object):
 
         if network_type:
             body['network']['provider:network_type'] = network_type
-            phys_net = self.config.internal_networks.physical_network
-            if segmentation_id is not None and phys_net is not None:
+            if segmentation_id:
                 body['network']['provider:segmentation_id'] = segmentation_id
-                body['network']['provider:physical_network'] = phys_net
+            if physical_network:
+                body['network']['provider:physical_network'] = physical_network
 
         network = self.neutron.create_network(body)['network']
         body = {
@@ -224,25 +231,45 @@ class BasicStageClient(object):
         return server
 
     def _setup_resources(self):
-        if not self.image_instance:
-            self.image_instance = self.comp.find_image(self.config.image_name)
-        if self.image_instance is None:
+        # To avoid reuploading image in server mode, check whether image_name is set or not
+        if self.image_name:
+            self.image_instance = self.comp.find_image(self.image_name)
+        if self.image_instance:
+            LOG.info("Reusing image %s" % self.image_name)
+        else:
+            image_name_search_pattern = '(nfvbenchvm-\d+(\.\d+)*).qcow2'
             if self.config.vm_image_file:
-                LOG.info('%s: image for VM not found, trying to upload it ...'
-                         % self.config.image_name)
-                res = self.comp.upload_image_via_url(self.config.image_name,
+                match = re.search(image_name_search_pattern, self.config.vm_image_file)
+                if match:
+                    self.image_name = match.group(1)
+                    LOG.info('Using provided VM image file %s' % self.config.vm_image_file)
+                else:
+                    raise StageClientException('Provided VM image file name %s must start with '
+                                               '"nfvbenchvm-<version>"' % self.config.vm_image_file)
+            else:
+                pkg_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+                for f in os.listdir(pkg_root):
+                    if re.search(image_name_search_pattern, f):
+                        self.config.vm_image_file = pkg_root + '/' + f
+                        self.image_name = f.replace('.qcow2', '')
+                        LOG.info('Found built-in VM image file %s' % f)
+                        break
+                else:
+                    raise StageClientException('Cannot find any built-in VM image file.')
+            if self.image_name:
+                self.image_instance = self.comp.find_image(self.image_name)
+            if not self.image_instance:
+                LOG.info('Uploading %s'
+                         % self.image_name)
+                res = self.comp.upload_image_via_url(self.image_name,
                                                      self.config.vm_image_file)
 
                 if not res:
                     raise StageClientException('Error uploading image %s from %s. ABORTING.'
-                                               % (self.config.image_name,
+                                               % (self.image_name,
                                                   self.config.vm_image_file))
-                self.image_instance = self.comp.find_image(self.config.image_name)
-            else:
-                raise StageClientException('%s: image to launch VM not found. ABORTING.'
-                                           % self.config.image_name)
-
-        LOG.info('Found image %s to launch VM' % self.config.image_name)
+                LOG.info('Image %s successfully uploaded.' % self.image_name)
+                self.image_instance = self.comp.find_image(self.image_name)
 
         self.__setup_flavor()
 
@@ -376,7 +403,7 @@ class BasicStageClient(object):
         """
         vlans = []
         for net in self.nets:
-            assert(net['provider:network_type'] == 'vlan')
+            assert (net['provider:network_type'] == 'vlan')
             vlans.append(net['provider:segmentation_id'])
 
         return vlans
@@ -414,7 +441,6 @@ class BasicStageClient(object):
 
 
 class EXTStageClient(BasicStageClient):
-
     def __init__(self, config, cred):
         super(EXTStageClient, self).__init__(config, cred)
 
@@ -431,7 +457,6 @@ class EXTStageClient(BasicStageClient):
 
 
 class PVPStageClient(BasicStageClient):
-
     def __init__(self, config, cred):
         super(PVPStageClient, self).__init__(config, cred)
 
@@ -475,7 +500,6 @@ class PVPStageClient(BasicStageClient):
 
 
 class PVVPStageClient(BasicStageClient):
-
     def __init__(self, config, cred):
         super(PVVPStageClient, self).__init__(config, cred)