Merge "Allow Juju AZ context information to be used"
This commit is contained in:
commit
81598e4d94
31
README.md
31
README.md
@ -43,6 +43,37 @@ different cephx keys and user names.
|
|||||||
See LP Bug [#1671422](https://bugs.launchpad.net/charm-cinder-ceph/+bug/1671422)
|
See LP Bug [#1671422](https://bugs.launchpad.net/charm-cinder-ceph/+bug/1671422)
|
||||||
for more information.
|
for more information.
|
||||||
|
|
||||||
|
Availability Zones
|
||||||
|
==================
|
||||||
|
|
||||||
|
There are two options to provide default_availability_zone config
|
||||||
|
for nova nodes:
|
||||||
|
|
||||||
|
- default-availability-zone
|
||||||
|
- customize-failure-domain
|
||||||
|
|
||||||
|
The order of precedence is as follows:
|
||||||
|
|
||||||
|
1. Information from a Juju provider (JUJU_AVAILABILITY_ZONE)
|
||||||
|
if customize-failure-domain is set to True and Juju
|
||||||
|
has set the JUJU_AVAILABILITY_ZONE to a non-empty value;
|
||||||
|
2. The value of default-availability-zone will be used
|
||||||
|
if customize-failure-domain is set to True but no
|
||||||
|
JUJU_AVAILABILITY_ZONE is provided via hook
|
||||||
|
context by the Juju provider;
|
||||||
|
3. Otherwise, the value of default-availability-zone
|
||||||
|
charm option will be used.
|
||||||
|
|
||||||
|
The default_availability_zone in Nova affects scheduling if a
|
||||||
|
given Nova node was not placed into an aggregate with an
|
||||||
|
availability zone present as a property by an operator. Using
|
||||||
|
customize-failure-domain is recommended as it provides AZ-aware
|
||||||
|
scheduling out of the box if an operator specifies an AZ during
|
||||||
|
instance creation.
|
||||||
|
|
||||||
|
These options also affect the AZ propagated down to networking
|
||||||
|
subordinates which is useful for AZ-aware Neutron agent scheduling.
|
||||||
|
|
||||||
NFV support
|
NFV support
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
15
config.yaml
15
config.yaml
@ -373,11 +373,24 @@ options:
|
|||||||
.
|
.
|
||||||
This option determines the availability zone to be used when it is not
|
This option determines the availability zone to be used when it is not
|
||||||
specified in the VM creation request. If this option is not set, the
|
specified in the VM creation request. If this option is not set, the
|
||||||
default availability zone 'nova' is used.
|
default availability zone 'nova' is used. If customize-failure-domain
|
||||||
|
is set to True, it will override this option only if an AZ is set by
|
||||||
|
the Juju provider. If JUJU_AVAILABILITY_ZONE is not set, the value
|
||||||
|
specified by this option will be used regardless of
|
||||||
|
customize-failure-domain's setting.
|
||||||
.
|
.
|
||||||
NOTE: Availability zones must be created manually using the
|
NOTE: Availability zones must be created manually using the
|
||||||
'openstack aggregate create' command.
|
'openstack aggregate create' command.
|
||||||
.
|
.
|
||||||
|
customize-failure-domain:
|
||||||
|
type: boolean
|
||||||
|
default: False
|
||||||
|
description: |
|
||||||
|
Juju propagates availability zone information to charms from the
|
||||||
|
underlying machine provider such as MAAS and this option allows the
|
||||||
|
charm to use JUJU_AVAILABILITY_ZONE to set default_availability_zone for
|
||||||
|
Nova nodes. This option overrides the default-availability-zone charm
|
||||||
|
config setting only when the Juju provider sets JUJU_AVAILABILITY_ZONE.
|
||||||
resume-guests-state-on-host-boot:
|
resume-guests-state-on-host-boot:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: False
|
default: False
|
||||||
|
@ -51,6 +51,7 @@ from charmhelpers.contrib.network.ip import (
|
|||||||
get_relation_ip,
|
get_relation_ip,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# This is just a label and it must be consistent across
|
# This is just a label and it must be consistent across
|
||||||
# nova-compute nodes to support live migration.
|
# nova-compute nodes to support live migration.
|
||||||
CEPH_SECRET_UUID = '514c9fca-8cbe-11e2-9c52-3bc8c7819472'
|
CEPH_SECRET_UUID = '514c9fca-8cbe-11e2-9c52-3bc8c7819472'
|
||||||
@ -86,6 +87,11 @@ def _network_manager():
|
|||||||
return manager()
|
return manager()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_availability_zone():
|
||||||
|
from nova_compute_utils import get_availability_zone as get_az
|
||||||
|
return get_az()
|
||||||
|
|
||||||
|
|
||||||
def _neutron_security_groups():
|
def _neutron_security_groups():
|
||||||
'''
|
'''
|
||||||
Inspects current cloud-compute relation and determine if nova-c-c has
|
Inspects current cloud-compute relation and determine if nova-c-c has
|
||||||
@ -722,7 +728,5 @@ class NovaComputeAvailabilityZoneContext(context.OSContextGenerator):
|
|||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
if config('default-availability-zone'):
|
ctxt['default_availability_zone'] = _get_availability_zone()
|
||||||
ctxt['default_availability_zone'] = config(
|
|
||||||
'default-availability-zone')
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
@ -109,6 +109,7 @@ from nova_compute_utils import (
|
|||||||
configure_local_ephemeral_storage,
|
configure_local_ephemeral_storage,
|
||||||
pause_unit_helper,
|
pause_unit_helper,
|
||||||
resume_unit_helper,
|
resume_unit_helper,
|
||||||
|
get_availability_zone,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.network.ip import (
|
from charmhelpers.contrib.network.ip import (
|
||||||
@ -464,7 +465,7 @@ def update_nrpe_config():
|
|||||||
def neutron_plugin_joined(relid=None, remote_restart=False):
|
def neutron_plugin_joined(relid=None, remote_restart=False):
|
||||||
rel_settings = {
|
rel_settings = {
|
||||||
'hugepage_number': get_hugepage_number(),
|
'hugepage_number': get_hugepage_number(),
|
||||||
'default_availability_zone': config('default-availability-zone')
|
'default_availability_zone': get_availability_zone()
|
||||||
}
|
}
|
||||||
if remote_restart:
|
if remote_restart:
|
||||||
rel_settings['restart-trigger'] = str(uuid.uuid4())
|
rel_settings['restart-trigger'] = str(uuid.uuid4())
|
||||||
|
@ -942,3 +942,10 @@ def configure_local_ephemeral_storage():
|
|||||||
# storage is never reconfigured by mistake, losing instance disks
|
# storage is never reconfigured by mistake, losing instance disks
|
||||||
db.set('storage-configured', True)
|
db.set('storage-configured', True)
|
||||||
db.flush()
|
db.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def get_availability_zone():
|
||||||
|
use_juju_az = config('customize-failure-domain')
|
||||||
|
juju_az = os.environ.get('JUJU_AVAILABILITY_ZONE')
|
||||||
|
return (juju_az if use_juju_az and juju_az
|
||||||
|
else config('default-availability-zone'))
|
||||||
|
@ -563,3 +563,68 @@ class SerialConsoleContextTests(CharmTestCase):
|
|||||||
'host_uuid': self.host_uuid,
|
'host_uuid': self.host_uuid,
|
||||||
'force_raw_images': True,
|
'force_raw_images': True,
|
||||||
'reserved_host_memory': 512}, libvirt())
|
'reserved_host_memory': 512}, libvirt())
|
||||||
|
|
||||||
|
|
||||||
|
class NovaComputeAvailabilityZoneContextTests(CharmTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(NovaComputeAvailabilityZoneContextTests,
|
||||||
|
self).setUp(context, TO_PATCH)
|
||||||
|
self.os_release.return_value = 'kilo'
|
||||||
|
|
||||||
|
@patch('nova_compute_utils.config')
|
||||||
|
@patch('os.environ.get')
|
||||||
|
def test_availability_zone_no_juju_with_env(self, mock_get,
|
||||||
|
mock_config):
|
||||||
|
def environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': 'az1',
|
||||||
|
}[key]
|
||||||
|
mock_get.side_effect = environ_get_side_effect
|
||||||
|
|
||||||
|
def config_side_effect(key):
|
||||||
|
return {
|
||||||
|
'customize-failure-domain': False,
|
||||||
|
'default-availability-zone': 'nova',
|
||||||
|
}[key]
|
||||||
|
|
||||||
|
mock_config.side_effect = config_side_effect
|
||||||
|
az_context = context.NovaComputeAvailabilityZoneContext()
|
||||||
|
self.assertEqual(
|
||||||
|
{'default_availability_zone': 'nova'}, az_context())
|
||||||
|
|
||||||
|
@patch('nova_compute_utils.config')
|
||||||
|
@patch('os.environ.get')
|
||||||
|
def test_availability_zone_no_juju_no_env(self, mock_get,
|
||||||
|
mock_config):
|
||||||
|
def environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': '',
|
||||||
|
}[key]
|
||||||
|
mock_get.side_effect = environ_get_side_effect
|
||||||
|
|
||||||
|
def config_side_effect(key):
|
||||||
|
return {
|
||||||
|
'customize-failure-domain': False,
|
||||||
|
'default-availability-zone': 'nova',
|
||||||
|
}[key]
|
||||||
|
|
||||||
|
mock_config.side_effect = config_side_effect
|
||||||
|
az_context = context.NovaComputeAvailabilityZoneContext()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
{'default_availability_zone': 'nova'}, az_context())
|
||||||
|
|
||||||
|
@patch('os.environ.get')
|
||||||
|
def test_availability_zone_juju(self, mock_get):
|
||||||
|
def environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': 'az1',
|
||||||
|
}[key]
|
||||||
|
mock_get.side_effect = environ_get_side_effect
|
||||||
|
|
||||||
|
self.config.side_effect = self.test_config.get
|
||||||
|
self.test_config.set('customize-failure-domain', True)
|
||||||
|
az_context = context.NovaComputeAvailabilityZoneContext()
|
||||||
|
self.assertEqual(
|
||||||
|
{'default_availability_zone': 'az1'}, az_context())
|
||||||
|
@ -542,6 +542,29 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
**expect_rel_settings
|
**expect_rel_settings
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch('os.environ.get')
|
||||||
|
@patch.object(hooks, 'get_hugepage_number')
|
||||||
|
def test_neutron_plugin_joined_relid_juju_az(self,
|
||||||
|
get_hugepage_number,
|
||||||
|
mock_env_get):
|
||||||
|
self.test_config.set('customize-failure-domain', True)
|
||||||
|
|
||||||
|
def environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': 'az1',
|
||||||
|
}[key]
|
||||||
|
mock_env_get.side_effect = environ_get_side_effect
|
||||||
|
get_hugepage_number.return_value = None
|
||||||
|
hooks.neutron_plugin_joined(relid='relid23')
|
||||||
|
expect_rel_settings = {
|
||||||
|
'hugepage_number': None,
|
||||||
|
'default_availability_zone': 'az1',
|
||||||
|
}
|
||||||
|
self.relation_set.assert_called_with(
|
||||||
|
relation_id='relid23',
|
||||||
|
**expect_rel_settings
|
||||||
|
)
|
||||||
|
|
||||||
@patch.object(hooks, 'get_hugepage_number')
|
@patch.object(hooks, 'get_hugepage_number')
|
||||||
def test_neutron_plugin_joined_huge(self, get_hugepage_number):
|
def test_neutron_plugin_joined_huge(self, get_hugepage_number):
|
||||||
get_hugepage_number.return_value = 12
|
get_hugepage_number.return_value = 12
|
||||||
|
@ -981,3 +981,55 @@ class NovaComputeUtilsTests(CharmTestCase):
|
|||||||
priority=80
|
priority=80
|
||||||
)
|
)
|
||||||
self.is_block_device.assert_not_called()
|
self.is_block_device.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(utils.os.environ, 'get')
|
||||||
|
def test_get_az_customize_with_env(self, os_environ_get_mock):
|
||||||
|
self.test_config.set('customize-failure-domain', True)
|
||||||
|
self.test_config.set('default-availability-zone', 'nova')
|
||||||
|
|
||||||
|
def os_environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': 'az1',
|
||||||
|
}[key]
|
||||||
|
os_environ_get_mock.side_effect = os_environ_get_side_effect
|
||||||
|
az = utils.get_availability_zone()
|
||||||
|
self.assertEqual('az1', az)
|
||||||
|
|
||||||
|
@patch.object(utils.os.environ, 'get')
|
||||||
|
def test_get_az_customize_without_env(self, os_environ_get_mock):
|
||||||
|
self.test_config.set('customize-failure-domain', True)
|
||||||
|
self.test_config.set('default-availability-zone', 'mynova')
|
||||||
|
|
||||||
|
def os_environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': '',
|
||||||
|
}[key]
|
||||||
|
os_environ_get_mock.side_effect = os_environ_get_side_effect
|
||||||
|
az = utils.get_availability_zone()
|
||||||
|
self.assertEqual('mynova', az)
|
||||||
|
|
||||||
|
@patch.object(utils.os.environ, 'get')
|
||||||
|
def test_get_az_no_customize_without_env(self, os_environ_get_mock):
|
||||||
|
self.test_config.set('customize-failure-domain', False)
|
||||||
|
self.test_config.set('default-availability-zone', 'nova')
|
||||||
|
|
||||||
|
def os_environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': '',
|
||||||
|
}[key]
|
||||||
|
os_environ_get_mock.side_effect = os_environ_get_side_effect
|
||||||
|
az = utils.get_availability_zone()
|
||||||
|
self.assertEqual('nova', az)
|
||||||
|
|
||||||
|
@patch.object(utils.os.environ, 'get')
|
||||||
|
def test_get_az_no_customize_with_env(self, os_environ_get_mock):
|
||||||
|
self.test_config.set('customize-failure-domain', False)
|
||||||
|
self.test_config.set('default-availability-zone', 'nova')
|
||||||
|
|
||||||
|
def os_environ_get_side_effect(key):
|
||||||
|
return {
|
||||||
|
'JUJU_AVAILABILITY_ZONE': 'az1',
|
||||||
|
}[key]
|
||||||
|
os_environ_get_mock.side_effect = os_environ_get_side_effect
|
||||||
|
az = utils.get_availability_zone()
|
||||||
|
self.assertEqual('nova', az)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user