#!/usr/bin/perl -T
#==========================================================================
#
# FILE: backup.pl
#
# USAGE: ./backup.pl -T (depois de tornar o script executável: 'chmod +x backup.pl')
#
# DESCRIPTION: Backup de ficheiros (recursivo) para tar.gz
# Dump de base de dados mysql (sql -> tar.gz)
# Envia ficheiros para servidor FTP
# Envia mail com tempo de execução do backup
#
# OPTIONS: ---
# REQUIREMENTS: Net::FTP
# Mail::Sendmail
# BUGS: ---
# NOTES: O backup é composto por dois ficheiros: <DATA>_files.tar.gz e <DATA>_mysql.tar.gz.
# Desta forma facilita-se o acesso a um ou a outro consoante a necessidade.
# AUTHOR: slack_guy @ TZ
# VERSION: 0.1
# CREATED: 09-08-2008 12:15:27 WEST
#==========================================================================
# This program comes with NO WARRANTY, to the extent permitted by law.
#==========================================================================
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#==========================================================================
#
use strict;
use warnings;
$ENV{'PATH'} = '/usr/local/bin:/usr/bin';
use Time::HiRes qw/gettimeofday tv_interval/;
my $time_start = [gettimeofday];
my $data = data();
#==========================================================================
# Definições: modifica os parâmetros de acordo com o teu sistema
my $defs = {
ftp_server => 'ftp.example.com',
ftp_user => 'ftp_username',
ftp_pass => 'ftp_password',
ftp_remote_dir => 'backups',
mysql_user => 'mysql_username',
mysql_pass => 'mysql_password',
mysql_db => 'mysql_database',
# pastas a copiar
dirs2backup => [
'/home/me/www/xpto',
'/home/you/www/xyz',
],
# ficheiro de backup
backup2file => "/home/me/tmp/${data}_files.tar.gz",
# log temporario de ficheiros a copiar; é eliminado quando deixa de ser necessario
temp_log_file => "/home/me/tmp/backup_$data.log",
# ficheiro temporario com o dump da BD; é eliminado quando deixa de ser necessario
temp_dump => "/home/me/tmp/dump_$data.sql",
# ficheiro com o dump da BD que vai ser transferido para o servidor remoto
mysql_tar => "/home/me/tmp/${data}_mysql.tar.gz",
# qualquer expressao diferente de 'sim' equivale a 'nao'
apagar_backups_locais => 'sim',
mail_to => '[email protected]',
mail_from => '[email protected]',
mail_subject => "Backup de $data",
mail_smtp => 'mail.example.com', # ou 'localhost'
};
# A partir daqui não deverá ser necessário alterar mais nada.
#==========================================================================
my $cmds = {
find => '/usr/bin/find',
tar => '/bin/tar',
mysql_dump => '/usr/bin/mysqldump',
};
dump_db();
backup();
send_ftp();
my $time_end = tv_interval( $time_start, [gettimeofday] );
send_mail();
finish();
exit 0;
sub finish {
if ( $defs->{apagar_backups_locais}
&& $defs->{apagar_backups_locais} eq 'sim' )
{
unlink $defs->{backup2file};
unlink $defs->{mysql_tar};
}
return;
}
sub send_ftp {
use Net::FTP;
my $ftp = Net::FTP->new( $defs->{ftp_server}, Debug => 0 )
or die "Impossivel ligar ao servidor $defs->{ftp_server} : $@";
$ftp->login( $defs->{ftp_user}, $defs->{ftp_pass} )
or die "Impossivel entrar ", $ftp->message;
$ftp->cwd( $defs->{ftp_remote_dir} )
or die "Impossivel ir para a pasta $defs->{ftp_remote_dir} ",
$ftp->message;
$ftp->put( $defs->{backup2file} )
or die "Impossivel copiar o ficheiro ", $ftp->message;
$ftp->put( $defs->{mysql_tar} )
or die "Impossivel copiar o ficheiro ", $ftp->message;
$ftp->quit;
return;
}
sub backup {
my $pastas = $defs->{dirs2backup};
# criamos um log com todas as pastas e ficheiros que vamos compactar
foreach my $pasta (@$pastas) {
my $cmd = qx|$cmds->{find} $pasta >> $defs->{temp_log_file}|;
}
# criamos o tar.gz com os ficheiros
my $tgz = qx|$cmds->{tar} czpf $defs->{backup2file} -T $defs->{temp_log_file} 2>/dev/null|;
# apagamos o log
unlink $defs->{temp_log_file};
return;
}
sub dump_db {
# Dump da base de dados
my $dump_cmd = qq|$cmds->{mysql_dump} --opt --user=$defs->{mysql_user} |;
$dump_cmd .= qq|--password=$defs->{mysql_pass} $defs->{mysql_db} |;
$dump_cmd .= qq| > $defs->{temp_dump}|;
my $dump_mysql = qx|$dump_cmd|;
# Compactar o dump da BD
my $tgz =
qx|$cmds->{tar} czfp $defs->{mysql_tar} $defs->{temp_dump} 2>/dev/null|;
# Eliminar o dump temporario (ficheiro .sql)
unlink $defs->{temp_dump};
return;
}
sub data {
use POSIX qw/strftime/;
my $data = POSIX::strftime( "%F %T", localtime );
$data =~ s/[\s\-:]/_/gmx;
return $data;
}
sub send_mail {
my $duracao = sprintf( "%.2f", $time_end );
my %mail = (
To => $defs->{mail_to},
From => $defs->{mail_from},
Subject => $defs->{mail_subject},
Message => "Backup concluído em $duracao segundos\n",
Smtp => $defs->{mail_smtp},
);
use Mail::Sendmail;
sendmail(%mail) or die $!;
return;
}