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..d827d38ee3b 100644 --- a/lib/ansible/modules/debconf.py +++ b/lib/ansible/modules/debconf.py @@ -121,12 +121,20 @@ 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"""#""" -from ansible.module_utils.common.text.converters import to_text, to_native from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.common.text.converters import to_text, to_native +from ansible.module_utils.common.validation import _check_type_str_no_conversion def get_password_value(module, pkg, question, vtype): @@ -162,12 +170,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 +214,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 = "" @@ -214,6 +227,15 @@ def main(): if vtype == 'boolean': value = to_text(value).lower() + if vtype == 'seen': + input_value = to_text(value).lower() + if input_value not in ['true', 'false']: + module.fail_json(msg=f"Invalid value provided for vtype 'seen': {input_value}") + value = input_value + + if vtype not in ('boolean', 'seen', 'multiselect'): + value = _check_type_str_no_conversion(value) + # if question doesn't exist, value cannot match if question not in prev: changed = True @@ -230,6 +252,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..1ee3d6cbd3f 100644 --- a/test/integration/targets/debconf/tasks/main.yml +++ b/test/integration/targets/debconf/tasks/main.yml @@ -215,6 +215,87 @@ 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 + + - name: Set invalid value for vtype seen + ansible.builtin.debconf: + name: locales + question: locales/default_environment_locale + vtype: seen + value: invalid + register: invalid_flag + ignore_errors: yes + + - name: validate results for invalid value for vtype seen + assert: + that: + - not invalid_flag.changed + - '"Invalid value provided for vtype" in invalid_flag.msg' + + - name: set invalid type of value for vtype string + ansible.builtin.debconf: + name: ansible + question: ansible/sample_question + vtype: string + value: + - a + register: invalid_flag + ignore_errors: yes + + - name: validate results for invalid type of value for vtype string + assert: + that: + - not invalid_flag.changed + - '"is not a string and conversion is not allowed" in invalid_flag.msg' + always: - name: uninstall debconf-utils apt: