/[smeserver]/rpms/e-smith-backup/sme9/e-smith-backup-2.4.0-consoleBackup.patch
ViewVC logotype

Annotation of /rpms/e-smith-backup/sme9/e-smith-backup-2.4.0-consoleBackup.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Sun Mar 6 04:52:54 2016 UTC (8 years, 8 months ago) by wellsi
Branch: MAIN
CVS Tags: e-smith-backup-2_4_0-45_el6_sme, e-smith-backup-2_4_0-46_el6_sme, HEAD
Overhaul of console backup

1 wellsi 1.1 diff -urN e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm
2     --- e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm 1969-12-31 16:00:00.000000000 -0800
3     +++ e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm 2016-01-09 16:32:40.000000000 -0800
4     @@ -0,0 +1,503 @@
5     +#----------------------------------------------------------------------
6     +# Copyright 2015 Ian Wells
7     +# This program is free software; you can redistribute it and/or
8     +# modify it under the same terms as Perl itself.
9     +#----------------------------------------------------------------------
10     +
11     +package esmith::BlockDevices;
12     +
13     +use strict;
14     +use warnings;
15     +use English '-no_match_vars';
16     +use Carp;
17     +use File::Path qw(make_path remove_tree);
18     +use POSIX qw(:sys_wait_h strftime);
19     +use Locale::gettext;
20     +use File::stat;
21     +use v5.10.1;
22     +use Taint::Util;
23     +use Readonly;
24     +use File::Find;
25     +
26     +use vars qw($VERSION @ISA @EXPORT_OK);
27     +
28     +@ISA = qw(Exporter);
29     +
30     +=head1 NAME
31     +
32     +esmith::BlockDevices - Module to handle block devices
33     +
34     +=head1 SYNOPSIS
35     +
36     + use esmith::BlockDevices;
37     + my $devices = BlockDevices->new ();
38     +
39     +=head1 DESCRIPTION
40     +
41     +This module provides an abstracted interface to the
42     +block devices used for backup/restore
43     +
44     +=cut
45     +
46     +my $EMPTY = q{};
47     +
48     +sub new
49     +{
50     + my $class = shift;
51     + my $self = {
52     + _blox => $EMPTY,
53     + mount => $EMPTY,
54     + _fstype => $EMPTY,
55     + allowmount => $EMPTY,
56     + @_,
57     + };
58     + bless $self, $class;
59     + return $self;
60     +}
61     +
62     +sub lsblk
63     +{
64     +#ToDo add some comments
65     + my %blox; # a hash to hold the device information
66     +
67     + my $short = qx(/bin/lsblk -sdn -o KNAME);
68     + my @long = qx(/bin/lsblk -P -b -o KNAME,MAJ:MIN,RM,RO,TYPE,MOUNTPOINT,FSTYPE,LABEL,UUID,MODEL,SIZE,STATE,MODE,OWNER,GROUP);
69     + # Not all of this information may be needed currently, but it does not affect the processing time
70     + untaint ($short);
71     + untaint (@long);
72     +
73     + my $devicemodel= $EMPTY;
74     +
75     + for (@long)
76     + {
77     + my @line = split /\"\s/s;
78     + my $name;
79     + if ($line[0] =~ /KNAME=\"(.*)/s)
80     + {
81     + $name = $1;
82     + }
83     + else {carp 'Could not match KNAME'; last;} # should never occur.
84     +
85     + $blox{$name}{tip} = ($short =~ m/^$name$/sm) ? 1 : 0;
86     +
87     + for (@line)
88     + {
89     + my ($key,$value) = split /=/s;
90     + $value =~ s/\"//sg;
91     + $blox{$name}{$key} = trim($value);
92     + }
93     + if ($blox{$name}{TYPE} =~ /rom|disk/s)
94     + {
95     + $devicemodel = $blox{$name}{MODEL};
96     + }
97     + else
98     + {
99     + $blox{$name}{MODEL} = trim($devicemodel);
100     + }
101     + $blox{$name}{SIZEH} = scaleIt($blox{$name}{SIZE});
102     + }
103     + return \%blox;
104     +}
105     +
106     +sub findValidFS
107     +{
108     +# Find all filesystem types that are supported
109     + my %fs; # a hash to hold the supported filesystem type information
110     +
111     + my @cmd = `cat /proc/filesystems`;
112     + foreach (@cmd)
113     + {
114     + if (/.*\/(.*?)\.ko/s){$fs {$1}=$1;}
115     + }
116     + @cmd = `ls -1 /lib/modules/\$(uname -r)/kernel/fs/*/*ko`;
117     + foreach (@cmd)
118     + {
119     + if (/.*\/(.*?)\.ko/s){$fs {$1}=$1;}
120     + }
121     + return \%fs;
122     +}
123     +
124     +sub scanBlocks
125     +{
126     + # Scan all the block devices
127     + # This takes some seconds on systems with many filesystems
128     + my ($self) = @_;
129     + $self->{_blox} = lsblk;
130     + $self->{_fstype} = findValidFS;
131     + return;
132     +}
133     +
134     +sub list
135     +{
136     + my ($self) = @_;
137     + my @dirs=();
138     + my $hashref = $self->{_blox};
139     +
140     + foreach my $drive (keys %{$hashref})
141     + {
142     + push @dirs, $drive;
143     + }
144     +
145     + return @dirs;
146     +}
147     +
148     +sub checkBackupDriveSize
149     +{
150     + my ($self,$drive, $size) = @_;
151     + my $hashref = $self->{_blox};
152     + my $sz = $EMPTY;
153     + my $mntdir = $self->{mount};
154     + Readonly my $VFAT_LIMIT => 2147483648;
155     + Readonly my $KBYTE => 1024;
156     +
157     + # size > drive size
158     + if ($size > $hashref->{$drive}{SIZE})
159     + {
160     + return 1; # filesystem too small
161     + }
162     +
163     + # FAT32 drive and size > 2G
164     + if (($size > $VFAT_LIMIT) && ($hashref->{$drive}{FSTYPE} eq 'vfat'))
165     + {
166     + return 2; # filesystem vfat limit
167     + }
168     +
169     +#ToDo add a check here to see if mounting is allowed by db value
170     +
171     + # check mount and find actual size
172     + if ($self->mountable ($drive)) # Only check filesystems that appear mountable
173     + {
174     + $self->mount ($drive);
175     + my $filesize = -s "$mntdir/smeserver.tgz";
176     +
177     + # Check free disk space
178     + my $df = qx(/bin/df -P \"$mntdir\");
179     + if ($df =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\d*%)/s)
180     + {
181     + my $dsize = ($3 * $KBYTE) + ($filesize //= 0);
182     + if ($size > $dsize) # not enough space
183     + {
184     + $sz = 3; # filesystem has too little free space
185     + }
186     + }
187     + else # fail (never seen in testing)
188     + {
189     + $sz = 4; # Failed to get disk size
190     + }
191     + $self->unmount;
192     + }
193     + return $sz;
194     +}
195     +
196     +# Check each block device
197     +# Return two arrays, valid drives, invalid drives
198     +sub checkBackupDrives
199     +{
200     + my ($self,$bsize) = @_;
201     + my @valid = ();
202     + my @invalid = ();
203     + $self->scanBlocks; # scan all block devices
204     + my $hashref = $self->{_blox};
205     + my $allowmount = $self->{'allowmount'}; # Are mounted drives allowed in $checks.
206     + my $checks = 'UU RO FS'; # These checks are always valid
207     + $checks .= ' MO' if ($allowmount eq 'enabled');
208     + $checks .= ' SZ' if ($bsize); # Only run the size check when a valid size is given
209     +
210     + foreach my $drive (keys %{$hashref})
211     + {
212     + $hashref->{$drive}{REASON} = $EMPTY; # Reason for a filesystem being (in)valid
213     + next unless $hashref->{$drive}{tip}; #Ignore drives that have child filesystems
214     +
215     + # drives mounted on /, /boot, or [SWAP] are never valid for backups
216     + next if ($hashref->{$drive}{MOUNTPOINT} =~ /^\/boot$|^\[SWAP\]$|^\/$/s );
217     +
218     + # validate each filesystem against the checks
219     + foreach my $check (split / /s, $checks)
220     + {
221     + for ($check)
222     + {
223     + if (/^UU/si) # No UUID
224     + {
225     + $hashref->{$drive}{REASON} .='UU ' unless $self->uuid ($drive); last;
226     + }
227     + if (/^RO/si) # Read Only
228     + {
229     + $hashref->{$drive}{REASON} .='RO ' if $self->readonly ($drive); last;
230     + }
231     + if (/^FS/si) # Invalid filesystem
232     + {
233     + $hashref->{$drive}{REASON} .='FS ' unless $self->validFS ($drive); last;
234     + }
235     + if (/^MO/si) # Mounted
236     + {
237     + $hashref->{$drive}{REASON} .='MO ' if $self->mountpoint ($drive); last;
238     + }
239     + if (/^SZ/si) # filesystem size, this includes mounting to check free space
240     + {
241     + $hashref->{$drive}{REASON} .='SZ ' if $self->checkBackupDriveSize ($drive, $bsize);
242     + #ToDo the return value contains the reason why there is insufficient space, but this is not used yet.
243     + last;
244     + }
245     + { carp "not supported yet in checkBackupDrives: $check"; } # Should never be seen
246     + }
247     + }
248     + if ($hashref->{$drive}{REASON})
249     + {
250     + push @invalid, $drive;
251     + }
252     + else
253     + {
254     + push @valid, $drive;
255     + }
256     + }
257     + return (\@valid, \@invalid);
258     +}
259     +
260     +sub findBackup
261     +{
262     + my ($self, $kname, $foundref, $maxDepth, $count) = @_;
263     + my $hashref = $self->{_blox};
264     + my $mountpoint = $self->{'mount'};
265     + my $file = 'smeserver.tgz';
266     +
267     + $self->mount ($kname);
268     + sleep 1;
269     +
270     + # start with the absolute path
271     + my $findRoot = Cwd::realpath($mountpoint);
272     +
273     + # determine the depth of our beginning directory
274     + my $begDepth = 1 + grep { length } File::Spec->splitdir($findRoot);
275     +
276     + find (
277     + {
278     + preprocess => sub
279     + { @_ if (scalar File::Spec->splitdir($File::Find::dir) - $begDepth) <= $maxDepth },
280     + wanted => sub
281     + {
282     + if (($_ =~ m/^$file/s) && ($File::Find::name =~ qr|^([-+@\w\s./:\\]+)$| )) # if matching the backup name
283     + {
284     + $$count++;
285     + my $sb = stat $1;
286     + ${$foundref}{$$count}{count}=$$count;
287     + ${$foundref}{$$count}{device}=$kname;
288     + ${$foundref}{$$count}{path} = $1;
289     + ${$foundref}{$$count}{path} =~ s/$mountpoint//; #strip off the mountpoint
290     + ${$foundref}{$$count}{path} =~ s/$file//; #strip off the filename
291     + ${$foundref}{$$count}{size}=$sb->size; # size in bytes
292     + ${$foundref}{$$count}{sizeH}=scaleIt($sb->size); # human readable size
293     + ${$foundref}{$$count}{time}=strftime '%d %b %g %H:%M', localtime $sb->mtime;
294     + }
295     + },
296     + untaint => 1,
297     + untaint_pattern => qr|^([-+@\w\s./:\\]+)$|,
298     + untaint_skip =>1,
299     + },
300     + $findRoot
301     + );
302     +
303     + $self->unmount;
304     + return;
305     +}
306     +
307     +sub desc # brief description of a filesystem
308     +{
309     + my ($self,$kname) = @_;
310     + my $hashref = $self->{_blox};
311     +
312     + my $model = $hashref->{$kname}{MODEL};
313     + my $label = $hashref->{$kname}{LABEL} || gettext('no label');
314     + my $size = $hashref->{$kname}{SIZEH};
315     +
316     + return "$label $model $size";
317     +}
318     +
319     +
320     +# Given the KNAME check if the filesystem.could be mountable
321     +# Check that there are no children, i.e. a tip
322     +# Check that it has a UUID, Filesystem,
323     +sub mountable
324     +{
325     + my ($self,$kname) = @_;
326     + my $hashref = $self->{_blox};
327     + return ($hashref->{$kname}{tip} && $hashref->{$kname}{UUID} && _isFS ($hashref->{$kname}{FSTYPE})) ? 1 : $EMPTY;
328     +}
329     +
330     +# Given the KNAME check if the filesystem.is read-only
331     +# returns 1 for Read-Only and $EMPTY for R-W
332     +sub readonly
333     +{
334     + my ($self,$kname) = @_;
335     + my $hashref = $self->{_blox};
336     + return ($hashref->{$kname}{RO}) ? 1 : $EMPTY;
337     +}
338     +
339     +sub mountpoint
340     +{
341     + my ($self,$kname) = @_;
342     + my $hashref = $self->{_blox};
343     + return ($hashref->{$kname}{MOUNTPOINT});
344     +}
345     +
346     +sub uuid
347     +{
348     + my ($self,$kname) = @_;
349     + my $hashref = $self->{_blox};
350     + return ($hashref->{$kname}{UUID});
351     +}
352     +
353     +sub model
354     +{
355     + my ($self,$kname) = @_;
356     + my $hashref = $self->{_blox};
357     + return ($hashref->{$kname}{MODEL});
358     +}
359     +
360     +# Given the KNAME return the label
361     +# returns 'no label' if none found
362     +sub label
363     +{
364     + my ($self,$kname) = @_;
365     + my $hashref = $self->{_blox};
366     + return ($hashref->{$kname}{LABEL}) || gettext('no label');
367     +}
368     +
369     +sub size
370     +{
371     + my ($self,$kname) = @_;
372     + my $hashref = $self->{_blox};
373     + return ($hashref->{$kname}{SIZE});
374     +}
375     +
376     +# Given a filesystem.(eg sr0) check if it's filesystem type is allowed
377     +sub validFS
378     +{
379     + my ($self,$kname) = @_;
380     + my $hashref = $self->{_blox};
381     + my $fsref = $self->{_fstype};
382     + return ($fsref->{$hashref->{$kname}{FSTYPE}}) || $EMPTY;
383     +}
384     +
385     +# Given a filesystem.type (eg vfat) check if it is allowed
386     +sub _isFS
387     +{
388     + my ($filesystem) = @_;
389     + return $EMPTY unless $filesystem;
390     +
391     + my $fsref = findValidFS;
392     + return ($fsref->{$filesystem}) || $EMPTY;
393     +}
394     +
395     +# Return the reason string which indicates why a drive is (in)valid
396     +sub reason
397     +{
398     + my ($self,$kname) = @_;
399     + my $hashref = $self->{_blox};
400     + return ($hashref->{$kname}{REASON});
401     +}
402     +
403     +# Given the KNAME mount the filesystem, example
404     +# system ('/bin/mount', '-t', 'vfat', '-U', '9891-4C8A', '/tmp/mnt');
405     +sub mount
406     +{
407     + my ($self, $kname) = @_;
408     + my $hashref = $self->{_blox};
409     +
410     + $self->createMountpoint;
411     +
412     + system ('/bin/mount', '-t', $hashref->{$kname}{FSTYPE}, '-U', $hashref->{$kname}{UUID}, $self->{mount}) == 0
413     + or croak (gettext('Failed to mount')." $self->{mount},$hashref->{$kname}{FSTYPE},$hashref->{$kname}{UUID}: $?");
414     + return;
415     +}
416     +
417     +# Unmount the block device
418     +sub unmount
419     +{
420     + my $self = shift;
421     + system('/bin/umount', $self->{mount}) == 0
422     + or croak (gettext('Failed to unmount')." $self->{mount}: $?");
423     + return;
424     +}
425     +
426     +# Create the mountpoint directory
427     +# Error if already mounted
428     +sub createMountpoint
429     +{
430     + my $self = shift;
431     + my $mount = $self->{mount};
432     +
433     + # Check if the mountpoint is in use
434     + if (!checkMount ($mount))
435     + {
436     + # Try to unmount, will die if fails
437     + $self->unmount;
438     + }
439     +
440     + if ($mount && ! -d $mount)
441     + {
442     + eval {make_path($mount)};
443     + croak (gettext('Error while creating')." $mount $EVAL_ERROR".gettext('Maybe insufficient permissions.')) if $EVAL_ERROR;
444     + }
445     + return;
446     +}
447     +
448     +sub destroy
449     +{
450     +# cleanup, unmount and remove mountpoint
451     +
452     + my $self = shift;
453     + my $mount = $self->{mount};
454     +
455     +
456     + # Check if the mountpoint is in use
457     + if (!checkMount ($mount))
458     + {
459     + $self->unmount;
460     + }
461     +
462     + if ($mount && -d $mount)
463     + {
464     + eval {remove_tree($mount)};
465     + croak (gettext('Error while deleting')." $mount $EVAL_ERROR") if $EVAL_ERROR;
466     + }
467     + return;
468     +}
469     +
470     +
471     +### The following subroutines are not specific to block devices
472     +sub scaleIt {
473     + Readonly my $KBYTE => 1024;
474     + my( $size, $n ) =( shift, 0 );
475     + ++$n and $size /= $KBYTE until $size < $KBYTE;
476     + if ($size >= 1000){++$n ; $size /= $KBYTE;}
477     + return sprintf "%.3g %s",
478     + $size, ( qw[ bytes KB MB GB TB] )[ $n ];
479     +}
480     +
481     +sub checkMount
482     +{
483     + # check if $mountdir is mounted
484     + my $mountdir = shift;
485     + $|=1; # Auto-flush
486     +
487     + # copy STDOUT to another filehandle
488     + open (my $STDOLD, '>&', STDOUT);
489     +
490     + open(STDOUT, ">/dev/null");
491     + if ( open(MOUNTDIR, "|-", "/bin/findmnt", $mountdir)){;}
492     +
493     + # restore STDOUT
494     + open (STDOUT, '>&', $STDOLD);
495     +
496     + return (!close(MOUNTDIR));
497     +}
498     +
499     +# remove leading and trailing spaces from a string
500     +# this should be moved to a util library.
501     +sub trim
502     +{
503     + my ($string) = @_;
504     + $string =~ s/^\s+|\s+$//g;
505     + return $string;
506     +}
507     +1;
508     diff -urN e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm
509     --- e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm 2016-02-06 18:23:27.978666800 -0800
510     +++ e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_backup.pm 2016-01-09 16:32:40.000000000 -0800
511     @@ -6,8 +6,14 @@
512     use esmith::util;
513     use Locale::gettext;
514     use esmith::Backup;
515     -#use Filesys::DiskFree;
516     -#use Sys::Filesystem;
517     +use Carp;
518     +use feature qw( say );
519     +use esmith::BlockDevices;
520     +use POSIX qw(:sys_wait_h strftime);
521     +use File::stat;
522     +use Taint::Util;
523     +
524     +my $EMPTY = q{};
525    
526     sub new
527     {
528     @@ -21,7 +27,7 @@
529     }
530    
531     sub name
532     -{
533     +{
534     return $_[0]->{name};
535     }
536    
537     @@ -42,22 +48,10 @@
538     return sub {
539     my $fh = shift;
540     my @backup_list = esmith::Backup->restore_list;
541     -
542     - unless (open(DU, "-|"))
543     - {
544     - open(STDERR, ">/dev/null");
545     - exec qw(/usr/bin/du -sb), map { "/$_" } @backup_list;
546     - }
547     - my $backup_size = 0;
548     - while (<DU>)
549     - {
550     - next unless (/^(\d+)/);
551     - $backup_size += $1;
552     - }
553     - close DU;
554     + my $backup_size = backupSize (@backup_list);
555    
556     open(OLDSTDOUT, ">&STDOUT");
557     - unless (open(STDOUT, ">/mnt/bootstrap-console-backup/smeserver.tgz"))
558     + unless (open(STDOUT, ">$device/smeserver.tgz"))
559     {
560     return gettext("Could not create backup file on device").": $!\n";
561     }
562     @@ -74,7 +68,7 @@
563     my $status = 0;
564    
565     my $gzip = open(GZIP, "|-");
566     - return "could not run gzip" unless defined $gzip;
567     + return "could not run gzip" unless defined $gzip;
568     unless ($gzip)
569     {
570     close $fh;
571     @@ -127,140 +121,130 @@
572     {
573     my ($self, $console, $db) = @_;
574     my @backup_list = esmith::Backup->restore_list;
575     + my $compressionLevel = $db->get_prop('backupconsole', 'CompressionLevel') || '-6';
576     + my $mountpoint = $db->get_prop('backupconsole', 'Mountpoint') || '/mnt/bootstrap-console-backup';
577     + my $allowMounted = $db->get_prop('backupconsole', 'AllowMounted') || 'disabled'; ### For future use
578    
579     $ENV{PATH} = "/bin:/usr/bin";
580     $ENV{HOME} = "/root";
581    
582     - my $compressionLevel = $db->get_prop("backupconsole", "CompressionLevel") || "-6";
583     + my $devices = esmith::BlockDevices->new ('mount' => $mountpoint, 'allowmount' => $allowMounted);
584     +
585     + INITIATE_BACKUP:
586     my ($rc, $choice) = $console->yesno_page
587     (
588     - title => gettext("Create Backup to removable media"),
589     + title => gettext('Create Backup to removable media'),
590     defaultno => 1,
591     - text =>
592     - gettext("Do you wish to create backup on removable media?"),
593     - );
594     - return unless $rc == 0;
595     - INITIATE_BACKUP:
596     - ($rc, $choice) = $console->yesno_page
597     - (
598     - title => gettext("Insert media to use for backup"),
599     - left => gettext("Next"),
600     - right => gettext("Cancel"),
601     - text =>
602     - gettext("Insert removable media, then hit the enter key."),
603     - );
604     - return unless $rc == 0;
605     - sleep(3);
606     - my @dirs = ();
607     - my @labels = ();
608     - foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
609     - $udi =~ m/^(\S+)/;
610     -
611     - my $is_readonly = qx(hal-get-property --udi $1 --key volume.is_mounted_read_only);
612     -
613     - if ($is_readonly eq "false\n") {
614     -
615     - my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
616     -
617     - if ($is_mounted eq "false\n") {
618     - my $blkdev = qx(hal-get-property --udi $1 --key block.device);
619     - $blkdev =~ m/^(\S+)/;
620     - push @dirs, $1;
621     - }
622     - if ($is_mounted eq "false\n") {
623     - my $vollbl = qx(hal-get-property --udi $1 --key volume.label);
624     - $vollbl =~ m/^(\S+)/;
625     - if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
626     - chomp $vollbl;
627     - push @labels, lc($vollbl);
628     - }
629     - }
630     - }
631     - unless ($dirs[0])
632     + text => gettext('Do you want to create a backup on removable media?')."\n\n".
633     + gettext('Insert removable media before proceeding.')."\n".
634     + gettext('It may take many seconds to scan for media.'),
635     + );
636     + if ($rc != 0)
637     {
638     - ($rc, $choice) = $console->message_page
639     - (
640     - title => gettext("Writable backup medium not found"),
641     - right => gettext("Back"),
642     - text =>
643     - gettext("No removable and/or writable media or device found"),
644     - );
645     - goto INITIATE_BACKUP;
646     + $devices->destroy;
647     + return;
648     }
649     - mkdir("/mnt/bootstrap-console-backup");
650    
651     - my $device = $dirs[0];
652     - if (defined $dirs[1])
653     - {
654     - my $count=1;
655     - my @args = map { $count++ . '.' => $_ } @dirs;
656     + ### determine which filesystems are valid or not for backups
657     + # check expected backup size
658     + my $backup_size = backupSize (@backup_list);
659    
660     - my ($rc, $choice) = $console->menu_page
661     - (
662     - title => gettext("Choose device to use for backup"),
663     - text => ("@dirs \n @labels"),
664     - argsref => \@args,
665     - left => gettext("Cancel"),
666     - right => gettext("OK"),
667     - );
668     - goto INITIATE_BACKUP unless ($rc == 0);
669     - my %args_hash = ( @args );
670     - $device = $args_hash{$choice};
671     - }
672     - unless ( system("/bin/mount", "$device", "/mnt/bootstrap-console-backup") == '0' )
673     + # validate each filesystem
674     + my ($valid, $invalid) = $devices->checkBackupDrives ($backup_size);
675     + my $text = $EMPTY;
676     +
677     + if (${$invalid}[0]) # If there are filesystems that are not valid.
678     {
679     - ($rc, $choice) = $console->message_page
680     - (
681     - title => gettext("No mountable backup medium"),
682     - right => gettext("Back"),
683     - text =>
684     - gettext("Unable to mount removable media, please check the file system format (default : Vfat,Ext2,Ext3,Ext4)"),
685     - );
686     - goto INITIATE_BACKUP;
687     + $text .= gettext ('These filesystems are not valid:')."\n";
688     + foreach my $drive (sort @{$invalid})
689     + {
690     + $text .= "$drive ".$devices->desc($drive).' '.gettext ('Reason').': '.$devices->reason($drive)."\n";
691     + }
692     + $text .= "\n";
693     }
694    
695     - use File::stat;
696     - my $st = stat("/mnt/bootstrap-console-backup/smeserver.tgz");
697     - if ($st)
698     + unless (${$valid}[0]) # Unless a device is found show error page
699     {
700     -# TODO
701     -# old backup exists - what do we want to do with it?
702     - my $size = $st->size;
703     - }
704     + my $title = gettext('No valid backup device found').' '.gettext('size').' '.esmith::BlockDevices::scaleIt($backup_size);
705     + $text .= "\n$title, ".gettext('please try again');
706     + ($rc, $choice) = $console->yesno_page
707     + (
708     + title => $title,
709     + text => $text,
710     + left => gettext('Try again'),
711     + right => gettext('Cancel'),
712     + );
713     + if ($rc == 0) # Try Again
714     + {
715     + goto INITIATE_BACKUP;
716     + }
717     + else
718     + {
719     + $devices->destroy;
720     + return;
721     + }
722     + }
723     + $text .= gettext ('The following are valid for backup').' ';
724     + $text .= gettext ('size').' '.esmith::BlockDevices::scaleIt($backup_size);
725    
726     + #ToDo when valid + invalid > 13 then may need to limit the information
727     + my @args = map { $_ => $devices->desc($_) } @{$valid};
728     +
729     + # Display the available backup destinations.
730     + ($rc, $choice) = $console->menu_page
731     + (
732     + title => gettext('Choose device to use for backup').' '.gettext('size').' '.esmith::BlockDevices::scaleIt($backup_size),
733     + text => $text,
734     + argsref => \@args,
735     + left => gettext('Cancel'),
736     + right => gettext('OK'),
737     + );
738     + goto INITIATE_BACKUP unless ($rc == 0);
739     + untaint $choice;
740     + $devices->mount ($choice); # mount the chosen filesystem
741     +
742     $console->infobox(
743     - title => gettext("Preparing for backup"),
744     - text => gettext("Please stand by while the system is prepared for backup..."),
745     + title => gettext('Preparing for backup'),
746     + text => gettext('Please stand by while the system is prepared for backup...'),
747     );
748    
749     - my $backup_size = 0;
750     - system("/sbin/e-smith/signal-event", "pre-backup");
751     + system("/sbin/e-smith/signal-event", 'pre-backup');
752     +
753     + $console->gauge(make_backup_callback($mountpoint,$compressionLevel), 'title' => gettext('Creating backup file'));
754     +
755     + $devices->destroy;
756     +
757     + system("/sbin/e-smith/signal-event", 'post-backup');
758     + $console->message_page
759     + (
760     + title => gettext('Backup complete'),
761     + text => gettext('Remove backup media.'),
762     + );
763     + return;
764     +}
765     +
766     +
767     +sub backupSize
768     +{
769     + my $size;
770     +
771     unless (open(DU, "-|"))
772     {
773     open(STDERR, ">/dev/null");
774     - exec qw(/usr/bin/du -sb), map { "/$_" } @backup_list;
775     + exec qw(/usr/bin/du -sb), map { "/$_" } @_;
776     }
777     while (<DU>)
778     {
779     next unless (/^(\d+)/);
780     - $backup_size += $1;
781     + $size += $1;
782     }
783     close DU;
784     -
785     - $console->gauge(make_backup_callback("/mnt/bootstrap-console-backup",$compressionLevel), 'title' => gettext("Creating backup file"));
786     -
787     - system("/bin/umount", "/mnt/bootstrap-console-backup");
788     - rmdir("/mnt/bootstrap-console-backup");
789     - system("/sbin/e-smith/signal-event", "post-backup");
790     - ($rc, $choice) = $console->message_page
791     - (
792     - title => gettext("Backup complete"),
793     - text =>
794     - gettext("Remove removable media, then hit the enter key."),
795     - );
796     +
797     + return $size;
798     }
799    
800     #use esmith::console;
801     #esmith::console::perform_backup->new->doit(esmith::console->new,
802     # esmith::ConfigDB->open);
803     1;
804     +
805     diff -urN e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm
806     --- e-smith-backup-2.4.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 2016-02-06 18:23:27.839666800 -0800
807     +++ e-smith-backup-2.4.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 2016-01-09 16:32:40.000000000 -0800
808     @@ -4,6 +4,12 @@
809     use esmith::ConfigDB;
810     use esmith::console;
811     use Locale::gettext;
812     +use Carp;
813     +use feature qw( say );
814     +use esmith::BlockDevices;
815     +use Taint::Util;
816     +
817     +my $EMPTY = q{};
818    
819     sub new
820     {
821     @@ -16,9 +22,8 @@
822     return $self;
823     }
824    
825     -
826     sub name
827     -{
828     +{
829     return $_[0]->{name};
830     }
831    
832     @@ -30,124 +35,154 @@
833     sub doit
834     {
835     my ($self, $console, $db) = @_;
836     - if ($db->get_prop('bootstrap-console', 'Run') eq 'yes') # called from bootstrap console
837     + my $compressionLevel = $db->get_prop('backupconsole', 'CompressionLevel') || '-6';
838     + my $mountpoint = $db->get_prop('backupconsole', 'Mountpoint') || '/mnt/bootstrap-console-backup';
839     + my $allowMounted = $db->get_prop('backupconsole', 'AllowMounted') || 'disabled'; ### For future use
840     + my $restoreMaxDepth = $db->get_prop('backupconsole', 'MaxDepth') || 1; ### For future use
841     + my %found;
842     + my $backupcount = 0;
843     + my $backupdrive; # Which filesystem holds the backup
844     + my $backupfile; # full path to the backup
845     + my ($time, $size); # time and size of chosen backup
846     +
847     + if ($db->get_prop('bootstrap-console', 'Run') eq 'yes') # called from bootstrap console
848     {
849     return if ($db->get_value('PasswordSet') eq 'yes'); # too late
850     }
851     return if ($db->get_prop('bootstrap-console', 'Restore') eq 'disabled');
852     +
853     + my $devices = esmith::BlockDevices->new ('mount' => $mountpoint, 'allowmount' => $allowMounted);
854     +
855     + INITIATE_RESTORE:
856     my ($rc, $choice) = $console->yesno_page
857     (
858     title => gettext("Restore From Backup"),
859     defaultno => 1,
860     - text =>
861     - gettext("Do you wish to restore from backup?"),
862     - );
863     - return unless $rc == 0;
864     - mkdir("/mnt/bootstrap-console-backup");
865     - system("/etc/init.d/messagebus", "start");
866     - system("/etc/init.d/haldaemon", "start");
867     - INITIATE_RESTORE:
868     - ($rc, $choice) = $console->yesno_page
869     - (
870     - title => gettext("Insert media containing backup"),
871     - left => gettext("Next"),
872     - right => gettext("Cancel"),
873     - text =>
874     - gettext("Insert removable media containing your backup file, then hit the enter key."),
875     - );
876     - unless ($rc == 0) {
877     - system("/etc/init.d/haldaemon", "stop");
878     - system("/etc/init.d/messagebus", "stop");
879     - rmdir("/mnt/bootstrap-console-backup");
880     + text => gettext('Do you wish to restore from backup?')."\n\n".
881     + gettext('Insert removable media before proceeding.')."\n".
882     + gettext('It may take many seconds to scan for media.'),
883     + ); # Buttons are Yes & No
884     + if ($rc != 0) # choice was not Yes
885     + {
886     + $devices->destroy;
887     return;
888     }
889     - sleep(3);
890     - my @dirs;
891     - @dirs = ();
892     - foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
893     - $udi =~ m/^(\S+)/;
894     - my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
895     -
896     - if ($is_mounted eq "false\n") {
897     - my $blkdev = qx(hal-get-property --udi $1 --key block.device);
898     - $blkdev =~ m/^(\S+)/;
899     - push @dirs, $1;
900     +
901     + ### determine which filesystems are valid or not for backups
902     +
903     + # validate each filesystem
904     + my ($valid, $invalid) = $devices->checkBackupDrives ($EMPTY);
905     + my $text = $EMPTY;
906     +
907     + if (${$valid}[0]) # There are filesystems that could hold a backup.
908     + {
909     + $text .= gettext ('These filesystems could hold backups')."\n";
910     + foreach my $drive (sort @{$valid})
911     + {
912     + $text .= "$drive ".$devices->desc($drive)."\n";
913     + $devices->findBackup ($drive, \%found, $restoreMaxDepth, \$backupcount);
914     }
915     + $text .= "\n";
916     }
917     - unless ($dirs[0])
918     +
919     + unless ($backupcount) # Unless a valid backup is found show error page
920     {
921     - ($rc, $choice) = $console->message_page
922     - (
923     - title => gettext("Backup medium not found"),
924     - right => "Try again",
925     - text =>
926     - gettext("No removable media or device found"),
927     - );
928     - goto INITIATE_RESTORE;
929     - }
930     - my $device = $dirs[0];
931     - if (defined $dirs[1])
932     - {
933     - my $count=1;
934     - # FIXME use better regexp
935     - my @args = map { /(.*)/; $count++ . '.' => $1 } @dirs;
936     + if (${$invalid}[0]) # If there are filesystems that are not valid.
937     + {
938     + $text .= gettext ('These filesystems are not valid:')."\n";
939     + foreach my $drive (sort @{$invalid})
940     + {
941     + $text .= "$drive ".$devices->desc($drive).' '.gettext ('Reason').': '.$devices->reason($drive)."\n";
942     + }
943     + $text .= "\n";
944     + }
945     + my $title = gettext('No valid backup device found');
946     + $text .= "\n$title, ".gettext('please try again');
947     + ($rc, $choice) = $console->yesno_page
948     + (
949     + title => $title,
950     + text => $text,
951     + left => gettext('Try again'),
952     + right => gettext('Cancel'),
953     + );
954     + if ($rc == 0) # Try Again
955     + {
956     + goto INITIATE_RESTORE;
957     + }
958     + else
959     + {
960     + $devices->destroy;
961     + return;
962     + }
963     + }
964    
965     - my ($rc, $choice) = $console->menu_page
966     - (
967     - title => gettext("Choose device to restore from"),
968     - text => gettext("Please select which device contains the backup file you wish to restore from."),
969     - argsref => \@args,
970     - left => gettext("Cancel"),
971     - right => gettext("OK"),
972     - );
973     + # %found contains $backupcount backups.
974     + if ($backupcount == 1)
975     + {
976     + # One backup found, so simple yes/no choice
977     + $backupdrive = $found{1}{device}; # Find the (only) device that a backup was found on
978     + $backupfile = $found{1}{path}; # find the actual backup
979     + $time = gettext('Date') .' '. $found{1}{time};
980     + $size = gettext('Size') .' '. $found{1}{sizeH};
981     +
982     + ($rc, $choice) = $console->yesno_page
983     + (
984     + title => gettext('Start restore from backup'),
985     + text =>
986     + gettext('Backup found on device').
987     + "\n$backupdrive ".$devices->desc($backupdrive)."\n\n".
988     + gettext('Backup details').
989     + "\n$backupfile $size $time\n\n\n".
990     + gettext('Do you wish to restore from this file?'),
991     + );
992     goto INITIATE_RESTORE unless ($rc == 0);
993     - my %args_hash = ( @args );
994     - $device = $args_hash{$choice};
995     + $size = $found{1}{size};
996     }
997     - system("/bin/mount", "$device", "/mnt/bootstrap-console-backup");
998     - sleep(1);
999     -
1000     - unless (-f "/mnt/bootstrap-console-backup/smeserver.tgz")
1001     + else # Multiple backups found so display a choice
1002     {
1003     - system("/bin/umount", "$device");
1004     - ($rc, $choice) = $console->message_page
1005     - (
1006     - title => gettext("Backup file not found"),
1007     - right => "Try again",
1008     - text =>
1009     - gettext("No backup file found"),
1010     - );
1011     - goto INITIATE_RESTORE;
1012     - }
1013     - use File::stat;
1014     - my $st = stat("/mnt/bootstrap-console-backup/smeserver.tgz");
1015     - my $size = $st->size;
1016     -
1017     - ($rc, $choice) = $console->yesno_page
1018     - (
1019     - title => gettext("Start restore from backup"),
1020     - text =>
1021     - gettext("Backup file found:") . " smeserver.tgz ($device) " .
1022     - gettext("size") . " $size " . gettext("bytes") .
1023     - "\n\n" .
1024     - gettext("Do you wish to restore from this file?"),
1025     - );
1026     - unless ($rc == 0) {
1027     - system("/bin/umount", "$device");
1028     - goto INITIATE_RESTORE;
1029     + $text = gettext ('Backups found on these devices')."\n";
1030     + foreach my $backupfound (sort keys %found)
1031     + {
1032     + $backupdrive = $found{$backupfound}{device};
1033     + if (($backupfound == 1) || ($found{$backupfound}{device} ne $found{$backupfound-1}{device}))
1034     + {
1035     + $text.= "$backupdrive ".$devices->desc($backupdrive)."\n";
1036     + }
1037     + }
1038     + my @args = map { $_ => "$found{$_}{device} $found{$_}{path} $found{$_}{sizeH} $found{$_}{time}" } sort keys %found;
1039     + ($rc, $choice) = $console->menu_page
1040     + (
1041     + title => gettext('Start restore from backup'),
1042     + text =>
1043     + "$text\n".
1044     + gettext ('Please select the backup that you wish to restore from.'),
1045     + argsref => \@args,
1046     + left => gettext('Cancel'),
1047     + right => gettext('OK'),
1048     + );
1049     + goto INITIATE_RESTORE unless ($rc == 0);
1050     + untaint $choice;
1051     + $backupdrive = $found{$choice}{device};
1052     + $size = $found{$choice}{size};
1053     }
1054     +
1055     + $devices->mount ($backupdrive); # mount the chosen filesystem
1056     + sleep(1); # Some mounts take time to become active
1057     +
1058     + ###ToDo This section has no error checking
1059     + ###ToDo 'Restoring data is not localized
1060     + # Execute the restore
1061     system("/sbin/e-smith/signal-event", "pre-restore");
1062     - system("(cd / ; cat /mnt/bootstrap-console-backup/smeserver.tgz |
1063     + system("(cd / ; cat $mountpoint/smeserver.tgz |
1064     pv -n -s $size |
1065     gunzip |
1066     tar xf - > /dev/null ) 2>&1 |
1067     dialog --backtitle 'Restoring data' --guage 'Progress' 7 70");
1068     - system("/bin/umount", "$device");
1069     - system("/etc/init.d/haldaemon", "stop");
1070     - system("/etc/init.d/messagebus", "stop");
1071     - rmdir("/mnt/bootstrap-console-backup");
1072     +
1073     + # Restore complete, now clean-up
1074     + $devices->destroy;
1075     system("/sbin/e-smith/signal-event", "post-upgrade");
1076     -
1077     +
1078     unless ( $self->{bootstrap} )
1079     {
1080     $db->set_prop("bootstrap-console", "Run", "yes");

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed