summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2020-08-14 17:37:25 -0400
committerAndreas Grapentin <andreas@grapentin.org>2022-01-18 17:29:36 +0100
commitef67221e1971aca6b0891b2f6ac30da07fe1037d (patch)
tree60ec3ea06923a5d490100ed3db204b6718e2cbe8
parent4fc356ae8183780fc5a6dd875600fd0e3ee9d6fd (diff)
refactor librechroot args processing
-rwxr-xr-xsrc/chroot-tools/librechroot230
1 files changed, 130 insertions, 100 deletions
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
index 56a8292..ae01e51 100755
--- a/src/chroot-tools/librechroot
+++ b/src/chroot-tools/librechroot
@@ -41,6 +41,76 @@ umask 0022
################################################################################
+# Utility functions #
+################################################################################
+
+# Usage: detect_chroot_arch $makepkg_conf
+detect_chroot_arch()
+{
+ local makepkg_conf="$1"
+ local chroot_arch
+
+ chroot_arch=$(grep -a '^CARCH=' "$makepkg_conf" 2> /dev/null | cut -d '=' -f 2 | tr -d '"')
+ [[ ${chroot_arch} =~ x86_64|i686|armv7h ]] || chroot_arch=$(uname -m)
+
+ echo ${chroot_arch}
+}
+
+# Usage: make_empty_repo $copydir
+make_empty_repo() {
+ local copydir=$1
+ mkdir -p "${copydir}/repo"
+ bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null
+ ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db"
+}
+
+# Usage: chroot_add_to_local_repo $copydir $pkgfiles...
+chroot_add_to_local_repo() {
+ local copydir=$1; shift
+ mkdir -p "$copydir/repo"
+ local pkgfile
+ for pkgfile in "$@"; do
+ cp "$pkgfile" "$copydir/repo"
+ pushd "$copydir/repo" >/dev/null
+ repo-add repo.db.tar.gz "${pkgfile##*/}"
+ popd >/dev/null
+ done
+}
+
+# Print code to set $rootdir and $copydir; blank them on error
+calculate_directories() {
+ # Don't assume that CHROOTDIR or CHROOT are set,
+ # but assume that COPY is set.
+ local rootdir copydir
+
+ if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then
+ rootdir="${CHROOTDIR}/${CHROOT}/root"
+ else
+ rootdir=''
+ fi
+
+ if [[ ${COPY:0:1} = / ]]; then
+ copydir=$COPY
+ elif [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then
+ copydir="${CHROOTDIR}/${CHROOT}/${COPY}"
+ else
+ copydir=''
+ fi
+
+ declare -p rootdir
+ declare -p copydir
+}
+
+check_mountpoint() {
+ local file=$1
+ local mountpoint mountopts
+ mountpoint="$(df -P "$file"|sed '1d;s/.*\s//')"
+ mountopts=($(LC_ALL=C mount|awk "{ if (\$3==\"$mountpoint\") { gsub(/[(,)]/, \" \", \$6); print \$6 } }"))
+ ! in_array nosuid "${mountopts[@]}" && ! in_array noexec "${mountopts[@]}"
+}
+
+
+################################################################################
# Wrappers for files in ${pkglibexecdir}/chroot/ #
################################################################################
@@ -64,15 +134,9 @@ hack_arch_nspawn_flags() {
esac
done
- # Detect the architecture of the chroot
- local CARCH
- if [[ -f "$makepkg_conf" ]]; then
- eval "$(grep -a '^CARCH=' "$makepkg_conf")"
- else
- CARCH="$(uname -m)"
- fi
-
+ local CARCH=$(detect_chroot_arch "$makepkg_conf")
local setarch interpreter
+
case $CARCH in
armv7h|armv7l) setarch=armv7l; interpreter=/usr/bin/qemu-arm-static ;;
*) setarch=$CARCH; interpreter=/usr/bin/qemu-$CARCH-static ;;
@@ -141,67 +205,14 @@ mkarchroot() {
"${cmd[@]}"
}
-################################################################################
-# Utility functions #
-################################################################################
-
-# Usage: make_empty_repo $copydir
-make_empty_repo() {
- local copydir=$1
- mkdir -p "${copydir}/repo"
- bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null
- ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db"
-}
-
-# Usage: chroot_add_to_local_repo $copydir $pkgfiles...
-chroot_add_to_local_repo() {
- local copydir=$1; shift
- mkdir -p "$copydir/repo"
- local pkgfile
- for pkgfile in "$@"; do
- cp "$pkgfile" "$copydir/repo"
- pushd "$copydir/repo" >/dev/null
- repo-add repo.db.tar.gz "${pkgfile##*/}"
- popd >/dev/null
- done
-}
-
-# Print code to set $rootdir and $copydir; blank them on error
-calculate_directories() {
- # Don't assume that CHROOTDIR or CHROOT are set,
- # but assume that COPY is set.
- local rootdir copydir
-
- if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then
- rootdir="${CHROOTDIR}/${CHROOT}/root"
- else
- rootdir=''
- fi
-
- if [[ ${COPY:0:1} = / ]]; then
- copydir=$COPY
- elif [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then
- copydir="${CHROOTDIR}/${CHROOT}/${COPY}"
- else
- copydir=''
- fi
-
- declare -p rootdir
- declare -p copydir
-}
-
-check_mountpoint() {
- local file=$1
- local mountpoint mountopts
- mountpoint="$(df -P "$file"|sed '1d;s/.*\s//')"
- mountopts=($(LC_ALL=C mount|awk "{ if (\$3==\"$mountpoint\") { gsub(/[(,)]/, \" \", \$6); print \$6 } }"))
- ! in_array nosuid "${mountopts[@]}" && ! in_array noexec "${mountopts[@]}"
-}
################################################################################
# Main program #
################################################################################
+readonly DEF_PACMANCONF_DIR=/usr/share/pacman/defaults/
+
+
usage() {
eval "$(calculate_directories)"
print "Usage: %s [OPTIONS] COMMAND [ARGS...]" "${0##*/}"
@@ -252,10 +263,10 @@ usage() {
by the by `CARCH` variable in the `/etc/makepkg.conf`
file inside of the chroot.'
echo
- prose 'The `-A CARCH` flag is *almost* simply an alias for'
- printf ' %s\n' \
- '-C "/usr/share/pacman/defaults/pacman.conf.$CARCH" \' \
- '-M "/usr/share/pacman/defaults/makepkg.conf.$CARCH"'
+ prose 'The `-A CARCH` flag is *almost* simply an alias for'
+ printf ' %s\n' \
+ "-C \"${DEF_PACMAN_CONF_DIR}pacman.conf.\$CARCH\" \\" \
+ "-M \"${DEF_PACMAN_CONF_DIR}makepkg.conf.\$CARCH\""
prose 'However, before doing that, it actually makes a temporary copy of
`pacman.conf`, and modifies it to:'
bullet 'set `Architecture` to match the `CARCH` line in `makepkg.conf`'
@@ -310,43 +321,36 @@ main() {
declare -i retconf=0
load_conf chroot.conf CHROOTDIR CHROOT || retconf=$?
+ local target_arch=$(uname -m)
local mode=enter opt
declare -Ai used_opts
+ local tmp_pacmanconf="$(mktemp --tmpdir ${tmp_pacmanconf_prefix}.XXXXXXXXXX)"
+ local has_tmp_pacmanconf=0
+ local def_pacmanconf
+ local def_makepkgconf
+
+ trap 'rm -f -- "$tmp_pacmanconf"' EXIT
+
## parse CLI options ##
while getopts 'n:l:NC:M:A:w:r:' opt; do
case $opt in
- n) CHROOT=$OPTARG;;
- l) COPY=$OPTARG;;
- N) sysd_nspawn_flags+=(--private-network);;
- C|M) arch_nspawn_flags+=(-$opt "$OPTARG");;
- A)
- if ! [[ -f "/usr/share/pacman/defaults/pacman.conf.$OPTARG" && -f "/usr/share/pacman/defaults/makepkg.conf.$OPTARG" ]]; then
- error 'Unsupported architecture: %s' "$OPTARG"
- plain 'See the files in %q for valid architectures.' /usr/share/pacman/defaults/
- return $EXIT_INVALIDARGUMENT;
- fi
- trap 'rm -f -- "$tmppacmanconf"' EXIT
- tmppacmanconf="$(mktemp --tmpdir librechroot-pacman.conf.XXXXXXXXXX)"
- sed -r \
- -e "s|^#?\\s*Architecture.+|Architecture = ${OPTARG}|g" \
- -e "s|^.*Include\s*=\s*/etc/pacman.d/.*\.conf|#&|" \
- < "/usr/share/pacman/defaults/pacman.conf.$OPTARG" \
- > "$tmppacmanconf"
- echo -e '\n\n# Enable the volatile i686 [build-support] repo only as needed.' \
- '\n#[build-support]\n#Server = http://mirror.archlinux32.org/$arch/$repo/' \
- '\n\n# Enable the volatile arm [aur] repo only as needed.' \
- '\n#[aur]\n#Server = https://mirror.archlinuxarm.org/$arch/$repo/' \
- >> "$tmppacmanconf"
- arch_nspawn_flags+=(
- -C "$tmppacmanconf"
- -M "/usr/share/pacman/defaults/makepkg.conf.$OPTARG"
- );;
- w) sysd_nspawn_flags+=("--bind=$OPTARG");;
- r) sysd_nspawn_flags+=("--bind-ro=$OPTARG");;
- *) usage >&2; return $EXIT_INVALIDARGUMENT;;
+ n ) CHROOT=$OPTARG ;;
+ l ) COPY=$OPTARG ;;
+ N ) sysd_nspawn_flags+=(--private-network) ;;
+ C|M) target_arch=$(detect_chroot_arch "$OPTARG")
+ arch_nspawn_flags+=(-$opt "$OPTARG") ;;
+ A ) target_arch=$OPTARG
+ def_pacmanconf="${DEF_PACMANCONF_DIR}"pacman.conf.${target_arch}
+ def_makepkgconf="${DEF_PACMANCONF_DIR}"makepkg.conf.${target_arch}
+ arch_nspawn_flags+=( -C "${tmp_pacmanconf}"
+ -M "${def_makepkgconf}" )
+ has_tmp_pacmanconf=1 ;;
+ w ) sysd_nspawn_flags+=("--bind=$OPTARG") ;;
+ r ) sysd_nspawn_flags+=("--bind-ro=$OPTARG") ;;
+ * ) usage >&2; return $EXIT_INVALIDARGUMENT ;;
esac
used_opts[$opt]+=1
done
@@ -425,6 +429,31 @@ main() {
fi
:;;
esac
+ if (( has_tmp_pacmanconf )) && \
+ ! [[ -f "${def_pacmanconf}" && -f "${def_makepkgconf}" ]]; then
+ error 'Unsupported architecture: %s' "${target_arch}"
+ plain 'See the files in %q for valid architectures.' "${DEF_PACMANCONF_DIR}"
+ return $EXIT_INVALIDARGUMENT;
+ fi
+
+
+ ## process CLI options ##
+
+ if (( has_tmp_pacmanconf )); then
+ sed -r \
+ -e "s|^#?\\s*Architecture.+|Architecture = ${target_arch}|g" \
+ -e "s|^.*Include\s*=\s*/etc/pacman.d/.*\.conf|#&|" \
+ < "${def_pacmanconf}" \
+ > "$tmp_pacmanconf"
+ echo -e '\n\n# Enable the volatile i686 [build-support] repo only as needed.' \
+ '\n#[build-support]\n#Server = http://mirror.archlinux32.org/$arch/$repo/' \
+ '\n\n# Enable the volatile arm [aur] repo only as needed.' \
+ '\n#[aur]\n#Server = https://mirror.archlinuxarm.org/$arch/$repo/' \
+ >> "$tmp_pacmanconf"
+ fi
+
+
+ ## finalize state ##
[[ $retconf = 0 ]] || exit $retconf
eval "$(calculate_directories)"
@@ -434,7 +463,8 @@ main() {
readonly rootdir copydir
readonly mode
- ########################################################################
+
+ ## business ##
if (( EUID )); then
error "This program must be run as root."
@@ -484,8 +514,8 @@ main() {
# - set 'CacheDir' in \`/etc/pacman.conf'"
# - apply -C or -M flags
arch-nspawn "$copydir" true </dev/null
- if [[ -n ${tmppacmanconf:-} ]]; then
- rm -f -- "$tmppacmanconf"
+ if [[ -n ${tmp_pacmanconf:-} ]]; then
+ rm -f -- "$tmp_pacmanconf"
fi
trap EXIT # clear the trap to remove the tmp pacman.conf from -A
arch_nspawn_flags=() # XXX dirty hack, don't apply -C or -M again