#!/bin/sh # # Update FreeBSD sources and ports with csup and build a new world. # This can be safely run in multiuser mode. See the FreeBSD Handbook # and /usr/src/UPDATING for more details. Install with install_fbsd. # # The latest version of this script and its companion, install_fbsd can be # found in http://halplant.com:88/software/FreeBSD/scripts/ # My kernel config file and sup files, along with other system config # files can be found in http://halplant.com:88/server/config/ # # (c) 2000-2004 Andrew J. Caines. Redistribution and modification are welcome, # with proper attribution. No warranty. No money back. You broke it. export PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin umask 002 # Make all directories and kernel config redefinable on invocation Date=`date +%Y-%m-%d` ProgName=`basename $0` SrcDir=${SrcDir:-/usr/src} ObjDir=${ObjDir:-/usr/obj} BaseDir=${BaseDir:-/usr/local/etc/csup} ConfDir=${ConfDir:-/root/etc} Kernel=${Kernel:-`hostname -s | tr [:lower:] [:upper:]`} LockFile=/var/run/$ProgName.lock # Tuning options for buildworld/kernel. Can override some make.conf settings BuildWorldOpts=${BuildWorldOpts:-"-j 4"} BuildKernelOpts=${BuildKernelOpts:-} if [ -n "$NOCLEAN" ] then BuildWorldOpts="$BuildWorldOpts -DNOCLEAN" BuildKernelOpts="$BuildKernelOpts -DNOCLEAN" fi # Syslog logging options for logger LoggerOpts="-i -t $ProgName" # Default is "-p user.notice" # Don't leave the lock file behind is we catch a signal trap "rm $LockFile" 1 2 3 11 15 # Check we aren't already running if [ -f $LockFile ] then echo "Lock file $LockFile found for PID `cat $LockFile`" >&2 ; exit 1 else echo $$ > $LockFile fi # Compiler caching, activated by setting CCACHE_CC ccache=/usr/local/bin/ccache if [ -n "$CCACHE_CC" -a -x $ccache ] then CCACHE_DIR=${CCACHE_DIR:-/data/cache} CCACHE_LOGFILE=${CCACHE_LOGFILE:-/data/cache/log/ccache.log} CC="$ccache $CCACHE_CC" export CCACHE_CC CCACHE_DIR CCACHE_LOGFILE CC logger $LoggerOpts 'Using cache for '$CC'. Log file '$CCACHE_LOGFILE fi # File away old logs of the current update type rotate_logs() { mv $BaseDir/log/*${1}*.log $BaseDir/log/old/ 2>&- ( cd $BaseDir/log/old/ ; bzip2 --best --force --quiet *.log ) & } update_ports() { PortsDir=${PortsDir:-/usr/ports} PortsLockFile=$BaseDir/ports-lockfile PortsSupFile=$BaseDir/${Kernel}_ports-supfile PortsCvsupLog=$BaseDir/log/csup-ports_$Date.log PortsIndexLog=$BaseDir/log/index-ports_$Date.log logger $LoggerOpts 'Starting download of ports. Log file '$PortsCvsupLog if csup -l $PortsLockFile -L 2 $PortsSupFile 1> $PortsCvsupLog 2>&1 then logger $LoggerOpts 'Finished downloading ports.' else logger $LoggerOpts 'Ports download failed! See log file '$PortsCvsupLog rm $LockFile ; exit 1 fi # Update ports INDEX.db and pkgdb.db logger $LoggerOpts 'Updating ports and package DBs. Log file '$PortsIndexLog if [ -x /usr/local/sbin/portupgrade ] then portsdb -Uu > $PortsIndexLog pkgdb -u >> $PortsIndexLog portversion -v -l '<>?!' else make -C $PortsDir fetchindex pkg_version -vL'=' fi # Fetch new port distfiles if portupgrade is installed if [ -x /usr/local/sbin/portupgrade ] then logger $LoggerOpts 'Fetching ports distfiles.' portupgrade --all --fetch-only fi } update_docs() { DocLockFile=$BaseDir/docs-lockfile DocSupFile=$BaseDir/${Kernel}_docs-supfile DocCvsupLog=$BaseDir/log/csup-docs_$Date.log logger $LoggerOpts 'Starting download of docs. Log file '$DocCvsupLog if csup -l $DocLockFile -L 2 $DocSupFile 1> $DocCvsupLog 2>&1 then logger $LoggerOpts 'Finished downloading docs.' else logger $LoggerOpts 'Docs download failed! See log file '$DocCvsupLog rm $LockFile ; exit 1 fi } update_src() { SrcLockFile=$BaseDir/src-lockfile SrcSupFile=$BaseDir/${Kernel}_src-supfile SrcCvsupLog=$BaseDir/log/csup-src_$Date.log logger $LoggerOpts 'Starting download of sources. Log file '$SrcCvsupLog if csup -l $SrcLockFile -L 2 $SrcSupFile 1> $SrcCvsupLog 2>&1 then logger $LoggerOpts 'Finished downloading sources.' else logger $LoggerOpts 'Source download failed! See log file '$CvsupLog rm $LockFile ; exit 1 fi } build_world() { BuildLog=$BaseDir/log/buildworld_$Date.log # Mount ObjDir if it's an unmounted mfs or separate filesystem mount | fgrep -q $ObjDir || mount $ObjDir 2>&- # Blow away /usr/obj if cd $ObjDir then if [ -z "$NOCLEAN" ] then ( rm -rf *; chflags -R noschg * ; rm -rf * ) 2>/dev/null fi else echo "No $ObjDir found. Aborting" >&2 ; exit 1 fi logger $LoggerOpts Building a new world. Log file $BuildLog cd $SrcDir if make $BuildWorldOpts buildworld 1> $BuildLog 2>&1 then logger $LoggerOpts 'New world built.' else logger $LoggerOpts 'New world build failed! See log file '$BuildLog rm $LockFile ; exit 1 fi } build_kernel() { KernelLog=$BaseDir/log/buildkernel_$Date.log logger $LoggerOpts 'Building a new kernel. Log file '$KernelLog cp $ConfDir/$Kernel $SrcDir/sys/i386/conf/ cd $SrcDir if make $BuildKernelOpts buildkernel KERNCONF=$Kernel 1> $KernelLog 2>&1 then logger $LoggerOpts 'New kernel built.' else logger $LoggerOpts 'New kernel build failed! See log file '$KernelLog rm $LockFile ; exit 1 fi } # Fetch sources and ports at the same time, ignore docs then build new # world, by default. Do specific stage when specified. case $1 in ports) rotate_logs ports; update_ports ;; src) rotate_logs src; update_src ;; docs) rotate_logs docs; update_docs ;; world) rotate_logs world; build_world ;; kernel) rotate_logs kernel; build_kernel ;; system) rotate_logs '*'; update_src && build_world && build_kernel ;; '') rotate_logs '*'; update_ports & update_src && build_world && build_kernel ;; *) echo "Usage: $0 (ports|docs|src|world|kernel|system)" >&2 ;; esac # Remove lock rm -f $LockFile