App-BorgRestore

 view release on metacpan or  search on metacpan

script/borg-restore.pl  view on Meta::CPAN

		printf "\e[1;33m%s\e[0m %s\n", App::BorgRestore::Helper::format_timestamp($archive->{modification_time}), $archive->{archive};
		$counter++;
	}
}

fun user_select_archive ($archives) {
	my $selected_archive;

	if (!@$archives) {
		return;
	}

	print_archive_list($archives);

	printf "\e[0;34m%s: \e[0m", "Enter ID to restore (Enter to skip)";
	my $selection = <STDIN>;
	return if !defined($selection);
	chomp $selection;

	return unless ($selection =~ /^\d+$/ && defined(${$archives}[$selection]));
	return ${$archives}[$selection];
}

sub logger_setup {
	my $appender = "Screen";
	$appender = "ScreenColoredLevels" if -t STDERR; ## no critic (InputOutput::ProhibitInteractiveTest)

	my $conf = "
	log4perl.rootLogger = INFO, screenlog

	log4perl.appender.screenlog          = Log::Log4perl::Appender::$appender
	log4perl.appender.screenlog.stderr   = 1
	log4perl.appender.screenlog.layout   = Log::Log4perl::Layout::PatternLayout
	log4perl.appender.screenlog.layout.ConversionPattern = %p %m%n

	log4perl.PatternLayout.cspec.U = sub {my \@c = caller(\$_[4]); \$c[0] =~ s/::/./g; return sprintf('%s:%s', \$c[0], \$c[2]);}
	";
	Log::Log4perl::init( \$conf );
	Log::Any::Adapter->set('Log4perl');

	$SIG{__WARN__} = sub {
		local $Log::Log4perl::caller_depth =
			$Log::Log4perl::caller_depth + 1;
		 Log::Log4perl->get_logger()->warn(@_);
	};

	$SIG{__DIE__} = sub {
		# ignore eval blocks
		return if($^S);
		local $Log::Log4perl::caller_depth =
			$Log::Log4perl::caller_depth + 1;
		 Log::Log4perl->get_logger()->fatal("Uncaught exception: ".$_[0], @_[1..$#_]);
		 exit(2);
	};
}

sub main {
	logger_setup();

	my %opts;
	# untaint PATH because we do not expect this to be run across user boundaries
	$ENV{PATH} = App::BorgRestore::Helper::untaint($ENV{PATH}, qr(.*));

	Getopt::Long::Configure ("bundling");
	GetOptions(\%opts, "help|h", "debug", "update-cache|u", "destination|d=s", "time|t=s", "adhoc", "version", "list", "quiet", "detail", "json") or pod2usage(2);
	pod2usage(0) if $opts{help};

	if ($opts{version}) {
		printf "Version: %s\n", $App::BorgRestore::VERSION;
		return 0;
	}

	pod2usage(-verbose => 0) if (@ARGV== 0 and !$opts{"update-cache"} and !$opts{"list"});

	if ($opts{quiet}) {
		my $logger = Log::Log4perl->get_logger('');
		$logger->level($WARN);
	}

	if ($opts{debug}) {
		my $logger = Log::Log4perl->get_logger('');
		$logger->level($DEBUG);
		Log::Log4perl->appenders()->{"screenlog"}->layout(
			Log::Log4perl::Layout::PatternLayout->new("%d %8r [%-30U] %p %m%n"));
	}

	$app = App::BorgRestore->new();

	if ($opts{"update-cache"}) {
		$app->update_cache();
		return 0;
	}

	if ($opts{"list"}) {
		my @patterns = @ARGV;
		push @patterns, '', if @patterns == 0;

		my $json_data = {};

		for my $pattern (@patterns) {
			$pattern = App::BorgRestore::Helper::untaint($pattern, qr/.*/);

			my $paths = $app->search_path($pattern);
			for my $path (@$paths) {
				my $archives; $archives = $app->find_archives($path) if $opts{detail};
				if ($opts{json}) {
					$json_data->{$path} = {
						path => $path,
						archives => $archives,
					} unless defined $json_data->{$path};
				} else {
					printf "%s\n", $path;
					print_archive_list($archives, 0) if defined $archives;
				}
			}
		}

		if ($opts{json}) {
			print encode_json($json_data);
		}

		return 0;
	}

	if (!$app->cache_contains_data() && !$opts{adhoc}) {
		$log->error("Cache is empty. Either the cache path is incorrect or you did not run --update yet.");
		$log->error("If you did not create a cache yet, you may want to rerun with --adhoc to simply list all backups.");
		return 1;
	}

	my @paths = @ARGV;

	my $path;
	my $timespec;
	my $destination;
	my $archives;

	$path = $ARGV[0];

	if (defined($opts{destination})) {
		$destination = $opts{destination};
	}

	if (defined($opts{time})) {
		$timespec = $opts{time};
	}

	if (@ARGV > 1) {
		die "Too many arguments";
	}

	my $abs_path = $app->resolve_relative_path($path);

	$destination = dirname($abs_path) unless defined($destination);
	my $backup_path = $app->map_path_to_backup_path($abs_path);

	$log->debug("Asked to restore $backup_path to $destination");

	if ($opts{adhoc}) {
		$archives = $app->get_all_archives();
	} else {



( run in 1.009 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )