From 76142ddb9721143f44b36b7507393e0413fcbdbc Mon Sep 17 00:00:00 2001 From: Robin Roth Date: Thu, 4 Dec 2014 11:25:06 +0100 Subject: [PATCH 1/3] Allow multiple versions in rpm state Fix bug in ansible get_package_state and get_current_version that breaks when there are multiple versions of a package installed and there is a list of packages to install. The previous implementation used 'zip' to match requested names to installed names which fails, because rpm outputs multiple lines per package when there are multiple versions. Testcase: Install opensuse, install multiple kernel versions (happens by update) Before patch: calling zypper: state=present for name={{item}} with_items: - kernel-desktop - git leads to ansible aborting. After the patch ansible performs as expected and makes sure both packages are present. Also the last version number is used for further update information in this version (before if only one package name was given the oldest version number was used). --- packaging/os/zypper.py | 48 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/packaging/os/zypper.py b/packaging/os/zypper.py index 87bbcd1f135..7091145423b 100644 --- a/packaging/os/zypper.py +++ b/packaging/os/zypper.py @@ -95,25 +95,31 @@ def zypper_version(module): return rc, stderr # Function used for getting versions of currently installed packages. -def get_current_version(m, name): +def get_current_version( packages): cmd = ['/bin/rpm', '-q', '--qf', '%{NAME} %{VERSION}-%{RELEASE}\n'] - cmd.extend(name) - (rc, stdout, stderr) = m.run_command(cmd) + cmd.extend(packages) + + stdout = subprocess.check_output(cmd) current_version = {} rpmoutput_re = re.compile('^(\S+) (\S+)$') - for stdoutline, package in zip(stdout.splitlines(), name): - m = rpmoutput_re.match(stdoutline) - if m == None: + + for stdoutline in stdout.splitlines(): + match = rpmoutput_re.match(stdoutline) + if match == None: return None - rpmpackage = m.group(1) - rpmversion = m.group(2) - if package != rpmpackage: + package = match.group(1) + version = match.group(2) + current_version[package] = version + + for package in packages: + if package not in current_version: + print package + ' was not returned by rpm \n' return None - current_version[package] = rpmversion return current_version + # Function used to find out if a package is currently installed. def get_package_state(m, packages): cmd = ['/bin/rpm', '--query', '--qf', 'package %{NAME} is installed\n'] @@ -123,19 +129,21 @@ def get_package_state(m, packages): installed_state = {} rpmoutput_re = re.compile('^package (\S+) (.*)$') - for stdoutline, name in zip(stdout.splitlines(), packages): - m = rpmoutput_re.match(stdoutline) - if m == None: - return None - package = m.group(1) - result = m.group(2) - if not name.startswith(package): - print name + ':' + package + ':' + stdoutline + '\n' + for stdoutline in stdout.splitlines(): + match = rpmoutput_re.match(stdoutline) + if match == None: return None + package = match.group(1) + result = match.group(2) if result == 'is installed': - installed_state[name] = True + installed_state[package] = True else: - installed_state[name] = False + installed_state[package] = False + + for package in packages: + if package not in installed_state: + print package + ' was not returned by rpm \n' + return None return installed_state From 7948b91bad04f0f3a13dc44bacaf74dc7464b24b Mon Sep 17 00:00:00 2001 From: Robin Roth Date: Thu, 4 Dec 2014 11:28:18 +0100 Subject: [PATCH 2/3] fix local change --- packaging/os/zypper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/os/zypper.py b/packaging/os/zypper.py index 7091145423b..c848e86fcc6 100644 --- a/packaging/os/zypper.py +++ b/packaging/os/zypper.py @@ -95,11 +95,11 @@ def zypper_version(module): return rc, stderr # Function used for getting versions of currently installed packages. -def get_current_version( packages): +def get_current_version(m, packages): cmd = ['/bin/rpm', '-q', '--qf', '%{NAME} %{VERSION}-%{RELEASE}\n'] cmd.extend(packages) - stdout = subprocess.check_output(cmd) + rc, stdout, stderr = m.run_command(cmd, check_rc=False) current_version = {} rpmoutput_re = re.compile('^(\S+) (\S+)$') From 23495a16f4f16982ef30f2994c9e405c9276bc78 Mon Sep 17 00:00:00 2001 From: Robin Roth Date: Thu, 29 Jan 2015 10:32:09 +0100 Subject: [PATCH 3/3] fixed tab/space mix --- packaging/os/zypper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/os/zypper.py b/packaging/os/zypper.py index c848e86fcc6..11f0380e81a 100644 --- a/packaging/os/zypper.py +++ b/packaging/os/zypper.py @@ -141,7 +141,7 @@ def get_package_state(m, packages): installed_state[package] = False for package in packages: - if package not in installed_state: + if package not in installed_state: print package + ' was not returned by rpm \n' return None