Add library module for dpkg-reconfigure
This commit is contained in:
parent
76ace23b5e
commit
877e651917
174
library/dpkg_reconfigure
Normal file
174
library/dpkg_reconfigure
Normal file
@ -0,0 +1,174 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Ansible module for reconfiguring debian packages.
|
||||
(c) 2013, Sebastien Bocahu <sebastien.bocahu@nuxit.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: dpkg_reconfigure
|
||||
short_description: Reconfigure a Debian package.
|
||||
description:
|
||||
- Reconfigure a Debian package using dpkg-reconfigure.
|
||||
version_added: "1.2"
|
||||
notes:
|
||||
- A number of questions has to be answered (depending on the package).
|
||||
Use 'DEBIAN_FRONTED=editor dpkg-reconfigure $pkg' for finding them.
|
||||
options:
|
||||
pkg:
|
||||
description:
|
||||
- Package to configure.
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
answers:
|
||||
description:
|
||||
- Debconf configuration answer(s)/question(s).
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
author: Sebastien Bocahu
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Set default locale to fr_FR.UTF-8, and generate en_US.UTF-8 as well:
|
||||
dpkg_reconfigure:
|
||||
pkg: locales
|
||||
answers:
|
||||
locales/default_environment_locale: fr_FR.UTF-8
|
||||
locales/locales_to_be_generated: en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8
|
||||
|
||||
# Reconfigure roundcube, using configuration answers stored in a file:
|
||||
dpkg_reconfigure: pkg=roundcube answers='$FILE(/path/dpkg-reconfigure/roundcube)'"
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pwd
|
||||
import os.path
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
def get_selections(module, pkg):
|
||||
cmd = [module.get_bin_path('debconf-show', True)]
|
||||
cmd.append(' %s' % pkg)
|
||||
rc, out, err = module.run_command(' '.join(cmd))
|
||||
|
||||
if rc == 0:
|
||||
selections = {}
|
||||
for answer in out.split('\n'):
|
||||
item = re.search('^[* ] ([^:]+): (.*)$', answer)
|
||||
if item:
|
||||
value = item.group(2).strip()
|
||||
if value == 'true':
|
||||
value = 'yes'
|
||||
elif value == 'false':
|
||||
value = 'no'
|
||||
selections[ item.group(1).strip() ] = value
|
||||
return selections
|
||||
else:
|
||||
module.fail_json(msg=err)
|
||||
|
||||
|
||||
def dpkg_reconfigure(module, pkg, wanted_config):
|
||||
editor_script = [ '#!/bin/sh', 'sed -i "$1" -f - <<EOF' ]
|
||||
for question in wanted_config:
|
||||
e_question = re.sub(r'([\\/&])', r'\\\1', question)
|
||||
e_answer = re.sub(r'([\\/&])', r'\\\1', wanted_config[question])
|
||||
editor_script.append('s/^\\(%s\\)\\s*=.*/\\1="%s"/' % (e_question, e_answer))
|
||||
editor_script.append('EOF')
|
||||
|
||||
outfd, outsock_path = tempfile.mkstemp()
|
||||
tmp = os.fdopen(outfd,'w')
|
||||
tmp.write('\n'.join(editor_script))
|
||||
tmp.close()
|
||||
os.chmod(outsock_path, stat.S_IEXEC)
|
||||
|
||||
cmd = [ 'EDITOR=%s DEBIAN_FRONTEND=editor' % outsock_path ]
|
||||
cmd.append(module.get_bin_path('dpkg-reconfigure', True))
|
||||
cmd.append(pkg)
|
||||
rc, out, err = module.run_command(' '.join(cmd), use_unsafe_shell=True)
|
||||
os.unlink(outsock_path)
|
||||
|
||||
if rc == 0:
|
||||
return True, err
|
||||
else:
|
||||
return False, err
|
||||
|
||||
|
||||
def enforce_state(module, params):
|
||||
|
||||
pkg = params["pkg"]
|
||||
answers = params["answers"]
|
||||
|
||||
wanted_config = {}
|
||||
|
||||
if type(answers) is dict:
|
||||
wanted_config = answers
|
||||
else:
|
||||
for answer in answers.split('\n'):
|
||||
item = re.findall(r"[^\s]+", answer)
|
||||
if len(item) > 1:
|
||||
wanted_config[ item[0].strip() ] = ' '.join(item[1:])
|
||||
elif len(item) == 1:
|
||||
wanted_config[ item[0].strip() ] = ''
|
||||
|
||||
for key in wanted_config:
|
||||
value = wanted_config[key]
|
||||
if isinstance(value, bool):
|
||||
if value:
|
||||
wanted_config[key] = 'yes'
|
||||
else:
|
||||
wanted_config[key] = 'no'
|
||||
|
||||
current_config = get_selections(module, params["pkg"])
|
||||
|
||||
already_configured = 1
|
||||
for answer in wanted_config:
|
||||
if not answer in current_config or current_config[answer] != wanted_config[answer]:
|
||||
already_configured = 0
|
||||
|
||||
if already_configured:
|
||||
module.exit_json(changed=False, msg="Already configured")
|
||||
else:
|
||||
rc, msg = dpkg_reconfigure(module, pkg, wanted_config)
|
||||
if not rc:
|
||||
module.fail_json(msg=msg)
|
||||
|
||||
params['changed'] = True
|
||||
params['msg'] = msg
|
||||
return params
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
pkg = dict(required=True),
|
||||
answers = dict(required=True),
|
||||
)
|
||||
)
|
||||
|
||||
results = enforce_state(module, module.params)
|
||||
module.exit_json(**results)
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
|
||||
main()
|
Loading…
Reference in New Issue
Block a user