From 7bee994e1cfb423649dba0c9b1efd9aa71b02eb3 Mon Sep 17 00:00:00 2001 From: Jonathon Klobucar Date: Wed, 13 Apr 2016 07:49:38 -0700 Subject: [PATCH] Fix for serial when percent amount is less than one host (#15396) Ansible when there was a percentage that was calculated to be less than 1.0 would run all hosts as the value for a rolling update. The error is due to the fact that Python will round a float that is under 1.0 to 0, which will trigger the case of 0 hosts. The 0 host case tells ansible to run all hosts. The fix will see if the percentage calculation after int conversion is 0 and will else to 1 host. --- lib/ansible/executor/playbook_executor.py | 2 +- test/units/executor/test_playbook_executor.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/ansible/executor/playbook_executor.py b/lib/ansible/executor/playbook_executor.py index 5a1b76f9410..4827ebc8d43 100644 --- a/lib/ansible/executor/playbook_executor.py +++ b/lib/ansible/executor/playbook_executor.py @@ -214,7 +214,7 @@ class PlaybookExecutor: # and convert it to an integer value based on the number of hosts if isinstance(play.serial, string_types) and play.serial.endswith('%'): serial_pct = int(play.serial.replace("%","")) - serial = int((serial_pct/100.0) * len(all_hosts)) + serial = int((serial_pct/100.0) * len(all_hosts)) or 1 else: if play.serial is None: serial = -1 diff --git a/test/units/executor/test_playbook_executor.py b/test/units/executor/test_playbook_executor.py index 4a8c27c71ac..8b65ff6acb9 100644 --- a/test/units/executor/test_playbook_executor.py +++ b/test/units/executor/test_playbook_executor.py @@ -92,3 +92,14 @@ class TestPlayIterator(unittest.TestCase): mock_inventory.get_hosts.return_value = ['host0','host1','host2','host3','host4','host5','host6','host7','host8','host9'] self.assertEqual(pbe._get_serialized_batches(play), [['host0','host1'],['host2','host3'],['host4','host5'],['host6','host7'],['host8','host9']]) + # Test when serial percent is under 1.0 + playbook = Playbook.load(pbe._playbooks[2], variable_manager=mock_var_manager, loader=fake_loader) + play = playbook.get_plays()[0] + mock_inventory.get_hosts.return_value = ['host0','host1','host2'] + self.assertEqual(pbe._get_serialized_batches(play), [['host0'],['host1'],['host2']]) + + # Test when there is a remainder for serial as a percent + playbook = Playbook.load(pbe._playbooks[2], variable_manager=mock_var_manager, loader=fake_loader) + play = playbook.get_plays()[0] + mock_inventory.get_hosts.return_value = ['host0','host1','host2','host3','host4','host5','host6','host7','host8','host9','host10'] + self.assertEqual(pbe._get_serialized_batches(play), [['host0','host1'],['host2','host3'],['host4','host5'],['host6','host7'],['host8','host9'],['host10']])