From 46c4def0733a78ce08702d188e3e1a141fb07316 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Mon, 29 Aug 2011 10:53:50 +0200 Subject: Support non-standard install locations This build system overhaul allows for adding (define-style) macros to our scripts. All source files are now suffixed with ".in" to clarify that they might contain unprocessed defines. The Makefile provides a new rule to preprocess source files and generate proper output scripts. Also, add a "@pkgdatadir@" define (as used in GNU Autotools) and use it instead of hardcoded paths to "/usr/share/devtools" everywhere. We missed this when adding PREFIX support to the build system in commit 35fc83ce7d8dc26cd424321f2e8638d05da0a6d4. Signed-off-by: Lukas Fleischer --- .gitignore | 13 +++ Makefile | 8 +- archbuild | 68 ------------ archbuild.in | 68 ++++++++++++ archco | 23 ---- archco.in | 23 ++++ archrelease | 67 ------------ archrelease.in | 67 ++++++++++++ archrm | 13 --- archrm.in | 13 +++ bash_completion | 69 ------------ bash_completion.in | 69 ++++++++++++ checkpkg | 90 ---------------- checkpkg.in | 90 ++++++++++++++++ commitpkg | 207 ------------------------------------ commitpkg.in | 207 ++++++++++++++++++++++++++++++++++++ finddeps | 46 -------- finddeps.in | 46 ++++++++ lddd | 46 -------- lddd.in | 46 ++++++++ makechrootpkg | 305 ----------------------------------------------------- makechrootpkg.in | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mkarchroot | 231 ---------------------------------------- mkarchroot.in | 231 ++++++++++++++++++++++++++++++++++++++++ rebuildpkgs | 101 ------------------ rebuildpkgs.in | 101 ++++++++++++++++++ zsh_completion | 81 -------------- zsh_completion.in | 81 ++++++++++++++ 28 files changed, 1367 insertions(+), 1348 deletions(-) delete mode 100755 archbuild create mode 100644 archbuild.in delete mode 100755 archco create mode 100644 archco.in delete mode 100755 archrelease create mode 100644 archrelease.in delete mode 100755 archrm create mode 100644 archrm.in delete mode 100644 bash_completion create mode 100644 bash_completion.in delete mode 100755 checkpkg create mode 100644 checkpkg.in delete mode 100755 commitpkg create mode 100644 commitpkg.in delete mode 100755 finddeps create mode 100644 finddeps.in delete mode 100755 lddd create mode 100644 lddd.in delete mode 100755 makechrootpkg create mode 100644 makechrootpkg.in delete mode 100755 mkarchroot create mode 100644 mkarchroot.in delete mode 100755 rebuildpkgs create mode 100644 rebuildpkgs.in delete mode 100644 zsh_completion create mode 100644 zsh_completion.in diff --git a/.gitignore b/.gitignore index d823845..cd39b63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,15 @@ *~ devtools-*.tar.gz +archbuild +archco +archrelease +archrm +bash_completion +checkpkg +commitpkg +finddeps +lddd +makechrootpkg +mkarchroot +rebuildpkgs +zsh_completion diff --git a/Makefile b/Makefile index 6f7a238..47378ff 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,13 @@ ARCHBUILD_LINKS = \ multilib-build \ multilib-testing-build -all: +all: $(BINPROGS) $(SBINPROGS) bash_completion zsh_completion + +%: %.in + @echo "GEN $@" + @sed -e "s|@pkgdatadir[@]|$(DESTDIR)$(PREFIX)/share/devtools|g" "$<" >"$@" + @chmod a-w "$@" + @chmod +x "$@" install: install -dm0755 $(DESTDIR)$(PREFIX)/bin diff --git a/archbuild b/archbuild deleted file mode 100755 index 5518996..0000000 --- a/archbuild +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -base_packages=(base base-devel sudo) - -cmd="${0##*/}" -if [[ "${cmd%%-*}" == 'multilib' ]]; then - repo="${cmd%-build}" - arch='x86_64' - base_packages+=(multilib-devel) -else - tag="${cmd%-build}" - repo=${tag%-*} - arch=${tag##*-} -fi -chroots='/var/tmp/archbuild' -clean_first=false - -usage() { - echo "usage $cmd" - echo ' -c Recreate the chroot before building' - echo ' -r Create chroots in this directory' - exit 1 -} - -while getopts 'cr:' arg; do - case "${arg}" in - c) clean_first=true ;; - r) chroots="$OPTARG" ;; - *) usage ;; - 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})..." - - 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} mkarchroot \ - -u \ - "${chroots}/${repo}-${arch}/root" -fi - -echo "Building in chroot for [${repo}] (${arch})..." -setarch "${arch}" makechrootpkg -c -r "${chroots}/${repo}-${arch}" diff --git a/archbuild.in b/archbuild.in new file mode 100644 index 0000000..92d2554 --- /dev/null +++ b/archbuild.in @@ -0,0 +1,68 @@ +#!/bin/bash + +base_packages=(base base-devel sudo) + +cmd="${0##*/}" +if [[ "${cmd%%-*}" == 'multilib' ]]; then + repo="${cmd%-build}" + arch='x86_64' + base_packages+=(multilib-devel) +else + tag="${cmd%-build}" + repo=${tag%-*} + arch=${tag##*-} +fi +chroots='/var/tmp/archbuild' +clean_first=false + +usage() { + echo "usage $cmd" + echo ' -c Recreate the chroot before building' + echo ' -r Create chroots in this directory' + exit 1 +} + +while getopts 'cr:' arg; do + case "${arg}" in + c) clean_first=true ;; + r) chroots="$OPTARG" ;; + *) usage ;; + 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})..." + + 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 "@pkgdatadir@/pacman-${repo}.conf" \ + -M "@pkgdatadir@/makepkg-${arch}.conf" \ + "${chroots}/${repo}-${arch}/root" \ + "${base_packages[@]}" +else + setarch ${arch} mkarchroot \ + -u \ + "${chroots}/${repo}-${arch}/root" +fi + +echo "Building in chroot for [${repo}] (${arch})..." +setarch "${arch}" makechrootpkg -c -r "${chroots}/${repo}-${arch}" diff --git a/archco b/archco deleted file mode 100755 index 31134f4..0000000 --- a/archco +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -scriptname=${0##*/} - -if [ "$1" = '' ]; then - echo 'Usage: '$scriptname' ...' - exit 1 -fi - -case $scriptname in - archco) - SVNURL="svn+ssh://gerolde.archlinux.org/srv/svn-packages";; - communityco) - SVNURL="svn+ssh://aur.archlinux.org/srv/svn-packages";; - *) - echo "error: couldn't find svn url for $scriptname" - exit 1 - ;; -esac - -for i in "$@"; do - svn co "$SVNURL/$i" -done diff --git a/archco.in b/archco.in new file mode 100644 index 0000000..31134f4 --- /dev/null +++ b/archco.in @@ -0,0 +1,23 @@ +#!/bin/bash + +scriptname=${0##*/} + +if [ "$1" = '' ]; then + echo 'Usage: '$scriptname' ...' + exit 1 +fi + +case $scriptname in + archco) + SVNURL="svn+ssh://gerolde.archlinux.org/srv/svn-packages";; + communityco) + SVNURL="svn+ssh://aur.archlinux.org/srv/svn-packages";; + *) + echo "error: couldn't find svn url for $scriptname" + exit 1 + ;; +esac + +for i in "$@"; do + svn co "$SVNURL/$i" +done diff --git a/archrelease b/archrelease deleted file mode 100755 index 2f6a563..0000000 --- a/archrelease +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -abort() { - echo ${1:-'archrelease: Cancelled'} - exit 1 -} - -if [[ -z $1 ]]; then - abort 'Usage: archrelease ...' -fi - -# TODO: validate repo is really repo-arch - -if [[ ! -f PKGBUILD ]]; then - abort 'archrelease: PKGBUILD not found' -fi - -trunk=${PWD##*/} - -# Normally this should be trunk, but it may be something -# such as 'gnome-unstable' -IFS='/' read -r -d '' -a parts <<< "$PWD" -if [[ "${parts[@]:(-2):1}" == "repos" ]]; then - abort 'archrelease: Should not be in repos dir (try from trunk/)' -fi -unset parts - -if [[ $(svn status -q) ]]; then - abort 'archrelease: You have not committed your changes yet!' -fi - -pushd .. >/dev/null -IFS=$'\n' read -r -d '' -a known_files < <(svn ls -r HEAD "$trunk") -for file in "${known_files[@]}"; do - if [[ ${file:(-1)} = '/' ]]; then - abort "archrelease: subdirectories are not supported in package directories!" - fi -done - -for tag in "$@"; do - echo -n "copying ${trunk} to ${tag}..." - - if [[ -d repos/$tag ]]; then - declare -a trash - trash=() - while read -r file; do - trash+=("repos/$tag/$file") - done < <(svn ls "repos/$tag") - svn rm -q "${trash[@]}" - else - mkdir -p "repos/$tag" - svn add --parents -q "repos/$tag" - fi - - for file in "${known_files[@]}"; do - svn copy -q -r HEAD "$trunk/$file" "repos/$tag/" - done - - echo 'done' -done - -echo -n "releasing package..." -printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" -svn commit -q -m "archrelease: copy ${trunk} to $tag_list" || abort -echo 'done' - -popd >/dev/null diff --git a/archrelease.in b/archrelease.in new file mode 100644 index 0000000..2f6a563 --- /dev/null +++ b/archrelease.in @@ -0,0 +1,67 @@ +#!/bin/bash + +abort() { + echo ${1:-'archrelease: Cancelled'} + exit 1 +} + +if [[ -z $1 ]]; then + abort 'Usage: archrelease ...' +fi + +# TODO: validate repo is really repo-arch + +if [[ ! -f PKGBUILD ]]; then + abort 'archrelease: PKGBUILD not found' +fi + +trunk=${PWD##*/} + +# Normally this should be trunk, but it may be something +# such as 'gnome-unstable' +IFS='/' read -r -d '' -a parts <<< "$PWD" +if [[ "${parts[@]:(-2):1}" == "repos" ]]; then + abort 'archrelease: Should not be in repos dir (try from trunk/)' +fi +unset parts + +if [[ $(svn status -q) ]]; then + abort 'archrelease: You have not committed your changes yet!' +fi + +pushd .. >/dev/null +IFS=$'\n' read -r -d '' -a known_files < <(svn ls -r HEAD "$trunk") +for file in "${known_files[@]}"; do + if [[ ${file:(-1)} = '/' ]]; then + abort "archrelease: subdirectories are not supported in package directories!" + fi +done + +for tag in "$@"; do + echo -n "copying ${trunk} to ${tag}..." + + if [[ -d repos/$tag ]]; then + declare -a trash + trash=() + while read -r file; do + trash+=("repos/$tag/$file") + done < <(svn ls "repos/$tag") + svn rm -q "${trash[@]}" + else + mkdir -p "repos/$tag" + svn add --parents -q "repos/$tag" + fi + + for file in "${known_files[@]}"; do + svn copy -q -r HEAD "$trunk/$file" "repos/$tag/" + done + + echo 'done' +done + +echo -n "releasing package..." +printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" +svn commit -q -m "archrelease: copy ${trunk} to $tag_list" || abort +echo 'done' + +popd >/dev/null diff --git a/archrm b/archrm deleted file mode 100755 index 4a683f6..0000000 --- a/archrm +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [ "$1" = '' ]; then - echo 'Usage: archrm ' - exit 1 -fi - -# FIXME: Check if there are uncommited changes -#pushd $1 -# -#popd - -rm -rf $1 diff --git a/archrm.in b/archrm.in new file mode 100644 index 0000000..4a683f6 --- /dev/null +++ b/archrm.in @@ -0,0 +1,13 @@ +#!/bin/bash + +if [ "$1" = '' ]; then + echo 'Usage: archrm ' + exit 1 +fi + +# FIXME: Check if there are uncommited changes +#pushd $1 +# +#popd + +rm -rf $1 diff --git a/bash_completion b/bash_completion deleted file mode 100644 index cd959fc..0000000 --- a/bash_completion +++ /dev/null @@ -1,69 +0,0 @@ -_devtools_compgen() { - local i r - COMPREPLY=($(compgen -W '$*' -- "$cur")) - for ((i=1; i < ${#COMP_WORDS[@]}-1; i++)); do - for r in ${!COMPREPLY[@]}; do - if [[ ${COMP_WORDS[i]} = ${COMPREPLY[r]} ]]; then - unset 'COMPREPLY[r]'; break - fi - done - done -} - -_archco_pkg() { - _devtools_compgen "$( - \pacman -$1 - )" -} - -_archco() { - local cur prev - COMPREPLY=() - cur=$(_get_cword) - prev=${COMP_WORDS[COMP_CWORD-1]} - - _archco_pkg Slq - true -} && -complete -F _archco archco communityco - -_makechrootpkg() { - local cur - COMPREPLY=() - _get_comp_words_by_ref cur - - case $cur in - -*) - COMPREPLY=( $( compgen -W '-I -c -d -h -l -r -u' -- "$cur" ) ) - ;; - *) - _filedir - return 0 - ;; - esac - - true -} && -complete -F _makechrootpkg makechrootpkg - -_mkarchroot() { - local cur - COMPREPLY=() - _get_comp_words_by_ref cur - - case $cur in - -*) - COMPREPLY=( $( compgen -W '-C -M -c -f -h -n -r -u' -- "$cur" ) ) - ;; - *) - _filedir - return 0 - ;; - esac - - true -} && -complete -F _mkarchroot mkarchroot - - -# ex:et ts=2 sw=2 ft=sh diff --git a/bash_completion.in b/bash_completion.in new file mode 100644 index 0000000..cd959fc --- /dev/null +++ b/bash_completion.in @@ -0,0 +1,69 @@ +_devtools_compgen() { + local i r + COMPREPLY=($(compgen -W '$*' -- "$cur")) + for ((i=1; i < ${#COMP_WORDS[@]}-1; i++)); do + for r in ${!COMPREPLY[@]}; do + if [[ ${COMP_WORDS[i]} = ${COMPREPLY[r]} ]]; then + unset 'COMPREPLY[r]'; break + fi + done + done +} + +_archco_pkg() { + _devtools_compgen "$( + \pacman -$1 + )" +} + +_archco() { + local cur prev + COMPREPLY=() + cur=$(_get_cword) + prev=${COMP_WORDS[COMP_CWORD-1]} + + _archco_pkg Slq + true +} && +complete -F _archco archco communityco + +_makechrootpkg() { + local cur + COMPREPLY=() + _get_comp_words_by_ref cur + + case $cur in + -*) + COMPREPLY=( $( compgen -W '-I -c -d -h -l -r -u' -- "$cur" ) ) + ;; + *) + _filedir + return 0 + ;; + esac + + true +} && +complete -F _makechrootpkg makechrootpkg + +_mkarchroot() { + local cur + COMPREPLY=() + _get_comp_words_by_ref cur + + case $cur in + -*) + COMPREPLY=( $( compgen -W '-C -M -c -f -h -n -r -u' -- "$cur" ) ) + ;; + *) + _filedir + return 0 + ;; + esac + + true +} && +complete -F _mkarchroot mkarchroot + + +# ex:et ts=2 sw=2 ft=sh diff --git a/checkpkg b/checkpkg deleted file mode 100755 index 94a7529..0000000 --- a/checkpkg +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -# Source makepkg.conf; fail if it is not found -if [[ -r '/etc/makepkg.conf' ]]; then - source '/etc/makepkg.conf' -else - echo '/etc/makepkg.conf not found!' - exit 1 -fi - -# Source user-specific makepkg.conf overrides -if [[ -r ~/.makepkg.conf ]]; then - source ~/.makepkg.conf -fi - -if [[ ! -f PKGBUILD ]]; then - echo 'This must be run in the directory of a built package.' - exit 1 -fi - -. PKGBUILD -if [[ $arch == 'any' ]]; then - CARCH='any' -fi - -STARTDIR=$(pwd) -TEMPDIR=$(mktemp -d /tmp/checkpkg-script.XXXX) -cd "$TEMPDIR" - -for _pkgname in "${pkgname[@]}"; do - if [[ -z ${epoch} ]] ; then - pkgfile=${_pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} - else - pkgfile=${_pkgname}-${epoch}:${pkgver}-${pkgrel}-${CARCH}${PKGEXT} - fi - - if [[ -f "$STARTDIR/$pkgfile" ]]; then - ln -s "$STARTDIR/$pkgfile" "$pkgfile" - elif [[ -f "$PKGDEST/$pkgfile" ]]; then - ln -s "$PKGDEST/$pkgfile" "$pkgfile" - else - echo "File \"$pkgfile\" doesn't exist" - exit 1 - fi - - pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname") - - if [[ $? -ne 0 ]]; then - echo "Couldn't download previous package for $_pkgname." - exit 1 - fi - - oldpkg=${pkgurl##*://*/} - - if [[ ${oldpkg##*/} = ${pkgfile##*/} ]]; then - echo "The built package ($_pkgname) is the one in the repo right now!" - exit 1 - fi - - if [[ ! -f $oldpkg ]]; then - if [[ $pkgurl = file://* ]]; then - ln -s "${pkgurl#file://}" "${pkgurl##file://*/}" - elif [[ -f "$PKGDEST/$oldpkg" ]]; then - ln -s "$PKGDEST/$oldpkg" "$oldpkg" - elif [[ -f "$STARTDIR/$oldpkg" ]]; then - ln -s "$STARTDIR/$oldpkg" "$oldpkg" - else - wget --quiet "$pkgurl" - fi - fi - - bsdtar tf "$oldpkg" | sort > "filelist-$_pkgname-old" - bsdtar tf "$pkgfile" | sort > "filelist-$_pkgname" - - sdiff -s "filelist-$_pkgname-old" "filelist-$_pkgname" - - if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then - mkdir -p pkg - cd pkg - bsdtar xf ../"$pkgfile" > /dev/null - diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do - echo "${i}: " "$(objdump -p "$i" | grep SONAME)" - done - cd .. - else - echo "No soname differences for $_pkgname." - fi -done - -echo "Files saved to $TEMPDIR" diff --git a/checkpkg.in b/checkpkg.in new file mode 100644 index 0000000..94a7529 --- /dev/null +++ b/checkpkg.in @@ -0,0 +1,90 @@ +#!/bin/bash + +# Source makepkg.conf; fail if it is not found +if [[ -r '/etc/makepkg.conf' ]]; then + source '/etc/makepkg.conf' +else + echo '/etc/makepkg.conf not found!' + exit 1 +fi + +# Source user-specific makepkg.conf overrides +if [[ -r ~/.makepkg.conf ]]; then + source ~/.makepkg.conf +fi + +if [[ ! -f PKGBUILD ]]; then + echo 'This must be run in the directory of a built package.' + exit 1 +fi + +. PKGBUILD +if [[ $arch == 'any' ]]; then + CARCH='any' +fi + +STARTDIR=$(pwd) +TEMPDIR=$(mktemp -d /tmp/checkpkg-script.XXXX) +cd "$TEMPDIR" + +for _pkgname in "${pkgname[@]}"; do + if [[ -z ${epoch} ]] ; then + pkgfile=${_pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} + else + pkgfile=${_pkgname}-${epoch}:${pkgver}-${pkgrel}-${CARCH}${PKGEXT} + fi + + if [[ -f "$STARTDIR/$pkgfile" ]]; then + ln -s "$STARTDIR/$pkgfile" "$pkgfile" + elif [[ -f "$PKGDEST/$pkgfile" ]]; then + ln -s "$PKGDEST/$pkgfile" "$pkgfile" + else + echo "File \"$pkgfile\" doesn't exist" + exit 1 + fi + + pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname") + + if [[ $? -ne 0 ]]; then + echo "Couldn't download previous package for $_pkgname." + exit 1 + fi + + oldpkg=${pkgurl##*://*/} + + if [[ ${oldpkg##*/} = ${pkgfile##*/} ]]; then + echo "The built package ($_pkgname) is the one in the repo right now!" + exit 1 + fi + + if [[ ! -f $oldpkg ]]; then + if [[ $pkgurl = file://* ]]; then + ln -s "${pkgurl#file://}" "${pkgurl##file://*/}" + elif [[ -f "$PKGDEST/$oldpkg" ]]; then + ln -s "$PKGDEST/$oldpkg" "$oldpkg" + elif [[ -f "$STARTDIR/$oldpkg" ]]; then + ln -s "$STARTDIR/$oldpkg" "$oldpkg" + else + wget --quiet "$pkgurl" + fi + fi + + bsdtar tf "$oldpkg" | sort > "filelist-$_pkgname-old" + bsdtar tf "$pkgfile" | sort > "filelist-$_pkgname" + + sdiff -s "filelist-$_pkgname-old" "filelist-$_pkgname" + + if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then + mkdir -p pkg + cd pkg + bsdtar xf ../"$pkgfile" > /dev/null + diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do + echo "${i}: " "$(objdump -p "$i" | grep SONAME)" + done + cd .. + else + echo "No soname differences for $_pkgname." + fi +done + +echo "Files saved to $TEMPDIR" diff --git a/commitpkg b/commitpkg deleted file mode 100755 index 2a732b5..0000000 --- a/commitpkg +++ /dev/null @@ -1,207 +0,0 @@ -#!/bin/bash - -abort() { - echo ${1:-'Cancelled'} - exit 1 -} - -getpkgfile() { - if [[ ${#} -ne 1 ]]; then - echo 'ERROR: No canonical package found!' >&2 - exit 1 - elif [ ! -f "${1}" ]; then - echo "ERROR: Package ${1} not found!" >&2 - exit 1 - fi - - echo ${1} -} - -## -# usage : get_full_version( $epoch, $pkgver, $pkgrel ) -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -## -get_full_version() { - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi -} - -# Source makepkg.conf; fail if it is not found -if [ -r '/etc/makepkg.conf' ]; then - source '/etc/makepkg.conf' -else - abort '/etc/makepkg.conf not found!' -fi - -# Source user-specific makepkg.conf overrides -if [ -r ~/.makepkg.conf ]; then - . ~/.makepkg.conf -fi - -cmd=${0##*/} - -if [ ! -f PKGBUILD ]; then - abort 'No PKGBUILD file' -fi - -. PKGBUILD -pkgbase=${pkgbase:-$pkgname} - -case "$cmd" in - commitpkg) - if [ $# -eq 0 ]; then - abort 'usage: commitpkg [-l limit] [-a arch] [commit message]' - fi - repo="$1" - shift - ;; - *pkg) - repo="${cmd%pkg}" - ;; - *) - abort 'usage: commitpkg [-l limit] [-a arch] [commit message]' - ;; -esac - -case "$repo" in - core|extra|testing|staging) - server='gerolde.archlinux.org' ;; - community*|multilib*) - server='aur.archlinux.org' ;; - *) - server='gerolde.archlinux.org' - echo "Non-standard repository $repo in use, defaulting to server $server" ;; -esac - -# check if all local source files are under version control -for s in "${source[@]}"; do - if [[ $s != *://* ]] && ! svn status -v "$s" | grep -q '^[ AMRX~]'; then - abort "$s is not under version control" - fi -done - -# check if changelog and install files are under version control -for i in 'changelog' 'install'; do - filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) - for file in $filelist; do - # evaluate any bash variables used - eval file=${file} - if ! svn status -v "${file}" | grep -q '^[ AMRX~]'; then - abort "${file} is not under version control" - fi - done -done - -# see if any limit options were passed, we'll send them to rsync -rsyncopts=(-e ssh -p --chmod=ug=rw,o=r -c -h -L --progress --partial -y) -while getopts ':l:a:' flag; do - case $flag in - l) rsyncopts+=("--bwlimit=$2") ;; - a) commit_arch=$2 ;; - :) echo "option requires an argument -- '$OPTARG'" >&2 - exit 1 ;; - \?) echo "invalid option -- '$OPTARG'" >&2 - exit 1 ;; - esac -done -shift $(( OPTIND - 1 )) - -if [ -n "$(svn status -q)" ]; then - echo -n 'committing changes to trunk...' - msgtemplate="upgpkg: $pkgbase $(get_full_version ${epoch:-0} $pkgver $pkgrel)"$'\n\n' - if [ -n "$1" ]; then - svn commit -q -m "${msgtemplate}${1}" || abort - else - msgfile="$(mktemp)" - echo "$msgtemplate" > "$msgfile" - if [ -n "$SVN_EDITOR" ]; then - $SVN_EDITOR "$msgfile" - elif [ -n "$VISUAL" ]; then - $VISUAL "$msgfile" - elif [ -n "$EDITOR" ]; then - $EDITOR "$msgfile" - else - vi "$msgfile" - fi - [ -s "$msgfile" ] || abort - svn commit -q -F "$msgfile" || abort - unlink "$msgfile" - fi - echo 'done' -fi - -declare -a uploads - -for _arch in ${arch[@]}; do - if [ -n "$commit_arch" ] && [ "${_arch}" != "$commit_arch" ]; then - echo "skipping ${_arch}" - continue - fi - - for _pkgname in ${pkgname[@]}; do - fullver=$(get_full_version ${epoch:-0} $pkgver $pkgrel) - pkgfile=$(getpkgfile "$_pkgname-$fullver-${_arch}".pkg.tar.?z 2>/dev/null) - pkgdestfile=$(getpkgfile "$PKGDEST/$_pkgname-$fullver-${_arch}".pkg.tar.?z 2>/dev/null) - - if [ -f "$pkgfile" ]; then - pkgfile="./$pkgfile" - elif [ -f "$pkgdestfile" ]; then - pkgfile="$pkgdestfile" - else - echo "skipping ${_arch}" - continue 2 - fi - uploads+=("$pkgfile") - - if [[ $SIGNPKG == 'y' ]]; then - echo "Signing package ${pkgfile}..." - if [[ -n $GPGKEY ]]; then - SIGNWITHKEY="-u ${GPGKEY}" - fi - gpg --detach-sign --use-agent ${SIGNWITHKEY} "${pkgfile}" || abort - fi - - sigfile="${pkgfile}.sig" - if [ -f "${sigfile}" ]; then - uploads+=("$sigfile") - elif [[ $SIGNPKG == 'y' ]]; then - abort "Signature ${pkgfile}.sig was not found" - fi - done -done - -if [[ -n $commit_arch ]]; then - archrelease "$repo-$commit_arch" || abort -else - archrelease "${arch[@]/#/$repo-}" || abort -fi - -if [[ ${#uploads[*]} -gt 0 ]]; then - echo 'uploading all package and signature files' - rsync "${rsyncopts[@]}" "${uploads[@]}" "$server:staging/$repo/" || abort -fi - -if [ "${arch[*]}" == 'any' ]; then - if [ -d ../repos/$repo-i686 -a -d ../repos/$repo-x86_64 ]; then - pushd ../repos/ >/dev/null - echo "removing $repo-i686 and $repo-x86_64..." - svn rm $repo-i686 - svn rm $repo-x86_64 - svn commit -q -m "removed $repo-i686 and $repo-x86_64 for $pkgname" - echo 'done' - popd >/dev/null - fi -else - if [ -d ../repos/$repo-any ]; then - pushd ../repos/ >/dev/null - echo "removing $repo-any..." - svn rm $repo-any - svn commit -q -m "removed $repo-any for $pkgname" - echo 'done' - popd >/dev/null - fi -fi diff --git a/commitpkg.in b/commitpkg.in new file mode 100644 index 0000000..2a732b5 --- /dev/null +++ b/commitpkg.in @@ -0,0 +1,207 @@ +#!/bin/bash + +abort() { + echo ${1:-'Cancelled'} + exit 1 +} + +getpkgfile() { + if [[ ${#} -ne 1 ]]; then + echo 'ERROR: No canonical package found!' >&2 + exit 1 + elif [ ! -f "${1}" ]; then + echo "ERROR: Package ${1} not found!" >&2 + exit 1 + fi + + echo ${1} +} + +## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## +get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi +} + +# Source makepkg.conf; fail if it is not found +if [ -r '/etc/makepkg.conf' ]; then + source '/etc/makepkg.conf' +else + abort '/etc/makepkg.conf not found!' +fi + +# Source user-specific makepkg.conf overrides +if [ -r ~/.makepkg.conf ]; then + . ~/.makepkg.conf +fi + +cmd=${0##*/} + +if [ ! -f PKGBUILD ]; then + abort 'No PKGBUILD file' +fi + +. PKGBUILD +pkgbase=${pkgbase:-$pkgname} + +case "$cmd" in + commitpkg) + if [ $# -eq 0 ]; then + abort 'usage: commitpkg [-l limit] [-a arch] [commit message]' + fi + repo="$1" + shift + ;; + *pkg) + repo="${cmd%pkg}" + ;; + *) + abort 'usage: commitpkg [-l limit] [-a arch] [commit message]' + ;; +esac + +case "$repo" in + core|extra|testing|staging) + server='gerolde.archlinux.org' ;; + community*|multilib*) + server='aur.archlinux.org' ;; + *) + server='gerolde.archlinux.org' + echo "Non-standard repository $repo in use, defaulting to server $server" ;; +esac + +# check if all local source files are under version control +for s in "${source[@]}"; do + if [[ $s != *://* ]] && ! svn status -v "$s" | grep -q '^[ AMRX~]'; then + abort "$s is not under version control" + fi +done + +# check if changelog and install files are under version control +for i in 'changelog' 'install'; do + filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) + for file in $filelist; do + # evaluate any bash variables used + eval file=${file} + if ! svn status -v "${file}" | grep -q '^[ AMRX~]'; then + abort "${file} is not under version control" + fi + done +done + +# see if any limit options were passed, we'll send them to rsync +rsyncopts=(-e ssh -p --chmod=ug=rw,o=r -c -h -L --progress --partial -y) +while getopts ':l:a:' flag; do + case $flag in + l) rsyncopts+=("--bwlimit=$2") ;; + a) commit_arch=$2 ;; + :) echo "option requires an argument -- '$OPTARG'" >&2 + exit 1 ;; + \?) echo "invalid option -- '$OPTARG'" >&2 + exit 1 ;; + esac +done +shift $(( OPTIND - 1 )) + +if [ -n "$(svn status -q)" ]; then + echo -n 'committing changes to trunk...' + msgtemplate="upgpkg: $pkgbase $(get_full_version ${epoch:-0} $pkgver $pkgrel)"$'\n\n' + if [ -n "$1" ]; then + svn commit -q -m "${msgtemplate}${1}" || abort + else + msgfile="$(mktemp)" + echo "$msgtemplate" > "$msgfile" + if [ -n "$SVN_EDITOR" ]; then + $SVN_EDITOR "$msgfile" + elif [ -n "$VISUAL" ]; then + $VISUAL "$msgfile" + elif [ -n "$EDITOR" ]; then + $EDITOR "$msgfile" + else + vi "$msgfile" + fi + [ -s "$msgfile" ] || abort + svn commit -q -F "$msgfile" || abort + unlink "$msgfile" + fi + echo 'done' +fi + +declare -a uploads + +for _arch in ${arch[@]}; do + if [ -n "$commit_arch" ] && [ "${_arch}" != "$commit_arch" ]; then + echo "skipping ${_arch}" + continue + fi + + for _pkgname in ${pkgname[@]}; do + fullver=$(get_full_version ${epoch:-0} $pkgver $pkgrel) + pkgfile=$(getpkgfile "$_pkgname-$fullver-${_arch}".pkg.tar.?z 2>/dev/null) + pkgdestfile=$(getpkgfile "$PKGDEST/$_pkgname-$fullver-${_arch}".pkg.tar.?z 2>/dev/null) + + if [ -f "$pkgfile" ]; then + pkgfile="./$pkgfile" + elif [ -f "$pkgdestfile" ]; then + pkgfile="$pkgdestfile" + else + echo "skipping ${_arch}" + continue 2 + fi + uploads+=("$pkgfile") + + if [[ $SIGNPKG == 'y' ]]; then + echo "Signing package ${pkgfile}..." + if [[ -n $GPGKEY ]]; then + SIGNWITHKEY="-u ${GPGKEY}" + fi + gpg --detach-sign --use-agent ${SIGNWITHKEY} "${pkgfile}" || abort + fi + + sigfile="${pkgfile}.sig" + if [ -f "${sigfile}" ]; then + uploads+=("$sigfile") + elif [[ $SIGNPKG == 'y' ]]; then + abort "Signature ${pkgfile}.sig was not found" + fi + done +done + +if [[ -n $commit_arch ]]; then + archrelease "$repo-$commit_arch" || abort +else + archrelease "${arch[@]/#/$repo-}" || abort +fi + +if [[ ${#uploads[*]} -gt 0 ]]; then + echo 'uploading all package and signature files' + rsync "${rsyncopts[@]}" "${uploads[@]}" "$server:staging/$repo/" || abort +fi + +if [ "${arch[*]}" == 'any' ]; then + if [ -d ../repos/$repo-i686 -a -d ../repos/$repo-x86_64 ]; then + pushd ../repos/ >/dev/null + echo "removing $repo-i686 and $repo-x86_64..." + svn rm $repo-i686 + svn rm $repo-x86_64 + svn commit -q -m "removed $repo-i686 and $repo-x86_64 for $pkgname" + echo 'done' + popd >/dev/null + fi +else + if [ -d ../repos/$repo-any ]; then + pushd ../repos/ >/dev/null + echo "removing $repo-any..." + svn rm $repo-any + svn commit -q -m "removed $repo-any for $pkgname" + echo 'done' + popd >/dev/null + fi +fi diff --git a/finddeps b/finddeps deleted file mode 100755 index ded7a93..0000000 --- a/finddeps +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# -# finddeps - find packages that depend on a given depname -# - -if [ "$1" = '' ]; then - echo 'usage: finddeps ' - echo '' - echo 'Find packages that depend on a given depname.' - echo 'Run this script from the top-level directory of your ABS tree.' - echo '' - exit 0 -fi - -match=$1 -tld=$(pwd) - -for d in $(find . -type d); do - cd $d - if [ -f PKGBUILD ]; then - unset pkgname depends makedepends - . PKGBUILD - for dep in "${depends[@]}"; do - # 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 comparator, if any - depname=${dep%%[<>=]*} - if [ "$depname" = "$match" ]; then - echo "$d (makedepends)" - fi - done - for dep in "${optdepends[@]/:*}"; do - # lose the version comaparator, if any - depname=${dep%%[<>=]*} - if [ "$depname" = "$match" ]; then - echo "$d (optdepends)" - fi - done - fi - cd $tld -done diff --git a/finddeps.in b/finddeps.in new file mode 100644 index 0000000..ded7a93 --- /dev/null +++ b/finddeps.in @@ -0,0 +1,46 @@ +#!/bin/bash +# +# finddeps - find packages that depend on a given depname +# + +if [ "$1" = '' ]; then + echo 'usage: finddeps ' + echo '' + echo 'Find packages that depend on a given depname.' + echo 'Run this script from the top-level directory of your ABS tree.' + echo '' + exit 0 +fi + +match=$1 +tld=$(pwd) + +for d in $(find . -type d); do + cd $d + if [ -f PKGBUILD ]; then + unset pkgname depends makedepends + . PKGBUILD + for dep in "${depends[@]}"; do + # 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 comparator, if any + depname=${dep%%[<>=]*} + if [ "$depname" = "$match" ]; then + echo "$d (makedepends)" + fi + done + for dep in "${optdepends[@]/:*}"; do + # lose the version comaparator, if any + depname=${dep%%[<>=]*} + if [ "$depname" = "$match" ]; then + echo "$d (optdepends)" + fi + done + fi + cd $tld +done diff --git a/lddd b/lddd deleted file mode 100755 index 9695c9b..0000000 --- a/lddd +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# lddd - find broken library links on your machine -# - -ifs=$IFS -IFS="${IFS}:" - -libdirs="/lib /usr/lib /usr/local/lib $(cat /etc/ld.so.conf.d/*)" -extras= - -TEMPDIR=$(mktemp -d /tmp/lddd-script.XXXX) - -echo 'Go out and drink some tea, this will take a while :) ...' -# Check ELF binaries in the PATH and specified dir trees. -for tree in $PATH $libdirs $extras; do - echo DIR $tree - - # Get list of files in tree. - files=$(find $tree -type f ! -name '*.a' ! -name '*.la' ! -name '*.py*' ! -name '*.txt' ! -name '*.h' ! -name '*.ttf' ! \ - -name '*.rb' ! -name '*.ko' ! -name '*.pc' ! -name '*.enc' ! -name '*.cf' ! -name '*.def' ! -name '*.rules' ! -name \ - '*.cmi' ! -name '*.mli' ! -name '*.ml' ! -name '*.cma' ! -name '*.cmx' ! -name '*.cmxa' ! -name '*.pod' ! -name '*.pm' \ - ! -name '*.pl' ! -name '*.al' ! -name '*.tcl' ! -name '*.bs' ! -name '*.o' ! -name '*.png' ! -name '*.gif' ! -name '*.cmo' \ - ! -name '*.cgi' ! -name '*.defs' ! -name '*.conf' ! -name '*_LOCALE' ! -name 'Compose' ! -name '*_OBJS' ! -name '*.msg' ! \ - -name '*.mcopclass' ! -name '*.mcoptype') - IFS=$ifs - for i in $files; do - if [ $(file $i | grep -c 'ELF') -ne 0 ]; then - # Is an ELF binary. - if [ $(ldd $i 2>/dev/null | grep -c 'not found') -ne 0 ]; then - # Missing lib. - echo "$i:" >> $TEMPDIR/raw.txt - ldd $i 2>/dev/null | grep 'not found' >> $TEMPDIR/raw.txt - fi - fi - done -done -grep '^/' $TEMPDIR/raw.txt | sed -e 's/://g' >> $TEMPDIR/affected-files.txt -# invoke pacman -for i in $(cat $TEMPDIR/affected-files.txt); do - pacman -Qo $i | awk '{print $4,$5}' >> $TEMPDIR/pacman.txt -done -# clean list -sort -u $TEMPDIR/pacman.txt >> $TEMPDIR/possible-rebuilds.txt - -echo "Files saved to $TEMPDIR" diff --git a/lddd.in b/lddd.in new file mode 100644 index 0000000..9695c9b --- /dev/null +++ b/lddd.in @@ -0,0 +1,46 @@ +#!/bin/sh +# +# lddd - find broken library links on your machine +# + +ifs=$IFS +IFS="${IFS}:" + +libdirs="/lib /usr/lib /usr/local/lib $(cat /etc/ld.so.conf.d/*)" +extras= + +TEMPDIR=$(mktemp -d /tmp/lddd-script.XXXX) + +echo 'Go out and drink some tea, this will take a while :) ...' +# Check ELF binaries in the PATH and specified dir trees. +for tree in $PATH $libdirs $extras; do + echo DIR $tree + + # Get list of files in tree. + files=$(find $tree -type f ! -name '*.a' ! -name '*.la' ! -name '*.py*' ! -name '*.txt' ! -name '*.h' ! -name '*.ttf' ! \ + -name '*.rb' ! -name '*.ko' ! -name '*.pc' ! -name '*.enc' ! -name '*.cf' ! -name '*.def' ! -name '*.rules' ! -name \ + '*.cmi' ! -name '*.mli' ! -name '*.ml' ! -name '*.cma' ! -name '*.cmx' ! -name '*.cmxa' ! -name '*.pod' ! -name '*.pm' \ + ! -name '*.pl' ! -name '*.al' ! -name '*.tcl' ! -name '*.bs' ! -name '*.o' ! -name '*.png' ! -name '*.gif' ! -name '*.cmo' \ + ! -name '*.cgi' ! -name '*.defs' ! -name '*.conf' ! -name '*_LOCALE' ! -name 'Compose' ! -name '*_OBJS' ! -name '*.msg' ! \ + -name '*.mcopclass' ! -name '*.mcoptype') + IFS=$ifs + for i in $files; do + if [ $(file $i | grep -c 'ELF') -ne 0 ]; then + # Is an ELF binary. + if [ $(ldd $i 2>/dev/null | grep -c 'not found') -ne 0 ]; then + # Missing lib. + echo "$i:" >> $TEMPDIR/raw.txt + ldd $i 2>/dev/null | grep 'not found' >> $TEMPDIR/raw.txt + fi + fi + done +done +grep '^/' $TEMPDIR/raw.txt | sed -e 's/://g' >> $TEMPDIR/affected-files.txt +# invoke pacman +for i in $(cat $TEMPDIR/affected-files.txt); do + pacman -Qo $i | awk '{print $4,$5}' >> $TEMPDIR/pacman.txt +done +# clean list +sort -u $TEMPDIR/pacman.txt >> $TEMPDIR/possible-rebuilds.txt + +echo "Files saved to $TEMPDIR" diff --git a/makechrootpkg b/makechrootpkg deleted file mode 100755 index a60c9fe..0000000 --- a/makechrootpkg +++ /dev/null @@ -1,305 +0,0 @@ -#!/bin/bash -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -FORCE='n' -RUN='' -MAKEPKG_ARGS='-s --noconfirm' -REPACK='' -WORKDIR=$PWD - -update_first='0' -clean_first='0' -install_pkg='' -add_to_db=0 - -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 [--] [makepkg args]" - echo ' Run this script in a PKGBUILD dir to build a package inside a' - echo ' clean chroot. All unrecognized arguments passed to this script' - echo ' will be passed to makepkg.' - echo '' - echo ' The chroot dir consists of the following directories:' - echo ' /{root, copy} but only "root" is required' - echo ' by default. The working copy will be created as needed' - echo '' - echo 'The chroot "root" directory must be created via the following' - echo 'command:' - echo ' mkarchroot /root base base-devel sudo' - echo '' - echo "Default makepkg args: $MAKEPKG_ARGS" - echo '' - echo 'Flags:' - echo '-h This help' - echo '-c Clean the chroot before building' - echo '-u Update the working copy of the chroot before building' - echo ' This is useful for rebuilds without dirtying the pristine' - echo ' chroot' - echo '-d Add the package to a local db at /repo after building' - echo '-r The chroot dir to use' - echo '-I Install a package into the working copy of the chroot' - echo '-l The directory to use as the working copy of the chroot' - echo ' Useful for maintaining multiple copies.' - echo " Default: $default_copy" - exit 1 -} - -while getopts 'hcudr:I:l:' arg; do - case "${arg}" in - h) usage ;; - c) clean_first=1 ;; - u) update_first=1 ;; - d) add_to_db=1 ;; - r) chrootdir="$OPTARG" ;; - I) install_pkg="$OPTARG" ;; - l) copy="$OPTARG" ;; - *) MAKEPKG_ARGS="$MAKEPKG_ARGS -$arg $OPTARG" ;; - esac -done - -# Canonicalize chrootdir, getting rid of trailing / -chrootdir=$(readlink -e "$chrootdir") - -if [[ ${copy:0:1} = "/" ]]; then - copydir=$copy -else - [[ -z $copy ]] && copy=$default_copy - copydir="$chrootdir/$copy" -fi - -# Pass all arguments after -- right to makepkg -MAKEPKG_ARGS="$MAKEPKG_ARGS ${*:$OPTIND}" - -# See if -R was passed to makepkg -for arg in ${*:$OPTIND}; do - if [ "$arg" = '-R' ]; then - REPACK=1 - break; - fi -done - -if [ "$EUID" != '0' ]; then - echo 'This script must be run as root.' - exit 1 -fi - -if [ ! -f PKGBUILD -a -z "$install_pkg" ]; then - echo 'This must be run in a directory containing a PKGBUILD.' - exit 1 -fi - -if [ ! -d "$chrootdir" ]; then - echo "No chroot dir defined, or invalid path '$chrootdir'" - exit 1 -fi - -if [ ! -d "$chrootdir/root" ]; then - echo 'Missing chroot dir root directory.' - echo "Try using: mkarchroot $chrootdir/root base base-devel sudo" - usage -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...' - 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 - pkgname="$(basename "$install_pkg")" - cp "$install_pkg" "$copydir/$pkgname" - mkarchroot -r "pacman -U /$pkgname --noconfirm" "$copydir" - ret=$? - rm "$copydir/$pkgname" - # Exit early, we've done all we need to - exit $ret -fi - -if [ $update_first -eq 1 ]; then - mkarchroot -u "$copydir" -fi - -[ -d "$copydir/build" ] || mkdir "$copydir/build" - -if [ "$REPACK" != "1" ]; then - # Remove anything in there UNLESS -R (repack) was passed to makepkg - rm -rf "$copydir/build/"* -fi - -# Read .makepkg.conf even if called via sudo -if [ -n "${SUDO_USER}" ]; then - makepkg_conf="/$(eval echo ~${SUDO_USER})/.makepkg.conf" -else - makepkg_conf="~/.makepkg.conf" -fi - -# Get SRC/PKGDEST from makepkg.conf -if [ -f "${makepkg_conf}" ]; then - eval $(grep '^SRCDEST=' "${makepkg_conf}") - eval $(grep '^PKGDEST=' "${makepkg_conf}") - - eval $(grep '^MAKEFLAGS=' "${makepkg_conf}") - eval $(grep '^PACKAGER=' "${makepkg_conf}") -fi -[ -z "${SRCDEST}" ] && eval $(grep '^SRCDEST=' /etc/makepkg.conf) -[ -z "${PKGDEST}" ] && eval $(grep '^PKGDEST=' /etc/makepkg.conf) - -[ -d "$copydir/pkgdest" ] || mkdir "$copydir/pkgdest" -if ! grep 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf" >/dev/null 2>&1; then - echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf" -fi - -[ -d "$copydir/srcdest" ] || mkdir "$copydir/srcdest" -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) -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) -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") -export CARCH -# Copy PKGBUILD and sources -source=($(. PKGBUILD; echo ${source[@]})) -cp PKGBUILD "$copydir/build/" -for f in ${source[@]}; do - basef=$(echo $f | sed 's|::.*||' | sed 's|^.*://.*/||g') - if [ -f "$basef" ]; then - cp "$basef" "$copydir/srcdest/" - elif [ -f "$SRCDEST/$basef" ]; then - cp "$SRCDEST/$basef" "$copydir/srcdest/" - fi -done - -( . PKGBUILD -for i in 'changelog' 'install'; do - filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) - for file in $filelist; do - # evaluate any bash variables used - eval file=${file} - if [[ -f "$file" ]]; then - cp "$file" "$copydir/build/" - fi - done -done -) - -chown -R nobody "$copydir/build" -chown -R nobody "$copydir/srcdest" -chown -R nobody "$copydir/pkgdest" - -echo 'nobody ALL = NOPASSWD: /usr/bin/pacman' > "$copydir/etc/sudoers.d/nobody-pacman" -chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" - -#This is a little gross, but this way the script is recreated every time in the -#working copy -(cat </dev/null && namcap /build/PKGBUILD /pkgdest/*.pkg.tar.* > /build/namcap.log -exit 0 -EOF -) > "$copydir/chrootbuild" -chmod +x "$copydir/chrootbuild" - -if mkarchroot -r "/chrootbuild" "$copydir"; then - for pkgfile in "${copydir}"/pkgdest/*.pkg.tar.*; do - [ -e "$pkgfile" ] || continue - if [ "$add_to_db" -eq "1" ]; then - mkdir -p "${copydir}/repo" - pushd "${copydir}/repo" >/dev/null - cp "$pkgfile" . - repo-add repo.db.tar.gz "$(basename "$pkgfile")" - popd >/dev/null - fi - - if [ -d "$PKGDEST" ]; then - mv "$pkgfile" "${PKGDEST}" - else - mv "$pkgfile" "${WORKDIR}" - fi - done - - for l in "${copydir}"/build/{namcap,*-{build,check,package,package_*}}.log; do - [ -f "$l" ] && mv "$l" "${WORKDIR}" - done -else - #just in case. We returned 1, make sure we fail - touch "${copydir}/build/BUILD_FAILED" -fi - -for f in "${copydir}"/srcdest/*; do - [ -e "$f" ] || continue - if [ -d "$SRCDEST" ]; then - mv "$f" "${SRCDEST}" - else - mv "$f" "${WORKDIR}" - fi -done - -if [ -e "${copydir}/build/BUILD_FAILED" ]; then - echo "Build failed, check $copydir/build" - rm "${copydir}/build/BUILD_FAILED" - exit 1 -fi diff --git a/makechrootpkg.in b/makechrootpkg.in new file mode 100644 index 0000000..a60c9fe --- /dev/null +++ b/makechrootpkg.in @@ -0,0 +1,305 @@ +#!/bin/bash +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +FORCE='n' +RUN='' +MAKEPKG_ARGS='-s --noconfirm' +REPACK='' +WORKDIR=$PWD + +update_first='0' +clean_first='0' +install_pkg='' +add_to_db=0 + +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 [--] [makepkg args]" + echo ' Run this script in a PKGBUILD dir to build a package inside a' + echo ' clean chroot. All unrecognized arguments passed to this script' + echo ' will be passed to makepkg.' + echo '' + echo ' The chroot dir consists of the following directories:' + echo ' /{root, copy} but only "root" is required' + echo ' by default. The working copy will be created as needed' + echo '' + echo 'The chroot "root" directory must be created via the following' + echo 'command:' + echo ' mkarchroot /root base base-devel sudo' + echo '' + echo "Default makepkg args: $MAKEPKG_ARGS" + echo '' + echo 'Flags:' + echo '-h This help' + echo '-c Clean the chroot before building' + echo '-u Update the working copy of the chroot before building' + echo ' This is useful for rebuilds without dirtying the pristine' + echo ' chroot' + echo '-d Add the package to a local db at /repo after building' + echo '-r The chroot dir to use' + echo '-I Install a package into the working copy of the chroot' + echo '-l The directory to use as the working copy of the chroot' + echo ' Useful for maintaining multiple copies.' + echo " Default: $default_copy" + exit 1 +} + +while getopts 'hcudr:I:l:' arg; do + case "${arg}" in + h) usage ;; + c) clean_first=1 ;; + u) update_first=1 ;; + d) add_to_db=1 ;; + r) chrootdir="$OPTARG" ;; + I) install_pkg="$OPTARG" ;; + l) copy="$OPTARG" ;; + *) MAKEPKG_ARGS="$MAKEPKG_ARGS -$arg $OPTARG" ;; + esac +done + +# Canonicalize chrootdir, getting rid of trailing / +chrootdir=$(readlink -e "$chrootdir") + +if [[ ${copy:0:1} = "/" ]]; then + copydir=$copy +else + [[ -z $copy ]] && copy=$default_copy + copydir="$chrootdir/$copy" +fi + +# Pass all arguments after -- right to makepkg +MAKEPKG_ARGS="$MAKEPKG_ARGS ${*:$OPTIND}" + +# See if -R was passed to makepkg +for arg in ${*:$OPTIND}; do + if [ "$arg" = '-R' ]; then + REPACK=1 + break; + fi +done + +if [ "$EUID" != '0' ]; then + echo 'This script must be run as root.' + exit 1 +fi + +if [ ! -f PKGBUILD -a -z "$install_pkg" ]; then + echo 'This must be run in a directory containing a PKGBUILD.' + exit 1 +fi + +if [ ! -d "$chrootdir" ]; then + echo "No chroot dir defined, or invalid path '$chrootdir'" + exit 1 +fi + +if [ ! -d "$chrootdir/root" ]; then + echo 'Missing chroot dir root directory.' + echo "Try using: mkarchroot $chrootdir/root base base-devel sudo" + usage +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...' + 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 + pkgname="$(basename "$install_pkg")" + cp "$install_pkg" "$copydir/$pkgname" + mkarchroot -r "pacman -U /$pkgname --noconfirm" "$copydir" + ret=$? + rm "$copydir/$pkgname" + # Exit early, we've done all we need to + exit $ret +fi + +if [ $update_first -eq 1 ]; then + mkarchroot -u "$copydir" +fi + +[ -d "$copydir/build" ] || mkdir "$copydir/build" + +if [ "$REPACK" != "1" ]; then + # Remove anything in there UNLESS -R (repack) was passed to makepkg + rm -rf "$copydir/build/"* +fi + +# Read .makepkg.conf even if called via sudo +if [ -n "${SUDO_USER}" ]; then + makepkg_conf="/$(eval echo ~${SUDO_USER})/.makepkg.conf" +else + makepkg_conf="~/.makepkg.conf" +fi + +# Get SRC/PKGDEST from makepkg.conf +if [ -f "${makepkg_conf}" ]; then + eval $(grep '^SRCDEST=' "${makepkg_conf}") + eval $(grep '^PKGDEST=' "${makepkg_conf}") + + eval $(grep '^MAKEFLAGS=' "${makepkg_conf}") + eval $(grep '^PACKAGER=' "${makepkg_conf}") +fi +[ -z "${SRCDEST}" ] && eval $(grep '^SRCDEST=' /etc/makepkg.conf) +[ -z "${PKGDEST}" ] && eval $(grep '^PKGDEST=' /etc/makepkg.conf) + +[ -d "$copydir/pkgdest" ] || mkdir "$copydir/pkgdest" +if ! grep 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf" >/dev/null 2>&1; then + echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf" +fi + +[ -d "$copydir/srcdest" ] || mkdir "$copydir/srcdest" +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) +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) +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") +export CARCH +# Copy PKGBUILD and sources +source=($(. PKGBUILD; echo ${source[@]})) +cp PKGBUILD "$copydir/build/" +for f in ${source[@]}; do + basef=$(echo $f | sed 's|::.*||' | sed 's|^.*://.*/||g') + if [ -f "$basef" ]; then + cp "$basef" "$copydir/srcdest/" + elif [ -f "$SRCDEST/$basef" ]; then + cp "$SRCDEST/$basef" "$copydir/srcdest/" + fi +done + +( . PKGBUILD +for i in 'changelog' 'install'; do + filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) + for file in $filelist; do + # evaluate any bash variables used + eval file=${file} + if [[ -f "$file" ]]; then + cp "$file" "$copydir/build/" + fi + done +done +) + +chown -R nobody "$copydir/build" +chown -R nobody "$copydir/srcdest" +chown -R nobody "$copydir/pkgdest" + +echo 'nobody ALL = NOPASSWD: /usr/bin/pacman' > "$copydir/etc/sudoers.d/nobody-pacman" +chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" + +#This is a little gross, but this way the script is recreated every time in the +#working copy +(cat </dev/null && namcap /build/PKGBUILD /pkgdest/*.pkg.tar.* > /build/namcap.log +exit 0 +EOF +) > "$copydir/chrootbuild" +chmod +x "$copydir/chrootbuild" + +if mkarchroot -r "/chrootbuild" "$copydir"; then + for pkgfile in "${copydir}"/pkgdest/*.pkg.tar.*; do + [ -e "$pkgfile" ] || continue + if [ "$add_to_db" -eq "1" ]; then + mkdir -p "${copydir}/repo" + pushd "${copydir}/repo" >/dev/null + cp "$pkgfile" . + repo-add repo.db.tar.gz "$(basename "$pkgfile")" + popd >/dev/null + fi + + if [ -d "$PKGDEST" ]; then + mv "$pkgfile" "${PKGDEST}" + else + mv "$pkgfile" "${WORKDIR}" + fi + done + + for l in "${copydir}"/build/{namcap,*-{build,check,package,package_*}}.log; do + [ -f "$l" ] && mv "$l" "${WORKDIR}" + done +else + #just in case. We returned 1, make sure we fail + touch "${copydir}/build/BUILD_FAILED" +fi + +for f in "${copydir}"/srcdest/*; do + [ -e "$f" ] || continue + if [ -d "$SRCDEST" ]; then + mv "$f" "${SRCDEST}" + else + mv "$f" "${WORKDIR}" + fi +done + +if [ -e "${copydir}/build/BUILD_FAILED" ]; then + echo "Build failed, check $copydir/build" + rm "${copydir}/build/BUILD_FAILED" + exit 1 +fi diff --git a/mkarchroot b/mkarchroot deleted file mode 100755 index 8e74c54..0000000 --- a/mkarchroot +++ /dev/null @@ -1,231 +0,0 @@ -#!/bin/bash -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -FORCE='n' -RUN='' -NOCOPY='n' - -working_dir='' - -APPNAME=$(basename "${0}") - -# usage: usage -usage() { - echo "usage ${APPNAME} [options] working-dir [package-list | app]" - echo ' options:' - echo ' -r 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 Location of a pacman config file' - echo ' -M Location of a makepkg config file' - echo ' -n Do not copy config files into the chroot' - echo ' -c Set pacman cache. Default: /var/cache/pacman/pkg' - echo ' -h This message' - exit $1 -} - -while getopts 'r:ufnhC:M:c:' arg; do - case "${arg}" in - r) RUN="$OPTARG" ;; - u) RUN='/bin/sh -c "pacman -Syu --noconfirm && (pacman -Qqu >/dev/null && pacman -Su --noconfirm || exit 0)"' ;; - f) FORCE='y' ;; - C) pac_conf="$OPTARG" ;; - M) makepkg_conf="$OPTARG" ;; - n) NOCOPY='y' ;; - c) cache_dir="$OPTARG" ;; - h|?) usage 0 ;; - *) echo "invalid argument '${arg}'"; usage 1 ;; - esac -done - -if [ "$EUID" != '0' ]; then - echo 'error: this script must be run as root.' - exit 1 -fi - -shift $(($OPTIND - 1)) - -if [ "$RUN" = '' -a $# -lt 2 ]; then - echo 'you must specify a directory and one or more packages' - usage 1 -elif [ $# -lt 1 ]; then - echo 'you must specify a directory' - usage 1 -fi - -working_dir="$(readlink -f ${1})" -shift 1 - -[ "${working_dir}" = '' ] && echo 'error: please specify a working directory' && usage 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*//') - unset cache_conf -fi - -if [ -f /etc/pacman.d/mirrorlist ]; then - host_mirror=$(pacman -Sddp extra/devtools 2>/dev/null | sed -E 's#(.*/)extra/os/.*#\1$repo/os/$arch#') -fi -if [ -z "${host_mirror}" ]; then - host_mirror='http://mirrors.kernel.org/archlinux/$repo/os/$arch' -fi -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 -chroot_mount() { - [ -e "${working_dir}/sys" ] || mkdir "${working_dir}/sys" - mount -t sysfs sysfs "${working_dir}/sys" - - [ -e "${working_dir}/proc" ] || mkdir "${working_dir}/proc" - mount -t proc proc "${working_dir}/proc" - - [ -e "${working_dir}/dev" ] || mkdir "${working_dir}/dev" - mount -t tmpfs dev "${working_dir}/dev" -o mode=0755,size=10M,nosuid - mknod -m 666 "${working_dir}/dev/null" c 1 3 - mknod -m 666 "${working_dir}/dev/zero" c 1 5 - mknod -m 600 "${working_dir}/dev/console" c 5 1 - mknod -m 644 "${working_dir}/dev/random" c 1 8 - mknod -m 644 "${working_dir}/dev/urandom" c 1 9 - mknod -m 666 "${working_dir}/dev/tty" c 5 0 - mknod -m 666 "${working_dir}/dev/tty0" c 4 0 - mknod -m 666 "${working_dir}/dev/full" c 1 7 - ln -s /proc/kcore "${working_dir}/dev/core" - ln -s /proc/self/fd "${working_dir}/dev/fd" - ln -s /proc/self/fd/0 "${working_dir}/dev/stdin" - ln -s /proc/self/fd/1 "${working_dir}/dev/stdout" - ln -s /proc/self/fd/2 "${working_dir}/dev/stderr" - - [ -e "${working_dir}/dev/shm" ] || mkdir "${working_dir}/dev/shm" - mount -t tmpfs shm "${working_dir}/dev/shm" -o nodev,nosuid,size=128M - - [ -e "${working_dir}/dev/pts" ] || mkdir "${working_dir}/dev/pts" - mount -t devpts devpts "${working_dir}/dev/pts" -o newinstance,ptmxmode=666 - ln -s pts/ptmx "${working_dir}/dev/ptmx" - - [ -e "${cache_dir}" ] || mkdir -p "${cache_dir}" - [ -e "${working_dir}/${cache_dir}" ] || mkdir -p "${working_dir}/${cache_dir}" - mount -o bind "${cache_dir}" "${working_dir}/${cache_dir}" - - if [ -n "${host_mirror_path}" ]; then - [ -e "${working_dir}/${host_mirror_path}" ] || mkdir -p "${working_dir}/${host_mirror_path}" - mount -o bind "${host_mirror_path}" "${working_dir}/${host_mirror_path}" - mount -o remount,ro,bind "${host_mirror_path}" "${working_dir}/${host_mirror_path}" - fi - - trap 'chroot_umount' EXIT INT QUIT TERM HUP -} - -copy_hostconf () { - chroot "${working_dir}" /bin/findmnt -rnu -o SOURCE,TARGET,FSTYPE,OPTIONS > "${working_dir}/etc/mtab" - cp /etc/resolv.conf "${working_dir}/etc/resolv.conf" - echo "Server = ${host_mirror}" > ${working_dir}/etc/pacman.d/mirrorlist -} - -chroot_umount () { - umount "${working_dir}/proc" - umount "${working_dir}/sys" - umount "${working_dir}/dev/pts" - umount "${working_dir}/dev/shm" - umount "${working_dir}/dev" - 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 -if [ "$RUN" != "" ]; then - # run chroot {{{ - #Sanity check - if [ ! -f "${working_dir}/.arch-chroot" ]; then - echo "error: '${working_dir}' does not appear to be a Arch chroot" - echo ' please build the image using mkarchroot' - exit 1 - fi - - chroot_lock - chroot_mount - copy_hostconf - - eval chroot "${working_dir}" ${RUN} - - # }}} -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}" - if [ "$pac_conf" != "" ]; then - pacargs="$pacargs --config=${pac_conf}" - fi - - if [ $# -ne 0 ]; then - op='-Sy' - if [ "$FORCE" = "y" ]; then - op="${op}f" - fi - if ! pacman ${op} ${pacargs} $@; then - echo 'error: failed to install all packages' - exit 1 - fi - fi - - if [ -d "${working_dir}/lib/modules" ]; then - ldconfig -r "${working_dir}" - fi - - if [ "$pac_conf" != "" -a "$NOCOPY" = "n" ]; then - cp ${pac_conf} ${working_dir}/etc/pacman.conf - fi - - if [ "$makepkg_conf" != "" -a "$NOCOPY" = "n" ]; then - cp ${makepkg_conf} ${working_dir}/etc/makepkg.conf - fi - - if [ -e "${working_dir}/etc/locale.gen" ]; then - sed -i 's@^#\(en_US\|de_DE\)\(\.UTF-8\)@\1\2@' "${working_dir}/etc/locale.gen" - chroot "${working_dir}" locale-gen - fi - - if [ ! -e "${working_dir}/.arch-chroot" ]; then - date +%s > "${working_dir}/.arch-chroot" - fi - # }}} -fi diff --git a/mkarchroot.in b/mkarchroot.in new file mode 100644 index 0000000..8e74c54 --- /dev/null +++ b/mkarchroot.in @@ -0,0 +1,231 @@ +#!/bin/bash +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +FORCE='n' +RUN='' +NOCOPY='n' + +working_dir='' + +APPNAME=$(basename "${0}") + +# usage: usage +usage() { + echo "usage ${APPNAME} [options] working-dir [package-list | app]" + echo ' options:' + echo ' -r 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 Location of a pacman config file' + echo ' -M Location of a makepkg config file' + echo ' -n Do not copy config files into the chroot' + echo ' -c Set pacman cache. Default: /var/cache/pacman/pkg' + echo ' -h This message' + exit $1 +} + +while getopts 'r:ufnhC:M:c:' arg; do + case "${arg}" in + r) RUN="$OPTARG" ;; + u) RUN='/bin/sh -c "pacman -Syu --noconfirm && (pacman -Qqu >/dev/null && pacman -Su --noconfirm || exit 0)"' ;; + f) FORCE='y' ;; + C) pac_conf="$OPTARG" ;; + M) makepkg_conf="$OPTARG" ;; + n) NOCOPY='y' ;; + c) cache_dir="$OPTARG" ;; + h|?) usage 0 ;; + *) echo "invalid argument '${arg}'"; usage 1 ;; + esac +done + +if [ "$EUID" != '0' ]; then + echo 'error: this script must be run as root.' + exit 1 +fi + +shift $(($OPTIND - 1)) + +if [ "$RUN" = '' -a $# -lt 2 ]; then + echo 'you must specify a directory and one or more packages' + usage 1 +elif [ $# -lt 1 ]; then + echo 'you must specify a directory' + usage 1 +fi + +working_dir="$(readlink -f ${1})" +shift 1 + +[ "${working_dir}" = '' ] && echo 'error: please specify a working directory' && usage 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*//') + unset cache_conf +fi + +if [ -f /etc/pacman.d/mirrorlist ]; then + host_mirror=$(pacman -Sddp extra/devtools 2>/dev/null | sed -E 's#(.*/)extra/os/.*#\1$repo/os/$arch#') +fi +if [ -z "${host_mirror}" ]; then + host_mirror='http://mirrors.kernel.org/archlinux/$repo/os/$arch' +fi +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 +chroot_mount() { + [ -e "${working_dir}/sys" ] || mkdir "${working_dir}/sys" + mount -t sysfs sysfs "${working_dir}/sys" + + [ -e "${working_dir}/proc" ] || mkdir "${working_dir}/proc" + mount -t proc proc "${working_dir}/proc" + + [ -e "${working_dir}/dev" ] || mkdir "${working_dir}/dev" + mount -t tmpfs dev "${working_dir}/dev" -o mode=0755,size=10M,nosuid + mknod -m 666 "${working_dir}/dev/null" c 1 3 + mknod -m 666 "${working_dir}/dev/zero" c 1 5 + mknod -m 600 "${working_dir}/dev/console" c 5 1 + mknod -m 644 "${working_dir}/dev/random" c 1 8 + mknod -m 644 "${working_dir}/dev/urandom" c 1 9 + mknod -m 666 "${working_dir}/dev/tty" c 5 0 + mknod -m 666 "${working_dir}/dev/tty0" c 4 0 + mknod -m 666 "${working_dir}/dev/full" c 1 7 + ln -s /proc/kcore "${working_dir}/dev/core" + ln -s /proc/self/fd "${working_dir}/dev/fd" + ln -s /proc/self/fd/0 "${working_dir}/dev/stdin" + ln -s /proc/self/fd/1 "${working_dir}/dev/stdout" + ln -s /proc/self/fd/2 "${working_dir}/dev/stderr" + + [ -e "${working_dir}/dev/shm" ] || mkdir "${working_dir}/dev/shm" + mount -t tmpfs shm "${working_dir}/dev/shm" -o nodev,nosuid,size=128M + + [ -e "${working_dir}/dev/pts" ] || mkdir "${working_dir}/dev/pts" + mount -t devpts devpts "${working_dir}/dev/pts" -o newinstance,ptmxmode=666 + ln -s pts/ptmx "${working_dir}/dev/ptmx" + + [ -e "${cache_dir}" ] || mkdir -p "${cache_dir}" + [ -e "${working_dir}/${cache_dir}" ] || mkdir -p "${working_dir}/${cache_dir}" + mount -o bind "${cache_dir}" "${working_dir}/${cache_dir}" + + if [ -n "${host_mirror_path}" ]; then + [ -e "${working_dir}/${host_mirror_path}" ] || mkdir -p "${working_dir}/${host_mirror_path}" + mount -o bind "${host_mirror_path}" "${working_dir}/${host_mirror_path}" + mount -o remount,ro,bind "${host_mirror_path}" "${working_dir}/${host_mirror_path}" + fi + + trap 'chroot_umount' EXIT INT QUIT TERM HUP +} + +copy_hostconf () { + chroot "${working_dir}" /bin/findmnt -rnu -o SOURCE,TARGET,FSTYPE,OPTIONS > "${working_dir}/etc/mtab" + cp /etc/resolv.conf "${working_dir}/etc/resolv.conf" + echo "Server = ${host_mirror}" > ${working_dir}/etc/pacman.d/mirrorlist +} + +chroot_umount () { + umount "${working_dir}/proc" + umount "${working_dir}/sys" + umount "${working_dir}/dev/pts" + umount "${working_dir}/dev/shm" + umount "${working_dir}/dev" + 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 +if [ "$RUN" != "" ]; then + # run chroot {{{ + #Sanity check + if [ ! -f "${working_dir}/.arch-chroot" ]; then + echo "error: '${working_dir}' does not appear to be a Arch chroot" + echo ' please build the image using mkarchroot' + exit 1 + fi + + chroot_lock + chroot_mount + copy_hostconf + + eval chroot "${working_dir}" ${RUN} + + # }}} +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}" + if [ "$pac_conf" != "" ]; then + pacargs="$pacargs --config=${pac_conf}" + fi + + if [ $# -ne 0 ]; then + op='-Sy' + if [ "$FORCE" = "y" ]; then + op="${op}f" + fi + if ! pacman ${op} ${pacargs} $@; then + echo 'error: failed to install all packages' + exit 1 + fi + fi + + if [ -d "${working_dir}/lib/modules" ]; then + ldconfig -r "${working_dir}" + fi + + if [ "$pac_conf" != "" -a "$NOCOPY" = "n" ]; then + cp ${pac_conf} ${working_dir}/etc/pacman.conf + fi + + if [ "$makepkg_conf" != "" -a "$NOCOPY" = "n" ]; then + cp ${makepkg_conf} ${working_dir}/etc/makepkg.conf + fi + + if [ -e "${working_dir}/etc/locale.gen" ]; then + sed -i 's@^#\(en_US\|de_DE\)\(\.UTF-8\)@\1\2@' "${working_dir}/etc/locale.gen" + chroot "${working_dir}" locale-gen + fi + + if [ ! -e "${working_dir}/.arch-chroot" ]; then + date +%s > "${working_dir}/.arch-chroot" + fi + # }}} +fi diff --git a/rebuildpkgs b/rebuildpkgs deleted file mode 100755 index be279bb..0000000 --- a/rebuildpkgs +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash -# This script rebuilds a list of packages in order -# and reports anything that fails -# -# Due to sudo usage, it is recommended to allow makechrootpkg -# to be run with NOPASSWD in your sudoers file -# -# FIXME -# Currently uses $(pwd)/rebuilds as the directory for rebuilding... -# TODO make this work for community too - -if [ $# -le 1 ]; then - echo "usage: $(basename $0) " - echo " example: $(basename $0) ~/chroot readline bash foo bar baz" - exit 1 -fi - -# Source makepkg.conf; fail if it is not found -if [ -r '/etc/makepkg.conf' ]; then - source '/etc/makepkg.conf' -else - echo '/etc/makepkg.conf not found!' - exit 1 -fi - -die () { - echo $@ >&2 - exit 1 -} - -bump_pkgrel() { - # Get the current pkgrel from SVN and update the working copy with it - # This prevents us from incrementing out of control :) - pbuild='.svn/text-base/PKGBUILD.svn-base' - oldrel=$(grep 'pkgrel=' $pbuild | cut -d= -f2) - - #remove decimals - rel=$(echo $oldrel | cut -d. -f1) - - newrel=$(($rel + 1)) - - sed -i "s/pkgrel=$oldrel/pkgrel=$newrel/" PKGBUILD -} - -pkg_from_pkgbuild() { - # we want the sourcing to be done in a subshell so we don't pollute our current namespace - export CARCH PKGEXT - (source PKGBUILD; echo "$pkgname-$pkgver-$pkgrel-$CARCH$PKGEXT") -} - -chrootdir="$1"; shift -pkgs="$@" - -SVNPATH='svn+ssh://gerolde.archlinux.org/srv/svn-packages' - -echo ":: Work will be done in $(pwd)/rebuilds" - -REBUILD_ROOT="$(pwd)/rebuilds" -mkdir -p "$REBUILD_ROOT" -cd "$REBUILD_ROOT" - -/usr/bin/svn co -N $SVNPATH - -FAILED="" -for pkg in $pkgs; do - cd "$REBUILD_ROOT/svn-packages" - - echo ":: Building '$pkg'" - /usr/bin/svn update "$pkg" - if [ ! -d "$pkg/trunk" ]; then - FAILED="$FAILED $pkg" - echo ":: $pkg does not exist in SVN" - continue - fi - cd "$pkg/trunk/" - - bump_pkgrel - - if ! sudo makechrootpkg -u -d -r "$chrootdir" -- --noconfirm; then - FAILED="$FAILED $pkg" - echo ":: $pkg Failed!" - else - pkgfile=$(pkg_from_pkgbuild) - if [ -e "$pkgfile" ]; then - echo ":: $pkg Complete" - else - FAILED="$FAILED $pkg" - echo ":: $pkg Failed, no package built!" - fi - fi -done - -cd "$REBUILD_ROOT" -if [ "$FAILED" != "" ]; then - echo 'Packages failed:' - for pkg in $FAILED; do - echo -e "\t$pkg" - done -fi - -echo 'SVN pkgbumps in svn-packages/ - commit when ready' diff --git a/rebuildpkgs.in b/rebuildpkgs.in new file mode 100644 index 0000000..be279bb --- /dev/null +++ b/rebuildpkgs.in @@ -0,0 +1,101 @@ +#!/bin/bash +# This script rebuilds a list of packages in order +# and reports anything that fails +# +# Due to sudo usage, it is recommended to allow makechrootpkg +# to be run with NOPASSWD in your sudoers file +# +# FIXME +# Currently uses $(pwd)/rebuilds as the directory for rebuilding... +# TODO make this work for community too + +if [ $# -le 1 ]; then + echo "usage: $(basename $0) " + echo " example: $(basename $0) ~/chroot readline bash foo bar baz" + exit 1 +fi + +# Source makepkg.conf; fail if it is not found +if [ -r '/etc/makepkg.conf' ]; then + source '/etc/makepkg.conf' +else + echo '/etc/makepkg.conf not found!' + exit 1 +fi + +die () { + echo $@ >&2 + exit 1 +} + +bump_pkgrel() { + # Get the current pkgrel from SVN and update the working copy with it + # This prevents us from incrementing out of control :) + pbuild='.svn/text-base/PKGBUILD.svn-base' + oldrel=$(grep 'pkgrel=' $pbuild | cut -d= -f2) + + #remove decimals + rel=$(echo $oldrel | cut -d. -f1) + + newrel=$(($rel + 1)) + + sed -i "s/pkgrel=$oldrel/pkgrel=$newrel/" PKGBUILD +} + +pkg_from_pkgbuild() { + # we want the sourcing to be done in a subshell so we don't pollute our current namespace + export CARCH PKGEXT + (source PKGBUILD; echo "$pkgname-$pkgver-$pkgrel-$CARCH$PKGEXT") +} + +chrootdir="$1"; shift +pkgs="$@" + +SVNPATH='svn+ssh://gerolde.archlinux.org/srv/svn-packages' + +echo ":: Work will be done in $(pwd)/rebuilds" + +REBUILD_ROOT="$(pwd)/rebuilds" +mkdir -p "$REBUILD_ROOT" +cd "$REBUILD_ROOT" + +/usr/bin/svn co -N $SVNPATH + +FAILED="" +for pkg in $pkgs; do + cd "$REBUILD_ROOT/svn-packages" + + echo ":: Building '$pkg'" + /usr/bin/svn update "$pkg" + if [ ! -d "$pkg/trunk" ]; then + FAILED="$FAILED $pkg" + echo ":: $pkg does not exist in SVN" + continue + fi + cd "$pkg/trunk/" + + bump_pkgrel + + if ! sudo makechrootpkg -u -d -r "$chrootdir" -- --noconfirm; then + FAILED="$FAILED $pkg" + echo ":: $pkg Failed!" + else + pkgfile=$(pkg_from_pkgbuild) + if [ -e "$pkgfile" ]; then + echo ":: $pkg Complete" + else + FAILED="$FAILED $pkg" + echo ":: $pkg Failed, no package built!" + fi + fi +done + +cd "$REBUILD_ROOT" +if [ "$FAILED" != "" ]; then + echo 'Packages failed:' + for pkg in $FAILED; do + echo -e "\t$pkg" + done +fi + +echo 'SVN pkgbumps in svn-packages/ - commit when ready' diff --git a/zsh_completion b/zsh_completion deleted file mode 100644 index d87850a..0000000 --- a/zsh_completion +++ /dev/null @@ -1,81 +0,0 @@ -#compdef archbuild archco archrelease archrm commitpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-i686-build=archbuild extra-x86_64-build=archbuild testing-i686-build=archbuild testing-x86_64-build=archbuild staging-i686-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild communityco=archco - -_arch=(i686 x86_64 any) - -_tags=( - core-i686 core-x86_64 core-any - extra-i686 extra-x86_64 extra-any - multilib-i686 multilib-x86_64 multilib-any - staging-i686 staging-x86_64 staging-any - testing-i686 testing-x86_64 testing-any - multilib-testing-i686 multilib-testing-x86_64 multilib-testing-any - community-i686 community-x86_64 community-any - community-staging-i686 community-staging-x86_64 community-staging-any - community-testing-i686 community-testing-x86_64 community-testing-any -) - -_archbuild_args=( - '-c[Recreate the chroot before building]' - '-r[Create chroots in this directory]:base_dir:_files -/' -) - -_archco_args=( - '*:packages:_devtools_completions_all_packages' -) - -_archrelease_args=( - "*:arch:($_tags[*])" -) - -_archrm_args=( - '1:path:_files -/' -) - -_commitpkg_args=( - "-a[Release to a specific architecture only]:arch:($_arch[*])" - '-l[Set bandwidth limit]:limit' - '1:commit_msg' -) - -_finddeps_args=( - '1:packages:_devtools_completions_all_packages' -) - -_makechrootpkg_args=( - '-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"' - '-c[Clean the chroot before building]' - '-d[Add the package to a local db at /repo after building]' - '-h[Display usage]' - '-l[The directory to use as the working copy]:copy_dir:_files -/' - '-r[The chroot dir to use]:chroot_dir:_files -/' - '-u[Update the working copy of the chroot before building]' -) - -_mkarchroot_args=( - '-r[Run a program within the context of the chroot]:app' - '-u[Update the chroot via pacman]' - '-f[Force overwrite of files in the working-dir]' - '-C[Location of a pacman config file]:pacman_config:_files' - '-M[Location of a makepkg config file]:makepkg_config:_files' - '-n[Do not copy config files into the chroot]' - '-c[Set pacman cache]:pacman_cache:_files -/' - '-h[Display usage]' -) - -_rebuildpkgs_args=( - '1:chroot_dir:_files -/' - '*:packages:_devtools_completions_all_packages' -) - -_devtools_completions_all_packages() { - typeset -U packages - packages=($(_call_program packages pacman -Sql)) - compadd - "${(@)packages}" -} - -_devtools() { - local argname="_${service}_args[@]" - _arguments -s "${(P)argname}" -} - -_devtools diff --git a/zsh_completion.in b/zsh_completion.in new file mode 100644 index 0000000..d87850a --- /dev/null +++ b/zsh_completion.in @@ -0,0 +1,81 @@ +#compdef archbuild archco archrelease archrm commitpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-i686-build=archbuild extra-x86_64-build=archbuild testing-i686-build=archbuild testing-x86_64-build=archbuild staging-i686-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild communityco=archco + +_arch=(i686 x86_64 any) + +_tags=( + core-i686 core-x86_64 core-any + extra-i686 extra-x86_64 extra-any + multilib-i686 multilib-x86_64 multilib-any + staging-i686 staging-x86_64 staging-any + testing-i686 testing-x86_64 testing-any + multilib-testing-i686 multilib-testing-x86_64 multilib-testing-any + community-i686 community-x86_64 community-any + community-staging-i686 community-staging-x86_64 community-staging-any + community-testing-i686 community-testing-x86_64 community-testing-any +) + +_archbuild_args=( + '-c[Recreate the chroot before building]' + '-r[Create chroots in this directory]:base_dir:_files -/' +) + +_archco_args=( + '*:packages:_devtools_completions_all_packages' +) + +_archrelease_args=( + "*:arch:($_tags[*])" +) + +_archrm_args=( + '1:path:_files -/' +) + +_commitpkg_args=( + "-a[Release to a specific architecture only]:arch:($_arch[*])" + '-l[Set bandwidth limit]:limit' + '1:commit_msg' +) + +_finddeps_args=( + '1:packages:_devtools_completions_all_packages' +) + +_makechrootpkg_args=( + '-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"' + '-c[Clean the chroot before building]' + '-d[Add the package to a local db at /repo after building]' + '-h[Display usage]' + '-l[The directory to use as the working copy]:copy_dir:_files -/' + '-r[The chroot dir to use]:chroot_dir:_files -/' + '-u[Update the working copy of the chroot before building]' +) + +_mkarchroot_args=( + '-r[Run a program within the context of the chroot]:app' + '-u[Update the chroot via pacman]' + '-f[Force overwrite of files in the working-dir]' + '-C[Location of a pacman config file]:pacman_config:_files' + '-M[Location of a makepkg config file]:makepkg_config:_files' + '-n[Do not copy config files into the chroot]' + '-c[Set pacman cache]:pacman_cache:_files -/' + '-h[Display usage]' +) + +_rebuildpkgs_args=( + '1:chroot_dir:_files -/' + '*:packages:_devtools_completions_all_packages' +) + +_devtools_completions_all_packages() { + typeset -U packages + packages=($(_call_program packages pacman -Sql)) + compadd - "${(@)packages}" +} + +_devtools() { + local argname="_${service}_args[@]" + _arguments -s "${(P)argname}" +} + +_devtools -- cgit v1.2.3-70-g09d2