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 542835cb50)
This commit is contained in:
Andy McCrae 2018-03-21 11:25:50 +00:00 committed by Andy McCrae
parent a90e760635
commit 2ab0160123
3 changed files with 50 additions and 6 deletions

View File

@ -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")

View File

@ -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")

View File

@ -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