From 870adc14f99d6cd237c73b703ad3b3b5f5416896 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 24 May 2018 12:28:46 -0400 Subject: [PATCH] fix a bug in the instance policy algorithm when both min and % are used see: https://github.com/ansible/tower/issues/897 --- awx/main/tasks.py | 4 ++++ awx/main/tests/functional/test_instances.py | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/awx/main/tasks.py b/awx/main/tasks.py index cbe70a394f..dc3c8df28b 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -175,6 +175,10 @@ def apply_cluster_membership_policies(self): # Finally process instance policy percentages for g in sorted(actual_groups, cmp=lambda x,y: len(x.instances) - len(y.instances)): for i in sorted(actual_instances, cmp=lambda x,y: len(x.groups) - len(y.groups)): + if i.obj.id in g.instances: + # If the instance is already _in_ the group, it was + # probably applied earlier via a minimum policy + continue if 100 * float(len(g.instances)) / len(actual_instances) >= g.obj.policy_instance_percentage: break logger.info(six.text_type("Policy percentage, adding Instance {} to Group {}").format(i.obj.hostname, g.obj.name)) diff --git a/awx/main/tests/functional/test_instances.py b/awx/main/tests/functional/test_instances.py index 91dee86b9e..40216ae123 100644 --- a/awx/main/tests/functional/test_instances.py +++ b/awx/main/tests/functional/test_instances.py @@ -193,6 +193,19 @@ def test_inherited_instance_group_membership(instance_group_factory, default_ins assert default_instance_group not in j.preferred_instance_groups +@pytest.mark.django_db +@mock.patch('awx.main.tasks.handle_ha_toplogy_changes', return_value=None) +def test_mixed_group_membership(mock, instance_factory, instance_group_factory): + for i in range(5): + instance_factory("i{}".format(i)) + ig_1 = instance_group_factory("ig1", percentage=60) + ig_2 = instance_group_factory("ig2", minimum=3) + ig_3 = instance_group_factory("ig3", minimum=1, percentage=60) + apply_cluster_membership_policies() + for group in (ig_1, ig_2, ig_3): + assert len(group.instances.all()) == 3 + + @pytest.mark.django_db def test_instance_group_capacity(instance_factory, instance_group_factory): i1 = instance_factory("i1")