|
|
@ -0,0 +1,145 @@ |
|
|
|
#!/usr/bin/env python |
|
|
|
# Copyright 2017 Red Hat, Inc. |
|
|
|
# All Rights Reserved. |
|
|
|
# |
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
|
|
# not use this file except in compliance with the License. You may obtain |
|
|
|
# a copy of the License at |
|
|
|
# |
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
# |
|
|
|
# Unless required by applicable law or agreed to in writing, software |
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
|
|
# License for the specific language governing permissions and limitations |
|
|
|
# under the License. |
|
|
|
|
|
|
|
""" Check for available updates for a given package.""" |
|
|
|
|
|
|
|
import collections |
|
|
|
import subprocess |
|
|
|
|
|
|
|
from ansible.module_utils.basic import AnsibleModule |
|
|
|
from yaml import safe_load as yaml_safe_load |
|
|
|
|
|
|
|
DOCUMENTATION = ''' |
|
|
|
--- |
|
|
|
module: check_package_update |
|
|
|
short_description: Check for available updates for a given package |
|
|
|
description: |
|
|
|
- Check for available updates for a given package |
|
|
|
options: |
|
|
|
package: |
|
|
|
required: true |
|
|
|
description: |
|
|
|
- The name of the package you want to check |
|
|
|
type: str |
|
|
|
pkg_mgr: |
|
|
|
required: true |
|
|
|
description: |
|
|
|
- Supported Package Manager, DNF or YUM |
|
|
|
type: str |
|
|
|
author: "Florian Fuchs" |
|
|
|
''' |
|
|
|
|
|
|
|
EXAMPLES = ''' |
|
|
|
- hosts: webservers |
|
|
|
tasks: |
|
|
|
- name: Get available updates for packages |
|
|
|
check_package_update: |
|
|
|
package: python-tripleoclient |
|
|
|
pkg_mgr: "{{ ansible_pkg_mgr}}" |
|
|
|
''' |
|
|
|
|
|
|
|
SUPPORTED_PKG_MGRS = ( |
|
|
|
'yum', |
|
|
|
'dnf', |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
PackageDetails = collections.namedtuple('PackageDetails', |
|
|
|
['name', 'version', 'release', 'arch']) |
|
|
|
|
|
|
|
|
|
|
|
def get_package_details(output): |
|
|
|
if output: |
|
|
|
return PackageDetails( |
|
|
|
output.split('|')[0], |
|
|
|
output.split('|')[1], |
|
|
|
output.split('|')[2], |
|
|
|
output.split('|')[3], |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def _command(command): |
|
|
|
# Return the result of a subprocess call |
|
|
|
# as [stdout, stderr] |
|
|
|
process = subprocess.Popen(command, |
|
|
|
stdout=subprocess.PIPE, |
|
|
|
stderr=subprocess.PIPE, |
|
|
|
universal_newlines=True) |
|
|
|
return process.communicate() |
|
|
|
|
|
|
|
|
|
|
|
def check_update(module, package, pkg_mgr): |
|
|
|
if pkg_mgr not in SUPPORTED_PKG_MGRS: |
|
|
|
module.fail_json( |
|
|
|
msg='Package manager "{}" is not supported.'.format(pkg_mgr)) |
|
|
|
return |
|
|
|
|
|
|
|
installed_stdout, installed_stderr = _command( |
|
|
|
['rpm', '-qa', '--qf', |
|
|
|
'%{NAME}|%{VERSION}|%{RELEASE}|%{ARCH}', |
|
|
|
package]) |
|
|
|
|
|
|
|
# Fail the module if for some reason we can't lookup the current package. |
|
|
|
if installed_stderr != '': |
|
|
|
module.fail_json(msg=installed_stderr) |
|
|
|
return |
|
|
|
elif not installed_stdout: |
|
|
|
module.fail_json( |
|
|
|
msg='"{}" is not an installed package.'.format(package)) |
|
|
|
return |
|
|
|
|
|
|
|
installed = get_package_details(installed_stdout) |
|
|
|
|
|
|
|
pkg_mgr_option = 'available' |
|
|
|
if pkg_mgr == 'dnf': |
|
|
|
pkg_mgr_option = '--available' |
|
|
|
|
|
|
|
available_stdout, available_stderr = _command( |
|
|
|
[pkg_mgr, '-q', 'list', pkg_mgr_option, installed.name]) |
|
|
|
|
|
|
|
if available_stdout: |
|
|
|
new_pkg_info = available_stdout.split('\n')[1].rstrip().split()[:2] |
|
|
|
new_ver, new_rel = new_pkg_info[1].split('-') |
|
|
|
|
|
|
|
module.exit_json( |
|
|
|
changed=False, |
|
|
|
name=installed.name, |
|
|
|
current_version=installed.version, |
|
|
|
current_release=installed.release, |
|
|
|
new_version=new_ver, |
|
|
|
new_release=new_rel) |
|
|
|
else: |
|
|
|
module.exit_json( |
|
|
|
changed=False, |
|
|
|
name=installed.name, |
|
|
|
current_version=installed.version, |
|
|
|
current_release=installed.release, |
|
|
|
new_version=None, |
|
|
|
new_release=None) |
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
module = AnsibleModule( |
|
|
|
argument_spec=yaml_safe_load(DOCUMENTATION)['options'] |
|
|
|
) |
|
|
|
|
|
|
|
check_update(module, |
|
|
|
module.params.get('package'), |
|
|
|
module.params.get('pkg_mgr')) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
main() |