Orchestration and Services
Infrabase https://github.com/EDGEMTech/infrabase is a lightweight build and deployment environment tailored for embedded systems development, it uses the Bitbake task orchestrator and some classes from the core layer of OpenEmbedded.
It's possible to try out Infrabase - to get started follow the guide to setup the build dependencies :
https://edgemtech.github.io/infrabase/user_guide.html#pre-requisites
Once the setup is complete, you can get a running Linux system like so:
git clone https://github.com/EDGEMTech/infrabase
cd infrabase
. env.sh
build.sh -a bsp-linux
build.sh -x qemu # Build qemu
This builds everything needed to produce a system with a Linux kernel and the user space system utilities provided by Buildroot. It also builds a custom version of Qemu.
Now we are ready for the deployment:
sudo deploy.sh -a bsp-linux
This will create an SD card image in the ./filesystem directory, it is then possible to start the image inside Qemu by running:
stv # Starts the system
If everything went well, you should get to the root shell.
One of the strong points of Infrabase is that it handles deployment. Normally Yocto-based build solutions
handle deployment operations with external scripts or tools, this is not the case in Infrabase, deployment is done inside the recipes.
This is why deploy.sh invokes bitbake using sudo - normally, one is not supposed to run Bitbake as the root user!
Instead it's necessary to use the fakeroot utility to imitate the root user. For example Yocto uses fakeroot to prepare archives where files need to be owned by root.
Fakeroot works by using the LD_PRELOAD environment variable to load a wrapper around the getuid, chown, chmod system calls.
For Infrabase however, the use of fakeroot is not sufficient as it needs full root privileges to use the mount(2) syscall to be able to mount the filesystem image using a loop device
In previous versions of Infrabase the user had to add "username ALL=(ALL) NOPASSWD: ALL" to /etc/sudoers.conf during the initial setup.
This was because sudo was used extensively inside deployment tasks. In recent versions, I have removed the use of sudo inside the tasks and instead have opted to execute bitbake as the root user. But this approach is not great either as it creates stamp and log files as root. Currently, we run chown at the end of each deployment task. - this is cumbersome and it's easy to forget to add a call at the end of the task that is run as root to restore file ownership.
So I've been on the hunt for another solution and decided to check if it's possible to use namespaces to imitate the root user ? Turns out it is, one can start /bin/bash in a namespace where the regular user id is mapped to the root user.
unshare --map-root-user /bin/dash
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
# >testing
# ls -lah
-rw-rw-r-- 1 root root 0 Okt 12 19:15 testing
# exit
ls -lah testing
-rw-rw-r-- 1 etag etag 0 Okt 12 19:15 testing
Inside the namespace the file is created as root, but outside it will belong to the regular user. Namespaces allow to have a different view of the file system on a per-process basis.
Just like fakeroot, this technique has some limitations, it is not possible to mount/umount volumes or modify files owned by root.
Processes can also join an existing namespaces with the setns(2) syscall. So one can prepare a namespace as a privileged user and then share it with other less privileged processes ? The proof of concepts I did seems to be indicating that this is possible - So I will attempt to use this technique in Infrabase in the coming weeks.