Merge pull request #46 from ckotte/pkgbuild

Add pkgbuild option to build local package
pull/50/head v0.42
kewl 2020-10-01 13:39:11 +02:00 committed by GitHub
commit 592c6d9841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 24 deletions

View File

@ -20,6 +20,7 @@ The following helpers are supported and automatically selected, if present, in t
|use |**auto**, yay, pacaur, trizen, pikaur, aurman, makepkg |The tool to use, 'auto' uses the first known helper found and makepkg as a fallback.| |use |**auto**, yay, pacaur, trizen, pikaur, aurman, makepkg |The tool to use, 'auto' uses the first known helper found and makepkg as a fallback.|
|extra_args |**null** |A list of additional arguments to pass directly to the tool. Cannot be used in 'auto' mode.| |extra_args |**null** |A list of additional arguments to pass directly to the tool. Cannot be used in 'auto' mode.|
|aur_only |yes, **no** |Limit helper operation to the AUR.| |aur_only |yes, **no** |Limit helper operation to the AUR.|
|local_pkgbuild |Local directory with PKGBUILD, **null** |Only valid with makepkg or pikaur. Don't download the package from AUR. Build the package using a local PKGBUILD and the other build files.|
|skip_pgp_check |yes, **no** |Only valid with makepkg. Skip PGP signatures verification of source file, useful when installing packages without GnuPG properly configured.| |skip_pgp_check |yes, **no** |Only valid with makepkg. Skip PGP signatures verification of source file, useful when installing packages without GnuPG properly configured.|
|ignore_arch |yes, **no** |Only valid with makepkg. Ignore a missing or incomplete arch field, useful when the PKGBUILD does not have the arch=('yourarch') field.| |ignore_arch |yes, **no** |Only valid with makepkg. Ignore a missing or incomplete arch field, useful when the PKGBUILD does not have the arch=('yourarch') field.|
@ -30,7 +31,8 @@ The following helpers are supported and automatically selected, if present, in t
## Installing ## Installing
### AUR package ### AUR package
The [ansible-aur-git](https://aur.archlinux.org/packages/ansible-aur-git) package is available in the AUR. The [ansible-aur-git](https://aur.archlinux.org/packages/ansible-aur-git) package is available in the AUR.
Note the module is installed in `/usr/share/ansible/plugins/modules` which is one of the default module library paths.
Note: The module is installed in `/usr/share/ansible/plugins/modules` which is one of the default module library paths.
### Manual installation ### Manual installation
Just clone the *ansible-aur* repository into your user custom-module directory: Just clone the *ansible-aur* repository into your user custom-module directory:
@ -44,7 +46,7 @@ git clone https://github.com/kewlfft/ansible-aur.git ~/.ansible/plugins/modules/
ansible-galaxy install kewlfft.aur ansible-galaxy install kewlfft.aur
``` ```
Note that if this module is installed from Ansible Galaxy, you will need to list it explicitly in your playbook: Note: If this module is installed from Ansible Galaxy, you will need to list it explicitly in your playbook:
``` ```
# playbook.yml # playbook.yml
- hosts: localhost - hosts: localhost
@ -106,6 +108,17 @@ Use it in a task, as in the following examples:
- package_name_1 - package_name_1
- package_name_2 - package_name_2
# Upgrade the system using yay, only act on AUR packages, note that dependency resolving will still include repository packages # Upgrade the system using yay, only act on AUR packages.
# Note: Dependency resolving will still include repository packages.
- aur: upgrade=yes use=yay aur_only=yes - aur: upgrade=yes use=yay aur_only=yes
# Install gnome-shell-extension-caffeine-git using pikaur and a local PKGBUILD.
# Skip if it is already installed
- aur:
name: gnome-shell-extension-caffeine-git
use: pikaur
local_pkgbuild: {{ role_path }}/files/gnome-shell-extension-caffeine-git
state: present
become: yes
become_user: aur_builder
``` ```

View File

@ -2,13 +2,14 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from ansible.module_utils.basic import * from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
import json import json
import shlex import shlex
import tarfile import tarfile
import os import os
import os.path import os.path
import shutil
import tempfile import tempfile
import urllib.parse import urllib.parse
@ -72,6 +73,14 @@ options:
- Limit helper operation to the AUR. - Limit helper operation to the AUR.
type: bool type: bool
default: no default: no
local_pkgbuild:
description:
- Only valid with makepkg or pikaur.
Directory with PKGBUILD and build files.
Cannot be used unless use is set to 'makepkg' or 'pikaur'.
type: path
default: no
notes: notes:
- When used with a `loop:` each package will be processed individually, - When used with a `loop:` each package will be processed individually,
it is much more efficient to pass the list directly to the `name` option. it is much more efficient to pass the list directly to the `name` option.
@ -102,6 +111,11 @@ use_cmd = {
'makepkg': ['makepkg', '--syncdeps', '--install', '--noconfirm', '--needed'] 'makepkg': ['makepkg', '--syncdeps', '--install', '--noconfirm', '--needed']
} }
use_cmd_local_pkgbuild = {
'pikaur': ['pikaur', '-P', '--noconfirm', '--noedit', '--needed', '--install'],
'makepkg': ['makepkg', '--syncdeps', '--install', '--noconfirm', '--needed']
}
has_aur_option = ['yay', 'pacaur', 'trizen', 'pikaur', 'aurman'] has_aur_option = ['yay', 'pacaur', 'trizen', 'pikaur', 'aurman']
@ -145,39 +159,61 @@ def check_packages(module, packages):
module.exit_json(changed=status, msg=message, diff=diff) module.exit_json(changed=status, msg=message, diff=diff)
def build_command_prefix(use, extra_args, skip_pgp_check=False, ignore_arch=False, aur_only=False): def build_command_prefix(use, extra_args, skip_pgp_check=False, ignore_arch=False, aur_only=False, local_pkgbuild=None):
""" """
Create the prefix of a command that can be used by the install and upgrade functions. Create the prefix of a command that can be used by the install and upgrade functions.
""" """
command = def_lang + use_cmd[use] if local_pkgbuild:
command = def_lang + use_cmd_local_pkgbuild[use]
else:
command = def_lang + use_cmd[use]
if skip_pgp_check: if skip_pgp_check:
command.append('--skippgpcheck') command.append('--skippgpcheck')
if ignore_arch: if ignore_arch:
command.append('--ignorearch') command.append('--ignorearch')
if aur_only and use in has_aur_option: if aur_only and use in has_aur_option:
command.append('--aur') command.append('--aur')
if local_pkgbuild and use != 'makepkg':
command.append(local_pkgbuild)
if extra_args: if extra_args:
command += shlex.split(extra_args) command += shlex.split(extra_args)
return command return command
def install_with_makepkg(module, package, extra_args, skip_pgp_check, ignore_arch): def install_with_makepkg(module, package, extra_args, skip_pgp_check, ignore_arch, local_pkgbuild=None):
""" """
Install the specified package with makepkg Install the specified package or a local PKGBUILD with makepkg
""" """
module.get_bin_path('fakeroot', required=True) if not local_pkgbuild:
f = open_url('https://aur.archlinux.org/rpc/?v=5&type=info&arg={}'.format(urllib.parse.quote(package))) module.get_bin_path('fakeroot', required=True)
result = json.loads(f.read().decode('utf8')) f = open_url('https://aur.archlinux.org/rpc/?v=5&type=info&arg={}'.format(urllib.parse.quote(package)))
if result['resultcount'] != 1: result = json.loads(f.read().decode('utf8'))
return (1, '', 'package {} not found'.format(package)) if result['resultcount'] != 1:
result = result['results'][0] return (1, '', 'package {} not found'.format(package))
f = open_url('https://aur.archlinux.org/{}'.format(result['URLPath'])) result = result['results'][0]
f = open_url('https://aur.archlinux.org/{}'.format(result['URLPath']))
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir:
tar = tarfile.open(mode='r|*', fileobj=f) if local_pkgbuild:
tar.extractall(tmpdir) shutil.copytree(local_pkgbuild, tmpdir, dirs_exist_ok=True)
tar.close() command = build_command_prefix('makepkg', extra_args)
command = build_command_prefix('makepkg', extra_args, skip_pgp_check=skip_pgp_check, ignore_arch=ignore_arch) rc, out, err = module.run_command(command, cwd=tmpdir, check_rc=True)
rc, out, err = module.run_command(command, cwd=os.path.join(tmpdir, result['Name']), check_rc=True) else:
tar = tarfile.open(mode='r|*', fileobj=f)
tar.extractall(tmpdir)
tar.close()
command = build_command_prefix('makepkg', extra_args, skip_pgp_check=skip_pgp_check, ignore_arch=ignore_arch)
rc, out, err = module.run_command(command, cwd=os.path.join(tmpdir, result['Name']), check_rc=True)
return (rc, out, err)
def install_local_package(module, package, use, extra_args, local_pkgbuild):
"""
Install the specified package with a local PKGBUILD
"""
with tempfile.TemporaryDirectory() as tmpdir:
shutil.copytree(local_pkgbuild, tmpdir, dirs_exist_ok=True)
command = build_command_prefix(use, extra_args, local_pkgbuild=tmpdir + '/PKGBUILD')
rc, out, err = module.run_command(command, check_rc=True)
return (rc, out, err) return (rc, out, err)
@ -213,11 +249,14 @@ def upgrade(module, use, extra_args, aur_only):
) )
def install_packages(module, packages, use, extra_args, state, skip_pgp_check, ignore_arch, aur_only): def install_packages(module, packages, use, extra_args, state, skip_pgp_check, ignore_arch, aur_only, local_pkgbuild):
""" """
Install the specified packages Install the specified packages
""" """
assert use in use_cmd if local_pkgbuild:
assert use in use_cmd_local_pkgbuild
else:
assert use in use_cmd
changed_iter = False changed_iter = False
@ -227,7 +266,9 @@ def install_packages(module, packages, use, extra_args, state, skip_pgp_check, i
rc = 0 rc = 0
continue continue
if use == 'makepkg': if use == 'makepkg':
rc, out, err = install_with_makepkg(module, package, extra_args, skip_pgp_check, ignore_arch) rc, out, err = install_with_makepkg(module, package, extra_args, skip_pgp_check, ignore_arch, local_pkgbuild)
elif local_pkgbuild:
rc, out, err = install_local_package(module, package, use, extra_args, local_pkgbuild)
else: else:
command = build_command_prefix(use, extra_args, aur_only=aur_only) command = build_command_prefix(use, extra_args, aur_only=aur_only)
command.append(package) command.append(package)
@ -278,6 +319,10 @@ def make_module():
'default': False, 'default': False,
'type': 'bool', 'type': 'bool',
}, },
'local_pkgbuild': {
'default': None,
'type': 'path',
},
}, },
mutually_exclusive=[['name', 'upgrade']], mutually_exclusive=[['name', 'upgrade']],
required_one_of=[['name', 'upgrade']], required_one_of=[['name', 'upgrade']],
@ -301,6 +346,15 @@ def make_module():
if use != 'makepkg' and (params['skip_pgp_check'] or params['ignore_arch']): if use != 'makepkg' and (params['skip_pgp_check'] or params['ignore_arch']):
module.fail_json(msg="This option is only available with 'makepkg'.") module.fail_json(msg="This option is only available with 'makepkg'.")
if not (use in use_cmd_local_pkgbuild) and params['local_pkgbuild']:
module.fail_json(msg="This option is not available with '%s'" % use)
if params['local_pkgbuild'] and not os.path.isdir(params['local_pkgbuild']):
module.fail_json(msg="Directory %s not found" % (params['local_pkgbuild']))
if params['local_pkgbuild'] and not os.access(params['local_pkgbuild'] + '/PKGBUILD', os.R_OK):
module.fail_json(msg="PKGBUILD inside %s not readable" % (params['local_pkgbuild']))
if params.get('upgrade', False) and use == 'makepkg': if params.get('upgrade', False) and use == 'makepkg':
module.fail_json(msg="The 'upgrade' action cannot be used with 'makepkg'.") module.fail_json(msg="The 'upgrade' action cannot be used with 'makepkg'.")
@ -319,7 +373,15 @@ def apply_module(module, use):
if module.check_mode: if module.check_mode:
check_packages(module, params['name']) check_packages(module, params['name'])
else: else:
install_packages(module, params['name'], use, params['extra_args'], params['state'], params['skip_pgp_check'], params['ignore_arch'], params['aur_only']) install_packages(module,
params['name'],
use,
params['extra_args'],
params['state'],
params['skip_pgp_check'],
params['ignore_arch'],
params['aur_only'],
params['local_pkgbuild'])
def main(): def main():