Backup-Duplicity-YADW

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Backup-Duplicity-YADW

0.12    2014-01-26
		fixed pidfile bug where the file did not get cleaned up properly
		
0.11	2014-01-18
		modified share/etc/yadw_inc_backup.sh, share/etc/yadw_full_backup.sh, 
		and share/etc/yadw/default.conf default settings
		
0.10	2014-01-18
		more bug fixes

0.09	2013-11-23
		bug fixes
		
0.08	2013-11-23
		added pod to yadw command line utility and default.conf

MANIFEST  view on Meta::CPAN

Build.PL
Changes
LICENSE
MANIFEST
META.yml
README
TODO
bin/yadw
dist.ini
lib/Backup/Duplicity/YADW.pm
share/etc/cron.hourly/yadw_inc_backup.sh
share/etc/cron.weekly/yadw_full_backup.sh
share/etc/yadw/default.conf
t/00-load.t
t/10-methods.t
t/20-yadw.t
t/boilerplate.t
t/etc/test.conf
t/etc/test_bad.conf
t/manifest.t
t/pod-coverage.t
t/pod.t

bin/yadw  view on Meta::CPAN

		{
			say STDERR "yadw is already running";
			exit 0;
		}
		else {
			die $@;
		}
	}

	if ( $Command eq 'full' ) {
		$Yadw->backup('full');
	}
	elsif ( $Command =~ /^inc/ ) {
		$Yadw->backup('inc');
	}
	elsif ( $Command eq 'expire' ) {
		$Yadw->expire();
	}
	elsif ( $Command eq 'verify' ) {
		$Yadw->verify();
	}
	elsif ( $Command eq 'status' ) {
		$Yadw->status();
	}

bin/yadw  view on Meta::CPAN


=head1 SAMPLE ETC FILES

Sample config/cron scripts can be found in the "share" dir.  To find your 
"share" dir run this:

  perl '-MFile::ShareDir ":ALL"' -E 'say dist_dir("Backup-Duplicity-YADW")';

=head1 CONFIGURATION

To setup your system for backups I recommend these steps:

1.  Login as root and install Backup::Duplicity::YADW if you have not done so
already.

2.  Install the default.conf:

  mkdir /etc/yadw
  cp <sharedir>/yadw/default.conf /etc/yadw
  chmod 600 /etc/yadw/default.conf

2.  Modify /etc/yadw/default.conf to your liking.

3.  Run a manual full backup test.  This will also prime the pump so to speak
for automated backups to run.

  yadw full

=head1 AUTOMATE

1.  *AFTER* a successful manual full backup, install weekly cron to perform
weekly full backups.

  cp <sharedir>/cron.weekly/yadw_full_backup.sh /etc/cron.weekly

2.  Install hourly cron for inc backups.

  cp <sharedir>/cron.hourly/yadw_inc_backup.sh /etc/cron.hourly

=head1 AUTHOR

John Gravatt <john@gravatt.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by John Gravatt.

This is free software; you can redistribute it and/or modify it under

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

	my $conf =
		Config::ApacheFormat->new( fix_booleans     => 1,
								   autoload_support => 0 );

	$conf->read( $self->conf_dir . "/" . $self->conf_file );
	$self->_conf($conf);
	$self->_init_logs;
	$self->_write_pidfile;
}

sub backup {

	args_pos
		my $self,
		my $type => 'Str';

	$type = $type eq 'inc' ? 'incremental' : $type;

	confess "invalid type: $type"
		if $type ne 'full' and $type ne 'incremental';

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

	$pid->guard;  # remove pidfile automatically when it goes out of scope
	$self->_pid($pid);
}

sub _get_expire_days {

	args_pos
		my $self,
		my $cmds;

	my $days = $self->_conf->get('days2keepbackups');

	if ( !defined $days ) {
		confess "missing configuration days2keepbackups";
	}
	elsif ( !$days ) {

		#		confess "days2keepbackups must be greater than 0";
	}

	push @$cmds, $days . 'D';
}


sub expire {

	args_pos my $self;

	$self->_log( 'info', "removing old backups" );

	my @cmd = ( 'duplicity', 'remove-older-than' );

	$self->_get_expire_days( \@cmd );
	push @cmd, '--force';
	push @cmd, '--extra-clean';
	$self->_get_targetdir( \@cmd );

	$self->_system(@cmd);

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

	$self->_system(@cmd);

	return 1;
}


sub verify {

	args_pos my $self;

	$self->_log( 'info', "verifying backups" );

	my @cmd = ( 'duplicity', 'verify' );

	$self->_get_verbosity( \@cmd );
	$self->_get_exclude_device_files( \@cmd );
	$self->_get_incl_excl_list( \@cmd );
	$self->_get_encrypt_key( \@cmd );
	$self->_get_log_file( \@cmd );
	$self->_get_s3_new( \@cmd );
	$self->_get_targetdir( \@cmd );

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

	# TODO
}

sub _init_logs {

	args_pos my $self;

	$self->_get_syslog;

	if ( $self->use_syslog ) {
		openlog( 'backups', $$, 'user' );
	}

	$self->_log( 'info', "$0 @ARGV" );
}

sub _verbose {

	my $self = shift;

	print STDERR "[VERBOSE] @_\n" if $self->verbose;

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

  $yadw = Backup::Duplicity::YADW->new;
 
  $yadw = Backup::Duplicity::YADW->new(
               conf_dir   => '/etc/mydir',
               conf_file  => 'other.conf',
               dry_run    => 0,
               use_syslog => 1,
               verbose    => 0
               );
              
  $yadw->backup();
  $yadw->verify();
  $yadw->expire();

  $yadw->restore("/my/file/location");

=head1 DESCRIPTION

This is a wrapper for Duplicity.  I found my command lines for invoking 
Duplicity getting quite lengthy and wanted a way to persist my configurations
in an intuitive manner.  I looked at several other Duplicity wrappers, but

lib/Backup/Duplicity/YADW.pm  view on Meta::CPAN

=head2 verbose

Print extra messages about whats going on.

=head1 METHODS

=head2 new( [ %attributes ] )

Constructor - 'nuff said

=head2 backup( $type )

Tell duplicity to do a backup.  Requires either 'full' or 'inc' for a type.
Returns true on success.

=head2 expire( )

Tell duplicity to "remove-older-than <days in conf file>".

=head2 status( )

Equivalent to "collection-status" in duplicity.  Returns true on success.

=head2 verify( )

Tell duplicity to verify backups.  Returns true on success.

=head2 restore( %args )

Tell duplicity to do a restore.

Required args:

  location => $path

Optional args:

  time => $time (see duplicity manpage)

Returns true on success.

=head1 SEE ALSO

yadw (ready to use backup script)

=head1 AUTHOR

John Gravatt <john@gravatt.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by John Gravatt.

This is free software; you can redistribute it and/or modify it under

t/10-methods.t  view on Meta::CPAN

use vars qw();

###### MAIN ######

system( 'rm -rf ' . TESTDIR );

if ( !which('duplicity') ) {
	plan skip_all => 'unable to find duplicity on PATH';
}

my $y = method_test_backup();
method_test_verify($y);
method_test_restore($y);
method_test_expire($y);
method_test_status($y);
verify_pidfile_check();
$y = undef;
method_test_backup_bad();

done_testing();

###### END MAIN ######

END {

	unless ( $ENV{DEBUG} ) {
		system( 'rm -rf ' . TESTDIR );
	}

t/10-methods.t  view on Meta::CPAN


	return $file;
}

sub method_test_expire {
	my $y = shift;

	ok( $y->expire );
}

sub method_test_backup {

	my $dir = generate_test_dir();

	my $y =
		Backup::Duplicity::YADW->new( conf_dir  => "t/etc",
									  conf_file => "test.conf",
									  verbose   => $ENV{VERBOSE}
		);

	eval { $y->backup('bogus') };
	ok($@);
	ok( $y->backup('full') );
	ok( $y->backup('inc') );

	return $y;
}

sub verify_pidfile_check {
	eval {
		my $y =
			Backup::Duplicity::YADW->new( conf_dir  => "t/etc",
										  conf_file => "test_bad.conf",
										  verbose   => $ENV{VERBOSE}
			);
	};
	ok($@);
	ok( $Backup::Duplicity::YADW::ErrCode
		== Backup::Duplicity::YADW::PID_EXISTS() );
}

sub method_test_backup_bad {

	my $y =
		Backup::Duplicity::YADW->new( conf_dir  => "t/etc",
									  conf_file => "test_bad.conf",
									  verbose   => $ENV{VERBOSE}
		);

	eval { $y->backup('full') };
	ok($@);
}

sub method_test_verify {
	my $y = shift;
	ok( $y->verify );
}

sub replace_src_dir {

t/etc/test.conf  view on Meta::CPAN

# toggle for using the syslog facility
SysLog = on

# <source dir> 
SourceDir /tmp/yadwtest/testdata

# <target url>
TargetUrl file:///tmp/yadwtest/backups

# --encrypt-key
EncryptKey off

# --s3-use-new-style
##S3UseNewStyle on

# --exclude-device-files
ExcludeDeviceFiles on

t/etc/test_bad.conf  view on Meta::CPAN

# toggle for using the syslog facility
SysLog = on

# <source dir> 
SourceDir /tmp/yadwtest/testdata

# <target url>
TargetUrl bogus:///tmp/yadwtest/backups

# --encrypt-key
EncryptKey off

# --s3-use-new-style
##S3UseNewStyle on

# --exclude-device-files
ExcludeDeviceFiles on



( run in 1.336 second using v1.01-cache-2.11-cpan-49f99fa48dc )