summaryrefslogtreecommitdiffstats
path: root/conf/__init__.py
diff options
context:
space:
mode:
authorMartin Klozik <martinx.klozik@intel.com>2016-08-16 14:59:05 +0100
committerMartin Klozik <martinx.klozik@intel.com>2016-09-01 14:52:49 +0100
commitc9cd093f2f441adc9dd33627255326008e021a67 (patch)
treedcf81dde95fbc91e65f8670841ffdbfb65a6c4a6 /conf/__init__.py
parentb2289e1f6abab2d807eb55d9ec868039dc2384e2 (diff)
multi VM: Multi VMs in serial or parallel
Support for deployment scenarios with any number of VMs in both serial and parallel configuration. Detailed content of the patch: * VswitchControllerPXP class for multi VM support * pvvpxx and pvpvxx deployments for xx VMs in serial respective parallel configuration * special GUEST_ options expansion to requested number of VMs; * support of GUEST_ options specific macros #VMINDEX, #MAC(), #IP() and #EVAL() * all GUEST specific options are turned to lists to be VM specific * support for VM with 1 NIC * support for VM with multiple NIC pairs; traffic is routed in serial or parallel between NIC paris based on deployment scenario * support for PVVP and PVPV scenarios using VMs with different numbers of NICs JIRA: VSPERF-361 Change-Id: I05bedbdfa9a81ea0166d9b03d83ae49d6cb8b19b Signed-off-by: Martin Klozik <martinx.klozik@intel.com> Reviewed-by: Maryam Tahhan <maryam.tahhan@intel.com> Reviewed-by: Al Morton <acmorton@att.com> Reviewed-by: Christian Trautman <ctrautma@redhat.com> Reviewed-by: Bill Michalowski <bmichalo@redhat.com> Reviewed-by: Antonio Fischetti <antonio.fischetti@intel.com>
Diffstat (limited to 'conf/__init__.py')
-rw-r--r--conf/__init__.py75
1 files changed, 74 insertions, 1 deletions
diff --git a/conf/__init__.py b/conf/__init__.py
index 46228235..88e8cec6 100644
--- a/conf/__init__.py
+++ b/conf/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,7 +22,22 @@ and any user provided settings file.
import os
import re
+import logging
import pprint
+import ast
+import netaddr
+
+_LOGGER = logging.getLogger(__name__)
+
+# regex to parse configuration macros from 04_vnf.conf
+# it will select all patterns starting with # sign
+# and returns macro parameters and step
+# examples of valid macros:
+# #VMINDEX
+# #MAC(AA:BB:CC:DD:EE:FF) or #MAC(AA:BB:CC:DD:EE:FF,2)
+# #IP(192.168.1.2) or #IP(192.168.1.2,2)
+# #EVAL(2*#VMINDEX)
+_PARSE_PATTERN = r'(#[A-Z]+)(\(([^(),]+)(,([0-9]+))?\))?'
class Settings(object):
"""Holding class for settings.
@@ -121,6 +136,64 @@ class Settings(object):
for key in os.environ:
setattr(self, key, os.environ[key])
+ def check_vm_settings(self, vm_number):
+ """
+ Check all VM related settings starting with GUEST_ prefix.
+ If it is not available for defined number of VMs, then vsperf
+ will try to expand it automatically. Expansion is performed
+ also in case that first list item contains a macro.
+ """
+ for key in self.__dict__:
+ if key.startswith('GUEST_'):
+ if (isinstance(self.__dict__[key], str) and
+ self.__dict__[key].find('#') >= 0):
+ self.__dict__[key] = [self.__dict__[key]]
+ self._expand_vm_settings(key, 1)
+ self.__dict__[key] = self.__dict__[key][0]
+
+ if isinstance(self.__dict__[key], list):
+ if (len(self.__dict__[key]) < vm_number or
+ str(self.__dict__[key][0]).find('#') >= 0):
+ # expand configuration for all VMs
+ self._expand_vm_settings(key, vm_number)
+
+ def _expand_vm_settings(self, key, vm_number):
+ """
+ Expand VM option with given key for given number of VMs
+ """
+ master_value = self.__dict__[key][0]
+ master_value_str = str(master_value)
+ if master_value_str.find('#') >= 0:
+ self.__dict__[key] = []
+ for vmindex in range(vm_number):
+ value = master_value_str.replace('#VMINDEX', str(vmindex))
+ for macro, args, param, _, step in re.findall(_PARSE_PATTERN, value):
+ multi = int(step) if len(step) and int(step) else 1
+ if macro == '#EVAL':
+ tmp_result = str(eval(param))
+ elif macro == '#MAC':
+ mac_value = netaddr.EUI(param).value
+ mac = netaddr.EUI(mac_value + vmindex * multi)
+ mac.dialect = netaddr.mac_unix_expanded
+ tmp_result = str(mac)
+ elif macro == '#IP':
+ ip_value = netaddr.IPAddress(param).value
+ tmp_result = str(netaddr.IPAddress(ip_value + vmindex * multi))
+ else:
+ raise RuntimeError('Unknown configuration macro {} in {}'.format(macro, key))
+
+ value = value.replace("{}{}".format(macro, args), tmp_result)
+
+ # retype value to original type if needed
+ if not isinstance(master_value, str):
+ value = ast.literal_eval(value)
+ self.__dict__[key].append(value)
+ else:
+ for vmindex in range(len(self.__dict__[key]), vm_number):
+ self.__dict__[key].append(master_value)
+
+ _LOGGER.debug("Expanding option: %s = %s", key, self.__dict__[key])
+
def __str__(self):
"""Provide settings as a human-readable string.