diff options
author | David P <megver83@parabola.nu> | 2021-07-08 22:57:45 -0400 |
---|---|---|
committer | bill-auger <mr.j.spam.me@gmail.com> | 2022-08-30 21:26:46 -0400 |
commit | 6d5a55989216ac0545d8ac0fd10215b1608ef980 (patch) | |
tree | 8aa921bf3d20a194b6b3d8e798341d0e0bb8546d | |
parent | de5205f21a660ebe0e338ec87905c420afdbe353 (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-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | archbuild.in | 2 | ||||
-rw-r--r-- | bash_completion.in | 4 | ||||
-rw-r--r-- | chroot-run.in (renamed from arch-nspawn.in) | 75 | ||||
-rw-r--r-- | lib/mount.sh | 84 | ||||
-rw-r--r-- | makechrootpkg.in | 15 | ||||
-rw-r--r-- | mkarchroot.in | 4 | ||||
-rw-r--r-- | zsh_completion.in | 4 |
9 files changed, 161 insertions, 31 deletions
@@ -15,4 +15,4 @@ rebuildpkgs zsh_completion find-libdeps crossrepomove -arch-nspawn +chroot-run @@ -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 -/' |