diff -ruN e-smith-backup-2.4.0.p28/root/sbin/e-smith/console-menu-items/usbBackup.pl e-smith-backup-2.4.0.p29/root/sbin/e-smith/console-menu-items/usbBackup.pl --- e-smith-backup-2.4.0.p28/root/sbin/e-smith/console-menu-items/usbBackup.pl 1969-12-31 16:00:00.000000000 -0800 +++ e-smith-backup-2.4.0.p29/root/sbin/e-smith/console-menu-items/usbBackup.pl 2014-03-20 22:04:42.000000000 -0700 @@ -0,0 +1,3 @@ +package esmith::console::perform_backup; +use esmith::console::perform_backup; +return new esmith::console::perform_backup; diff -ruN e-smith-backup-2.4.0.p28/root/sbin/e-smith/console-menu-items/usbRestore.pl e-smith-backup-2.4.0.p29/root/sbin/e-smith/console-menu-items/usbRestore.pl --- e-smith-backup-2.4.0.p28/root/sbin/e-smith/console-menu-items/usbRestore.pl 1969-12-31 16:00:00.000000000 -0800 +++ e-smith-backup-2.4.0.p29/root/sbin/e-smith/console-menu-items/usbRestore.pl 2014-03-20 22:04:42.000000000 -0700 @@ -0,0 +1,3 @@ +package esmith::console::perform_restore; +use esmith::console::perform_restore; +return new esmith::console::perform_restore; diff -ruN e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/backup_running.pm e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/backup_running.pm --- e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/backup_running.pm 1969-12-31 16:00:00.000000000 -0800 +++ e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/backup_running.pm 2014-03-20 22:04:42.000000000 -0700 @@ -0,0 +1,61 @@ +package esmith::console::backup_running; +use strict; +use warnings; +use esmith::ConfigDB; +use Locale::gettext; + +sub new +{ + my $class = shift; + my $self = {}; + bless $self, $class; + return $self; +} + +sub doit +{ + my ($self, $console, $db) = @_; + #------------------------------------------------------------- + # check whether a backup in process and incomplete + #------------------------------------------------------------- + my $restore_db = esmith::ConfigDB->open_ro("/etc/e-smith/restore"); + return unless $restore_db; + + my $restore_state = $restore_db->get_prop('restore', 'state') || 'idle'; + + return unless ($restore_state eq 'running'); + my ($rc, $choice) = $console->message_page + ( + title => gettext("Inconsistent system state"), + text => + gettext("********** Inconsistent system state detected ***********") . + "\n\n" . + gettext("The restoration of a system backup was running and incomplete at the time of the last reboot. The system should not be used in this state.") . + "\n\n" . + gettext("Consult the User Guide for further instructions."), + ); + + ($rc, $choice) = $console->yesno_page + ( + title => gettext("System will be halted"), + text => + gettext("The server will now be halted.") . + "\n\n" . + gettext("Consult the User Guide for recovery instructions.") . + "\n\n" . + gettext("Do you wish to halt the system right now?"), + ); + + return unless ($rc == 0); + + system("/usr/bin/tput", "clear"); + system("/sbin/e-smith/signal-event", "halt"); + + # A bit of a hack to avoid the console restarting before the + # reboot takes effect. + + sleep(600); +} + +1; + diff -ruN e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm --- e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm 1969-12-31 16:00:00.000000000 -0800 +++ e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm 2014-03-20 22:04:42.000000000 -0700 @@ -0,0 +1,256 @@ +package esmith::console::perform_backup; +use strict; +use warnings; +use esmith::ConfigDB; +use esmith::console; +use esmith::util; +use Locale::gettext; +use esmith::Backup; +#use Filesys::DiskFree; +#use Sys::Filesystem; + +sub new +{ + my $class = shift; + my $self = { + name => gettext("Perform backup to removable media"), + order => 80, + }; + bless $self, $class; + return $self; +} + +sub name +{ + return $_[0]->{name}; +} + +sub order +{ + return $_[0]->{order}; +} + +sub backup_size +{ + my $self = shift; + +} + +sub make_backup_callback +{ + my ($device, $CompressionLevel) = @_; + return sub { + my $fh = shift; + my @backup_list = esmith::Backup->restore_list; + + unless (open(DU, "-|")) + { + open(STDERR, ">/dev/null"); + exec qw(/usr/bin/du -sb), map { "/$_" } @backup_list; + } + my $backup_size = 0; + while () + { + next unless (/^(\d+)/); + $backup_size += $1; + } + close DU; + + open(OLDSTDOUT, ">&STDOUT"); + unless (open(STDOUT, ">/mnt/bootstrap-console-backup/smeserver.tgz")) + { + return gettext("Could not create backup file on device").": $!\n"; + } + + open(OLDSTDERR, ">&STDERR"); + my $logger = open(STDERR, "|-"); + die "Can't fork: $!\n" unless defined $logger; + + unless ($logger) + { + exec qw(/usr/bin/logger -p local1.info -t console_backup); + } + + my $status = 0; + + my $gzip = open(GZIP, "|-"); + return "could not run gzip" unless defined $gzip; + unless ($gzip) + { + close $fh; + exec "gzip", $CompressionLevel; + } + + my $pv = open(PV, "|-"); + return "could not run pv" unless defined $pv; + unless ($pv) + { + open(STDOUT, ">&GZIP"); + close GZIP; + open(STDERR, ">&$fh"); + exec qw(pv -i 0.2 -n -s), $backup_size + } + + my $tar = fork; + return "could not run tar" unless defined $tar; + unless ($tar) + { + open(STDOUT, ">&PV"); + close PV; + close GZIP; + close $fh; + chdir "/"; + exec qw(tar cf -), grep { -e $_ } @backup_list; + } + waitpid($tar, 0); + warn "status from tar was $?\n" if $?; + unless (close PV) + { + $status |= $! ? $! : $?; + warn "status from pv is $status\n" if $status; + } + unless (close GZIP) + { + $status |= $! ? $! : $?; + warn "status from gzip is $status\n" if $status; + } + + open(STDOUT, ">&OLDSTDOUT"); + open(STDERR, ">&OLDSTDERR"); + close(OLDSTDERR); + close(OLDSTDOUT); + return $status ? gettext("Backup failed. Look at the log files for more details.") : gettext("Backup successfully created."); + }; +} + +sub doit +{ + my ($self, $console, $db) = @_; + my @backup_list = esmith::Backup->restore_list; + + $ENV{PATH} = "/bin:/usr/bin"; + $ENV{HOME} = "/root"; + + my $compressionLevel = $db->get_prop("backupconsole", "CompressionLevel") || "-6"; + my ($rc, $choice) = $console->yesno_page + ( + title => gettext("Create Backup to removable media"), + defaultno => 1, + text => + gettext("Do you wish to create backup on removable media?"), + ); + return unless $rc == 0; + INITIATE_BACKUP: + ($rc, $choice) = $console->yesno_page + ( + title => gettext("Insert media to use for backup"), + left => gettext("Next"), + right => gettext("Cancel"), + text => + gettext("Insert removable media, then hit the enter key."), + ); + return unless $rc == 0; + sleep(3); + my @dirs = (); + my @labels = (); + foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) { + $udi =~ m/^(\S+)/; + + my $is_readonly = qx(hal-get-property --udi $1 --key volume.is_mounted_read_only); + + if ($is_readonly eq "false\n") { + + my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted); + + if ($is_mounted eq "false\n") { + my $blkdev = qx(hal-get-property --udi $1 --key block.device); + $blkdev =~ m/^(\S+)/; + push @dirs, $1; + } + if ($is_mounted eq "false\n") { + my $vollbl = qx(hal-get-property --udi $1 --key volume.label); + $vollbl =~ m/^(\S+)/; + if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';} + chomp $vollbl; + push @labels, lc($vollbl); + } + } + } + unless ($dirs[0]) + { + ($rc, $choice) = $console->message_page + ( + title => gettext("Writable backup medium not found"), + right => gettext("Back"), + text => + gettext("No removable and/or writable media or device found"), + ); + goto INITIATE_BACKUP; + } + mkdir("/mnt/bootstrap-console-backup"); + + my $device = $dirs[0]; + if (defined $dirs[1]) + { + my $count=1; + my @args = map { $count++ . '.' => $_ } @dirs; + + my ($rc, $choice) = $console->menu_page + ( + title => gettext("Choose device to use for backup"), + text => ("@dirs \n @labels"), + argsref => \@args, + left => gettext("Cancel"), + right => gettext("OK"), + ); + goto INITIATE_BACKUP unless ($rc == 0); + my %args_hash = ( @args ); + $device = $args_hash{$choice}; + } + system("/bin/mount", "$device", "/mnt/bootstrap-console-backup"); + + use File::stat; + my $st = stat("/mnt/bootstrap-console-backup/smeserver.tgz"); + if ($st) + { +# TODO +# old backup exists - what do we want to do with it? + my $size = $st->size; + } + + $console->infobox( + title => gettext("Preparing for backup"), + text => gettext("Please stand by while the system is prepared for backup..."), + ); + + my $backup_size = 0; + system("/sbin/e-smith/signal-event", "pre-backup"); + unless (open(DU, "-|")) + { + open(STDERR, ">/dev/null"); + exec qw(/usr/bin/du -sb), map { "/$_" } @backup_list; + } + while () + { + next unless (/^(\d+)/); + $backup_size += $1; + } + close DU; + + $console->gauge(make_backup_callback("/mnt/bootstrap-console-backup",$compressionLevel), 'title' => gettext("Creating backup file")); + + system("/bin/umount", "/mnt/bootstrap-console-backup"); + rmdir("/mnt/bootstrap-console-backup"); + system("/sbin/e-smith/signal-event", "post-backup"); + ($rc, $choice) = $console->message_page + ( + title => gettext("Backup complete"), + text => + gettext("Remove removable media, then hit the enter key."), + ); +} + +#use esmith::console; +#esmith::console::perform_backup->new->doit(esmith::console->new, +# esmith::ConfigDB->open); +1; diff -ruN e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm --- e-smith-backup-2.4.0.p28/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 1969-12-31 16:00:00.000000000 -0800 +++ e-smith-backup-2.4.0.p29/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 2014-03-20 21:35:22.000000000 -0700 @@ -0,0 +1,182 @@ +package esmith::console::perform_restore; +use strict; +use warnings; +use esmith::ConfigDB; +use esmith::console; +use Locale::gettext; + +sub new +{ + my $class = shift; + my $self = { + name => gettext("Restore from removable media"), + order => installOrder(), + }; + bless $self, $class; + return $self; +} + + +sub name +{ + return $_[0]->{name}; +} + +sub order +{ + return $_[0]->{order}; +} + +sub doit +{ + my ($self, $console, $db) = @_; + if ($db->get_prop('bootstrap-console', 'Run') eq 'yes') # called from bootstrap console + { + return if ($db->get_value('PasswordSet') eq 'yes'); # too late + } + return if ($db->get_prop('bootstrap-console', 'Restore') eq 'disabled'); + my ($rc, $choice) = $console->yesno_page + ( + title => gettext("Restore From Backup"), + defaultno => 1, + text => + gettext("Do you wish to restore from backup?"), + ); + return unless $rc == 0; + mkdir("/mnt/bootstrap-console-backup"); + system("/etc/init.d/messagebus", "start"); + system("/etc/init.d/haldaemon", "start"); + INITIATE_RESTORE: + ($rc, $choice) = $console->yesno_page + ( + title => gettext("Insert media containing backup"), + left => gettext("Next"), + right => gettext("Cancel"), + text => + gettext("Insert removable media containing your backup file, then hit the enter key."), + ); + unless ($rc == 0) { + system("/etc/init.d/haldaemon", "stop"); + system("/etc/init.d/messagebus", "stop"); + rmdir("/mnt/bootstrap-console-backup"); + return; + } + sleep(3); + my @dirs; + @dirs = (); + foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) { + $udi =~ m/^(\S+)/; + my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted); + + if ($is_mounted eq "false\n") { + my $blkdev = qx(hal-get-property --udi $1 --key block.device); + $blkdev =~ m/^(\S+)/; + push @dirs, $1; + } + } + unless ($dirs[0]) + { + ($rc, $choice) = $console->message_page + ( + title => gettext("Backup medium not found"), + right => "Try again", + text => + gettext("No removable media or device found"), + ); + goto INITIATE_RESTORE; + } + my $device = $dirs[0]; + if (defined $dirs[1]) + { + my $count=1; + # FIXME use better regexp + my @args = map { /(.*)/; $count++ . '.' => $1 } @dirs; + + my ($rc, $choice) = $console->menu_page + ( + title => gettext("Choose device to restore from"), + text => gettext("Please select which device contains the backup file you wish to restore from."), + argsref => \@args, + left => gettext("Cancel"), + right => gettext("OK"), + ); + goto INITIATE_RESTORE unless ($rc == 0); + my %args_hash = ( @args ); + $device = $args_hash{$choice}; + } + system("/bin/mount", "$device", "/mnt/bootstrap-console-backup"); + sleep(1); + + unless (-f "/mnt/bootstrap-console-backup/smeserver.tgz") + { + system("/bin/umount", "$device"); + ($rc, $choice) = $console->message_page + ( + title => gettext("Backup file not found"), + right => "Try again", + text => + gettext("No backup file found"), + ); + goto INITIATE_RESTORE; + } + use File::stat; + my $st = stat("/mnt/bootstrap-console-backup/smeserver.tgz"); + my $size = $st->size; + + ($rc, $choice) = $console->yesno_page + ( + title => gettext("Start restore from backup"), + text => + gettext("Backup file found:") . " smeserver.tgz ($device) " . + gettext("size") . " $size " . gettext("bytes") . + "\n\n" . + gettext("Do you wish to restore from this file?"), + ); + unless ($rc == 0) { + system("/bin/umount", "$device"); + goto INITIATE_RESTORE; + } + system("/sbin/e-smith/signal-event", "pre-restore"); + system("(cd / ; cat /mnt/bootstrap-console-backup/smeserver.tgz | + pv -n -s $size | + gunzip | + tar xf - > /dev/null ) 2>&1 | + dialog --backtitle 'Restoring data' --guage 'Progress' 7 70"); + system("/bin/umount", "$device"); + system("/etc/init.d/haldaemon", "stop"); + system("/etc/init.d/messagebus", "stop"); + rmdir("/mnt/bootstrap-console-backup"); + system("/sbin/e-smith/signal-event", "post-upgrade"); + + unless ( $self->{bootstrap} ) + { + $db->set_prop("bootstrap-console", "Run", "yes"); + $db->set_prop("bootstrap-console", "ForceSave", "yes"); + $db->set_prop("bootstrap-console", "Restore", "disabled"); + + system("/usr/bin/tput", "clear"); + system("/sbin/e-smith/signal-event", "reboot"); + + # A bit of a hack to avoid the console restarting before the + # reboot takes effect. + + sleep(600); + } + return; +} + +# Determine if this server is a fresh install for restore from backup +# Earlier the expression used was ($db->get_value('PasswordSet') eq 'yes') +# To prevent a restore return a negative number +# To allow a restore choose an appropiate sort order, eg 90 +sub installOrder +{ + my $order = (`grep :x:5...: /etc/group`) ? -1 : 90; + return $order; +} + +#use esmith::console; +#esmith::console::perform_restore->new->doit(esmith::console->new, +# esmith::ConfigDB->open); +1; +