e921437d614581d46e4db8e1552fb54e70dcd29a
[yardstick.git] / yardstick / benchmark / contexts / standalone.py
1 # Copyright (c) 2016-2017 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 """This module handle non managed standalone virtualization node."""
15
16 from __future__ import absolute_import
17 import logging
18 import errno
19 import collections
20 import yaml
21
22 from yardstick.benchmark.contexts.base import Context
23 from yardstick.common.constants import YARDSTICK_ROOT_PATH
24 from yardstick.common.utils import import_modules_from_package, itersubclasses
25
26 LOG = logging.getLogger(__name__)
27
28
29 class StandaloneContext(Context):
30     """ This class handles standalone nodes - VM running on Non-Managed NFVi
31     Configuration: vswitch, ovs, ovs-dpdk, sr-iov, linuxbridge
32     """
33
34     __context_type__ = "Standalone"
35
36     def __init__(self):
37         self.name = None
38         self.file_path = None
39         self.nodes = []
40         self.networks = {}
41         self.nfvi_node = []
42         self.nfvi_obj = None
43         super(self.__class__, self).__init__()
44
45     def read_config_file(self):
46         """Read from config file"""
47
48         with open(self.file_path) as stream:
49             LOG.info("Parsing pod file: %s", self.file_path)
50             cfg = yaml.load(stream)
51         return cfg
52
53     def get_nfvi_obj(self):
54         print("{0}".format(self.nfvi_node[0]['role']))
55         context_type = self.get_context_impl(self.nfvi_node[0]['role'])
56         nfvi_obj = context_type()
57         nfvi_obj.__init__()
58         nfvi_obj.parse_pod_and_get_data(self.file_path)
59         return nfvi_obj
60
61     def init(self, attrs):
62         """initializes itself from the supplied arguments"""
63
64         self.name = attrs["name"]
65         self.file_path = attrs.get("file", "pod.yaml")
66         LOG.info("Parsing pod file: %s", self.file_path)
67
68         try:
69             cfg = self.read_config_file()
70         except IOError as ioerror:
71             if ioerror.errno == errno.ENOENT:
72                 self.file_path = YARDSTICK_ROOT_PATH + self.file_path
73                 cfg = self.read_config_file()
74             else:
75                 raise
76
77         self.nodes.extend(cfg["nodes"])
78         self.nfvi_node.extend([node for node in cfg["nodes"]
79                                if node["role"] == "nfvi_node"])
80         # add optional static network definition
81         self.networks.update(cfg.get("networks", {}))
82         for node in cfg["nodes"]:
83             if str(node["role"]) == "Sriov":
84                 self.nfvi_node.extend([node for node in cfg["nodes"]
85                                        if str(node["role"]) == "Sriov"])
86             if str(node["role"]) == "ovs-dpdk":
87                 LOG.info("{0}".format(node["role"]))
88             else:
89                 LOG.debug("Node role is other than SRIOV and OVS")
90         self.nfvi_obj = self.get_nfvi_obj()
91         LOG.debug("Nodes: %r", self.nodes)
92         LOG.debug("NFVi Node: %r", self.nfvi_node)
93         LOG.debug("Networks: %r", self.networks)
94
95     def deploy(self):
96         """don't need to deploy"""
97
98         # Todo: NFVi deploy (sriov, vswitch, ovs etc) based on the config.
99         self.nfvi_obj.ssh_remote_machine()
100         if self.nfvi_obj.first_run is True:
101             self.nfvi_obj.install_req_libs()
102
103         nic_details = self.nfvi_obj.get_nic_details()
104         print("{0}".format(nic_details))
105         self.nfvi_obj.setup_sriov_context(
106             self.nfvi_obj.sriov[0]['phy_ports'],
107             nic_details,
108             self.nfvi_obj.sriov[0]['phy_driver'])
109         pass
110
111     def undeploy(self):
112         """don't need to undeploy"""
113
114         # Todo: NFVi undeploy (sriov, vswitch, ovs etc) based on the config.
115         # self.nfvi_obj = self.get_nfvi_obj()
116         self.nfvi_obj.ssh_remote_machine()
117         self.nfvi_obj.destroy_vm()
118         pass
119
120     def _get_server(self, attr_name):
121         """lookup server info by name from context
122
123         Keyword arguments:
124         attr_name -- A name for a server listed in nodes config file
125         """
126
127         if isinstance(attr_name, collections.Mapping):
128             return None
129
130         if self.name != attr_name.split(".")[1]:
131             return None
132
133         node_name = attr_name.split(".")[0]
134         matching_nodes = (n for n in self.nodes if n["name"] == node_name)
135
136         try:
137             # A clone is created in order to avoid affecting the
138             # original one.
139             node = dict(next(matching_nodes))
140         except StopIteration:
141             return None
142
143         try:
144             duplicate = next(matching_nodes)
145         except StopIteration:
146             pass
147         else:
148             raise ValueError("Duplicate nodes!!! Nodes: %s %s",
149                              (matching_nodes, duplicate))
150
151         node["name"] = attr_name
152         return node
153
154     def _get_network(self, attr_name):
155         if not isinstance(attr_name, collections.Mapping):
156             network = self.networks.get(attr_name)
157
158         else:
159             # Don't generalize too much  Just support vld_id
160             vld_id = attr_name.get('vld_id')
161             if vld_id is None:
162                 return None
163             try:
164                 network = next(n for n in self.networks.values() if
165                                n.get("vld_id") == vld_id)
166             except StopIteration:
167                 return None
168
169         if network is None:
170             return None
171
172         result = {
173             # name is required
174             "name": network["name"],
175             "vld_id": network.get("vld_id"),
176             "segmentation_id": network.get("segmentation_id"),
177             "network_type": network.get("network_type"),
178             "physical_network": network.get("physical_network"),
179         }
180         return result
181
182     def get_context_impl(self, nfvi_type):
183         """ Find the implementing class from vnf_model["vnf"]["name"] field
184
185         :param vnf_model: dictionary containing a parsed vnfd
186         :return: subclass of GenericVNF
187         """
188         import_modules_from_package(
189             "yardstick.benchmark.contexts")
190         expected_name = nfvi_type
191         impl = [c for c in itersubclasses(StandaloneContext)
192                 if c.__name__ == expected_name]
193         try:
194             return next(iter(impl))
195         except StopIteration:
196             raise ValueError("No implementation for %s", expected_name)