Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
World Update script running as a cron.
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Fri May 16, 2008 12:27 pm    Post subject: World Update script running as a cron. Reply with quote

So I decided to write a script that can be run as a cron job that will do my world update every week and email me a report. I'm sure this has been done before but I couldn't find a nice simple bash script that did it and that did not require babysitting.

Feel free to tell me how lame my scripting skills are as this is the first bash script I've written with any meat to it.

Original Version:
Code:

#!/bin/bash
###################
#
# Script to bring Ziggy up to the latest and greatest
#
###################

#Ye Old log file.
log=log.bry

echo "Subject: World Update Report." > $log

#First we need to update our list.
emerge --sync
if [ $? -gt 0 ]; then
       echo "Sync Failed, wierd." >> $log
       #mail
       sendmail -F someone@thismachine someone@somewhere < $log
       exit
else
       echo "Sync Successful, move along." >> $log
fi

#Now let's toss the list of updatables in there for emailage.
emerge -uDpv world >> $log
if [ $(grep -c blocking $log) -gt 0 ]; then
       echo "There are package conflictions:" >> $log
       grep -i blocking $log >> $log
       #mail
       sendmail -F someone@thismachine someone@somewhere < $log
       exit
elif [ $(grep -c "0 packages" $log) -gt 0 ]; then
       echo "There are no updates available" >> $log
       #mail
       sendmail -F someone@thismachine someone@somewhere < $log
       exit
fi

emerge -uD world
if [ $? -gt 0 ]; then
       echo "Emerge failed." >> $log
       echo "" >> $log
       echo "Emerge log:" >> $log
       tail -20 /var/log/emerge.log >> $log
       #mail
       sendmail -F someone@thismachine someone@somewhere < $log
       exit
else
       echo "World update completed successfully." >> $log
       date >> $log
fi

revlist=revlist.bry
revdep-rebuild -p > $revlist
while [ $(grep -c "Now you can remove" $revlist) -gt 0 ]
do
       revdep-rebuild
       if [ $? -gt 0 ]; then
               echo "There was a problem with the rebuild" >> $log
               echo "" >> $log
               echo "Emerge.log:" >> $log
               tail -20 /var/log/emerge.log >> $log
               #mail
               sendmail -F someone@thismachine someone@somewhere < $log
               exit
       fi
       revdep-rebuild -p > $revlist
done
echo ""
echo "System completely updated, congratulations." >> $log
sendmail -F someone@thismachine someone@somewhere < $log


If you use this make sure to change someone@thismachine someone@somewhere to show what you want.

I have a cron job set up to run this script every Tuesday at 2:00 AM and it has been working great so far.

------------
edited to include updated script for comparison:

Code:

#!/bin/bash
###################
#
# Script to bring Ziggy up to the latest and greatest
#
###################

#Ye Old log file.
log=log.bry
worldtmp=worldtmp.bry
email="sendmail -F someplace@here someplace@somewhereelse"
blist=blist.bry
check=`find /etc -name "._cfg_*" -print|wc -l`
echo "Subject: World Update Report." > $log

if [ $1 == "--with-sync" || $2 == "--with-sync" ]; then
        #First we need to update our list.
        if emerge --sync; then
                echo "Sync Successful, move along." >> $log
        else
                echo "Sync Failed, wierd." >> $log
                #mail
                $email < $log
                exit
        fi
else
        echo "Skipping Sync..."
fi

#Now let's toss the list of updatables in there for emailage.
emerge -uDpv world >> $log
if grep -q blocking $log; then
        echo "There are package conflictions:" >> $log
        grep -i blocking $log >> $log
        #mail
        $email < $log
        exit
elif grep -q "0 packages" $log; then
        echo "There are no updates available" >> $log
        #mail
        $email < $log
        exit
fi
#Watch out for kernel update attempt and remove if found.
if grep -q gentoo-sources $log; then
        echo "" >> $log
        echo "Found a kernel update trying to happen." >> $log
        sed "/gentoo-sources/d" /var/lib/portage/world > $worldtmp
        mv $worldtmp /var/lib/portage/world
        echo "Removed kernel from world file, continuuing with emerge..." >> $log
        echo "" >> $log
fi

if [ $1 == "--with-blist" || $2 == "--with-blist" ]; then
        #Check world file for blacklisted items from predefined blacklist.
        if grep -q -f $blist $log; then
                echo "" >> $log
                echo "There were updates available that you personally have blocked.  Update cancelled.  You should probably babysit this one." >> $log
                echo "" >> $log
                echo "Blacklisted update(s):" >> $log
                grep -f $blist $log >> $log
                $email < $log
                exit
        fi
fi
#Begin update.
if emerge -uD world; then
        echo "World update completed successfully." >> $log
        date >> $log
else
        echo "World update completed successfully." >> $log
        date >> $log

        echo "Emerge failed." >> $log
        echo "" >> $log
        echo "Emerge log:" >> $log
        tail -20 /var/log/emerge.log >> $log
        #mail
        $email < $log
        exit
fi

#Rebuild until not necessary anymore.
revlist=revlist.bry
revdep-rebuild -p > $revlist
while grep -q "Now you can remove" $revlist; do
        revdep-rebuild
        if [ $? -gt 0 ]; then
                echo "There was a problem with the rebuild" >> $log
                echo "" >> $log
                echo "Emerge.log:" >> $log
                tail -20 /var/log/emerge.log >> $log
                #mail
                $email < $log
                exit
        fi
        revdep-rebuild -p > $revlist
done
#Check whether or not configs need updating.
if [ $check -gt 0 ]; then
        echo "There are configs that need updating." >> $log
        echo "Be sure to log on and update them soon." >> $log
        echo "" >> $log
else
        echo "No configs need updating." >> $log
        echo "" >> $log

echo ""
echo "System completely updated, congratulations." >> $log
#mail
$email < $log


Last edited by ziggysquatch on Tue May 27, 2008 6:57 pm; edited 4 times in total
Back to top
View user's profile Send private message
mamac
l33t
l33t


Joined: 29 Feb 2004
Posts: 890

PostPosted: Fri May 16, 2008 1:38 pm    Post subject: Reply with quote

Hi,

I'd rather 'emerge -uDNv world' and after that 'emerge --depclean' or maybe at least add the output of 'emerge --depclean -p' in the log

That's a good idea but to my opinion that has to go together with a good management of /etc/portage/package.mask, .use and .keywords (i.e. it could update your gentoo-sources and change the link to /usr/src/linux without asking anything).

Good job though!
_________________
Powered by Gentoo Linux since 2003
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Fri May 16, 2008 1:55 pm    Post subject: Reply with quote

Thanks for your input. I have had to manage my world file especially making sure that each time I update my kernel I remove it from the world file (although I have the build and symlink use flags shut off just in case).

That's a good idea to put the depclean in there I will have to add that.
Back to top
View user's profile Send private message
timeBandit
Bodhisattva
Bodhisattva


Joined: 31 Dec 2004
Posts: 2719
Location: here, there or in transit

PostPosted: Fri May 16, 2008 3:33 pm    Post subject: Re: World Update script running as a cron. Reply with quote

ziggysquatch wrote:
Feel free to tell me how lame my scripting skills are ....
How about few friendly pointers instead? :)

Many people (even experienced scripters sometimes) forget that you don't always need constructs like [ $? -ne 0 ] to test the return code of a process. The command can go right in the if statement. A zero exit code equates to true, nonzero to false. Examples in your script:
Code:
if emerge --sync; then
       echo "Sync Successful, move along." >> $log
else
       echo "Sync Failed, wierd." >> $log
fi
    ...
if emerge -uD world >>$log; then
       echo "World update completed successfully." >> $log
else
       echo "Emerge failed." >> $log
fi
The [ command is actually an external program so this can save many process forks in a large script. (I added the redirection to emerge just to show how it's done.)

Another trick: grep returns a zero status if it finds a match and its -q option suppresses all output. Thus:
Code:
emerge -uDpv world >> $log
if grep -q blocking $log; then
       echo "There are package conflicts:" >> $log
elif grep -q "0 packages" $log; then
       echo "There are no updates available" >> $log
fi

These techniques work with other conditional statements, too:
Code:
while grep -q "Now you can remove" $revlist; do
       if ! revdep-rebuild; then
               echo "There was a problem with the rebuild" >> $log
       fi
       revdep-rebuild -p > $revlist
done

Finally, if you must do this, you might want to also mail the log to a machine other than the one you're updating. emerge world via cron is somewhat discouraged because sooner or later, it will break your system.
_________________
Plants are pithy, brooks tend to babble--I'm content to lie between them.
Super-short f.g.o checklist: Search first, strip comments, mark solved, help others.
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Fri May 16, 2008 4:01 pm    Post subject: Reply with quote

Thanks for the excellent pointers. I will be doing some code cleanup pretty soon.

I know my system will eventually break from this but at least it will email me right away (the email tip is good too but I don't have a separate machine for mail yet). Before I wrote this I had to bring this machine up to date and it hadn't had a world update/revdep-rebuild ever nor a reinstall and it has been running for 4 years so I've gotten accustomed to fixing the brokenness that may arrise.

I spent about 3 weeks cleaning up the mess and that's when I decided to write the script. My laptop on the other hand gets updated regularly because I use it more often than this machine.
Back to top
View user's profile Send private message
AllenJB
Veteran
Veteran


Joined: 02 Sep 2005
Posts: 1285

PostPosted: Fri May 16, 2008 4:31 pm    Post subject: Reply with quote

TimeBandit already said it, but I'm going to say it again:


Running a world update as a cron job is a REALLY bad idea.

Things that can go wrong (off the top of my head, I'm sure there's more):

1) baselayout is updated, requiring some major config files to be updated and possibly other system critical files. For whatever reason, your system reboots... except it doesn't complete the reboot because the configuration is incorrect.

2) pam / shadow / some other login related package gets updated requiring configuration updates or perhaps other manual intervention for a major upgrade. In this case, for a remote system, you don't even need a reboot, all you need is for SSH to die for some reason. BAM! You can no longer log in to your system.

3) SSH / some other important service is upgraded on your system, requiring configuration updates to make the new version work. For whatever reason the server dies, but your server is set up to automatically restart it (using, for example, daemon tools, a cronjob or a simple inittab entry). BAM! The service no longer works as expected.

Also, when running world update cronjobs, you're going to have to ensure your backup script (you do run backups, right?) runs before the update. If it clashes, you could get a partially upgraded (and thus broken) backup. You could try to have it run after, but backing up a broken system (due to the above) is just plain silly.
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Fri May 16, 2008 4:44 pm    Post subject: Reply with quote

The backup does run before.

All of the things you mention are going to happen even if I am sitting right there doing the update myself. Also, all of that, including the baselayout problem (terrible thing) have happened to me before. That's the point of the log being mailed as soon as there is a problem or if there is a success. This way I can see what was updated and can know whether I should possibly check things out or attempt a reboot.

hmm. I should have it tell me if configs need updating. I will have to add that.
Back to top
View user's profile Send private message
Section_8
l33t
l33t


Joined: 22 May 2004
Posts: 627

PostPosted: Fri May 16, 2008 5:17 pm    Post subject: Reply with quote

Another thing to watch out for in automated updates like this: it emerges gentoo-sources with the symlink USE flag, then later emerges a package that installs a kernel module (such as nvidia-drivers). The kernel module builds with the wrong kernel version (the one that just emerged instead of the kernel you're actually running) and won't load.

I just have a simple weekly cron job the does emerge --sync and emerge --fetchonly -uDNv world. Like AllenJB, I won't actually emerge packages from a cron job. I also have -symlink on gentoo-sources.
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Fri May 16, 2008 5:22 pm    Post subject: Reply with quote

Yeah, I've got -symlink and -build on gentoo-sources but I've been removing gentoo-sources from the world file. I think I'm going to add something that checks for gentoo-sources in the world file and either fails out or removes it for me if it finds it.
Back to top
View user's profile Send private message
Section_8
l33t
l33t


Joined: 22 May 2004
Posts: 627

PostPosted: Fri May 16, 2008 5:57 pm    Post subject: Reply with quote

Another gotcha from automatic updates - a major enhancement to some package pulls in a truckload of dependencies you don't have installed. I like to see this coming and decide how to handle it. I'm a control freak with my system (which is why I have gentoo) and like to know what's getting installed.
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Tue May 20, 2008 7:04 pm    Post subject: Reply with quote

I posted the new updated script based on the suggestions by helpful people in this thread. I left the old one there for comparison so that the previous comments make sense and so that other people looking for script help might find an example that helps them.

I did add the if statement that looks for and, if it finds one, removes the gentoo-sources from the world file. Feel free to give me some new pointers because they are very helpful. You can even tell me how horrible I am for running this as a cron but I will still do it. It may be helpful for those who should think twice before setting up a cron that does this.
Back to top
View user's profile Send private message
hielvc
Advocate
Advocate


Joined: 19 Apr 2002
Posts: 2805
Location: Oceanside, Ca

PostPosted: Wed May 21, 2008 3:22 pm    Post subject: Reply with quote

You could add this to your script as preproccessor :lol:
demerge - emerge the other way around
_________________
An A-Z Index of the Linux BASH command line
Back to top
View user's profile Send private message
jcat
Veteran
Veteran


Joined: 26 May 2006
Posts: 1337

PostPosted: Thu May 22, 2008 7:01 am    Post subject: Reply with quote

While I agree that auto updates with portage can be troublesome, you could try and make your script a bit more bullet-proof to try avoid issues.

Add a check for some more keywords like "baselayout", "pam", "shadow" etc and abort the update if they are found in the list of updatable packages.



Cheers,
jcat
Back to top
View user's profile Send private message
ziggysquatch
Apprentice
Apprentice


Joined: 16 Nov 2004
Posts: 172
Location: /USA/Minnesota

PostPosted: Tue May 27, 2008 7:02 pm    Post subject: Reply with quote

Posted the new script with a black list option so you can have a file that lists packages that should stop an update from occurring (thanks jcat).

Also added the ability to use options to control whether a sync is required or if you want to look at the black list or not (mostly used while testing or if the update failed for some reason and you want/need to run it again).

I also fixed some painfully obvious flaws in the if statements... :oops:

Thanks everyone for your comments. Let me know if you see anything else or if I can make it cooler.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum