From 2ab01601235d9087c1381432cde5f511f4c66e5c Mon Sep 17 00:00:00 2001 From: Andy McCrae Date: Wed, 21 Mar 2018 11:25:50 +0000 Subject: [PATCH] Utilise sorted to ensure no random changes This is a manual backport of a5ef4ea. The config_template plugin was unified in Queens. As part of the ceph-ansible project, this change was put in: ceph/ceph-ansible@ec04221 This was to handle the case where the config would change, initiating a restart handler, even though no actual change happened. We can juse use sorted() since we are passing back a list with .items() which can then be sorted. The above change didn't include a change to ensure the order of the sections, which meant that although the individual items were sorted the sections could change order causing unnecessary changes. Additionally, this adds a test to retemplate the file 3 times, with a lot more sections to ensure the order remains the same, this will fail when the config template changes even though no changes have happened. Change-Id: I7c7cd9ef1dd767a2a5d754ac4663cf8655dd60c2 (cherry picked from commit 542835cb502856f6aa4b59c0c9565fdb3061de39) --- action/_v1_config_template.py | 6 ++--- action/_v2_config_template.py | 6 ++--- tests/test-config_template.yml | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/action/_v1_config_template.py b/action/_v1_config_template.py index 579c7f89..af652c75 100644 --- a/action/_v1_config_template.py +++ b/action/_v1_config_template.py @@ -145,14 +145,14 @@ class ConfigTemplateParser(ConfigParser.RawConfigParser): def write(self, fp): if self._defaults: fp.write("[%s]\n" % 'DEFAULT') - for key, value in self._defaults.items(): + for key, value in sorted(self._defaults.items()): self._write_check(fp, key=key, value=value) else: fp.write("\n") - for section in self._sections: + for section in sorted(self._sections): fp.write("[%s]\n" % section) - for key, value in self._sections[section].items(): + for key, value in sorted(self._sections[section].items()): self._write_check(fp, key=key, value=value, section=True) else: fp.write("\n") diff --git a/action/_v2_config_template.py b/action/_v2_config_template.py index 593ac86c..98420d8e 100644 --- a/action/_v2_config_template.py +++ b/action/_v2_config_template.py @@ -187,14 +187,14 @@ class ConfigTemplateParser(ConfigParser.RawConfigParser): def write(self, fp): if self._defaults: fp.write("[%s]\n" % 'DEFAULT') - for key, value in self._defaults.items(): + for key, value in sorted(self._defaults.items()): self._write_check(fp, key=key, value=value) else: fp.write("\n") - for section in self._sections: + for section in sorted(self._sections): fp.write("[%s]\n" % section) - for key, value in self._sections[section].items(): + for key, value in sorted(self._sections[section].items()): self._write_check(fp, key=key, value=value, section=True) else: fp.write("\n") diff --git a/tests/test-config_template.yml b/tests/test-config_template.yml index 5046f1ef..d1545f23 100644 --- a/tests/test-config_template.yml +++ b/tests/test-config_template.yml @@ -129,12 +129,56 @@ - "{{ test_ignore_none_type.content | b64decode | search('(?m)^india$') }}" - "{{ test_ignore_none_type.content | b64decode | search('(?m)^juliett kilo$') }}" + - name: Template multiple times to assert no changes + config_template: + src: "{{ playbook_dir }}/templates/test.ini" + dest: "/tmp/test_with_content.ini" + config_type: "ini" + config_overrides: "{{ item[1] }}" + register: template_changed + failed_when: template_changed | changed + with_nested: + - [ 0, 1, 2 ] + - [ "{{ test_config_ini_overrides }}" ] + vars: test_config_ini_overrides: DEFAULT: new_key: "new_value" foo: baz: "bar" + section1: + key1: "value1" + key2: "value2" + key3: "value3" + key4: "value4" + key5: "value5" + key6: "value6" + key7: "value7" + key8: "value8" + key9: "value9" + key10: "value10" + key11: "value11" + section2: + key1: "value1" + section3: + key1: "value1" + section4: + key1: "value1" + section5: + key1: "value1" + section6: + key1: "value1" + section7: + key1: "value1" + section8: + key1: "value1" + section9: + key1: "value1" + section10: + key1: "value1" + section11: + key1: "value1" test_config_yml_overrides: list_one: - four