X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yardstick%2Fbenchmark%2Fcontexts%2Fheat.py;h=479548b34115e51fab785028e467d4cf6425b121;hb=536076de790aed38b462edd8f8b2f079d3e828b2;hp=8c514d250aaa17a1a28b557c8e345e1fe4eb48aa;hpb=41a4f75e6c951d527daa752419acf282b4626193;p=yardstick.git diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py index 8c514d250..479548b34 100644 --- a/yardstick/benchmark/contexts/heat.py +++ b/yardstick/benchmark/contexts/heat.py @@ -7,19 +7,31 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +from __future__ import absolute_import +from __future__ import print_function + +import collections +import logging +import os import sys +import uuid + +import paramiko import pkg_resources from yardstick.benchmark.contexts.base import Context -from yardstick.benchmark.contexts.model import Server -from yardstick.benchmark.contexts.model import PlacementGroup from yardstick.benchmark.contexts.model import Network +from yardstick.benchmark.contexts.model import PlacementGroup, ServerGroup +from yardstick.benchmark.contexts.model import Server from yardstick.benchmark.contexts.model import update_scheduler_hints -from yardstick.orchestrator.heat import HeatTemplate +from yardstick.orchestrator.heat import HeatTemplate, get_short_key_uuid +from yardstick.definitions import YARDSTICK_ROOT_PATH + +LOG = logging.getLogger(__name__) class HeatContext(Context): - '''Class that represents a context in the logical model''' + """Class that represents a context in the logical model""" __context_type__ = "Heat" @@ -29,6 +41,7 @@ class HeatContext(Context): self.networks = [] self.servers = [] self.placement_groups = [] + self.server_groups = [] self.keypair_name = None self.secgroup_name = None self._server_map = {} @@ -37,33 +50,39 @@ class HeatContext(Context): self._user = None self.template_file = None self.heat_parameters = None - super(self.__class__, self).__init__() - - def init(self, attrs): - '''initializes itself from the supplied arguments''' + # generate an uuid to identify yardstick_key + # the first 8 digits of the uuid will be used + self.key_uuid = uuid.uuid4() + self.key_filename = ''.join( + [YARDSTICK_ROOT_PATH, 'yardstick/resources/files/yardstick_key-', + get_short_key_uuid(self.key_uuid)]) + super(HeatContext, self).__init__() + + def init(self, attrs): # pragma: no cover + """initializes itself from the supplied arguments""" self.name = attrs["name"] - if "user" in attrs: - self._user = attrs["user"] + self._user = attrs.get("user") - if "heat_template" in attrs: - self.template_file = attrs["heat_template"] - self.heat_parameters = attrs.get("heat_parameters", None) + self.template_file = attrs.get("heat_template") + if self.template_file: + self.heat_parameters = attrs.get("heat_parameters") return self.keypair_name = self.name + "-key" self.secgroup_name = self.name + "-secgroup" - if "image" in attrs: - self._image = attrs["image"] + self._image = attrs.get("image") - if "flavor" in attrs: - self._flavor = attrs["flavor"] + self._flavor = attrs.get("flavor") - if "placement_groups" in attrs: - for name, pgattrs in attrs["placement_groups"].items(): - pg = PlacementGroup(name, self, pgattrs["policy"]) - self.placement_groups.append(pg) + self.placement_groups = [PlacementGroup(name, self, pgattrs["policy"]) + for name, pgattrs in attrs.get( + "placement_groups", {}).items()] + + self.server_groups = [ServerGroup(name, self, sgattrs["policy"]) + for name, sgattrs in attrs.get( + "server_groups", {}).items()] for name, netattrs in attrs["networks"].items(): network = Network(name, self, netattrs) @@ -74,24 +93,32 @@ class HeatContext(Context): self.servers.append(server) self._server_map[server.dn] = server + rsa_key = paramiko.RSAKey.generate(bits=2048, progress_func=None) + rsa_key.write_private_key_file(self.key_filename) + print("Writing %s ..." % self.key_filename) + with open(self.key_filename + ".pub", "w") as pubkey_file: + pubkey_file.write( + "%s %s\n" % (rsa_key.get_name(), rsa_key.get_base64())) + del rsa_key + @property def image(self): - '''returns application's default image name''' + """returns application's default image name""" return self._image @property def flavor(self): - '''returns application's default flavor name''' + """returns application's default flavor name""" return self._flavor @property def user(self): - '''return login user name corresponding to image''' + """return login user name corresponding to image""" return self._user def _add_resources_to_template(self, template): - '''add to the template the resources represented by this context''' - template.add_keypair(self.keypair_name) + """add to the template the resources represented by this context""" + template.add_keypair(self.keypair_name, self.key_uuid) template.add_security_group(self.secgroup_name) for network in self.networks: @@ -132,24 +159,22 @@ class HeatContext(Context): # workround for openstack nova bug, check JIRA: YARDSTICK-200 # for details if len(availability_servers) == 2: - if len(scheduler_hints["different_host"]) == 0: + if not scheduler_hints["different_host"]: scheduler_hints.pop("different_host", None) server.add_to_template(template, self.networks, scheduler_hints) - added_servers.append(server.stack_name) else: scheduler_hints["different_host"] = \ scheduler_hints["different_host"][0] server.add_to_template(template, self.networks, scheduler_hints) - added_servers.append(server.stack_name) else: server.add_to_template(template, self.networks, scheduler_hints) - added_servers.append(server.stack_name) + added_servers.append(server.stack_name) # create list of servers with affinity policy affinity_servers = [] @@ -169,14 +194,25 @@ class HeatContext(Context): server.add_to_template(template, self.networks, scheduler_hints) added_servers.append(server.stack_name) + # add server group + for sg in self.server_groups: + template.add_server_group(sg.name, sg.policy) + # add remaining servers with no placement group configured for server in list_of_servers: - if len(server.placement_groups) == 0: - server.add_to_template(template, self.networks, {}) + # TODO placement_group and server_group should combine + if not server.placement_groups: + scheduler_hints = {} + # affinity/anti-aff server group + sg = server.server_group + if sg: + scheduler_hints["group"] = {'get_resource': sg.name} + server.add_to_template(template, + self.networks, scheduler_hints) def deploy(self): - '''deploys template into a stack using cloud''' - print "Deploying context '%s'" % self.name + """deploys template into a stack using cloud""" + print("Deploying context '%s'" % self.name) heat_template = HeatTemplate(self.name, self.template_file, self.heat_parameters) @@ -195,34 +231,42 @@ class HeatContext(Context): # copy some vital stack output into server objects for server in self.servers: - if len(server.ports) > 0: + if server.ports: # TODO(hafe) can only handle one internal network for now - port = server.ports.values()[0] + port = next(iter(server.ports.values())) server.private_ip = self.stack.outputs[port["stack_name"]] if server.floating_ip: server.public_ip = \ self.stack.outputs[server.floating_ip["stack_name"]] - print "Context '%s' deployed" % self.name + print("Context '%s' deployed" % self.name) def undeploy(self): - '''undeploys stack from cloud''' + """undeploys stack from cloud""" if self.stack: - print "Undeploying context '%s'" % self.name + print("Undeploying context '%s'" % self.name) self.stack.delete() self.stack = None - print "Context '%s' undeployed" % self.name + print("Context '%s' undeployed" % self.name) + + if os.path.exists(self.key_filename): + try: + os.remove(self.key_filename) + os.remove(self.key_filename + ".pub") + except OSError: + LOG.exception("Key filename %s", self.key_filename) def _get_server(self, attr_name): - '''lookup server info by name from context + """lookup server info by name from context attr_name: either a name for a server created by yardstick or a dict with attribute name mapping when using external heat templates - ''' + """ key_filename = pkg_resources.resource_filename( - 'yardstick.resources', 'files/yardstick_key') + 'yardstick.resources', + 'files/yardstick_key-' + get_short_key_uuid(self.key_uuid)) - if type(attr_name) is dict: + if isinstance(attr_name, collections.Mapping): cname = attr_name["name"].split(".")[1] if cname != self.name: return None