diff --git a/changelogs/fragments/debconf_seen_flag.yml b/changelogs/fragments/debconf_seen_flag.yml new file mode 100644 index 00000000000..55fba4f1d0f --- /dev/null +++ b/changelogs/fragments/debconf_seen_flag.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - debconf - convert datatype for value when vtype is seen (https://github.com/ansible/ansible/issues/85683). diff --git a/lib/ansible/modules/debconf.py b/lib/ansible/modules/debconf.py index 701c19dabb6..b8be48fea74 100644 --- a/lib/ansible/modules/debconf.py +++ b/lib/ansible/modules/debconf.py @@ -121,6 +121,13 @@ EXAMPLES = r""" value: "{{ site_passphrase }}" vtype: password no_log: True + +- name: Set seen flag to true for locales + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: 'true' """ RETURN = r"""#""" @@ -162,12 +169,17 @@ def get_selections(module, pkg): module.fail_json(msg=err) selections = {} - + seen = [] # list of seen questions for line in out.splitlines(): (key, value) = line.split(':', 1) - selections[key.strip('*').strip()] = value.strip() + if key.startswith('*'): + key = key.strip('*').strip() + seen.append(key) + selections[key] = value.strip() + else: + selections[key.strip()] = value.strip() - return selections + return selections, seen def set_selection(module, pkg, question, vtype, value, unseen): @@ -201,7 +213,7 @@ def main(): value = module.params["value"] unseen = module.params["unseen"] - prev = get_selections(module, pkg) + prev, seen_list = get_selections(module, pkg) changed = False msg = "" @@ -211,7 +223,7 @@ def main(): module.fail_json(msg="when supplying a question you must supply a valid vtype and value") # ensure we compare booleans supplied to the way debconf sees them (true/false strings) - if vtype == 'boolean': + if vtype in ('boolean', 'seen'): value = to_text(value).lower() # if question doesn't exist, value cannot match @@ -230,6 +242,13 @@ def main(): except TypeError as exc: module.fail_json(msg="Invalid value provided for 'multiselect': %s" % to_native(exc)) existing = sorted([i.strip() for i in existing.split(",")]) + elif vtype == 'seen': + # vtype seen is a special case where we only care if the question is seen or not + if question in seen_list: + # if the question is seen, the value must be true + existing = 'true' + else: + existing = 'false' if value != existing: changed = True diff --git a/test/integration/targets/debconf/tasks/main.yml b/test/integration/targets/debconf/tasks/main.yml index f650d3e7019..45dd5f00e07 100644 --- a/test/integration/targets/debconf/tasks/main.yml +++ b/test/integration/targets/debconf/tasks/main.yml @@ -215,6 +215,56 @@ that: - debconf_bool_test_bool_2.changed + - name: Set default locale to fr_FR.UTF-8 + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + value: fr_FR.UTF-8 + vtype: select + + - name: Set seen flag to false + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: false + register: false_flag + + - name: Set seen flag to false again (idempotency) + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: false + register: false_flag_again + + - name: Check if setting seen flag to false works idempotently + assert: + that: + - false_flag.changed + - not false_flag_again.changed + + - name: Set seen flag to true + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: true + register: true_flag + + - name: Set seen flag to true again (idempotency) + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: true + register: true_flag_again + + - assert: + that: + - true_flag.changed + - not true_flag_again.changed + always: - name: uninstall debconf-utils apt: