From ca96a3aa9ccb88f2b041506b46bb628df74e64f8 Mon Sep 17 00:00:00 2001 From: Kerim Gokarslan Date: Thu, 14 Sep 2017 20:17:41 -0700 Subject: NFVBENCH-27 Search vm image under project folder Change-Id: I0d9c148e868fbcd665734eb92ac5c182693c3c67 Signed-off-by: Kerim Gokarslan --- docs/testing/user/userguide/server.rst | 3 +- nfvbench/cfg.default.yaml | 19 +++++------- nfvbench/chain_clients.py | 53 +++++++++++++++++++++++----------- nfvbench/compute.py | 7 ++--- nfvbench/nfvbench.py | 3 -- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/docs/testing/user/userguide/server.rst b/docs/testing/user/userguide/server.rst index ebdd828..f1ab618 100644 --- a/docs/testing/user/userguide/server.rst +++ b/docs/testing/user/userguide/server.rst @@ -170,7 +170,6 @@ The entire default configuration can be viewed using the --show-json-config opti "flow_count": 1, "generic_poll_sec": 2, "generic_retry_count": 100, - "image_name": "nfvbenchvm", "inter_node": false, "internal_networks": { "left": { @@ -304,7 +303,7 @@ The entire default configuration can be viewed using the --show-json-config opti ], "unidir_reverse_traffic_pps": 1, "vlan_tagging": true, - "vm_image_file": "file://172.29.172.152/downloads/nfvbench/nfvbenchvm-latest.qcow2", + "vm_image_file": "/nfvbench/nfvbenchvm-0.3.qcow2", "vts_ncs": { "host": null, "password": "secret", diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml index 534b3c7..f36cbea 100644 --- a/nfvbench/cfg.default.yaml +++ b/nfvbench/cfg.default.yaml @@ -19,21 +19,16 @@ # option, e.g. "--interval" -# Name of the image to use for launching the loopback VMs. This name must be -# the exact same name used in OpenStack (as shown from 'nova image-list') -# Can be overridden by --image or -i -image_name: 'nfvbenchvm' # Forwarder to use in nfvbenchvm image. Available options: ['vpp', 'testpmd'] vm_forwarder: testpmd -# NFVbench can automatically upload a VM image if the image named by -# image_name is missing, for that you need to specify a file location where -# the image can be retrieved -# -# To upload the image as a file, download it to preferred location -# and prepend it with file:// like in this example: -# file:// -# NFVbench (the image must have the same name as defined in image_name above). +# By default (empty) NFVBench will try to locate a VM image file +# from the package root directory named "nfvbench-.qcow2" and +# upload that file. The image name will be "nfvbench-" +# This can be overridden by specifying here a pathname of a file +# that follows the same naming convention. +# In most cases, this field should be left empty as the packaging should +# include the proper VM image file vm_image_file: # Name of the flavor to use for the loopback VMs diff --git a/nfvbench/chain_clients.py b/nfvbench/chain_clients.py index bf51552..c6df08a 100644 --- a/nfvbench/chain_clients.py +++ b/nfvbench/chain_clients.py @@ -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 = [] @@ -229,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-"' % 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() @@ -381,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 @@ -419,7 +441,6 @@ class BasicStageClient(object): class EXTStageClient(BasicStageClient): - def __init__(self, config, cred): super(EXTStageClient, self).__init__(config, cred) @@ -436,7 +457,6 @@ class EXTStageClient(BasicStageClient): class PVPStageClient(BasicStageClient): - def __init__(self, config, cred): super(PVPStageClient, self).__init__(config, cred) @@ -480,7 +500,6 @@ class PVPStageClient(BasicStageClient): class PVVPStageClient(BasicStageClient): - def __init__(self, config, cred): super(PVVPStageClient, self).__init__(config, cred) diff --git a/nfvbench/compute.py b/nfvbench/compute.py index 681a852..5806164 100644 --- a/nfvbench/compute.py +++ b/nfvbench/compute.py @@ -51,9 +51,7 @@ class Compute(object): retry = 0 try: # check image is file/url based. - file_prefix = "file://" - image_location = image_file.split(file_prefix)[1] - with open(image_location) as f_image: + with open(image_file) as f_image: img = self.glance_client.images.create(name=str(final_image_name), disk_format="qcow2", container_format="bare", @@ -82,8 +80,7 @@ class Compute(object): return False except Exception: LOG.error(traceback.format_exc()) - LOG.error("Failed while uploading the image, please make sure the " - "cloud under test has the access to file: %s.", image_file) + LOG.error("Failed to upload image %s.", image_file) return False return True diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py index 37645aa..67b953f 100644 --- a/nfvbench/nfvbench.py +++ b/nfvbench/nfvbench.py @@ -291,9 +291,6 @@ def parse_opts_from_cli(): action='store', help='Traffic generator profile to use') - parser.add_argument('-i', '--image', dest='image_name', - action='store', - help='VM image name to use') parser.add_argument('-0', '--no-traffic', dest='no_traffic', default=None, -- cgit 1.2.3-korg