LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-30-2010, 05:55 AM   #1
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Rep: Reputation: 0
grub.conf fixer


Hi, my first post here, sorry if I've put this in the wrong place. Really looking for some scripting help or some ideas on how to automate a tedious task.

My issues is this. I have about 100 client RHEL5 machines. All are identical build/software/partitioning etc. They are dual booting windows XP. The default is to have them booting into XP at the moment. However in linux, updates are run randomly as people use linux etc. Some machines may get a lot of use on the linux side where others get very little. This ends up causing issues where some grud.conf files are changed to defualt boot to linux after updates to kernels etc. There can be kernel differences on the machines too due to the random use of linux on these machines.

Now, what I would like to achieve would be to run a script that would connect to these machines, read the grub.conf and to then set the default os value to be whatever OS I choose. In this case I assume it would be easiest to count the "titles" and then find which one is "Windows XP" and thus set the default to whatever number XP would be. I assume you could read the titles in order, and set them to a variable, count them and then find which number is titled "Windows XP", minus 1 to bring the start number to 0 as grub.conf requires and then edit the defaul to this number. Hope that's clear.

I have a pretty basic knowledge of scripting. I've written some scripts to update the systems when I desire, add key pairs, copy files, add mount points etc. However the script I need to edit grub is well beyond my knowledge and as much as I've searched, I've been unable to find something that would suit my needs. I'd like it to just be a shell script so I'd be able to edit it as rquired if that's possible. Would also help me learn more.

Any help would be appreciated, I can't bear the idea of going around the machines again manually editing grub.conf for hours.

Thanks
 
Old 06-30-2010, 06:29 AM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Code:
#!/bin/sh --
CONF=/boot/grub/grub.conf; [ -e $CONF ] || exit 127
COUNT=0; grep ^title $CONF|while read TITLE; do
 [ "${TITLE//ows XP/}" = "${TITLE}" ] ||\
 { sed -i "s|^default=0$|default=$COUNT|" $CONF; break; }
 ((COUNT++)); done; exit 0
...however I doubt the script is the hardest part. For instance if changing GRUB is only the tip of the iceberg then maybe it could be a good time to look into system configuration management packages? On a lower level the script might error out but does nothing to detect /boot being on a read-only partition, immutable files or other errors. Also users with root account access can easily change things back at any time... Wrt control, ever thought about PXE, BTW?

Last edited by unSpawn; 06-30-2010 at 12:38 PM. Reason: //More *is* more
 
Old 06-30-2010, 10:58 AM   #3
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Ok thanks. That's a really nice start. This really would be one of the few things I would need to do on these machines. They get reinstalled yearly but are used for many different types of teaching etc so they can get a bit messed up. That's why having a script to run every now and then would be perfect for me. I used your code and added a bit so I can churn through all the computers currently logged into linux.

#!/bin/bash

echo -----------------------------
echo RESET GRUB TO BOOT WINDOWS XP
echo -----------------------------

#Read list of machines and run commands below

cat list.txt|while read pc; do

#check pc is online
ping –c 1 $pc
Y=$?

#If ping successful connect and rename grub. Problem here is how to run this on remote machines. Maybe use ssh?
if [ $Y –eq 0 ]; then

GRUB=/boot/grub/grub.conf
COUNT=0; grep ^title $GRUB|while read TITLE; do
[ “${TITLE//ows XP/}” = “${TITLE}” ] ||\
#problem with sed part, doesn't seem to change the default value unless default=0, if not 0 it just appends the number or does nothing.
{ sed –i “s|^default=0$ | default=$COUNT| “ $CONF; break; }
((COUNT++)) ; done; exit 0

else
echo “Ping error code $Y on $pc” >> log.txt

fi
done

Not sure how well this would work. First problem I have is that it will only change the default value if it is 0 not if it is anything else. Secondly, running the edit on the machine would mean I needed to connect. In many ways there's no reason why I couldn't just use the code you gave and add it as a cron job. Having it running via the network would just be as a matter of interest and for the sake of learning. Not sure if I could just do something like (which doesn't seem likely):

ssh $pc COUNT=0; grep ^title $GRUB|while read TITLE; do
ssh $pc [ “${TITLE//ows XP/}” = “${TITLE}” ] ||\

In the sense of running via the network, detecting if the machine responds to ping is good but not perfect as it still responds if booting into Windows XP causing some delays. Perhaps there is a way to check for linux instead of pinging?

Anyway, thank you very much for the help, I appreciate it. Already very promissing
 
Old 06-30-2010, 01:19 PM   #4
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Original Poster
Rep: Reputation: 0
No worries, I'm not going to mess around with trying to run this remotely. Was thinking I could scp the grub.conf and then edit it on my machine and then scp it back to the remote host but a cron job makes the most sense to me anyway.

Also just changed 0$ to .$ and it now changes any number as long as it's only 1 digit. Although I can't deny I don't really understand the wildcards in sed yet. Was obviouslly hoping default=* would work to replace anything with the string default=$COUNT. But .$ seems to do the job anyway so it's all good.

Thank you very very much. Just saved me a ton of time.
 
Old 06-30-2010, 01:40 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by broomx View Post
it will only change the default value if it is 0 not if it is anything else.
'sed –i "s|^default=.*$|default=$COUNT|"'?


Quote:
Originally Posted by broomx View Post
running the edit on the machine would mean I needed to connect. In many ways there's no reason why I couldn't just use the code you gave and add it as a cron job.
...or an /etc/inittab entry or a "@boot" cron task or a yum wrapper or a SysV initscript or a /etc/rc.d/rc.local addition to name just a few (un)common options.


Quote:
Originally Posted by broomx View Post
Having it running via the network would just be as a matter of interest and for the sake of learning.
See tentakel, fanout, dsh, mussh, clusterssh and other distributed SSH solutions?


Quote:
Originally Posted by broomx View Post
In the sense of running via the network, detecting if the machine responds to ping is good but not perfect as it still responds if booting into Windows XP causing some delays. Perhaps there is a way to check for linux instead of pinging?
Pull may be easier than push. You shouldn't do this in R/L but a "pull" cronjob like 'curl http://address_of_management_host/pa...ipt.sh|/bin/sh' (or something like 'webjob') Just Works. Maybe interrogate a DHCP lease table. That way you only ping hosts that are on-line. Or maybe use nmap OS scan. Or maybe let the hosts contact your management station with a certain payload triggering things. Or maybe just connect to ssh? 'curl -s host_address:22|grep -q SSH' (provided XP doesn't run Cygwin OpenSSH).
 
1 members found this post helpful.
Old 06-30-2010, 02:20 PM   #6
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Original Poster
Rep: Reputation: 0
The ssh test is awesome. None of the xp machines would run cygwin so it's a perfect test. Once again, many thanks. I may just persist and make a network script for the fun of it and for the learning experience. I like a lot of error correction so I'll have fun with that.

Still thinking about work and working on scripts when I'm home and should be chilling may seen lame but I'm enjoying it

You've been more than helpful. A very pleasent experience for my first post here. Glad I finally registered
 
Old 06-30-2010, 03:20 PM   #7
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Well, this is what I've come up with and it works very well so far. I guess it's a pretty long winded and not very efficient but it seems to go pretty fast and does the job. I'm sure my loopig is also totally terrible and inefficient too.

Code:
#!/bin/bash

set +v
echo ------------------------------
echo SET DEFAULT BOOT TO WINDOWS XP
echo ------------------------------
echo ""

cat list.txt|while read pc; do

echo "Checking for Linux on $pc"
curl -s $pc:22|grep -q SSH
LINUXTEST=$?

if [ $LINUXTEST -eq 0 ]; then
        echo "Linux decected on $pc"; echo "Getting grub.conf from $pc"
        scp -q -o StrictHostKeyChecking=no $pc:/boot/grub/grub.conf .
        FILEPULL=$?

                if [ $FILEPULL -eq 0 ]; then
                        echo "Setting grub.conf to boot WIndows XP by default"
                        CONF=/home/user1/scripts/grub/grub.conf; [ -e $CONF ] || exit 127
                        COUNT=0; grep ^title $CONF|while read TITLE; do
                        [ "${TITLE//ows/}" = "${TITLE}" ] ||\
                        { sed -i "s|^default=.*.|default=$COUNT|" $CONF; EDITCODE=$?; break; }
                        ((COUNT++)); done;

                                if [ $EDITCODE=0 ]; then
                                        echo "grub.conf edit complete"
                                        scp -q -o StrictHostKeyChecking=no grub.conf $pc:/boot/grub/grub.conf && echo "push copy success" && echo ""
                                        rm -f grub.conf
                                else
                                        echo "edit failed"
                                        echo ""
                                        rm -f grub.conf
                                fi

                else
                        echo "grub.conf copy failed from $pc"
                        echo ""
                fi
else
        echo "$pc not online or not running Linux"
        echo""
fi
done
 
Old 06-30-2010, 06:01 PM   #8
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Shame you didn't go for pull but OK, thanks for posting back your final script version!
 
Old 06-30-2010, 07:00 PM   #9
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
As you're using GRUB, another approach to your problem might be to use the default saved and savedefault directives to just have the system(s) boot into the last used OS.

Can you control which Linux distribution(s) are installed on the various systems, and do you do so? Some distributions (e.g., Ubuntu) have already switched to GRUB2, and most distributions have GRUB2 in their repositories. So, potentially, any system user with "root" access via su or sudo could replace the older boot loader with some other one, and your script would end up changing an unused file. (And older Ubuntu distributions use menu.lst instead of grub.conf as the GRUB configuration file,)

I'd strongly endorse unSpawn's suggestion that you look for a system configuration management package.
 
1 members found this post helpful.
Old 07-01-2010, 04:09 AM   #10
broomx
LQ Newbie
 
Registered: Jun 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Some system configuration management package would be nice, I'll look into it.

Thanks
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can't open grub.conf/lilo.conf with kate being root cola Slackware 6 09-28-2009 07:26 AM
mpeg fixer for linux system Dassu Linux - Software 3 11-06-2007 12:47 AM
Is lilo.conf file format is same for grub.conf? Chundo Linux - Newbie 1 01-30-2006 06:21 PM
create lilo.conf or grub.conf through commands newpenguin Linux - Software 1 11-28-2003 08:22 PM
lilo.conf and grub.conf no read access shanenin Linux - Software 1 10-02-2003 03:53 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:31 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration