Managing Arch Linux ARM Repositories from x86_64 Systems
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:
- crema 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 crema 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. A row starting with
# indicates a command that must be executed as root, if a row starts with
$ the command is executed as normal user.
$ 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
# 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 crema 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/crema-git.git [root@root alarm]# cd crema-git [root@root crema-git]# sudo -u alarm makepkg -si [root@root crema-git]# cd .. [root@root alarm]# rm -rd crema-git
Create crema configuration and exit chroot:
[root@root alarm]# sudo -u alarm mkdir -p .config/crema [root@root alarm]# sudo -u alarm nano .config/crema/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.confas 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 crema add -r <YOUR_REPOSITORY> -n -a >PACKAGE>
Since crema builds in a chroot per default and a chroot in a chroot is not working, the option
-nhas to be set. This applies to
crema add ...and
crema update ....
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 crema inside the chroot container more convenient, it might make sense to create a shell alias like below by adding that row to your
alias crema-armv7h="sudo arm-nspawn <YOUR-CHROOT-DIRECTORY>/root sudo -u alarm crema"
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
--bindsince 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
# arm-nspawn <YOUR-CHROOT-FOLDER>/root --bind <PACKAGE-FOLDER-AT-HOST>:/home/alarm/pkg sudo -u alarm crema 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
# arm-nspawn <YOUR-CHROOT-FOLDER>/root [root@root ~]# nano /etc/makepkg.conf
Replace the row
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:
To be able to use the key with crema, the GPG configuration of user alarm must be adjusted:
[root@root ~]# sudo -u alarm nano /home/alarm/.gnupg/gpg.conf
Add the rows
use-agent pinentry-mode loopback
[root@root ~]# sudo -u alarm nano /home/alarm/.gnupg/gpg-agent.conf
Add the row
root@root ~]# exit