1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# (c) 2013, Raul Melo 5# Written by Raul Melo <raulmelo@gmail.com> 6# Based on yum module written by Seth Vidal <skvidal at fedoraproject.org> 7# 8# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 9 10from __future__ import absolute_import, division, print_function 11__metaclass__ = type 12 13 14ANSIBLE_METADATA = {'metadata_version': '1.1', 15 'status': ['preview'], 16 'supported_by': 'community'} 17 18 19DOCUMENTATION = ''' 20--- 21module: swdepot 22short_description: Manage packages with swdepot package manager (HP-UX) 23description: 24 - Will install, upgrade and remove packages with swdepot package manager (HP-UX) 25version_added: "1.4" 26notes: [] 27author: "Raul Melo (@melodous)" 28options: 29 name: 30 description: 31 - package name. 32 required: true 33 version_added: 1.4 34 state: 35 description: 36 - whether to install (C(present), C(latest)), or remove (C(absent)) a package. 37 required: true 38 choices: [ 'present', 'latest', 'absent'] 39 version_added: 1.4 40 depot: 41 description: 42 - The source repository from which install or upgrade a package. 43 version_added: 1.4 44''' 45 46EXAMPLES = ''' 47- swdepot: 48 name: unzip-6.0 49 state: present 50 depot: 'repository:/path' 51 52- swdepot: 53 name: unzip 54 state: latest 55 depot: 'repository:/path' 56 57- swdepot: 58 name: unzip 59 state: absent 60''' 61 62import re 63 64from ansible.module_utils.basic import AnsibleModule 65from ansible.module_utils.six.moves import shlex_quote 66 67 68def compare_package(version1, version2): 69 """ Compare version packages. 70 Return values: 71 -1 first minor 72 0 equal 73 1 first greater """ 74 75 def normalize(v): 76 return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")] 77 normalized_version1 = normalize(version1) 78 normalized_version2 = normalize(version2) 79 if normalized_version1 == normalized_version2: 80 rc = 0 81 elif normalized_version1 < normalized_version2: 82 rc = -1 83 else: 84 rc = 1 85 return rc 86 87 88def query_package(module, name, depot=None): 89 """ Returns whether a package is installed or not and version. """ 90 91 cmd_list = '/usr/sbin/swlist -a revision -l product' 92 if depot: 93 rc, stdout, stderr = module.run_command("%s -s %s %s | grep %s" % (cmd_list, shlex_quote(depot), shlex_quote(name), shlex_quote(name)), 94 use_unsafe_shell=True) 95 else: 96 rc, stdout, stderr = module.run_command("%s %s | grep %s" % (cmd_list, shlex_quote(name), shlex_quote(name)), use_unsafe_shell=True) 97 if rc == 0: 98 version = re.sub(r"\s\s+|\t", " ", stdout).strip().split()[1] 99 else: 100 version = None 101 102 return rc, version 103 104 105def remove_package(module, name): 106 """ Uninstall package if installed. """ 107 108 cmd_remove = '/usr/sbin/swremove' 109 rc, stdout, stderr = module.run_command("%s %s" % (cmd_remove, name)) 110 111 if rc == 0: 112 return rc, stdout 113 else: 114 return rc, stderr 115 116 117def install_package(module, depot, name): 118 """ Install package if not already installed """ 119 120 cmd_install = '/usr/sbin/swinstall -x mount_all_filesystems=false' 121 rc, stdout, stderr = module.run_command("%s -s %s %s" % (cmd_install, depot, name)) 122 if rc == 0: 123 return rc, stdout 124 else: 125 return rc, stderr 126 127 128def main(): 129 module = AnsibleModule( 130 argument_spec=dict( 131 name=dict(aliases=['pkg'], required=True), 132 state=dict(choices=['present', 'absent', 'latest'], required=True), 133 depot=dict(default=None, required=False) 134 ), 135 supports_check_mode=True 136 ) 137 name = module.params['name'] 138 state = module.params['state'] 139 depot = module.params['depot'] 140 141 changed = False 142 msg = "No changed" 143 rc = 0 144 if (state == 'present' or state == 'latest') and depot is None: 145 output = "depot parameter is mandatory in present or latest task" 146 module.fail_json(name=name, msg=output, rc=rc) 147 148 # Check local version 149 rc, version_installed = query_package(module, name) 150 if not rc: 151 installed = True 152 msg = "Already installed" 153 154 else: 155 installed = False 156 157 if (state == 'present' or state == 'latest') and installed is False: 158 if module.check_mode: 159 module.exit_json(changed=True) 160 rc, output = install_package(module, depot, name) 161 162 if not rc: 163 changed = True 164 msg = "Package installed" 165 166 else: 167 module.fail_json(name=name, msg=output, rc=rc) 168 169 elif state == 'latest' and installed is True: 170 # Check depot version 171 rc, version_depot = query_package(module, name, depot) 172 173 if not rc: 174 if compare_package(version_installed, version_depot) == -1: 175 if module.check_mode: 176 module.exit_json(changed=True) 177 # Install new version 178 rc, output = install_package(module, depot, name) 179 180 if not rc: 181 msg = "Package upgraded, Before " + version_installed + " Now " + version_depot 182 changed = True 183 184 else: 185 module.fail_json(name=name, msg=output, rc=rc) 186 187 else: 188 output = "Software package not in repository " + depot 189 module.fail_json(name=name, msg=output, rc=rc) 190 191 elif state == 'absent' and installed is True: 192 if module.check_mode: 193 module.exit_json(changed=True) 194 rc, output = remove_package(module, name) 195 if not rc: 196 changed = True 197 msg = "Package removed" 198 else: 199 module.fail_json(name=name, msg=output, rc=rc) 200 201 if module.check_mode: 202 module.exit_json(changed=False) 203 204 module.exit_json(changed=changed, name=name, state=state, msg=msg) 205 206 207if __name__ == '__main__': 208 main() 209