Merge "Consider datastore version when generating configs"
This commit is contained in:
@@ -38,36 +38,53 @@ class SingleInstanceConfigTemplate(object):
|
||||
rendering on the guest
|
||||
"""
|
||||
|
||||
template_name = "%s/config.template"
|
||||
template_name = "config.template"
|
||||
|
||||
def __init__(self, datastore_manager, flavor_dict, instance_id):
|
||||
def __init__(self, datastore_version, flavor_dict, instance_id):
|
||||
"""Constructor
|
||||
|
||||
:param datastore_manager: The datastore manager.
|
||||
:type name: str.
|
||||
:param datastore_version: The datastore version.
|
||||
:type datastore_version: DatastoreVersion
|
||||
:param flavor_dict: dict containing flavor details for use in jinja.
|
||||
:type flavor_dict: dict.
|
||||
:param instance_id: trove instance id
|
||||
:type: instance_id: str
|
||||
:type instance_id: str
|
||||
|
||||
"""
|
||||
self.flavor_dict = flavor_dict
|
||||
template_filename = self.template_name % datastore_manager
|
||||
self.template = ENV.get_template(template_filename)
|
||||
self.datastore_manager = datastore_manager
|
||||
self.datastore_version = datastore_version
|
||||
#TODO(tim.simpson): The current definition of datastore_version is a
|
||||
# bit iffy and I believe will change soon, so I'm
|
||||
# creating a dictionary here for jinja to consume
|
||||
# rather than pass in the datastore version object.
|
||||
self.datastore_dict = {
|
||||
'name': self.datastore_version.datastore_name,
|
||||
'manager': self.datastore_version.manager,
|
||||
'version': self.datastore_version.name,
|
||||
}
|
||||
self.instance_id = instance_id
|
||||
|
||||
def get_template(self):
|
||||
patterns = ['{name}/{version}/{template_name}',
|
||||
'{name}/{template_name}',
|
||||
'{manager}/{template_name}']
|
||||
context = self.datastore_dict.copy()
|
||||
context['template_name'] = self.template_name
|
||||
names = [name.format(**context) for name in patterns]
|
||||
return ENV.select_template(names)
|
||||
|
||||
def render(self, **kwargs):
|
||||
"""Renders the jinja template
|
||||
|
||||
:returns: str -- The rendered configuration file
|
||||
|
||||
"""
|
||||
template = ENV.get_template(self.template_name %
|
||||
self.datastore_manager)
|
||||
template = self.get_template()
|
||||
server_id = self._calculate_unique_id()
|
||||
self.config_contents = template.render(
|
||||
flavor=self.flavor_dict, server_id=server_id, **kwargs)
|
||||
flavor=self.flavor_dict,
|
||||
datastore=self.datastore_dict,
|
||||
server_id=server_id, **kwargs)
|
||||
return self.config_contents
|
||||
|
||||
def render_dict(self):
|
||||
@@ -76,10 +93,10 @@ class SingleInstanceConfigTemplate(object):
|
||||
to apply the default configuration dynamically.
|
||||
"""
|
||||
config = self.render()
|
||||
cfg_parser = SERVICE_PARSERS.get(self.datastore_manager)
|
||||
cfg_parser = SERVICE_PARSERS.get(self.datastore_version.manager)
|
||||
if not cfg_parser:
|
||||
raise exception.NoConfigParserFound(
|
||||
datastore_manager=self.datastore_manager)
|
||||
datastore_manager=self.datastore_version.manager)
|
||||
return cfg_parser(config).parse()
|
||||
|
||||
def _calculate_unique_id(self):
|
||||
@@ -92,7 +109,7 @@ class SingleInstanceConfigTemplate(object):
|
||||
|
||||
|
||||
class OverrideConfigTemplate(SingleInstanceConfigTemplate):
|
||||
template_name = "%s/override.config.template"
|
||||
template_name = "override.config.template"
|
||||
|
||||
|
||||
def load_heat_template(datastore_manager):
|
||||
|
||||
@@ -97,6 +97,7 @@ class DatastoreVersion(object):
|
||||
|
||||
def __init__(self, db_info):
|
||||
self.db_info = db_info
|
||||
self._datastore_name = None
|
||||
|
||||
@classmethod
|
||||
def load(cls, datastore, id_or_name):
|
||||
@@ -127,6 +128,14 @@ class DatastoreVersion(object):
|
||||
def datastore_id(self):
|
||||
return self.db_info.datastore_id
|
||||
|
||||
@property
|
||||
def datastore_name(self):
|
||||
if self._datastore_name is None:
|
||||
self._datastore_name = Datastore.load(self.datastore_id).name
|
||||
return self._datastore_name
|
||||
|
||||
#TODO(tim.simpson): This would be less confusing if it was called "version"
|
||||
# and datastore_name was called "name".
|
||||
@property
|
||||
def name(self):
|
||||
return self.db_info.name
|
||||
|
||||
@@ -707,7 +707,7 @@ class Instance(BuiltInstance):
|
||||
flavor = self.get_flavor()
|
||||
LOG.debug("flavor: %s" % flavor)
|
||||
config = template.SingleInstanceConfigTemplate(
|
||||
self.ds_version.manager, flavor, id)
|
||||
self.ds_version, flavor, id)
|
||||
return config.render_dict()
|
||||
|
||||
def resize_flavor(self, new_flavor_id):
|
||||
|
||||
@@ -139,22 +139,21 @@ class ConfigurationMixin(object):
|
||||
Configuration related tasks for instances and resizes.
|
||||
"""
|
||||
|
||||
def _render_config(self, datastore_manager, flavor, instance_id):
|
||||
def _render_config(self, flavor):
|
||||
config = template.SingleInstanceConfigTemplate(
|
||||
datastore_manager, flavor, instance_id)
|
||||
self.datastore_version, flavor, self.id)
|
||||
config.render()
|
||||
return config
|
||||
|
||||
def _render_override_config(self, datastore_manager, flavor, instance_id,
|
||||
overrides=None):
|
||||
def _render_override_config(self, flavor, overrides=None):
|
||||
config = template.OverrideConfigTemplate(
|
||||
datastore_manager, flavor, instance_id)
|
||||
self.datastore_version, flavor, self.id)
|
||||
config.render(overrides=overrides)
|
||||
return config
|
||||
|
||||
def _render_config_dict(self, datastore_manager, flavor, instance_id):
|
||||
def _render_config_dict(self, flavor):
|
||||
config = template.SingleInstanceConfigTemplate(
|
||||
datastore_manager, flavor, instance_id)
|
||||
self.datastore_version, flavor, self.id)
|
||||
ret = config.render_dict()
|
||||
LOG.debug("the default template dict of mysqld section: %s" % ret)
|
||||
return ret
|
||||
@@ -213,10 +212,8 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
availability_zone,
|
||||
nics)
|
||||
|
||||
config = self._render_config(datastore_manager, flavor, self.id)
|
||||
config_overrides = self._render_override_config(datastore_manager,
|
||||
None,
|
||||
self.id,
|
||||
config = self._render_config(flavor)
|
||||
config_overrides = self._render_override_config(flavor,
|
||||
overrides=overrides)
|
||||
|
||||
backup_info = None
|
||||
@@ -823,10 +820,10 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
|
||||
status = inst_models.InstanceTasks.RESTART_REQUIRED
|
||||
self.update_db(task_status=status)
|
||||
|
||||
flavor = self.nova_client.flavors.get(self.flavor_id)
|
||||
|
||||
config_overrides = self._render_override_config(
|
||||
self.ds_version.manager,
|
||||
None,
|
||||
self.id,
|
||||
flavor,
|
||||
overrides=overrides)
|
||||
try:
|
||||
self.guest.update_overrides(config_overrides.config_contents,
|
||||
@@ -864,9 +861,7 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
|
||||
}
|
||||
return str(int(digits) * conversions[size])
|
||||
|
||||
default_config = self._render_config_dict(self.ds_version.manager,
|
||||
flavor,
|
||||
self.id)
|
||||
default_config = self._render_config_dict(flavor)
|
||||
args = {
|
||||
"ds_manager": self.ds_version.manager,
|
||||
"config": default_config,
|
||||
@@ -976,7 +971,7 @@ class BackupTasks(object):
|
||||
backup.delete()
|
||||
|
||||
|
||||
class ResizeVolumeAction(ConfigurationMixin):
|
||||
class ResizeVolumeAction(object):
|
||||
"""Performs volume resize action."""
|
||||
|
||||
def __init__(self, instance, old_size, new_size):
|
||||
@@ -1200,7 +1195,7 @@ class ResizeVolumeAction(ConfigurationMixin):
|
||||
raise TroveError(msg)
|
||||
|
||||
|
||||
class ResizeActionBase(ConfigurationMixin):
|
||||
class ResizeActionBase(object):
|
||||
"""Base class for executing a resize action."""
|
||||
|
||||
def __init__(self, instance):
|
||||
@@ -1385,11 +1380,7 @@ class ResizeAction(ResizeActionBase):
|
||||
% self.instance.id)
|
||||
LOG.debug("Repairing config.")
|
||||
try:
|
||||
config = self._render_config(
|
||||
self.instance.datastore_version.manager,
|
||||
self.old_flavor,
|
||||
self.instance.id
|
||||
)
|
||||
config = self.instance._render_config(self.old_flavor)
|
||||
config = {'config_contents': config.config_contents}
|
||||
self.instance.guest.reset_configuration(config)
|
||||
except GuestTimeout:
|
||||
@@ -1411,8 +1402,7 @@ class ResizeAction(ResizeActionBase):
|
||||
server=self.instance.server)
|
||||
|
||||
def _start_datastore(self):
|
||||
config = self._render_config(self.instance.datastore_version.manager,
|
||||
self.new_flavor, self.instance.id)
|
||||
config = self.instance._render_config(self.new_flavor)
|
||||
self.instance.guest.start_db_with_conf_changes(config.config_contents)
|
||||
|
||||
|
||||
|
||||
1
trove/templates/mysql/mysql-test/config.template
Normal file
1
trove/templates/mysql/mysql-test/config.template
Normal file
@@ -0,0 +1 @@
|
||||
hyper = 0M
|
||||
@@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import mox
|
||||
from mock import Mock
|
||||
from testtools import TestCase
|
||||
from proboscis import test
|
||||
|
||||
@@ -25,6 +26,7 @@ from trove.common import template
|
||||
from trove.common import utils
|
||||
from trove.common.context import TroveContext
|
||||
from trove.common import instance as rd_instance
|
||||
from trove.datastore.models import DatastoreVersion
|
||||
from trove.guestagent import api as guest
|
||||
from trove.instance.models import DBInstance
|
||||
from trove.instance.models import InstanceServiceStatus
|
||||
@@ -120,8 +122,12 @@ class ResizeTests(ResizeTestBase):
|
||||
NEW_FLAVOR.__dict__)
|
||||
|
||||
def _start_mysql(self):
|
||||
datastore = Mock(spec=DatastoreVersion)
|
||||
datastore.datastore_name = 'mysql'
|
||||
datastore.name = 'mysql-5.6'
|
||||
datastore.manager = 'mysql'
|
||||
config = template.SingleInstanceConfigTemplate(
|
||||
"mysql", NEW_FLAVOR.__dict__, self.instance.id)
|
||||
datastore, NEW_FLAVOR.__dict__, self.instance.id)
|
||||
self.instance.guest.start_db_with_conf_changes(config.render())
|
||||
|
||||
def test_guest_wont_stop_mysql(self):
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
#limitations under the License.
|
||||
|
||||
|
||||
from mock import Mock
|
||||
import testtools
|
||||
import re
|
||||
|
||||
from trove.common import template
|
||||
from trove.common import exception
|
||||
from trove.datastore.models import DatastoreVersion
|
||||
from trove.tests.unittests.util import util
|
||||
|
||||
|
||||
@@ -25,7 +27,7 @@ class TemplateTest(testtools.TestCase):
|
||||
util.init_db()
|
||||
self.env = template.ENV
|
||||
self.template = self.env.get_template("mysql/config.template")
|
||||
self.flavor_dict = {'ram': 1024}
|
||||
self.flavor_dict = {'ram': 1024, 'name': 'small', 'id': '55'}
|
||||
self.server_id = "180b5ed1-3e57-4459-b7a3-2aeee4ac012a"
|
||||
|
||||
def tearDown(self):
|
||||
@@ -56,12 +58,28 @@ class TemplateTest(testtools.TestCase):
|
||||
self.server_id)
|
||||
|
||||
def test_single_instance_config_rendering(self):
|
||||
config = template.SingleInstanceConfigTemplate('mysql',
|
||||
datastore = Mock(spec=DatastoreVersion)
|
||||
datastore.datastore_name = 'MySql'
|
||||
datastore.name = 'mysql-5.6'
|
||||
datastore.manager = 'mysql'
|
||||
config = template.SingleInstanceConfigTemplate(datastore,
|
||||
self.flavor_dict,
|
||||
self.server_id)
|
||||
self.validate_template(config.render(), "query_cache_size",
|
||||
self.flavor_dict, self.server_id)
|
||||
|
||||
def test_renderer_discovers_special_config(self):
|
||||
"""Finds our special config file for the version 'mysql-test'."""
|
||||
datastore = Mock(spec=DatastoreVersion)
|
||||
datastore.datastore_name = 'mysql'
|
||||
datastore.name = 'mysql-test'
|
||||
datastore.manager = 'mysql'
|
||||
config = template.SingleInstanceConfigTemplate(datastore,
|
||||
self.flavor_dict,
|
||||
self.server_id)
|
||||
self.validate_template(config.render(), "hyper",
|
||||
{'ram': 0}, self.server_id)
|
||||
|
||||
|
||||
class HeatTemplateLoadTest(testtools.TestCase):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user