From a874f412c78c04ae02b92a3d0da8a10956f80b74 Mon Sep 17 00:00:00 2001 From: "Sridhar K. N. Rao" Date: Tue, 28 Nov 2017 16:52:15 +0530 Subject: loadgen: Support for Stressor-VMs as a Loadgen This patch adds support for stressor-VMs as a loadgen in VSPERF. The changes include: 1. 07_loadgen.conf: User can specify the stressor-VM specific configuration. It includes, image-name, path, nics, memory, etc. 2. loadgen/stressorvm/stressor_vm.py: This file implement ILoadGenerator interface. It implements all the necessary APIs for starting and stopping the loads. 3. Fixed Pylint Error 4. Removed the network device configuration from qemu-system-x86_64 command as stessor-vm mostly focus on CPU and memory stressing. 5. Moved the creation of loadgen after the VNFs are setup in testcase.py. 6. Fixed copyright issues. 7. Removed python-3 checking. Improved exception handling 8. Set Default loadgen as DummyLoadGen 9. Improved OSError Printing with directory name and error 10. Update the year in license. 2017-2018. JIRA: VSPERF-504 Change-Id: Iad6c0780c184f8e36eddcbcae2a580f41118e8dc Signed-off-by: Sridhar K. N. Rao --- tools/load_gen/stressorvm/__init__.py | 16 +++++ tools/load_gen/stressorvm/stressor_vm.py | 117 +++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 tools/load_gen/stressorvm/__init__.py create mode 100644 tools/load_gen/stressorvm/stressor_vm.py (limited to 'tools/load_gen') diff --git a/tools/load_gen/stressorvm/__init__.py b/tools/load_gen/stressorvm/__init__.py new file mode 100644 index 00000000..6a22d81c --- /dev/null +++ b/tools/load_gen/stressorvm/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2017-2018 Spirent Communications +# +# 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. + +"""Package with wrapper for Stressor-VMs +""" diff --git a/tools/load_gen/stressorvm/stressor_vm.py b/tools/load_gen/stressorvm/stressor_vm.py new file mode 100644 index 00000000..410f10e3 --- /dev/null +++ b/tools/load_gen/stressorvm/stressor_vm.py @@ -0,0 +1,117 @@ +# Copyright 2017-2018 Spirent Communications. +# +# 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. + +""" +Wrapper file to create and manage Stressor-VM as loadgen +""" + +import logging +import os +from tools import tasks +from tools.load_gen.load_gen import ILoadGenerator +from conf import settings as S + + +class QemuVM(tasks.Process): + """ + Class for controling an instance of QEMU + """ + def __init__(self, index): + self._running = False + self._logger = logging.getLogger(__name__) + self._number = index + pnumber = int(S.getValue('NN_BASE_VNC_PORT')) + self._number + cpumask = ",".join(S.getValue('NN_CORE_BINDING')[self._number]) + self._monitor = '%s/vm%dmonitor' % ('/tmp', pnumber) + self._logfile = (os.path.join(S.getValue('LOG_DIR'), + S.getValue('NN_LOG_FILE')) + + str(self._number)) + self._log_prefix = 'vnf_%d_cmd : ' % pnumber + name = 'NN%d' % index + vnc = ':%d' % pnumber + self._shared_dir = '%s/qemu%d_share' % ('/tmp', pnumber) + if not os.path.exists(self._shared_dir): + try: + os.makedirs(self._shared_dir) + except OSError as exp: + raise OSError("Failed to create shared directory %s: %s", + self._shared_dir, exp) + + self.nics_nr = S.getValue('NN_NICS_NR')[self._number] + self.image = S.getValue('NN_IMAGE')[self._number] + self._cmd = ['sudo', '-E', 'taskset', '-c', cpumask, + S.getValue('TOOLS')['qemu-system'], + '-m', S.getValue('NN_MEMORY')[self._number], + '-smp', S.getValue('NN_SMP')[self._number], + '-cpu', 'host,migratable=off', + '-drive', 'if={},file='.format( + S.getValue('NN_BOOT_DRIVE_TYPE')[self._number]) + + self.image, '-boot', + 'c', '--enable-kvm', + '-monitor', 'unix:%s,server,nowait' % self._monitor, + '-nographic', '-vnc', str(vnc), '-name', name, + '-snapshot', '-net none', '-no-reboot', + '-drive', + 'if=%s,format=raw,file=fat:rw:%s,snapshot=off' % + (S.getValue('NN_SHARED_DRIVE_TYPE')[self._number], + self._shared_dir) + ] + + def start(self): + """ + Start QEMU instance + """ + super(QemuVM, self).start() + self._running = True + + def stop(self, sig, slp): + """ + Stops VNF instance. + """ + if self._running: + self._logger.info('Killing VNF...') + # force termination of VNF and wait to terminate; It will avoid + # sporadic reboot of host. + super(QemuVM, self).kill(signal=sig, sleep=slp) + # remove shared dir if it exists to avoid issues with file consistency + if os.path.exists(self._shared_dir): + tasks.run_task(['rm', '-f', '-r', self._shared_dir], self._logger, + 'Removing content of shared directory...', True) + self._running = False + + +# pylint: disable=super-init-not-called +class StressorVM(ILoadGenerator): + """ + Wrapper Class for Load-Generation through stressor-vm + """ + # pylint: disable=unused-argument + def __init__(self, config): + self.qvm_list = [] + for vmindex in range(int(S.getValue('NN_COUNT'))): + qvm = QemuVM(vmindex) + self.qvm_list.append(qvm) + + def start(self): + """Start stressor VMs + """ + for nvm in self.qvm_list: + nvm.start() + + def kill(self, signal='-9', sleep=2): + """ + Stop Stressor VMs + """ + for nvm in self.qvm_list: + nvm.stop(signal, sleep) -- cgit 1.2.3-korg