Subject: using etcupdate to update a destdir, instead of "/"
To: None <current-users@netbsd.org>
From: Jeff Rizzo <riz@netbsd.org>
List: current-users
Date: 12/11/2005 14:51:44
--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I found myself in a situation where I wanted to be able to use etcupdate
to update the etc files somewhere *other* than the root of the current
machine - like for a diskless client, on a server.  (Or, in my case,
in a filesystem image mounted from vnd0)  Since etcupdate didn't
seem to be able to do this natively, I added it.

Here are patches which add this functionality - I'd appreciate if people
can look them over, test them, and let me know what I missed.  I chose
the "-d" flag, since that's what vipw and pwd_mkdb already use.

BE AWARE THAT THIS PROGRAM IS DESIGNED TO CHANGE CONFIGURATION FILES
ON THE CURRENT MACHINE.  If I missed something, you could wind up
altering the machine's configuration instead of the config in the
destdir!  I have tried it on the filesystem I wrote it for, and it
worked fine, but I'm not responsible if this blows up your system!  :)

Feedback appreciated-

+j

Index: usr.sbin/etcupdate/etcupdate
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.sbin/etcupdate/etcupdate,v
retrieving revision 1.22
diff -u -r1.22 etcupdate
--- usr.sbin/etcupdate/etcupdate	17 Apr 2005 23:12:40 -0000	1.22
+++ usr.sbin/etcupdate/etcupdate	11 Dec 2005 22:45:15 -0000
@@ -62,6 +62,7 @@
 BINARY=3D
 AUTOMATIC=3D
 LOCALSKIP=3D
+NEWROOT=3D
 MACHINE=3D"${MACHINE:=3D`uname -m`}"
 export MACHINE
 MACHINE_ARCH=3D"${MACHINE_ARCH:=3D`uname -p`}"
@@ -81,6 +82,7 @@
 Options:
=20
   -b srcdir    Location of the extracted sets
+  -d destdir   Update etc in destdir instead of /
   -p pager     Which pager to use              (default: /usr/bin/more)
   -s srcdir    Location of the source files    (default: /usr/src/etc)
   -t temproot  Where to store temporary files  (default: /tmp/temproot)
@@ -132,7 +134,7 @@
=20
 	# Install the new file
 	verbose "Installing ${1}"
-	cp -p "${TEMPROOT}${1}" "${1}" && rm -f "${TEMPROOT}${1}"
+	cp -p "${TEMPROOT}${1}" "${NEWROOT}${1}" && rm -f "${TEMPROOT}${1}"
=20
 	# Check if this was a special file
 	case "${1}" in
@@ -157,23 +159,23 @@
 	[ "${AUTOMATIC}" !=3D "YES" ] && return
=20
 	D=3D`dirname "${1}"`
-	mkdir -p "/var/etcupdate/${D}"
-	md5 "${1}" > "/var/etcupdate/${1}"
+	mkdir -p "${NEWROOT}/var/etcupdate/${D}"
+	md5 "${1}" > "${NEWROOT}/var/etcupdate/${1}"
 }
=20
 diff_and_merge_file() {
 	# $1 =3D target file
=20
-	if cmp -s "${TEMPROOT}${1}" "${1}"; then
+	if cmp -s "${TEMPROOT}${1}" "${NEWROOT}${1}"; then
 		verbose "=3D=3D=3D> ${1} (ok)"
 		rm -f "${TEMPROOT}${1}"
 		install_checksum "${1}"
 		return
 	fi
=20
-	if [ "${AUTOMATIC}" =3D "YES" -a -f "/var/etcupdate/${1}"  ] ; then
-		SUM1=3D`md5 "${1}"`
-		SUM2=3D`cat "/var/etcupdate/${1}"`
+	if [ "${AUTOMATIC}" =3D "YES" -a -f "${NEWROOT}/var/etcupdate/${1}"  ] ; =
then
+		SUM1=3D`md5 "${NEWROOT}${1}"`
+		SUM2=3D`cat "${NEWROOT}/var/etcupdate/${1}"`
 		if [ "${SUM1}" =3D "${SUM2}" ] ; then
 			install_file "${1}"
 			install_checksum "${1}"
@@ -184,7 +186,7 @@
 	if [ "${LOCALSKIP}" =3D "YES" ] ; then
 		ID1=3D`ident -q "${TEMPROOT}${1}" | sed -n 2p`
 		ID1=3D"${ID1:-0}"
-		ID2=3D`ident -q "${1}" | sed -n 2p`
+		ID2=3D`ident -q "${NEWROOT}${1}" | sed -n 2p`
 		ID2=3D"${ID2:-1}"
 		if [ "${ID1}" =3D "${ID2}" ] ; then
 			verbose "=3D=3D=3D> ${1} (ok:RCS)"
@@ -194,14 +196,14 @@
 	fi
=20
 	clear
-	if [ ! -f "${1}" ]; then
+	if [ ! -f "${NEWROOT}${1}" ]; then
 		verbose "=3D=3D=3D> ${1} (missing)"
 		DOES_EXIST=3D
 	else
 		verbose "=3D=3D=3D> ${1} (modified)"
 		verbose ""
 		DOES_EXIST=3DYES
-		diff -u "${1}" "${TEMPROOT}${1}" | ${PAGER}
+		diff -u "${NEWROOT}${1}" "${TEMPROOT}${1}" | ${PAGER}
 	fi
=20
 	STAY_HERE=3DYES
@@ -218,8 +220,8 @@
 		# Ask the user if (s)he wants to install the new
 		# version or perform a more complicated manual work.
 		echo ""
-		echo -n "File: ${1}"
-		if [ ! -f "${1}" ]; then
+		echo -n "File: ${NEWROOT}${1}"
+		if [ ! -f "${NEWROOT}${1}" ]; then
 			echo -n " (missing)"
 		else
 			echo -n " (modified)"
@@ -278,13 +280,13 @@
 			sdiff -o "${TEMPROOT}${1}.merged"	\
 				--width=3D${WIDTH}		\
 				--suppress-common-lines --text	\
-				"${1}" "${TEMPROOT}${1}"
+				"${NEWROOT}${1}" "${TEMPROOT}${1}"
 			mv -f "${TEMPROOT}${1}.merged" "${TEMPROOT}${1}"
 			ALREADY_MERGED=3DYES
 			;;
 		[sS])
 			[ -z "${DOES_EXIST}" ] && continue
-			diff -u "${1}" "${TEMPROOT}${1}" | ${PAGER}
+			diff -u "${NEWROOT}${1}" "${TEMPROOT}${1}" | ${PAGER}
 			;;
 		[uU])
 			if [ -f "${B}" ]; then
@@ -312,7 +314,7 @@
 #
=20
 # Read global configuration
-GLOBALRC=3D"/etc/`basename $0`.conf"
+GLOBALRC=3D"${NEWROOT}/etc/`basename $0`.conf"
 [ -r ${GLOBALRC} ] && . ${GLOBALRC}
=20
 # Read user configuration
@@ -320,7 +322,7 @@
 [ -r ${USERRC} ] && . ${USERRC}
=20
 # Read command line arguments
-ARGV=3D`getopt ab:hlp:s:t:vw: $*`
+ARGV=3D`getopt ab:d:hlp:s:t:vw: $*`
 [ $? !=3D 0 ] && usage
 set -- ${ARGV}
 for i; do
@@ -334,6 +336,10 @@
 		SRCDIR=3D"${2}"
 		shift 2
 		;;
+	-d)
+		NEWROOT=3D"${2}"
+		shift 2
+		;;
 	-h)
 		usage
 		;;
@@ -455,11 +461,11 @@
 	for i in `find ${TEMPROOT} -type d`; do
 		D=3D`echo ${i} | sed "s#${TEMPROOT}##"`
 		[ "x${i}" =3D "x${TEMPROOT}" ] && continue
-		[ ! -d "${D}" ] && install_dir "${D}"
+		[ ! -d "${NEWROOT}${D}" ] && install_dir "${D}"
 	done
 fi
=20
-# Start the comparision
+# Start the comparison
 echo "*** Checking for added/modified files"
 for i in `find ${TEMPROOT} -type f  -a ! -name \*.etcupdate.\*`; do
 	D=3D`echo ${i} | sed "s#${TEMPROOT}##"`
@@ -489,17 +495,17 @@
 	if yesno "You have created new directories. Run mtree to set" \
 	         "permissions"
 	then
-		(cd / && mtree -Udef /etc/mtree/NetBSD.dist)
+		(cd ${NEWROOT}/ && mtree -Udef ${NEWROOT}/etc/mtree/NetBSD.dist)
 	fi
 fi
 if [ ! -z "${NEED_MAKEDEV}" ]; then
-	if yesno "Do you want to rebuild the device nodes in /dev"; then
-		verbose "Running MAKEDEV in /dev"
-		(cd "/dev" && ./MAKEDEV all)
+	if yesno "Do you want to rebuild the device nodes in ${NEWROOT}/dev"; then
+		verbose "Running MAKEDEV in ${NEWROOT}/dev"
+		(cd "${NEWROOT}/dev" && ./MAKEDEV all)
 	else
 		echo ""
-		echo "*** You SHOULD rebuild the device nodes in /dev"
-		echo "*** This is done by running \"(cd /dev &&" \
+		echo "*** You SHOULD rebuild the device nodes in ${NEWROOT}/dev"
+		echo "*** This is done by running \"(cd ${NEWROOT}/dev &&" \
 		     "./MAKEDEV all)\" as root".
 		echo ""
 	fi
@@ -521,7 +527,7 @@
 	         "new master.passwd"
 	then
 		verbose "Running pwd_mkdb"
-		pwd_mkdb -p "/etc/master.passwd"
+		pwd_mkdb -d ${NEWROOT}/ -p "${NEWROOT}/etc/master.passwd"
 	else
 		echo ""
 		echo "*** You MUST rebuild the password databases to make" \
@@ -534,6 +540,6 @@
 if [ -x /usr/sbin/postinstall -a -z "${BINARY}" ]; then
 	S=3D`echo ${SRCDIR} | sed 's+/etc++'`
 	echo "*** Running /usr/sbin/postinstall"
-	/usr/sbin/postinstall -s "${S}" check
+	/usr/sbin/postinstall -d ${NEWROOT}/ -s "${S}" check
 fi
 echo "*** All done"
Index: usr.sbin/etcupdate/etcupdate.8
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.sbin/etcupdate/etcupdate.8,v
retrieving revision 1.10
diff -u -r1.10 etcupdate.8
--- usr.sbin/etcupdate/etcupdate.8	2 Apr 2003 19:30:57 -0000	1.10
+++ usr.sbin/etcupdate/etcupdate.8	11 Dec 2005 22:45:15 -0000
@@ -34,7 +34,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF=
 THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 2, 2003
+.Dd December 11, 2005
 .Dt ETCUPDATE 8
 .Os
 .Sh NAME
@@ -45,6 +45,7 @@
 .Nm
 .Op Fl ahlv
 .Op Fl b Ar srcdir
+.Op Fl d Ar destdir
 .Op Fl p Ar pager
 .Op Fl s Ar srcdir
 .Op Fl t Ar temproot
@@ -109,6 +110,13 @@
 .Fl b Ar srcdir
 option later in this manual page).
 .Pp
+The user can update a directory other than the root
+.Pa /
+by using the
+.Fl d Ar destdir
+option.
+This can be used to update diskless clients from the server, for example.
+.Pp
 The following options are available:
 .Bl -tag -width XXtXtemprootX
 .It Fl a
@@ -135,6 +143,10 @@
 .Pa srcdir
 directory is treated like
 .Pa temproot ) .
+.It Fl d Ar destdir
+Update the configuration of the directory tree rooted at
+.Pa destdir
+instead of the root directory.
 .It Fl h
 Prints a help text.
 .It Fl l

--3V7upXqbjpZ4EhLz
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (NetBSD)

iQCVAwUBQ5ytgLOuUtxCgar5AQL3jQP+O5btHVXlDHwG/b2+1aAV+CNYeiH1uNLb
PiiRrjlWQ2R0uuAKmKssUXJ6v1HN9Imy3zOtIRS6BEi5VPH9vzo5aUm9VL0+diP4
uv+CxZ3uj4M1HU/Ux5qEFpVUnH2iguXenfJ2+tvg6qC2CGFV8/js2AW/qyU4/dnG
qq2yDJIuSH4=
=CuxI
-----END PGP SIGNATURE-----

--3V7upXqbjpZ4EhLz--