summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archbuild.in9
-rw-r--r--lib/common.sh51
-rw-r--r--makechrootpkg.in17
-rw-r--r--mkarchroot.in99
4 files changed, 119 insertions, 57 deletions
diff --git a/archbuild.in b/archbuild.in
index 9f9633c..4dcc0f3 100644
--- a/archbuild.in
+++ b/archbuild.in
@@ -51,17 +51,12 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then
[[ -d $copy ]] || continue
msg2 "Deleting chroot copy '$(basename "${copy}")'..."
- exec 9>"$copydir.lock"
- if ! flock -n 9; then
- stat_busy "Locking chroot copy '$copy'"
- flock 9
- stat_done
- fi
+ lock_open_write 9 "$copy.lock" "Locking chroot copy '$copy'"
{ type -P btrfs && btrfs subvolume delete "${copy}"; } &>/dev/null
rm -rf --one-file-system "${copy}"
done
- exec 9>&-
+ lock_close 9
rm -rf --one-file-system "${chroots}/${repo}-${arch}"
mkdir -p "${chroots}/${repo}-${arch}"
diff --git a/lib/common.sh b/lib/common.sh
index b39bbbc..932799e 100644
--- a/lib/common.sh
+++ b/lib/common.sh
@@ -104,6 +104,57 @@ in_array() {
}
##
+# usage : lock_open_write( $fd, $path, $wait_message )
+##
+lock_open_write() {
+ local fd=$1
+ local path=$2
+ local msg=$3
+
+ # Only reopen the FD if it wasn't handed to us
+ if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then
+ mkdir -p "${path%/*}"
+ eval "exec $fd>${path}.lock"
+ fi
+
+ if ! flock -n $fd; then
+ stat_busy "$msg"
+ flock $fd
+ stat_done
+ fi
+}
+
+##
+# usage : lock_open_read( $fd, $path, $wait_message )
+##
+lock_open_read() {
+ local fd=$1
+ local path=$2
+ local msg=$3
+
+ # Only reopen the FD if it wasn't handed to us
+ if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then
+ mkdir -p "${path%/*}"
+ eval "exec $fd>${path}.lock"
+ fi
+
+ if ! flock -sn $fd; then
+ stat_busy "$msg"
+ flock -s $fd
+ stat_done
+ fi
+}
+
+
+##
+# usage : lock_close( $fd )
+##
+lock_close() {
+ local fd=$1
+ eval "exec $fd>&-"
+}
+
+##
# usage : get_full_version( [$pkgname] )
# return : full version spec, including epoch (if necessary), pkgver, pkgrel
##
diff --git a/makechrootpkg.in b/makechrootpkg.in
index e7e5f21..717e02f 100644
--- a/makechrootpkg.in
+++ b/makechrootpkg.in
@@ -119,23 +119,12 @@ chroottype=$(stat -f -c %T "$chrootdir")
# Lock the chroot we want to use. We'll keep this lock until we exit.
# Note this is the same FD number as in mkarchroot
-exec 9>"$copydir.lock"
-if ! flock -n 9; then
- stat_busy "Locking chroot copy [$copy]"
- flock 9
- stat_done
-fi
+lock_open_write 9 "$copydir.lock" "Locking chroot copy [$copy]"
if [[ ! -d $copydir ]] || $clean_first; then
# Get a read lock on the root chroot to make
# sure we don't clone a half-updated chroot
- exec 8>"$chrootdir/root.lock"
-
- if ! flock -sn 8; then
- stat_busy "Locking clean chroot"
- flock -s 8
- stat_done
- fi
+ lock_open_read 8 "$chrootdir/root" "Locking clean chroot"
stat_busy "Creating clean working copy [$copy]"
if [[ "$chroottype" == btrfs ]]; then
@@ -152,7 +141,7 @@ if [[ ! -d $copydir ]] || $clean_first; then
stat_done
# Drop the read lock again
- exec 8>&-
+ lock_close 8
fi
if [[ -n "${install_pkgs[*]}" ]]; then
diff --git a/mkarchroot.in b/mkarchroot.in
index 9059cdb..ce732be 100644
--- a/mkarchroot.in
+++ b/mkarchroot.in
@@ -13,8 +13,9 @@ m4_include(lib/common.sh)
CHROOT_VERSION='v2'
FORCE='n'
-RUN=''
+MODE='i'
NOCOPY='n'
+NONETWORK='n'
working_dir=''
@@ -22,49 +23,81 @@ APPNAME=$(basename "${0}")
# usage: usage <exitvalue>
usage() {
- echo "Usage: ${APPNAME} [options] working-dir [package-list | app]"
+ echo "Usage: ${APPNAME} [options] working-dir [exta-arguments]"
echo ' options:'
- echo ' -r <app> Run "app" within the context of the chroot'
- echo ' -u Update the chroot via pacman'
echo ' -f Force overwrite of files in the working-dir'
echo ' -C <file> Location of a pacman config file'
echo ' -M <file> Location of a makepkg config file'
echo ' -n Do not copy config files into the chroot'
echo ' -c <dir> Set pacman cache'
- echo ' -h This message'
- exit 1
+ echo ' -N Disable networking in the chroot'
+ echo ' modes:'
+ echo ' -i Install the packages "extra-arguments" in the chroot.'
+ echo ' This creates the chroot if it does not exist.'
+ echo ' This is the default mode.'
+ echo ' -r Run the command "extra-arguments" within the chroot'
+ echo ' -u Update the chroot via pacman'
+ echo ' -h Print this message'
+
+ exit ${1-1}
}
-while getopts 'r:ufnhC:M:c:' arg; do
+################################################################################
+
+while getopts 'fC:M:nc:Niruh' arg; do
case "${arg}" in
- r) RUN="$OPTARG" ;;
- u) RUN='pacman -Syu --noconfirm' ;;
f) FORCE='y' ;;
C) pac_conf="$OPTARG" ;;
M) makepkg_conf="$OPTARG" ;;
n) NOCOPY='y' ;;
c) cache_dir="$OPTARG" ;;
- h|?) usage ;;
+ N) NONETWORK='y' ;;
+
+ i|r|u) MODE="$arg" ;;
+ h) usage 0 ;;
+
*) error "invalid argument '${arg}'"; usage ;;
esac
done
-if (( $EUID != 0 )); then
- die 'This script must be run as root.'
-fi
-
shift $(($OPTIND - 1))
-if [[ -z $RUN ]] && (( $# < 2 )); then
- die 'You must specify a directory and one or more packages.'
-elif (( $# < 1 )); then
- die 'You must specify a directory.'
+case $MODE in
+ i)
+ case $# in
+ 0) die 'You must specify a directory and one or more packages.' ;;
+ 1) die 'You must specify one or more packages.' ;;
+ esac
+ ;;
+ r)
+ case $# in
+ 0) die 'You must specify a directory and a command.' ;;
+ 1) die 'You must specify a command.' ;;
+ esac
+ ;;
+ u)
+ case $# in
+ 0) die 'You must specify a directory.' ;;
+ 1) : ;;
+ 2) die 'Extra arguments' ;;
+ esac
+ ;;
+esac
+
+working_dir="$(readlink -f "${1}")"
+shift 1
+[[ -z $working_dir ]] && die 'Please specify a working directory.'
+
+if [[ $MODE == u ]]; then
+ MODE=r
+ set -- pacman -Syu --noconfirm
fi
-working_dir="$(readlink -f ${1})"
-shift 1
+################################################################################
-[[ -z $working_dir ]] && die 'Please specify a working directory.'
+if (( $EUID != 0 )); then
+ die 'This script must be run as root.'
+fi
if [[ -z $cache_dir ]]; then
cache_dirs=($(pacman -v $cache_conf 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g'))
@@ -112,29 +145,23 @@ copy_hostconf () {
}
chroot_lock () {
- # Only reopen the FD if it wasn't handed to us
- if [[ $(readlink -f /dev/fd/9) != "${working_dir}.lock" ]]; then
- exec 9>"${working_dir}.lock"
- fi
-
- # Lock the chroot. Take note of the FD number.
- if ! flock -n 9; then
- stat_busy "Locking chroot"
- flock 9
- stat_done
- fi
+ lock_open_write 9 "${working_dir}" "Locking chroot"
}
chroot_run() {
local dir=$1
shift
- systemd-nspawn -D "${dir}" "${mount_args[@]}" -- ${@} 2>/dev/null
+ local nspawn_args=(-D "$dir" "${mount_args[@]}")
+ if [[ $NONETWORK = y ]]; then
+ nspawn_args+=(--private-network)
+ fi
+ systemd-nspawn "${nspawn_args[@]}" -- "${@}" 2>/dev/null
}
# }}}
umask 0022
-if [[ -n $RUN ]]; then
+if [[ $MODE == r ]]; then
# run chroot {{{
#Sanity check
if [[ ! -f "${working_dir}/.arch-chroot" ]]; then
@@ -147,10 +174,10 @@ if [[ -n $RUN ]]; then
build_mount_args
copy_hostconf
- chroot_run "${working_dir}" ${RUN}
+ chroot_run "${working_dir}" "$@"
# }}}
-else
+elif [[ $MODE == i ]]; then
# {{{ build chroot
if [[ -e $working_dir && $FORCE = 'n' ]]; then
die "Working directory '${working_dir}' already exists - try using -f"