1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-22 04:17:44 +00:00
freebsd-ports/Tools/portbuild/scripts/buildscript
Kris Kennaway 5d0b9b3789 * Remove vestiges of procfs mounting/umounting from here; we have to
do it in portbuild from outside the jail thesedays

* Ignore /var/db/fontconfig which does not get restored to pristine state

* Save copies of master.passwd and groups and check them after the build
  for changes, to look for user/group additions that may not be correctly
  registered in UIDs/GIDs.  Future work will hopefully automatically
  check against those files and make unregistered IDs a fatal condition

* Correct logic mistake that was keeping distfiles for collection when
  the checksum mismatched
2007-07-29 19:35:00 +00:00

415 lines
12 KiB
Bash
Executable File

#!/bin/sh
# usage: $0 DIRNAME PHASE
# PHASE is 1 (checksum) or 2 (package)
cleanup() {
status=$1
# Don't keep distfiles if 'make checksum' failed
keep_distfiles=$(make -V ALWAYS_KEEP_DISTFILES)
if [ ${status} -eq 1 -o -z "${keep_distfiles}" ]; then
cd ${dir}
distdir=$(make -V DISTDIR)
if [ ! -z "${distdir}" ]; then
rm -rf ${distdir}/*
fi
fi
if [ -e ${dir}/.keep ]; then
cd ${dir}
objdir=$(make -V WRKDIR)
tar cfjC /tmp/work.tbz ${objdir}/.. work
fi
if [ ${status} -gt 0 ]; then
cat /tmp/make.log${status}
fi
echo 1 > /tmp/status
touch /.dirty
echo "================================================================"
echo -n "build of ${dir} ended at "
date
exit 0
}
add_pkg() {
pkgs=$*
echo add_pkg $pkgs
cd /tmp/depends
export PKG_PATH=/tmp/depends
if [ ! -z "${pkgs}" ]; then
arch=$(uname -m)
echo "adding dependencies"
for i in $pkgs; do
echo "pkg_add $i"
base=$(basename $i .tgz)
base=$(basename $base .tbz)
if pkg_info -q -e $base; then
echo "skipping $base, already added"
else
if ! pkg_add $i; then
echo "error in dependency $i, exiting"
cleanup 0
fi
fi
done
fi
}
del_pkg() {
pkgs=$*
cd /tmp/depends
export PKG_PATH=/tmp/depends
if [ ! -z "${pkgs}" ]; then
recursion=1
dellist=""
while [ $recursion -eq 1 ]; do
unset delpkg nextpkg
recursion=0
for i in $pkgs; do
base=$(basename $i .tgz)
base=$(basename $base .tbz)
if [ -s /var/db/pkg/${base}/+REQUIRED_BY ]; then
recursion=1
nextpkg="${base} ${nextpkg}"
elif [ -d /var/db/pkg/${base}/ ]; then
delpkg="${base} ${delpkg}"
fi
done
pkgs="${nextpkg}"
if [ "$dellist" != "" -a "$dellist" = "$delpkg" ]; then
echo "deleted list =\""$dellist"\", packages to delete ="\"$delpkg\"
echo "The following packages were left behind (perhaps your dependency list is incomplete):"
ls /var/db/pkg
echo "error in pkg_delete, exiting"
cleanup 0
else
for j in ${delpkg}; do
echo "Deleting ${j}"
if ! (pkg_delete -f $j); then
echo "--> error in pkg_delete, exiting"
cleanup 0
fi
done
dellist=$delpkg
fi
done
fi
}
dir=$1
phase=$2
ED=$3
PD=$4
FD=$5
BD=$6
RD=$7
export PATH=/pkg/libexec/ccache/:$PATH
export CCACHE_PATH=/usr/bin:/usr/local/bin
export MALLOC_OPTIONS=AJ
L=`echo ${LOCALBASE} | sed 's,^/,,'`
X=`echo ${X11BASE} | sed 's,^/,,'`
if [ $phase = 1 ]; then
cd $dir || exit 1
echo "building for: $(uname -mr)"
echo "maintained by: $(make maintainer)"
echo "port directory: ${dir}"
echo "build started at $(date)"
echo "FETCH_DEPENDS=${FD}"
echo "PATCH_DEPENDS=${PD}"
echo "EXTRACT_DEPENDS=${ED}"
echo "BUILD_DEPENDS=${BD}"
echo "RUN_DEPENDS=${RD}"
echo "prefixes: LOCALBASE=${L} X11BASE=${X}"
#Allow ports to notice they're being run on bento
export PACKAGE_BUILDING=1
# Stash a copy of /etc/master.passwd and /etc/group to detect whether someone modifies it
cp /etc/master.passwd /etc/master.passwd-save
cp /etc/group /etc/group-save
# Files we do not care about changing between pre-build and post-cleanup
cat > /tmp/mtree.preexclude <<EOF
./root/*
./var/*
./tmp/*
./etc/make.conf.bak
./etc/make.conf
./work/*
./compat/linux/proc
./usr/share/man/cat*/*
./usr/local/etc/apache
./usr/local/etc/apache2
./usr/local/news
./usr/local/share/xml
./usr/X11R6/etc/gconf
./usr/local/etc/gconf
./var/db/fontconfig
EOF
# Record a "pristine" mtree.
mtree -X /tmp/mtree.preexclude -xcn -k uid,gid,mode -p / > /tmp/mtree.pristine
add_pkg $FD
cd $dir || exit 1
pkgname=$(make package-name)
echo "================================================================"
echo "====================<phase 1: make checksum>===================="
if /pnohang $TIMEOUT /tmp/make.log1 ${pkgname} make checksum; then
cat /tmp/make.log1
echo "0" > /tmp/status
else
cleanup 1
fi
else
cd $dir || exit 1
pkgname=$(make package-name)
echo "================================================================"
echo "====================<phase 2: make extract>===================="
add_pkg ${ED}
cd $dir
/pnohang $TIMEOUT /tmp/make.log2 ${pkgname} make extract || cleanup 2
cat /tmp/make.log2
del_pkg ${ED}
# Fetch depends still need to be here for 'make extract' since that target
# always reruns 'make fetch' due to the lack of fetch cookie (and no place
# to put it since WRKDIR isn't created by 'make fetch')
del_pkg $FD
echo "================================================================"
echo "====================<phase 3: make patch>===================="
add_pkg ${PD}
cd $dir
/pnohang $TIMEOUT /tmp/make.log3 ${pkgname} make patch || cleanup 3
cat /tmp/make.log3
del_pkg ${PD}
echo "================================================================"
echo "====================<phase 4: make build>===================="
add_pkg ${BD}
# Files we do not care about changing between pre-build and post-cleanup
cat > /tmp/mtree.buildexclude <<EOF
./var/log/*
./tmp/*
./work/*
./compat/linux/proc
./root/*
./var/mail/*
./var/tmp/*
./usr/share/man/cat*/*
./usr/local/etc/apache
./usr/local/etc/apache2
./usr/local/news
./usr/local/share/xml
./usr/X11R6/etc/gconf
./usr/local/etc/gconf
./var/db/fontconfig
EOF
# Record a "pristine" mtree.
mtree -X /tmp/mtree.buildexclude -xcn -k uid,gid,mode -p / > /tmp/mtree.prebuild
xvfb=0
if which -s Xvfb; then
xvfb=1
pid=$(echo $$ % 32768 | bc)
X11BASE=$(which Xvfb | sed -e 's./bin/Xvfb..')
Xvfb :${pid} -fp ${X11BASE}/lib/X11/fonts/misc &
DISPLAY=${JAIL_ADDR}:${pid}
export DISPLAY
fi
cd $dir
/pnohang $TIMEOUT /tmp/make.log4 ${pkgname} make build || cleanup 4
cat /tmp/make.log4
echo "================================================================"
echo "====================<phase 5: make test>===================="
cd $dir
/pnohang $TIMEOUT /tmp/make.log5 ${pkgname} make -k regression-test
cat /tmp/make.log5
mtree -X /tmp/mtree.buildexclude -x -f /tmp/mtree.prebuild -p / | egrep -v "^(${L}/var|${X}/lib/X11/xserver/SecurityPolicy|${L}/share/nls/POSIX|${L}/share/nls/en_US.US-ASCII|etc/services|compat |${X} |etc/manpath.config|etc/.*.bak|${L}/info/dir|${X}/lib/X11/fonts/.*/fonts\.|usr/(X11R6|local)/man/..( |/man. )|${X}/lib/X11/fonts/TrueType|${X}/etc/gconf/gconf.xml.defaults/%gconf-tree.*.xml|${L}/etc/gconf/gconf.xml.defaults/%gconf-tree.*.xml|var/db/fontconfig/* )" > /tmp/list.preinstall
if [ -s /tmp/list.preinstall ]; then
echo "================================================================"
echo "Fatal error: filesystem was touched prior to 'make install' phase"
cat /tmp/list.preinstall
echo "================================================================"
cleanup 0
fi
echo "================================================================"
echo "====================<phase 6: make install>===================="
add_pkg ${RD}
cat > /tmp/mtree.exclude <<EOF
./root/*
./var/*
./tmp/*
./etc/make.conf.bak
./etc/make.conf
./work/*
./compat/linux/proc
EOF
mtree -X /tmp/mtree.exclude -xcn -k uid,gid,mode -p / > /tmp/mtree
cd $dir
if /pnohang $TIMEOUT /tmp/make.log6 ${pkgname} make install; then
cat /tmp/make.log6
echo "0" > /tmp/status
else
cleanup 6
fi
echo "================================================================"
echo "====================<phase 7: make package>===================="
cd $dir
if /pnohang $TIMEOUT /tmp/make.log7 ${pkgname} make package; then
cat /tmp/make.log7
echo "0" > /tmp/status
prefix=$(make -V PREFIX)
del_pkg ${pkgname}
else
cleanup 7
fi
mtree -X /tmp/mtree.exclude -x -f /tmp/mtree -p / | egrep -v "^(${L}/var|${X}/lib/X11/xserver/SecurityPolicy|${L}/share/nls/POSIX|${L}/share/nls/en_US.US-ASCII|etc/services|compat |${X} |etc/manpath.config|etc/.*.bak|${L}/info/dir|${X}/lib/X11/fonts/.*/fonts\.|usr/(X11R6|local)/man/..( |/man. )|${X}/lib/X11/fonts/TrueType|${X}/etc/gconf/gconf.xml.defaults/%gconf-tree.*.xml|${L}/etc/gconf/gconf.xml.defaults/%gconf-tree.*.xml|var/db/fontconfig/* )" > /tmp/list3
# Compare the state of the filesystem now to before the 'make install' phase
dirty=0
if [ -s /tmp/list3 ]; then
cd /
grep ' extra$' /tmp/list3 | awk '{print $1}' | xargs -J % find % -ls > /tmp/list4
grep ' missing$' /tmp/list3 > /tmp/list5
grep -vE ' (extra|missing)$' /tmp/list3 > /tmp/list6
if [ "x${NOPLISTCHECK}" = "x" ]; then
if grep -vqE "($X|$L)/etc/" /tmp/list4; then
echo "1" > /tmp/status
dirty=1
fi
if [ -s /tmp/list5 -o -s /tmp/list6 ]; then
echo "1" > /tmp/status
dirty=1
fi
fi
echo "================================================================"
fi
echo
echo "=== Checking filesystem state"
if [ -s /tmp/list4 ]; then
echo "list of extra files and directories in / (not present before this port was installed but present after it was deinstalled)"
cat /tmp/list4
fi
if [ -s /tmp/list5 ]; then
echo "list of files present before this port was installed but missing after it was deinstalled)"
cat /tmp/list5
fi
if [ -s /tmp/list6 ]; then
echo "list of filesystem changes from before and after port installation and deinstallation"
cat /tmp/list6
fi
if [ "${dirty}" = 1 ]; then
cleanup 0
fi
# BUILD_DEPENDS and RUN_DEPENDS are both present at install-time (e.g. gmake)
# Concatenate and remove duplicates
BRD=$(echo $BD $RD | tr ' ' '\n' | sort -u | tr '\n' ' ')
del_pkg ${BRD}
cd /var/db/pkg
if [ $(echo $(echo * | wc -c)) != 2 ]; then
echo "leftover packages:" *
del_pkg *
echo "1" > /tmp/status
cleanup 0
fi
# Compare the state of the filesystem now to clean system (should again be clean)
mtree -X /tmp/mtree.preexclude -x -f /tmp/mtree.pristine -p / | egrep -v "^(${L}/var|${X}/lib/X11/xserver/SecurityPolicy|${L}/share/nls/POSIX|${L}/share/nls/en_US.US-ASCII|etc/services|compat |${X} |etc/manpath.config|etc/.*.bak|${L}/info/dir|${X}/lib/X11/fonts/.*/fonts\.|usr/(X11R6|local)/man/..( |/man. )|${X}/lib/X11/fonts/TrueType )" > /tmp/list3
echo
echo "=== Checking filesystem state after all packages deleted"
if [ -s /tmp/list3 ]; then
cd /
grep ' extra$' /tmp/list3 | awk '{print $1}' | xargs -J % find % -ls > /tmp/list4
grep ' missing$' /tmp/list3 > /tmp/list5
grep -vE ' (extra|missing)$' /tmp/list3 > /tmp/list6
if [ "x${NOPLISTCHECK}" = "x" ]; then
if grep -vqE "($X|$L)/etc/" /tmp/list4; then
#echo "1" > /tmp/status
fi
if [ -s /tmp/list5 ]; then
#echo "1" > /tmp/status
fi
fi
echo "================================================================"
if [ -s /tmp/list4 ]; then
echo "list of extra files and directories in / (not present on clean system but present after everything was deinstalled)"
cat /tmp/list4
touch /.dirty
fi
if [ -s /tmp/list5 ]; then
echo "list of files present on clean system but missing after everything was deinstalled)"
cat /tmp/list5
touch /.dirty
fi
if [ -s /tmp/list6 ]; then
echo "list of filesystem changes from before and after all port installation/deinstallation"
cat /tmp/list6
touch /.dirty
fi
fi
cmp /etc/group /etc/group-save || (echo "=== /etc/group was modified:"; diff -du /etc/group-save /etc/group)
cmp /etc/master.passwd /etc/master.passwd-save || (echo "=== /etc/master.passwd was modified:"; diff -du /etc/master.passwd-save /etc/master.passwd)
if [ ${xvfb} = 1 ]; then
kill $(jobid %1)
fi
cd ${dir}
keep_distfiles=$(make -V ALWAYS_KEEP_DISTFILES)
distdir=$(make -V DISTDIR)
if [ -z "${keep_distfiles}" -a ! -z "${distdir}" ]; then
rm -rf ${distdir}/*
fi
if [ -e ${dir}/.keep ]; then
cd ${dir}
objdir=$(make -V WRKDIR)
tar cfjC /tmp/work.tbz ${objdir}/.. work
fi
echo "================================================================"
echo -n "build of ${dir} ended at "
date
fi
exit 0