diff --git a/config.yaml b/config.yaml index 7bd31d16..179f27b7 100644 --- a/config.yaml +++ b/config.yaml @@ -617,6 +617,17 @@ options: . Possible Values are positive integers. Any value less than 1 will be treated as 1. + scheduler-max-attempts: + type: int + default: + description: | + The value to be configured for max_attempts property under scheduler. + . + This is useful for rescheduling instances to hosts when affinity policies + are in place as described in the following URL + https://docs.openstack.org/nova/latest/admin/troubleshooting/affinity-policy-violated.html + . + The default 3 spice-agent-enabled: # LP: #1856602 type: boolean default: True # OpenStack's default value. diff --git a/hooks/nova_cc_context.py b/hooks/nova_cc_context.py index 079fe5c3..96610113 100644 --- a/hooks/nova_cc_context.py +++ b/hooks/nova_cc_context.py @@ -440,6 +440,8 @@ class NovaConfigContext(ch_context.WorkerConfigContext): ctxt['console_access_port'] = hookenv.config('console-access-port') ctxt['scheduler_host_subset_size'] = hookenv.config( 'scheduler-host-subset-size') + ctxt['scheduler_max_attempts'] = hookenv.config( + 'scheduler-max-attempts') ctxt['unique_server_names'] = hookenv.config('unique-server-names') ctxt['skip_hosts_with_build_failures'] = hookenv.config( 'skip-hosts-with-build-failures') diff --git a/templates/ocata/nova.conf b/templates/ocata/nova.conf index 3bcd944b..d91dc88e 100644 --- a/templates/ocata/nova.conf +++ b/templates/ocata/nova.conf @@ -205,6 +205,10 @@ enabled_filters = {{ scheduler_default_filters }} host_subset_size = {{ scheduler_host_subset_size }} {%- endif %} +{%- if scheduler_max_attempts %} +max_attempts = {{ scheduler_max_attempts }} +{%- endif %} + [api] auth_strategy=keystone {% if vendor_data or vendor_data_url -%} diff --git a/templates/pike/nova.conf b/templates/pike/nova.conf index 50b72cd5..6987f973 100644 --- a/templates/pike/nova.conf +++ b/templates/pike/nova.conf @@ -219,6 +219,10 @@ build_failure_weight_multiplier = 0.0 host_subset_size = {{ scheduler_host_subset_size }} {%- endif %} +{%- if scheduler_max_attempts %} +max_attempts = {{ scheduler_max_attempts }} +{%- endif %} + [api] auth_strategy=keystone {% if vendor_data or vendor_data_url -%} diff --git a/templates/rocky/nova.conf b/templates/rocky/nova.conf index 2be1d8d6..6f5b2a38 100644 --- a/templates/rocky/nova.conf +++ b/templates/rocky/nova.conf @@ -221,6 +221,10 @@ build_failure_weight_multiplier = 0.0 host_subset_size = {{ scheduler_host_subset_size }} {%- endif %} +{%- if scheduler_max_attempts %} +max_attempts = {{ scheduler_max_attempts }} +{%- endif %} + [api] auth_strategy=keystone {% if vendor_data or vendor_data_url -%} diff --git a/templates/train/nova.conf b/templates/train/nova.conf index 004695f3..4bcfc7ed 100644 --- a/templates/train/nova.conf +++ b/templates/train/nova.conf @@ -235,6 +235,10 @@ build_failure_weight_multiplier = 0.0 host_subset_size = {{ scheduler_host_subset_size }} {%- endif %} +{%- if scheduler_max_attempts %} +max_attempts = {{ scheduler_max_attempts }} +{%- endif %} + [api] auth_strategy=keystone {% if vendor_data or vendor_data_url -%} diff --git a/unit_tests/test_nova_cc_contexts.py b/unit_tests/test_nova_cc_contexts.py index d9f48127..ce68e82c 100644 --- a/unit_tests/test_nova_cc_contexts.py +++ b/unit_tests/test_nova_cc_contexts.py @@ -341,10 +341,13 @@ class NovaComputeContextTests(CharmTestCase): mock_config_ip.side_effect = self.test_config.get mock_unit_get.return_value = '127.0.0.1' self.test_config.set('scheduler-default-filters', 'TestFilter') + self.test_config.set('scheduler-max-attempts', 10) self.test_config.set('unique-server-names', 'project') ctxt = context.NovaConfigContext()() self.assertEqual(ctxt['scheduler_default_filters'], self.config('scheduler-default-filters')) + self.assertEqual(ctxt['scheduler_max_attempts'], + self.config('scheduler-max-attempts')) self.assertEqual(ctxt['cpu_allocation_ratio'], self.config('cpu-allocation-ratio')) self.assertEqual(ctxt['ram_allocation_ratio'],