diff options
Diffstat (limited to 'ansible_collections/community/general/plugins/modules/urpmi.py')
-rw-r--r-- | ansible_collections/community/general/plugins/modules/urpmi.py | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/ansible_collections/community/general/plugins/modules/urpmi.py b/ansible_collections/community/general/plugins/modules/urpmi.py new file mode 100644 index 000000000..34e099e4d --- /dev/null +++ b/ansible_collections/community/general/plugins/modules/urpmi.py @@ -0,0 +1,221 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2013, Philippe Makowski +# Written by Philippe Makowski <philippem@mageia.org> +# Based on apt module written by Matthew Williams <matthew@flowroute.com> + +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: urpmi +short_description: Urpmi manager +description: + - Manages packages with I(urpmi) (such as for Mageia or Mandriva) +extends_documentation_fragment: + - community.general.attributes +attributes: + check_mode: + support: none + diff_mode: + support: none +options: + name: + description: + - A list of package names to install, upgrade or remove. + required: true + aliases: [ package, pkg ] + type: list + elements: str + state: + description: + - Indicates the desired package state. + choices: [ absent, present, installed, removed ] + default: present + type: str + update_cache: + description: + - Update the package database first C(urpmi.update -a). + type: bool + default: false + no_recommends: + description: + - Corresponds to the C(--no-recommends) option for I(urpmi). + type: bool + default: true + force: + description: + - Assume "yes" is the answer to any question urpmi has to ask. + Corresponds to the C(--force) option for I(urpmi). + type: bool + default: true + root: + description: + - Specifies an alternative install root, relative to which all packages will be installed. + Corresponds to the C(--root) option for I(urpmi). + aliases: [ installroot ] + type: str +author: +- Philippe Makowski (@pmakowski) +''' + +EXAMPLES = ''' +- name: Install package foo + community.general.urpmi: + pkg: foo + state: present + +- name: Remove package foo + community.general.urpmi: + pkg: foo + state: absent + +- name: Remove packages foo and bar + community.general.urpmi: + pkg: foo,bar + state: absent + +- name: Update the package database (urpmi.update -a -q) and install bar (bar will be the updated if a newer version exists) +- community.general.urpmi: + name: bar + state: present + update_cache: true +''' + + +from ansible.module_utils.basic import AnsibleModule + + +def query_package(module, name, root): + # rpm -q returns 0 if the package is installed, + # 1 if it is not installed + rpm_path = module.get_bin_path("rpm", True) + cmd = "%s -q %s %s" % (rpm_path, name, root_option(root)) + rc, stdout, stderr = module.run_command(cmd, check_rc=False) + if rc == 0: + return True + else: + return False + + +def query_package_provides(module, name, root): + # rpm -q returns 0 if the package is installed, + # 1 if it is not installed + rpm_path = module.get_bin_path("rpm", True) + cmd = "%s -q --whatprovides %s %s" % (rpm_path, name, root_option(root)) + rc, stdout, stderr = module.run_command(cmd, check_rc=False) + return rc == 0 + + +def update_package_db(module): + + urpmiupdate_path = module.get_bin_path("urpmi.update", True) + cmd = "%s -a -q" % (urpmiupdate_path,) + rc, stdout, stderr = module.run_command(cmd, check_rc=False) + if rc != 0: + module.fail_json(msg="could not update package db") + + +def remove_packages(module, packages, root): + + remove_c = 0 + # Using a for loop in case 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, root): + continue + + urpme_path = module.get_bin_path("urpme", True) + cmd = "%s --auto %s %s" % (urpme_path, root_option(root), package) + rc, stdout, stderr = module.run_command(cmd, check_rc=False) + + 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, root, force=True, no_recommends=True): + + packages = "" + for package in pkgspec: + if not query_package_provides(module, package, root): + packages += "'%s' " % package + + if len(packages) != 0: + if no_recommends: + no_recommends_yes = '--no-recommends' + else: + no_recommends_yes = '' + + if force: + force_yes = '--force' + else: + force_yes = '' + + urpmi_path = module.get_bin_path("urpmi", True) + cmd = ("%s --auto %s --quiet %s %s %s" % (urpmi_path, force_yes, + no_recommends_yes, + root_option(root), + packages)) + + rc, out, err = module.run_command(cmd) + + for package in pkgspec: + if not query_package_provides(module, package, root): + module.fail_json(msg="'urpmi %s' failed: %s" % (package, err)) + + # urpmi always have 0 for exit code if --force is used + 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 root_option(root): + if (root): + return "--root=%s" % (root) + else: + return "" + + +def main(): + module = AnsibleModule( + argument_spec=dict( + state=dict(type='str', default='present', + choices=['absent', 'installed', 'present', 'removed']), + update_cache=dict(type='bool', default=False), + force=dict(type='bool', default=True), + no_recommends=dict(type='bool', default=True), + name=dict(type='list', elements='str', required=True, aliases=['package', 'pkg']), + root=dict(type='str', aliases=['installroot']), + ), + ) + + p = module.params + + if p['update_cache']: + update_package_db(module) + + if p['state'] in ['installed', 'present']: + install_packages(module, p['name'], p['root'], p['force'], p['no_recommends']) + + elif p['state'] in ['removed', 'absent']: + remove_packages(module, p['name'], p['root']) + + +if __name__ == '__main__': + main() |