1 # Copyright 2017-2018 Spirent Communications.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 Wrapper file to create and manage Stressor-VM as loadgen
21 from tools import tasks
22 from tools.load_gen.load_gen import ILoadGenerator
23 from conf import settings as S
26 class QemuVM(tasks.Process):
28 Class for controling an instance of QEMU
30 def __init__(self, index):
32 self._logger = logging.getLogger(__name__)
34 pnumber = int(S.getValue('NN_BASE_VNC_PORT')) + self._number
35 cpumask = ",".join(S.getValue('NN_CORE_BINDING')[self._number])
36 self._monitor = '%s/vm%dmonitor' % ('/tmp', pnumber)
37 self._logfile = (os.path.join(S.getValue('LOG_DIR'),
38 S.getValue('NN_LOG_FILE')) +
40 self._log_prefix = 'vnf_%d_cmd : ' % pnumber
43 self._shared_dir = '%s/qemu%d_share' % ('/tmp', pnumber)
44 if not os.path.exists(self._shared_dir):
46 os.makedirs(self._shared_dir)
47 except OSError as exp:
48 raise OSError("Failed to create shared directory %s: %s" %
49 self._shared_dir, exp)
51 self.nics_nr = S.getValue('NN_NICS_NR')[self._number]
52 self.image = S.getValue('NN_IMAGE')[self._number]
53 self._cmd = ['sudo', '-E', 'taskset', '-c', cpumask,
54 S.getValue('TOOLS')['qemu-system'],
55 '-m', S.getValue('NN_MEMORY')[self._number],
56 '-smp', S.getValue('NN_SMP')[self._number],
57 '-cpu', 'host,migratable=off',
58 '-drive', 'if={},file='.format(
59 S.getValue('NN_BOOT_DRIVE_TYPE')[self._number]) +
62 '-monitor', 'unix:%s,server,nowait' % self._monitor,
63 '-nographic', '-vnc', str(vnc), '-name', name,
64 '-snapshot', '-net none', '-no-reboot',
66 'if=%s,format=raw,file=fat:rw:%s,snapshot=off' %
67 (S.getValue('NN_SHARED_DRIVE_TYPE')[self._number],
75 super(QemuVM, self).start()
78 def stop(self, sig, slp):
83 self._logger.info('Killing VNF...')
84 # force termination of VNF and wait to terminate; It will avoid
85 # sporadic reboot of host.
86 super(QemuVM, self).kill(signal=sig, sleep=slp)
87 # remove shared dir if it exists to avoid issues with file consistency
88 if os.path.exists(self._shared_dir):
89 tasks.run_task(['rm', '-f', '-r', self._shared_dir], self._logger,
90 'Removing content of shared directory...', True)
94 # pylint: disable=super-init-not-called
95 class StressorVM(ILoadGenerator):
97 Wrapper Class for Load-Generation through stressor-vm
99 def __init__(self, _config):
101 for vmindex in range(int(S.getValue('NN_COUNT'))):
102 qvm = QemuVM(vmindex)
103 self.qvm_list.append(qvm)
106 """Start stressor VMs
108 for nvm in self.qvm_list:
111 def kill(self, signal='-9', sleep=2):
115 for nvm in self.qvm_list:
116 nvm.stop(signal, sleep)