Advanced installation

This section describes steps that are automatically done by the script we suggested to use in Simple installation chapter, in order to let user to manually setup and configure its Local builder container by itself.

Setup your environnement:

Install LXD

sudo apt install lxd
sudo zypper addrepo --refresh snappy
sudo zypper –gpg-auto-import-keys refresh
sudo zypper dup –from snappy
sudo zypper install snapd
sudo systemctl enable snapd
sudo usermod -aG lxd ${USER}

Close your session and open a new one

sudo systemctl start snapd
sudo snap refresh
sudo snap install lxd
# make sure that any previous LXC version are uninstalled
sudo dnf remove lxc
# now install LXD
sudo dnf copr enable ganto/lxc3
sudo dnf install lxc lxd
sudo systemctl enable --now lxc lxd
sudo usermod -aG lxd ${USER}
# fix to be able to use systemd inside container
sudo sed -i -e 's:systemd.unified_cgroup_hierarchy=0 ::' -e 's:rhgb:systemd.unified_cgroup_hierarchy=0 rhgb:' grub /etc/default/grub
sudo grub2-mkconfig -o /etc/grub2.cfg

Initialize and configure LXD

LXD allows auto-configuration with a preseed file.

    cat << EOF | lxd init --preseed
      images.auto_update_interval: "0"
    - config:
        ipv4.address: auto
        ipv6.address: none
      description: ""
      managed: false
      name: lxdbr0
      type: ""
    - config: {}
      description: ""
      name: default
      driver: dir
    - config: {}
      description: ""
          name: eth0
          nictype: bridged
          parent: lxdbr0
          type: nic
          path: /
          pool: default
          type: disk
      name: default
    cluster: null
1. Being able to map user directory inside the container
# allowing the LXD daemon which is running as root to remap my host’s user ID inside a container:
echo "root:$(id -u):1" | sudo tee -a /etc/subuid /etc/subgid
2. Adding IotBzh LXD image store

Now, we have to add the Iot.Bzh LXC Image store as remote to the daemon:

lxc remote add iotbzh
Certificate fingerprint: ba56e65b627ecca7d652a91f2cbd784e1295bd5ac9491398d07424e6c6f22084
ok (y/n)? y
Password: <password>
lxc image list iotbzh:
|             ALIAS             | FINGERPRINT  | PUBLIC |                   DESCRIPTION                    |  ARCH  |   SIZE   |         UPLOAD DATE          |
| redpesk-builder/28            | f4946633a307 | yes    | Redpesk Devel 28 (Builder)                       | x86_64 | 386.63MB | Jan 14, 2021 at 5:29pm (UTC) |
| redpesk-builder/33            | a1880edf91ca | yes    | Redpesk Devel 33 (Builder)                       | x86_64 | 483.20MB | Jan 14, 2021 at 5:33pm (UTC) |
| redpesk-cloud-publication     | b610206a78b8 | yes    | Redpesk Cloud Publication Binding Host Container | x86_64 | 254.81MB | Feb 2, 2021 at 1:03pm (UTC)  |

3. Create a redpesk LXD profile

Create a redpesk profile to add custom configuration

# created only one time
lxc profile create redpesk

# add /dev/loop-control device to support mock 2.x
lxc profile device add redpesk loop-control unix-char path=/dev/loop-control
lxc profile set redpesk security.privileged true
lxc profile set redpesk security.nesting true
lxc profile set redpesk security.syscalls.blacklist "keyctl errno 38\nkeyctl_chown errno 38"

Setting up the LXC container

1. Import and start

Download and import the redpesk builder image:

export container_name
lxc launch iotbzh:redpesk-builder/33 ${container_name} -p default -p redpesk

Retrieve and add a host entry in your system to easily reach the container:

lxc network list-leases lxdbr0

# retrieve local address of your container
lxc ls -c 4

# OR
MY_IP_ADD_RESS=$(lxc ls --format json |jq -r '.[0][0].address')

echo "${MY_IP_ADD_RESS} ${container_name}" | sudo tee -a /etc/hosts

2. Mapping your user directory inside the container

You will have three repositories in your container (gitsources, gitpkgs, and build). To have files on your host and retrieve them in the container, you can precise directories path.

# Import your SSH key
lxc config device add ${container_name} my_ssh disk source=~/.ssh path=/home/devel/.ssh

# Add your applications sources directory, example:
# Add your gitpkgs directory (where is the specfile), example:
# Add your build directory (files generated by rpmbuild), example:

# Directories will be created if they don't exist
mkdir -p {$gitsources,$gitpkgs,$build}

# Mapping of host directories to retrieve your files in the container
lxc config device add ${container_name} my_gitsources disk source=${gitsources} path=/home/devel/gitsources
lxc config device add ${container_name} my_gitpkgs disk source=${gitpkgs} path=/home/devel/gitpkgs
lxc config device add ${container_name} my_build disk source=${build} path=/home/devel/rpmbuild

Enter in your container and watch permission inside the imported directory:

ssh devel@${container_name}
ls -l ~/gitsources
ls -l ~/gitpkgs
ls -l ~/build

If your files and directories are owned by the user nobody then you won’t be able to build directly from theses directories. You have to remap the uid/gid and restart the container:

lxc config set ${container_name} raw.idmap "uid $(id -u) 1000"
lxc config set ${container_name} raw.idmap "gid $(id -g) 1000"
lxc restart ${container_name}

Setup your HOST for local crossbuild


  1. Install qemu-user-static and remove qemu-user-binfmt from your host:
sudo apt install qemu-user-static binfmt-support
sudo apt remove qemu-user-binfmt
  1. Stop and disable automount of binfmt_misc:
sudo systemctl stop proc-sys-fs-binfmt_misc.automount
sudo systemctl disable proc-sys-fs-binfmt_misc.automount
sudo systemctl stop binfmt-support.service
  1. Manually mount binfmt_misc (if not already mounted):
sudo mount -t binfmt_misc none /proc/sys/fs/binfmt_misc/
  1. Modify /var/lib/binfmts/qemu-aarch64 with this exact content : sudo vim /var/lib/binfmts/qemu-aarch64

  1. Update qemu-aarch64 support:
sudo update-binfmts --disable qemu-aarch64
sudo update-binfmts --enable qemu-aarch64
  1. Verify the support of qemu-aarch64: cat /proc/sys/fs/binfmt_misc/qemu-aarch64

You might have this content:

interpreter /usr/bin/qemu-aarch64-static
flags: F
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff

NOTE: flags can be set to ‘0CF’. This is correct too.


Just install the qemu-user-static package:

sudo dnf install qemu-user-static

Verify the support of qemu-aarch64:

cat /proc/sys/fs/binfmt_misc/qemu-aarch64

You might have this content:

interpreter /usr/bin/qemu-aarch64-static
flags: F
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff