Skip to content

Commit

Permalink
pacman: support yay as root (#6713)
Browse files Browse the repository at this point in the history
* pacman: support yay as root

* make pylint happy

* minor adjustments

* rollback some test actions

* removal of user and pkgs in handlers

* add comment to note

* add changelog frag

* fix doc

* Update tests/integration/targets/pacman/tasks/yay-become.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/pacman/tasks/yay-become.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* simplify pkg install in int. tests

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
  • Loading branch information
russoz and felixfontein authored Jul 8, 2023
1 parent 7748002 commit f6ee217
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 12 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/6713-yay-become.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
36 changes: 24 additions & 12 deletions plugins/modules/pacman.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@
it is much more efficient to pass the list directly to the O(name) option.
- To use an AUR helper (O(executable) option), a few extra setup steps might be required beforehand.
For example, a dedicated build user with permissions to install packages could be necessary.
- >
In the tests, while using C(yay) as the O(executable) option, the module failed to install AUR packages
with the error: C(error: target not found: <pkg>).
"""

RETURN = """
Expand Down Expand Up @@ -263,6 +266,7 @@
reason_for: all
"""

import re
import shlex
from ansible.module_utils.basic import AnsibleModule
from collections import defaultdict, namedtuple
Expand Down Expand Up @@ -418,7 +422,7 @@ def _build_install_diff(pacman_verb, pkglist):
for p in name_ver:
# With Pacman v6.0.1 - libalpm v13.0.1, --upgrade outputs "loading packages..." on stdout. strip that.
# When installing from URLs, pacman can also output a 'nothing to do' message. strip that too.
if "loading packages" in p or "there is nothing to do" in p:
if "loading packages" in p or "there is nothing to do" in p or 'Avoid running' in p:
continue
name, version = p.split()
if name in self.inventory["installed_pkgs"]:
Expand Down Expand Up @@ -706,11 +710,12 @@ def _build_inventory(self):
installed_pkgs = {}
dummy, stdout, dummy = self.m.run_command([self.pacman_path, "--query"], check_rc=True)
# Format of a line: "pacman 6.0.1-2"
query_re = re.compile(r'^\s*(?P<pkg>\S+)\s+(?P<ver>\S+)\s*$')
for l in stdout.splitlines():
l = l.strip()
if not l:
query_match = query_re.match(l)
if not query_match:
continue
pkg, ver = l.split()
pkg, ver = query_match.groups()
installed_pkgs[pkg] = ver

installed_groups = defaultdict(set)
Expand All @@ -721,11 +726,12 @@ def _build_inventory(self):
# base-devel file
# base-devel findutils
# ...
query_groups_re = re.compile(r'^\s*(?P<group>\S+)\s+(?P<pkg>\S+)\s*$')
for l in stdout.splitlines():
l = l.strip()
if not l:
query_groups_match = query_groups_re.match(l)
if not query_groups_match:
continue
group, pkgname = l.split()
group, pkgname = query_groups_match.groups()
installed_groups[group].add(pkgname)

available_pkgs = {}
Expand All @@ -747,21 +753,27 @@ def _build_inventory(self):
# vim-plugins vim-airline-themes
# vim-plugins vim-ale
# ...
sync_groups_re = re.compile(r'^\s*(?P<group>\S+)\s+(?P<pkg>\S+)\s*$')
for l in stdout.splitlines():
l = l.strip()
if not l:
sync_groups_match = sync_groups_re.match(l)
if not sync_groups_match:
continue
group, pkg = l.split()
group, pkg = sync_groups_match.groups()
available_groups[group].add(pkg)

upgradable_pkgs = {}
rc, stdout, stderr = self.m.run_command(
[self.pacman_path, "--query", "--upgrades"], check_rc=False
)

stdout = stdout.splitlines()
if stdout and "Avoid running" in stdout[0]:
stdout = stdout[1:]
stdout = "\n".join(stdout)

# non-zero exit with nothing in stdout -> nothing to upgrade, all good
# stderr can have warnings, so not checked here
if rc == 1 and stdout == "":
if rc == 1 and not stdout:
pass # nothing to upgrade
elif rc == 0:
# Format of lines:
Expand All @@ -771,7 +783,7 @@ def _build_inventory(self):
l = l.strip()
if not l:
continue
if "[ignored]" in l:
if "[ignored]" in l or "Avoid running" in l:
continue
s = l.split()
if len(s) != 4:
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/targets/pacman/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Remove user yaybuilder
ansible.builtin.user:
name: yaybuilder
state: absent

- name: Remove yay
ansible.builtin.package:
name: yay
state: absent

- name: Remove packages for yay-become
ansible.builtin.package:
name:
- base-devel
- yay
- git
- nmap
state: absent
1 change: 1 addition & 0 deletions tests/integration/targets/pacman/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
- include_tasks: 'update_cache.yml'
- include_tasks: 'locally_installed_package.yml'
- include_tasks: 'reason.yml'
- include_tasks: 'yay-become.yml'
66 changes: 66 additions & 0 deletions tests/integration/targets/pacman/tasks/yay-become.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

# This is more convoluted that one might expect, because:
# - yay is not available or installation in ArchLinux (as it is in Manjaro - issue 6184 reports using it)
# - to install yay in ArchLinux requires building the package
# - makepkg cannot be run as root, but the user running it must have sudo to install the resulting package

- name: create user
ansible.builtin.user:
name: yaybuilder
state: present
notify: Remove user yaybuilder

- name: grant sudo powers to builder
community.general.sudoers:
name: yaybuilder
user: yaybuilder
commands: ALL
nopassword: true

- name: Install base packages
ansible.builtin.package:
name:
- base-devel
- git
- go
state: present
notify: Remove packages for yay-become

- name: Hack permssions for the remote_tmp_dir
ansible.builtin.file:
path: "{{ remote_tmp_dir }}"
mode: '0777'

- name: Create temp directory for builder
ansible.builtin.file:
path: "{{ remote_tmp_dir }}/builder"
owner: yaybuilder
state: directory
mode: '0755'

- name: clone yay git repo
become: true
become_user: yaybuilder
ansible.builtin.git:
repo: https://aur.archlinux.org/yay.git
dest: "{{ remote_tmp_dir }}/builder/yay"
depth: 1

- name: make package
become: true
become_user: yaybuilder
ansible.builtin.command:
chdir: "{{ remote_tmp_dir }}/builder/yay"
cmd: makepkg -si --noconfirm
notify: Remove yay

- name: Install nmap
community.general.pacman:
name: nmap
state: present
executable: yay
extra_args: --builddir /var/cache/yay

0 comments on commit f6ee217

Please sign in to comment.