RHEL4 -> RHEL5 upgrade script

So, this has been done for months, but I haven’t gotten around to posting it. So, here it is. Upgrade RHEL4 to RHEL5 with an LVM snapshot of the running system and a backout script (you need to have free space in the VG to do this, really — pure LVM snapshots work, but it’ll fill up to 100% when you try to back out and leave it unbootable if your snapshot isn’t the same size as the regular partitions).

It assumes HP’s packages for Proliants are installed, and a tarball of a yum root with the packages you need to install are present. It rips out any package not on our list of “needed” packages (yours may be different). If you’re actually using a RHEL CD or a full repo (rather than just pushing what you need to remote sites), change the repo definition accordingly.

Variable names are odd, but those are easy enough to fix if you want something more descriptive of what it does:

#!/usr/bin/env perl
 
use Sys::Hostname;
my $host = hostname;
system("mkdir /var/upgrade");
open(my $output, ">/var/upgrade/upgrade.log");
system("cd /boot; tar jcf bootback.tbz *; mv bootback.tbz /root");
system("mkdir /root/bootsave");
system('tail -n 8 /boot/grub/menu.lst |head -n 4| sed -e \'s/LogVol00/ssLogVol00/\' | sed -e \'s/Red.*/Rollback to EL4/\' > /root/bootsave/menu.lst');
system("cp -v /boot/*2.6* /root/bootsave");
system("cp /etc/fstab /etc/fstab.original");
system("cp /etc/fstab /etc/fstab.rollback");
system('sed -i -e \'s/\(LogVol[0-9]*\) /ss\1 /\' /etc/fstab.rollback');
system("cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.save");
system('sed -i -e \'s/\(.*[^#]filter.*sdb.*\)/#\1/\' /etc/lvm/lvm.conf');
system('sed -i -e \'s:\("a/.*/"\):\1, "r|/dev/cdrom|":\' /etc/lvm/lvm.conf');
 
#I'm not happy about it, but our lastlog is huge, and there's no space for it anywhere in the snapshot. Save off a copy, at least.
#system("cp /var/log/lastlog /root && gzip /root/lastlog && cat /dev/null > /var/log/lastlog");
system("cat /dev/null > /var/log/lastlog");
 
system("cp -v /var/adm/sw/products/backout.pl /usr/bin/backout");
#Try to take snapshots.  Die if it fails, since we're not committed yet, and we want to ensure we can
#abort if necessary
my @lvs = `lvs --noheading --units k| awk '{print \$1, \$4}' | grep -v ss`;
system("mkdir /mnt/snap");
chomp(@lvs);
for my $lv (@lvs) {
        my @args = split(' ', $lv);
        my ($size) = $args[1] =~ m/^(\d+)/;
        $size = int($size * .3);
        #Create new LVM filesystems to back up to
        my $cmd =  "lvcreate --name ss$args[0] --size $size\K VolGroup00 >> /var/upgrade/upgrade.log";
        system($cmd) == 0 or die "Error: $? (probably insufficient free extents)\n";
        $cmd = "mkfs.ext3 /dev/VolGroup00/ss$args[0] >> /var/upgrade/upgrade.log";
        system($cmd);
        $cmd = "mount /dev/VolGroup00/ss$args[0] /mnt/snap";
        system($cmd) == 0 or die "Can't mount snapshot!\n";
        my $mount = `grep $args[0] /etc/fstab | awk '{print \$2}'`;
        chomp($mount);
        $cmd = "cd $mount; find . -xdev | cpio -pvdaum /mnt/snap >> /var/upgrade/upgrade.log";
        system($cmd) == 0 or die "Error in cpio: $? (probably not enough free space)\n";
        $cmd = "umount /mnt/snap";
        system($cmd);
}
 
#Save off fstab
system("mount /dev/VolGroup00/ssLogVol00 /mnt/snap") == 0 or die "Can't mount snapshot!\n";
system("cp /etc/fstab.rollback /mnt/snap/etc/fstab");
system("umount /mnt/snap");
 
#Remove packages before the upgrade from a known-good list
#Anything that differs, kill it
open(my $file, "/var/adm/sw/products/stillinstalled.fs");
my @good = <$file>;
chomp(@good);
close($file);
 
my @current = `rpm -qa --queryformat "%{NAME}.%{ARCH}\n" | grep -v none | grep -v svt`;
chomp(@current);
 
my %known = map { $_ => 1 } @good;
my %present = map {$_ => 1 } @current;
 
my @killrpms;
 
foreach my $rpm (keys %present) {
        unless ($known{$rpm}) {
                push(@killrpms, $rpm);
        }
}
 
my $rpmkillcmd = "rpm -e --nodeps --allmatches " . join(' ',@killrpms);
print "$rpmkillcmd\n";
rpmrun($rpmkillcmd);
 
#Extract the upgrade files
system("mkdir -p /tmp/upgrade");
system("tar -xzvf /var/adm/sw/products/rhel53upgrade.tgz -C /tmp/upgrade");
 
my @rpms = `rpm -qa --queryformat "\%\{NAME\}.\%\{ARCH\}\n"`;
chomp(@rpms);
 
my @specific = `rpm -qa --queryformat "%{NAME}-%{VERSION}.%{ARCH}\n"| egrep "elfutils|elfutils-libelf|pwlib|rpm-libs"`;
 
chomp(@specific);
my $specdel = join(' ', @specific);
 
my @nuke = `rpm -qa --queryformat "%{NAME}-%{VERSION}.%{ARCH}\n" | egrep "libselinux|util-linux|e2fsprogs"`;
chomp(@nuke);
my @cracklib = `rpm -qa --queryformat "%{NAME}-%{VERSION}.%{ARCH}\n" | egrep "cracklib.*i386"`;
chomp(@cracklib);
my @nukers = (@nuke, @cracklib);
 
my @findkernels = `rpm -qa |grep kernel`;
chomp(@findkernels);
 
my @deleters;
my @oldkernels;
my %del = map {$_ => 1} qw{VFlib2 caching-nameserver autofs kudzu pcmcia-cs xorg-x11 newt-perl hal crypto-utils gdm openjade docbook-dtds scrollkeeper pilot-link octave kdemultimedia kdebase xorg-x11-xdm system-config-printer system-config-printer-gui hal-cups-utils linuxwacom OPC OPCCOMM dce redhat-logos redhat-menus redhat-artwork system-config-securitylevel system-config-securitylevel-tui HPOvEaAgt HPOvLcja HPOvPCO HPOvBbc HPOvPacc HPOvLczC HPOvEaAes HPOvEaAja HPOvSecCo HPOvAgtEx HPOvLcko HPOvCtrl HPOvEaAzC HPOvSecCC HPOvXercesA HPOvLces HPOvDepl HPOvXpl HPOvPerlA HPOvXalanA HPOvEaAko HPOvConf};
 
my %postdel = map {$_ => 1} qw{lha bluez-bluefw desktop-backgrounds-extra gtk-engines ttfprint gsl lam-libs ash krbafs tclx fribidi Omni-foomatic Omni mysqlclient10 FreeWnn-libs w3c-libwww};
my @postdeleters;
 
foreach my $rpm (@rpms) {
        my ($shortname) = $rpm =~ m/(.*)\..*/;
        if ($del{$shortname}) {
                push(@deleters, $rpm);
        }
        if ($postdel{$shortname}) {
                push(@postdeleters, $rpm);
        }
}
 
foreach my $kernel (@findkernels) {
        push(@oldkernels, $kernel);
}
 
my $removelist = join(' ', @deleters);
my $removekernels = join(' ', @oldkernels);
my $nukelist = join(' ',@nukers);
 
my %version = map {$_ => 1} qw{redhat-release-notes-5Server.x86_64.rpm redhat-release-5Server.x86_64.rpm};
 
my %prepinstall = map {$_ => 1} qw(rpm-libs.x86_64.rpm rpm.x86_64.rpm yum.noarch.rpm rpm-python.x86_64.rpm popt.x86_64.rpm glibc.x86_64.rpm glibc-common.x86_64.rpm beecrypt.x86_64.rpm glibc-headers.x86_64.rpm glibc-devel.x86_64.rpm binutils.x86_64.rpm elfutils.x86_64.rpm elfutils-libelf.x86_64.rpm elfutils-libs.x86_64.rpm beecrypt-python.x86_64.rpm python.x86_64.rpm python-devel.x86_64.rpm python-elementtree.x86_64.rpm python-sqlite.x86_64.rpm sqlite.x86_64.rpm sqlite-devel.x86_64.rpm python-urlgrabber.noarch.rpm neon.x86_64.rpm libxml2.x86_64.rpm libxml2-python.x86_64.rpm db4.x86_64.rpm libselinux.x86_64.rpm libsepol.x86_64.rpm mcstrans.x86_64.rpm m2crypto.x86_64.rpm krb5-libs.x86_64.rpm openssl.x86_64.rpm readline.x86_64.rpm python-iniparse.noarch.rpm yum-metadata-parser.x86_64.rpm nss.x86_64.rpm glib2.x86_64.rpm e2fsprogs.x86_64.rpm e2fsprogs-libs.x86_64.rpm nspr.x86_64.rpm);
 
my @instlist;
my $packdir = "/tmp/upgrade/base/";
opendir(my $dir, $packdir);
my %cdromfiles = map {$_ => 1} readdir($dir);
closedir($dir);
my @versions;
my @installers;
my $kernel;
foreach my $entry (keys %cdromfiles) {
        my ($packname, $packarch) = $entry =~ m/(.*?)-\d[^S].*(\..*?\.rpm)/;
        my $package = $packname . $packarch;
        if ($version{$package}) {
                $entry = $packdir . $entry;
                push (@versions, $entry);
        }
        if ($prepinstall{$package}) {
                $entry = $packdir . $entry;
                push (@installers, $entry);
        }
        if ($entry =~ /kernel-\d.*/) {
                $kernel = $packdir . $entry;
        }
}
 
my $installlist = join(' ', @installers);
my $versionlist = join(' ', @versions);
 
print "rpm -Uvh $versionlist\n";
rpmrun("rpm -Uvh $versionlist");
print "rpm --import /tmp/upgrade/base/RPM-GPG-KEY-redhat-release\n";
rpmrun("rpm --import /tmp/upgrade/base/RPM-GPG-KEY-redhat-release");
print "rpm -Uvh --nodeps --replacefiles $installlist\n";
rpmrun("rpm -Uvh --nodeps --replacefiles $installlist");
print "rm -f /var/lib/rpm/__* && rpm --rebuilddb\n";
system("rm -f /var/lib/rpm/__* && rpm --rebuilddb");
if ($removelist != "") {
        print "rpm -e --allmatches --nodeps $removelist\n";
        rpmrun("rpm -e --allmatches --nodeps $removelist");
}
if ($specdel != "") {
        print "rpm -e --allmatches $specdel\n";
        rpmrun("rpm -e --allmatches $specdel");
}
open(my $yumconf, "> /etc/yum.repos.d/iso.repo");
print $yumconf "[rh53]\nbaseurl=file:///tmp/upgrade/base\nenabled=1\ngpgcheck=0";
close($yumconf);
system("yum clean all");
rpmrun("rpm -ivh --nodeps $kernel");
print "rpm -e --nodeps $removekernels\n";
rpmrun("rpm -e --nodeps $removekernels");
rpmrun("rpm -ivh --nodeps --replacefiles /var/adm/sw/products/openssl097a-0.9.7a-9.el5_2.1.i386.rpm");
if ($nukelist != "") {
        print "rpm -e --nodeps $nukelist\n";
        rpmrun("rpm -e --nodeps $nukelist");
}
rpmrun("rpm -e hpasm hprsm hponcfg; yum -y --exclude=expect upgrade && rpm -e --nodeps e2fsprogs.i386; yum -y install kernel-devel bind bind-chroot compat-openldap openmotif22 e2fsprogs-libs nss.i386 swig numactl enscript guile rpm-libs.i386 libtool-ltdl nspr wdaemon sqlite.i386 libgcj.i386 elfutils-libelf.i386");
my $postdeletelist = join(' ', @postdeleters);
if ($postdeletelist != "") {
        rpmrun("rpm -e --allmatches $postdeletelist");
}
rpmrun("mkdir -p /usr/bin/X11 && ln -s /usr/bin/mwm /usr/bin/X11/mwm && ln -s /usr/bin/xauth /usr/bin/X11/xauth && ln -s /usr/bin/xmodmap /usr/bin/X11/xmodmap && ln -s /usr/bin/xset /usr/bin/X11/xset && ln -s /usr/bin/xsetroot /usr/bin/X11/xsetroot && ln -s /usr/bin/xterm /usr/bin/X11/xterm");
system("cp -v /var/adm/sw/products/postinstall.pl /usr/bin/postinstall");
system("chmod 777 /tmp");
system("echo 'nohup /usr/bin/postinstall &' >> /etc/rc.local");
system("grub-install /dev/your/root");
finished("success");
 
 
 
sub finished {
        my ($status) = @_;
        system("cp -v /root/bootsave/*2.6* /boot");
        system('sed -i -e \'s/2.6.*ELsmp/2.6.18-128.el5/g\' /boot/grub/menu.lst');
        system('sed -i -e \'s/Red Hat.*up/RHEL5/g\' /boot/grub/menu.lst');
        system('sed -i -e \'s/2.6.*EL/2.6.18-128.el5/g\' /boot/grub/menu.lst');
        system("cat /root/bootsave/menu.lst >> /boot/grub/menu.lst");
        if ($status =~ /failed/) {
                my $msg = "Upgrade failed!  Please boot into the snapshot and run /usr/bin/backout.";
                notify($msg);
                die "Upgrade on $host failed!  Please boot into the snapshot and run /usr/bin/backout.\n";
        }
        else {
                my $msg = "Upgrade on $host successful.  Rebooting...";
                notify($msg);
                print "Upgrade successful.  Rebooting...\n";
                system("chmod +x /etc/rc.d/rc.local");
                system("reboot -t now");
        }
}
 
sub rpmrun {
        my ($cmd) = @_;
        print "$cmd\n";
        #We're probably past the point of no return here, so I'm not going to die(), but I'll still print
        system("$cmd >> /var/upgrade/upgrade.log 2>&1") == 0 or failed($_);
 
}
 
sub failed {
        my ($message) = @_;
        print "Failed on $message packages\n";
        finished("failed");
}
 
sub notify {
        my ($message) = @_;
        my @admins = ('youraddress@whatever.domain');
        foreach my $admin (@admins) {
                system("echo $message \| mailx -s '$host upgrade' $admin");
        }
}

List of packages:

acl.x86_64
acpid.x86_64
alchemist.i386
alchemist.x86_64
alsa-lib.i386
alsa-lib.x86_64
anacron.x86_64
aspell-en.x86_64
aspell.i386
aspell.x86_64
atk.i386
atk.x86_64
attr.x86_64
at.x86_64
audiofile.i386
audiofile.x86_64
audit-libs.i386
audit-libs.x86_64
audit.x86_64
authconfig.x86_64
basesystem.noarch
bash.x86_64
bc.x86_64
beecrypt.i386
beecrypt.x86_64
bind-libs.i386
bind-libs.x86_64
bind-utils.x86_64
binutils.x86_64
bitmap-fonts.noarch
bitstream-vera-fonts.noarch
bzip2-libs.i386
bzip2-libs.x86_64
bzip2.x86_64
chkconfig.x86_64
chkfontpath.x86_64
compat-dapl-1.2.5.x86_64
compat-db.i386
compat-libgcc-296.i386
compat-libstdc++-296.i386
compat-libstdc++-33.i386
comps-extras.noarch
coreutils.x86_64
cpio.x86_64
cpp.x86_64
cracklib-dicts.x86_64
cracklib.x86_64
crash.x86_64
crontabs.noarch
cups-libs.i386
cups-libs.x86_64
cups.x86_64
curl.i386
cyrus-sasl.i386
cyrus-sasl-md5.i386
cyrus-sasl-md5.x86_64
cyrus-sasl-plain.i386
cyrus-sasl-plain.x86_64
cyrus-sasl.x86_64
db4.i386
db4.x86_64
dbus-glib.i386
dbus-glib.x86_64
dbus.i386
dbus-python.x86_64
dbus.x86_64
desktop-backgrounds-basic.noarch
desktop-backgrounds-extra.noarch
desktop-file-utils.x86_64
device-mapper.i386
device-mapper.x86_64
diffutils.x86_64
dmraid.i386
docbook-dtds.noarch
dos2unix.x86_64
dosfstools.x86_64
e2fsprogs.x86_64
ed.x86_64
eject.x86_64
elfutils-libelf.x86_64
elfutils.x86_64
esound.i386
esound.x86_64
ethtool.x86_64
expat.i386
expat.x86_64
expect.i386
fbset.x86_64
filesystem.x86_64
file.x86_64
findutils.x86_64
finger.x86_64
fontconfig.i386
fontconfig.x86_64
fonts-xorg-base.noarch
foomatic.x86_64
freetype.i386
freetype.x86_64
ftp.x86_64
gail.i386
gail.x86_64
gamin.i386
gamin.x86_64
gawk.x86_64
gcc.x86_64
GConf2.i386
GConf2.x86_64
gdbm.i386
gdbm.x86_64
gd.i386
gd.x86_64
gettext.x86_64
ghostscript-fonts.noarch
ghostscript.i386
ghostscript.x86_64
glib2.i386
glib2.x86_64
glibc-common.x86_64
glibc-devel.x86_64
glibc-headers.x86_64
glibc.i686
glibc-kernheaders.x86_64
glibc.x86_64
glib.i386
glib.x86_64
gmp.i386
gmp.x86_64
gnome-keyring.i386
gnome-keyring.x86_64
gnome-mime-data.x86_64
gnome-python2-bonobo.x86_64
gnome-python2-canvas.x86_64
gnome-python2-gtkhtml2.x86_64
gnome-python2.x86_64
gnome-vfs2.i386
gnome-vfs2.x86_64
gnupg.x86_64
gnutls.i386
gnutls.x86_64
gpm.i386
gpm.x86_64
grep.x86_64
groff.x86_64
grub.x86_64
gtk2.i386
gtk2.x86_64
gtkhtml2.i386
gtkhtml2.x86_64
guile.i386
gzip.x86_64
hal.i386
hal.x86_64
hdparm.x86_64
hesiod.i386
hesiod.x86_64
hotplug.x86_64
htmlview.noarch
hwdata.noarch
info.x86_64
initscripts.x86_64
intltool.x86_64
iproute.x86_64
ipsec-tools.x86_64
iptables.x86_64
iptstate.x86_64
iputils.x86_64
jpackage-utils.noarch
jwhois.x86_64
kbd.x86_64
kernel-devel.x86_64
kernel-ib.x86_64
kernel-smp-devel.x86_64
kernel-smp.x86_64
kernel-utils.x86_64
kernel.x86_64
keyutils-libs.x86_64
keyutils.x86_64
krb5-auth-dialog.x86_64
krb5-libs.i386
krb5-libs.x86_64
krb5-workstation.x86_64
krbafs.i386
kudzu.x86_64
less.x86_64
lftp.x86_64
lha.x86_64
libacl.i386
libacl.x86_64
libart_lgpl.i386
libart_lgpl.x86_64
libattr.i386
libattr.x86_64
libbonobo.i386
libbonoboui.x86_64
libbonobo.x86_64
libcap.i386
libcap.x86_64
libcroco.i386
libcroco.x86_64
libf2c.i386
libgcc.i386
libgcc.x86_64
libgcrypt.i386
libgcrypt.x86_64
libgfortran.i386
libglade2.i386
libglade2.x86_64
libgnomecanvas.i386
libgnomecanvas.x86_64
libgnomecups.i386
libgnomecups.x86_64
libgnome.i386
libgnomeprint22.i386
libgnomeprint22.x86_64
libgnomeprintui22.i386
libgnomeprintui22.x86_64
libgnomeui.x86_64
libgnome.x86_64
libgpg-error.i386
libgpg-error.x86_64
libgsf.x86_64
libibverbs.i386
libibverbs.x86_64
libIDL.i386
libIDL.x86_64
libidn.i386
libidn.x86_64
libieee1284.i386
libjpeg.i386
libjpeg.x86_64
libmng.i386
libmng.x86_64
libobjc.i386
libogg.i386
libogg.x86_64
libpcap.i386
libpcap.x86_64
libpng10.i386
libpng.i386
libpng.x86_64
libraw1394.i386
libraw1394.x86_64
librdmacm.i386
librdmacm.x86_64
librsvg2.x86_64
libselinux.i386
libselinux.x86_64
libsepol.i386
libsepol.x86_64
libstdc++.i386
libstdc++.x86_64
libtermcap.i386
libtermcap.x86_64
libtiff.i386
libtiff.x86_64
libusb.i386
libusb.x86_64
libuser.i386
libuser.x86_64
libvorbis.i386
libvorbis.x86_64
libxml2.i386
libxml2-python.x86_64
libxml2.x86_64
libxslt.i386
libxslt.x86_64
logrotate.x86_64
logwatch.noarch
lshw.x86_64
lsof.x86_64
lvm2.x86_64
m4.x86_64
mailcap.noarch
mailx.x86_64
MAKEDEV.x86_64
make.x86_64
man-pages.noarch
man.x86_64
mcelog.x86_64
mdadm.x86_64
metacity.x86_64
mgetty.x86_64
mikmod.i386
mingetty.x86_64
mkinitrd.x86_64
mktemp.x86_64
module-init-tools.x86_64
mpage.x86_64
mtools.x86_64
mtr.x86_64
mt-st.x86_64
nano.x86_64
ncurses.i386
ncurses.x86_64
nc.x86_64
netconfig.x86_64
netdump.x86_64
net-snmp-libs.i386
net-snmp-libs.x86_64
net-tools.x86_64
newt.i386
newt.x86_64
nss_db.i386
nss_db.x86_64
ntp.x86_64
ntsysv.x86_64
numactl.x86_64
Omni-foomatic.x86_64
Omni.i386
Omni.x86_64
OpenIPMI-libs.x86_64
OpenIPMI.x86_64
openldap.i386
openldap.x86_64
openmotif21.i386
openmotif.i386
openssh-askpass-gnome.x86_64
openssh-askpass.x86_64
openssh-clients.x86_64
openssh-server.x86_64
openssh.x86_64
openssl096b.i386
openssl.i686
openssl.x86_64
ORBit2.i386
ORBit2.x86_64
pam_ccreds.i386
pam_ccreds.x86_64
pam.i386
pam_krb5.i386
pam_krb5.x86_64
pam_passwdqc.i386
pam_passwdqc.x86_64
pam_smb.i386
pam_smb.x86_64
pam.x86_64
pango.i386
pango.x86_64
parted.x86_64
passwd.x86_64
patch.x86_64
pax.x86_64
pciutils.x86_64
pcre.i386
pcre.x86_64
pdksh.x86_64
perl-DateManip.noarch
perl-DBI.x86_64
perl-Filter.x86_64
perl-HTML-Parser.x86_64
perl-HTML-Tagset.noarch
perl-libwww-perl.noarch
perl-libxml-enno.noarch
perl-libxml-perl.noarch
perl-Parse-Yapp.noarch
perl-URI.noarch
perl.x86_64
perl-XML-Dumper.noarch
perl-XML-Encoding.noarch
perl-XML-Parser.x86_64
pinfo.x86_64
pnm2ppa.x86_64
popt.i386
popt.x86_64
ppp.x86_64
procmail.x86_64
procps.x86_64
psacct.x86_64
psmisc.x86_64
psutils.x86_64
pygtk2-libglade.x86_64
pygtk2.x86_64
pyOpenSSL.x86_64
pyorbit.x86_64
python.x86_64
pyxf86config.x86_64
PyXML.x86_64
qt.i386
qt.x86_64
quota.x86_64
rdate.x86_64
rdist.x86_64
readline.i386
readline.x86_64
redhat-logos.noarch
redhat-lsb.i386
redhat-lsb.x86_64
redhat-menus.noarch
redhat-release.x86_64
rhgb.x86_64
rhnlib.noarch
rhpl.x86_64
rootfiles.noarch
rpm-libs.i386
rpm-libs.x86_64
rpm-python.x86_64
rpm.x86_64
rp-pppoe.x86_64
rsync.x86_64
scrollkeeper.i386
scrollkeeper.x86_64
SDL.i386
sed.x86_64
sendmail.x86_64
setarch.x86_64
setserial.x86_64
setup.noarch
setuptool.x86_64
sgml-common.noarch
shadow-utils.x86_64
shared-mime-info.x86_64
sharutils.x86_64
slang.i386
slang.x86_64
specspo.noarch
speex.i386
speex.x86_64
startup-notification.i386
startup-notification.x86_64
statserial.x86_64
stunnel.x86_64
sudo.x86_64
switchdesk.noarch
symlinks.x86_64
sysfsutils.x86_64
sysklogd.x86_64
sysstat.x86_64
system-config-date.noarch
system-config-display.noarch
system-config-keyboard.noarch
system-config-language.noarch
system-config-lvm.noarch
system-config-mouse.noarch
system-config-rootpassword.noarch
system-config-securitylevel-tui.x86_64
system-config-securitylevel.x86_64
system-config-services.noarch
system-config-users.noarch
system-logviewer.noarch
SysVinit.x86_64
talk.x86_64
tar.x86_64
tcl.i386
tcl.x86_64
tclx.i386
tcpdump.x86_64
tcp_wrappers.i386
tcp_wrappers.x86_64
tcsh.x86_64
telnet.x86_64
termcap.noarch
time.x86_64
tk.i386
tk.x86_64
tmpwatch.x86_64
traceroute.x86_64
ttmkfdir.x86_64
tzdata.noarch
udev.x86_64
umb-scheme.x86_64
unix2dos.x86_64
unzip.x86_64
urw-fonts.noarch
usbutils.x86_64
usermode-gtk.x86_64
usermode.x86_64
utempter.i386
utempter.x86_64
util-linux.x86_64
vasclnts.x86_64
vasclnts.x86_64
vas.x86_64
vconfig.x86_64
vim-common.x86_64
vim-enhanced.x86_64
vim-minimal.x86_64
vixie-cron.x86_64
vnc-server.x86_64
vte.i386
vte.x86_64
WFBwfssh-maint.x86_64
WFBwfssh.x86_64
wget.x86_64
which.x86_64
words.noarch
Xaw3d.i386
xinetd.x86_64
xinitrc.noarch
xml-common.noarch
xmlsec1.i386
xmlsec1-openssl.i386
xmlsec1-openssl.x86_64
xmlsec1.x86_64
xorg-x11-deprecated-libs.i386
xorg-x11-deprecated-libs.x86_64
xorg-x11-font-utils.x86_64
xorg-x11-libs.i386
xorg-x11-libs.x86_64
xorg-x11-Mesa-libGL.i386
xorg-x11-Mesa-libGLU.i386
xorg-x11-Mesa-libGLU.x86_64
xorg-x11-Mesa-libGL.x86_64
xorg-x11-tools.x86_64
xorg-x11-twm.x86_64
xorg-x11.x86_64
xorg-x11-xauth.x86_64
xorg-x11-xfs.x86_64
xsri.x86_64
xterm.x86_64
zip.x86_64
zlib.i386
zlib.x86_64

Backout script:

#!/usr/bin/perl
open(my $fstab, "/etc/fstab.original");
my @lines = <$fstab>;
close($fstab);
chomp(@lines);
 
#Check if we're on the live partitions
my $test = `mount`;
if ($test =~ /-LogVol\d+/) {
        die "Please ensure you are in the snapshot before running the backout!\n";
}
 
my %mapping;
for my $line (@lines) {
        if ($line =~ /Vol/) {
                my @fields = split(/\s+/, $line);
                $mapping{$fields[0]} = $fields[1];
        }
}
 
system("mkdir /mnt/backout");
foreach my $vol (keys %mapping) {
        print "$vol -> $mapping{$vol}\n";
        print "mount $vol /mnt/backout\n";
        system("mount $vol /mnt/backout");
 
        #Clean it out
        system("rm -rf /mnt/backout/*");
 
        #Step into whatever directory matches and cpio it to the appropriate filesystem
        #Copy special nodes and don't cross filesystems
        print "cd $mapping{$vol}; find . -xdev | cpio -pvdaum /mnt/backout\n";
        system("cd $mapping{$vol}; find . -xdev | cpio -pvdaum /mnt/backout") == 0 or die "Error in cpiO: $? (probably not enough free space)\n";
        print "umount /mnt/backout\n";
        system("umount /mnt/backout");
}
#restore fstab
system("mount /dev/VolGroup00/LogVol00 /mnt/backout");
system("cp -v /etc/fstab.original /mnt/backout/etc/fstab");
system("cp -v /etc/fstab.original /etc/fstab");
 
#restore /boot
my $cmd = "tar -xjvf /root/bootback.tbz -C /boot";
print "$cmd\n";
system($cmd);
system("reboot -t now");

Postinstall script (for anything you need done after the reboot, emails you to let you know it’s done):

#!/usr/bin/perl
 
use Sys::Hostname;
my $host = hostname;
 
 
system("rpm -e hpasm hprsm; yum -y install hponcfg hpacucli hp-health >> /var/log/upgrade.log 2>&1");
 
my @admins = ('youraddress@whatever.domain');
foreach my $admin (@admins) {
        system("cat /etc/motd | sed -e 's/~//g' | sed -e '/^\\s*\$/d' | mailx -s '$host upgraded' $admin");
}
 
#Take us out of rc.local
system("sed -i -e 's/.*postinstall//' /etc/rc.local");