Merge "Add ratio online data migration when load compute node"
This commit is contained in:
commit
45415e5792
@ -173,6 +173,7 @@ class ComputeNode(base.NovaPersistentObject, base.NovaObject):
|
||||
'pci_device_pools',
|
||||
])
|
||||
fields = set(compute.fields) - special_cases
|
||||
online_updates = {}
|
||||
for key in fields:
|
||||
value = db_compute[key]
|
||||
# NOTE(sbauza): Since all compute nodes don't possibly run the
|
||||
@ -184,36 +185,31 @@ class ComputeNode(base.NovaPersistentObject, base.NovaObject):
|
||||
# the next release (Newton) where the opt default values will be
|
||||
# restored for both cpu (16.0), ram (1.5) and disk (1.0)
|
||||
# allocation ratios.
|
||||
# TODO(sbauza): Remove that in the next major version bump where
|
||||
# we break compatibility with old Liberty computes
|
||||
if (key == 'cpu_allocation_ratio' or key == 'ram_allocation_ratio'
|
||||
or key == 'disk_allocation_ratio'):
|
||||
if value == 0.0:
|
||||
# Operator has not yet provided a new value for that ratio
|
||||
# on the compute node
|
||||
value = None
|
||||
if value is None:
|
||||
# ResourceTracker is not updating the value (old node)
|
||||
# or the compute node is updated but the default value has
|
||||
# not been changed
|
||||
value = getattr(CONF, key)
|
||||
if value in (0.0, None) \
|
||||
and key == 'cpu_allocation_ratio':
|
||||
# It's not specified either on the controller
|
||||
value = 16.0
|
||||
if value in (0.0, None) \
|
||||
and key == 'ram_allocation_ratio':
|
||||
# It's not specified either on the controller
|
||||
value = 1.5
|
||||
if value in (0.0, None) \
|
||||
and key == 'disk_allocation_ratio':
|
||||
# It's not specified either on the controller
|
||||
value = 1.0
|
||||
# TODO(yikun): Remove this online migration code when all ratio
|
||||
# values are NOT 0.0 or NULL
|
||||
ratio_keys = ['cpu_allocation_ratio', 'ram_allocation_ratio',
|
||||
'disk_allocation_ratio']
|
||||
if key in ratio_keys and value in (None, 0.0):
|
||||
# ResourceTracker is not updating the value (old node)
|
||||
# or the compute node is updated but the default value has
|
||||
# not been changed
|
||||
r = getattr(CONF, key)
|
||||
# NOTE(yikun): If the allocation ratio record is not set, the
|
||||
# allocation ratio will be changed to the
|
||||
# CONF.x_allocation_ratio value if x_allocation_ratio is
|
||||
# set, and fallback to use the CONF.initial_x_allocation_ratio
|
||||
# otherwise.
|
||||
init_x_ratio = getattr(CONF, 'initial_%s' % key)
|
||||
value = r if r else init_x_ratio
|
||||
online_updates[key] = value
|
||||
elif key == 'mapped':
|
||||
value = 0 if value is None else value
|
||||
|
||||
setattr(compute, key, value)
|
||||
|
||||
if online_updates:
|
||||
db.compute_node_update(context, compute.id, online_updates)
|
||||
|
||||
stats = db_compute['stats']
|
||||
if stats:
|
||||
compute.stats = jsonutils.loads(stats)
|
||||
|
@ -11,11 +11,15 @@
|
||||
# under the License.
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
|
||||
import nova.conf
|
||||
from nova import context
|
||||
from nova.db import api as db
|
||||
from nova import objects
|
||||
from nova.objects import fields as obj_fields
|
||||
from nova import test
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
_HOSTNAME = 'fake-host'
|
||||
_NODENAME = 'fake-node'
|
||||
|
||||
@ -76,6 +80,33 @@ class ComputeNodeTestCase(test.TestCase):
|
||||
super(ComputeNodeTestCase, self).setUp()
|
||||
self.context = context.RequestContext('fake-user', 'fake-project')
|
||||
|
||||
def _create_zero_and_none_cn(self):
|
||||
cn1 = fake_compute_obj.obj_clone()
|
||||
cn1._context = self.context
|
||||
cn1.create()
|
||||
|
||||
db.compute_node_update(self.context, cn1.id,
|
||||
{'cpu_allocation_ratio': 0.0,
|
||||
'disk_allocation_ratio': 0.0,
|
||||
'ram_allocation_ratio': 0.0})
|
||||
cn1_db = db.compute_node_get(self.context, cn1.id)
|
||||
for x in ['cpu', 'disk', 'ram']:
|
||||
self.assertEqual(0.0, cn1_db['%s_allocation_ratio' % x])
|
||||
|
||||
cn2 = fake_compute_obj.obj_clone()
|
||||
cn2._context = self.context
|
||||
cn2.host += '-alt'
|
||||
cn2.create()
|
||||
# We can't set a cn_obj.xxx_allocation_ratio to None,
|
||||
# so we set ratio to None in db directly
|
||||
db.compute_node_update(self.context, cn2.id,
|
||||
{'cpu_allocation_ratio': None,
|
||||
'disk_allocation_ratio': None,
|
||||
'ram_allocation_ratio': None})
|
||||
cn2_db = db.compute_node_get(self.context, cn2.id)
|
||||
for x in ['cpu', 'disk', 'ram']:
|
||||
self.assertIsNone(None, cn2_db['%s_allocation_ratio' % x])
|
||||
|
||||
def test_get_all_by_uuids(self):
|
||||
cn1 = fake_compute_obj.obj_clone()
|
||||
cn1._context = self.context
|
||||
@ -135,3 +166,25 @@ class ComputeNodeTestCase(test.TestCase):
|
||||
'ironic')
|
||||
self.assertEqual(1, len(cns))
|
||||
self.assertEqual(cn1.uuid, cns[0].uuid)
|
||||
|
||||
def test_ratio_online_migration_when_load(self):
|
||||
# set cpu and disk, and leave ram unset(None)
|
||||
self.flags(cpu_allocation_ratio=1.0)
|
||||
self.flags(disk_allocation_ratio=2.0)
|
||||
|
||||
self._create_zero_and_none_cn()
|
||||
|
||||
# trigger online migration
|
||||
objects.ComputeNodeList.get_all(self.context)
|
||||
|
||||
cns = db.compute_node_get_all(self.context)
|
||||
|
||||
for cn in cns:
|
||||
# the cpu/disk ratio is refreshed to CONF.xxx_allocation_ratio
|
||||
self.assertEqual(CONF.cpu_allocation_ratio,
|
||||
cn['cpu_allocation_ratio'])
|
||||
self.assertEqual(CONF.disk_allocation_ratio,
|
||||
cn['disk_allocation_ratio'])
|
||||
# the ram ratio is refreshed to CONF.initial_xxx_allocation_ratio
|
||||
self.assertEqual(CONF.initial_ram_allocation_ratio,
|
||||
cn['ram_allocation_ratio'])
|
||||
|
@ -654,7 +654,6 @@ class TestUpgradeCheckResourceProviders(test.NoDBTestCase):
|
||||
# create a deleted compute node record (shouldn't count)
|
||||
cn2 = objects.ComputeNode(
|
||||
context=ctxt,
|
||||
deleted=1,
|
||||
host='fakehost',
|
||||
vcpus=4,
|
||||
memory_mb=8 * 1024,
|
||||
@ -666,6 +665,7 @@ class TestUpgradeCheckResourceProviders(test.NoDBTestCase):
|
||||
hypervisor_version=1,
|
||||
cpu_info='{"arch": "x86_64"}')
|
||||
cn2.create()
|
||||
cn2.destroy()
|
||||
|
||||
# create a single resource provider with some VCPU inventory
|
||||
self._create_resource_provider(FAKE_VCPU_INVENTORY)
|
||||
|
@ -22,6 +22,7 @@ from oslo_utils import timeutils
|
||||
from oslo_versionedobjects import base as ovo_base
|
||||
from oslo_versionedobjects import exception as ovo_exc
|
||||
|
||||
from nova import conf
|
||||
from nova.db import api as db
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
@ -131,6 +132,8 @@ fake_compute_with_resources = objects.ComputeNode(
|
||||
supported_hv_specs=fake_supported_hv_specs,
|
||||
)
|
||||
|
||||
CONF = conf.CONF
|
||||
|
||||
|
||||
class _TestComputeNodeObject(object):
|
||||
def supported_hv_specs_comparator(self, expected, obj_val):
|
||||
@ -550,7 +553,13 @@ class _TestComputeNodeObject(object):
|
||||
primitive = compute.obj_to_primitive(target_version='1.15')
|
||||
self.assertNotIn('disk_allocation_ratio', primitive)
|
||||
|
||||
def test_compat_allocation_ratios_old_compute(self):
|
||||
@mock.patch('nova.db.api.compute_node_update')
|
||||
def test_compat_allocation_ratios_old_compute(self, mock_update):
|
||||
"""Tests the scenario that allocation ratios are overridden in config
|
||||
and the legacy compute node record from the database has None set for
|
||||
the allocation ratio values. The result is that the migrated record
|
||||
allocation ratios should reflect the config overrides.
|
||||
"""
|
||||
self.flags(cpu_allocation_ratio=2.0, ram_allocation_ratio=3.0,
|
||||
disk_allocation_ratio=0.9)
|
||||
compute_dict = fake_compute_node.copy()
|
||||
@ -565,7 +574,19 @@ class _TestComputeNodeObject(object):
|
||||
self.assertEqual(3.0, compute.ram_allocation_ratio)
|
||||
self.assertEqual(0.9, compute.disk_allocation_ratio)
|
||||
|
||||
def test_compat_allocation_ratios_zero_conf(self):
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, 123, {'cpu_allocation_ratio': 2.0,
|
||||
'ram_allocation_ratio': 3.0,
|
||||
'disk_allocation_ratio': 0.9})
|
||||
|
||||
@mock.patch('nova.db.api.compute_node_update')
|
||||
def test_compat_allocation_ratios_zero_conf(self, mock_update):
|
||||
"""Tests that the override allocation ratios are set to 0.0 for
|
||||
whatever reason (maybe an old nova.conf sample file is being used)
|
||||
and the legacy compute node record has None for allocation ratios,
|
||||
so the resulting data migration makes the record allocation ratios
|
||||
use the CONF.initial_*_allocation_ratio values.
|
||||
"""
|
||||
self.flags(cpu_allocation_ratio=0.0, ram_allocation_ratio=0.0,
|
||||
disk_allocation_ratio=0.0)
|
||||
compute_dict = fake_compute_node.copy()
|
||||
@ -576,11 +597,25 @@ class _TestComputeNodeObject(object):
|
||||
cls = objects.ComputeNode
|
||||
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
||||
|
||||
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
||||
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_cpu_allocation_ratio, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_ram_allocation_ratio, compute.ram_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_disk_allocation_ratio, compute.disk_allocation_ratio)
|
||||
|
||||
def test_compat_allocation_ratios_None_conf_zero_values(self):
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, 123, {'cpu_allocation_ratio': 16.0,
|
||||
'ram_allocation_ratio': 1.5,
|
||||
'disk_allocation_ratio': 1.0})
|
||||
|
||||
@mock.patch('nova.db.api.compute_node_update')
|
||||
def test_compat_allocation_ratios_None_conf_zero_values(self, mock_update):
|
||||
"""Tests the scenario that the CONF.*_allocation_ratio overrides are
|
||||
left to the default (None) and the compute node record allocation
|
||||
ratio values in the DB are 0.0, so they will be migrated to the
|
||||
CONF.initial_*_allocation_ratio values.
|
||||
"""
|
||||
# the CONF.x_allocation_ratio is None by default
|
||||
compute_dict = fake_compute_node.copy()
|
||||
# the computes provide allocation ratios 0.0
|
||||
@ -590,11 +625,25 @@ class _TestComputeNodeObject(object):
|
||||
cls = objects.ComputeNode
|
||||
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
||||
|
||||
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
||||
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_cpu_allocation_ratio, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_ram_allocation_ratio, compute.ram_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_disk_allocation_ratio, compute.disk_allocation_ratio)
|
||||
|
||||
def test_compat_allocation_ratios_None_conf_None_values(self):
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, 123, {'cpu_allocation_ratio': 16.0,
|
||||
'ram_allocation_ratio': 1.5,
|
||||
'disk_allocation_ratio': 1.0})
|
||||
|
||||
@mock.patch('nova.db.api.compute_node_update')
|
||||
def test_compat_allocation_ratios_None_conf_None_values(self, mock_update):
|
||||
"""Tests the scenario that the override CONF.*_allocation_ratio options
|
||||
are the default values (None), the compute node record from the DB has
|
||||
None values for allocation ratios, so the resulting migrated record
|
||||
will have the CONF.initial_*_allocation_ratio values.
|
||||
"""
|
||||
# the CONF.x_allocation_ratio is None by default
|
||||
compute_dict = fake_compute_node.copy()
|
||||
# # the computes provide allocation ratios None
|
||||
@ -604,9 +653,17 @@ class _TestComputeNodeObject(object):
|
||||
cls = objects.ComputeNode
|
||||
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
||||
|
||||
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
||||
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_cpu_allocation_ratio, compute.cpu_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_ram_allocation_ratio, compute.ram_allocation_ratio)
|
||||
self.assertEqual(
|
||||
CONF.initial_disk_allocation_ratio, compute.disk_allocation_ratio)
|
||||
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, 123, {'cpu_allocation_ratio': 16.0,
|
||||
'ram_allocation_ratio': 1.5,
|
||||
'disk_allocation_ratio': 1.0})
|
||||
|
||||
def test_get_all_by_not_mapped(self):
|
||||
for mapped in (1, 0, 1, 3):
|
||||
|
Loading…
Reference in New Issue
Block a user