From ceab5027db52b5e1a3bdcd4e8df44a5417013040 Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 27 Feb 2008 17:23:39 +0000 Subject: initial import git-svn-id: http://svn.mandriva.com/svn/soft/draksnapshot/trunk@237660 99302b65-d5f7-0310-b3dd-f8cd6f4e3d94 --- lib/.perl_checker.cache | Bin 0 -> 3212038 bytes lib/MDV/Snapshot/.perl_checker | 1 + lib/MDV/Snapshot/Common.pm | 47 +++++++++ lib/MDV/Snapshot/Restore.pm | 210 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 lib/.perl_checker.cache create mode 120000 lib/MDV/Snapshot/.perl_checker create mode 100644 lib/MDV/Snapshot/Common.pm create mode 100644 lib/MDV/Snapshot/Restore.pm (limited to 'lib') diff --git a/lib/.perl_checker.cache b/lib/.perl_checker.cache new file mode 100644 index 0000000..9c02a4c Binary files /dev/null and b/lib/.perl_checker.cache differ diff --git a/lib/MDV/Snapshot/.perl_checker b/lib/MDV/Snapshot/.perl_checker new file mode 120000 index 0000000..6246b2f --- /dev/null +++ b/lib/MDV/Snapshot/.perl_checker @@ -0,0 +1 @@ +../../../.perl_checker \ No newline at end of file diff --git a/lib/MDV/Snapshot/Common.pm b/lib/MDV/Snapshot/Common.pm new file mode 100644 index 0000000..3ef2d63 --- /dev/null +++ b/lib/MDV/Snapshot/Common.pm @@ -0,0 +1,47 @@ +package MDV::Snapshot::Common; + +################################################################################ +# Backup Configuration Tool # +# # +# Copyright (C) 2008 Mandriva # +# # +# Thierry Vignaud # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License Version 2 as # +# published by the Free Software Foundation. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +################################################################################ + + +use lib qw(/usr/lib/libDrakX); +use common; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw($config_file $backup_directory); + +our ($config_file, $backup_directory); + +sub init { + $config_file = "$::prefix/etc/rsnapshot.conf"; + + $backup_directory = "$::prefix/" . + (split(/\s/, (find { /^snapshot_root\s/ } cat_($config_file)), 2))[1]; + + # normalize for glob(): + chomp($backup_directory); + $backup_directory =~ s!/*$!!; +} + +init(); + +1; diff --git a/lib/MDV/Snapshot/Restore.pm b/lib/MDV/Snapshot/Restore.pm new file mode 100644 index 0000000..0a2a83c --- /dev/null +++ b/lib/MDV/Snapshot/Restore.pm @@ -0,0 +1,210 @@ +package MDV::Snapshot::Restore; + +################################################################################ +# Backup Configuration Tool # +# # +# Copyright (C) 2008 Mandriva # +# # +# Thierry Vignaud # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License Version 2 as # +# published by the Free Software Foundation. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +################################################################################ + + +use lib qw(/usr/lib/libDrakX); +use c; +use locale; +use MDV::Snapshot::Common; +use common; +use interactive; +use POSIX; +use run_program; +use fsedit; +use fs::type; +use fs; +use any; + +sub get_fstab() { + my $all_hds = fsedit::get_hds(); + fs::get_raw_hds('', $all_hds); + fs::get_info_from_fstab($all_hds); + [ fs::get::fstab($all_hds) ]; # $fstab +} + +sub get_handle { + my ($fstab, $part, $o_rw) = @_; + my ($mntpnt) = map { $_->{mntpoint} } grep { $_->{device} eq $part->{device} } @$fstab; + + # do not bother failed to mount with ro b/c already mounted: + $mntpnt ? { dir => $mntpnt } : any::inspect($part, $::prefix, $o_rw); +} + + +sub find_disks_with_rsnapshot { + my ($fstab) = @_; + + my @true_fs = + grep { isTrueLocalFS($_) && + !member($_->{mntpoint}, + '/home', grep { $_ ne '/' } fs::type::directories_needed_to_boot()); + } @$fstab; + + log::l("looking for rsnapshot.conf on partitions " . join(' ', map { $_->{device} } @true_fs)); + + my @found; + foreach my $part (@true_fs) { + my $handle = get_handle($fstab, $part); + next if !$handle; + next if ! -e "$handle->{dir}/etc/rsnapshot.conf"; + + if (my $f = common::release_file($handle->{dir})) { + my $h = common::parse_release_file($handle->{dir}, $f, $part); + $h->{name} = $h->{release}; + push @found, $h; + } + } + + return @found; +} + +sub get_snapshots() { + my %backups = + map { + my $backup = $_; + my ($type, $_number) = m!$backup_directory/([^/]*)\.([0-9]*)!; + my $raw_date = [ stat($backup) ]->[-4]; + my $date = POSIX::strftime($type eq 'hourly' ? "%c" : "%x", localtime($raw_date)); + c::set_tagged_utf8($date); + $backup => { raw_date => $raw_date, date => $date, backup => $backup, type => $type }; + } glob_("$backup_directory/*"); + %backups; +} + +sub configure { + my ($in) = @_; + my $backup; + my %backups = get_snapshots(); + + if (!%backups) { + $in->ask_warn(N("Error"), N("No backup found!")); + return; + } + + my %i18n = ( + 'hourly' => N("Hourly"), + 'daily' => N("Daily"), + 'weekly' => N("Weekly"), + 'monthly' => N("Monthly"), + ); + + $in->ask_from_( + { + title => N("Backup snapshots configuration"), + }, + [ + { title => 1, label => N("Backup snapshots configuration") }, + { label => N("Please select the backup you want to restore.") }, + { val => \$backup, sort => 0, allow_empty_list => 1, + format => sub { + #-PO: eg: "Daily snapshot done on Sun Feb 4 + N("%s snapshot done on %s", $i18n{$backups{$_[0]}{type}}, $backups{$_[0]}{date}); + }, + list => [ sort { $backups{$a}{raw_date} cmp $backups{$b}{raw_date} } keys %backups ], + }, + ]) or return; + + my $_wait = $in->wait_message(N("Please wait"), N("Restoring backup in progress")); + my $backup_dir = $backups{$backup}{backup}; + # FIXME: add a progress bar + foreach (glob_("$backup_dir/localhost/*")) { + my $dir = $_; + s!^$backup_dir/localhost!!; + log::l("would run system('rsync', '-vrlpt', $dir, $::prefix$_)\n") if $::testing; + # FIXME: should we use --delete? + run_program::run('rsync', '-vrlpt', $dir, "$::prefix$_") if !$::testing; + } +} + + +sub mount_all { + my ($in, $fstab) = @_; + local $::testing = 0; + + my @errs; + foreach my $part (sort { $a->{mntpoint} cmp $b->{mntpoint} } + grep { $_->{mntpoint} && maybeFormatted($_) && $_->{device} ne 'none' + && !member($_->{fs_type}, 'swap', 'nfs', if_($::isInstall, 'ntfs')); + } + @$fstab) { + + eval { fs::mount::part($part) }; + push @errs, $@ if $@; + } + $in->ask_warn(N("Warning"), N("mount failled:") . join("\n", '', @errs)) if @errs; +} + +sub main { + my ($in) = @_; + + my ($system, $fstab, @found); + refresh: + $fstab = get_fstab(); + @found = find_disks_with_rsnapshot($fstab); + + $in->ask_from_({ interactive_help_id => 'configureX_chooser', + title => N("Restoring Backup"), + messages => join("\n", + N("Please select the partition of the system to restore."), + N("Do not forgot to plug the USB disk that contains your backups."), + ) + }, + [ + { label => N("System to restore"), }, + { + val => \$system, list => \@found, allow_empty_list => 1, + format => sub { + my $dev = $_[0]; + N("\"%s\" (on %s)", $dev->{name}, $dev->{part}{device}); + }, + }, + { + val => N("Refresh"), clicked => sub { goto refresh }, + }, + ]); + + my $handle = get_handle($fstab, $system->{part}, 1); + local $::prefix = $handle->{dir}; + + # reinit paths according to temp mount point: + MDV::Snapshot::Common::init(); + + my $ch_fstab; + if (ref($handle) =~ /before_leaving/) { + $ch_fstab = [ fs::read_fstab($::prefix, '/etc/fstab') ]; + mount_all($in, $ch_fstab); + } + + configure($in); + + # make sure everything is umounted: + if (ref($handle) =~ /before_leaving/) { + + # reread for {real_mountpoint}: + $ch_fstab = [ fs::read_fstab($::prefix, '/etc/fstab') ]; + + eval { fs::mount::umount_all($ch_fstab) }; + } +} + +1; -- cgit v1.2.1