Fix pacman: "IndexError: list index out of range" #63077 (#65750)

* Fix #63077

If the package is already installed the stdout is not as expected by this function. Either remove `--needed` or just noop if we detect pacman returning. We cannot match the stdout string, as that is most likely localized.

```
[root@archBook user]# /usr/bin/pacman --upgrade --noconfirm --noprogressbar --needed  /srv/aur/src/i3cat-git/i3cat-git-r38.c6d29dd-1-x86_64.pkg.tar.xz
loading packages...
warning: i3cat-git-r38.c6d29dd-1 is up to date -- skipping
 there is nothing to do
```

* Add comment

Add comment

* Add changelog fragment.

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Klaus Frank 2020-02-01 14:37:27 +01:00 committed by GitHub
parent 3baea92ec9
commit 14b1febf64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 14 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- "pacman - fix module crash with ``IndexError: list index out of range`` (https://github.com/ansible/ansible/issues/63077)"

View file

@ -329,14 +329,17 @@ def install_packages(module, pacman_path, state, packages, package_files):
if rc != 0: if rc != 0:
module.fail_json(msg="failed to install %s: %s" % (" ".join(to_install_repos), stderr)) module.fail_json(msg="failed to install %s: %s" % (" ".join(to_install_repos), stderr))
data = stdout.split('\n')[3].split(' ')[2:] # As we pass `--needed` to pacman returns a single line of ` there is nothing to do` if no change is performed.
data = [i for i in data if i != ''] # The check for > 3 is here because we pick the 4th line in normal operation.
for i, pkg in enumerate(data): if len(stdout.split('\n')) > 3:
data[i] = re.sub('-[0-9].*$', '', data[i].split('/')[-1]) data = stdout.split('\n')[3].split(' ')[2:]
if module._diff: data = [i for i in data if i != '']
diff['after'] += "%s\n" % pkg for i, pkg in enumerate(data):
data[i] = re.sub('-[0-9].*$', '', data[i].split('/')[-1])
if module._diff:
diff['after'] += "%s\n" % pkg
install_c += len(to_install_repos) install_c += len(to_install_repos)
if to_install_files: if to_install_files:
cmd = "%s --upgrade --noconfirm --noprogressbar --needed %s %s" % (pacman_path, module.params["extra_args"], " ".join(to_install_files)) cmd = "%s --upgrade --noconfirm --noprogressbar --needed %s %s" % (pacman_path, module.params["extra_args"], " ".join(to_install_files))
@ -345,14 +348,17 @@ def install_packages(module, pacman_path, state, packages, package_files):
if rc != 0: if rc != 0:
module.fail_json(msg="failed to install %s: %s" % (" ".join(to_install_files), stderr)) module.fail_json(msg="failed to install %s: %s" % (" ".join(to_install_files), stderr))
data = stdout.split('\n')[3].split(' ')[2:] # As we pass `--needed` to pacman returns a single line of ` there is nothing to do` if no change is performed.
data = [i for i in data if i != ''] # The check for > 3 is here because we pick the 4th line in normal operation.
for i, pkg in enumerate(data): if len(stdout.split('\n')) > 3:
data[i] = re.sub('-[0-9].*$', '', data[i].split('/')[-1]) data = stdout.split('\n')[3].split(' ')[2:]
if module._diff: data = [i for i in data if i != '']
diff['after'] += "%s\n" % pkg for i, pkg in enumerate(data):
data[i] = re.sub('-[0-9].*$', '', data[i].split('/')[-1])
if module._diff:
diff['after'] += "%s\n" % pkg
install_c += len(to_install_files) install_c += len(to_install_files)
if state == 'latest' and len(package_err) > 0: if state == 'latest' and len(package_err) > 0:
message = "But could not ensure 'latest' state for %s package(s) as remote version could not be fetched." % (package_err) message = "But could not ensure 'latest' state for %s package(s) as remote version could not be fetched." % (package_err)