Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--arch-nspawn.in2
-rw-r--r--lib/common.sh32
-rw-r--r--makechrootpkg.in250
-rw-r--r--makepkg-x86_64.conf2
5 files changed, 121 insertions, 167 deletions
diff --git a/Makefile b/Makefile
index f3c9692..d93fefd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-V=20160527.1
+V=20160528
PREFIX = /usr/local
diff --git a/arch-nspawn.in b/arch-nspawn.in
index 85af8c5..adee72e 100644
--- a/arch-nspawn.in
+++ b/arch-nspawn.in
@@ -61,7 +61,7 @@ else
cache_dirs=("$cache_dir")
fi
-host_mirror=$(pacman -Sddp extra/devtools 2>/dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#')
+host_mirror=$(pacman --cachedir /doesnt/exist -Sddp extra/devtools 2>/dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#')
[[ $host_mirror == *file://* ]] && host_mirror_path=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g')
# {{{ functions
diff --git a/lib/common.sh b/lib/common.sh
index b8bab9b..68b001d 100644
--- a/lib/common.sh
+++ b/lib/common.sh
@@ -162,19 +162,15 @@ get_full_version() {
# usage : lock( $fd, $file, $message, [ $message_arguments... ] )
##
lock() {
- local fd=$1
- local file=$2
- local mesg=("${@:3}")
-
# Only reopen the FD if it wasn't handed to us
- if ! [[ "/dev/fd/$fd" -ef "$file" ]]; then
- mkdir -p "${file%/*}"
- eval "exec $fd>"'"$file"'
+ if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
+ mkdir -p "${2%/*}"
+ eval "exec $1>"'"$2"'
fi
- if ! flock -n $fd; then
- stat_busy "${mesg[@]}"
- flock $fd
+ if ! flock -n $1; then
+ stat_busy "${@:3}"
+ flock $1
stat_done
fi
}
@@ -183,19 +179,15 @@ lock() {
# usage : slock( $fd, $file, $message, [ $message_arguments... ] )
##
slock() {
- local fd=$1
- local file=$2
- local mesg=("${@:3}")
-
# Only reopen the FD if it wasn't handed to us
- if ! [[ "/dev/fd/$fd" -ef "$file" ]]; then
- mkdir -p "${file%/*}"
- eval "exec $fd>"'"$file"'
+ if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
+ mkdir -p "${2%/*}"
+ eval "exec $1>"'"$2"'
fi
- if ! flock -sn $fd; then
- stat_busy "${mesg[@]}"
- flock -s $fd
+ if ! flock -sn $1; then
+ stat_busy "${@:3}"
+ flock -s $1
stat_done
fi
}
diff --git a/makechrootpkg.in b/makechrootpkg.in
index 7ff2fd7..c6ef240 100644
--- a/makechrootpkg.in
+++ b/makechrootpkg.in
@@ -102,12 +102,37 @@ btrfs_subvolume_id() (
#
# Given $FILEPATH somewhere on a mounted btrfs filesystem, print the
# ID and full path of every subvolume on the filesystem, one per line
-# in the format "$ID $PATH".
+# in the format "$ID $PATH", where $PATH is relative to the top-level
+# subvolume (which might not be what is mounted).
+#
+# BUG: Due to limitations in the `btrfs` tool, this will not correctly
+# list subvolumes whose path contains a space.
btrfs_subvolume_list_all() (
set -o pipefail
- local mountpoint
- mountpoint="$(df --output=target "$1" | sed 1d)" || return $?
- LC_ALL=C btrfs subvolume list -a "$mountpoint" | sed -r 's|^ID ([0-9]+) .* path (<FS_TREE>/)?(\S*).*|\1 \3|'
+
+ local mountpoint all
+ mountpoint="$(df --output=target "$1" | sed 1d)" || return
+ # The output of `btrfs subvolume list -a` is a space-separated
+ # sequence of "key value key value...". Unfortunately both
+ # keys and values can contain space, and there's no escaping
+ # or indication of when this happens. So we assume
+ # 1. ID is the first column
+ # 2. That no key or value will contain " path"
+ # 3. That the "path" value does not contain a space.
+ all="$(LC_ALL=C btrfs subvolume list -a "$mountpoint" | sed -r 's|^ID ([0-9]+) .* path (<FS_TREE>/)?(\S*).*|\1 \3|')" || return
+
+ # Sanity check the output
+ local id path
+ while read -r id path; do
+ # ID should be numeric
+ [[ "$id" =~ ^-?[0-9]+$ ]] || return
+ # While a path could countain a space, the above code
+ # doesn't support it; if there is space, then it means
+ # we got a line not matching the expected format.
+ [[ "$path" != *' '* ]] || return
+ done <<<"$all"
+
+ printf '%s\n' "$all"
)
# Usage: btrfs_subvolume_list $SUBVOLUME
@@ -120,9 +145,9 @@ btrfs_subvolume_list() {
local subvolume=$1
local id all path subpath
- id="$(btrfs_subvolume_id "$subvolume")" || return $?
- all="$(btrfs_subvolume_list_all "$subvolume")" || return $?
- path="$(sed -n "s/^$id //p" <<<"$all")"
+ id="$(btrfs_subvolume_id "$subvolume")" || return
+ all="$(btrfs_subvolume_list_all "$subvolume")" || return
+ path=$(awk -v id="$id" '$1 == id { sub($1 FS, ""); print }' <<<"$all")
while read -r id subpath; do
if [[ "$subpath" = "$path"/* ]]; then
printf '%s\n' "${subpath#"${path}/"}"
@@ -139,11 +164,20 @@ btrfs_subvolume_list() {
# `btrfs subvolume delete`.
btrfs_subvolume_delete() {
local dir="$1"
- local subvolumes subvolume
- subvolumes=($(btrfs_subvolume_list "$dir")) || return $?
- for subvolume in "${subvolumes[@]}"; do
- btrfs subvolume delete "$dir/$subvolume" || return $?
- done
+
+ # We store the result as a variable because we want to see if
+ # btrfs_subvolume_list fails or succeeds before we start
+ # deleting things. (Then we have to work around the subshell
+ # trimming the trailing newlines.)
+ local subvolumes
+ subvolumes="$(btrfs_subvolume_list "$dir")" || return
+ [[ -z "$subvolumes" ]] || subvolumes+=$'\n'
+
+ local subvolume
+ while read -r subvolume; do
+ btrfs subvolume delete "$dir/$subvolume" || return
+ done < <(printf '%s' "$subvolumes")
+
btrfs subvolume delete "$dir"
}
@@ -217,21 +251,17 @@ delete_chroot() {
install_packages() {
local copydir=$1
local install_pkgs=("${@:2}")
- declare -i ret=0
- local pkgname
- local install_pkg
- for install_pkg in "${install_pkgs[@]}"; do
- pkgname="${install_pkg##*/}"
- cp "$install_pkg" "$copydir/$pkgname"
+ local -a pkgnames
+ local ret
- arch-nspawn "$copydir" \
- "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
- pacman -U /$pkgname --noconfirm
- (( ret += !! $? ))
+ pkgnames=("${install_pkgs[@]##*/}")
- rm "$copydir/$pkgname"
- done
+ cp -- "${install_pkgs[@]}" "$copydir/root/"
+ arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
+ pacman -U --noconfirm -- "${pkgnames[@]/#//root/}"
+ ret=$?
+ rm -- "${pkgnames[@]/#/$copydir/root/}"
return $ret
}
@@ -248,67 +278,38 @@ prepare_chroot() {
$repack || rm -rf "$copydir/build"
- mkdir -p "$copydir/build"
- if ! grep -q 'BUILDDIR="/build"' "$copydir/etc/makepkg.conf"; then
- echo 'BUILDDIR="/build"' >> "$copydir/etc/makepkg.conf"
- fi
-
- # Read .makepkg.conf and gnupg pubring
- if [[ -r $USER_HOME/.gnupg/pubring.kbx ]]; then
- install -D "$USER_HOME/.gnupg/pubring.kbx" "$copydir/build/.gnupg/pubring.kbx"
- fi
- if [[ -r $USER_HOME/.gnupg/pubring.gpg ]]; then
- install -D "$USER_HOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg"
- fi
-
- mkdir -p "$copydir/pkgdest"
- if ! grep -q 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf"; then
- echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf"
- fi
-
- mkdir -p "$copydir/srcpkgdest"
- if ! grep -q 'SRCPKGDEST="/srcpkgdest"' "$copydir/etc/makepkg.conf"; then
- echo 'SRCPKGDEST="/srcpkgdest"' >> "$copydir/etc/makepkg.conf"
- fi
-
- mkdir -p "$copydir/logdest"
- if ! grep -q 'LOGDEST="/logdest"' "$copydir/etc/makepkg.conf"; then
- echo 'LOGDEST="/logdest"' >> "$copydir/etc/makepkg.conf"
- fi
-
- # These two get bind-mounted read-only
- # XXX: makepkg dislikes having these dirs read-only, so separate them
- mkdir -p "$copydir/startdir" "$copydir/startdir_host"
- mkdir -p "$copydir/srcdest" "$copydir/srcdest_host"
- if ! grep -q 'SRCDEST="/srcdest"' "$copydir/etc/makepkg.conf"; then
- echo 'SRCDEST="/srcdest"' >> "$copydir/etc/makepkg.conf"
- fi
-
- builduser_uid=${SUDO_UID:-$UID}
+ local builduser_uid="${SUDO_UID:-$UID}"
+ local builduser_gid="$(id -g "$builduser_uid")"
+ local install="install -o $builduser_uid -g $builduser_gid"
+ local x
# We can't use useradd without chrooting, otherwise it invokes PAM modules
# which we might not be able to load (i.e. when building i686 packages on
# an x86_64 host).
- printf 'builduser:x:%d:100:builduser:/build:/bin/bash\n' "$builduser_uid" >>"$copydir/etc/passwd"
- chown -R "$builduser_uid" "$copydir"/{build,pkgdest,srcpkgdest,logdest,srcdest,startdir}
+ sed -e '/^builduser:/d' -i "$copydir"/etc/{passwd,group}
+ printf >>"$copydir/etc/group" 'builduser:x:%d:\n' $builduser_gid
+ printf >>"$copydir/etc/passwd" 'builduser:x:%d:%d:builduser:/build:/bin/bash\n' $builduser_uid $builduser_gid
- if [[ -n ${MAKEFLAGS:-} ]]; then
- sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf"
- echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf"
- fi
+ $install -d "$copydir"/{build,build/.gnupg,startdir,{pkg,srcpkg,src,log}dest}
- if [[ -n ${PACKAGER:-} ]]; then
- sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf"
- echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf"
- fi
+ for x in .gnupg/pubring.{kbx,gpg}; do
+ [[ -r $USER_HOME/$x ]] || continue
+ $install -m 644 "$USER_HOME/$x" "$copydir/build/$x"
+ done
- if [[ ! -f $copydir/etc/sudoers.d/builduser-pacman ]]; then
- cat > "$copydir/etc/sudoers.d/builduser-pacman" <<EOF
+ sed -e '/^MAKEFLAGS=/d' -e '/^PACKAGER=/d' -i "$copydir/etc/makepkg.conf"
+ for x in BUILDDIR=/build PKGDEST=/pkgdest SRCPKGDEST=/srcpkgdest SRCDEST=/srcdest LOGDEST=/logdest \
+ "MAKEFLAGS='${MAKEFLAGS:-}'" "PACKAGER='${PACKAGER:-}'"
+ do
+ grep -q "^$x" "$copydir/etc/makepkg.conf" && continue
+ echo "$x" >>"$copydir/etc/makepkg.conf"
+ done
+
+ cat > "$copydir/etc/sudoers.d/builduser-pacman" <<EOF
Defaults env_keep += "HOME"
builduser ALL = NOPASSWD: /usr/bin/pacman
EOF
- chmod 440 "$copydir/etc/sudoers.d/builduser-pacman"
- fi
+ chmod 440 "$copydir/etc/sudoers.d/builduser-pacman"
if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then
local line=$(grep -n '^\[' "$copydir/etc/pacman.conf" |grep -Fv ':[options]'|sed 's/:.*//;1q')
@@ -318,6 +319,9 @@ Server = file:///repo
'
sed -i "${line}i${ins//$'\n'/\\n}" "$copydir/etc/pacman.conf"
fi
+ # Avoid having to use `pacman -Sy` to update [repo], as
+ # networking might be disabled inside of the chroot.
+ cp "$copydir/repo/repo.db" "$copydir/var/lib/pacman/sync/repo.db"
# This is a little gross, but this way the script is recreated every time in the
# working copy
@@ -333,18 +337,33 @@ Server = file:///repo
printf '_chrootbuild "$@" || exit\n'
if $run_namcap; then
- cat <<'EOF'
-pacman -S --needed --noconfirm namcap
-for pkgfile in /startdir/PKGBUILD /pkgdest/*; do
- echo "Checking ${pkgfile##*/}"
- sudo -u builduser namcap "$pkgfile" 2>&1 | tee "/logdest/${pkgfile##*/}-namcap.log"
-done
-EOF
+ declare -f _chrootnamcap
+ printf '_chrootnamcap || exit\n'
fi
} >"$copydir/chrootbuild"
chmod +x "$copydir/chrootbuild"
}
+# These functions aren't run in makechrootpkg,
+# so no global variables
+_chrootprepare() {
+ . /etc/profile
+ sudo -iu builduser bash -c 'cd /startdir; makepkg "$@" --nobuild' -bash "$@"
+}
+
+_chrootbuild() {
+ . /etc/profile
+ sudo -iu builduser bash -c 'cd /startdir; makepkg "$@" --noextract --noprepare' -bash "$@"
+}
+
+_chrootnamcap() {
+ pacman -S --needed --noconfirm namcap
+ for pkgfile in /startdir/PKGBUILD /pkgdest/*; do
+ echo "Checking ${pkgfile##*/}"
+ sudo -u builduser namcap "$pkgfile" 2>&1 | tee "/logdest/${pkgfile##*/}-namcap.log"
+ done
+}
+
# Usage: download_sources $copydir $src_owner
# Globals:
# - SRCDEST
@@ -371,63 +390,6 @@ download_sources() {
rm -rf "$builddir"
}
-_chrootprepare() {
- # This function isn't run in makechrootpkg,
- # so no global variables
-
- . /etc/profile
- export HOME=/build
- shopt -s nullglob
-
- # XXX: Workaround makepkg disliking read-only dirs
- rm -rf -- /srcdest/* /startdir/*
- ln -sft /srcdest /srcdest_host/*
- ln -sft /startdir /startdir_host/*
-
- # XXX: Keep bzr and svn sources writable
- # Since makepkg 4.1.1 they get checked out via cp -a, copying the symlink
- for dir in /srcdest /startdir; do
- for vcs in bzr svn; do
- cd "$dir"
- for vcsdir in */.$vcs; do
- rm "${vcsdir%/.$vcs}"
- cp -a "${dir}_host/${vcsdir%/.$vcs}" .
- chown -R builduser "${vcsdir%/.$vcs}"
- done
- done
- done
-
- cd /startdir
-
- # XXX: Keep PKGBUILD writable for pkgver()
- rm PKGBUILD*
- cp /startdir_host/PKGBUILD* .
- chown builduser PKGBUILD*
-
- # Safety check
- if [[ ! -w PKGBUILD ]]; then
- echo "Can't write to PKGBUILD!"
- exit 1
- fi
-
- # Sync deps now, as networking may be disabled during _chrootbuild
- cp /repo/repo.db /var/lib/pacman/sync/repo.db
- sudo -u builduser makepkg "$@" --nobuild
-}
-
-_chrootbuild() {
- # This function isn't run in makechrootpkg,
- # so no global variables
-
- . /etc/profile
- export HOME=/build
- shopt -s nullglob
-
- cd /startdir
-
- sudo -u builduser makepkg "$@" --noextract --noprepare
-}
-
# Usage: move_products $copydir $owner
# Globals:
# - PKGDEST
@@ -515,7 +477,7 @@ main() {
umask 0022
- load_vars "$USER_HOME/.makepkg.conf"
+ load_vars "${XDG_CONFIG_HOME:-$USER_HOME/.config}/pacman/makepkg.conf" || load_vars "$USER_HOME/.makepkg.conf"
load_vars /etc/makepkg.conf
# Use PKGBUILD directory if these don't exist
@@ -547,13 +509,13 @@ main() {
prepare_chroot "$copydir" "$USER_HOME" "$repack"
if arch-nspawn "$copydir" \
- --bind-ro="$PWD:/startdir_host" \
- --bind-ro="$SRCDEST:/srcdest_host" \
+ --bind="$PWD:/startdir" \
+ --bind="$SRCDEST:/srcdest" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootprepare "${makepkg_args[@]}" &&
arch-nspawn "$copydir" \
- --bind-ro="$PWD:/startdir_host" \
- --bind-ro="$SRCDEST:/srcdest_host" \
+ --bind="$PWD:/startdir" \
+ --bind="$SRCDEST:/srcdest" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootbuild "${makepkg_args[@]}"
then
diff --git a/makepkg-x86_64.conf b/makepkg-x86_64.conf
index bf83f35..058da9b 100644
--- a/makepkg-x86_64.conf
+++ b/makepkg-x86_64.conf
@@ -31,7 +31,7 @@ VCSCLIENTS=('bzr::bzr'
#########################################################################
#
CARCH="x86_64"
-CHOST="x86_64-unknown-linux-gnu"
+CHOST="x86_64-pc-linux-gnu"
#-- Compiler and Linker Flags
# -march (or -mcpu) builds exclusively for an architecture