Setting up AnotherAURHelper with LXC
It is recommended to use AnotherAURHelper with a container as a safety net due
to the fact that makechrootpkg
directly sources/parses PKGBUILDs.
The following assumes you already have LXC installed. If not, follow the ArchWiki until you can get an arbitrary container up and running.
Note
The following code blocks will have different prefixes. >
is used to
specify commands run on an ArchLinux installation, and $
is used to
specify commands run inside of the LXC container.
Privileged Containers
AnotherAURHelper requires to be run in a privileged container because it uses a chroot. If your LXC is already configured for unprivileged containers, you can create a privileged container by commenting out the config for an unprivileged container and creating a container, and uncommenting after the container has been created to allow future containers to be created as unprivileged.
# /etc/lxc/default.conf
#lxc.idmap = u 0 100000 65536
#lxc.idmap = g 0 100000 65536
LXC Container Setup
Create the container like the following on your host system.
> sudo lxc-create -n aur_helper -t download
Downloading the image index
---
DIST RELEASE ARCH VARIANT BUILD
---
...
archlinux current amd64 default 20250303_05:33
archlinux current arm64 default 20250303_05:49
...
---
Distribution:
> archlinux
Release:
> current
Architecture:
> amd64
The cached copy has expired, re-downloading...
Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs
---
You just created an Archlinux x86_64 (20250303_05:33) container.
Start the container.
> sudo lxc-start -n aur_helper -s lxc.apparmor.allow_nesting=1 -s lxc.apparmor.profile=generated
Attach to a shell inside the container.
> sudo lxc-attach -n aur_helper
Getting Required Packages
Update your mirror-list in the container and update.
$ pacman -Syu
base-devel
, devtools
, python-toml
, ccache
, and sqlite
is required.
$ pacman -S base-devel devtools python-toml ccache sqlite
You may need to grab an editor like vim
, emacs
, or nano
.
$ pacman -S vim emacs nano
If your filesystem is using btrfs
, you will need to install btrfs-progs
.
$ pacman -S btrfs-progs
Setting up SSH for the Container
This is pretty straightforward, but for those unfamiliar with ssh, here's a quick setup guide.
First, install openssh
.
$ pacman -S openssh
Enable and start sshd.
$ systemctl enable --now sshd
After setting up the user in the following section, you can use ssh to log in to the user.
You can fetch the local ip address of the running container with the following.
> sudo lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
aur_helper RUNNING 0 - omitted omitted false
Just use the local ip address in the IPV4 column and you can ssh into your user like so.
> ssh build@10.0.3.1
Creating the build user
A build
user is to be created with sudo
privileges that will be used to run
the builds.
First, create the user.
$ useradd -m -s /usr/bin/bash build
Then add sudo privileges for the build
user.
$ EDITOR=nano visudo
Add the following line for sudo privileges for build
.
build ALL=(ALL:ALL) NOPASSWD: ALL
If you prefer to have build
use a password for sudo privielges, then use the
following instead.
build ALL=(ALL:ALL) ALL
And set build
's password.
$ passwd build
Open a shell as build
to check if it works.
$ su - build
$ sudo ls -a
At this point you should be able to ssh into build
.
Creating the CHROOT
Note
Continue the following steps as the build
user, not as root
.
Use /usr/bin/mkarchroot
to create a CHROOT at /home/build/chroot/root
.
$ mkdir /home/build/chroot
$ mkarchroot /home/build/chroot/root base base-devel cmake ninja
Warning
Do NOT preinstall ccache
or sccache
in the CHROOT as it will be handled
by AnotherAURHelper.
Note
From now on, you must refer to the CHROOT as /home/build/chroot
when
handling it in AnotherAURHelper, even if the actual chroot is inside of
/home/build/chroot/root
.
Note
The default LXC ArchLinux container has /etc/locale.conf
set to C.UTF-8
.
You may have to change locale settings as in the installation guide on the
ArchWiki.
Note
You are able to run commands in the CHROOT:
$ arch-nspawn /home/build/chroot/root pacman -S cmake
You may do this to also set proper locale information in the CHROOT.
You may want to uncomment some lines in
/home/build/chroot/root/etc/pacman.conf
to allow fetching multilib
packages.
# pacman.conf
...
[multilib]
Include = /etc/pacman.d/mirrorlist
...
When the CHROOT is used to build packages by AnotherAURHelper, it should automatically use the same mirrorlist as the one used by the LXC container.
Set up GnuPG for Signature Verifcation and Package Signing
Checking GnuPG
Create a directory at a location of your choosing, ideally inside of
/home/build/
.
$ mkdir /home/build/checking_gpg
$ chmod 700 /home/build/checking_gpg
$ GNUPGHOME=/home/build/checking_gpg gpg -k
Whenever a build fails due to missing gpg public keys, the key can be added to this directory. Usually there should be a key file inside of the AUR pkg's directory, but otherwise the fingerprint can be used to fetch it directly.
# Load key from file
$ GNUPGHOME=/home/build/checking_gpg gpg --import < the_pub_key_file.pub
# Fetch key via fingerprint from a keyserver
$ GNUPGHOME=/home/build/checking_gpg gpg --recv-keys A_DEV_KEYS_FINGERPRINT
Signing GnuPG
A GnuPG public/private key pair will need to be generated. Only keys with
signature creation is necessary, so generate accordingly. Like the previous
GnuPG directory, this can be placed in /home/build/
.
Note
If you encounter errors, try using --pinentry-mode loopback
as a flag to
pass to gpg. Otherwise, run the shell inside of a tmux
session. This may
occur if you are accessing the build
user through an attached shell
instead of ssh
.
Also, be prepared to set up a password for this key.
Warning
Write the password down somewhere so you don't forget it! If you ever lose this password, you will need to revoke the old key, re-generate a new key, delete all package signatures, and re-sign all packages and the package database. You can do so by following instructions here.
Note
It may be beneficial to use a long password for this key instead of a short memorable one, as a malicious PKGBUILD might attempt to access it if the PKGBUILD hasn't been properly vetted first.
Follow the following to generate a GnuPG key for signatures only.
$ mkdir /home/build/signing_gpg
$ chmod 700 /home/build/signing_gpg
$ GNUPGHOME=/home/build/signing_gpg gpg --pinentry-mode loopback --full-gen-key
gpg (GnuPG) 2.4.7; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: keybox '/home/build/signing_gpg/pubring.kbx' created
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
Your selection?
$ 10
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection?
$ 1
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
$ 0
Key does not expire at all
Is this correct? (y/N)
$ y
GnuPG needs to construct a user ID to identify your key.
Real name:
$ My Name (AUR Helper Signing Key)
Email address:
$ my_email@example.com
Comment:
$ Key for AnotherAURHelper
You selected this USER-ID:
"My Name (AUR Helper Signing Key) (Key for AnotherAURHelper) <my_email@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
$ O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
Enter passphrase:
$ ***********
gpg: /home/build/signing_gpg/trustdb.gpg: trustdb created
gpg: directory '/home/build/signing_gpg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/build/signing_gpg/openpgp-revocs.d/BFD86E817FA4B097A8636507A4FDFD431A0D481B.rev'
public and secret key created and signed.
pub ed25519 2025-03-04 [SC]
BFD86E817FA4B097A8636507A4FDFD431A0D481B
uid My Name (AUR Helper Signing Key) (Key for AnotherAURHelper) <my_email@example.com>
Verify you inputed the password correctly:
$ echo test_file > test_file
$ GNUPGHOME=/home/build/signing_gpg gpg --pinentry-mode loopback --detach-sign test_file
Enter passphrase:
$ ***********
$ GNUPGHOME=/home/build/signing_gpg gpg --verify test_file.sig
gpg: assuming signed data in 'test_file'
gpg: Signature made Tue Mar 4 03:59:43 2025 UTC
gpg: using EDDSA key BFD86E817FA4B097A8636507A4FDFD431A0D481B
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: Good signature from "My Name (AUR Helper Signing Key) (Key for AnotherAURHelper) <my_email@example.com>" [ultimate]
# cleanup
$ rm test_file test_file.sig
Set up Output Dir and Configuration
Create an output directory for your built packages.
$ mkdir /home/build/aur_pkgs
Set up a /home/build/config.toml
file with config for AnotherAURHelper.
Note
The config.toml
file can be named anything.
Refer to the example_config.toml
file inside AnotherAURHelper's repo as a
reference.
At this point, we will clone AnotherAURHelper.
$ git clone https://github.com/Stephen-Seo/AnotherAURHelper.git
Your config should look like the following:
########## MANDATORY VARIABLES
chroot = "/home/build/chroot"
# Location to place built packages.
pkg_out_dir = "/home/build/aur_pkgs"
# It is recommended to put the repo file in the "pkg_out_dir".
# If the tar file doesn't already exist, it will be automatically created.
repo = "/home/build/aur_pkgs/MyRepo.db.tar"
# Location to clone packages from AUR.
clones_dir = "/home/build/aur"
gpg_dir = "/home/build/checking_gpg"
logs_dir = "/home/build/logs"
signing_gpg_dir = "/home/build/signing_gpg"
signing_gpg_key_fp = "BFD86E817FA4B097A8636507A4FDFD431A0D481B"
editor = "/usr/bin/nano"
# if true, all logs are prepended with current time in UTC
is_timed = true
# if true, all output build logs are prepended with current time in UTC
is_log_timed = true
# Default log_limit is 1 GiB
log_limit = 1073741824
# If true, then make the build fail if the limit is reached
error_on_limit = true
# If true, timestamps are in localtime. If false, timestamps are UTC.
datetime_in_local_time = true
# If true, all builds will be done in a tmpfs. Recommended to have a lot of RAM and/or swap.
tmpfs = false
# If true, only packages to be built will be printed when USR1 is signaled.
print_state_info_only_building_sigusr1 = true
# The path to the persistent state.
persistent_state_db = "/home/build/aur_helper_state.db"
########## END OF MANDATORY VARIABLES
Note
The repo = ...
option determines the name of the repository. If you want
to name it "MyCoolRepo", then it should be set as repo = "/home/build/aur_pkgs/MyCoolRepo.db.tar"
.
Note
The signing_gpg_key_fp = ...
option ensures the correct signing key is
used. You can use GNUPGHOME=/home/build/signing_gpg gpg -K
to get your
signing key's fingerprint to put in here.
Note
The persistent_state_db = ...
option ensures that the per-package-option
hash_compare_PKGBUILD
doesn't skip a PKGBUILD that hasn't been explicitly
trusted. Also note this is a fairly new feature that may still be only in
the dev branch of AnotherAURHelper's repository.
Create some necessary directories.
$ mkdir -p aur_pkgs
$ mkdir -p aur
$ mkdir -p logs
Create some necessary symlinks based on the previously set repo = ...
.
$ ln -s MyRepo.db.tar /home/build/aur_pkgs/MyRepo.db
$ ln -s MyRepo.files.tar /home/build/aur_pkgs/MyRepo.files
Here is a few packages you can add to your config.toml
.
[[entry]]
name = "stdman"
[[entry]]
name = "cpufetch-git"
Registering the Repo on other Arch systems
Warning
Some commands/config should be used on in your LXC container and some on a different ArchLinux system that will install the packages built by AnotherAURHelper. Thus, be sure you are on the right system before inputting commands as it may get confusing.
The following assumes that the AUR repo's name is MyRepo
as indicated in the
previous config.
Add the following to your /etc/pacman.conf
on an ArchLinux system that will
install the built AUR packages you build.
[MyRepo]
SigLevel = Required TrustedOnly
Server = file:///home/user/aur_pkgs
Note
This config assumes use of sshfs
or rsync
.
Note
It is possible to use nginx
(or others) to host the directory to use as a
repo accessible over http/https. This is a little more involved but is
possible. Accessing such on other systems may set the Server = ...
line
in the /etc/pacman.conf
to a url like
Server = https://example.com/aur_pkgs
.
We're not done yet, as the other ArchLinux system needs to get the public key of the AUR Helper signing key to verify the packages built and signed by AnotherAURHelper.
Export the public key of your GnuPG signing key from your LXC instance.
$ GNUPGHOME=/home/build/signing_gpg gpg --export > signing_key.pub
Use scp
, sftp
, or sshfs
to get this public key out of the container. Use
pacman-key
on the other ArchLinux system to import and locally sign the
public key to trust it.
> sudo pacman-key -a signing_key.pub
Check that the imported key is the only key listed when querying for it.
> sudo pacman-key --finger 'AUR Helper Signing Key'
pub ed25519 2025-03-04 [SC]
BFD8 6E81 7FA4 B097 A863 6507 A4FD FD43 1A0D 481B
uid [ unknown] My Name (AUR Helper Signing Key) (Key for AnotherAURHelper) <my_email@example.com>
If there is only one key listed, then you can use the AUR Helper Signing Key
string to specify the correct key to sign. (Signing another key in GnuPG means
that you trust it.) If more than one key is listed, you will have to adjust the
string passed to pacman-key --finger ...
until only the key you want to sign
is shown.
Once you've determined the string that specifies the key you created and want to sign, sign it.
> sudo pacman-key --lsign-key 'AUR Helper Signing Key'
Once this is done, the ArchLinux system will now trust packages signed by your signing key. If you want to revoke such a key, you can delete it from your pacman's keyring.
Warning
Be careful with pacman-key
's delete command, as you might accidentally
delete keys you don't mean to delete. If such a thing happens, you may have
to regenerate your ArchLinux installation's pacman keyring.
Use the following command to delete a key from your ArchLinux system's keyring.
> sudo pacman-key -d 'AUR Helper Signing Key'
Testing
The build process will typically involve running the following.
$ ./AnotherAURHelper/update.py --config /home/build/config.toml
Just follow the steps, and by the end of it, it should build your packages,
sign them, and place them in the directory specified in your config.toml
.
Warning
Be sure to pacman -Syu
in the container before running update.py
. You
should be doing this at most once per day (if you use AnotherAURHelper once
a day).
Serving the Packages
As mentioned earlier, the contents of your /home/build/aur_pkgs
directory can
be served with nginx
or others. The directory can be copied from your LXC
container to elsewhere with ssh
(sshfs
maybe) or even rsync
.