mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-22 04:17:44 +00:00
5d0b9b3789
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
415 lines
12 KiB
Bash
Executable File
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
|