summaryrefslogtreecommitdiffstats
path: root/lib/MDV
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MDV')
l---------lib/MDV/Snapshot/.perl_checker1
-rw-r--r--lib/MDV/Snapshot/Common.pm47
-rw-r--r--lib/MDV/Snapshot/Restore.pm210
3 files changed, 258 insertions, 0 deletions
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 <tvignaud at mandriva dot com> #
+# #
+# 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 <tvignaud at mandriva dot com> #
+# #
+# 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;