All pastes #460903 Raw Edit

update-world w/ time estimation

public shellscript v1 · immutable
#460903 ·published 2007-04-27 11:06 UTC
rendered paste body
#!/bin/bash# update-world 1.6.1# count_zero 2006# Licensed under the GPLv2# Modified by Michal Gorny - added emerge time estimation with genlop## update-world is a bash script that forces an emerge -uD world to continue, even# in the face of (inevitable) compile failures.  Failed builds are added to a list,# and the script jumps to the next package in the queue.## just run update-world --prepare (or --empty) followed by update-world --install.## Release Notes:# v1.7b added USE flag management, broken (for the moment)# v1.6.1: Bugfixes, added utf-8 support# v1.6: Script preserves colored output.  Fixed version numbering in help output.# v1.5: now handles 'fetch restriction' properly# v1.4: uses '--newuse' for emerges to respect new use flags# v1.3: uses '--oneshot' for emerges so they don't get added to the world file.# v1.2: Script now detects log directly instead of accepting only /var/log/portage# v1.1: minor bugfix to allow package without version to be added to 'emergelist'# v1.0: Release### Set the program directory and important variablessource /etc/make.confexport EMERGE_DEFAULT_OPTS=""homedir=~/.update-worldworkdir="$homedir/`date +%F`"logdir="$workdir/log"mkdir -p $logdirtouch $homedir/failedlistemergelist=$homedir/emergelistemergetemp=$workdir/emergetempfailedlist=$homedir/failedlist#portlogdir=`cat /etc/make.conf | grep ^PORT_LOGDIR | sed 's/PORT_LOGDIR=//' | sed 's/\"//g' | sed 's/\/$//'`masked=$homedir/masked# parameter for '--empty' to emerge -e worldif [[ $1 == '--empty' || $1 == '-e' ]]	then parameter='-pev'	else parameter='-puvD --newuse'fi#### update-world --prepare ##### Prepare the list of packages to emerge into emerglistif [[ $1 == "--prepare" || $1 == "-p" || $1 == '--empty' || $1 == '-e' ]]	then	if [[ -e $emergelist ]]		then echo -n "The file 'emergelist' already exists and will be overwritten.Continue anyway? (y/n) "		read continue		if [[ $continue == 'y' || $continue == 'yes' || $continue == 'Y' || $continue == 'Yes' || $continue == 'YES' || $continue == '' ]]			then :			else echo exiting.			exit 0		fi		else :	fi	emerge $parameter world > $emergelist	emerge $parameter world	if which genlop >/dev/null 2>&1; then		cat "$emergelist" | genlop -p | grep ^Estimated	fi	# Make sure there are no errors in the emerge processecho	if [[ -n `cat $emergelist | sed -n 's/^\[ebuild[[:upper:][:lower:] ]*B[[:upper:][:lower:] ]*\].*/&/p'` ]]		then echo "WARNING: You have a blocking package.  Fix this before continuing."		rm -f $emergelist		exit 1		elif grep -q "masked" $emergelist		then echo "WARNING: You may need to unmask some packages before continuing."		elif grep -q "emerge: there are no ebuilds to satisfy" $emergelist		then echo "WARNING: One of the specified packages doesn't exist"		rm -f $emergelist		exit 1		elif [[ -n `cat $emergelist | sed -n 's/^\[ebuild[[:upper:][:lower:] ]*F[[:upper:][:lower:] ]*\].*/&/p'` ]]		then fetchrestricted=`cat $emergelist | sed -n 's/^\[ebuild[[:upper:][:lower:] ]*F[[:upper:][:lower:] ]*\].*/&/p' | sed -n 's/^\[ebuild[[:upper:][:lower:] ]*\]\ \([[:lower:][:upper:]0-9._+\/-]*\).*/\1/p'`		echo "WARNING: The following packages have Fetch Restriction turned on:$fetchrestrictedPlease download the sources to /usr/portage/distfiles/ and rerun this script."		exit 1		else :	fi	echo "These are the packages that will be installed.  If you want to alter this list,just edit the file 'emergelist' in $homedir. When finished, run'update-world --install'"	cat $emergelist | sed -n 's/^\[ebuild[[:upper:][:lower:] ]*\]\ \([[:lower:][:upper:]0-9._+\/-]*\).*/\1/p' | sed 's/.*/=&/' | sort -d > $emergetemp	cp $emergetemp $emergelist	rm -f $failedlist	exit 0#### update-world --install ##### Install the packages listed in emergelistelif [[ $1 == "--install" || $1 == "-i" ]]	then	# Verify that the emergelist doesn't produce errors	cat $emergelist | xargs emerge -p > $emergetemp	if grep -q "blocks B " $emergetemp		then echo "WARNING: You have a blocking package.  Fix this before continuing."		rm -f $emergetemp		exit 1		elif grep -q "masked" $emergelist		then echo "WARNING: You need to unmask some packages before continuing."		rm -f $emergetemp		exit 1		elif grep -q "emerge: there are no ebuilds to satisfy" $emergelist		then echo "WARNING: One of the specified packages doesn't exist"		rm -f $emergetemp		exit 1		elif [[ -z `cat $emergelist` ]]		then echo "WARNING: no 'emergelist' exists.  Did you run 'update-world --prepare' first?"		rm -f $emergetemp		exit 1		else :	fi	# Until loop to make portage continue until finished	increment=0	until [[ $increment == 1 ]]	do		cat $emergelist | xargs emerge -1		# Detect which packages have been successfully emerged and remove from the queue		installed=`tac /var/log/emerge.log | sed '/Started\ emerge/,$d' | grep "completed emerge" | sed 's/^.*)\ //' | sed 's/\ to.*//'`		for each in $installed		do 			eachsed=`echo $each | sed 's|\/|\\\/|'`			if [[ -z `cat $emergelist | grep $each` ]]				then eachsed=`echo $eachsed | sed 's/\-[0-9].*//'`				else :			fi 			cat $emergelist | sed "/$eachsed/d" > $emergetemp			mv $emergetemp $emergelist		done		# See if all packages have been emerged		if [[ -z `cat $emergelist` ]]			then increment=1			else :		fi		if [[ $increment == 0 ]]		then		errorlog=`ls -t $PORT_LOGDIR | sed '2,$d'`		if [[ -n `cat $PORT_LOGDIR/$errorlog | grep 'signal 2'` ]]			then echo "*** User hit 'Control-C' ... exiting." 			exit 1			else :		fi		sleep 5		echo		echo "*** Hit Control-C to exit, or just wait to continue with emerge."		echo		sleep 10		echo "*** Continuing with emerge."		# Detect failed emerge and add to failedlist, remove failed package from emergelist		failedpkg=`tac /var/log/emerge.log | sed '1d' | sed '/terminating/,$d' | sed '/completed\ emerge/,$d' | grep ">>>" | sed 's/.*)\ //' | sed 's/\ to.*//'`		if [[ -n `tail -n 1 $failedlist | grep $failedpkg` ]]			then echo "The failed package $failedpkg could not be merged and must be successfully installed before continuing."			exit 1			else :		fi		echo $failedpkg >> $failedlist		failedpkgsed=`echo $failedpkg | sed 's|\/|\\\/|'`		cat $emergelist | sed "/$failedpkgsed/d" > $emergetemp		mv $emergetemp $emergelist		ln -s $PORT_LOGDIR/$errorlog $logdir/${errorlog}_error-log		echo		echo		echo "*** $failedpkg compile failed, skipping."		# Is there a package in 'emergelist' that requires the failed pkg as a dep? If so, remove it too.		failedpkgdeps=`echo $failedpkg | sed 's/-[0-9].*//'`		deps=`equery depends $failedpkgdeps | sed '/^\[/d' | sed 's/-[0-9].*//'`		for each in `echo $deps`		do			if [[ -n `cat $emergelist | grep "$each"` ]]				then				if [[ -n `emerge -p $each | grep "$failedpkg"` ]]					then					each2=`cat $emergelist | grep $each | sed 's/\=//'`					echo "$each2 (depends on $failedpkg)" >> $failedlist					eachsed=`echo $each | sed 's|\/|\\\/|'`					cat $emergelist | sed "/$eachsed/d" > $emergetemp					mv $emergetemp $emergelist					echo "*** $each depends on $failedpkg, skipping."					else :				fi				else :			fi		done		echo "*** Continuing with emerge world"		else :		fi	done# if improper argument is given to 'update-world' display the help textelse echo "update-world 1.6count_zero 2006licensed under the GPLv2Description:This is a bash script to automate the 'emerge -uD world' process.Its purpose is to make updating the system as hands-free as possible.It does this by automatically recovering from a failed emerge and movingon to the next one, presenting the user with a list of failed packagesonce the update has finished.  No more 'babysitting' the update process!Just start it, and deal with any failed packages at the end.  Log filesfrom the failed emerges are saved in the log directory.The default program directory is ~/.update-worldUsage:update-world [--prepare | -p ]	Prepares a list of packages produced by 'emerge -puvD world'	and outputs them to the file 'emergelist' in the current directory.	Add, remove, or change the version of any of the packages listed	in this file with your favorite editor before continuing.update-world [--empty | -e ]	Same as --prepare except it performs 'emerge -ev world' to recompile	all packages on a system.update-world [--install | -i ]	Begins the emerge process based upon the 'emergelist' file created 	from running 'update-world --prepare'.  Once finished, failed builds	will be saved in the file 'failedlist' in the current directory."exit 1fiecho "Congratulations!  'emerge world' complete."echo# All done! display the failed packages, if anyif [[ -z `cat $failedlist` ]]	then echo "All packages emerged successfully"	else echo "These packages couldn't be merged due to compile errors:"	echo	cat $failedlist	echo	echo "Look in $logdir/ for the portage log files of the failed builds.Check bugs.gentoo.org or the Gentoo Forums for help."fiexit 0