summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorAntoine Jacoutot <ajacoutot@cvs.openbsd.org>2009-05-11 20:25:56 +0000
committerAntoine Jacoutot <ajacoutot@cvs.openbsd.org>2009-05-11 20:25:56 +0000
commit32cc4c9570d443ae860506d8b9a2f593775c995f (patch)
treebb0fd26f81afb7084f1456061cd4cdaf01d76b78 /usr.sbin
parent37e4db5e282d06b63e893529d44ba3e137606c2a (diff)
This commit adds a new feature to sysmerge(8), usable in '-a' mode.
From now on, checksums of reference files (sets and/or src) will be stored under /var/db/sysmerge/{etcsum,xetcsum,srcsum} . This allows for "remembering last choice" several people have requested. This deprecates the need for -X and -S which have been removed (these switches may come back at some point for the auto-patch feature which halex@ proposed). It will only compare files which reference sources have changed since the last run and will attempt to automatically upgrade them to the newest version provided that they have no local changes. i.e. first run should dislay differences, second run should not display anything except if something changed between old and new sets/src. This way sysmerge can also warn you from files which may have been obsoleted. General idea taken from Net/FreeBSD but we're doing things differently. Intensively discussed with oga@, sthen@ and halex@ ok oga@ sthen@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/sysmerge/sysmerge.841
-rw-r--r--usr.sbin/sysmerge/sysmerge.sh186
2 files changed, 80 insertions, 147 deletions
diff --git a/usr.sbin/sysmerge/sysmerge.8 b/usr.sbin/sysmerge/sysmerge.8
index 46bd6fc210c..ca655384060 100644
--- a/usr.sbin/sysmerge/sysmerge.8
+++ b/usr.sbin/sysmerge/sysmerge.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysmerge.8,v 1.21 2009/04/12 07:43:17 ajacoutot Exp $
+.\" $OpenBSD: sysmerge.8,v 1.22 2009/05/11 20:25:55 ajacoutot Exp $
.\"
.\" Copyright (c) 2008 Antoine Jacoutot <ajacoutot@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 12 2009 $
+.Dd $Mdocdate: May 11 2009 $
.Dt SYSMERGE 8
.Os
.Sh NAME
@@ -24,9 +24,7 @@
.Nm
.Bk -words
.Op Fl ab
-.Op Fl S Ar etcXX.tgz
.Op Fl s Ar src \*(Ba etcXX.tgz
-.Op Fl X Ar xetcXX.tgz
.Op Fl x Ar xetcXX.tgz
.Ek
.Sh DESCRIPTION
@@ -103,7 +101,10 @@ The options are as follows:
Automatic mode.
If this option is specified,
.Nm
-will automatically install missing files
+will only compare files which reference sources have changed since
+the last run and will attempt to automatically upgrade them to the
+newest version provided that they have no local changes.
+It will automatically install missing files
and files differing only by CVS Id,
and will disable strict file comparison when possible (using CVS Id).
.Pa /etc/fbtab ,
@@ -122,38 +123,12 @@ If this option is specified,
.Nm
will run unattended (non-interactively), saving differing files for
later manual processing.
-.It Fl S Ar etcXX.tgz
-Specify a path to an
-etcXX.tgz tarball,
-where XX represents the version to be upgraded from.
-.Nm
-will attempt to automatically upgrade files from this version
-to the one specified by
-.Fl s ,
-provided that the file has no local changes.
-Files that have not been modified between the supplied tarballs will
-not be offered for comparison.
-A tarball path specified as an FTP or HTTP URL will be passed
-to ${FETCH_CMD}.
.It Fl s Ar src \*(Ba etcXX.tgz
Specify a path to an
.Ox
top src directory or an etcXX.tgz tarball.
A tarball path specified as an FTP or HTTP URL will be passed
to ${FETCH_CMD}.
-.It Fl X Ar xetcXX.tgz
-Specify a path to an
-xetcXX.tgz tarball,
-where XX represents the version to be upgraded from.
-.Nm
-will attempt to automatically upgrade files from this version
-to the one specified by
-.Fl x ,
-provided that the file has no local changes.
-Files that have not been modified between the supplied tarballs will
-not be offered for comparison.
-A tarball path specified as an FTP or HTTP URL will be passed
-to ${FETCH_CMD}.
.It Fl x Ar xetcXX.tgz
Specify a path to an
xetcXX.tgz tarball.
@@ -185,6 +160,10 @@ A special test was added to handle this
and they are offered for comparison only if they really differ.
.Sh ENVIRONMENT
.Bl -tag -width "DESTDIRXXX"
+.It Ev DBDIR
+Directory in which checksum files are stored.
+If unset, this defaults to
+.Pa /var/db/sysmerge .
.It Ev DESTDIR
Directory in which to merge and install files.
If unset, this defaults to
diff --git a/usr.sbin/sysmerge/sysmerge.sh b/usr.sbin/sysmerge/sysmerge.sh
index 7964a60ee54..d9bd10d4705 100644
--- a/usr.sbin/sysmerge/sysmerge.sh
+++ b/usr.sbin/sysmerge/sysmerge.sh
@@ -1,6 +1,6 @@
#!/bin/sh -
#
-# $OpenBSD: sysmerge.sh,v 1.39 2009/04/28 08:25:27 ajacoutot Exp $
+# $OpenBSD: sysmerge.sh,v 1.40 2009/05/11 20:25:55 ajacoutot Exp $
#
# This script is based on the FreeBSD mergemaster script, written by
# Douglas Barton <DougB@FreeBSD.org>
@@ -30,6 +30,7 @@ WRKDIR=`mktemp -d -p /var/tmp sysmerge.XXXXX` || exit 1
SWIDTH=`stty size | awk '{w=$2} END {if (w==0) {w=80} print w}'`
MERGE_CMD="${MERGE_CMD:=sdiff -as -w ${SWIDTH} -o}"
REPORT="${REPORT:=${WRKDIR}/sysmerge.log}"
+DBDIR="${DBDIR:=/var/db/sysmerge}"
EDITOR="${EDITOR:=/usr/bin/vi}"
PAGER="${PAGER:=/usr/bin/more}"
@@ -41,6 +42,14 @@ clean_src() {
fi
}
+# restore files from backups
+restore_bak() {
+ for i in ${DBDIR}/.*.bak; do
+ _i=`basename ${i} .bak`
+ mv ${i} ${DBDIR}/${_i#.}
+ done
+}
+
# remove newly created work directory and exit with status 1
error_rm_wrkdir() {
rmdir ${WRKDIR} 2> /dev/null
@@ -51,7 +60,7 @@ usage() {
echo "usage: ${0##*/} [-ab] [-S etcXX.tgz] [-s src | etcXX.tgz] [-X xetcXX.tgz] [-x xetcXX.tgz]" >&2
}
-trap "clean_src; rm -rf ${WRKDIR}; exit 1" 1 2 3 13 15
+trap "restore_bak; clean_src; rm -rf ${WRKDIR}; exit 1" 1 2 3 13 15
if [ "`id -u`" -ne 0 ]; then
echo " *** Error: need root privileges to run this script"
@@ -77,36 +86,6 @@ do_pre() {
fi
fi
- if [ "${OTGZ}" ]; then
- TGZV=`echo ${TGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'`
- OTGZV=`echo ${OTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'`
- if [ -z "${TGZ}" ]; then
- echo " *** Error: please specify a valid path to the new etcXX.tgz"
- error_rm_wrkdir
- elif cmp -s ${OTGZ} ${TGZ}; then
- echo " *** Error: old and new etcXX.tgz are identical"
- error_rm_wrkdir
- elif [ "${OTGZV}" -gt "${TGZV}" ]; then
- echo " *** Error: old etc${OTGZV}.tgz version is higher than new etc${TGZV}.tgz"
- error_rm_wrkdir
- fi
- fi
-
- if [ "${OXTGZ}" ]; then
- XTGZV=`echo ${XTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'`
- OXTGZV=`echo ${OXTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'`
- if [ -z "${XTGZ}" ]; then
- echo " *** Error: please specify a valid path to the new xetcXX.tgz"
- error_rm_wrkdir
- elif cmp -s ${OXTGZ} ${XTGZ}; then
- echo " *** Error: old and new xetcXX.tgz are identical"
- error_rm_wrkdir
- elif [ "${OXTGZV}" -gt "${XTGZV}" ]; then
- echo " *** Error: old xetc${OXTGZV}.tgz version is higher than new xetc${XTGZV}.tgz"
- error_rm_wrkdir
- fi
- fi
-
TEMPROOT="${WRKDIR}/temproot"
BKPDIR="${WRKDIR}/backups"
@@ -120,25 +99,12 @@ do_pre() {
elif [ "${SRCDIR}" ]; then
echo " etc source: ${SRCDIR}"
fi
- if [ "${OTGZURL}" ]; then
- echo " old etc source: ${OTGZURL}"
- echo " (fetched in ${OTGZ})"
- else
- [ "${OTGZ}" ] && echo " old etc source: ${OTGZ}"
- fi
- if [ "${OTGZ}" -o "${OXTGZ}" ]; then echo ""; fi
if [ "${XTGZURL}" ]; then
echo " xetc source: ${XTGZURL}"
echo " (fetched in ${XTGZ})"
else
[ "${XTGZ}" ] && echo " xetc source: ${XTGZ}"
fi
- if [ "${OXTGZURL}" ]; then
- echo " old xetc source: ${OXTGZURL}"
- echo " (fetched in ${OXTGZ})"
- else
- [ "${OXTGZ}" ] && echo " old xetc source: ${OXTGZ}"
- fi
echo ""
echo " base work directory: ${WRKDIR}"
echo " temp root directory: ${TEMPROOT}"
@@ -159,33 +125,67 @@ do_pre() {
do_populate() {
+ mkdir -p ${DBDIR} || error_rm_wrkdir
echo "===> Creating and populating temporary root under"
echo " ${TEMPROOT}"
mkdir -p ${TEMPROOT}
if [ "${SRCDIR}" ]; then
+ local SRCSUM=srcsum
cd ${SRCDIR}/etc
make DESTDIR=${TEMPROOT} distribution-etc-root-var > /dev/null 2>&1
+ (cd ${TEMPROOT} && find . -type f | xargs cksum >> ${WRKDIR}/${SRCSUM})
fi
if [ "${TGZ}" -o "${XTGZ}" ]; then
for i in ${TGZ} ${XTGZ}; do
tar -xzphf ${i} -C ${TEMPROOT};
done
+ if [ "${TGZ}" ]; then
+ local ETCSUM=etcsum
+ _E=$(cd `dirname ${TGZ}` && pwd)/`basename ${TGZ}`
+ (cd ${TEMPROOT} && tar -tzf ${_E} | xargs cksum >> ${WRKDIR}/${ETCSUM})
+ fi
+ if [ "${XTGZ}" ]; then
+ local XETCSUM=xetcsum
+ _X=$(cd `dirname ${XTGZ}` && pwd)/`basename ${XTGZ}`
+ (cd ${TEMPROOT} && tar -tzf ${_X} | xargs cksum >> ${WRKDIR}/${XETCSUM})
+ fi
fi
- if [ "${OTGZ}" -o "${OXTGZ}" ]; then
- OTEMPROOT="${WRKDIR}/.otemproot"
- mkdir -p ${OTEMPROOT}
- for i in ${OTGZ} ${OXTGZ}; do
- tar -xzphf ${i} -C ${OTEMPROOT};
- tar -tzf ${i} >> ${WRKDIR}/olist;
- done
- for i in ${TGZ} ${XTGZ}; do
- tar -tzf ${i} >> ${WRKDIR}/nlist;
- done
- OBSOLETE_FILES=`diff -C 0 ${WRKDIR}/olist ${WRKDIR}/nlist | grep -E '^- .' | sed -e 's,^- .,,g'`
- rm -f ${WRKDIR}/olist ${WRKDIR}/nlist
- fi
+ for i in ${SRCSUM} ${ETCSUM} ${XETCSUM}; do
+ if [ -f ${DBDIR}/${i} ]; then
+ # delete file in temproot if it has not changed since last release
+ # and is present in current installation
+ if [ "${AUTOMODE}" ]; then
+ _R=$(cd ${TEMPROOT} && cksum -c ${DBDIR}/${i} 2> /dev/null | grep OK | awk '{ print $2 }' | sed 's/[:]//')
+ for _r in ${_R}; do
+ if [ -f ${DESTDIR}/${_r} -a -f ${TEMPROOT}/${_r} ]; then
+ rm -f ${TEMPROOT}/${_r}
+ fi
+ done
+ fi
+
+ # set auto-upgradable files
+ _D=`diff -u ${WRKDIR}/${i} ${DBDIR}/${i} | grep -E '^\+' | sed '1d' | awk '{print $3}'`
+ for _d in ${_D}; do
+ CURSUM=$(cd ${DESTDIR:=/} && cksum ${_d} 2> /dev/null)
+ if [ -n "`grep "${CURSUM}" ${DBDIR}/${i}`" -a -z "`grep "${CURSUM}" ${WRKDIR}/${i}`" ]; then
+ set -A AUTO_UPG -- ${_d}
+ fi
+ done
+
+ # check for obsolete files
+ awk '{ print $3 }' ${DBDIR}/${i} > ${WRKDIR}/new
+ awk '{ print $3 }' ${WRKDIR}/${i} > ${WRKDIR}/old
+ if [ -n "`diff -q ${WRKDIR}/old ${WRKDIR}/new`" ]; then
+ OBSOLETE_FILES="${OBSOLETE_FILES} `diff -C 0 ${WRKDIR}/new ${WRKDIR}/old | grep -E '^- .' | sed -e 's,^- .,,g'`"
+ fi
+ rm ${WRKDIR}/new ${WRKDIR}/old
+
+ mv ${DBDIR}/${i} ${DBDIR}/.${i}.bak
+ fi
+ mv ${WRKDIR}/${i} ${DBDIR}/${i}
+ done
# files we don't want/need to deal with
IGNORE_FILES="/etc/*.db /etc/mail/*.db /etc/passwd /etc/motd /etc/myname /var/mail/root"
@@ -369,29 +369,22 @@ diff_loop() {
unset NO_INSTALLED
unset CAN_INSTALL
+ unset FORCE_UPG
while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "todo" ]; do
if [ "${HANDLE_COMPFILE}" = "v" ]; then
echo "\n========================================================================\n"
fi
if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
- # automatically install files which differ only by CVS Id
if [ "${AUTOMODE}" ]; then
- if diff -q -I'[$]OpenBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then
- if mm_install "${COMPFILE}"; then
- echo "===> ${COMPFILE} installed successfully"
- AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n"
- else
- echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand"
+ # automatically install files if current != new and current = old
+ for i in "${AUTO_UPG[@]}"; do
+ if [ "${i}" = "${COMPFILE}" ]; then
+ FORCE_UPG=1
fi
- return
- fi
- fi
- if [ "${OTGZ}" -o "${OXTGZ}" ]; then
- # if current != new and current = old, auto-install new
- if diff -q "${DESTDIR}${COMPFILE#.}" "${OTEMPROOT}${COMPFILE#.}" > /dev/null 2>&1; then
- echo "===> ${COMPFILE} has not been modified since previous release/snapshot,"
- echo " automatically installing new version"
+ done
+ # automatically install files which differ only by CVS Id
+ if [ -z "`diff -q -I'[$]OpenBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"`" -o -n "${FORCE_UPG}" ]; then
if mm_install "${COMPFILE}"; then
echo "===> ${COMPFILE} installed successfully"
AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n"
@@ -521,9 +514,6 @@ do_compare() {
# make sure files are different; if not, delete the one in temproot
if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then
rm "${COMPFILE}"
- # delete file in temproot if it has not changed since last release
- elif [ "${OTGZ}" -o "${OXTGZ}" ] && diff -q "${COMPFILE}" "${OTEMPROOT}${COMPFILE#.}" > /dev/null 2>&1; then
- rm "${COMPFILE}"
# xetcXX.tgz contains binary files; set IS_BINFILE to disable sdiff
elif diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" | grep "Binary" > /dev/null 2>&1; then
IS_BINFILE=1
@@ -540,9 +530,6 @@ do_compare() {
do_post() {
- clean_src
- rm -rf ${OTEMPROOT}
-
echo "===> Making sure your directory hierarchy has correct perms, running mtree"
mtree -qdef ${DESTDIR}/etc/mtree/4.4BSD.dist -p ${DESTDIR:=/} -U > /dev/null
@@ -564,7 +551,7 @@ do_post() {
echo "${BKPDIR}\n" >> ${REPORT}
fi
if [ "${OBSOLETE_FILES}" ]; then
- echo "===> File(s) removed from previous set (maybe obsolete)" >> ${REPORT}
+ echo "===> File(s) removed from previous source (maybe obsolete)" >> ${REPORT}
echo "${OBSOLETE_FILES}" >> ${REPORT}
fi
if [ "${FILES_IN_TEMPROOT}" ]; then
@@ -583,6 +570,9 @@ do_post() {
echo "===> Removing ${WRKDIR}"
rm -rf "${WRKDIR}"
fi
+
+ clean_src
+ rm -f ${DBDIR}/.*.bak
}
@@ -632,42 +622,6 @@ while getopts abs:x:S:X: arg; do
error_rm_wrkdir
fi
;;
- S)
- if [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \
- awk -F/ '{print $NF}' | \
- grep '^etc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then
- OTGZ=${OPTARG}
- elif echo ${OPTARG} | \
- grep -qE '^(http|ftp)://.*/etc[0-9][0-9]\.tgz$'; then
- OTGZ=${WRKDIR}/etc.tgz
- OTGZURL=${OPTARG}
- if ! ${FETCH_CMD} -o ${OTGZ} ${OTGZURL}; then
- echo " *** Error: could not retrieve ${OTGZURL}"
- error_rm_wrkdir
- fi
- else
- echo " *** Error: ${OPTARG} is not a path to etcXX.tgz"
- error_rm_wrkdir
- fi
- ;;
- X)
- if [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \
- awk -F/ '{print $NF}' | \
- grep '^xetc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then
- OXTGZ=${OPTARG}
- elif echo ${OPTARG} | \
- grep -qE '^(http|ftp)://.*/xetc[0-9][0-9]\.tgz$'; then
- OXTGZ=${WRKDIR}/xetc.tgz
- OXTGZURL=${OPTARG}
- if ! ${FETCH_CMD} -o ${OXTGZ} ${OXTGZURL}; then
- echo " *** Error: could not retrieve ${OXTGZURL}"
- error_rm_wrkdir
- fi
- else
- echo " *** Error: ${OPTARG} is not a path to xetcXX.tgz"
- error_rm_wrkdir
- fi
- ;;
*)
usage
error_rm_wrkdir