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).
This commit is contained in:
parent
19e688b017
commit
76142ddb97
1 changed files with 28 additions and 20 deletions
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue