#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (c) 2013, Raul Melo # Written by Raul Melo # Based on yum module written by Seth Vidal # # 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: swdepot short_description: Manage packages with swdepot package manager (HP-UX) description: - Will install, upgrade and remove packages with swdepot package manager (HP-UX) notes: [] author: "Raul Melo (@melodous)" extends_documentation_fragment: - community.general.attributes attributes: check_mode: support: full diff_mode: support: none options: name: description: - package name. aliases: [pkg] required: true type: str state: description: - whether to install (C(present), C(latest)), or remove (C(absent)) a package. required: true choices: [ 'present', 'latest', 'absent'] type: str depot: description: - The source repository from which install or upgrade a package. type: str ''' EXAMPLES = ''' - name: Install a package community.general.swdepot: name: unzip-6.0 state: present depot: 'repository:/path' - name: Install the latest version of a package community.general.swdepot: name: unzip state: latest depot: 'repository:/path' - name: Remove a package community.general.swdepot: name: unzip state: absent ''' import re from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six.moves import shlex_quote def compare_package(version1, version2): """ Compare version packages. Return values: -1 first minor 0 equal 1 first greater """ def normalize(v): return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")] normalized_version1 = normalize(version1) normalized_version2 = normalize(version2) if normalized_version1 == normalized_version2: rc = 0 elif normalized_version1 < normalized_version2: rc = -1 else: rc = 1 return rc def query_package(module, name, depot=None): """ Returns whether a package is installed or not and version. """ cmd_list = '/usr/sbin/swlist -a revision -l product' if depot: rc, stdout, stderr = module.run_command("%s -s %s %s | grep %s" % (cmd_list, shlex_quote(depot), shlex_quote(name), shlex_quote(name)), use_unsafe_shell=True) else: rc, stdout, stderr = module.run_command("%s %s | grep %s" % (cmd_list, shlex_quote(name), shlex_quote(name)), use_unsafe_shell=True) if rc == 0: version = re.sub(r"\s\s+|\t", " ", stdout).strip().split()[1] else: version = None return rc, version def remove_package(module, name): """ Uninstall package if installed. """ cmd_remove = '/usr/sbin/swremove' rc, stdout, stderr = module.run_command("%s %s" % (cmd_remove, name)) if rc == 0: return rc, stdout else: return rc, stderr def install_package(module, depot, name): """ Install package if not already installed """ cmd_install = '/usr/sbin/swinstall -x mount_all_filesystems=false' rc, stdout, stderr = module.run_command("%s -s %s %s" % (cmd_install, depot, name)) if rc == 0: return rc, stdout else: return rc, stderr def main(): module = AnsibleModule( argument_spec=dict( name=dict(aliases=['pkg'], required=True), state=dict(choices=['present', 'absent', 'latest'], required=True), depot=dict(default=None, required=False) ), supports_check_mode=True ) name = module.params['name'] state = module.params['state'] depot = module.params['depot'] changed = False msg = "No changed" rc = 0 if (state == 'present' or state == 'latest') and depot is None: output = "depot parameter is mandatory in present or latest task" module.fail_json(name=name, msg=output, rc=rc) # Check local version rc, version_installed = query_package(module, name) if not rc: installed = True msg = "Already installed" else: installed = False if (state == 'present' or state == 'latest') and installed is False: if module.check_mode: module.exit_json(changed=True) rc, output = install_package(module, depot, name) if not rc: changed = True msg = "Package installed" else: module.fail_json(name=name, msg=output, rc=rc) elif state == 'latest' and installed is True: # Check depot version rc, version_depot = query_package(module, name, depot) if not rc: if compare_package(version_installed, version_depot) == -1: if module.check_mode: module.exit_json(changed=True) # Install new version rc, output = install_package(module, depot, name) if not rc: msg = "Package upgraded, Before " + version_installed + " Now " + version_depot changed = True else: module.fail_json(name=name, msg=output, rc=rc) else: output = "Software package not in repository " + depot module.fail_json(name=name, msg=output, rc=rc) elif state == 'absent' and installed is True: if module.check_mode: module.exit_json(changed=True) rc, output = remove_package(module, name) if not rc: changed = True msg = "Package removed" else: module.fail_json(name=name, msg=output, rc=rc) if module.check_mode: module.exit_json(changed=False) module.exit_json(changed=changed, name=name, state=state, msg=msg) if __name__ == '__main__': main()