diff options
-rw-r--r-- | Makefile | 141 | ||||
-rwxr-xr-x | archbuild | 35 | ||||
-rwxr-xr-x | finddeps | 4 | ||||
-rwxr-xr-x | makechrootpkg | 65 | ||||
-rwxr-xr-x | mkarchroot | 29 |
5 files changed, 169 insertions, 105 deletions
@@ -1,90 +1,71 @@ V=0.9.17 +BINPROGS = \ + checkpkg \ + commitpkg \ + archco \ + communityco \ + archrelease \ + archrm \ + archbuild \ + lddd \ + finddeps \ + rebuildpkgs + +SBINPROGS = \ + mkarchroot \ + makechrootpkg + +CONFIGFILES = \ + makepkg-i686.conf \ + makepkg-x86_64.conf \ + pacman-extra.conf \ + pacman-testing.conf \ + pacman-staging.conf \ + pacman-multilib.conf \ + pacman-multilib-testing.conf + +COMMITPKG_LINKS = \ + extrapkg \ + corepkg \ + testingpkg \ + stagingpkg \ + communitypkg \ + community-testingpkg \ + community-stagingpkg \ + multilibpkg \ + multilib-testingpkg + +ARCHBUILD_LINKS = \ + extra-i686-build \ + extra-x86_64-build \ + testing-i686-build \ + testing-x86_64-build \ + staging-i686-build \ + staging-x86_64-build \ + multilib-build \ + multilib-testing-build + all: install: - # commitpkg/checkpkg and friends - install -d -m755 $(DESTDIR)/usr/bin - install -m 755 checkpkg $(DESTDIR)/usr/bin - install -m 755 commitpkg $(DESTDIR)/usr/bin - ln -sf commitpkg $(DESTDIR)/usr/bin/extrapkg - ln -sf commitpkg $(DESTDIR)/usr/bin/corepkg - ln -sf commitpkg $(DESTDIR)/usr/bin/testingpkg - ln -sf commitpkg $(DESTDIR)/usr/bin/stagingpkg - ln -sf commitpkg $(DESTDIR)/usr/bin/communitypkg - ln -sf commitpkg $(DESTDIR)/usr/bin/community-testingpkg - ln -sf commitpkg $(DESTDIR)/usr/bin/community-stagingpkg - ln -sf commitpkg $(DESTDIR)/usr/bin/multilibpkg - ln -sf commitpkg $(DESTDIR)/usr/bin/multilib-testingpkg - # arch{co,release,rm} - install -m 755 archco $(DESTDIR)/usr/bin - install -m 755 communityco $(DESTDIR)/usr/bin - install -m 755 archrelease $(DESTDIR)/usr/bin - install -m 755 archrm $(DESTDIR)/usr/bin - # new chroot tools, only usable by root - install -d -m 755 $(DESTDIR)/usr/sbin - install -m 755 mkarchroot $(DESTDIR)/usr/sbin - install -m 755 makechrootpkg $(DESTDIR)/usr/sbin - install -m 755 archbuild $(DESTDIR)/usr/bin - ln -sf archbuild $(DESTDIR)/usr/bin/extra-i686-build - ln -sf archbuild $(DESTDIR)/usr/bin/extra-x86_64-build - ln -sf archbuild $(DESTDIR)/usr/bin/testing-i686-build - ln -sf archbuild $(DESTDIR)/usr/bin/testing-x86_64-build - ln -sf archbuild $(DESTDIR)/usr/bin/staging-i686-build - ln -sf archbuild $(DESTDIR)/usr/bin/staging-x86_64-build - ln -sf archbuild $(DESTDIR)/usr/bin/multilib-build - ln -sf archbuild $(DESTDIR)/usr/bin/multilib-testing-build - # Additional packaging helper scripts - install -m 755 lddd $(DESTDIR)/usr/bin - install -m 755 finddeps $(DESTDIR)/usr/bin - install -m 755 rebuildpkgs $(DESTDIR)/usr/bin - # install default config - install -d -m755 $(DESTDIR)/usr/share/devtools - install -m 644 makepkg-i686.conf $(DESTDIR)/usr/share/devtools - install -m 644 makepkg-x86_64.conf $(DESTDIR)/usr/share/devtools - install -m 644 pacman-extra.conf $(DESTDIR)/usr/share/devtools - install -m 644 pacman-testing.conf $(DESTDIR)/usr/share/devtools - install -m 644 pacman-staging.conf $(DESTDIR)/usr/share/devtools - install -m 644 pacman-multilib.conf $(DESTDIR)/usr/share/devtools - install -m 644 pacman-multilib-testing.conf $(DESTDIR)/usr/share/devtools + install -dm0755 $(DESTDIR)/usr/bin + install -dm0755 $(DESTDIR)/usr/sbin + install -dm0755 $(DESTDIR)/usr/share/devtools + install -m0755 ${BINPROGS} $(DESTDIR)/usr/bin + install -m0755 ${SBINPROGS} $(DESTDIR)/usr/sbin + install -m0644 ${CONFIGFILES} $(DESTDIR)/usr/share/devtools + for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)/usr/bin/$$l; done + for l in ${ARCHBUILD_LINKS}; do ln -sf archbuild $(DESTDIR)/usr/bin/$$l; done uninstall: - # remove all files we installed - rm $(DESTDIR)/usr/bin/checkpkg - rm $(DESTDIR)/usr/bin/commitpkg - rm $(DESTDIR)/usr/bin/extrapkg - rm $(DESTDIR)/usr/bin/corepkg - rm $(DESTDIR)/usr/bin/testingpkg - rm $(DESTDIR)/usr/bin/stagingpkg - rm $(DESTDIR)/usr/bin/communitypkg - rm $(DESTDIR)/usr/bin/community-testingpkg - rm $(DESTDIR)/usr/bin/community-stagingpkg - rm $(DESTDIR)/usr/bin/multilibpkg - rm $(DESTDIR)/usr/bin/multilib-testingpkg - rm $(DESTDIR)/usr/sbin/mkarchroot - rm $(DESTDIR)/usr/sbin/makechrootpkg - rm $(DESTDIR)/usr/bin/extra-i686-build - rm $(DESTDIR)/usr/bin/extra-x86_64-build - rm $(DESTDIR)/usr/bin/testing-i686-build - rm $(DESTDIR)/usr/bin/testing-x86_64-build - rm $(DESTDIR)/usr/bin/staging-i686-build - rm $(DESTDIR)/usr/bin/staging-x86_64-build - rm $(DESTDIR)/usr/bin/multilib-build - rm $(DESTDIR)/usr/bin/multilib-testing-build - rm $(DESTDIR)/usr/bin/lddd - rm $(DESTDIR)/usr/bin/finddeps - rm $(DESTDIR)/usr/bin/archco - rm $(DESTDIR)/usr/bin/archrelease - rm $(DESTDIR)/usr/bin/archrm - rm $(DESTDIR)/usr/bin/communityco - rm $(DESTDIR)/usr/bin/rebuildpkgs - rm $(DESTDIR)/usr/share/devtools/makepkg-i686.conf - rm $(DESTDIR)/usr/share/devtools/makepkg-x86_64.conf - rm $(DESTDIR)/usr/share/devtools/pacman-extra.conf - rm $(DESTDIR)/usr/share/devtools/pacman-testing.conf - rm $(DESTDIR)/usr/share/devtools/pacman-staging.conf - rm $(DESTDIR)/usr/share/devtools/pacman-multilib.conf - rm $(DESTDIR)/usr/share/devtools/pacman-multilib-testing.conf + for f in ${BINPROGS}; do rm -f $(DESTDIR)/usr/bin/$$f; done + for f in ${SBINPROGS}; do rm -f $(DESTDIR)/usr/sbin/$$f; done + for f in ${CONFIGFILES}; do rm -f $(DESTDIR)/usr/share/devtools/$$f; done + for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)/usr/bin/$$l; done + for l in ${ARCHBUILD_LINKS}; do rm -f $(DESTDIR)/usr/bin/$$l; done dist: git archive --format=tar --prefix=devtools-$(V)/ $(V) | gzip -9 > devtools-$(V).tar.gz + +.PHONY: all install uninstall dist @@ -4,9 +4,9 @@ base_packages='base base-devel sudo' cmd="$(basename "${0%-build}")" if [ "${cmd%-*}" == 'multilib' ]; then - repo="${cmd}" - arch='x86_64' - base_packages+=' gcc-multilib libtool-multilib' + repo="${cmd}" + arch='x86_64' + base_packages+=' multilib-devel' else repo=${cmd%-*} arch=${cmd##*-} @@ -29,20 +29,39 @@ while getopts 'cr:' arg; do esac done +if [ "$EUID" != '0' ]; then + echo 'This script must be run as root.' + exit 1 +fi + if ${clean_first} || [ ! -d "${chroots}/${repo}-${arch}" ]; then echo "Creating chroot for [${repo}] (${arch})..." - sudo rm -rf ${chroots}/${repo}-${arch} - sudo mkdir -p ${chroots}/${repo}-${arch} - setarch ${arch} sudo mkarchroot \ + + for copy in ${chroots}/${repo}-${arch}/*; do + [[ -d $copy ]] || continue + echo "Deleting chroot copy '$(basename "${copy}")'..." + + # Lock the copy + exec 9>${copy}.lock + flock 9 + + { type -P btrfs && btrfs subvolume delete ${copy}; } &>/dev/null + rm -rf ${copy} + done + exec 9>&- + + rm -rf ${chroots}/${repo}-${arch} + mkdir -p ${chroots}/${repo}-${arch} + setarch ${arch} mkarchroot \ -C /usr/share/devtools/pacman-${repo}.conf \ -M /usr/share/devtools/makepkg-${arch}.conf \ ${chroots}/${repo}-${arch}/root \ ${base_packages} else - setarch ${arch} sudo mkarchroot \ + setarch ${arch} mkarchroot \ -u \ ${chroots}/${repo}-${arch}/root fi echo "Building in chroot for [${repo}] (${arch})..." -setarch ${arch} sudo makechrootpkg -c -r ${chroots}/${repo}-${arch} +setarch ${arch} makechrootpkg -c -r ${chroots}/${repo}-${arch} @@ -21,14 +21,14 @@ for d in $(find . -type d); do unset pkgname depends makedepends . PKGBUILD for dep in "${depends[@]}"; do - # lose the version comaparator, if any + # lose the version comparator, if any depname=${dep%%[<>=]*} if [ "$depname" = "$match" ]; then echo "$d (depends)" fi done for dep in "${makedepends[@]}"; do - # lose the version comaparator, if any + # lose the version comparator, if any depname=${dep%%[<>=]*} if [ "$depname" = "$match" ]; then echo "$d (makedepends)" diff --git a/makechrootpkg b/makechrootpkg index 9cd2841..2a9f56b 100755 --- a/makechrootpkg +++ b/makechrootpkg @@ -12,7 +12,6 @@ FORCE='n' RUN='' MAKEPKG_ARGS='-s --noconfirm' REPACK='' -COPY='copy' WORKDIR=$PWD update_first='0' @@ -24,6 +23,10 @@ chrootdir='' APPNAME=$(basename "${0}") +default_copy=$USER +[[ -n $SUDO_USER ]] && default_copy=$SUDO_USER +[[ -z $default_copy || $default_copy = root ]] && default_copy=copy + usage() { echo "usage ${APPNAME} [options] -r <chrootdir> [--] [makepkg args]" echo ' Run this script in a PKGBUILD dir to build a package inside a' @@ -50,7 +53,8 @@ usage() { echo '-r <dir> The chroot dir to use' echo '-I <pkg> Install a package into the working copy of the chroot' echo '-l <copy> The directory to use as the working copy of the chroot' - echo ' Useful for maintain multiple copies Default: copy' + echo ' Useful for maintaining multiple copies.' + echo " Default: $default_copy" exit 1 } @@ -62,14 +66,16 @@ while getopts 'hcudr:I:l:' arg; do d) add_to_db=1 ;; r) chrootdir="$OPTARG" ;; I) install_pkg="$OPTARG" ;; - l) COPY="$OPTARG" ;; + l) copy="$OPTARG" ;; *) MAKEPKG_ARGS="$MAKEPKG_ARGS -$arg $OPTARG" ;; esac done -#Get rid of trailing / in chrootdir -[ "$chrootdir" != "/" ] && chrootdir=$(echo $chrootdir | sed 's#/$##') -copydir="$chrootdir/$COPY" +# Canonicalize chrootdir, getting rid of trailing / +chrootdir=$(readlink -e "$chrootdir") + +[[ -z $copy ]] && copy=$default_copy +copydir="$chrootdir/$copy" # Pass all arguments after -- right to makepkg MAKEPKG_ARGS="$MAKEPKG_ARGS ${*:$OPTIND}" @@ -104,11 +110,44 @@ if [ ! -d "$chrootdir/root" ]; then fi umask 0022 + +# 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 + echo -n "locking chroot copy '$copy'..." + flock 9 + echo "done" +fi + if [ ! -d "$copydir" -o "$clean_first" -eq "1" ]; 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 + echo -n "locking clean chroot..." + flock -s 8 + echo "done" + fi + echo -n 'creating clean working copy...' - mkdir -p "$copydir" - rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir" + use_rsync=false + if type -P btrfs >/dev/null; then + [ -d $copydir ] && btrfs subvolume delete "$copydir" &>/dev/null + btrfs subvolume snapshot "$chrootdir/root" "$copydir" &>/dev/null || use_rsync=true + else + use_rsync=true + fi + + if $use_rsync; then + mkdir -p "$copydir" + rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir" + fi echo 'done' + + # Drop the read lock again + exec 8>&- fi if [ -n "$install_pkg" ]; then @@ -160,9 +199,15 @@ if ! grep 'SRCDEST="/srcdest"' "$copydir/etc/makepkg.conf" >/dev/null 2>&1; then echo 'SRCDEST="/srcdest"' >> "$copydir/etc/makepkg.conf" fi [ -z "${MAKEFLAGS}" ] && eval $(grep '^MAKEFLAGS=' /etc/makepkg.conf) -[ -n "${MAKEFLAGS}" ] && echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" +if [ -n "${MAKEFLAGS}" ]; then + sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf" + echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" +fi [ -z "${PACKAGER}" ] && eval $(grep '^PACKAGER=' /etc/makepkg.conf) -[ -n "${PACKAGER}" ] && echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf" +if [ -n "${PACKAGER}" ]; then + sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf" + echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf" +fi # Set target CARCH as it might be used within the PKGBUILD to select correct sources eval $(grep '^CARCH=' "$copydir/etc/makepkg.conf") @@ -26,7 +26,7 @@ usage() { 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. Default: /var/cache/pacman/pkg" + echo ' -c <dir> Set pacman cache. Default: /var/cache/pacman/pkg' echo ' -h This message' exit $1 } @@ -68,7 +68,7 @@ shift 1 if [ -z "$cache_dir" ]; then cache_conf=${working_dir}/etc/pacman.conf [ ! -f $cache_conf ] && cache_conf=${pac_conf:-/etc/pacman.conf} - cache_dir=$((grep -m 1 '^CacheDir' $cache_conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir\s*=\s*//') + cache_dir=$( (grep -m 1 '^CacheDir' $cache_conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir\s*=\s*//') unset cache_conf fi @@ -82,8 +82,7 @@ if echo "${host_mirror}" | grep -q 'file://'; then host_mirror_path=$(echo "${host_mirror}" | sed -E 's#file://(/.*)/\$repo/os/\$arch#\1#g') fi -# {{{ functions - +# {{{ functions chroot_mount() { [ -e "${working_dir}/sys" ] || mkdir "${working_dir}/sys" mount -t sysfs sysfs "${working_dir}/sys" @@ -142,6 +141,20 @@ chroot_umount () { umount "${working_dir}/${cache_dir}" [ -n "${host_mirror_path}" ] && umount "${working_dir}/${host_mirror_path}" } + +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 + echo -n "locking chroot..." + flock 9 + echo "done" + fi +} # }}} umask 0022 @@ -154,22 +167,28 @@ if [ "$RUN" != "" ]; then exit 1 fi + chroot_lock chroot_mount copy_hostconf eval chroot "${working_dir}" ${RUN} # }}} - else +else # {{{ build chroot if [ -e "${working_dir}" -a "${FORCE}" = "n" ]; then echo "error: working dir '${working_dir}' already exists - try using -f" exit 1 fi + if { type -P btrfs && btrfs subvolume create "${working_dir}"; } &>/dev/null; then + chmod 0755 "${working_dir}" + fi + mkdir -p "${working_dir}/var/lib/pacman/sync" mkdir -p "${working_dir}/etc/" + chroot_lock chroot_mount pacargs="--noconfirm --root=${working_dir} --cachedir=${cache_dir}" |