From 0c2ec0d9d1b5249c826a113c7e83129953ebe0f2 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 19 Dec 2013 16:54:02 -0500 Subject: [PATCH 01/13] debconf package Signed-off-by: Brian Coca --- system/debconf | 160 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 system/debconf diff --git a/system/debconf b/system/debconf new file mode 100644 index 00000000000..2215d016748 --- /dev/null +++ b/system/debconf @@ -0,0 +1,160 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to configure debian packages. +(c) 2014, Brian Coca + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: debconf +short_description: Configure a debian package +description: + - Configure a Debian package using debconf-set-selections +version_added: "1.5" +notes: + - A number of questions have to be answered (depending on the package). + Use 'debconf-show ' on any debian/derivative with the package + installed to see questions/settings available. +options: + name: + description: + - Name of package to configure. + required: true + default: null + aliases: ['pkg'] + setting: + description: + - A debconf configuration setting + required: false + default: null + aliases: ['question', 'selection'] + type: + description: + - The type of value supplied + required: false + default: null + choices: [string, boolean, select, multiselect, note, text, password, title] + aliases: [] + value: + description: + - Value to set the configuration to + required: false + default: null + aliases: ['awnser'] + unseen: + description: + - Do not set 'seen' flag when preseeding + required: false + default: False + aliases: [] +author: Brian Coca + +''' + +EXAMPLES = ''' +# Set default locale to fr_FR.UTF-8 +debconf: name=locales setting='locales/default_environment_locale' value=fr_FR.UTF-8 + +# set to generate locales: +debconf: name=locales setting='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' + +# Accept oracle license +debconf: names='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' type='select' +''' + +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: + selections = {} + for line in out.splitlines(): + #if not line.startswith('*'): # only awnsered + # continue + (key, value) = line.split(':') + selections[ key.strip('*').strip() ] = value.strip() + return selections + else: + module.fail_json(msg=err) + + +def set_selection(module, pkg, question, type, value, unseen): + + awnser = [ question ] + if 'type': + awnser.append(type) + awnser.append(value) + + data = ' '.join(awnser) + + setsel = module.get_bin_path('debconf-set-selections', True) + cmd = ["echo '%s %s' |" % (pkg, data), setsel] + if unseen: + cmd.append('-u') + + return module.run_command(' '.join(cmd)) + +def main(): + + module = AnsibleModule( + argument_spec = dict( + name = dict(required=True, aliases=['pkg'], type='str'), + setting = dict(required=False, aliases=['question', 'selection'], type='str'), + type = dict(required=False, type='str', choices=['string', 'boolean', 'select', 'multiselect', 'note', 'text', 'password', 'title']), + value= dict(required=False, type='str'), + unseen = dict(required=False, type='bool'), + ), + supports_check_mode=True, + ) + + #TODO: enable passing array of optionas and/or debconf file from get-selections dump + pkg = module.params["name"] + question = module.params["setting"] + type = module.params["type"] + value = module.params["value"] + unseen = module.params["unseen"] + + prev = get_selections(module, pkg) + diff = '' + + changed = False + msg = "" + + if question is not None: + if not question in prev or prev[question] != value: + changed = True + + if changed: + if not module.check_mode: + rc, msg, e = set_selection(module, pkg, question, type, value, unseen) + if rc: + module.fail_json(msg=e) + curr = { question: value } + prev = (question, prev[question]) + + module.exit_json(changed=changed, msg=msg, current=curr, previous=prev) + + module.exit_json(changed=changed, msg=msg, current=prev) + +# this is magic, see lib/ansible/module_common.py +#<> +main() + + From 564bd29eebca9974836c85ffdc96ecc0b48c072b Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 19 Dec 2013 17:21:00 -0500 Subject: [PATCH 02/13] fixed typo for showing diff Signed-off-by: Brian Coca --- system/debconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index 2215d016748..b05b05d1764 100644 --- a/system/debconf +++ b/system/debconf @@ -147,7 +147,7 @@ def main(): if rc: module.fail_json(msg=e) curr = { question: value } - prev = (question, prev[question]) + prev = (question: prev[question]) module.exit_json(changed=changed, msg=msg, current=curr, previous=prev) From 3587053119a0129f8ad88e26ed182bbcbb1f80bd Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 19 Dec 2013 17:22:05 -0500 Subject: [PATCH 03/13] and it was supposed to be a dict Signed-off-by: Brian Coca --- system/debconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index b05b05d1764..1b48e04156f 100644 --- a/system/debconf +++ b/system/debconf @@ -147,7 +147,7 @@ def main(): if rc: module.fail_json(msg=e) curr = { question: value } - prev = (question: prev[question]) + prev = {question: prev[question]} module.exit_json(changed=changed, msg=msg, current=curr, previous=prev) From ce72f277870eb9f95ac08ceb3ee32ca8ffcf02ae Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 20 Dec 2013 12:50:06 -0500 Subject: [PATCH 04/13] corrected indentation and now handles non existing previous key (not just changed existing) Signed-off-by: Brian Coca --- system/debconf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/system/debconf b/system/debconf index 1b48e04156f..23f147fcfa3 100644 --- a/system/debconf +++ b/system/debconf @@ -146,8 +146,12 @@ def main(): rc, msg, e = set_selection(module, pkg, question, type, value, unseen) if rc: module.fail_json(msg=e) - curr = { question: value } - prev = {question: prev[question]} + + curr = { question: value } + if question in prev: + prev = {question: prev[question]} + else: + prev[question] = '' module.exit_json(changed=changed, msg=msg, current=curr, previous=prev) From 72eba691752a6622d86f7647efca6d81f440a0b2 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 23 Dec 2013 13:35:27 -0500 Subject: [PATCH 05/13] did some minor refactoring on docs and fixed spelling mistakes (thanks Mikhail) Signed-off-by: Brian Coca --- system/debconf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/system/debconf b/system/debconf index 23f147fcfa3..18f51b705e4 100644 --- a/system/debconf +++ b/system/debconf @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """ -Ansible module to configure debian packages. +Ansible module to configure .deb packages. (c) 2014, Brian Coca This file is part of Ansible @@ -24,13 +24,13 @@ along with Ansible. If not, see . DOCUMENTATION = ''' --- module: debconf -short_description: Configure a debian package +short_description: Configure a .deb package description: - - Configure a Debian package using debconf-set-selections + - Configure a .deb package using debconf-set-selections version_added: "1.5" notes: - A number of questions have to be answered (depending on the package). - Use 'debconf-show ' on any debian/derivative with the package + Use 'debconf-show ' on any Debian or derivative with the package installed to see questions/settings available. options: name: @@ -60,7 +60,7 @@ options: aliases: ['awnser'] unseen: description: - - Do not set 'seen' flag when preseeding + - Do not set 'seen' flag when pre-seeding required: false default: False aliases: [] From ebba754ee6e30253516fbb40cec45c4847e9b201 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 23 Dec 2013 13:48:53 -0500 Subject: [PATCH 06/13] corrected my grammar (again Mikhail) Signed-off-by: Brian Coca --- system/debconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index 18f51b705e4..bd8dedfdfcd 100644 --- a/system/debconf +++ b/system/debconf @@ -47,7 +47,7 @@ options: aliases: ['question', 'selection'] type: description: - - The type of value supplied + - The type of the value supplied required: false default: null choices: [string, boolean, select, multiselect, note, text, password, title] From 45872dfee702f2053cc3f0cd244f1f47fe4bcefa Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 23 Dec 2013 14:09:15 -0500 Subject: [PATCH 07/13] making pylint happier Signed-off-by: Brian Coca --- system/debconf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/system/debconf b/system/debconf index bd8dedfdfcd..7324e7de6f1 100644 --- a/system/debconf +++ b/system/debconf @@ -85,7 +85,7 @@ def get_selections(module, pkg): if rc == 0: selections = {} - for line in out.splitlines(): + for line in out.splitlines(): #if not line.startswith('*'): # only awnsered # continue (key, value) = line.split(':') @@ -160,5 +160,3 @@ def main(): # this is magic, see lib/ansible/module_common.py #<> main() - - From ddb191f208cc04411fe0c0b7610204f14340c5d5 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 5 Feb 2014 18:08:01 -0500 Subject: [PATCH 08/13] fixes as per feedback --- system/debconf | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/system/debconf b/system/debconf index 7324e7de6f1..639232ab74f 100644 --- a/system/debconf +++ b/system/debconf @@ -45,7 +45,7 @@ options: required: false default: null aliases: ['question', 'selection'] - type: + vtype: description: - The type of the value supplied required: false @@ -57,7 +57,7 @@ options: - Value to set the configuration to required: false default: null - aliases: ['awnser'] + aliases: ['answer'] unseen: description: - Do not set 'seen' flag when pre-seeding @@ -76,33 +76,33 @@ debconf: name=locales setting='locales/default_environment_locale' value=fr_FR.U debconf: name=locales setting='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' # Accept oracle license -debconf: names='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' type='select' +debconf: names='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' ''' 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: - selections = {} - for line in out.splitlines(): - #if not line.startswith('*'): # only awnsered - # continue - (key, value) = line.split(':') - selections[ key.strip('*').strip() ] = value.strip() - return selections - else: + if rc != 0: module.fail_json(msg=err) + selections = {} + + for line in out.splitlines(): + (key, value) = line.split(':') + selections[ key.strip('*').strip() ] = value.strip() + + return selections + -def set_selection(module, pkg, question, type, value, unseen): +def set_selection(module, pkg, question, vtype, value, unseen): - awnser = [ question ] - if 'type': - awnser.append(type) - awnser.append(value) + answer = [ question ] + if 'vtype': + answer.append(vtype) + answer.append(value) - data = ' '.join(awnser) + data = ' '.join(answer) setsel = module.get_bin_path('debconf-set-selections', True) cmd = ["echo '%s %s' |" % (pkg, data), setsel] @@ -117,7 +117,7 @@ def main(): argument_spec = dict( name = dict(required=True, aliases=['pkg'], type='str'), setting = dict(required=False, aliases=['question', 'selection'], type='str'), - type = dict(required=False, type='str', choices=['string', 'boolean', 'select', 'multiselect', 'note', 'text', 'password', 'title']), + vtype = dict(required=False, type='str', choices=['string', 'boolean', 'select', 'multiselect', 'note', 'text', 'password', 'title']), value= dict(required=False, type='str'), unseen = dict(required=False, type='bool'), ), @@ -127,7 +127,7 @@ def main(): #TODO: enable passing array of optionas and/or debconf file from get-selections dump pkg = module.params["name"] question = module.params["setting"] - type = module.params["type"] + vtype = module.params["vtype"] value = module.params["value"] unseen = module.params["unseen"] @@ -143,7 +143,7 @@ def main(): if changed: if not module.check_mode: - rc, msg, e = set_selection(module, pkg, question, type, value, unseen) + rc, msg, e = set_selection(module, pkg, question, vtype, value, unseen) if rc: module.fail_json(msg=e) @@ -157,6 +157,5 @@ def main(): module.exit_json(changed=changed, msg=msg, current=prev) -# this is magic, see lib/ansible/module_common.py -#<> -main() +# import module snippets +from ansible.module_utils.basic import * From 8a6a2aba75d4b80d823bc10bdeb393fcca966f06 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 5 Feb 2014 18:28:17 -0500 Subject: [PATCH 09/13] changes names to name in example --- system/debconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index 639232ab74f..35545343b26 100644 --- a/system/debconf +++ b/system/debconf @@ -76,7 +76,7 @@ debconf: name=locales setting='locales/default_environment_locale' value=fr_FR.U debconf: name=locales setting='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' # Accept oracle license -debconf: names='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' +debconf: name='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' ''' def get_selections(module, pkg): From c11fbd54e10dab66b1d3f3884b471f4647e0ae2e Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 6 Feb 2014 11:59:37 -0500 Subject: [PATCH 10/13] fixed main() issue created in prev fix, now values are empty string if they were None Signed-off-by: Brian Coca --- system/debconf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index 35545343b26..52c646e23c8 100644 --- a/system/debconf +++ b/system/debconf @@ -100,8 +100,10 @@ def set_selection(module, pkg, question, vtype, value, unseen): answer = [ question ] if 'vtype': answer.append(vtype) - answer.append(value) + if value is None: + value = '' + answer.append(value) data = ' '.join(answer) setsel = module.get_bin_path('debconf-set-selections', True) @@ -159,3 +161,5 @@ def main(): # import module snippets from ansible.module_utils.basic import * + +main() From 4b0c2d839e7e0346feeba10f269c8066aae21a8f Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sun, 9 Feb 2014 17:46:18 -0500 Subject: [PATCH 11/13] made changes as per feedback: - field names are more consistent with debconf - values are now 'booleanized' or accepted as list/set objects when pertinent - updated docs to reflect all of the above and debconf cli tools required --- system/debconf | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/system/debconf b/system/debconf index 52c646e23c8..e7560ddfff4 100644 --- a/system/debconf +++ b/system/debconf @@ -26,9 +26,10 @@ DOCUMENTATION = ''' module: debconf short_description: Configure a .deb package description: - - Configure a .deb package using debconf-set-selections + - Configure a .deb package using debconf-set-selections. version_added: "1.5" notes: + - This module requires the command line debconf tools. - A number of questions have to be answered (depending on the package). Use 'debconf-show ' on any Debian or derivative with the package installed to see questions/settings available. @@ -39,12 +40,12 @@ options: required: true default: null aliases: ['pkg'] - setting: + question: description: - A debconf configuration setting required: false default: null - aliases: ['question', 'selection'] + aliases: ['setting', 'selection'] vtype: description: - The type of the value supplied @@ -70,10 +71,10 @@ author: Brian Coca EXAMPLES = ''' # Set default locale to fr_FR.UTF-8 -debconf: name=locales setting='locales/default_environment_locale' value=fr_FR.UTF-8 +debconf: name=locales question='locales/default_environment_locale' value=fr_FR.UTF-8 # set to generate locales: -debconf: name=locales setting='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' +debconf: name=locales question='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' # Accept oracle license debconf: name='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' @@ -118,7 +119,7 @@ def main(): module = AnsibleModule( argument_spec = dict( name = dict(required=True, aliases=['pkg'], type='str'), - setting = dict(required=False, aliases=['question', 'selection'], type='str'), + question = dict(required=False, aliases=['setting', 'selection'], type='str'), vtype = dict(required=False, type='str', choices=['string', 'boolean', 'select', 'multiselect', 'note', 'text', 'password', 'title']), value= dict(required=False, type='str'), unseen = dict(required=False, type='bool'), @@ -128,7 +129,7 @@ def main(): #TODO: enable passing array of optionas and/or debconf file from get-selections dump pkg = module.params["name"] - question = module.params["setting"] + question = module.params["question"] vtype = module.params["vtype"] value = module.params["value"] unseen = module.params["unseen"] @@ -139,6 +140,12 @@ def main(): changed = False msg = "" + # Adjust value field if needed + if vtype == 'boolean': + value = boolean(value) + elif vtype == 'multiselect' and (isisntance(value, list) or isinstace(value, set)): + value = ','.join(value) + if question is not None: if not question in prev or prev[question] != value: changed = True From 01a1482f1a4075a7b5ce015d00c5a5f92243c489 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sun, 9 Feb 2014 20:47:01 -0500 Subject: [PATCH 12/13] hopefully last batch of fixes - removed previous 'typification' of input as it needs it is typed by module as strings and needs to be output as strings, making it useless. - now checks for vtype and value against None when question is specified - simplified set_selections as vtype and value should have a string value going in. - added example of querying questions for a package - added module requirement of question,vtype and value being required together. --- system/debconf | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/system/debconf b/system/debconf index e7560ddfff4..44e5dc33b69 100644 --- a/system/debconf +++ b/system/debconf @@ -26,7 +26,8 @@ DOCUMENTATION = ''' module: debconf short_description: Configure a .deb package description: - - Configure a .deb package using debconf-set-selections. + - Configure a .deb package using debconf-set-selections. Or just query + existing selections. version_added: "1.5" notes: - This module requires the command line debconf tools. @@ -78,6 +79,9 @@ debconf: name=locales question='locales/locales_to_be_generated value='en_US.UT # Accept oracle license debconf: name='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' + +# Specifying package you can register/return the list of questions and current values +debconf: name='tzdata' ''' def get_selections(module, pkg): @@ -98,14 +102,7 @@ def get_selections(module, pkg): def set_selection(module, pkg, question, vtype, value, unseen): - answer = [ question ] - if 'vtype': - answer.append(vtype) - - if value is None: - value = '' - answer.append(value) - data = ' '.join(answer) + data = ' '.join([ question, vtype, value ]) setsel = module.get_bin_path('debconf-set-selections', True) cmd = ["echo '%s %s' |" % (pkg, data), setsel] @@ -124,6 +121,7 @@ def main(): value= dict(required=False, type='str'), unseen = dict(required=False, type='bool'), ), + required_together = ( ['question','vtype', 'value'],), supports_check_mode=True, ) @@ -140,13 +138,10 @@ def main(): changed = False msg = "" - # Adjust value field if needed - if vtype == 'boolean': - value = boolean(value) - elif vtype == 'multiselect' and (isisntance(value, list) or isinstace(value, set)): - value = ','.join(value) - if question is not None: + if vtype is None or value is None: + module.fail_json(msg="when supliying a question you must supply a valide vtype and value") + if not question in prev or prev[question] != value: changed = True From a4f6a121811075b7e1f5f3a5fe76341748b6feb9 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sat, 1 Mar 2014 22:28:51 -0500 Subject: [PATCH 13/13] didnt make 1.5 ... lets see --- system/debconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/debconf b/system/debconf index 44e5dc33b69..ea2020b8876 100644 --- a/system/debconf +++ b/system/debconf @@ -28,7 +28,7 @@ short_description: Configure a .deb package description: - Configure a .deb package using debconf-set-selections. Or just query existing selections. -version_added: "1.5" +version_added: "1.6" notes: - This module requires the command line debconf tools. - A number of questions have to be answered (depending on the package).