#!/bin/sh # # $Id: mkcdroot,v 1.18 2002/08/21 03:13:11 bsd Exp $ # # Copyright 2001, 2002 Brian S. Dean # All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRIAN S. DEAN BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # DAMAGE. # # Author : Brian Dean # Date : 15 April, 2001 # PROG=`basename $0` CDROOT_LIBDIR=LIBDIR_VALUE PAUSE=1 #-------------------------------------------------------------------- # Operational defaults #-------------------------------------------------------------------- DEF_BASE=/scratch/cdroot/cdroot # Prefix to DEF_SRCTREE=/usr/src # head of the source tree DEF_DOWORLD=1 # perform an installworld DEF_DOKERN=1 # perform a buildkernel installkernel DEF_DOFDBOOT=1 # generate a 2.88 boot floppy image DEF_DOETCSRC=1 # populate /etc from /usr/src ($SRCTREE) DEF_DOETC=1 # populate /etc with new files DEF_DOSRC=0 # populate /usr/src on the CD from the host system sources DEF_DOOBJ=0 # copy /usr/obj from the host system DEF_DOPORTS=0 # copy /usr/ports from the host system DEF_DOINSTPORTS=0 # install standard ports DEF_DOINSTPKGS=0 # install standard packages DEF_KERNCONF=CDROOT # default kernel configuration file DEF_BOOTOPTS="" # default options to pass to the kernel DEF_PKGDIR=/scratch/pub/FreeBSD/ports/i386/packages-4-stable/Latest DEF_PKGLIST="XFree86 pdksh ddup" BASE=$DEF_BASE SRCTREE=$DEF_SRCTREE DOWORLD=$DEF_DOWORLD DOKERN=$DEF_DOKERN DOFDBOOT=$DEF_DOFDBOOT DOETCSRC=$DEF_DOETCSRC DOETC=$DEF_DOETC DOSRC=$DEF_DOSRC DOOBJ=$DEF_DOOBJ DOPORTS=$DEF_DOPORTS DOINSTPORTS=$DEF_DOINSTPORTS DOINSTPKGS=$DEF_DOINSTPKGS KERNCONF=$DEF_KERNCONF BOOTOPTS=$DEF_BOOTOPTS PKGDIR=${DEF_PKGDIR} PKGLIST=${DEF_PKGLIST} #-------------------------------------------------------------------- # Support Functions #-------------------------------------------------------------------- # Print negated "true"/"false", useful for diplaying default settings # for -no* options, i.e., -nosrc. tf_neg () { if [ "$1" -eq 1 ]; then echo "false" else echo "true" fi } # Print "yes"/"no", useful for diplaying default settings of 1/0 based # flags yn () { if [ "$1" -eq 1 ]; then echo "yes" else echo "no" fi } # function for error checking ckrc () { rc=$? if [ "$rc" -ne 0 ]; then echo -n "$PROG: $1 failed, rc=$rc" if [ "$2" = "exit" ]; then echo "aborting"; exit 1; fi echo fi } # install resolv.conf for name lookups; this is needed for installing # ports, etc., in a chroot'd environment on $DESTDIR neednamelookups () { if [ ! -f $DESTDIR/etc/resolv.conf ]; then if [ -f /etc/resolv.conf ]; then cp /etc/resolv.conf $DESTDIR/etc/resolv.conf fi fi } # Create directories if they don't alread exist domkdir () { for dir in $*; do if [ ! -d $dir ]; then echo "mkdir $dir" rm -f $dir mkdir -p $dir fi done } # Attempt to install a requested port installport () { neednamelookups while [ "$#" -ge 1 ]; do DIR=$1; shift while [ "$#" -ge 1 ]; do PORT=$1; shift echo "Installing $DIR/$PORT ..." chroot $DESTDIR \ /bin/sh -c "unset DESTDIR; cd /usr/ports/$DIR/$PORT && make install" done done } doworld () { # Perform an installworld targeting the new root DESTDIR="$1" echo "DOWORLD: DESTDIR=$DESTDIR" cd $SRCTREE mkdir ${DESTDIR}/dist make installworld DESTDIR=$DESTDIR } dokern () { # Build and install a kernel for the new root DESTDIR="$1" echo "DOKERN: DESTDIR=$DESTDIR" (cd $SRCTREE && make buildkernel installkernel KERNCONF=${KERNCONF} \ DESTDIR=$DESTDIR) } dosrc () { # populate ${DESTDIR}/usr/src from ${SRCTREE} DESTDIR="$1" echo "populate ${DESTDIR}/usr/src from ${SRCTREE}" mkdir -p ${DESTDIR}/usr/src && (cd ${DESTDIR}/usr/src && cp -rpv ${SRCTREE}/. .) } doetcsrc() { DESTDIR="$1" echo "DOETCSRC: DESTDIR=$DESTDIR" echo "Populate /etc" (cd $SRCTREE/etc && make DESTDIR=$DESTDIR distrib-dirs && make DESTDIR=$DESTDIR distribution) echo "Making devices" chroot $DESTDIR /bin/sh -c "(cd /dev && sh MAKEDEV all ad0s1a da0s1a)" echo "Remove /etc/rc.system" if [ -f ${DESTDIR}/rc.system ]; then rm ${DESTDIR}/etc/rc.system fi echo "Installing password files" chroot $DESTDIR /bin/sh -c "pwd_mkdb -p /etc/master.passwd" echo "Generating login capabilities database" chroot $DESTDIR /bin/sh -c "/usr/bin/cap_mkdb /etc/login.conf" echo "Creating aliases database" chroot $DESTDIR /bin/sh -c "unset $DESTDIR; /usr/bin/newaliases" echo "Create /etc/objformat" echo "OBJFORMAT=elf" > $DESTDIR/etc/objformat echo "Create /etc/fstab" echo "" > $DESTDIR/etc/fstab echo "Enable logins on /dev/ttyd0" tfile=/tmp/ttys.$$ cat $DESTDIR/etc/ttys | sed 's+^ttyd0 "/usr/libexec/getty std.9600" dialup off secure+ttyd0 "/usr/libexec/getty std.9600" dialup on secure+g' > $tfile && cp $tfile $DESTDIR/etc/ttys rm -f $tfile echo "Enable hardware flow control by default on std.9600" tfile=/tmp/gettytab.$$ cat $DESTDIR/etc/gettytab | sed 's+^ :np:sp#9600:$+ :np:sp#9600:hw:+g' > $tfile && cp $tfile $DESTDIR/etc/gettytab rm -f $tfile } dofdboot () { DESTDIR="$1" echo "DOFDBOOT: DESTDIR=$DESTDIR" echo "Generating 2.88 MB boot floppy image" KERNELIMG=${DESTDIR}/kernel umount /mnt > /dev/null 2>&1 vnconfig -u /dev/vn0 > /dev/null 2>&1 echo "Initialize boot floppy image" dd if=/dev/zero of=${DESTDIR}/boot/boot.fd bs=1024 count=2880 vnconfig -s labels -c /dev/vn0 ${DESTDIR}/boot/boot.fd disklabel -Brw /dev/vn0c minimum2 newfs -o space -T minimum2 /dev/vn0c mount /dev/vn0c /mnt echo "Copy kernel from ${KERNELIMG} to the boot floppy" cp ${KERNELIMG} /tmp/kernel gzip /tmp/kernel cp /tmp/kernel.gz /mnt rm /tmp/kernel.gz mkdir /mnt/boot mkdir /mnt/boot/defaults echo "Copy boot1, boot2, and loader to boot floppy" (cd ${DESTDIR}/boot && cp -p boot1 boot2 loader /mnt/boot) echo "Create boot.config" echo "-P" > /mnt/boot.config echo "-P" > ${DESTDIR}/boot.config echo "Create loader.rc" cat < /mnt/boot/loader.rc echo "BSD CDROM ROOT IMAGE" echo "LOADING KERNEL" load /kernel boot -C $BOOTOPTS EOF cat < ${DESTDIR}/boot/loader.rc echo "BSD NO-EMULATION CDROM ROOT IMAGE" echo "LOADING KERNEL" load /kernel boot -C $BOOTOPTS EOF umount /mnt } installcvsup () { DESTDIR="$1" # Provide a cvsup supfile to keep /usr/ports up to date if [ ! -f $DESTDIR/root/ports-supfile ]; then echo "Install ports cvsup file" cat <<_EOD_ > $DESTDIR/root/ports-supfile # cvsup -g -L 2 ports-supfile *default host=cvsup8.FreeBSD.org *default base=/usr *default prefix=/usr *default release=cvs tag=. *default delete use-rel-suffix *default compress ports-all _EOD_ fi # Fetch cvsup if it is not yet installed if [ ! -f $DESTDIR/usr/local/bin/cvsup ]; then echo "Install cvsup" cd $DESTDIR/root && \ fetch ${CVSUPLOC}/${CVSUP} && \ chroot $DESTDIR /bin/sh -c "unset DESTDIR; cd /root && pkg_add -v ${CVSUP} && rm -f ${CVSUP}" fi } updateports () { DESTDIR="$1" echo "Update /usr/ports" if [ ! -f /usr/local/bin/cvsup ]; then echo echo "You must install the cvsup package first." echo exit 1 fi neednamelookups chroot $DESTDIR /bin/sh -c \ "unset DESTDIR; cd /root && cvsup -g -L 2 ports-supfile" } # Display usage information printusage () { cat < Create a new read only root area starting at $DEF_BASE. The following options are supported: -base : Override the root install location [default=$DEF_BASE] -srctree : Override the location of the source tree [default=$DEF_SRCTREE] -noworld : do not perform an "installworld" [default=`tf_neg $DEF_DOWORLD`] -nokern : do not perform a "buildkernel installkernel" [default=`tf_neg $DEF_DOKERN`] -nofdboot : do not generate a 2.88 boot floppy [default=`tf_neg $DEF_DOFDBOOT`] -noetcsrc : do not populate /etc from $SRCTREE [default=`tf_neg $DEF_DOETCSRC`] -noetc : do not populate /etc with new files [default=`tf_neg $DEF_DOETC`] -nosrc : do not populate /usr/src from the host system [default=`tf_neg $DEF_DOSRC`] -noobj : do not populate /usr/obj from the host system [default=`tf_neg $DEF_DOOBJ`] -noports : do not populate /usr/ports from the host system [default=`tf_neg $DEF_DOPORTS`] -noinstports : do not attempt to install standard ports [default=`tf_neg $DEF_DOINSTPORTS`] -noinstpkgs : do not attempt to install standard packages [default=`tf_neg $DEF_DOINSTPKGS`] -pkgdir : directory where packages are located [default=$DEF_PKGDIR] -pkglist : set list of packages to install [default=$DEF_PKGLIST] -kernconf : override the default kernel config file for building/installing [default=$DEF_KERNCONF] -bootopts : override the default kernel options passed by the loader [default=$DEF_BOOTOPTS] -now : do not pause for 5 seconds before performing actions EOF } #------------------------------------------------------------ # check for command line options #------------------------------------------------------------ while [ "$#" -ne 0 ]; do VAL=1 case $1 in -no*) VAL=0; ;; esac case $1 in -base) BASE="$2" shift; shift ;; -srctree) SRCTREE="$2" shift; shift ;; -noworld|-world) DOWORLD=$VAL shift ;; -nokern|-kern) DOKERN=$VAL shift ;; -nofdboot|-fdboot) DOFDBOOT=$VAL shift ;; -noetcsrc|-etcsrc) DOETCSRC=$VAL shift ;; -noetc|-etc) DOETC=$VAL shift ;; -nosrc|-src) DOSRC=$VAL shift ;; -noobj|-obj) DOOBJ=$VAL shift ;; -noports|-ports) DOPORTS=$VAL shift ;; -noinstports|-instports) DOINSTPORTS=$VAL shift ;; -noinstpkgs|-instpkgs) DOINSTPKGS=$VAL shift ;; -pkgdir) PKGDIR=$2 shift; shift ;; -pkglist) PKGLIST=$2 shift; shift ;; -kernconf) KERNCONF="$2" shift; shift ;; -bootopts) BOOTOPTS="$2" shift; shift ;; -now) PAUSE=0 shift ;; *) echo echo "$PROG: unknown option \"$1\"" printusage exit 1 ;; esac done if [ "$#" -ne 0 ]; then printusage exit 1 fi if [ $DOINSTPKGS -eq 1 -a $DOINSTPORTS -eq 1 ]; then cat <-C to cancel " sleep 1 timeout=`expr $timeout - 1` done echo echo fi #---------------------------------------------------------------------- # Populate the most basic components of the OS if requested #---------------------------------------------------------------------- if [ "$DOWORLD" -eq 1 ]; then doworld ${DESTDIR} ckrc world exit fi if [ "$DOKERN" -eq 1 ]; then dokern ${DESTDIR} ckrc kernel exit fi if [ "$DOETCSRC" -eq 1 ]; then doetcsrc ${DESTDIR} ckrc etcsrc exit fi if [ "$DOETC" -eq 1 ]; then echo "Create /etc/rc.conf" cat < $DESTDIR/etc/rc.conf # /etc/rc.conf # # Generated by $PROG, `date` # # The options below can be overridden by entries on a floppy disk. # Create a ufs filesystem on a floppy disk, create an etc directory, # and put overrides there. Files are copied from the floppy:/etc and # replaces files here at boot time. If you override this file, # /etc/rc.conf, you should not change the options immediately below. moused_enable=YES moused_type=ps/2 moused_port=/dev/psm0 root_rw_mount=NO # let /etc/rc know that root is ro update_motd=NO # don't try to update /etc/motd diskless_mount=/etc/cdroot_mount # custom disk mounting program # # ********** WARNING ********** # # These next two options are dangerous and can result in the loss of # data on either ad0 or da0. Use with EXTREME caution. # # If cdroot_uselocaldisk is set to YES, then the /etc/cdroot_mount # program looks for either ad0 or da0. If one of these is found, then # it will be used to hold swap, /var, /tmp, and /local. # # The disk is initialized from scratch if the first fdisk slice does # not contain a valid FreeBSD label. If a label is present, the # filesystems are fsck'd and used as is. You can force the disk to be # re-initialized each time by specifying cdroot_force_diskinit=YES. cdroot_uselocaldisk=NO # use a local disk for swap, /var, /tmp, /local cdroot_force_diskinit=NO # alway re-initialize the local disk EOF echo "Make sure /etc/mail/local-host-names exists" touch ${DESTDIR}/etc/mail/local-host-names echo "Install /etc/cdroot_mount" cp ${CDROOT_LIBDIR}/cdroot_mount ${DESTDIR}/etc echo "Install /etc/cdroot_initdisk" cp ${CDROOT_LIBDIR}/cdroot_initdisk ${DESTDIR}/etc echo "Install /etc/inst" cp ${CDROOT_LIBDIR}/cdroot_inst ${DESTDIR}/etc/inst echo "Install /etc/rc.replacement" if [ ! -f "${DESTDIR}/etc/rc.system" ]; then cp -p ${DESTDIR}/etc/rc ${DESTDIR}/etc/rc.system fi cp ${CDROOT_LIBDIR}/rc.replacement ${DESTDIR}/etc/rc echo "Stash a copy of /dev/MAKEDEV into /etc" cp -p ${DESTDIR}/dev/MAKEDEV ${DESTDIR}/etc echo "Create /etc/install/dists.dat and pkgs.dat" if [ ! -d ${DESTDIR}/etc/install ]; then mkdir ${DESTDIR}/etc/install fi if [ ! -f ${DESTDIR}/etc/install/dists.dat ]; then cat < ${DESTDIR}/etc/install/dists.dat bin catpages compat22 compat3x compat4x crypto dict doc games info manpages ports proflibs src EOF else echo "${DESTDIR}/etc/install/dists.dat already present, not replaced" fi if [ ! -f ${DESTDIR}/etc/install/pkgs.dat ]; then cat < ${DESTDIR}/etc/install/pkgs.dat XFree86-4.1.0_4 emacs-20.7 pdksh-5.2.14 EOF else echo "${DESTDIR}/etc/install/pkgs.dat already present, not replaced" fi fi if [ ! -f ${DESTDIR}/usr/hosts.db -a -f /usr/hosts.db ]; then echo "install /usr/hosts.db" cp -p /usr/hosts.db ${DESTDIR}/usr/hosts.db fi if [ "$DOFDBOOT" -eq 1 ]; then dofdboot ${DESTDIR} ckrc fdboot exit fi if [ "$DOSRC" -eq 1 ]; then dosrc ${DESTDIR} ckrc "populate ${DESTDIR}/usr/src from $SRCTREE" exit fi #---------------------------------------------------------------------- # Several following commands depend on the current working directory # being the new root area #---------------------------------------------------------------------- cd $DESTDIR || exit 1 # Create needed directories relative to the new root domkdir local usr/local usr/local/etc/rc.d #---------------------------------------------------------------------- # Install requested packages #---------------------------------------------------------------------- if [ $DOINSTPKGS -eq 1 ]; then echo "Copying packages to the chroot'd area ..." if [ ! -d "${DESTDIR}/tmp/pkgs" ]; then mkdir ${DESTDIR}/tmp/pkgs ckrc "create temporary package directory" exit fi cp -p $PKGDIR/* ${DESTDIR}/tmp/pkgs ckrc "copy packages to temporary package directory" exit for PKG in $PKGLIST; do echo "Installing package $PKG ..." chroot ${DESTDIR} /bin/sh -c "unset DESTDIR; \ pkg_add -v /tmp/pkgs/$PKG.tgz" done rm -rf ${DESTDIR}/tmp/pkgs ckrc "removal of temporary package directory" fi #---------------------------------------------------------------------- # Update /usr/ports if requested to do so #---------------------------------------------------------------------- if [ "$DOPORTS" -eq 1 ]; then updateports ${DESTDIR} fi #---------------------------------------------------------------------- # Try and provide a working /bin/ksh #---------------------------------------------------------------------- if [ -d "${DESTDIR}/usr/ports/shells/pdksh" -a ! -f /bin/ksh ]; then installport shells pdksh fi if [ ! -f ${DESTDIR}/bin/ksh ]; then if [ -f "${DESTDIR}/usr/local/bin/ksh" ]; then cp -p ${DESTDIR}/usr/local/bin/ksh ${DESTDIR}/bin/ksh elif [ -f /usr/local/bin/ksh ]; then cp -p /usr/local/bin/ksh ${DESTDIR}/bin/ksh elif [ -f /bin/ksh ]; then cp -p /bin/ksh ${DESTDIR}/bin/ksh fi fi if [ -f ${DESTDIR}/bin/ksh ]; then grep '^/bin/ksh' ${DESTDIR}/etc/shells > /dev/null 2>&1 rc=$? if [ "$rc" -ne 0 ]; then echo "/bin/ksh" >> ${DESTDIR}/etc/shells fi fi #---------------------------------------------------------------------- # Attempt to install the standard ports if requested #---------------------------------------------------------------------- if [ $DOINSTPORTS -eq 1 ]; then # ports that require X11 installport x11 XFree86 installport editors emacs20 installport graphics xv installport net ethereal # Non-X11 ports installport mail mutt procmail installport net cvsup installport security sudo installport shells pdksh installport sysutils lsof fi