diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index dd3a16f9429f..e0c8f6df495c 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -631,29 +631,33 @@ class ResourceTracker(object): compute_node.stats = stats # Update the allocation ratios for the related ComputeNode object - # but only if the configured values are not the default 0.0; the + # but only if the configured values are not the default; the # ComputeNode._from_db_object method takes care of providing default - # allocation ratios when the config is left at the 0.0 default, so + # allocation ratios when the config is left at the default, so # we'll really end up with something like a - # ComputeNode.cpu_allocation_ratio of 16.0, not 0.0. We want to avoid - # resetting the ComputeNode fields to 0.0 because that will make + # ComputeNode.cpu_allocation_ratio of 16.0. We want to avoid + # resetting the ComputeNode fields to None because that will make # the _resource_change method think something changed when really it # didn't. # TODO(mriedem): Will this break any scenarios where an operator is # trying to *reset* the allocation ratios by changing config from - # non-0.0 back to 0.0? Maybe we should only do this if the fields on + # non-None back to None? Maybe we should only do this if the fields on # the ComputeNode object are not already set. For example, let's say # the cpu_allocation_ratio config was 1.0 and then the operator wants # to get back to the default (16.0 via the facade), and to do that they - # change the config back to 0.0 (or just unset the config option). + # change the config back to None (or just unset the config option). # Should we support that or treat these config options as "sticky" in # that once you start setting them, you can't go back to the implied - # defaults by unsetting or resetting to 0.0? Sort of like how + # defaults by unsetting or resetting to None? Sort of like how # per-tenant quota is sticky once you change it in the API. for res in ('cpu', 'disk', 'ram'): attr = '%s_allocation_ratio' % res conf_alloc_ratio = getattr(self, attr) - if conf_alloc_ratio != 0.0: + # NOTE(yikun): In Stein version, we change the default value of + # (cpu|ram|disk)_allocation_ratio from 0.0 to None, but we still + # should allow 0.0 to keep compatibility, and this 0.0 condition + # will be removed in the next version (T version). + if conf_alloc_ratio not in (0.0, None): setattr(compute_node, attr, conf_alloc_ratio) # now copy rest to compute_node diff --git a/nova/conf/compute.py b/nova/conf/compute.py index 108c3adc351c..3f1c277f60d7 100644 --- a/nova/conf/compute.py +++ b/nova/conf/compute.py @@ -381,7 +381,7 @@ Possible values: allocation_ratio_opts = [ cfg.FloatOpt('cpu_allocation_ratio', - default=0.0, + default=None, min=0.0, help=""" This option helps you specify virtual CPU to physical CPU allocation ratio. @@ -395,18 +395,18 @@ This configuration specifies ratio for CoreFilter which can be set per compute node. For AggregateCoreFilter, it will fall back to this configuration value if no per-aggregate setting is found. -NOTE: This can be set per-compute, or if set to 0.0, the value -set on the scheduler node(s) or compute node(s) will be used -and defaulted to 16.0. Once set to a non-default value, it is not possible -to "unset" the config to get back to the default behavior. If you want -to reset back to the default, explicitly specify 16.0. +NOTE: If this option is set to something *other than* ``None`` or ``0.0``, the +allocation ratio will be overwritten by the value of this option, otherwise, +the allocation ratio will not change. Once set to a non-default value, it is +not possible to "unset" the config to get back to the default behavior. If you +want to reset back to the default, explicitly specify 16.0. Possible values: * Any valid positive integer or float value """), cfg.FloatOpt('ram_allocation_ratio', - default=0.0, + default=None, min=0.0, help=""" This option helps you specify virtual RAM to physical RAM @@ -421,18 +421,18 @@ This configuration specifies ratio for RamFilter which can be set per compute node. For AggregateRamFilter, it will fall back to this configuration value if no per-aggregate setting found. -NOTE: This can be set per-compute, or if set to 0.0, the value -set on the scheduler node(s) or compute node(s) will be used and -defaulted to 1.5. Once set to a non-default value, it is not possible -to "unset" the config to get back to the default behavior. If you want -to reset back to the default, explicitly specify 1.5. +NOTE: If this option is set to something *other than* ``None`` or ``0.0``, the +allocation ratio will be overwritten by the value of this option, otherwise, +the allocation ratio will not change. Once set to a non-default value, it is +not possible to "unset" the config to get back to the default behavior. If you +want to reset back to the default, explicitly specify 1.5. Possible values: * Any valid positive integer or float value """), cfg.FloatOpt('disk_allocation_ratio', - default=0.0, + default=None, min=0.0, help=""" This option helps you specify virtual disk to physical disk @@ -451,11 +451,11 @@ images. It can be set to a value between 0.0 and 1.0 in order to preserve a percentage of the disk for uses other than instances. -NOTE: This can be set per-compute, or if set to 0.0, the value -set on the scheduler node(s) or compute node(s) will be used and -defaulted to 1.0. Once set to a non-default value, it is not possible -to "unset" the config to get back to the default behavior. If you want -to reset back to the default, explicitly specify 1.0. +NOTE: If this option is set to something *other than* ``None`` or ``0.0``, the +allocation ratio will be overwritten by the value of this option, otherwise, +the allocation ratio will not change. Once set to a non-default value, it is +not possible to "unset" the config to get back to the default behavior. If you +want to reset back to the default, explicitly specify 1.0. Possible values: diff --git a/nova/objects/compute_node.py b/nova/objects/compute_node.py index aa01b5e79fe1..9e96e5a3a25a 100644 --- a/nova/objects/compute_node.py +++ b/nova/objects/compute_node.py @@ -197,13 +197,16 @@ class ComputeNode(base.NovaPersistentObject, base.NovaObject): # or the compute node is updated but the default value has # not been changed value = getattr(CONF, key) - if value == 0.0 and key == 'cpu_allocation_ratio': + if value in (0.0, None) \ + and key == 'cpu_allocation_ratio': # It's not specified either on the controller value = 16.0 - if value == 0.0 and key == 'ram_allocation_ratio': + if value in (0.0, None) \ + and key == 'ram_allocation_ratio': # It's not specified either on the controller value = 1.5 - if value == 0.0 and key == 'disk_allocation_ratio': + if value in (0.0, None) \ + and key == 'disk_allocation_ratio': # It's not specified either on the controller value = 1.0 elif key == 'mapped': diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py index 2d0c31bdabac..752c16459f24 100644 --- a/nova/tests/unit/compute/test_resource_tracker.py +++ b/nova/tests/unit/compute/test_resource_tracker.py @@ -1538,7 +1538,7 @@ class TestUpdateComputeNode(BaseTestCase): def test_copy_resources_no_update_allocation_ratios(self): """Tests that a ComputeNode object's allocation ratio fields are - not set if the configured allocation ratio values are default 0.0. + not set if the configured allocation ratio values are default None. """ self._setup_rt() compute = _COMPUTE_NODE_FIXTURES[0].obj_clone() @@ -1551,11 +1551,34 @@ class TestUpdateComputeNode(BaseTestCase): attr_name = '%s_allocation_ratio' % res self.assertNotIn(attr_name, changes) + def test_copy_resources_update_allocation_zero_ratios(self): + """Tests that a ComputeNode object's allocation ratio fields are + not set if the configured allocation ratio values are 0.0. + """ + # NOTE(yikun): In Stein version, we change the default value of + # (cpu|ram|disk)_allocation_ratio from 0.0 to None, but we still + # should allow 0.0 to keep compatibility, and this 0.0 condition + # will be removed in the next version (T version). + # Set explicit ratio config values to 0.0 (the default is None). + for res in ('cpu', 'disk', 'ram'): + opt_name = '%s_allocation_ratio' % res + CONF.set_override(opt_name, 0.0) + self._setup_rt() + compute = _COMPUTE_NODE_FIXTURES[0].obj_clone() + compute.obj_reset_changes() # make sure we start clean + self.rt._copy_resources( + compute, self.driver_mock.get_available_resource.return_value) + # Assert that the ComputeNode fields were not changed. + changes = compute.obj_get_changes() + for res in ('cpu', 'disk', 'ram'): + attr_name = '%s_allocation_ratio' % res + self.assertNotIn(attr_name, changes) + def test_copy_resources_update_allocation_ratios_from_config(self): """Tests that a ComputeNode object's allocation ratio fields are - set if the configured allocation ratio values are not 0.0. + set if the configured allocation ratio values are not default. """ - # Set explicit ratio config values to 1.0 (the default is 0.0). + # Set explicit ratio config values to 1.0 (the default is None). for res in ('cpu', 'disk', 'ram'): opt_name = '%s_allocation_ratio' % res CONF.set_override(opt_name, 1.0) diff --git a/nova/tests/unit/objects/test_compute_node.py b/nova/tests/unit/objects/test_compute_node.py index 9aa761a5241f..87b8ae4f2b7d 100644 --- a/nova/tests/unit/objects/test_compute_node.py +++ b/nova/tests/unit/objects/test_compute_node.py @@ -565,9 +565,25 @@ class _TestComputeNodeObject(object): self.assertEqual(3.0, compute.ram_allocation_ratio) self.assertEqual(0.9, compute.disk_allocation_ratio) - def test_compat_allocation_ratios_default_values(self): + def test_compat_allocation_ratios_zero_conf(self): + self.flags(cpu_allocation_ratio=0.0, ram_allocation_ratio=0.0, + disk_allocation_ratio=0.0) compute_dict = fake_compute_node.copy() - # new computes provide allocation ratios defaulted to 0.0 + # the computes provide allocation ratios None + compute_dict['cpu_allocation_ratio'] = None + compute_dict['ram_allocation_ratio'] = None + compute_dict['disk_allocation_ratio'] = None + 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) + + def test_compat_allocation_ratios_None_conf_zero_values(self): + # the CONF.x_allocation_ratio is None by default + compute_dict = fake_compute_node.copy() + # the computes provide allocation ratios 0.0 compute_dict['cpu_allocation_ratio'] = 0.0 compute_dict['ram_allocation_ratio'] = 0.0 compute_dict['disk_allocation_ratio'] = 0.0 @@ -578,9 +594,10 @@ class _TestComputeNodeObject(object): self.assertEqual(1.5, compute.ram_allocation_ratio) self.assertEqual(1.0, compute.disk_allocation_ratio) - def test_compat_allocation_ratios_old_compute_default_values(self): + def test_compat_allocation_ratios_None_conf_None_values(self): + # the CONF.x_allocation_ratio is None by default compute_dict = fake_compute_node.copy() - # old computes don't provide allocation ratios to the table + # # the computes provide allocation ratios None compute_dict['cpu_allocation_ratio'] = None compute_dict['ram_allocation_ratio'] = None compute_dict['disk_allocation_ratio'] = None diff --git a/releasenotes/notes/add_initial_allocation_ratio-2d2666d62426a4bf.yaml b/releasenotes/notes/add_initial_allocation_ratio-2d2666d62426a4bf.yaml new file mode 100644 index 000000000000..217a2a9179b3 --- /dev/null +++ b/releasenotes/notes/add_initial_allocation_ratio-2d2666d62426a4bf.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + The default value for the "cpu_allocation_ratio", "ram_allocation_ratio" + and "disk_allocation_ratio" configurations have been changed to ``None``.