Managing Arch Linux ARM Repositories from x86_64 Systems
(Update: The tool armutils which is mentioned in this blog post is no longer maintained. The source code respository was archived).
I have some custom repositories for Arch Linux packages that I use for packages from AUR and other packages that I created. Recently, I started supporting ARM architectures and thus needed a way to manage (i.e., add/build, update, remove) these packages for ARM architectures as well. One possibility to do so is installing Arch Linux ARM on an ARM device and use it for the management tasks. However, by combining some tools it's also possible to manage ARM packages from a x86_64 system, even distributed builds via distcc are supported. In this blog post, I explain how this works.
The approach is based on the combination of two tools:
- repman is a tool to manage custom Arch Linux repositories. It is available for multiple architectures
- armutils provides scripts to create chroot containers for ARM architectures on x86_64 hosts and to utilize them
The idea is to create an ARM chroot container on an x86_64 host using armutils, install repman in that container and use it to manage ARM packages in a custom repository. The how-to below describes the detailed steps of that approach for an Aarch64 chroot container, but it also works for other ARM architectures, just replace the ARM image in the mkarmchroot
command accordingly.
-
Install armutils:
yay -Syu armutils-git
-
Create an Aarch64 chroot container in the folder
<YOUR-CHROOT-FOLDER>
and install the base-devel group:mkarmchroot -u http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz <YOUR-CHROOT-FOLDER>/root base-devel
-
Enter chroot:
arm-nspawn <YOUR-CHROOT-FOLDER>/root
-
Make user alarm a sudoer:
[root@root ~] echo "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/10-alarm
-
(Optional) Enable parallel package downloads:
[root@root ~] nano /etc/pacman.conf
Remove the comment sign from the row
#ParallelDownloads = 5
. -
Install repman and remove the cloned folder afterwards:
[root@root ~] pacman -Syu git [root@root ~] cd /home/alarm [root@root alarm] sudo -u alarm git clone https://aur.archlinux.org/repman-git.git [root@root alarm] cd repman-git [root@root repman-git] sudo -u alarm makepkg -si [root@root repman-git] cd .. [root@root alarm] rm -rd repman-git
-
Create repman configuration and exit chroot:
[root@root alarm] sudo -u alarm mkdir -p .config/repman [root@root alarm] sudo -u alarm nano .config/repman/repos.conf [root@root alarm] exit
-
Configure ssh: Create the keys and the ssh config as required to be able to access your repositories via rsync.
-
(Optional) Enable distributed builds by installing distcc in the chroot container and configure
<YOUR-CHROOT-FOLDER>/root/etc/makepkg.conf
as described in this documentation. -
You are done. Now you can, for example, add an ARM package from AUR to your custom repository by executing
arm-nspawn <YOUR-CHROOT-FOLDER>/root sudo -u alarm repman add -r <YOUR_REPOSITORY> -n -a <PACKAGE>
Since repman builds in a chroot per default and a chroot in a chroot is not working, the option
--nochroot
/-n
has to be set. This applies torepman add ...
andrepman update ...
.
Notes
Not all packages can be built that way
While - at least as far as I tried that out - most packages could be built with the described approach, for some packages that does not work - I observed errors thrown by qemu in some cases. Building them on ARM hardware worked without problems.
To make the execution of repman inside the chroot container more convenient, it might make sense to create a shell alias like below by adding that row to your ~/.bashrc
or ~/.zshrc
etc.
alias repman-armv7h="sudo arm-nspawn <YOUR-CHROOT-DIRECTORY>/root sudo -u alarm repman"
To make the new alias know to the system, execute for example
source ~/.zshrc
If you want to add local packages to a repository (i.e., packages that are stored on your local file system), the corresponding host package folder must be bound explicitly to a folder inside the chroot container with --bind
since otherwise the package files cannot be accessed from inside the container
The example below shows how this works:
-
Create an empty package folder in the chroot container (in the home folder of the alarm user in this case):
arm-nspawn <YOUR-CHROOT-FOLDER>/root sudo -u alarm mkdir home/alarm/pkg
-
Add the package to a custom repository (the package folder of the host is bound to the just created folder
pkg
):arm-nspawn <YOUR-CHROOT-FOLDER>/root --bind <PACKAGE-FOLDER-AT-HOST>:/home/alarm/pkg sudo -u alarm repman add -r <REPOSITORY> -n -l home/alarm/pkg
If it is required to add a developer key, this must be done inside the chroot for the user that is used for package management
For example:
arm-nspawn <YOUR-CHROOT-FOLDER>/root sudo -u alarm gpg --recv-keys <KEY-ID>
arm-nspawn <YOUR-CHROOT-FOLDER>/root sudo -u alarm gpg --lsign-key <KEY-ID>
To be able to sign packages or the repository DB, a private key must be known inside the chroot
Execute the following steps to do add the key for user alarm:
-
Enter chroot and set the variable
GPGKEY
:arm-nspawn <YOUR-CHROOT-FOLDER>/root [root@root ~] nano /etc/makepkg.conf
-
Replace the row
#GPGKEY=""
by
GPGKEY=<ID-OF-YOUR-KEY>
-
Import the private key from a file (here, we assume that the file was copied into the chroot):
[root@root ~] sudo -u alarm gpg --pinentry-mode loopback --import <YOUR-KEY-FILE>
-
Set trust level for the key:
[root@root ~] sudo -u alarm gpg --edit-key <ID-OF-YOUR-KEY> gpg> trust
-
Select the desired trust level and exit:
gpg> quit
-
To be able to use the key with repman, the GPG configuration of user alarm must be adjusted:
Adjust
~/.gnupg/gpg.conf
:[root@root ~] sudo -u alarm nano /home/alarm/.gnupg/gpg.conf
Add the rows
use-agent pinentry-mode loopback
Adjust
~/.gnupg/gpg-agent.conf
:[root@root ~] sudo -u alarm nano /home/alarm/.gnupg/gpg-agent.conf
Add the row
allow-loopback-pinentry
-
Exit chroot:
root@root ~] exit