summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Likins <alikins@redhat.com>2017-02-15 10:06:25 -0500
committerAdrian Likins <alikins@redhat.com>2017-02-16 13:26:00 -0500
commite28cea7e0520f8d1b81e57a9951d55a4feb3e34b (patch)
treeade5fd302f18fece6bc64c98f1baf8625799819f
parent5609d34abdd635e9a6c413927e6a9d38350ad224 (diff)
downloadansible-modules-core-e28cea7e0520f8d1b81e57a9951d55a4feb3e34b.tar.gz
Fix 'yum skips updates' bug (#21113)
When the 'yum check-update' output is parsed, the regex used to stitch wrapped lines together would fail on the first package. It would fail because there is an empty line before the first package, and this triggered the regex. To avoid a more complicated regex, preprocess the check-update output to strip out any empty lines. The regex is also updated to include a group on the non whitespace match to be used in the sub. Add test cases based on info provided in the bug reports. Fixes #20608 (backport of commit e511326222c908f8879f1283571234eda14f5471 from ansible/ansible) (cherry picked from commit 86c36e5e526b2aa9a14f0a462e7caf4adca41e8f)
-rw-r--r--packaging/os/yum.py67
1 files changed, 51 insertions, 16 deletions
diff --git a/packaging/os/yum.py b/packaging/os/yum.py
index 131144d8..4b0102ef 100644
--- a/packaging/os/yum.py
+++ b/packaging/os/yum.py
@@ -776,6 +776,53 @@ def remove(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
return res
+
+def run_check_update(module, yum_basecmd):
+ # run check-update to see if we have packages pending
+ rc, out, err = module.run_command(yum_basecmd + ['check-update'])
+ return rc, out, err
+
+
+def parse_check_update(check_update_output):
+ updates = {}
+
+ # remove incorrect new lines in longer columns in output from yum check-update
+ # yum line wrapping can move the repo to the next line
+ #
+ # Meant to filter out sets of lines like:
+ # some_looooooooooooooooooooooooooooooooooooong_package_name 1:1.2.3-1.el7
+ # some-repo-label
+ #
+ # But it also needs to avoid catching lines like:
+ # Loading mirror speeds from cached hostfile
+ #
+ # ceph.x86_64 1:11.2.0-0.el7 ceph
+
+ # preprocess string and filter out empty lines so the regex below works
+ out = re.sub('\n[^\w]\W+(.*)', ' \1',
+ check_update_output)
+
+ available_updates = out.split('\n')
+
+ # build update dictionary
+ for line in available_updates:
+ line = line.split()
+ # ignore irrelevant lines
+ # '*' in line matches lines like mirror lists:
+ # * base: mirror.corbina.net
+ # len(line) != 3 could be junk or a continuation
+ #
+ # FIXME: what is the '.' not in line conditional for?
+
+ if '*' in line or len(line) != 3 or '.' not in line[0]:
+ continue
+ else:
+ pkg, version, repo = line
+ name, dist = pkg.rsplit('.', 1)
+ updates.update({name: {'version': version, 'dist': dist, 'repo': repo}})
+ return updates
+
+
def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
res = {}
@@ -794,26 +841,13 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
if '*' in items:
update_all = True
- # run check-update to see if we have packages pending
- rc, out, err = module.run_command(yum_basecmd + ['check-update'])
+ rc, out, err = run_check_update(module, yum_basecmd)
+
if rc == 0 and update_all:
res['results'].append('Nothing to do here, all packages are up to date')
return res
elif rc == 100:
- # remove incorrect new lines in longer columns in output from yum check-update
- out=re.sub('\n\W+', ' ', out)
- available_updates = out.split('\n')
- # build update dictionary
- for line in available_updates:
- line = line.split()
- # ignore irrelevant lines
- # FIXME... revisit for something less kludgy
- if '*' in line or len(line) != 3 or '.' not in line[0]:
- continue
- else:
- pkg, version, repo = line
- name, dist = pkg.rsplit('.', 1)
- updates.update({name: {'version': version, 'dist': dist, 'repo': repo}})
+ updates = parse_check_update(out)
elif rc == 1:
res['msg'] = err
res['rc'] = rc
@@ -851,6 +885,7 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
nothing_to_do = False
break
+
# this contains the full NVR and spec could contain wildcards
# or virtual provides (like "python-*" or "smtp-daemon") while
# updates contains name only.