summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid P <megver83@parabola.nu>2021-07-08 22:57:45 -0400
committerbill-auger <mr.j.spam.me@gmail.com>2022-08-30 21:26:46 -0400
commit6d5a55989216ac0545d8ac0fd10215b1608ef980 (patch)
tree8aa921bf3d20a194b6b3d8e798341d0e0bb8546d
parentde5205f21a660ebe0e338ec87905c420afdbe353 (diff)
replace arch-nspawn with chroot-run (nonsystemd compat)
based in artix/artools Signed-off-by: David P <megver83@parabola.nu> Previously, these changes were kept on a separate nonsystemd branch for nonsystemd releases from v20180428 to v20190907. The nonsystemd build seems to work well on systemd systems, and it has no dependencies in [nonsystemd]; so there only needs to be one build in [libre]. This commit squashes the functional changes from the following commits from the former nonsystemd branch: * 7a2c689f3808a8b970006f9e8f01e883490ea72b chroot-run: declare mount_args at the beginning of the scriptlibretools-v20190907-nonsystemd * 37de77a06e7917ff50dec6ca469b45700986c698 chroot-run: better unshare arguments handling David P * 984c0b8e3c341b78ac689f0eeca1cf2460fc3336 chroot-run: use unshare David P * a57dfdb1cb87f9959b1cc218036456be7c7fa81d initial systemd-nspawn replacement with chroot David P
-rw-r--r--.gitignore2
-rw-r--r--Makefile2
-rw-r--r--archbuild.in2
-rw-r--r--bash_completion.in4
-rw-r--r--chroot-run.in (renamed from arch-nspawn.in)75
-rw-r--r--lib/mount.sh84
-rw-r--r--makechrootpkg.in15
-rw-r--r--mkarchroot.in4
-rw-r--r--zsh_completion.in4
9 files changed, 161 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index 1e92b82..0b61a93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,4 @@ rebuildpkgs
zsh_completion
find-libdeps
crossrepomove
-arch-nspawn
+chroot-run
diff --git a/Makefile b/Makefile
index 2d29c83..46094e8 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ BINPROGS = \
rebuildpkgs \
find-libdeps \
crossrepomove\
- arch-nspawn \
+ chroot-run \
mkarchroot \
makechrootpkg
diff --git a/archbuild.in b/archbuild.in
index 1e5b582..4e2aa7c 100644
--- a/archbuild.in
+++ b/archbuild.in
@@ -67,7 +67,7 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then
"${base_packages[@]}" || abort
else
lock 9 "${chroots}/${repo}-${arch}/root.lock" "Locking clean chroot"
- arch-nspawn \
+ chroot-run \
-C "@pkgdatadir@/pacman-${repo}.conf" \
-M "@pkgdatadir@/makepkg-${arch}.conf" \
"${chroots}/${repo}-${arch}/root" \
diff --git a/bash_completion.in b/bash_completion.in
index 9feef74..34a34af 100644
--- a/bash_completion.in
+++ b/bash_completion.in
@@ -68,7 +68,7 @@ _mkarchroot() {
} &&
complete -F _mkarchroot mkarchroot
-_arch-nspawn() {
+_chroot-run() {
local cur
COMPREPLY=()
_get_comp_words_by_ref cur
@@ -85,5 +85,5 @@ _arch-nspawn() {
true
} &&
-complete -F _arch-nspawn arch-nspawn
+complete -F _chroot-run chroot-run
# ex:et ts=2 sw=2 ft=sh
diff --git a/arch-nspawn.in b/chroot-run.in
index 96b3e38..4d832ec 100644
--- a/arch-nspawn.in
+++ b/chroot-run.in
@@ -12,32 +12,64 @@
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
+m4_include(lib/mount.sh)
+
+# $1: chroot
+kill_chroot_process(){
+ local prefix="$1" flink pid name
+ for root_dir in /proc/*/root; do
+ flink=$(readlink "$root_dir")
+ if [ "x$flink" != "x" ]; then
+ if [ "x${flink:0:${#prefix}}" = "x$prefix" ]; then
+ # this process is in the chroot...
+ pid=$(basename "$(dirname "$root_dir")")
+ name=$(ps -p "$pid" -o comm=)
+ msg2 "Killing chroot process: %s (%s)" "$name" "$pid"
+ kill -9 "$pid"
+ fi
+ fi
+ done
+ sleep 1
+}
-working_dir=''
+# umask might have been changed in /etc/profile
+# ensure that sane default is set again
+umask 0022
+working_dir=''
files=()
+mount_args=("-B:/etc/hosts:/etc/hosts")
+unshare_args=("-Cfimu")
+
usage() {
- echo "Usage: ${0##*/} [options] working-dir [systemd-nspawn arguments]"
- echo "A wrapper around systemd-nspawn. Provides support for pacman."
+ echo "Usage: ${0##*/} [options] working-dir [chroot arguments]"
+ echo "A wrapper around chroot. Provides support for pacman."
echo
echo ' options:'
echo ' -C <file> Location of a pacman config file'
echo ' -M <file> Location of a makepkg config file'
echo ' -c <dir> Set pacman cache'
echo ' -f <file> Copy file from the host to the chroot'
+ echo ' This option may be given multiple times'
echo ' -s Do not run setarch'
+ echo ' -b <args> Bind mountargs'
+ echo " <args> format: 'mntarg:srcdir:destdir'"
+ echo ' This option may be given multiple times'
+ echo ' -N Disable networking'
echo ' -h This message'
exit 1
}
-while getopts 'hC:M:c:f:s' arg; do
+while getopts 'hC:M:c:f:sb:N' arg; do
case "$arg" in
C) pac_conf="$OPTARG" ;;
M) makepkg_conf="$OPTARG" ;;
c) cache_dir="$OPTARG" ;;
f) files+=("$OPTARG") ;;
s) nosetarch=1 ;;
+ b) mount_args+=("$OPTARG") ;;
+ N) unshare_args+=("-n") ;;
h|?) usage ;;
*) error "invalid argument '%s'" "$arg"; usage ;;
esac
@@ -66,16 +98,14 @@ host_mirror=$($pacconf_cmd --repo extra Server 2> /dev/null | head -1 | sed -r '
# {{{ functions
build_mount_args() {
- declare -g mount_args=()
-
if [[ -n $host_mirror_path ]]; then
- mount_args+=("--bind-ro=$host_mirror_path")
+ mount_args+=("-B:$host_mirror_path:$host_mirror_path")
fi
- mount_args+=("--bind=${cache_dirs[0]}")
+ mount_args+=("-B:${cache_dirs[0]}:${cache_dirs[0]}")
for cache_dir in "${cache_dirs[@]:1}"; do
- mount_args+=("--bind-ro=$cache_dir")
+ mount_args+=("-Br:$cache_dir:$cache_dir")
done
}
@@ -94,6 +124,16 @@ copy_hostconf () {
sed -r "s|^#?\\s*CacheDir.+|CacheDir = ${cache_dirs[*]}|g" -i "$working_dir/etc/pacman.conf"
}
+
+chroot_extra_mount() {
+ chroot_add_resolv_conf "${working_dir}"
+
+ for arg in "${mount_args[@]}"; do
+ local flag=${arg%%:*} dest=${arg##*:} src=${arg%:*}
+ src=${src#*:}
+ chroot_mount "${src}" "${working_dir}${dest}" "${flag}"
+ done
+}
# }}}
umask 0022
@@ -106,6 +146,8 @@ elif [[ $(cat "$working_dir/.arch-chroot") != "$CHROOT_VERSION" ]]; then
fi
build_mount_args
+chroot_api_mount "${working_dir}" || die "failed to setup API filesystems in chroot %s" "${working_dir}"
+chroot_extra_mount
cache_dirs+=('/repo/')
copy_hostconf
@@ -116,9 +158,14 @@ esac
[[ -z $nosetarch ]] || unset CARCH
-exec ${CARCH:+setarch "$CARCH"} systemd-nspawn -q \
- -D "$working_dir" \
- -E "PATH=/usr/local/sbin:/usr/local/bin:/usr/bin" \
- --register=no --keep-unit --as-pid2 \
- "${mount_args[@]}" \
+${CARCH:+setarch "$CARCH"} unshare \
+ "${unshare_args[@]}" \
+ --mount-proc \
+ --setgroups allow \
+ -- \
+ chroot \
+ "${working_dir}" \
"$@"
+ret=$?
+kill_chroot_process "${working_dir}"
+exit $ret
diff --git a/lib/mount.sh b/lib/mount.sh
new file mode 100644
index 0000000..2705717
--- /dev/null
+++ b/lib/mount.sh
@@ -0,0 +1,84 @@
+#!/hint/bash
+
+#{{{ mount
+
+ignore_error() {
+ "$@" 2>/dev/null
+ return 0
+}
+
+trap_setup(){
+ [[ $(trap -p EXIT) ]] && die 'Error! Attempting to overwrite existing EXIT trap'
+ trap "$1" EXIT
+}
+
+chroot_mount() {
+# msg2 "mount: [%s]" "$2"
+ mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}")
+}
+
+chroot_add_resolv_conf() {
+ local chrootdir=$1 resolv_conf=$1/etc/resolv.conf
+
+ [[ -e /etc/resolv.conf ]] || return 0
+
+ # Handle resolv.conf as a symlink to somewhere else.
+ if [[ -L $chrootdir/etc/resolv.conf ]]; then
+ # readlink(1) should always give us *something* since we know at this point
+ # it's a symlink. For simplicity, ignore the case of nested symlinks.
+ resolv_conf=$(readlink "$chrootdir/etc/resolv.conf")
+ if [[ $resolv_conf = /* ]]; then
+ resolv_conf=$chrootdir$resolv_conf
+ else
+ resolv_conf=$chrootdir/etc/$resolv_conf
+ fi
+
+ # ensure file exists to bind mount over
+ if [[ ! -f $resolv_conf ]]; then
+ install -Dm644 /dev/null "$resolv_conf" || return 1
+ fi
+ elif [[ ! -e $chrootdir/etc/resolv.conf ]]; then
+ # The chroot might not have a resolv.conf.
+ return 0
+ fi
+
+ chroot_mount /etc/resolv.conf "$resolv_conf" --bind
+}
+
+chroot_mount_conditional() {
+ local cond=$1; shift
+ if eval "$cond"; then
+ chroot_mount "$@"
+ fi
+}
+
+chroot_setup(){
+ local mnt="$1" os="$2" args='-t tmpfs -o nosuid,nodev,mode=0755'
+ $os && args='--bind'
+ chroot_mount_conditional "! mountpoint -q '$mnt'" "$mnt" "$mnt" --bind &&
+ chroot_mount proc "$mnt/proc" -t proc -o nosuid,noexec,nodev &&
+ chroot_mount sys "$mnt/sys" -t sysfs -o nosuid,noexec,nodev,ro &&
+ ignore_error chroot_mount_conditional "[[ -d '$mnt/sys/firmware/efi/efivars' ]]" \
+ efivarfs "$mnt/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev &&
+ chroot_mount udev "$mnt/dev" -t devtmpfs -o mode=0755,nosuid &&
+ chroot_mount devpts "$mnt/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec &&
+ chroot_mount shm "$mnt/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev &&
+ chroot_mount /run "$mnt/run" ${args} &&
+ chroot_mount tmp "$mnt/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid
+}
+
+chroot_api_mount() {
+ CHROOT_ACTIVE_MOUNTS=()
+ trap_setup chroot_api_umount
+ chroot_setup "$1" false
+}
+
+chroot_api_umount() {
+ if (( ${#CHROOT_ACTIVE_MOUNTS[@]} )); then
+# msg2 "umount: [%s]" "${CHROOT_ACTIVE_MOUNTS[@]}"
+ umount "${CHROOT_ACTIVE_MOUNTS[@]}"
+ fi
+ unset CHROOT_ACTIVE_MOUNTS
+}
+
+#}}}
diff --git a/makechrootpkg.in b/makechrootpkg.in
index 492991e..cd58fb1 100644
--- a/makechrootpkg.in
+++ b/makechrootpkg.in
@@ -159,7 +159,7 @@ install_packages() {
pkgnames=("${install_pkgs[@]##*/}")
cp -- "${install_pkgs[@]}" "$copydir/root/"
- arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
+ chroot-run "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
pacman -U --noconfirm -- "${pkgnames[@]/#//root/}"
ret=$?
rm -- "${pkgnames[@]/#/$copydir/root/}"
@@ -435,8 +435,8 @@ main() {
while getopts 'hcur:I:l:nTD:d:U:' arg; do
case "$arg" in
c) clean_first=true ;;
- D) bindmounts_ro+=("--bind-ro=$OPTARG") ;;
- d) bindmounts_rw+=("--bind=$OPTARG") ;;
+ D) bindmounts_ro+=(-b "-Br:$OPTARG:$OPTARG") ;;
+ d) bindmounts_rw+=(-b "-B:$OPTARG:$OPTARG") ;;
u) update_first=true ;;
r) passeddir="$OPTARG" ;;
I) install_pkgs+=("$OPTARG") ;;
@@ -502,7 +502,7 @@ main() {
sync_chroot "$chrootdir/root" "$copydir" "$copy"
fi
- $update_first && arch-nspawn "$copydir" \
+ $update_first && chroot-run "$copydir" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
pacman -Syu --noconfirm
@@ -521,10 +521,9 @@ main() {
download_sources "$copydir" "$makepkg_user"
prepare_chroot "$copydir" "$USER_HOME" "$keepbuilddir" "$run_namcap"
-
- if arch-nspawn "$copydir" \
- --bind="$PWD:/startdir" \
- --bind="$SRCDEST:/srcdest" \
+ if chroot-run "$copydir" \
+ -b "-B:$PWD:/startdir" \
+ -b "-B:$SRCDEST:/srcdest" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootbuild "${makepkg_args[@]}"
then
diff --git a/mkarchroot.in b/mkarchroot.in
index 5165960..0f6c408 100644
--- a/mkarchroot.in
+++ b/mkarchroot.in
@@ -90,9 +90,9 @@ printf '%s.UTF-8 UTF-8\n' en_US de_DE > "$working_dir/etc/locale.gen"
echo 'LANG=en_US.UTF-8' > "$working_dir/etc/locale.conf"
echo "$CHROOT_VERSION" > "$working_dir/.arch-chroot"
-systemd-machine-id-setup --root="$working_dir"
+dbus-uuidgen --ensure="$working_dir"/etc/machine-id
-exec "$(librelib chroot/arch-nspawn)" \
+exec "$(librelib chroot/chroot-run)" \
${nosetarch:+-s} \
${pac_conf:+-C "$pac_conf"} \
${makepkg_conf:+-M "$makepkg_conf"} \
diff --git a/zsh_completion.in b/zsh_completion.in
index 3bd4c4d..82bcced 100644
--- a/zsh_completion.in
+++ b/zsh_completion.in
@@ -1,4 +1,4 @@
-#compdef archbuild archco arch-nspawn archrelease archrm commitpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-x86_64-build=archbuild testing-x86_64-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild multilib-staging-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-x86_64-build=archbuild communityco=archco
+#compdef archbuild archco chroot-run archrelease archrm commitpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-x86_64-build=archbuild testing-x86_64-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild multilib-staging-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-x86_64-build=archbuild communityco=archco
# License: Unspecified
m4_include(lib/valid-tags.sh)
@@ -12,7 +12,7 @@ _archco_args=(
'*:packages:_devtools_completions_all_packages'
)
-_arch_nspawn_args=(
+_chroot_run_args=(
'-C[Location of a pacman config file]:pacman_config:_files'
'-M[Location of a makepkg config file]:makepkg_config:_files'
'-c[Set pacman cache]:pacman_cache:_files -/'