Merge "mrg_buff_doc: Add documentation on mergable buffer option"
[vswitchperf.git] / core / vnf_controller.py
1 # Copyright 2015-2016 Intel Corporation.
2 #
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
6 #
7 #   http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14 """ VNF Controller interface
15 """
16
17 import logging
18 import pexpect
19 from conf import settings
20 from vnfs.vnf.vnf import IVnf
21
22 class VnfController(object):
23     """VNF controller class
24
25     Used to set-up and control VNFs for specified scenario
26
27     Attributes:
28         _vnf_class: A class object representing the VNF to be used.
29         _deployment: A string describing the scenario to set-up in the
30             constructor.
31         _vnfs: A list of vnfs controlled by the controller.
32     """
33
34     def __init__(self, deployment, vnf_class, extra_vnfs):
35         """Sets up the VNF infrastructure based on deployment scenario
36
37         :param vnf_class: The VNF class to be used.
38         :param extra_vnfs: The number of VNFs not involved in given
39             deployment scenario. It will be used to correctly expand
40             configuration values and initialize shared dirs. This parameter
41             is used in case, that additional VNFs are executed by TestSteps.
42         """
43         # reset VNF ID counter for each testcase
44         IVnf.reset_vnf_counter()
45
46         # setup controller with requested number of VNFs
47         self._logger = logging.getLogger(__name__)
48         self._vnf_class = vnf_class
49         self._deployment = deployment.lower()
50         self._vnfs = []
51         if self._deployment == 'pvp':
52             vm_number = 1
53         elif (self._deployment.startswith('pvvp') or
54               self._deployment.startswith('pvpv')):
55             if len(self._deployment) > 4:
56                 vm_number = int(self._deployment[4:])
57             else:
58                 vm_number = 2
59         else:
60             # VnfController is created for all deployments, including deployments
61             # without VNFs like p2p
62             vm_number = 0
63
64         if vm_number + extra_vnfs > 0:
65             self._logger.debug('Check configuration for %s guests.', vm_number + extra_vnfs)
66             settings.check_vm_settings(vm_number + extra_vnfs)
67             # enforce that GUEST_NIC_NR is 1 or even number of NICs
68             updated = False
69             nics_nr = settings.getValue('GUEST_NICS_NR')
70             for index in range(len(nics_nr)):
71                 if nics_nr[index] > 1 and nics_nr[index] % 2:
72                     updated = True
73                     nics_nr[index] = int(nics_nr[index] / 2) * 2
74             if updated:
75                 settings.setValue('GUEST_NICS_NR', nics_nr)
76                 self._logger.warning('Odd number of NICs was detected. Configuration '
77                                      'was updated to GUEST_NICS_NR = %s',
78                                      settings.getValue('GUEST_NICS_NR'))
79
80         if vm_number:
81             self._vnfs = [vnf_class() for _ in range(vm_number)]
82
83             self._logger.debug('__init__ ' + str(len(self._vnfs)) +
84                                ' VNF[s] with ' + ' '.join(map(str, self._vnfs)))
85
86     def get_vnfs(self):
87         """Returns a list of vnfs controlled by this controller.
88         """
89         self._logger.debug('get_vnfs ' + str(len(self._vnfs)) +
90                            ' VNF[s] with ' + ' '.join(map(str, self._vnfs)))
91         return self._vnfs
92
93     def get_vnfs_number(self):
94         """Returns a number of vnfs controlled by this controller.
95         """
96         self._logger.debug('get_vnfs_number ' + str(len(self._vnfs)) +
97                            ' VNF[s]')
98         return len(self._vnfs)
99
100     def start(self):
101         """Boots all VNFs set-up by __init__.
102
103         This is a blocking function.
104         """
105         self._logger.debug('start ' + str(len(self._vnfs)) +
106                            ' VNF[s] with ' + ' '.join(map(str, self._vnfs)))
107         try:
108             for vnf in self._vnfs:
109                 vnf.start()
110         except pexpect.TIMEOUT:
111             self.stop()
112             raise
113
114     def stop(self):
115         """Stops all VNFs set-up by __init__.
116
117         This is a blocking function.
118         """
119         self._logger.debug('stop ' + str(len(self._vnfs)) +
120                            ' VNF[s] with ' + ' '.join(map(str, self._vnfs)))
121         for vnf in self._vnfs:
122             vnf.stop()
123
124     def __enter__(self):
125         self.start()
126
127     def __exit__(self, type_, value, traceback):
128         self.stop()