Add auto upgrade capability to mergemaster.

An mtree description of all non-zero files that make
distribution installs (only size and md5) is built from the
temproot.  When the user completes a mergemaster run, the
mtree description file gets installed into /var/db for
safe-keeping.

When the user then decides to do a subsequent upgrade (with
the -U flag), the existing mtree description from /var/db
is called into service looking for files that are different in
DESTDIR. This is stashed away until a file that would normally
end up prompting the user to look at changes is encountered.
Since there are no user modified changes, the new file is
installed without bothering the user.

Looked at by:	dougb
MFC after:	6 weeks
This commit is contained in:
Gordon Tetlow 2006-04-29 18:21:43 +00:00
parent deff04b4f7
commit 55a5ff0140
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158149
2 changed files with 88 additions and 1 deletions

View File

@ -242,6 +242,8 @@ Specify an alternative
architecture name.
.It Fl D Ar /path
Specify the destination directory for the installed files.
.It Fl U
Attempt to auto upgrade files that have not been user modified.
.El
.Sh ENVIRONMENT
The

View File

@ -35,6 +35,7 @@ display_usage () {
echo " -w N Specify a screen width in columns to sdiff"
echo " -A architecture Alternative architecture name to pass to make"
echo ' -D /path/directory Specify the destination directory to install files to'
echo " -U Attempt to auto upgrade files that have not been user modified."
echo ''
}
@ -112,6 +113,24 @@ diff_loop () {
while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \
"${HANDLE_COMPFILE}" = "NOT V" ]; do
if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
if [ -n "${AUTO_UPGRADE}" ]; then
if echo "${CHANGED}" | grep -qsv ${DESTDIR}${COMPFILE#.}; then
echo ''
echo " *** ${COMPFILE} has not been user modified."
echo ''
if mm_install "${COMPFILE}"; then
echo " *** ${COMPFILE} upgraded successfully"
echo ''
# Make the list print one file per line
AUTO_UPGRADED_FILES="${AUTO_UPGRADED_FILES} ${DESTDIR}${COMPFILE#.}
"
else
echo " *** Problem upgrading ${COMPFILE}, it will remain to merge by hand"
fi
return
fi
fi
if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then
echo ''
echo ' ====================================================================== '
@ -225,6 +244,10 @@ press_to_continue () {
#
TEMPROOT='/var/tmp/temproot'
# Assign the location of the mtree database
#
MTREEDB='/var/db/mergemaster.mtree'
# Read /etc/mergemaster.rc first so the one in $HOME can override
#
if [ -r /etc/mergemaster.rc ]; then
@ -239,11 +262,14 @@ fi
# Check the command line options
#
while getopts ":ascrvhipCPm:t:du:w:D:A:" COMMAND_LINE_ARGUMENT ; do
while getopts ":ascrvhipCPm:t:du:w:D:A:U" COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
A)
ARCHSTRING='MACHINE_ARCH='${OPTARG}
;;
U)
AUTO_UPGRADE=yes
;;
s)
STRICT=yes
unset DIFF_OPTIONS
@ -312,6 +338,12 @@ if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
fi
# Check the for the mtree database in DESTDIR.
if [ ! -f ${DESTDIR}${MTREEDB} ]; then
echo "*** Unable to find mtree database. Skipping auto-upgrade."
unset AUTO_UPGRADE
fi
echo ''
# If the user has a pager defined, make sure we can run it
@ -382,6 +414,19 @@ DIFF_FLAG=${DIFF_FLAG:--u}
#
SOURCEDIR=${SOURCEDIR:-/usr/src/etc}
# Check DESTDIR against the mergemaster mtree database to see what
# files the user changed from the reference files.
#
CHANGED=
if [ -n "${AUTO_UPGRADE}" -a -f "${DESTDIR}${MTREEDB}" ]; then
for file in `mtree -eq -f ${DESTDIR}${MTREEDB} -p ${DESTDIR}/ \
2>/dev/null | awk '($2 == "changed") {print $1}'`; do
if [ -f "${DESTDIR}/$file" ]; then
CHANGED="${CHANGED} ${DESTDIR}/$file"
fi
done
fi
# Check the width of the user's terminal
#
if [ -t 0 ]; then
@ -577,6 +622,18 @@ rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
# We only need to compare things like freebsd.cf once
find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
# Delete 0 length files to make the mtree database as small as possible.
find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
# Build the mtree database in a temporary location.
# TODO: Possibly use mktemp instead for security reasons?
case "${PRE_WORLD}" in
'') mtree -ci -p ${TEMPROOT} -k size,md5digest > ${DESTDIR}${MTREEDB}.new 2>/dev/null
;;
*) # We don't want to mess with the mtree database on a pre-world run.
;;
esac
# Get ready to start comparing files
# Check umask if not specified on the command line,
@ -921,6 +978,12 @@ done # This is for the do way up there at the beginning of the comparison
echo ''
echo "*** Comparison complete"
if [ -f "${DESTDIR}${MTREEDB}.new" ]; then
echo "*** Saving mtree database for future upgrades"
mv -f ${DESTDIR}${MTREEDB}.new ${DESTDIR}${MTREEDB} 2>/dev/null
fi
echo ''
TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
@ -973,6 +1036,28 @@ case "${AUTO_INSTALLED_FILES}" in
;;
esac
case "${AUTO_UPGRADED_FILES}" in
'') ;;
*)
case "${AUTO_RUN}" in
'')
(
echo ''
echo '*** You chose the automatic upgrade option for files that you did'
echo ' not alter on your system. The following were upgraded for you:'
echo "${AUTO_UPGRADED_FILES}"
) | ${PAGER}
;;
*)
echo ''
echo '*** You chose the automatic upgrade option for files that you did'
echo ' not alter on your system. The following were upgraded for you:'
echo "${AUTO_UPGRADED_FILES}"
;;
esac
;;
esac
run_it_now () {
case "${AUTO_RUN}" in
'')