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

Contents 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 - (show annotations) (download)
Sun Mar 6 04:52:54 2016 UTC (8 years, 2 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 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