From bdf6819c71b4b8f1f34a14eab6820e8e96da7382 Mon Sep 17 00:00:00 2001 From: bleader Date: Fri, 10 May 2013 14:15:01 +0200 Subject: [PATCH] new module to handle FreeBSD packages with pkgng New binary package management should be the default soon in FreeBSD, and is already fully useable through self generated and non official binary repositories. - add support for pkgng - support specifying the repository url as a parameter - allow not to update cache Signed-off-by: bleader --- library/packaging/pkgng | 157 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 library/packaging/pkgng diff --git a/library/packaging/pkgng b/library/packaging/pkgng new file mode 100644 index 00000000000..ec0469bdc36 --- /dev/null +++ b/library/packaging/pkgng @@ -0,0 +1,157 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2013, bleader +# Written by bleader +# Based on pkgin module written by Shaun Zinck +# that was based on pacman module written by Afterburn +# that was 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: pkgng +short_description: Package manager for FreeBSD >= 9.0 +description: + - Manage binary packages for FreeBSD using 'pkgng' which + is available in versions after 9.0. +version_added: "1.2" +options: + name: + description: + - name of package to install/remove + required: true + state: + description: + - state of the package + choices: [ 'present', 'absent' ] + required: false + default: present + cached: + description: + - use local package base or try to fetch an updated one + choices: [ 'yes', 'no' ] + required: false + default: no + pkgsite: + description: + - specify packagesite to use for downloading packages, if + not specified, use settings from /usr/local/etc/pkg.conf + required: false +author: bleader +notes: + - When using pkgsite, be careful that already in cache packages won't be downloaded again. +examples: + - code: "pkgng: name=foo state=present" + description: install package foo" + - code: "pkgng: name=foo state=absent" + description: remove package foo + - code: "pkgng: name=foo,bar state=absent" + description: remove packages foo and bar +''' + + +import json +import shlex +import os +import sys + +def query_package(module, pkgin_path, name): + + rc, out, err = module.run_command("%s info -e %s" % (pkgin_path, name)) + + if rc == 0: + return True + + return False + + +def remove_packages(module, pkgin_path, 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, pkgin_path, package): + continue + + rc, out, err = module.run_command("%s delete -y %s" % (pkgin_path, package)) + + if query_package(module, pkgin_path, package): + module.fail_json(msg="failed to remove %s: %s" % (package, out)) + + 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, pkgin_path, packages, cached, pkgsite): + + install_c = 0 + + if pkgsite != "": + pkgsite="PACKAGESITE=%s" % (pkgsite) + + if cached == "no": + rc, out, err = module.run_command("%s %s update" % (pkgsite, pkgin_path)) + if rc != 0: + module.fail_json(msg="Could not update catalogue") + + for package in packages: + if query_package(module, pkgin_path, package): + continue + + rc, out, err = module.run_command("%s %s install -U -y %s" % (pkgsite, pkgin_path, package)) + + if not query_package(module, pkgin_path, package): + module.fail_json(msg="failed to install %s: %s" % (package, out)) + + install_c += 1 + + if install_c > 0: + module.exit_json(changed=True, msg="present %s package(s)" % (install_c)) + + module.exit_json(changed=False, msg="package(s) already present") + + +def main(): + module = AnsibleModule( + argument_spec = dict( + state = dict(default="present", choices=["present","absent"]), + name = dict(aliases=["pkg"], required=True), + cached = dict(default="no", required=False, choices=["yes","no"]), + pkgsite = dict(default="", required=False))) + + pkgin_path = module.get_bin_path('pkg', True) + + p = module.params + + pkgs = p["name"].split(",") + + if p["state"] == "present": + install_packages(module, pkgin_path, pkgs, p["cached"], p["pkgsite"]) + + elif p["state"] == "absent": + remove_packages(module, pkgin_path, pkgs) + +# this is magic, see lib/ansible/module_common.py +#<> + +main()