diff --git a/library/svr4pkg b/library/svr4pkg new file mode 100644 index 00000000000..7c776d3f923 --- /dev/null +++ b/library/svr4pkg @@ -0,0 +1,177 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Boyd Adamson +# +# 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 . +# + +DOCUMENTATION = ''' +--- +module: svr4pkg +short_description: Manage Solaris SVR4 packages +description: + - Manages SVR4 packages on Solaris 10 and 11. + - These were the native packages on Solaris <= 10 and are available + as a legacy feature in Solaris 11. + - Note that this is a very basic packaging system. It will not enforce + dependencies on install or remove. +version_added: 0.9 +author: Boyd Adamson +options: + name: + description: + - Package name, e.g. C(SUNWcsr) + required: true + + state: + description: + - Whether to install (C(present)), or remove (C(absent)) a package. + - If the package is to be installed, then C(src) is required. + - The SVR4 package system doesn't provide an upgrade operation. You need to uninstall the old, then install the new package. + required: true + choices: ["present", "absent"] + + src: + description: + - Specifies the location to install the package from. Required when C(state=present). + - Can be any path acceptable to the C(pkgadd) command's C(-d) option. e.g.: C(somefile.pkg), C(/dir/with/pkgs), C(http:/server/mypkgs.pkg). + - If using a file or directory, they must already be accessible by the host. See the I(copy) module for a way to get them there. + proxy: + description: + - HTTP[s] proxy to be used if C(src) is a URL. + +examples: + - code: svr4pkg name=CSWcommon src=/tmp/cswpkgs.pkg state=present + description: Install a package from an already copied file + - code: svr4pkg name=CSWpkgutil src=http://get.opencsw.org/now state=present + description: Install a package directly from an http site + - code: svr4pkg name=SUNWgnome-sound-recorder state=absent + description: Ensure that a package is not installed. +''' +import os +import tempfile + +def package_installed(module, name): + cmd = [module.get_bin_path('pkginfo', True)] + cmd.append('-q') + cmd.append(name) + res = subprocess.call(cmd) + if res == 0: + return True + else: + return False + +def create_admin_file(): + (desc, filename) = tempfile.mkstemp(prefix='ansible_svr4pkg', text=True) + fullauto = ''' +mail= +instance=unique +partial=nocheck +runlevel=quit +idepend=nocheck +rdepend=nocheck +space=quit +setuid=nocheck +conflict=nocheck +action=nocheck +networktimeout=60 +networkretries=3 +authentication=quit +keystore=/var/sadm/security +proxy= +basedir=default +''' + os.write(desc, fullauto) + os.close(desc) + return filename + +def run_command(module, cmd): + progname = cmd[0] + cmd[0] = module.get_bin_path(progname, True) + p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = p.communicate() + rc = p.returncode + return (rc, out, err) + +def package_install(module, name, src, proxy): + adminfile = create_admin_file() + cmd = [ 'pkgadd', '-na', adminfile, '-d', src ] + if proxy is not None: + cmd += [ '-x', proxy ] + cmd.append(name) + (rc, out, err) = run_command(module, cmd) + os.unlink(adminfile) + return (rc, out, err) + +def package_uninstall(module, name, src): + adminfile = create_admin_file() + cmd = [ 'pkgrm', '-na', adminfile, name] + (rc, out, err) = run_command(module, cmd) + os.unlink(adminfile) + return (rc, out, err) + +def main(): + module = AnsibleModule( + argument_spec = dict( + name = dict(required = True), + state = dict(required = True, choices=['present', 'absent']), + src = dict(default = None), + proxy = dict(default = None) + ) + ) + state = module.params['state'] + name = module.params['name'] + src = module.params['src'] + proxy = module.params['proxy'] + rc = None + out = '' + err = '' + result = {} + result['name'] = name + result['state'] = state + + if state == 'present': + if src is None: + module.fail_json(name=name, + msg="src is required when state=present") + if not package_installed(module, name): + (rc, out, err) = package_install(module, name, src, proxy) + # Stdout is normally empty but for some packages can be + # very long and is not often useful + if len(out) > 75: + out = out[:75] + '...' + + elif state == 'absent': + if package_installed(module, name): + (rc, out, err) = package_uninstall(module, name, src) + out = out[:75] + + if rc is None: + result['changed'] = False + else: + result['changed'] = True + + if out: + result['stdout'] = out + if err: + result['stderr'] = err + + module.exit_json(**result) + +# include magic from lib/ansible/module_common.py +#<> +main()