Refactor, backup replication ready
gitea/vn-vmware/pipeline/head There was a failure building this commit
Details
gitea/vn-vmware/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
db07203605
commit
c8e5fa806a
|
@ -1,2 +1,2 @@
|
||||||
config.my.pl
|
config.local.pl
|
||||||
visdkrc
|
visdkrc
|
11
config.pl
11
config.pl
|
@ -1,5 +1,5 @@
|
||||||
# Configuration file, be careful to respect the Perl syntax.
|
# Configuration file, be careful to respect the Perl syntax.
|
||||||
# Don't modify this file, copy it to config.my.pl and make your changes there.
|
# Don't modify this file, copy it to config.local.pl and make your changes there.
|
||||||
|
|
||||||
# The log file path
|
# The log file path
|
||||||
log_file => '/var/log/vn-vmware.log',
|
log_file => '/var/log/vn-vmware.log',
|
||||||
|
@ -10,18 +10,21 @@ datacenter => 'datacenter1',
|
||||||
# The datastore name where backups must be stored
|
# The datastore name where backups must be stored
|
||||||
backup_datastore => 'backup',
|
backup_datastore => 'backup',
|
||||||
|
|
||||||
# The local directory where backups datastore folder is mounted
|
# Directory where backups are stored
|
||||||
# If it's mounted via NFS you have to disable caching for the mount
|
# If it's mounted via NFS you have to disable caching for the mount
|
||||||
local_backup_dir => '/mnt/backup',
|
local_backup_dir => '/mnt/backup',
|
||||||
|
|
||||||
# Directory where backups will be restored
|
# Directory where backups are be restored
|
||||||
restore_dir => '/mnt/backup',
|
restore_dir => '/mnt/backup',
|
||||||
|
|
||||||
|
# Directory where local backup directory is replicated
|
||||||
|
replicate_dir => '/mnt/backup-sync',
|
||||||
|
|
||||||
# Number of processes used by pigz to compress backups
|
# Number of processes used by pigz to compress backups
|
||||||
pigz_processes => 1,
|
pigz_processes => 1,
|
||||||
|
|
||||||
# Whether to encrypt backups using gpg with passed passphrase file
|
# Whether to encrypt backups using gpg with passed passphrase file
|
||||||
passphrase_file => '/etc/vn-vmware/passphrase.gpg',
|
passphrase_file => '/etc/vn-vmware/gpg.key',
|
||||||
|
|
||||||
# The default rotation to use if none is specified on job
|
# The default rotation to use if none is specified on job
|
||||||
rotation => 'lastMonth',
|
rotation => 'lastMonth',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
vn-vmware (1.1.21) stable; urgency=low
|
vn-vmware (1.1.22) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ Vcs-Git: https://git.verdnatura.es/vn-vmware
|
||||||
Package: vn-vmware
|
Package: vn-vmware
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: perl, pigz, libsys-cpu-perl
|
Depends: perl, pigz, libsys-cpu-perl
|
||||||
Suggests: gpg
|
Suggests: gpg, rsync
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Description: Maintenance scripts for VMWare
|
Description: Maintenance scripts for VMWare
|
||||||
|
|
330
vn-vmware.pl
330
vn-vmware.pl
|
@ -24,9 +24,9 @@ use constant true => 1;
|
||||||
|
|
||||||
my %config;
|
my %config;
|
||||||
my @config_files = (
|
my @config_files = (
|
||||||
'/etc/vn-vmware/config.my.pl',
|
'/etc/vn-vmware/config.local.pl',
|
||||||
'/etc/vn-vmware/config.pl',
|
'/etc/vn-vmware/config.pl',
|
||||||
'config.my.pl',
|
'config.local.pl',
|
||||||
'config.pl'
|
'config.pl'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ foreach my $vi_config_file (@vi_config_files) {
|
||||||
my %opts = (
|
my %opts = (
|
||||||
'operation' => {
|
'operation' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Operation to perform: none, backup-job, clone-job, backup, rotate, restore, clone, snapshot, migrate",
|
help => "Operation to perform: none, backup, backup-job, rotate, restore, replicate, init, clone, clone-job, snapshot, migrate",
|
||||||
required => true
|
required => true
|
||||||
},
|
},
|
||||||
'job' => {
|
'job' => {
|
||||||
|
@ -92,9 +92,13 @@ my %opts = (
|
||||||
},
|
},
|
||||||
'restore-dir' => {
|
'restore-dir' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "The backup directory where backup will be restored",
|
help => "Directory where backups are be restored",
|
||||||
default => '.'
|
default => '.'
|
||||||
},
|
},
|
||||||
|
'replicate-dir' => {
|
||||||
|
type => "=s",
|
||||||
|
help => "Directory where local backup directory is replicated"
|
||||||
|
},
|
||||||
'dst-name' => {
|
'dst-name' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Name of the new virtual machine"
|
help => "Name of the new virtual machine"
|
||||||
|
@ -171,6 +175,21 @@ Opts::add_options(%opts);
|
||||||
Opts::parse();
|
Opts::parse();
|
||||||
Opts::validate();
|
Opts::validate();
|
||||||
|
|
||||||
|
my @config_options = (
|
||||||
|
'passphrase-file',
|
||||||
|
'restore-dir',
|
||||||
|
'replicate-dir'
|
||||||
|
);
|
||||||
|
foreach my $config_option (@config_options) {
|
||||||
|
my $underscore = $config_option;
|
||||||
|
$underscore =~ s/-/_/;
|
||||||
|
if (!Opts::option_is_set($config_option) && exists $config{$underscore}) {
|
||||||
|
Opts::set_option($config_option, $config{$underscore});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Opts::validate();
|
||||||
|
|
||||||
my $server = Opts::get_option('server');
|
my $server = Opts::get_option('server');
|
||||||
my $operation = Opts::get_option('operation');
|
my $operation = Opts::get_option('operation');
|
||||||
my $job = Opts::get_option('job');
|
my $job = Opts::get_option('job');
|
||||||
|
@ -181,6 +200,7 @@ my $rotation_count = Opts::get_option('rotation-count');
|
||||||
my $archive_regex = Opts::get_option('archive-regex');
|
my $archive_regex = Opts::get_option('archive-regex');
|
||||||
my $backup_file = Opts::get_option('backup-file');
|
my $backup_file = Opts::get_option('backup-file');
|
||||||
my $restore_dir = Opts::get_option('restore-dir');
|
my $restore_dir = Opts::get_option('restore-dir');
|
||||||
|
my $replicate_dir = Opts::get_option('replicate-dir');
|
||||||
my $dst_name = Opts::get_option('dst-name');
|
my $dst_name = Opts::get_option('dst-name');
|
||||||
my $dst_host = Opts::get_option('dst-host');
|
my $dst_host = Opts::get_option('dst-host');
|
||||||
my $dst_datastore = Opts::get_option('dst-datastore');
|
my $dst_datastore = Opts::get_option('dst-datastore');
|
||||||
|
@ -197,16 +217,13 @@ my $test = Opts::option_is_set('test');
|
||||||
my $snapshot_name = Opts::get_option('snapshot-name');
|
my $snapshot_name = Opts::get_option('snapshot-name');
|
||||||
my $snapshot_desc = Opts::get_option('snapshot-desc');
|
my $snapshot_desc = Opts::get_option('snapshot-desc');
|
||||||
|
|
||||||
if (!defined ($passphrase_file) && exists $config{passphrase_file}) {
|
|
||||||
$passphrase_file = $config{passphrase_file};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $vm;
|
my $vm;
|
||||||
my $log_fh;
|
my $log_fh;
|
||||||
my $archive_fn;
|
my $archive_fn;
|
||||||
my $backup_disks;
|
my $backup_disks;
|
||||||
my $time_pattern = '%Y-%m-%d_%H-%M';
|
my $time_pattern = '%Y-%m-%d_%H-%M';
|
||||||
my $local_backup_dir = $config{local_backup_dir};
|
my $local_backup_dir = $config{local_backup_dir};
|
||||||
|
my $secure_file = "$local_backup_dir/.keepme";
|
||||||
|
|
||||||
sub stringify_message {
|
sub stringify_message {
|
||||||
my ($message) = @_;
|
my ($message) = @_;
|
||||||
|
@ -288,26 +305,32 @@ sub main {
|
||||||
die "Operation not defined.";
|
die "Operation not defined.";
|
||||||
}
|
}
|
||||||
given ($operation) {
|
given ($operation) {
|
||||||
when ('backup-job') {
|
|
||||||
backup_job();
|
|
||||||
}
|
|
||||||
when ('clone-job') {
|
|
||||||
clone_job();
|
|
||||||
}
|
|
||||||
when ('backup') {
|
when ('backup') {
|
||||||
open_machine();
|
open_machine();
|
||||||
backup_machine();
|
backup_machine();
|
||||||
}
|
}
|
||||||
|
when ('backup-job') {
|
||||||
|
backup_job();
|
||||||
|
}
|
||||||
when ('rotate') {
|
when ('rotate') {
|
||||||
rotate_backup();
|
rotate_backup();
|
||||||
}
|
}
|
||||||
when ('restore') {
|
when ('restore') {
|
||||||
restore_backup();
|
restore_backup();
|
||||||
}
|
}
|
||||||
|
when ('replicate') {
|
||||||
|
replicate_backups();
|
||||||
|
}
|
||||||
|
when ('init') {
|
||||||
|
init_backup_dir();
|
||||||
|
}
|
||||||
when ('clone') {
|
when ('clone') {
|
||||||
open_machine();
|
open_machine();
|
||||||
clone_machine();
|
clone_machine();
|
||||||
}
|
}
|
||||||
|
when ('clone-job') {
|
||||||
|
clone_job();
|
||||||
|
}
|
||||||
when ('snapshot') {
|
when ('snapshot') {
|
||||||
open_machine();
|
open_machine();
|
||||||
snapshot_machine();
|
snapshot_machine();
|
||||||
|
@ -336,119 +359,30 @@ sub main {
|
||||||
|
|
||||||
#--------------------------------- Operations
|
#--------------------------------- Operations
|
||||||
|
|
||||||
sub backup_job() {
|
|
||||||
unless ($job) {
|
|
||||||
die "Job not defined.";
|
|
||||||
}
|
|
||||||
unless (exists $config{backup_jobs}{$job}) {
|
|
||||||
die "Backup job '$job' doesn't exist.";
|
|
||||||
}
|
|
||||||
|
|
||||||
log_message "Backup job '$job' started.";
|
|
||||||
|
|
||||||
my $backup_job = $config{backup_jobs}{$job};
|
|
||||||
my @machines = @{$backup_job->{machines}};
|
|
||||||
|
|
||||||
my $default_rotation;
|
|
||||||
|
|
||||||
if (exists $backup_job->{rotation}) {
|
|
||||||
$default_rotation = $backup_job->{rotation};
|
|
||||||
} elsif (exists $config{rotation}) {
|
|
||||||
$default_rotation = $config{rotation};
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $machine (@machines) {
|
|
||||||
eval {
|
|
||||||
my $rotation_name = $default_rotation;
|
|
||||||
|
|
||||||
if (ref($machine) eq 'HASH') {
|
|
||||||
$vm_name = $machine->{name};
|
|
||||||
$backup_disks = $machine->{disks};
|
|
||||||
|
|
||||||
if (exists $machine->{rotation}) {
|
|
||||||
$rotation_name = $machine->{rotation};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$vm_name = $machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined ($rotation_name)) {
|
|
||||||
unless (exists $config{rotations}{$rotation_name}) {
|
|
||||||
die "Rotation '$rotation_name' not defined.";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $rotation_cfg = $config{rotations}{$rotation_name};
|
|
||||||
|
|
||||||
if (exists $rotation_cfg->{count}) {
|
|
||||||
$rotation_count = $rotation_cfg->{count};
|
|
||||||
}
|
|
||||||
if (exists $rotation_cfg->{days}) {
|
|
||||||
$rotation_days = $rotation_cfg->{days};
|
|
||||||
}
|
|
||||||
if (exists $rotation_cfg->{archive_regex}) {
|
|
||||||
$archive_regex = $rotation_cfg->{archive_regex};
|
|
||||||
$archive_regex = qr/$archive_regex/;
|
|
||||||
}
|
|
||||||
if (exists $rotation_cfg->{archive_fn}) {
|
|
||||||
$archive_fn = $rotation_cfg->{archive_fn};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open_machine();
|
|
||||||
backup_machine();
|
|
||||||
rotate_backup();
|
|
||||||
};
|
|
||||||
if ($@) {
|
|
||||||
log_error $@;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_message "Backup job '$job' finished.";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub clone_job() {
|
|
||||||
unless ($job) {
|
|
||||||
die "Job not defined.";
|
|
||||||
}
|
|
||||||
unless (exists $config{clone_jobs}{$job}) {
|
|
||||||
die "Clone job '$job' doesn't exist.";
|
|
||||||
}
|
|
||||||
|
|
||||||
log_message "Clone job '$job' started.";
|
|
||||||
|
|
||||||
my $clone_job = $config{clone_jobs}{$job};
|
|
||||||
|
|
||||||
$vm_name = $clone_job->{vm};
|
|
||||||
$dst_name = $clone_job->{dst_name};
|
|
||||||
$dst_host = $clone_job->{dst_host};
|
|
||||||
$dst_datastore = $clone_job->{dst_datastore};
|
|
||||||
$memory = $clone_job->{memory};
|
|
||||||
$num_cpus = $clone_job->{num_cpus};
|
|
||||||
$mac = $clone_job->{mac};
|
|
||||||
$poweron = $clone_job->{poweron};
|
|
||||||
$overwrite = $clone_job->{overwrite};
|
|
||||||
|
|
||||||
open_machine();
|
|
||||||
clone_machine();
|
|
||||||
|
|
||||||
log_message "Clone job '$job' finished.";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub backup_machine() {
|
sub backup_machine() {
|
||||||
log_message "Backup of '$vm_name' started.";
|
log_message "Backup of '$vm_name' started.";
|
||||||
|
|
||||||
my $time = Time::Piece->new;
|
my $time = Time::Piece->new;
|
||||||
my $time_mark = $time->strftime($time_pattern);
|
my $time_mark = $time->strftime($time_pattern);
|
||||||
my $tmpDir = ".$time_mark";
|
my $tmp_dir = ".$time_mark";
|
||||||
my $backup_datastore = $config{backup_datastore};
|
my $backup_datastore = $config{backup_datastore};
|
||||||
my $ds_tmp_dir = "[$backup_datastore] $vm_name/$tmpDir";
|
my $ds_tmp_dir = "[$backup_datastore] $vm_name/$tmp_dir";
|
||||||
my $local_dir = "$local_backup_dir/$vm_name";
|
my $local_dir = "$local_backup_dir/$vm_name";
|
||||||
my $local_tmp_dir = "$local_dir/$tmpDir";
|
my $local_tmp_dir = "$local_dir/$tmp_dir";
|
||||||
my $tar_file = "$local_dir/${vm_name}_$time_mark.tar.gz";
|
my $tar_file = "$local_dir/${vm_name}_$time_mark.tar.gz";
|
||||||
|
|
||||||
|
if (defined($passphrase_file)) {
|
||||||
|
$tar_file = "$tar_file.gpg";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $tmp_file = "$tar_file.tmp";
|
||||||
|
|
||||||
if (-e $local_tmp_dir) {
|
if (-e $local_tmp_dir) {
|
||||||
die "Temporary backup directory already exists: $local_tmp_dir";
|
die "Temporary backup directory already exists: $local_tmp_dir";
|
||||||
}
|
}
|
||||||
|
if (-e $tar_file) {
|
||||||
|
die "Backup file already exists: $tar_file";
|
||||||
|
}
|
||||||
|
|
||||||
my $service_content = Vim::get_service_content();
|
my $service_content = Vim::get_service_content();
|
||||||
my $file_manager = Vim::get_view(mo_ref => $service_content->fileManager);
|
my $file_manager = Vim::get_view(mo_ref => $service_content->fileManager);
|
||||||
|
@ -589,13 +523,13 @@ sub backup_machine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Removing backup snapshot.";
|
log_message "Removing backup snapshot.";
|
||||||
unless ($test) {
|
if ($snapshot) {
|
||||||
$snapshot->RemoveSnapshot(
|
$snapshot->RemoveSnapshot(
|
||||||
removeChildren => true,
|
removeChildren => true,
|
||||||
consolidate => true
|
consolidate => true
|
||||||
);
|
);
|
||||||
|
$snapshot = undef;
|
||||||
}
|
}
|
||||||
$snapshot = undef;
|
|
||||||
|
|
||||||
my $pigz_processes;
|
my $pigz_processes;
|
||||||
|
|
||||||
|
@ -609,10 +543,10 @@ sub backup_machine() {
|
||||||
my $tar_command = "tar -I \"pigz -p $pigz_processes\" -c -C \"$local_tmp_dir\" .";
|
my $tar_command = "tar -I \"pigz -p $pigz_processes\" -c -C \"$local_tmp_dir\" .";
|
||||||
|
|
||||||
if (defined($passphrase_file)) {
|
if (defined($passphrase_file)) {
|
||||||
my $gpg_command = "gpg -c --passphrase-file \"$passphrase_file\" --batch --yes -o \"$tar_file.gpg\"";
|
my $gpg_command = "gpg -c --passphrase-file \"$passphrase_file\" --batch --yes -o \"$tmp_file\"";
|
||||||
$tar_command = "$tar_command | $gpg_command";
|
$tar_command = "$tar_command | $gpg_command";
|
||||||
} else {
|
} else {
|
||||||
$tar_command = "$tar_command -f \"$tar_file\"";
|
$tar_command = "$tar_command -f \"$tmp_file\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Compressing with Gzip (using $pigz_processes processes) to TAR file.";
|
log_message "Compressing with Gzip (using $pigz_processes processes) to TAR file.";
|
||||||
|
@ -629,6 +563,10 @@ sub backup_machine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setpriority(0, 0, $priority);
|
setpriority(0, 0, $priority);
|
||||||
|
unless ($test) {
|
||||||
|
move($tmp_file, $tar_file);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
my $err = $@;
|
my $err = $@;
|
||||||
|
@ -642,6 +580,14 @@ sub backup_machine() {
|
||||||
consolidate => true
|
consolidate => true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
unless ($test) {
|
||||||
|
if (-e $tar_file) {
|
||||||
|
unlink $tar_file;
|
||||||
|
}
|
||||||
|
if (-e $tmp_file) {
|
||||||
|
unlink $tmp_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Removing temporary directory: $local_tmp_dir";
|
log_message "Removing temporary directory: $local_tmp_dir";
|
||||||
|
@ -656,6 +602,76 @@ sub backup_machine() {
|
||||||
log_message "Backup of '$vm_name' successfully created.";
|
log_message "Backup of '$vm_name' successfully created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub backup_job() {
|
||||||
|
unless ($job) {
|
||||||
|
die "Job not defined.";
|
||||||
|
}
|
||||||
|
unless (exists $config{backup_jobs}{$job}) {
|
||||||
|
die "Backup job '$job' doesn't exist.";
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Backup job '$job' started.";
|
||||||
|
|
||||||
|
my $backup_job = $config{backup_jobs}{$job};
|
||||||
|
my @machines = @{$backup_job->{machines}};
|
||||||
|
|
||||||
|
my $default_rotation;
|
||||||
|
|
||||||
|
if (exists $backup_job->{rotation}) {
|
||||||
|
$default_rotation = $backup_job->{rotation};
|
||||||
|
} elsif (exists $config{rotation}) {
|
||||||
|
$default_rotation = $config{rotation};
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $machine (@machines) {
|
||||||
|
eval {
|
||||||
|
my $rotation_name = $default_rotation;
|
||||||
|
|
||||||
|
if (ref($machine) eq 'HASH') {
|
||||||
|
$vm_name = $machine->{name};
|
||||||
|
$backup_disks = $machine->{disks};
|
||||||
|
|
||||||
|
if (exists $machine->{rotation}) {
|
||||||
|
$rotation_name = $machine->{rotation};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$vm_name = $machine;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined ($rotation_name)) {
|
||||||
|
unless (exists $config{rotations}{$rotation_name}) {
|
||||||
|
die "Rotation '$rotation_name' not defined.";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $rotation_cfg = $config{rotations}{$rotation_name};
|
||||||
|
|
||||||
|
if (exists $rotation_cfg->{count}) {
|
||||||
|
$rotation_count = $rotation_cfg->{count};
|
||||||
|
}
|
||||||
|
if (exists $rotation_cfg->{days}) {
|
||||||
|
$rotation_days = $rotation_cfg->{days};
|
||||||
|
}
|
||||||
|
if (exists $rotation_cfg->{archive_regex}) {
|
||||||
|
$archive_regex = $rotation_cfg->{archive_regex};
|
||||||
|
$archive_regex = qr/$archive_regex/;
|
||||||
|
}
|
||||||
|
if (exists $rotation_cfg->{archive_fn}) {
|
||||||
|
$archive_fn = $rotation_cfg->{archive_fn};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open_machine();
|
||||||
|
backup_machine();
|
||||||
|
rotate_backup();
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
log_error $@;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Backup job '$job' finished.";
|
||||||
|
}
|
||||||
|
|
||||||
sub rotate_backup() {
|
sub rotate_backup() {
|
||||||
if ($rotation_days == 0 && $rotation_count == 0) {
|
if ($rotation_days == 0 && $rotation_count == 0) {
|
||||||
log_message "No rotation days or count, aborting.";
|
log_message "No rotation days or count, aborting.";
|
||||||
|
@ -717,7 +733,7 @@ sub rotate_backup() {
|
||||||
foreach my $archive_file (@archive_files) {
|
foreach my $archive_file (@archive_files) {
|
||||||
log_message "$archive_file";
|
log_message "$archive_file";
|
||||||
unless ($test) {
|
unless ($test) {
|
||||||
move ("$local_dir/$archive_file", "$archive_dir/$archive_file");
|
move("$local_dir/$archive_file", "$archive_dir/$archive_file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,9 +780,6 @@ sub restore_backup() {
|
||||||
die "Backup file doesn't exists: $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)) {
|
unless (defined($restore_dir)) {
|
||||||
die "Restore directory not defined."
|
die "Restore directory not defined."
|
||||||
}
|
}
|
||||||
|
@ -794,6 +807,49 @@ sub restore_backup() {
|
||||||
log_message "Backup restored successfully.";
|
log_message "Backup restored successfully.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub replicate_backups() {
|
||||||
|
log_message "Replicating backups to '$replicate_dir'.";
|
||||||
|
|
||||||
|
unless (-e $secure_file) {
|
||||||
|
die "Invalid source directory. Is it mounted and initialized?";
|
||||||
|
}
|
||||||
|
unless (-e $replicate_dir) {
|
||||||
|
die "Replicate dir doesn't exists: $replicate_dir";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $rsync_params = '-rltmD --delete-after --include="*.tar.gz" --include="*.tar.gz.gpg" --include="*/" --exclude="*"';
|
||||||
|
my $rsync_command = "rsync $rsync_params \"$local_backup_dir/\" \"$replicate_dir\"";
|
||||||
|
log_message $rsync_command;
|
||||||
|
|
||||||
|
unless ($test) {
|
||||||
|
my $tar_status = system($rsync_command);
|
||||||
|
unless ($rsync_command == 0) {
|
||||||
|
die "An error occurred while replicating backups.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Backups replicated successfully.";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub init_backup_dir() {
|
||||||
|
log_message "Initializing backup directory '$local_backup_dir'.";
|
||||||
|
|
||||||
|
if (-e $secure_file) {
|
||||||
|
die "Backup directory already initialized.";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $secure_content = "Don't delete me! I'm used to be sure this directory is mounted before running rsync\n";
|
||||||
|
|
||||||
|
unless ($test) {
|
||||||
|
my $secure_fh;
|
||||||
|
open($secure_fh, '>>', $secure_file);
|
||||||
|
print $secure_fh $secure_content;
|
||||||
|
close($secure_fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Backup directory initalized.";
|
||||||
|
}
|
||||||
|
|
||||||
sub clone_machine {
|
sub clone_machine {
|
||||||
log_message "Cloning '$vm_name' to '$dst_name'.";
|
log_message "Cloning '$vm_name' to '$dst_name'.";
|
||||||
log_message "Doing some previous checkings.";
|
log_message "Doing some previous checkings.";
|
||||||
|
@ -992,6 +1048,34 @@ sub clone_machine {
|
||||||
log_message "Clone '$dst_name' of '$vm_name' successfully created.";
|
log_message "Clone '$dst_name' of '$vm_name' successfully created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub clone_job() {
|
||||||
|
unless ($job) {
|
||||||
|
die "Job not defined.";
|
||||||
|
}
|
||||||
|
unless (exists $config{clone_jobs}{$job}) {
|
||||||
|
die "Clone job '$job' doesn't exist.";
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Clone job '$job' started.";
|
||||||
|
|
||||||
|
my $clone_job = $config{clone_jobs}{$job};
|
||||||
|
|
||||||
|
$vm_name = $clone_job->{vm};
|
||||||
|
$dst_name = $clone_job->{dst_name};
|
||||||
|
$dst_host = $clone_job->{dst_host};
|
||||||
|
$dst_datastore = $clone_job->{dst_datastore};
|
||||||
|
$memory = $clone_job->{memory};
|
||||||
|
$num_cpus = $clone_job->{num_cpus};
|
||||||
|
$mac = $clone_job->{mac};
|
||||||
|
$poweron = $clone_job->{poweron};
|
||||||
|
$overwrite = $clone_job->{overwrite};
|
||||||
|
|
||||||
|
open_machine();
|
||||||
|
clone_machine();
|
||||||
|
|
||||||
|
log_message "Clone job '$job' finished.";
|
||||||
|
}
|
||||||
|
|
||||||
sub snapshot_machine() {
|
sub snapshot_machine() {
|
||||||
log_message "Creating snapshot of '$vm_name'.";
|
log_message "Creating snapshot of '$vm_name'.";
|
||||||
|
|
||||||
|
|
Reference in New Issue