Backup restoration and encryption
gitea/vn-vmware/pipeline/head This commit looks good
Details
gitea/vn-vmware/pipeline/head This commit looks good
Details
This commit is contained in:
parent
a39d7db316
commit
93b90cd24c
10
config.pl
10
config.pl
|
@ -8,15 +8,21 @@ log_file => '/var/log/vn-vmware.log',
|
|||
datacenter => 'datacenter1',
|
||||
|
||||
# The datastore name where backups must be stored
|
||||
backup_datastore => 'backups',
|
||||
backup_datastore => 'backup',
|
||||
|
||||
# The local directory where backups datastore folder is mounted
|
||||
# If it's mounted via NFS you have to disable caching for the mount
|
||||
local_backup_dir => '/mnt/vm-backups',
|
||||
local_backup_dir => '/mnt/backup',
|
||||
|
||||
# Directory where backups will be restored
|
||||
restore_dir => '/mnt/backup',
|
||||
|
||||
# Number of processes used by pigz to compress backups
|
||||
pigz_processes => 1,
|
||||
|
||||
# Whether to encrypt backups using gpg with passed passphrase file
|
||||
passphrase_file => '/etc/vn-vmware/passphrase.gpg',
|
||||
|
||||
# The default rotation to use if none is specified on job
|
||||
rotation => 'lastMonth',
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vn-vmware (1.1.18) stable; urgency=low
|
||||
vn-vmware (1.1.19) stable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ Vcs-Git: https://git.verdnatura.es/vn-vmware
|
|||
Package: vn-vmware
|
||||
Architecture: all
|
||||
Depends: perl, pigz, libsys-cpu-perl
|
||||
Suggests: gpg
|
||||
Section: misc
|
||||
Priority: optional
|
||||
Description: Maintenance scripts for VMWare
|
||||
|
|
76
vn-vmware.pl
76
vn-vmware.pl
|
@ -56,7 +56,7 @@ foreach my $vi_config_file (@vi_config_files) {
|
|||
my %opts = (
|
||||
'operation' => {
|
||||
type => "=s",
|
||||
help => "Operation to perform: none, backup-job, clone-job, backup, rotate, clone, snapshot, migrate",
|
||||
help => "Operation to perform: none, backup-job, clone-job, backup, rotate, restore, clone, snapshot, migrate",
|
||||
required => true
|
||||
},
|
||||
'job' => {
|
||||
|
@ -68,6 +68,10 @@ my %opts = (
|
|||
variable => "VM_NAME",
|
||||
help => "Name of the virtual machine"
|
||||
},
|
||||
'passphrase-file' => {
|
||||
type => "=s",
|
||||
help => "Encrypt backup with passed passphrase file using gpg"
|
||||
},
|
||||
'rotation-days' => {
|
||||
type => "=i",
|
||||
help => "Rotation days for backups",
|
||||
|
@ -82,6 +86,15 @@ my %opts = (
|
|||
type => "=s",
|
||||
help => "Regular expression used to archive and exclude backups from rotation"
|
||||
},
|
||||
'backup-file' => {
|
||||
type => "=s",
|
||||
help => "The path to the backup file that will be restored"
|
||||
},
|
||||
'restore-dir' => {
|
||||
type => "=s",
|
||||
help => "The backup directory where backup will be restored",
|
||||
default => '.'
|
||||
},
|
||||
'dst-name' => {
|
||||
type => "=s",
|
||||
help => "Name of the new virtual machine"
|
||||
|
@ -162,9 +175,12 @@ my $server = Opts::get_option('server');
|
|||
my $operation = Opts::get_option('operation');
|
||||
my $job = Opts::get_option('job');
|
||||
my $vm_name = Opts::get_option('vm-name');
|
||||
my $passphrase_file = Opts::get_option('passphrase-file');
|
||||
my $rotation_days = Opts::get_option('rotation-days');
|
||||
my $rotation_count = Opts::get_option('rotation-count');
|
||||
my $archive_regex = Opts::get_option('archive-regex');
|
||||
my $backup_file = Opts::get_option('backup-file');
|
||||
my $restore_dir = Opts::get_option('restore-dir');
|
||||
my $dst_name = Opts::get_option('dst-name');
|
||||
my $dst_host = Opts::get_option('dst-host');
|
||||
my $dst_datastore = Opts::get_option('dst-datastore');
|
||||
|
@ -181,12 +197,16 @@ my $test = Opts::option_is_set('test');
|
|||
my $snapshot_name = Opts::get_option('snapshot-name');
|
||||
my $snapshot_desc = Opts::get_option('snapshot-desc');
|
||||
|
||||
if (!defined ($passphrase_file) && exists $config{passphrase_file}) {
|
||||
$passphrase_file = $config{passphrase_file};
|
||||
}
|
||||
|
||||
my $vm;
|
||||
my $log_fh;
|
||||
my $archive_fn;
|
||||
my $backup_disks;
|
||||
my $time_pattern = '%Y-%m-%d_%H-%M';
|
||||
my $local_backup_dir = $config{local_backup_dir};
|
||||
my $archive_fn = sub { return false; };
|
||||
|
||||
sub stringify_message {
|
||||
my ($message) = @_;
|
||||
|
@ -281,6 +301,9 @@ sub main {
|
|||
when ('rotate') {
|
||||
rotate_backup();
|
||||
}
|
||||
when ('restore') {
|
||||
restore_backup();
|
||||
}
|
||||
when ('clone') {
|
||||
open_machine();
|
||||
clone_machine();
|
||||
|
@ -583,14 +606,20 @@ sub backup_machine() {
|
|||
}
|
||||
|
||||
$pigz_processes = max(1, $pigz_processes);
|
||||
my $tar_command = "tar -I \"pigz -p $pigz_processes\" -cf $tar_file -C $local_tmp_dir .";
|
||||
my $tar_command = "tar -I \"pigz -p $pigz_processes\" -c -C $local_tmp_dir .";
|
||||
|
||||
if (defined($passphrase_file)) {
|
||||
my $gpg_command = "gpg -c --passphrase-file \"$passphrase_file\" --batch --yes -o $tar_file.gpg";
|
||||
$tar_command = "$tar_command | $gpg_command";
|
||||
} else {
|
||||
$tar_command = "$tar_command -f $tar_file";
|
||||
}
|
||||
|
||||
log_message "Compressing with Gzip (using $pigz_processes processes) to TAR file.";
|
||||
log_message $tar_command;
|
||||
|
||||
unless ($test) {
|
||||
my $tar_status = system($tar_command);
|
||||
|
||||
unless ($tar_status == 0) {
|
||||
die "An error occurred when trying to compress '$vm_name' machine files.";
|
||||
}
|
||||
|
@ -631,7 +660,7 @@ sub rotate_backup() {
|
|||
log_message "Rotating '$vm_name' backups.";
|
||||
|
||||
my $local_dir = "$local_backup_dir/$vm_name";
|
||||
my $regex = qr/^\Q$vm_name\E_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2})\.tar\.gz$/;
|
||||
my $regex = qr/^\Q$vm_name\E_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2})/;
|
||||
my $now = Time::Piece->new;
|
||||
|
||||
my @archive_files;
|
||||
|
@ -723,6 +752,43 @@ sub rotate_backup() {
|
|||
closedir($dh);
|
||||
}
|
||||
|
||||
sub restore_backup() {
|
||||
log_message "Restoring backup file '$backup_file'.";
|
||||
|
||||
unless (-e $backup_file) {
|
||||
die "Backup file doesn't exists: $backup_file"
|
||||
}
|
||||
|
||||
if (!defined ($restore_dir) && exists $config{restore_dir}) {
|
||||
$restore_dir = $config{restore_dir};
|
||||
}
|
||||
unless (defined($restore_dir)) {
|
||||
die "Restore directory not defined."
|
||||
}
|
||||
unless (-e $restore_dir) {
|
||||
die "Restore directory doesn't exists: $restore_dir"
|
||||
}
|
||||
|
||||
my $tar_command = "tar xz -C \"$restore_dir\"";
|
||||
|
||||
if ($backup_file =~ qr/\.gpg$/) {
|
||||
my $gpg_command = "gpg --decrypt --passphrase-file \"$passphrase_file\" --batch --yes \"$backup_file\"";
|
||||
$tar_command = "$gpg_command | $tar_command";
|
||||
} else {
|
||||
$tar_command = "$tar_command -f \"$backup_file\"";
|
||||
}
|
||||
|
||||
log_message $tar_command;
|
||||
unless ($test) {
|
||||
my $tar_status = system($tar_command);
|
||||
unless ($tar_status == 0) {
|
||||
die "An error occurred restoring backup $backup_file";
|
||||
}
|
||||
}
|
||||
|
||||
log_message "Backup restored successfully.";
|
||||
}
|
||||
|
||||
sub clone_machine {
|
||||
log_message "Cloning '$vm_name' to '$dst_name'.";
|
||||
log_message "Doing some previous checkings.";
|
||||
|
|
Reference in New Issue