diff options
-rwxr-xr-x | rescue-Flash/scripts/upgrade | 185 | ||||
-rwxr-xr-x | rescue-Flash/scripts/upgrade.merge-users | 52 |
2 files changed, 237 insertions, 0 deletions
diff --git a/rescue-Flash/scripts/upgrade b/rescue-Flash/scripts/upgrade new file mode 100755 index 000000000..17fb51b1b --- /dev/null +++ b/rescue-Flash/scripts/upgrade @@ -0,0 +1,185 @@ +#!/bin/bash + +# import functions library +source rescue_common + +tmpdir="/tmp/flash-rescue-root" +rootdir="$tmpdir/pen" + + +config_files_network_scripts="etc/sysconfig/network-scripts/ifcfg-* \ + etc/sysconfig/network-scripts/cellular.d \ + etc/sysconfig/network-scripts/vpn.d \ + etc/sysconfig/network-scripts/wireless.d" + +config_files_users="etc/passwd etc/shadow etc/group etc/gshadow" +config_files_time="etc/localtime etc/ntp etc/ntp.conf" +config_files="etc/sysconfig/* $config_files_users $config_files_time \ + etc/wpa_supplicant.conf etc/shorewall etc/kde \ + etc/udev/rules.d/61-*_config.rules" + +config_files_to_remove="etc/sysconfig/harddrake2" + +function prepare() { + + modprobe unionfs > /dev/null 2>&1 + modprobe squashfs > /dev/null 2>&1 + modprobe loop > /dev/null 2>&1 + + mkdir -p $rootdir + mkdir -p $tmpdir/squash + mkdir -p $tmpdir/user + mkdir -p $tmpdir/union + + if ! mount_usbroot $rootdir; then + return 1 + fi + + mount -t ext2 -o loop $sys_loop $tmpdir/user > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "Error mounting system.loop" + return 1 + fi + + return 0 +} + +function get_existing_rpms() { + + mount -t squashfs -o loop $sfs_loop $tmpdir/squash > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "Error mounting distrib.sqfs" + return 1 + fi + + mount -t unionfs -o dirs=$tmpdir/user=rw:$tmpdir/squash=ro \ + none $tmpdir/union + if [ $? -ne 0 ]; then + echo "Error creating union of distrib.sqfs and system.loop" + return 1 + fi + + chroot $tmpdir/union rpm -qa > /tmp/existing_rpms.list + if [ $? -ne 0 ]; then + echo "Error getting list of rpms installed prior to upgrade" + return 1 + fi + + umount $tmpdir/union > /dev/null 2>&1 + umount $tmpdir/squash > /dev/null 2>&1 + + return 0 +} + +function move_files() { + for i in $*; do + dir=`dirname $i` + [ "$dir" = "." ] || mkdir -p ..keep/$dir + mv $i ..keep/$dir + done +} + +function remove_non_user_nor_config_files() { + + cd $tmpdir/user + + rm -rf $config_files_to_remove + + if [ -e ..keep ]; then + mv ..keep ..keep.bak + fi + if [ -e ..keep ]; then + echo "remove_non_user_nor_config_files can't work with existing temp dir" + return 1 + fi + + mkdir ..keep + + move_files $config_files_network_scripts + rm -rf etc/sysconfig/network-scripts + + move_files home $config_files + rm -rf * + rm -rf .[^.]* + + mv ..keep/* . + rmdir ..keep + + cd - + + return 0 +} + +function copy_new_version() { + + return 0 +} + +function merge_config_files() { + + mount -t squashfs -o loop $sfs_loop $tmpdir/squash > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "Error mounting distrib.sqfs" + return 1 + fi + + ./upgrade.merge-users $tmpdir/user/etc $tmpdir/squash/etc + + return 0 +} + +function doit() { + + if [ -d $tmpdir/user/var/lib/rpm/Packages ]; then + get_existing_rpms || return 1 + fi + + remove_non_user_nor_config_files || return 1 + + copy_new_version + + merge_config_files || return 1 + + return 0 +} + +function cleanup() { + cd / + + umount $tmpdir/union > /dev/null 2>&1 + umount $tmpdir/user > /dev/null 2>&1 + umount $tmpdir/squash > /dev/null 2>&1 + umount $rootdir > /dev/null 2>&1 + + rmdir $tmpdir/union $tmpdir/user $tmpdir/squash 2> /dev/null + rmdir $rootdir $tmpdir 2> /dev/null +} + +clear +trap cleanup SIGINT + +version="" +if ! insert_pendrive; then + exit 1 +fi + +if [ x"$version" = x"1.0" ]; then + sys_loop="$rootdir/loopbacks/system.loop" + sfs_loop="$rootdir/loopbacks/distrib.sqfs" +else + sys_loop="$rootdir/.loopbacks/system.loop" + sfs_loop="$rootdir/.loopbacks/distrib.sqfs" +fi + +if ! prepare; then + cleanup + exit 1 +fi + +if ! doit; then + cleanup + exit 1 +fi + +cleanup +exit 0 diff --git a/rescue-Flash/scripts/upgrade.merge-users b/rescue-Flash/scripts/upgrade.merge-users new file mode 100755 index 000000000..297960e91 --- /dev/null +++ b/rescue-Flash/scripts/upgrade.merge-users @@ -0,0 +1,52 @@ +#!/usr/bin/perl + +use MDK::Common; + +@ARGV == 2 or die "merge_users <existing files dir> <new files dir>\n"; + +my ($existing_dir, $new_dir) = @ARGV; + +merge('passwd', 'shadow'); +merge('group', 'gshadow'); + +sub merge { + my ($main, $shadow) = @_; + + my @new = cat_("$new_dir/$main"); + my %new_ids = map { (split ':')[2] => $_ } @new; + + my %names_to_have; + foreach (cat_("$existing_dir/$main")) { + my @l = split ':'; + next if $l[0] eq 'nobody' || $l[2] < 500; + if (my $e = $new_ids{$l[2]}) { + $_ eq $e or warn "ERROR: conflicting entries:\n $_ $e"; + } else { + push @new, $_; + $names_to_have{$l[0]} = 1; + } + } + + my @new_shadow = grep { !/^root:/ } cat_("$new_dir/$shadow"); + foreach (cat_("$existing_dir/$shadow")) { + my ($name) = split ':'; + if ($name eq 'root') { + unshift @new_shadow, $_; + } elsif ($names_to_have{$name}) { + push @new_shadow, $_; + } + } + + if (rename "$existing_dir/$main", "$existing_dir/$main.old") { + output("$existing_dir/$main", @new); + } else { + warn "rename $existing_dir/$main failed: $?\n"; + <STDIN>; + } + if (rename "$existing_dir/$shadow", "$existing_dir/$shadow.old") { + output("$existing_dir/$shadow", @new_shadow); + } else { + warn "rename $existing_dir/$shadow failed: $?\n"; + <STDIN>; + } +} |