aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/benchmark/contexts/heat.py
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick/benchmark/contexts/heat.py')
-rw-r--r--yardstick/benchmark/contexts/heat.py143
1 files changed, 98 insertions, 45 deletions
diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py
index 7b7f1be32..0d1dfb86f 100644
--- a/yardstick/benchmark/contexts/heat.py
+++ b/yardstick/benchmark/contexts/heat.py
@@ -13,7 +13,6 @@ from __future__ import print_function
import collections
import logging
import os
-import uuid
import errno
from collections import OrderedDict
@@ -25,9 +24,12 @@ 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.common.openstack_utils import get_neutron_client
-from yardstick.orchestrator.heat import HeatTemplate, get_short_key_uuid
+from yardstick.common import exceptions as y_exc
+from yardstick.common.openstack_utils import get_shade_client
+from yardstick.orchestrator.heat import HeatStack
+from yardstick.orchestrator.heat import HeatTemplate
from yardstick.common import constants as consts
+from yardstick.common import utils
from yardstick.common.utils import source_env
from yardstick.ssh import SSH
@@ -50,7 +52,6 @@ class HeatContext(Context):
__context_type__ = "Heat"
def __init__(self):
- self.name = None
self.stack = None
self.networks = OrderedDict()
self.heat_timeout = None
@@ -67,14 +68,9 @@ class HeatContext(Context):
self._user = None
self.template_file = None
self.heat_parameters = None
- self.neutron_client = None
- # generate an uuid to identify yardstick_key
- # the first 8 digits of the uuid will be used
- self.key_uuid = uuid.uuid4()
+ self.shade_client = None
self.heat_timeout = None
- self.key_filename = ''.join(
- [consts.YARDSTICK_ROOT_PATH, 'yardstick/resources/files/yardstick_key-',
- get_short_key_uuid(self.key_uuid)])
+ self.key_filename = None
super(HeatContext, self).__init__()
@staticmethod
@@ -95,10 +91,10 @@ class HeatContext(Context):
return sorted_networks
def init(self, attrs):
- """initializes itself from the supplied arguments"""
- self.check_environment()
- self.name = attrs["name"]
+ """Initializes itself from the supplied arguments"""
+ super(HeatContext, self).init(attrs)
+ self.check_environment()
self._user = attrs.get("user")
self.template_file = attrs.get("heat_template")
@@ -137,7 +133,6 @@ class HeatContext(Context):
self._server_map[server.dn] = server
self.attrs = attrs
- SSH.gen_keys(self.key_filename)
def check_environment(self):
try:
@@ -176,10 +171,13 @@ class HeatContext(Context):
template.add_flavor(**self.flavor)
self.flavors.add(flavor)
- template.add_keypair(self.keypair_name, self.key_uuid)
+ template.add_keypair(self.keypair_name, self.name)
template.add_security_group(self.secgroup_name)
for network in self.networks.values():
+ # Using existing network
+ if network.is_existing():
+ continue
template.add_network(network.stack_name,
network.physical_network,
network.provider,
@@ -285,38 +283,65 @@ class HeatContext(Context):
scheduler_hints)
def get_neutron_info(self):
- if not self.neutron_client:
- self.neutron_client = get_neutron_client()
+ if not self.shade_client:
+ self.shade_client = get_shade_client()
- networks = self.neutron_client.list_networks()
+ networks = self.shade_client.list_networks()
for network in self.networks.values():
- for neutron_net in networks['networks']:
- if neutron_net['name'] == network.stack_name:
+ for neutron_net in (net for net in networks if net.name == network.stack_name):
network.segmentation_id = neutron_net.get('provider:segmentation_id')
# we already have physical_network
# network.physical_network = neutron_net.get('provider:physical_network')
network.network_type = neutron_net.get('provider:network_type')
network.neutron_info = neutron_net
+ def _create_new_stack(self, heat_template):
+ try:
+ return heat_template.create(block=True,
+ timeout=self.heat_timeout)
+ except KeyboardInterrupt:
+ raise y_exc.StackCreationInterrupt
+ except Exception:
+ LOG.exception("stack failed")
+ # let the other failures happen, we want stack trace
+ raise
+
+ def _retrieve_existing_stack(self, stack_name):
+ stack = HeatStack(stack_name)
+ if stack.get():
+ return stack
+ else:
+ LOG.warning("Stack %s does not exist", self.name)
+ return None
+
def deploy(self):
"""deploys template into a stack using cloud"""
LOG.info("Deploying context '%s' START", self.name)
+ self.key_filename = ''.join(
+ [consts.YARDSTICK_ROOT_PATH,
+ 'yardstick/resources/files/yardstick_key-',
+ self.name])
+ # Permissions may have changed since creation; this can be fixed. If we
+ # overwrite the file, we lose future access to VMs using this key.
+ # As long as the file exists, even if it is unreadable, keep it intact
+ if not os.path.exists(self.key_filename):
+ SSH.gen_keys(self.key_filename)
+
heat_template = HeatTemplate(self.name, self.template_file,
self.heat_parameters)
if self.template_file is None:
self._add_resources_to_template(heat_template)
- try:
- self.stack = heat_template.create(block=True,
- timeout=self.heat_timeout)
- except KeyboardInterrupt:
- raise SystemExit("\nStack create interrupted")
- except:
- LOG.exception("stack failed")
- # let the other failures happen, we want stack trace
- raise
+ if self._flags.no_setup:
+ # Try to get an existing stack, returns a stack or None
+ self.stack = self._retrieve_existing_stack(self.name)
+ if not self.stack:
+ self.stack = self._create_new_stack(heat_template)
+
+ else:
+ self.stack = self._create_new_stack(heat_template)
# TODO: use Neutron to get segmentation-id
self.get_neutron_info()
@@ -332,18 +357,35 @@ class HeatContext(Context):
LOG.info("Deploying context '%s' DONE", self.name)
+ @staticmethod
+ def _port_net_is_existing(port_info):
+ net_flags = port_info.get('net_flags', {})
+ return net_flags.get(consts.IS_EXISTING)
+
+ @staticmethod
+ def _port_net_is_public(port_info):
+ net_flags = port_info.get('net_flags', {})
+ return net_flags.get(consts.IS_PUBLIC)
+
def add_server_port(self, server):
- # use private ip from first port in first network
- try:
- private_port = next(iter(server.ports.values()))[0]
- except IndexError:
- LOG.exception("Unable to find first private port in %s", server.ports)
- raise
- server.private_ip = self.stack.outputs[private_port["stack_name"]]
+ server_ports = server.ports.values()
+ for server_port in server_ports:
+ port_info = server_port[0]
+ port_ip = self.stack.outputs[port_info["stack_name"]]
+ port_net_is_existing = self._port_net_is_existing(port_info)
+ port_net_is_public = self._port_net_is_public(port_info)
+ if port_net_is_existing and (port_net_is_public or
+ len(server_ports) == 1):
+ server.public_ip = port_ip
+ if not server.private_ip or len(server_ports) == 1:
+ server.private_ip = port_ip
+
server.interfaces = {}
for network_name, ports in server.ports.items():
for port in ports:
# port['port'] is either port name from mapping or default network_name
+ if self._port_net_is_existing(port):
+ continue
server.interfaces[port['port']] = self.make_interface_dict(network_name,
port['port'],
port['stack_name'],
@@ -380,20 +422,27 @@ class HeatContext(Context):
"local_ip": private_ip,
}
+ def _delete_key_file(self):
+ try:
+ utils.remove_file(self.key_filename)
+ utils.remove_file(self.key_filename + ".pub")
+ except OSError:
+ LOG.exception("There was an error removing the key file %s",
+ self.key_filename)
+
def undeploy(self):
"""undeploys stack from cloud"""
+ if self._flags.no_teardown:
+ LOG.info("Undeploying context '%s' SKIP", self.name)
+ return
+
if self.stack:
LOG.info("Undeploying context '%s' START", self.name)
self.stack.delete()
self.stack = None
LOG.info("Undeploying context '%s' DONE", 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)
+ self._delete_key_file()
super(HeatContext, self).undeploy()
@@ -429,13 +478,17 @@ class HeatContext(Context):
server.private_ip = self.stack.outputs.get(
attr_name.get("private_ip_attr", object()), None)
else:
- server = self._server_map.get(attr_name, None)
+ try:
+ server = self._server_map[attr_name]
+ except KeyError:
+ attr_name_no_suffix = attr_name.split("-")[0]
+ server = self._server_map.get(attr_name_no_suffix, None)
if server is None:
return None
pkey = pkg_resources.resource_string(
'yardstick.resources',
- h_join('files/yardstick_key', get_short_key_uuid(self.key_uuid))).decode('utf-8')
+ h_join('files/yardstick_key', self.name)).decode('utf-8')
result = {
"user": server.context.user,