You are not logged in.

#1 2026-04-13 21:15:27

maesli
Member
Registered: 2024-09-26
Posts: 7

pacstrap inside package()

I have this makefile which installs a new systemd-nspawn container:

MACHINES_DIR=/var/lib/machines
CONT_NAME=generic-arch

all:
        echo "nothing to build, just 'make install'"

install:
        mkdir -p $(DESTDIR)$(MACHINES_DIR)/$(CONT_NAME)
        pacstrap -K -c $(DESTDIR)$(MACHINES_DIR)/$(CONT_NAME) base
        install -D -m644 generic-arch.nspawn $(DESTDIR)/etc/systemd/nspawn/$(CONT_NAME).nspawn
        cat init.sh | systemd-nspawn -P -D $(DESTDIR)$(MACHINES_DIR)/$(CONT_NAME)

init.sh:

#! /bin/bash

LC_ALL=C tr -dc '[:graph:]' </dev/urandom | head -c 16 | passwd -s
systemctl enable systemd-networkd
systemctl enable systemd-resolved

generic-arch.nspawn:

[Exec]
PrivateUsers=managed
ResolvConf=bind-static

[Network]
Bridge=br0

I created a PKGBUILD for that setup:

pkgname="msl-base-arch"
pkgver=r3.a235591
pkgrel=1
pkgdesc="Base arch container"
arch=(any)
url=""
license=('unknown')
groups=()
depends=('systemd' 'bash')
makedepends=('git' 'arch-install-scripts' 'pacman' 'fakeroot' 'systemd')
provides=("${pkgname}")
conflicts=("${pkgname}")
replaces=()
backup=()
options=()
install=
source=("${srcdir}/${pkgname}::git://generic-arch/msl-gen-cont.git")
noextract=()
sha256sums=('SKIP')

pkgver() {
        cd "${srcdir}/${pkgname}"
        printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}

prepare() {
        cd "${srcdir}/${pkgname}"
        rename generic-arch base-arch *
        sed -i 's/generic-arch/base-arch/g' *
        sed -i 's/br0/msl-util-br/g' *
}

package() {
        cd "${srcdir}/${pkgname}"
        make DESTDIR="$pkgdir" install
}

When I run makepkg, I get the following:

==> Making package: msl-base-arch r2.0eddcf5-1 (Mon Apr 13 22:25:34 2026)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Updating /msl-base-arch git repo...
==> Validating source files with sha256sums...
    /msl-base-arch ... Skipped
==> Extracting sources...
  -> Creating working copy of /msl-base-arch git repo...
Reset branch 'makepkg'
==> Starting prepare()...
==> Starting pkgver()...
==> Removing existing $pkgdir/ directory...
==> Entering fakeroot environment...
==> Starting package()...
mkdir -p /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
pacstrap -K -c /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch base
==> Creating install root at /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
ERROR: ld.so: object 'libfakeroot.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
mount: /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch/proc: must be superuser to use mount.
       dmesg(1) may have more information after failed mount system call.
==> ERROR: failed to setup chroot /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
make: *** [makefile:9: install] Error 1
==> ERROR: A failure occurred in package().
    Aborting...

I get the same error when running

makechrootpkg -c -x failure -r $CHROOT

When I add sudo before pacstrap, makepkg prompts me my own password and fails at the fourth line of make install, while makechrootpkg prompts for builduser's password.

Why does pacstrap require root privileges in fakeroot? What am I missing here?

Offline

#2 2026-04-13 21:41:46

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 74,648

Re: pacstrap inside package()

Does "pacstrap -N -…" work?

Offline

#3 2026-04-14 05:15:34

maesli
Member
Registered: 2024-09-26
Posts: 7

Re: pacstrap inside package()

When I add the -N flag, with makepkg I get:

==> Starting package()...
mkdir -p /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
pacstrap -N -K -c /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch base
unshare: failed to write /proc/55957/uid_map: Operation not permitted
install -D -m644 base-arch.nspawn /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/etc/systemd/nspawn/base-arch.nspawn
cat init.sh | systemd-nspawn -P -D /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
Failed to lock /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch: Permission denied
make: *** [makefile:11: install] Error 1
==> ERROR: A failure occurred in package().
    Aborting...

With makechrootpkg I get:

==> Starting package()...
mkdir -p /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
pacstrap -N -K -c /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch base
unshare: no line matching user "root" in /etc/subuid
install -D -m644 base-arch.nspawn /build/msl-base-arch/pkg/msl-base-arch/etc/systemd/nspawn/base-arch.nspawn
cat init.sh | systemd-nspawn -P -D /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch
Failed to lock /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch: No such file or directory
make: *** [makefile:11: install] Error 1
==> ERROR: A failure occurred in package().
    Aborting...
==> ERROR: Build failed, inspecting /home/maesli/projects/msl-base-arch/chroot/maesli
[builduser@arch-nspawn-59036 ~]$ cd msl-base-arch/pkg/msl-base-arch/
etc/ var/
[builduser@arch-nspawn-59036 ~]$ cd msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch/
[builduser@arch-nspawn-59036 base-arch]$ ls
[builduser@arch-nspawn-59036 base-arch]$
logout
==> ERROR: Build failed, check /home/maesli/projects/msl-base-arch/chroot/maesli/build

In both cases, the targeted /var/lib/machines directories (/home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch and /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch) are empty as if pacstrap didn't run anything.

Offline

#4 2026-04-14 08:01:47

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 74,648

Re: pacstrap inside package()

Seems people have been there before…
https://gitlab.archlinux.org/archlinux/ … k_items/25

Why does pacstrap require root privileges in fakeroot?

ERROR: ld.so: object 'libfakeroot.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

https://bbs.archlinux.org/viewtopic.php … 25#p712825
But you can trace pacstrap by adding "set -x" at the top (it's a bash script)
Edit: under the shebang!

Last edited by seth (2026-04-14 08:02:03)

Offline

#5 2026-04-15 18:34:12

maesli
Member
Registered: 2024-09-26
Posts: 7

Re: pacstrap inside package()

I did some research and it seems that the fakeroot environment is just a facade for file creation with adequate UIDs and GIDs, but doesn't actually fool mount into mounting stuff. So far, the -N flag and unshare seems like the way to go, but I don't quite understand namespaces yet so I'll look into it more closely

Offline

#6 2026-04-15 19:34:47

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 74,648

Re: pacstrap inside package()

mount has the suid set which is why libfakeroot.so cannot be preloaded, so fakeroot doesn't apply.
unshare likely lacks some data structure in the chroot

/build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch: No such file or directory

despite

mkdir -p /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch

Offline

#7 2026-04-15 20:23:12

maesli
Member
Registered: 2024-09-26
Posts: 7

Re: pacstrap inside package()

The directory does exist, but it is empty because unshare had an error during pacstrap:

pacstrap -N -K -c /build/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch base
unshare: no line matching user "root" in /etc/subuid

Since this is what happens in the makechrootpkg, at a point where nothing is expected to exist in the soon-to-be-container's root dir, seems that I should setup id mapping in /build/msl-base-arch/pkg/msl-base-arch/etc/subuid, which I'm not yet sure how to even approach.

In the plain old makepkg case though, the soon-to-be-container's root dir is also empty because I suppose I got the uid mappings wrong:

pacstrap -N -K -c /home/maesli/projects/msl-base-arch/pkg/msl-base-arch/var/lib/machines/base-arch base
unshare: failed to write /proc/55957/uid_map: Operation not permitted

So now I'm doing a deep dive into namespaces to figure out what sort of uid mapping setup I really need.

Offline

#8 2026-04-17 22:30:12

maesli
Member
Registered: 2024-09-26
Posts: 7

Re: pacstrap inside package()

So I started experimenting with unshare to see whether the /etc/subuid and /etc/subgid setup was correct and it seems to work:

$ unshare --fork --pid --mount --map-auto --map-root-user --setuid 0 --setgid 0 /bin/bash
# id
uid=0(root) gid=0(root) groups=0(root)
#

But if I call fakeroot first, unshare doesn't work anymore:

$ fakeroot
# unshare --fork --pid --mount --map-auto --map-root-user --setuid 0 --setgid 0 /bin/bash
unshare: failed to write /proc/133202/uid_map: Operation not permitted
# id
uid=0(root) gid=0(root) groups=0(root)
#

I ended up cloning the repo which contains unshare and found out that it literally fails on a libc's write() call with EPERM error code, which according to man is caused by missing permissions in fcntl. I checked the contents of LD_PRELOAD in fakeroot and it's libfakeroot.so. I ran

 $ nm -D -U /usr/lib/libfakeroot/libfakeroot.so

, but it doesn't seem to contain neither write nor fcntl, so I honestly can't pinpoint what part of fakeroot is breaking unshare. I might just call it there and try another way of packaging nspawn containers.

Offline

Board footer

Powered by FluxBB