feat(makechrootpkg): add option to interactively inspect the chroot

Implement the -x option for makechrootpkg which allows to get an
interactive shell in the chroot after building the package. Useful to
ease the debugging of a package build.

Depending on the argument, the interactive shell is either always
spawned or only when an error occurred during build.

This option is also forwarded from `pkgctl build` via the `--inspect`
flag.

Component: pkgctl build
Component: makechrootpkg
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
This commit is contained in:
Levente Polyak 2023-03-23 23:38:29 +01:00
parent c9de6a18b9
commit cc369e86d2
No known key found for this signature in database
GPG Key ID: FC1B547C8D8172C8
7 changed files with 75 additions and 5 deletions

View File

@ -7,6 +7,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# shellcheck source=src/lib/valid-inspect.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
_binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1}
_colors=(never always auto)
@ -24,6 +26,7 @@ _makechrootpkg_args=(
-n
-T
-U
-x
)
_makechrootpkg_args_d_opts() { _filedir -d; }
_makechrootpkg_args_D_opts() { _filedir -d; }
@ -31,6 +34,7 @@ _makechrootpkg_args_r_opts() { _filedir -d; }
_makechrootpkg_args_I_opts() { _filedir '*.pkg.tar.*'; }
_makechrootpkg_args_l_opts() { _filedir -d; }
_makechrootpkg_args_U_opts() { :; }
_makechrootpkg_args_x_opts() { _devtools_completions_inspect; }
_makechrootpkg() { __devtools_complete _makechrootpkg; }
complete -F _makechrootpkg makechrootpkg
@ -169,6 +173,7 @@ _pkgctl_build_args=(
-o --offload
-c --clean
-w --worker
--inspect
--pkgver
--pkgrel
@ -186,6 +191,7 @@ _pkgctl_build_args__arch_opts() { _devtools_completions_arch; }
_pkgctl_build_args__repo_opts() { _devtools_completions_repo; }
_pkgctl_build_args__worker_opts() { :; }
_pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; }
_pkgctl_build_args__inspect_opts() { _devtools_completions_inspect; }
_pkgctl_build_args__pkgver_opts() { :; }
_pkgctl_build_args__pkgrel_opts() { :; }
_pkgctl_build_args__message_opts() { :; }
@ -371,6 +377,9 @@ _devtools_completions_all_packages() {
_devtools_completions_protocol() {
mapfile -t COMPREPLY < <(compgen -W "https" -- "$cur")
}
_devtools_completions_inspect() {
mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_INSPECT_MODES[*]}" -- "$cur")
}
__devtools_complete() {
local service=$1

View File

@ -7,6 +7,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# shellcheck source=src/lib/valid-inspect.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
_binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1}
_colors=(never always auto)
@ -42,6 +44,7 @@ _pkgctl_build_args=(
'(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]'
'(-c --clean)'{-c,--clean}'[Recreate the chroot before building]'
'(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"'
"--inspect[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])"
'(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:'
'--nocheck[Do not run the check() function in the PKGBUILD]'
'--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:'
@ -190,6 +193,7 @@ _makechrootpkg_args=(
'-n[Run namcap on the package]'
'-T[Build in a temporary directory]'
'-U[Run makepkg as a specified user]:makepkg_user'
"-x[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])"
)
_mkarchroot_args=(

View File

@ -73,4 +73,8 @@ Options
*-U*::
Run makepkg as a specified user
*-x* <when>::
Inspect chroot after build, possible modes are 'never' (default), 'always' or 'failure'
include::include/footer.asciidoc[]

View File

@ -38,6 +38,10 @@ Build Options
*-I, --install* 'FILE'::
Install a package into the working copy of the chroot
*--inspect* 'WHEN'::
Spawn an interactive shell to inspect the chroot after building. Useful to ease the debugging of a package build. +
Possible values for 'WHEN' are `'never'`, `'always'` or `'failure'`
*-w, --worker* 'SLOT'::
Name of the worker slot, useful for concurrent builds. By default the slot
is automatically assigned to the current tty pts number. In case the caller

View File

@ -20,6 +20,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# shellcheck source=src/lib/valid-tags.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# shellcheck source=src/lib/valid-inspect.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
source /usr/share/makepkg/util/config.sh
source /usr/share/makepkg/util/message.sh
@ -48,6 +50,7 @@ pkgctl_build_usage() {
-o, --offload Build on a remote server and transfer artifacts afterwards
-c, --clean Recreate the chroot before building
-I, --install FILE Install a package into the working copy of the chroot
--inspect WHEN Spawn an interactive shell to inspect the chroot (never, always, failure)
-w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names)
--nocheck Do not run the check() function in the PKGBUILD
@ -218,6 +221,14 @@ pkgctl_build() {
warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!'
shift
;;
--inspect)
(( $# <= 1 )) && die "missing argument for %s" "$1"
if ! in_array "${2}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then
die "Invalid inspect mode: %s" "${2}"
fi
MAKECHROOT_OPTIONS+=("-x" "${2}")
shift 2
;;
-r|--release)
# shellcheck source=src/lib/release.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh

10
src/lib/valid-inspect.sh Normal file
View File

@ -0,0 +1,10 @@
#!/hint/bash
#
# SPDX-License-Identifier: GPL-3.0-or-later
# shellcheck disable=2034
DEVTOOLS_VALID_INSPECT_MODES=(
never
always
failure
)

View File

@ -8,9 +8,12 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
# shellcheck source=src/lib/valid-inspect.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
source /usr/share/makepkg/util/config.sh
source /usr/share/makepkg/util/util.sh
shopt -s nullglob
@ -31,6 +34,8 @@ run_checkpkg=0
temp_chroot=0
tmp_opts="nosuid,nodev,size=50%,nr_inodes=2m"
inspect=never
bindmounts_ro=()
bindmounts_rw=()
@ -76,6 +81,7 @@ usage() {
echo '-C Run checkpkg on the package'
echo '-T Build in a temporary directory'
echo '-U Run makepkg as a specified user'
echo '-x <when> Inspect chroot after build (never, always, failure)'
exit 1
}
@ -280,7 +286,7 @@ move_products() {
}
# }}}
while getopts 'hcur:I:l:nCTD:d:U:' arg; do
while getopts 'hcur:I:l:nCTD:d:U:x:' arg; do
case "$arg" in
c) clean_first=1 ;;
D) bindmounts_ro+=("--bind-ro=$OPTARG") ;;
@ -293,6 +299,7 @@ while getopts 'hcur:I:l:nCTD:d:U:' arg; do
C) run_checkpkg=1 ;;
T) temp_chroot=1; copy+="-$$" ;;
U) makepkg_user="$OPTARG" ;;
x) inspect="$OPTARG" ;;
h|*) usage ;;
esac
done
@ -314,6 +321,10 @@ else
copydir="$chrootdir/$copy"
fi
if ! in_array "${inspect}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then
die "Invalid inspect mode: %s" "${inspect}"
fi
# Pass all arguments after -- right to makepkg
makepkg_args+=("${@:$OPTIND}")
@ -368,11 +379,16 @@ download_sources
prepare_chroot
nspawn_build_args=(
--bind="${PWD//:/\\:}:/startdir"
--bind="${SRCDEST//:/\\:}:/srcdest"
--tmpfs="/tmp:${tmp_opts}"
"${bindmounts_ro[@]}"
"${bindmounts_rw[@]}"
)
if arch-nspawn "$copydir" \
--bind="${PWD//:/\\:}:/startdir" \
--bind="${SRCDEST//:/\\:}:/srcdest" \
--tmpfs="/tmp:${tmp_opts}" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
"${nspawn_build_args[@]}" \
/chrootbuild "${makepkg_args[@]}"
then
mapfile -t pkgnames < <(sudo -u "$makepkg_user" bash -c 'source PKGBUILD; printf "%s\n" "${pkgname[@]}"')
@ -382,6 +398,18 @@ else
move_logfiles
fi
if [[ $inspect == always ]] || ( [[ $inspect == failure ]] && (( ret != 0 )) ); then
if (( ret == 0 )); then
msg "Build succeeded, inspecting %s" "$copydir"
else
error "Build failed, inspecting %s" "$copydir"
fi
arch-nspawn "$copydir" \
"${nspawn_build_args[@]}" \
--user=builduser \
--chdir=/build
fi
(( temp_chroot )) && delete_chroot "$copydir" "$copy"
if (( ret != 0 )); then