From 38a2ee7751fa1cdbbda51935c31823b81924b5f3 Mon Sep 17 00:00:00 2001 From: Philippe Makowski Date: Fri, 8 Nov 2013 21:43:19 +0100 Subject: [PATCH] urpmi module --- library/packaging/urpmi | 184 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 library/packaging/urpmi diff --git a/library/packaging/urpmi b/library/packaging/urpmi new file mode 100644 index 0000000000..4ff01a7413 --- /dev/null +++ b/library/packaging/urpmi @@ -0,0 +1,184 @@ +#!/usr/bin/python -tt +# -*- coding: utf-8 -*- + +# (c) 2013, Philippe Makowski +# Written by Philippe Makowski +# Based on apt module written by Matthew Williams +# +# This module 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. +# +# This software 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 this software. If not, see . + + +DOCUMENTATION = ''' +--- +module: urpmi +short_description: Urpmi manager +description: + - Manages packages with I(urpmi) (such as for Mageia or Mandriva) +version_added: "1.3.4" +options: + pkg: + description: + - name of package to install, upgrade or remove. + required: true + default: null + state: + description: + - Indicates the desired package state + required: false + default: present + choices: [ "absent", "present" ] + update_cache: + description: + - update the package database first C(urpmi.update -a). + required: false + default: no + choices: [ "yes", "no" ] + no-suggests: + description: + - Corresponds to the C(--no-suggests) option for I(urpmi). + required: false + default: yes + choices: [ "yes", "no" ] + force: + description: + - Corresponds to the C(--force) option for I(urpmi). + required: false + default: yes + choices: [ "yes", "no" ] +author: Philippe Makowski +notes: [] +''' + +EXAMPLES = ''' +# install package foo +- urpmi: pkg=foo state=present +# remove package foo +- urpmi: pkg=foo state=absent +# description: remove packages foo and bar +- urpmi: pkg=foo,bar state=absent +# description: update the package database (urpmi.update -a -q) and install bar (bar will be the updated if a newer version exists) +- urpmi: name=bar, state=present, update_cache=yes +''' + + +import json +import shlex +import os +import sys + +URPMI_PATH = '/usr/sbin/urpmi' +URPME_PATH = '/usr/sbin/urpme' + +def query_package(module, name): + + # rpm -q returns 0 if the package is installed, + # 1 if it is not installed + rc = os.system("rpm -q %s" % (name)) + if rc == 0: + return True + else: + return False + + +def update_package_db(module): + rc = os.system("urpmi.update -a -q") + + if rc != 0: + module.fail_json(msg="could not update package db") + + +def remove_packages(module, packages): + + remove_c = 0 + # Using a for loop incase of error, we can report the package that failed + for package in packages: + # Query the package first, to see if we even need to remove + if not query_package(module, package): + continue + + rc = os.system("%s --auto %s > /dev/null" % (URPME_PATH, package)) + + if rc != 0: + module.fail_json(msg="failed to remove %s" % (package)) + + remove_c += 1 + + if remove_c > 0: + + module.exit_json(changed=True, msg="removed %s package(s)" % remove_c) + + module.exit_json(changed=False, msg="package(s) already absent") + + +def install_packages(module, pkgspec, force=True, no_suggests=True): + + packages = "" + for package in pkgspec: + packages += "'%s' " % package + + if len(packages) != 0: + if no_suggests: + no_suggests_yes = '--no-suggests' + else: + no_suggests_yes = '' + + if force: + force_yes = '--force' + else: + force_yes = '' + + cmd = ("%s --auto %s --quiet %s %s > /dev/null" % (URPMI_PATH, force_yes, no_suggests_yes, packages)) + + rc, out, err = module.run_command(cmd) + if rc: + module.fail_json(msg="'urpmi %s' failed: %s" % (packages, err)) + else: + module.exit_json(changed=True, msg="%s present(s)" % packages) + else: + module.exit_json(changed=False) + + +def main(): + module = AnsibleModule( + argument_spec = dict( + state = dict(default='installed', choices=['installed', 'removed', 'absent', 'present']), + update_cache = dict(default=False, aliases=['update-cache'], type='bool'), + force = dict(default=True, type='bool'), + no_suggests = dict(default=True, aliases=['no-suggests'], type='bool'), + package = dict(aliases=['pkg', 'name'], required=True))) + + + if not os.path.exists(URPMI_PATH): + module.fail_json(msg="cannot find urpmi, looking for %s" % (URPMI_PATH)) + + p = module.params + + force_yes = p['force'] + no_suggest_yes = p['no_suggests'] + + if p['update_cache']: + update_package_db(module) + + packages = p['package'].split(',') + + if p['state'] in [ 'installed', 'present' ]: + install_packages(module, packages, force_yes, no_suggest_yes) + + elif p['state'] in [ 'removed', 'absent' ]: + remove_packages(module, packages) + +# this is magic, see lib/ansible/module_common.py +#<> + +main()