summaryrefslogtreecommitdiffstats
path: root/lib/ansible/modules/debconf.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/debconf.py')
-rw-r--r--lib/ansible/modules/debconf.py231
1 files changed, 231 insertions, 0 deletions
diff --git a/lib/ansible/modules/debconf.py b/lib/ansible/modules/debconf.py
new file mode 100644
index 0000000..32f0000
--- /dev/null
+++ b/lib/ansible/modules/debconf.py
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2014, Brian Coca <briancoca+ansible@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+---
+module: debconf
+short_description: Configure a .deb package
+description:
+ - Configure a .deb package using debconf-set-selections.
+ - Or just query existing selections.
+version_added: "1.6"
+extends_documentation_fragment:
+- action_common_attributes
+attributes:
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+ platform:
+ support: full
+ platforms: debian
+notes:
+ - This module requires the command line debconf tools.
+ - A number of questions have to be answered (depending on the package).
+ Use 'debconf-show <package>' on any Debian or derivative with the package
+ installed to see questions/settings available.
+ - Some distros will always record tasks involving the setting of passwords as changed. This is due to debconf-get-selections masking passwords.
+ - It is highly recommended to add I(no_log=True) to task while handling sensitive information using this module.
+ - The debconf module does not reconfigure packages, it just updates the debconf database.
+ An additional step is needed (typically with I(notify) if debconf makes a change)
+ to reconfigure the package and apply the changes.
+ debconf is extensively used for pre-seeding configuration prior to installation
+ rather than modifying configurations.
+ So, while dpkg-reconfigure does use debconf data, it is not always authoritative
+ and you may need to check how your package is handled.
+ - Also note dpkg-reconfigure is a 3-phase process. It invokes the
+ control scripts from the C(/var/lib/dpkg/info) directory with the
+ C(<package>.prerm reconfigure <version>),
+ C(<package>.config reconfigure <version>) and C(<package>.postinst control <version>) arguments.
+ - The main issue is that the C(<package>.config reconfigure) step for many packages
+ will first reset the debconf database (overriding changes made by this module) by
+ checking the on-disk configuration. If this is the case for your package then
+ dpkg-reconfigure will effectively ignore changes made by debconf.
+ - However as dpkg-reconfigure only executes the C(<package>.config) step if the file
+ exists, it is possible to rename it to C(/var/lib/dpkg/info/<package>.config.ignore)
+ before executing C(dpkg-reconfigure -f noninteractive <package>) and then restore it.
+ This seems to be compliant with Debian policy for the .config file.
+requirements:
+- debconf
+- debconf-utils
+options:
+ name:
+ description:
+ - Name of package to configure.
+ type: str
+ required: true
+ aliases: [ pkg ]
+ question:
+ description:
+ - A debconf configuration setting.
+ type: str
+ aliases: [ selection, setting ]
+ vtype:
+ description:
+ - The type of the value supplied.
+ - It is highly recommended to add I(no_log=True) to task while specifying I(vtype=password).
+ - C(seen) was added in Ansible 2.2.
+ type: str
+ choices: [ boolean, error, multiselect, note, password, seen, select, string, text, title ]
+ value:
+ description:
+ - Value to set the configuration to.
+ type: str
+ aliases: [ answer ]
+ unseen:
+ description:
+ - Do not set 'seen' flag when pre-seeding.
+ type: bool
+ default: false
+author:
+- Brian Coca (@bcoca)
+'''
+
+EXAMPLES = r'''
+- 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 to generate locales
+ ansible.builtin.debconf:
+ name: locales
+ question: locales/locales_to_be_generated
+ value: en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8
+ vtype: multiselect
+
+- name: Accept oracle license
+ ansible.builtin.debconf:
+ name: oracle-java7-installer
+ question: shared/accepted-oracle-license-v1-1
+ value: 'true'
+ vtype: select
+
+- name: Specifying package you can register/return the list of questions and current values
+ ansible.builtin.debconf:
+ name: tzdata
+
+- name: Pre-configure tripwire site passphrase
+ ansible.builtin.debconf:
+ name: tripwire
+ question: tripwire/site-passphrase
+ value: "{{ site_passphrase }}"
+ vtype: password
+ no_log: True
+'''
+
+RETURN = r'''#'''
+
+from ansible.module_utils._text import to_text
+from ansible.module_utils.basic import AnsibleModule
+
+
+def get_selections(module, pkg):
+ cmd = [module.get_bin_path('debconf-show', True), pkg]
+ rc, out, err = module.run_command(' '.join(cmd))
+
+ if rc != 0:
+ module.fail_json(msg=err)
+
+ selections = {}
+
+ for line in out.splitlines():
+ (key, value) = line.split(':', 1)
+ selections[key.strip('*').strip()] = value.strip()
+
+ return selections
+
+
+def set_selection(module, pkg, question, vtype, value, unseen):
+ setsel = module.get_bin_path('debconf-set-selections', True)
+ cmd = [setsel]
+ if unseen:
+ cmd.append('-u')
+
+ if vtype == 'boolean':
+ if value == 'True':
+ value = 'true'
+ elif value == 'False':
+ value = 'false'
+ data = ' '.join([pkg, question, vtype, value])
+
+ return module.run_command(cmd, data=data)
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ name=dict(type='str', required=True, aliases=['pkg']),
+ question=dict(type='str', aliases=['selection', 'setting']),
+ vtype=dict(type='str', choices=['boolean', 'error', 'multiselect', 'note', 'password', 'seen', 'select', 'string', 'text', 'title']),
+ value=dict(type='str', aliases=['answer']),
+ unseen=dict(type='bool', default=False),
+ ),
+ required_together=(['question', 'vtype', 'value'],),
+ supports_check_mode=True,
+ )
+
+ # TODO: enable passing array of options and/or debconf file from get-selections dump
+ pkg = module.params["name"]
+ question = module.params["question"]
+ vtype = module.params["vtype"]
+ value = module.params["value"]
+ unseen = module.params["unseen"]
+
+ prev = get_selections(module, pkg)
+
+ changed = False
+ msg = ""
+
+ if question is not None:
+ if vtype is None or value is None:
+ module.fail_json(msg="when supplying a question you must supply a valid vtype and value")
+
+ # if question doesn't exist, value cannot match
+ if question not in prev:
+ changed = True
+ else:
+
+ existing = prev[question]
+
+ # ensure we compare booleans supplied to the way debconf sees them (true/false strings)
+ if vtype == 'boolean':
+ value = to_text(value).lower()
+ existing = to_text(prev[question]).lower()
+
+ if value != existing:
+ changed = True
+
+ if changed:
+ if not module.check_mode:
+ rc, msg, e = set_selection(module, pkg, question, vtype, value, unseen)
+ if rc:
+ module.fail_json(msg=e)
+
+ curr = {question: value}
+ if question in prev:
+ prev = {question: prev[question]}
+ else:
+ prev[question] = ''
+ if module._diff:
+ after = prev.copy()
+ after.update(curr)
+ diff_dict = {'before': prev, 'after': after}
+ else:
+ diff_dict = {}
+
+ module.exit_json(changed=changed, msg=msg, current=curr, previous=prev, diff=diff_dict)
+
+ module.exit_json(changed=changed, msg=msg, current=prev)
+
+
+if __name__ == '__main__':
+ main()