Compare commits

...

30 Commits

Author SHA1 Message Date
Pierre Schmitz
164f5b758d prepare release 2013-10-20 13:32:16 +02:00
Pierre Schmitz
1ae58aed5b Remove libtool files by default 2013-10-20 13:31:02 +02:00
Allan McRae
0d16a91350 Make !staticlibs the default in makepkg.conf
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-10-19 16:26:54 +02:00
Dave Reisner
e77242c539 makechrootpkg: add generic support for additional bind mounts
Piggyback on systemd-nspawn's --bind and --bind-ro flags to allow
arbitrary mount points to be added to the build container.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-19 22:11:27 +02:00
Dave Reisner
9c85d116f0 checkpkg: avoid using PKGEXT to guess tarball name
We can't rely on PKGEXT since it's not sourced from a controlled
location. Case in point, if a user sets PKGEXT=.pkg.tar.gz, checkpkg
fails and offers no easy workaround.

Instead, use glob expansion to resolve the name of the tarball, bailing
if it can't be found definitively. This involves some refactoring to
avoid modifying PWD (which is advisable regardless).

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-18 18:19:12 +02:00
Dave Reisner
914ebe3a74 ensure that PKGBUILDs aren't sourced via PATH
Fixes FS#36378.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-18 18:17:31 +02:00
Dave Reisner
7267664ed8 arch-nspawn: allow oddly named directories
This fixes various errors one might encounter when trying to use a
build root or cachedir with whitespace in it.

Note that the cachedir fix is not a complete one, as pacman's output is
unreliable (and not meant for parsing here).

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-18 18:17:05 +02:00
Dave Reisner
e0f7c21a68 arch-nspawn: avoid escaping mount_args
eval is no longer involved in the execution of systemd-nspawn, so we no
longer need a layer of escaping on the arguments.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-18 18:16:59 +02:00
Pierre Schmitz
8dbb02de4f Prepare release 2013-08-08 22:51:14 +02:00
Pierre Schmitz
b12d5eaf85 Update makepkg.conf from pacman 4.1.2 2013-08-08 22:50:19 +02:00
Dave Reisner
0fa2536957 Makefile: validate generated files as part of build
For example...

$ make
GEN checkpkg
GEN commitpkg
GEN archco
archco: line 179: unexpected EOF while looking for matching `"'
archco: line 181: syntax error: unexpected end of file
make: *** [archco] Error 2

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-08 21:28:19 +02:00
Dave Reisner
be3c71fa81 avoid injecting code into the format string
Now that die() properly forwards arguments to error(), we can expect
that the first arg is a format string and not the entirety of the
output.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-08 21:28:10 +02:00
Dave Reisner
fb30cabe61 common: Properly forward arguments from die to error
Also allow this function to be called without arguments, in which case,
don't call error at all. Some uses of this function wrongly assumed
that this was already allowed.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-08 21:28:00 +02:00
Florian Pritz
29e62278a7 arch-nspawn: remove leading - from the machine name/hostname
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Pierre Schmitz <pierre@archlinux.de>
2013-08-08 21:24:55 +02:00
Pierre Schmitz
8c4553f68c prepare new release 2013-05-25 22:39:46 +02:00
Pierre Schmitz
6006783cbc Move all scripts from sbin to bin directories 2013-05-25 22:39:11 +02:00
Jan Alexander Steffens (heftig)
e26fddb608 Update .gitignore 2013-05-25 22:17:30 +02:00
Jan Alexander Steffens (heftig)
c3bb10046b crossrepomove: copy packages locally
Nymeria's HTTP mirror is now password-protected and crossrepomove broke.
2013-05-25 16:55:53 +02:00
Jan Alexander Steffens (heftig)
7a3f524201 makechrootpkg: Add hack for svn sources and makepkg 4.1.1 2013-05-25 16:55:53 +02:00
Jan Alexander Steffens (heftig)
fc71be3479 makechrootpkg: Update comments to point out the bad hacks 2013-05-11 12:26:21 +02:00
Jan Alexander Steffens (heftig)
38692e8d74 archbuild: Correct makechrootpkg argument order
The user-passed makechrootpkg_args may contain a "--" to pass
arguments to makepkg. In this case, the order is wrong.
2013-05-11 12:26:21 +02:00
Jan Alexander Steffens (heftig)
a5bc6acf32 arch-nspawn: Quiet systemd-nspawn again
systemd-nspawn always outputs some debug messages over stderr.
Both stdout and stderr from inside the chroot are sent through
a pty to stdout.
2013-05-11 12:26:20 +02:00
Jan Alexander Steffens (heftig)
4937422fcf makechrootpkg: Split out chrootbuild into a function
Now syntax highlighting works properly! :D
2013-05-11 12:26:16 +02:00
Jan Alexander Steffens (heftig)
4dcdbcaf1e makechrootpkg: Ensure we have a writable PKGBUILD
For pkgver updates.
2013-05-06 01:51:06 +02:00
Jan Alexander Steffens (heftig)
1489f75419 arch-nspawn: setarch to CARCH
Allows calling makechrootpkg without worrying about the architecture
2013-05-06 01:50:05 +02:00
Jan Alexander Steffens (heftig)
7ca4eb82dd makechrootpkg: Avoid parsing PKGBUILD and support VCS sources
- Ensure sources are available before entering chroot
 - Bind STARTDIR and SRCDEST into the chroot read-only
 - Refactor makechrootpkg and introduce meaningful functions

Avoids copying stuff from/to the chroot as much as possible. With
VCS sources these copies can get quite expensive.
2013-05-03 08:48:14 +02:00
Jan Alexander Steffens (heftig)
abba9f07a6 makechrootpkg: Remove add_to_db feature
I don't think this is much use in our common workflow. Our pacman
configs don't even make a reference to /repo.
2013-05-03 04:34:29 +02:00
Jan Alexander Steffens (heftig)
a7a05deb37 lib/common.sh: Introduce locking helper functions
Reduces code duplication.

With makechrootpkg not calling mkarchroot anymore,
the lock handover protocol is unneeded.

arch-nspawn does not do any locking, so add protection to archbuild.
2013-05-03 04:34:29 +02:00
Jan Alexander Steffens (heftig)
0e98bd8c48 arch-nspawn: Set machine name
Recent changes to systemd-nspawn have it take the machine name from
the chroot dir name, which isn't unique enough for our setup.
2013-05-03 04:34:29 +02:00
Jan Alexander Steffens (heftig)
453558c4bb mkarchroot: Refactor chroot running into a new script
Separates the two features of mkarchroot. Provides users of the new
arch-nspawn with the full feature set of systemd-nspawn.

For example, this can be used to bind custom directories into the chroot.
2013-05-02 10:33:24 +02:00
17 changed files with 471 additions and 387 deletions

1
.gitignore vendored
View File

@@ -15,3 +15,4 @@ rebuildpkgs
zsh_completion zsh_completion
find-libdeps find-libdeps
crossrepomove crossrepomove
arch-nspawn

View File

@@ -1,4 +1,4 @@
V=20130408 V=20131020
PREFIX = /usr/local PREFIX = /usr/local
@@ -13,9 +13,8 @@ BINPROGS = \
finddeps \ finddeps \
rebuildpkgs \ rebuildpkgs \
find-libdeps \ find-libdeps \
crossrepomove crossrepomove\
arch-nspawn \
SBINPROGS = \
mkarchroot \ mkarchroot \
makechrootpkg makechrootpkg
@@ -68,7 +67,7 @@ BASHCOMPLETION_LINKS = \
archco \ archco \
communityco communityco
all: $(BINPROGS) $(SBINPROGS) bash_completion zsh_completion all: $(BINPROGS) bash_completion zsh_completion
edit = sed -e "s|@pkgdatadir[@]|$(DESTDIR)$(PREFIX)/share/devtools|g" edit = sed -e "s|@pkgdatadir[@]|$(DESTDIR)$(PREFIX)/share/devtools|g"
@@ -78,16 +77,15 @@ edit = sed -e "s|@pkgdatadir[@]|$(DESTDIR)$(PREFIX)/share/devtools|g"
@m4 -P $@.in | $(edit) >$@ @m4 -P $@.in | $(edit) >$@
@chmod a-w "$@" @chmod a-w "$@"
@chmod +x "$@" @chmod +x "$@"
@bash -O extglob -n "$@"
clean: clean:
rm -f $(BINPROGS) $(SBINPROGS) bash_completion zsh_completion rm -f $(BINPROGS) bash_completion zsh_completion
install: install:
install -dm0755 $(DESTDIR)$(PREFIX)/bin install -dm0755 $(DESTDIR)$(PREFIX)/bin
install -dm0755 $(DESTDIR)$(PREFIX)/sbin
install -dm0755 $(DESTDIR)$(PREFIX)/share/devtools install -dm0755 $(DESTDIR)$(PREFIX)/share/devtools
install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin
install -m0755 ${SBINPROGS} $(DESTDIR)$(PREFIX)/sbin
install -m0644 ${CONFIGFILES} $(DESTDIR)$(PREFIX)/share/devtools install -m0644 ${CONFIGFILES} $(DESTDIR)$(PREFIX)/share/devtools
for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)$(PREFIX)/bin/$$l; done for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)$(PREFIX)/bin/$$l; done
for l in ${ARCHBUILD_LINKS}; do ln -sf archbuild $(DESTDIR)$(PREFIX)/bin/$$l; done for l in ${ARCHBUILD_LINKS}; do ln -sf archbuild $(DESTDIR)$(PREFIX)/bin/$$l; done
@@ -100,7 +98,6 @@ install:
uninstall: uninstall:
for f in ${BINPROGS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$f; done for f in ${BINPROGS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$f; done
for f in ${SBINPROGS}; do rm -f $(DESTDIR)$(PREFIX)/sbin/$$f; done
for f in ${CONFIGFILES}; do rm -f $(DESTDIR)$(PREFIX)/share/devtools/$$f; done for f in ${CONFIGFILES}; do rm -f $(DESTDIR)$(PREFIX)/share/devtools/$$f; done
for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done
for l in ${ARCHBUILD_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done for l in ${ARCHBUILD_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done

104
arch-nspawn.in Normal file
View File

@@ -0,0 +1,104 @@
#!/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.
m4_include(lib/common.sh)
CHROOT_VERSION='v3'
working_dir=''
usage() {
echo "Usage: ${0##*/} [options] working-dir [systemd-nspawn arguments]"
echo "A wrapper around systemd-nspawn. Provides support for pacman."
echo
echo ' options:'
echo ' -C <file> Location of a pacman config file'
echo ' -M <file> Location of a makepkg config file'
echo ' -c <dir> Set pacman cache'
echo ' -h This message'
exit 1
}
while getopts 'hC:M:c:' arg; do
case "$arg" in
C) pac_conf="$OPTARG" ;;
M) makepkg_conf="$OPTARG" ;;
c) cache_dir="$OPTARG" ;;
h|?) usage ;;
*) error "invalid argument '$arg'"; usage ;;
esac
done
shift $(($OPTIND - 1))
(( $EUID != 0 )) && die 'This script must be run as root.'
(( $# < 1 )) && die 'You must specify a directory.'
working_dir=$(readlink -f "$1")
shift 1
[[ -z $working_dir ]] && die 'Please specify a working directory.'
if [[ -z $cache_dir ]]; then
cache_dirs=($(pacman -v 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g'))
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 == *file://* ]] && host_mirror_path=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g')
# {{{ functions
build_mount_args() {
declare -g mount_args=()
if [[ -n $host_mirror_path ]]; then
mount_args+=(--bind-ro="$host_mirror_path")
fi
mount_args+=(--bind="${cache_dirs[0]}")
for cache_dir in ${cache_dirs[@]:1}; do
mount_args+=(--bind-ro="$cache_dir")
done
}
copy_hostconf () {
cp -a /etc/pacman.d/gnupg "$working_dir/etc/pacman.d"
echo "Server = $host_mirror" >"$working_dir/etc/pacman.d/mirrorlist"
[[ -n $pac_conf ]] && cp $pac_conf "$working_dir/etc/pacman.conf"
[[ -n $makepkg_conf ]] && cp $makepkg_conf "$working_dir/etc/makepkg.conf"
sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${cache_dirs[@]})|g" -i "$working_dir/etc/pacman.conf"
}
# }}}
umask 0022
# Sanity check
if [[ ! -f "$working_dir/.arch-chroot" ]]; then
die "'%s' does not appear to be a Arch chroot." "$working_dir"
elif [[ $(cat "$working_dir/.arch-chroot") != $CHROOT_VERSION ]]; then
die "chroot '%s' is not at version %s. Please rebuild." "$working_dir" "$CHROOT_VERSION"
fi
build_mount_args
copy_hostconf
eval $(grep '^CARCH=' "$working_dir/etc/makepkg.conf")
machine_name="${working_dir//[![:alnum:]_-]/-}"
machine_name="${machine_name#-}"
exec ${CARCH:+setarch "$CARCH"} systemd-nspawn 2>/dev/null \
-D "$working_dir" \
--machine "$machine_name" \
"${mount_args[@]}" \
"$@"

View File

@@ -51,12 +51,7 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then
[[ -d $copy ]] || continue [[ -d $copy ]] || continue
msg2 "Deleting chroot copy '$(basename "${copy}")'..." msg2 "Deleting chroot copy '$(basename "${copy}")'..."
exec 9>"$copydir.lock" lock 9 "$copydir.lock" "Locking chroot copy '$copy'"
if ! flock -n 9; then
stat_busy "Locking chroot copy '$copy'"
flock 9
stat_done
fi
if [[ "$(stat -f -c %T "${copy}")" == btrfs ]]; then if [[ "$(stat -f -c %T "${copy}")" == btrfs ]]; then
{ type -P btrfs && btrfs subvolume delete "${copy}"; } &>/dev/null { type -P btrfs && btrfs subvolume delete "${copy}"; } &>/dev/null
@@ -73,12 +68,13 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then
"${chroots}/${repo}-${arch}/root" \ "${chroots}/${repo}-${arch}/root" \
"${base_packages[@]}" || abort "${base_packages[@]}" || abort
else else
setarch ${arch} mkarchroot \ lock 9 "${chroots}/${repo}-${arch}/root.lock" "Locking clean chroot"
-u \ arch-nspawn \
-C "@pkgdatadir@/pacman-${repo}.conf" \ -C "@pkgdatadir@/pacman-${repo}.conf" \
-M "@pkgdatadir@/makepkg-${arch}.conf" \ -M "@pkgdatadir@/makepkg-${arch}.conf" \
"${chroots}/${repo}-${arch}/root" || abort "${chroots}/${repo}-${arch}/root" \
pacman -Syu --noconfirm || abort
fi fi
msg "Building in chroot for [${repo}] (${arch})..." msg "Building in chroot for [${repo}] (${arch})..."
exec setarch "${arch}" makechrootpkg "${makechrootpkg_args[@]}" -r "${chroots}/${repo}-${arch}" exec makechrootpkg -r "${chroots}/${repo}-${arch}" "${makechrootpkg_args[@]}"

View File

@@ -15,7 +15,7 @@ case $scriptname in
communityco) communityco)
SVNURL="svn+ssh://svn-community@nymeria.archlinux.org/srv/repos/svn-community/svn";; SVNURL="svn+ssh://svn-community@nymeria.archlinux.org/srv/repos/svn-community/svn";;
*) *)
die "Couldn't find svn url for $scriptname" die "Couldn't find svn url for %s" "$scriptname"
;; ;;
esac esac

View File

@@ -8,8 +8,8 @@ FORCE=
while getopts ':f' flag; do while getopts ':f' flag; do
case $flag in case $flag in
f) FORCE=1 ;; f) FORCE=1 ;;
:) die "Option requires an argument -- '$OPTARG'" ;; :) die "Option requires an argument -- '%s'" "$OPTARG" ;;
\?) die "Invalid option -- '$OPTARG'" ;; \?) die "Invalid option -- '%s'" "$OPTARG" ;;
esac esac
done done
shift $(( OPTIND - 1 )) shift $(( OPTIND - 1 ))
@@ -23,7 +23,7 @@ fi
if [[ -z $FORCE ]]; then if [[ -z $FORCE ]]; then
for tag in "$@"; do for tag in "$@"; do
if ! in_array "$tag" "${_tags[@]}"; then if ! in_array "$tag" "${_tags[@]}"; then
die 'archrelease: Invalid tag: "'$tag'" (use -f to force release)' die "archrelease: Invalid tag: '%s' (use -f to force release)" "$tag"
fi fi
done done
fi fi

View File

@@ -34,7 +34,7 @@ _makechrootpkg() {
case $cur in case $cur in
-*) -*)
COMPREPLY=( $( compgen -W '-I -c -d -h -l -r -u' -- "$cur" ) ) COMPREPLY=( $( compgen -W '-I -c -h -l -r -u' -- "$cur" ) )
;; ;;
*) *)
_filedir _filedir
@@ -53,7 +53,7 @@ _mkarchroot() {
case $cur in case $cur in
-*) -*)
COMPREPLY=( $( compgen -W '-C -M -c -h -n -r -u' -- "$cur" ) ) COMPREPLY=( $( compgen -W '-C -M -c -h' -- "$cur" ) )
;; ;;
*) *)
_filedir _filedir
@@ -65,5 +65,22 @@ _mkarchroot() {
} && } &&
complete -F _mkarchroot mkarchroot complete -F _mkarchroot mkarchroot
_arch-nspawn() {
local cur
COMPREPLY=()
_get_comp_words_by_ref cur
case $cur in
-*)
COMPREPLY=( $( compgen -W '-C -M -c -h' -- "$cur" ) )
;;
*)
_filedir
return 0
;;
esac
true
} &&
complete -F _arch-nspawn arch-nspawn
# ex:et ts=2 sw=2 ft=sh # ex:et ts=2 sw=2 ft=sh

View File

@@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
shopt -s extglob
m4_include(lib/common.sh) m4_include(lib/common.sh)
# Source makepkg.conf; fail if it is not found # Source makepkg.conf; fail if it is not found
@@ -18,22 +20,24 @@ if [[ ! -f PKGBUILD ]]; then
die 'This must be run in the directory of a built package.' die 'This must be run in the directory of a built package.'
fi fi
. PKGBUILD . ./PKGBUILD
if [[ $arch == 'any' ]]; then if [[ $arch == 'any' ]]; then
CARCH='any' CARCH='any'
fi fi
STARTDIR=$(pwd) STARTDIR=$(pwd)
TEMPDIR=$(mktemp -d --tmpdir checkpkg-script.XXXX) TEMPDIR=$(mktemp -d --tmpdir checkpkg-script.XXXX)
cd "$TEMPDIR"
for _pkgname in "${pkgname[@]}"; do for _pkgname in "${pkgname[@]}"; do
pkgfile=${_pkgname}-$(get_full_version $_pkgname)-${CARCH}${PKGEXT} pkgfile=(${_pkgname}-$(get_full_version $_pkgname)-${CARCH}.pkg.tar?(.?z))
if (( ${#pkgfile[*]} != 1 )); then
die 'Ambiguous package name: %s\n' "${pkgfile[*]}"
fi
if [[ -f "$STARTDIR/$pkgfile" ]]; then if [[ -f "$STARTDIR/$pkgfile" ]]; then
ln -s "$STARTDIR/$pkgfile" "$pkgfile" ln -s "$STARTDIR/$pkgfile" "$TEMPDIR/$pkgfile"
elif [[ -f "$PKGDEST/$pkgfile" ]]; then elif [[ -f "$PKGDEST/$pkgfile" ]]; then
ln -s "$PKGDEST/$pkgfile" "$pkgfile" ln -s "$PKGDEST/$pkgfile" "$TEMPDIR/$pkgfile"
else else
die "File \"$pkgfile\" doesn't exist" die "File \"$pkgfile\" doesn't exist"
fi fi
@@ -41,13 +45,13 @@ for _pkgname in "${pkgname[@]}"; do
pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname") pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname")
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
die "Couldn't download previous package for $_pkgname." die "Couldn't download previous package for %s." "$_pkgname"
fi fi
oldpkg=${pkgurl##*://*/} oldpkg=${pkgurl##*://*/}
if [[ ${oldpkg##*/} = ${pkgfile##*/} ]]; then if [[ ${oldpkg##*/} = ${pkgfile##*/} ]]; then
die "The built package ($_pkgname) is the one in the repo right now!" die "The built package (%s) is the one in the repo right now!" "$_pkgname"
fi fi
if [[ ! -f $oldpkg ]]; then if [[ ! -f $oldpkg ]]; then
@@ -58,23 +62,21 @@ for _pkgname in "${pkgname[@]}"; do
elif [[ -f "$STARTDIR/$oldpkg" ]]; then elif [[ -f "$STARTDIR/$oldpkg" ]]; then
ln -s "$STARTDIR/$oldpkg" "$oldpkg" ln -s "$STARTDIR/$oldpkg" "$oldpkg"
else else
curl -fsLC - --retry 3 --retry-delay 3 -o "$oldpkg" "$pkgurl" curl -fsLC - --retry 3 --retry-delay 3 -o "$oldpkg" "$pkgurl"
fi fi
fi fi
bsdtar tf "$oldpkg" | sort > "filelist-$_pkgname-old" bsdtar tf "$oldpkg" | sort > "$TEMPDIR/filelist-$_pkgname-old"
bsdtar tf "$pkgfile" | sort > "filelist-$_pkgname" bsdtar tf "$pkgfile" | sort > "$TEMPDIR/filelist-$_pkgname"
sdiff -s "filelist-$_pkgname-old" "filelist-$_pkgname" sdiff -s "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname"
if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then if diff "$TEMPDIR/filelist-$_pkgname"{-old,} | grep '\.so' &>/dev/null; then
mkdir -p pkg mkdir -p "$TEMPDIR/pkg"
cd pkg bsdtar -C "$TEMPDIR" xf ../"$pkgfile" #> /dev/null
bsdtar xf ../"$pkgfile" > /dev/null diff "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do
diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do
echo "${i}: " "$(objdump -p "$i" | grep SONAME)" echo "${i}: " "$(objdump -p "$i" | grep SONAME)"
done done
cd ..
else else
msg "No soname differences for $_pkgname." msg "No soname differences for $_pkgname."
fi fi

View File

@@ -36,7 +36,7 @@ if [[ ! -f PKGBUILD ]]; then
die 'No PKGBUILD file' die 'No PKGBUILD file'
fi fi
. PKGBUILD . ./PKGBUILD
pkgbase=${pkgbase:-$pkgname} pkgbase=${pkgbase:-$pkgname}
case "$cmd" in case "$cmd" in
@@ -58,7 +58,7 @@ esac
# check if all local source files are under version control # check if all local source files are under version control
for s in "${source[@]}"; do for s in "${source[@]}"; do
if [[ $s != *://* ]] && ! svn status -v "$s@" | grep -q '^[ AMRX~]'; then if [[ $s != *://* ]] && ! svn status -v "$s@" | grep -q '^[ AMRX~]'; then
die "$s is not under version control" die "%s is not under version control" "$s"
fi fi
done done
@@ -68,7 +68,7 @@ for i in 'changelog' 'install'; do
# evaluate any bash variables used # evaluate any bash variables used
eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
if ! svn status -v "${file}" | grep -q '^[ AMRX~]'; then if ! svn status -v "${file}" | grep -q '^[ AMRX~]'; then
die "${file} is not under version control" die "%s is not under version control" "$file"
fi fi
done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
done done
@@ -81,8 +81,8 @@ while getopts ':l:a:s:f' flag; do
s) server=$OPTARG ;; s) server=$OPTARG ;;
l) rsyncopts+=("--bwlimit=$OPTARG") ;; l) rsyncopts+=("--bwlimit=$OPTARG") ;;
a) commit_arch=$OPTARG ;; a) commit_arch=$OPTARG ;;
:) die "Option requires an argument -- '$OPTARG'" ;; :) die "Option requires an argument -- '%s'" "$OPTARG" ;;
\?) die "Invalid option -- '$OPTARG'" ;; \?) die "Invalid option -- '%s'" "$OPTARG" ;;
esac esac
done done
shift $(( OPTIND - 1 )) shift $(( OPTIND - 1 ))
@@ -164,7 +164,7 @@ for _arch in ${arch[@]}; do
gpg --detach-sign --use-agent ${SIGNWITHKEY} "${pkgfile}" || die gpg --detach-sign --use-agent ${SIGNWITHKEY} "${pkgfile}" || die
fi fi
if ! gpg --verify "$sigfile" >/dev/null 2>&1; then if ! gpg --verify "$sigfile" >/dev/null 2>&1; then
die "Signature ${pkgfile}.sig is incorrect!" die "Signature %s.sig is incorrect!" "$pkgfile"
fi fi
uploads+=("$sigfile") uploads+=("$sigfile")
done done

View File

@@ -25,12 +25,11 @@ case $scriptname in
target_repo='extra' target_repo='extra'
;; ;;
*) *)
die "Couldn't find configuration for $scriptname" die "Couldn't find configuration for %s" "$scriptname"
;; ;;
esac esac
server='nymeria.archlinux.org' server='nymeria.archlinux.org'
mirror="http://${server}"
source_svn="svn+ssh://svn-${source_name}@${server}/srv/repos/svn-${source_name}/svn" source_svn="svn+ssh://svn-${source_name}@${server}/srv/repos/svn-${source_name}/svn"
target_svn="svn+ssh://svn-${target_name}@${server}/srv/repos/svn-${target_name}/svn" target_svn="svn+ssh://svn-${target_name}@${server}/srv/repos/svn-${target_name}/svn"
source_dbscripts="/srv/repos/svn-${source_name}/dbscripts" source_dbscripts="/srv/repos/svn-${source_name}/dbscripts"
@@ -55,10 +54,8 @@ for _arch in ${arch[@]}; do
fi fi
for _pkgname in ${pkgname[@]}; do for _pkgname in ${pkgname[@]}; do
fullver=$(get_full_version $_pkgname) fullver=$(get_full_version $_pkgname)
# FIXME: this only works with .xz packages pkgpath="/srv/ftp/$source_repo/os/$repo_arch/$_pkgname-$fullver-${_arch}.pkg.tar.*"
ssh "${server}" "cd staging/${target_repo} ssh "$server" "cp $pkgpath staging/$target_repo" || die
curl -O ${mirror}/${source_repo}/os/${repo_arch}/$_pkgname-$fullver-${_arch}.pkg.tar.xz
curl -O ${mirror}/${source_repo}/os/${repo_arch}/$_pkgname-$fullver-${_arch}.pkg.tar.xz.sig" || die
done done
done done

View File

@@ -16,7 +16,7 @@ script_mode=${0##*/find-lib}
case $script_mode in case $script_mode in
deps|provides) true;; deps|provides) true;;
*) die "Unknown mode $script_mode" ;; *) die "Unknown mode %s" "$script_mode" ;;
esac esac
if [[ -z $1 ]]; then if [[ -z $1 ]]; then

View File

@@ -82,7 +82,7 @@ trap_exit() {
} }
die() { die() {
error "$*" (( $# )) && error "$@"
cleanup 1 cleanup 1
} }
@@ -130,3 +130,27 @@ get_full_version() {
fi fi
fi fi
} }
##
# usage : lock( $fd, $file, $message )
##
lock() {
eval "exec $1>"'"$2"'
if ! flock -n $1; then
stat_busy "$3"
flock $1
stat_done
fi
}
##
# usage : slock( $fd, $file, $message )
##
slock() {
eval "exec $1>"'"$2"'
if ! flock -sn $1; then
stat_busy "$3"
flock -s $1
stat_done
fi
}

View File

@@ -12,12 +12,11 @@ m4_include(lib/common.sh)
shopt -s nullglob shopt -s nullglob
makepkg_args='-s --noconfirm -L' makepkg_args='-s --noconfirm -L --holdver'
repack=false repack=false
update_first=false update_first=false
clean_first=false clean_first=false
install_pkg= install_pkg=
add_to_db=false
run_namcap=false run_namcap=false
temp_chroot=false temp_chroot=false
chrootdir= chrootdir=
@@ -25,6 +24,9 @@ passeddir=
declare -a install_pkgs declare -a install_pkgs
declare -i ret=0 declare -i ret=0
bindmounts_ro=()
bindmounts_rw=()
copy=$USER copy=$USER
[[ -n $SUDO_USER ]] && copy=$SUDO_USER [[ -n $SUDO_USER ]] && copy=$SUDO_USER
[[ -z "$copy" || $copy = root ]] && copy=copy [[ -z "$copy" || $copy = root ]] && copy=copy
@@ -49,10 +51,11 @@ usage() {
echo 'Flags:' echo 'Flags:'
echo '-h This help' echo '-h This help'
echo '-c Clean the chroot before building' echo '-c Clean the chroot before building'
echo '-d <dir> Bind directory into build chroot as read-write'
echo '-D <dir> Bind directory into build chroot as read-only'
echo '-u Update the working copy of 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 ' This is useful for rebuilds without dirtying the pristine'
echo ' chroot' echo ' chroot'
echo '-d Add the package to a local db at /repo after building'
echo '-r <dir> The chroot dir to use' echo '-r <dir> The chroot dir to use'
echo '-I <pkg> Install a package into the working copy of the chroot' 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 '-l <copy> The directory to use as the working copy of the chroot'
@@ -63,23 +66,33 @@ usage() {
exit 1 exit 1
} }
while getopts 'hcudr:I:l:nT' arg; do while getopts 'hcur:I:l:nTD:d:' arg; do
case "$arg" in case "$arg" in
h) usage ;; h) usage ;;
c) clean_first=true ;; c) clean_first=true ;;
D) bindmounts_ro+=(--bind-ro="$OPTARG") ;;
d) bindmounts_rw+=(--bind="$OPTARG") ;;
u) update_first=true ;; u) update_first=true ;;
d) add_to_db=true ;;
r) passeddir="$OPTARG" ;; r) passeddir="$OPTARG" ;;
I) install_pkgs+=("$OPTARG") ;; I) install_pkgs+=("$OPTARG") ;;
l) copy="$OPTARG" ;; l) copy="$OPTARG" ;;
n) run_namcap=true; makepkg_args="$makepkg_args -i" ;; n) run_namcap=true; makepkg_args="$makepkg_args -i" ;;
T) temp_chroot=true; copy+="-$RANDOM" ;; T) temp_chroot=true; copy+="-$$" ;;
*) makepkg_args="$makepkg_args -$arg $OPTARG" ;; *) makepkg_args="$makepkg_args -$arg $OPTARG" ;;
esac esac
done done
(( EUID != 0 )) && die 'This script must be run as root.'
[[ ! -f PKGBUILD && -z "${install_pkgs[*]}" ]] && die 'This must be run in a directory containing a PKGBUILD.'
# Canonicalize chrootdir, getting rid of trailing / # Canonicalize chrootdir, getting rid of trailing /
chrootdir=$(readlink -e "$passeddir") chrootdir=$(readlink -e "$passeddir")
[[ ! -d $chrootdir ]] && die "No chroot dir defined, or invalid path '%s'" "$passeddir"
[[ ! -d $chrootdir/root ]] && die "Missing chroot dir root directory. Try using: mkarchroot %s/root base-devel" "$chrootdir"
# Detect chrootdir filesystem type
chroottype=$(stat -f -c %T "$chrootdir")
if [[ ${copy:0:1} = / ]]; then if [[ ${copy:0:1} = / ]]; then
copydir=$copy copydir=$copy
@@ -98,239 +111,271 @@ for arg in ${*:$OPTIND}; do
fi fi
done done
if (( EUID )); then if [[ -n $SUDO_USER ]]; then
die 'This script must be run as root.' USER_HOME=$(eval echo ~$SUDO_USER)
else
USER_HOME=$HOME
fi fi
if [[ ! -f PKGBUILD && -z "${install_pkgs[*]}" ]]; then # {{{ functions
die 'This must be run in a directory containing a PKGBUILD.' load_vars() {
fi local makepkg_conf="$1" var
if [[ ! -d $chrootdir ]]; then [[ -f $makepkg_conf ]] || return 1
die "No chroot dir defined, or invalid path '$passeddir'"
fi
if [[ ! -d $chrootdir/root ]]; then for var in {SRC,PKG,LOG}DEST MAKEFLAGS PACKAGER; do
die "Missing chroot dir root directory. Try using: mkarchroot $chrootdir/root base-devel" [[ -z ${!var} ]] && eval $(grep "^${var}=" "$makepkg_conf")
fi done
umask 0022 return 0
}
# Detect chrootdir filesystem type create_chroot() {
chroottype=$(stat -f -c %T "$chrootdir") # Lock the chroot we want to use. We'll keep this lock until we exit.
lock 9 "$copydir.lock" "Locking chroot copy [$copy]"
# Lock the chroot we want to use. We'll keep this lock until we exit. if [[ ! -d $copydir ]] || $clean_first; then
# Note this is the same FD number as in mkarchroot # Get a read lock on the root chroot to make
exec 9>"$copydir.lock" # sure we don't clone a half-updated chroot
if ! flock -n 9; then slock 8 "$chrootdir/root.lock" "Locking clean chroot"
stat_busy "Locking chroot copy [$copy]"
flock 9
stat_done
fi
if [[ ! -d $copydir ]] || $clean_first; then stat_busy "Creating clean working copy [$copy]"
# Get a read lock on the root chroot to make if [[ "$chroottype" == btrfs ]]; then
# sure we don't clone a half-updated chroot if [[ -d $copydir ]]; then
exec 8>"$chrootdir/root.lock" btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume %s" "$copydir"
if ! flock -sn 8; then fi
stat_busy "Locking clean chroot" btrfs subvolume snapshot "$chrootdir/root" "$copydir" >/dev/null ||
flock -s 8 die "Unable to create subvolume %s" "$copydir"
stat_done else
fi mkdir -p "$copydir"
rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir"
stat_busy "Creating clean working copy [$copy]"
if [[ "$chroottype" == btrfs ]]; then
if [[ -d $copydir ]]; then
btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume $copydir"
fi fi
btrfs subvolume snapshot "$chrootdir/root" "$copydir" >/dev/null || stat_done
die "Unable to create subvolume $copydir"
else # Drop the read lock again
mkdir -p "$copydir" exec 8>&-
rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir"
fi fi
}
clean_temporary() {
stat_busy "Removing temporary copy [$copy]"
if [[ "$chroottype" == btrfs ]]; then
btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume %s" "$copydir"
else
# avoid change of filesystem in case of an umount failure
rm --recursive --force --one-file-system "$copydir" ||
die "Unable to delete %s" "$copydir"
fi
# remove lock file
rm -f "$copydir.lock"
stat_done stat_done
}
# Drop the read lock again install_packages() {
exec 8>&- local pkgname
fi
if [[ -n "${install_pkgs[*]}" ]]; then
for install_pkg in "${install_pkgs[@]}"; do for install_pkg in "${install_pkgs[@]}"; do
pkgname="${install_pkg##*/}" pkgname="${install_pkg##*/}"
cp "$install_pkg" "$copydir/$pkgname" cp "$install_pkg" "$copydir/$pkgname"
mkarchroot -r "pacman -U /$pkgname --noconfirm" "$copydir" arch-nspawn "$copydir" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
pacman -U /$pkgname --noconfirm
(( ret += !! $? )) (( ret += !! $? ))
rm "$copydir/$pkgname" rm "$copydir/$pkgname"
done done
# If there is no PKGBUILD we have done # If there is no PKGBUILD we are done
[[ -f PKGBUILD ]] || exit $ret [[ -f PKGBUILD ]] || exit $ret
fi }
$update_first && mkarchroot -u "$copydir" prepare_chroot() {
$repack || rm -rf "$copydir/build"
mkdir -p "$copydir/build" mkdir -p "$copydir/build"
if ! grep -q 'BUILDDIR="/build"' "$copydir/etc/makepkg.conf"; then
# Remove anything in there UNLESS -R (repack) was passed to makepkg echo 'BUILDDIR="/build"' >> "$copydir/etc/makepkg.conf"
$repack || rm -rf "$copydir"/build/*
# Read .makepkg.conf and .gnupg/pubring.gpg even if called via sudo
if [[ -n $SUDO_USER ]]; then
SUDO_HOME="$(eval echo ~$SUDO_USER)"
makepkg_conf="$SUDO_HOME/.makepkg.conf"
if [[ -r "$SUDO_HOME/.gnupg/pubring.gpg" ]]; then
install -D "$SUDO_HOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg"
fi fi
else
makepkg_conf="$HOME/.makepkg.conf" # Read .makepkg.conf and .gnupg/pubring.gpg even if called via sudo
if [[ -r "$HOME/.gnupg/pubring.gpg" ]]; then if [[ -r "$USER_HOME/.gnupg/pubring.gpg" ]]; then
install -D "$HOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg" install -D "$USER_HOME/.gnupg/pubring.gpg" \
"$copydir/build/.gnupg/pubring.gpg"
fi fi
fi
# Get SRC/PKGDEST from makepkg.conf mkdir -p "$copydir/pkgdest"
if [[ -f $makepkg_conf ]]; then if ! grep -q 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf"; then
eval $(grep '^SRCDEST=' "$makepkg_conf") echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf"
eval $(grep '^PKGDEST=' "$makepkg_conf") fi
eval $(grep '^MAKEFLAGS=' "$makepkg_conf")
eval $(grep '^PACKAGER=' "$makepkg_conf")
fi
[[ -z $SRCDEST ]] && eval $(grep '^SRCDEST=' /etc/makepkg.conf) mkdir -p "$copydir/logdest"
[[ -z $PKGDEST ]] && eval $(grep '^PKGDEST=' /etc/makepkg.conf) if ! grep -q 'LOGDEST="/logdest"' "$copydir/etc/makepkg.conf"; then
[[ -z $MAKEFLAGS ]] && eval $(grep '^MAKEFLAGS=' /etc/makepkg.conf) echo 'LOGDEST="/logdest"' >> "$copydir/etc/makepkg.conf"
[[ -z $PACKAGER ]] && eval $(grep '^PACKAGER=' /etc/makepkg.conf) fi
# Use PKGBUILD directory if PKGDEST or SRCDEST don't exist # These two get bind-mounted read-only
[[ -d $PKGDEST ]] || PKGDEST=. # XXX: makepkg dislikes having these dirs read-only, so separate them
[[ -d $SRCDEST ]] || SRCDEST=. 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
mkdir -p "$copydir/pkgdest" chown -R nobody "$copydir"/{build,pkgdest,logdest,srcdest,startdir}
if ! grep -q 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf"; then
echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf"
fi
mkdir -p "$copydir/srcdest" if [[ -n $MAKEFLAGS ]]; then
if ! grep -q 'SRCDEST="/srcdest"' "$copydir/etc/makepkg.conf"; then sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf"
echo 'SRCDEST="/srcdest"' >> "$copydir/etc/makepkg.conf" echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf"
fi fi
if [[ -n $MAKEFLAGS ]]; then if [[ -n $PACKAGER ]]; then
sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf" sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf"
echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf"
fi fi
if [[ -n $PACKAGER ]]; then if [[ ! -f $copydir/etc/sudoers.d/nobody-pacman ]]; then
sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf" cat > "$copydir/etc/sudoers.d/nobody-pacman" <<EOF
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
cp PKGBUILD "$copydir/build/"
(
source PKGBUILD
for file in "${source[@]}"; do
file="${file%%::*}"
file="${file##*://*/}"
if [[ -f $file ]]; then
cp "$file" "$copydir/srcdest/"
elif [[ -f $SRCDEST/$file ]]; then
cp "$SRCDEST/$file" "$copydir/srcdest/"
fi
done
# Find all changelog and install files, even inside functions
for i in 'changelog' 'install'; do
while read -r file; do
# evaluate any bash variables used
eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
[[ -f $file ]] && cp "$file" "$copydir/build/"
done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
done
)
chown -R nobody "$copydir"/{build,pkgdest,srcdest}
cat > "$copydir/etc/sudoers.d/nobody-pacman" <<EOF
Defaults env_keep += "HOME" Defaults env_keep += "HOME"
nobody ALL = NOPASSWD: /usr/bin/pacman nobody ALL = NOPASSWD: /usr/bin/pacman
EOF EOF
chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" chmod 440 "$copydir/etc/sudoers.d/nobody-pacman"
fi
# This is a little gross, but this way the script is recreated every time in the # This is a little gross, but this way the script is recreated every time in the
# working copy # working copy
cat >"$copydir/chrootbuild" <<EOF printf $'#!/bin/bash\n%s\n_chrootbuild %q %q' "$(declare -f _chrootbuild)" \
#!/bin/bash "$makepkg_args" "$run_namcap" >"$copydir/chrootbuild"
. /etc/profile chmod +x "$copydir/chrootbuild"
export HOME=/build }
cd /build download_sources() {
sudo -u nobody makepkg $makepkg_args || exit 1 local builddir="$(mktemp -d)"
chmod 1777 "$builddir"
if $run_namcap; then # Ensure sources are downloaded
pacman -S --needed --noconfirm namcap if [[ -n $SUDO_USER ]]; then
for pkgfile in /build/PKGBUILD /pkgdest/*.pkg.tar.?z; do sudo -u $SUDO_USER env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \
echo "Checking \${pkgfile##*/}" makepkg --config="$copydir/etc/makepkg.conf" --verifysource -o
sudo -u nobody namcap "\$pkgfile" 2>&1 | tee "/build/\${pkgfile##*/}-namcap.log" else
( export SRCDEST BUILDDIR="$builddir"
makepkg --asroot --config="$copydir/etc/makepkg.conf" --verifysource -o
)
fi
(( $? != 0 )) && die "Could not download sources."
# Clean up garbage from verifysource
rm -rf $builddir
}
_chrootbuild() {
# This function isn't run in makechrootpkg,
# so no global variables
local makepkg_args="$1"
local run_namcap="$2"
. /etc/profile
export HOME=/build
shopt -s nullglob
# XXX: Workaround makepkg disliking read-only dirs
ln -sft /srcdest /srcdest_host/*
ln -sft /startdir /startdir_host/*
# XXX: Keep svn sources writable
# Since makepkg 4.1.1 they get checked out via cp -a, copying the symlink
for dir in /srcdest /startdir; do
cd $dir
for svndir in */.svn; do
rm ${svndir%/.svn}
cp -a ${dir}_host/${svndir%/.svn} .
chown -R nobody ${svndir%/.svn}
done
done done
fi
exit 0 cd /startdir
EOF
chmod +x "$copydir/chrootbuild"
if mkarchroot -r "/chrootbuild" "$copydir"; then # XXX: Keep PKGBUILD writable for pkgver()
for pkgfile in "$copydir"/pkgdest/*.pkg.tar.?z; do rm PKGBUILD*
if $add_to_db; then cp /startdir_host/PKGBUILD* .
mkdir -p "$copydir/repo" chown nobody PKGBUILD*
pushd "$copydir/repo" >/dev/null
cp "$pkgfile" .
repo-add repo.db.tar.gz "${pkgfile##*/}"
popd >/dev/null
fi
# Safety check
if [[ ! -w PKGBUILD ]]; then
echo "Can't write to PKGBUILD!"
exit 1
fi
sudo -u nobody makepkg $makepkg_args || exit 1
if $run_namcap; then
pacman -S --needed --noconfirm namcap
for pkgfile in /startdir/PKGBUILD /pkgdest/*; do
echo "Checking ${pkgfile##*/}"
sudo -u nobody namcap "$pkgfile" 2>&1 | tee "/logdest/${pkgfile##*/}-namcap.log"
done
fi
exit 0
}
move_products() {
for pkgfile in "$copydir"/pkgdest/*; do
chown "$src_owner" "$pkgfile" chown "$src_owner" "$pkgfile"
mv "$pkgfile" "$PKGDEST" mv "$pkgfile" "$PKGDEST"
done done
for l in "$copydir"/build/*-{build,check,namcap,package,package_*}.log; do for l in "$copydir"/logdest/*; do
chown "$src_owner" "$l" chown "$src_owner" "$l"
[[ -f $l ]] && mv "$l" . mv "$l" "$LOGDEST"
done done
}
# }}}
umask 0022
load_vars "$USER_HOME/.makepkg.conf"
load_vars /etc/makepkg.conf
# Use PKGBUILD directory if these don't exist
[[ -d $PKGDEST ]] || PKGDEST=$PWD
[[ -d $SRCDEST ]] || SRCDEST=$PWD
[[ -d $LOGDEST ]] || LOGDEST=$PWD
create_chroot
$update_first && arch-nspawn "$copydir" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
pacman -Syu --noconfirm
[[ -n ${install_pkgs[*]} ]] && install_packages
prepare_chroot
download_sources
if arch-nspawn "$copydir" \
--bind-ro="$PWD:/startdir_host" \
--bind-ro="$SRCDEST:/srcdest_host" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootbuild
then
move_products
else else
# Just in case. We returned 1, make sure we fail (( ret += 1 ))
ret=1
fi fi
for f in "$copydir"/srcdest/*; do $temp_chroot && clean_temporary
chown "$src_owner" "$f"
mv "$f" "$SRCDEST"
done
if $temp_chroot; then if (( ret != 0 )); then
stat_busy "Removing temporary directoy [$copy]" if $temp_chroot; then
if [[ "$chroottype" == btrfs ]]; then die "Build failed"
btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume $copydir"
else else
# avoid change of filesystem in case of an umount failure die "Build failed, check %s/build" "$copydir"
rm --recursive --force --one-file-system "$copydir" ||
die "Unable to delete $copydir"
fi fi
# remove lock file
rm --force "$copydir.lock"
stat_done
elif (( ret != 0 )); then
die "Build failed, check $copydir/build"
else else
true true
fi fi

View File

@@ -67,7 +67,7 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
# These are default values for the options=() settings # These are default values for the options=() settings
######################################################################### #########################################################################
# #
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug) # Default: OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
# A negated option will do the opposite of the comments below. # A negated option will do the opposite of the comments below.
# #
#-- strip: Strip symbols from binaries/libraries #-- strip: Strip symbols from binaries/libraries
@@ -80,7 +80,7 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
#-- upx: Compress binary executable files using UPX #-- upx: Compress binary executable files using UPX
#-- debug: Add debugging flags as specified in DEBUG_* variables #-- debug: Add debugging flags as specified in DEBUG_* variables
# #
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug) OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512 #-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5) INTEGRITY_CHECK=(md5)
@@ -109,6 +109,8 @@ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#SRCDEST=/home/sources #SRCDEST=/home/sources
#-- Source packages: specify a fixed directory where all src packages will be placed #-- Source packages: specify a fixed directory where all src packages will be placed
#SRCPKGDEST=/home/srcpackages #SRCPKGDEST=/home/srcpackages
#-- Log files: specify a fixed directory where all log files will be placed
#LOGDEST=/home/makepkglogs
#-- Packager: name/email of the person or organization building packages #-- Packager: name/email of the person or organization building packages
#PACKAGER="John Doe <john@doe.com>" #PACKAGER="John Doe <john@doe.com>"
#-- Specify a key to use for package signing #-- Specify a key to use for package signing

View File

@@ -67,7 +67,7 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
# These are default values for the options=() settings # These are default values for the options=() settings
######################################################################### #########################################################################
# #
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug) # Default: OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
# A negated option will do the opposite of the comments below. # A negated option will do the opposite of the comments below.
# #
#-- strip: Strip symbols from binaries/libraries #-- strip: Strip symbols from binaries/libraries
@@ -80,7 +80,7 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
#-- upx: Compress binary executable files using UPX #-- upx: Compress binary executable files using UPX
#-- debug: Add debugging flags as specified in DEBUG_* variables #-- debug: Add debugging flags as specified in DEBUG_* variables
# #
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug) OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512 #-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5) INTEGRITY_CHECK=(md5)
@@ -109,6 +109,8 @@ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#SRCDEST=/home/sources #SRCDEST=/home/sources
#-- Source packages: specify a fixed directory where all src packages will be placed #-- Source packages: specify a fixed directory where all src packages will be placed
#SRCPKGDEST=/home/srcpackages #SRCPKGDEST=/home/srcpackages
#-- Log files: specify a fixed directory where all log files will be placed
#LOGDEST=/home/makepkglogs
#-- Packager: name/email of the person or organization building packages #-- Packager: name/email of the person or organization building packages
#PACKAGER="John Doe <john@doe.com>" #PACKAGER="John Doe <john@doe.com>"
#-- Specify a key to use for package signing #-- Specify a key to use for package signing

View File

@@ -12,53 +12,33 @@ m4_include(lib/common.sh)
CHROOT_VERSION='v3' CHROOT_VERSION='v3'
RUN=''
NOCOPY='n'
working_dir='' working_dir=''
APPNAME=$(basename "${0}")
# usage: usage <exitvalue>
usage() { usage() {
echo "Usage: ${APPNAME} [options] working-dir [package-list | app]" echo "Usage: ${0##*/} [options] working-dir [package-list | app]"
echo ' options:' echo ' options:'
echo ' -r <app> Run "app" within the context of the chroot'
echo ' -u Update the chroot via pacman'
echo ' -C <file> Location of a pacman config file' echo ' -C <file> Location of a pacman config file'
echo ' -M <file> Location of a makepkg config file' echo ' -M <file> Location of a makepkg config file'
echo ' -n Do not copy config files into the chroot'
echo ' -c <dir> Set pacman cache' echo ' -c <dir> Set pacman cache'
echo ' -h This message' echo ' -h This message'
exit 1 exit 1
} }
while getopts 'r:ufnhC:M:c:' arg; do while getopts 'hC:M:c:' arg; do
case "${arg}" in case "$arg" in
r) RUN="$OPTARG" ;;
u) RUN='pacman -Syu --noconfirm' ;;
C) pac_conf="$OPTARG" ;; C) pac_conf="$OPTARG" ;;
M) makepkg_conf="$OPTARG" ;; M) makepkg_conf="$OPTARG" ;;
n) NOCOPY='y' ;;
c) cache_dir="$OPTARG" ;; c) cache_dir="$OPTARG" ;;
h|?) usage ;; h|?) usage ;;
*) error "invalid argument '${arg}'"; usage ;; *) error "invalid argument '$arg'"; usage ;;
esac esac
done done
if (( $EUID != 0 )); then
die 'This script must be run as root.'
fi
shift $(($OPTIND - 1)) shift $(($OPTIND - 1))
if [[ -z $RUN ]] && (( $# < 2 )); then (( $EUID != 0 )) && die 'This script must be run as root.'
die 'You must specify a directory and one or more packages.' (( $# < 2 )) && die 'You must specify a directory and one or more packages.'
elif (( $# < 1 )); then
die 'You must specify a directory.'
fi
working_dir="$(readlink -f ${1})" working_dir="$(readlink -f $1)"
shift 1 shift 1
[[ -z $working_dir ]] && die 'Please specify a working directory.' [[ -z $working_dir ]] && die 'Please specify a working directory.'
@@ -69,117 +49,31 @@ else
cache_dirs=(${cache_dir}) cache_dirs=(${cache_dir})
fi fi
host_mirror=$(pacman -Sddp extra/devtools 2>/dev/null | sed -E 's#(.*/)extra/os/.*#\1$repo/os/$arch#')
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
build_mount_args() {
local p
declare -g mount_args=()
if [[ -n $host_mirror_path ]]; then
printf -v p '%q' "$host_mirror_path"
mount_args+=(--bind-ro="$p")
fi
printf -v p '%q' "${cache_dirs[0]}"
mount_args+=(--bind="$p")
for cache_dir in ${cache_dirs[@]:1}; do
printf -v p '%q' "$cache_dir"
mount_args+=(--bind-ro="$p")
done
}
copy_hostconf () {
cp -a /etc/pacman.d/gnupg "${working_dir}/etc/pacman.d"
echo "Server = ${host_mirror}" > ${working_dir}/etc/pacman.d/mirrorlist
if [[ -n $pac_conf && $NOCOPY = 'n' ]]; then
cp ${pac_conf} ${working_dir}/etc/pacman.conf
fi
if [[ -n $makepkg_conf && $NOCOPY = 'n' ]]; then
cp ${makepkg_conf} ${working_dir}/etc/makepkg.conf
fi
sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${cache_dirs[@]})|g" -i ${working_dir}/etc/pacman.conf
}
chroot_lock () {
# Only reopen the FD if it wasn't handed to us
if [[ $(readlink -f /dev/fd/9) != "${working_dir}.lock" ]]; then
exec 9>"${working_dir}.lock"
fi
# Lock the chroot. Take note of the FD number.
if ! flock -n 9; then
stat_busy "Locking chroot"
flock 9
stat_done
fi
}
chroot_run() {
local dir=$1
shift
systemd-nspawn -D "${dir}" "${mount_args[@]}" -- ${@} 2>/dev/null
}
# }}}
umask 0022 umask 0022
if [[ -n $RUN ]]; then
# run chroot {{{ [[ -e $working_dir ]] && die "Working directory '%s' already exists" "$working_dir"
#Sanity check
if [[ ! -f "${working_dir}/.arch-chroot" ]]; then mkdir -p "$working_dir"
die "'${working_dir}' does not appear to be a Arch chroot."
elif [[ $(cat "${working_dir}/.arch-chroot") != ${CHROOT_VERSION} ]]; then lock 9 "${working_dir}.lock" "Locking chroot"
die "'${working_dir}' is not compatible with ${APPNAME} version ${CHROOT_VERSION}. Please rebuild."
if [[ $(stat -f -c %T "$working_dir") == btrfs ]]; then
rmdir "$working_dir"
if ! btrfs subvolume create "$working_dir"; then
die "Couldn't create subvolume for '%s'" "$working_dir"
fi fi
chmod 0755 "$working_dir"
chroot_lock
build_mount_args
copy_hostconf
chroot_run "${working_dir}" ${RUN}
# }}}
else
# {{{ build chroot
if [[ -e $working_dir ]]; then
die "Working directory '${working_dir}' already exists"
fi
mkdir -p "${working_dir}"
if [[ "$(stat -f -c %T "${working_dir}")" == btrfs ]]; then
rmdir "${working_dir}"
if ! btrfs subvolume create "${working_dir}"; then
die "Couldn't create subvolume for '${working_dir}'"
fi
chmod 0755 "${working_dir}"
fi
chroot_lock
pacargs=("${cache_dirs[@]/#/--cachedir=}")
if [[ -n $pac_conf ]]; then
pacargs+=("--config=${pac_conf}")
fi
if ! pacstrap -GMcd "${working_dir}" "${pacargs[@]}" "$@"; then
die 'Failed to install all packages'
fi
printf '%s.UTF-8 UTF-8\n' en_US de_DE > "${working_dir}/etc/locale.gen"
chroot_run "${working_dir}" locale-gen
echo 'LANG=C' > "${working_dir}/etc/locale.conf"
copy_hostconf
echo "${CHROOT_VERSION}" > "${working_dir}/.arch-chroot"
# }}}
fi fi
pacstrap -GMcd ${pac_conf:+-C "$pac_conf"} "$working_dir" \
"${cache_dirs[@]/#/--cachedir=}" "$@" || die 'Failed to install all packages'
printf '%s.UTF-8 UTF-8\n' en_US de_DE > "$working_dir/etc/locale.gen"
echo 'LANG=C' > "$working_dir/etc/locale.conf"
echo "$CHROOT_VERSION" > "$working_dir/.arch-chroot"
exec arch-nspawn \
${pac_conf:+-C "$pac_conf"} \
${makepkg_conf:+-M "$makepkg_conf"} \
${cache_dir:+-c "$cache_dir"} \
"$working_dir" locale-gen

View File

@@ -1,4 +1,4 @@
#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 multilib-staging-build=archbuild kde-unstable-i686-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-i686-build=archbuild gnome-unstable-x86_64-build=archbuild communityco=archco #compdef archbuild archco arch-nspawn 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 multilib-staging-build=archbuild kde-unstable-i686-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-i686-build=archbuild gnome-unstable-x86_64-build=archbuild communityco=archco
m4_include(lib/valid-tags.sh) m4_include(lib/valid-tags.sh)
@@ -11,6 +11,13 @@ _archco_args=(
'*:packages:_devtools_completions_all_packages' '*:packages:_devtools_completions_all_packages'
) )
_arch_nspawn_args=(
'-C[Location of a pacman config file]:pacman_config:_files'
'-M[Location of a makepkg config file]:makepkg_config:_files'
'-c[Set pacman cache]:pacman_cache:_files -/'
'-h[Display usage]'
)
_archrelease_args=( _archrelease_args=(
"*:arch:($_tags[*])" "*:arch:($_tags[*])"
) )
@@ -32,7 +39,6 @@ _finddeps_args=(
_makechrootpkg_args=( _makechrootpkg_args=(
'-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"' '-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"'
'-c[Clean the chroot before building]' '-c[Clean the chroot before building]'
'-d[Add the package to a local db at /repo after building]'
'-h[Display usage]' '-h[Display usage]'
'-l[The directory to use as the working copy]:copy_dir:_files -/' '-l[The directory to use as the working copy]:copy_dir:_files -/'
'-r[The chroot dir to use]:chroot_dir:_files -/' '-r[The chroot dir to use]:chroot_dir:_files -/'
@@ -40,11 +46,8 @@ _makechrootpkg_args=(
) )
_mkarchroot_args=( _mkarchroot_args=(
'-r[Run a program within the context of the chroot]:app'
'-u[Update the chroot via pacman]'
'-C[Location of a pacman config file]:pacman_config:_files' '-C[Location of a pacman config file]:pacman_config:_files'
'-M[Location of a makepkg config file]:makepkg_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 -/' '-c[Set pacman cache]:pacman_cache:_files -/'
'-h[Display usage]' '-h[Display usage]'
) )
@@ -61,7 +64,7 @@ _devtools_completions_all_packages() {
} }
_devtools() { _devtools() {
local argname="_${service}_args[@]" local argname="_${service//-/_}_args[@]"
_arguments -s "${(P)argname}" _arguments -s "${(P)argname}"
} }