diff --git a/config.pl b/config.pl index 28b40c3..1d971c6 100644 --- a/config.pl +++ b/config.pl @@ -12,7 +12,13 @@ backup_datastore => 'backup', # Directory where backups are stored # If it's mounted via NFS you have to disable caching for the mount -local_backup_dir => '/mnt/backup', +backup_dir => '/mnt/backup', + +# The default storage class +storage_class => 'nearline', + +# The archive storage class +archive_class => 'archive', # Directory where backups are be restored restore_dir => '/mnt/backup', @@ -34,7 +40,7 @@ rotations => { lastMonth => { days => 31, count => 31, - archive_regex => '^\d{4}-\d{2}-01' + archive_regex => '^\d{4}-\d{2}-01', # Function used to archive and exclude backups from rotation # https://perldoc.perl.org/Time/Piece.html @@ -45,7 +51,8 @@ rotations => { } }, lastWeek => { - days => 7 + days => 7, + storage_class => 'archive' }, lastYear => { days => 365 diff --git a/debian/changelog b/debian/changelog index ef6af85..136b32a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -vn-vmware (1.1.27) stable; urgency=low +vn-vmware (1.1.28) stable; urgency=low * Initial Release. diff --git a/vn-vmware.pl b/vn-vmware.pl index 339f394..1e548ba 100755 --- a/vn-vmware.pl +++ b/vn-vmware.pl @@ -86,6 +86,21 @@ my %opts = ( type => "=s", help => "Regular expression used to archive and exclude backups from rotation" }, + 'backup-dir' => { + type => "=s", + help => "Local directory where backups are stored", + default => '.' + }, + 'storage-class' => { + type => "=s", + help => "The storage class", + default => 'default' + }, + 'archive-class' => { + type => "=s", + help => "The archive storage class", + default => 'archive' + }, 'backup-file' => { type => "=s", help => "The path to the backup file that will be restored" @@ -97,7 +112,7 @@ my %opts = ( }, 'replicate-dir' => { type => "=s", - help => "Directory where local backup directory is replicated" + help => "Directory where backup directory is replicated" }, 'dst-name' => { type => "=s", @@ -176,6 +191,9 @@ Opts::parse(); Opts::validate(); my @config_options = ( + 'backup-dir', + 'storage-class', + 'archive-class', 'passphrase-file', 'restore-dir', 'replicate-dir' @@ -198,6 +216,9 @@ 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_dir = Opts::get_option('backup-dir'); +my $storage_class = Opts::get_option('storage-class'); +my $archive_class = Opts::get_option('archive-class'); my $backup_file = Opts::get_option('backup-file'); my $restore_dir = Opts::get_option('restore-dir'); my $replicate_dir = Opts::get_option('replicate-dir'); @@ -222,8 +243,7 @@ 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 $secure_file = "$local_backup_dir/.keepme"; +my $secure_file = "$backup_dir/.keepme"; sub stringify_message { my ($message) = @_; @@ -366,8 +386,8 @@ sub backup_machine() { my $time_mark = $time->strftime($time_pattern); my $tmp_dir = ".$time_mark"; my $backup_datastore = $config{backup_datastore}; - my $ds_tmp_dir = "[$backup_datastore] $vm_name/$tmp_dir"; - my $local_dir = "$local_backup_dir/$vm_name"; + my $ds_tmp_dir = "[$backup_datastore] $storage_class/$vm_name/$tmp_dir"; + my $local_dir = "$backup_dir/$storage_class/$vm_name"; my $local_tmp_dir = "$local_dir/$tmp_dir"; my $tar_file = "$local_dir/${vm_name}_$time_mark.tar.gz"; @@ -511,15 +531,37 @@ sub backup_machine() { # diskType => 'thin' #); - unless ($test) { - $vdm->CopyVirtualDisk( - sourceName => $disk_path, - sourceDatacenter => $dc, - destName => "$ds_tmp_dir/$disk_file", - destDatacenter => $dc - #destSpec => $disk_spec - ); - } + # FIXME: Workaround for InvalidDiskFormat error + my $attempt = 0; + my $copied = false; + + do { + $attempt++; + + eval { + unless ($test) { + $vdm->CopyVirtualDisk( + sourceName => $disk_path, + sourceDatacenter => $dc, + destName => "$ds_tmp_dir/$disk_file", + destDatacenter => $dc + #destSpec => $disk_spec + ); + } + $copied = true; + }; + + my $copy_err = $@; + if ($copy_err) { + if ($attempt >= 3) { + die $copy_err; + } + + log_message $copy_err + log_message "Error while copying disk, sleeping some time and trying again."; + sleep(10); + } + } while (!$copied); } log_message "Removing backup snapshot."; @@ -636,6 +678,9 @@ sub backup_job() { if (exists $rotation_cfg->{days}) { $rotation_days = $rotation_cfg->{days}; } + if (exists $rotation_cfg->{storage_class}) { + $storage_class = $rotation_cfg->{storage_class}; + } if (exists $rotation_cfg->{archive_regex}) { $archive_regex = $rotation_cfg->{archive_regex}; $archive_regex = qr/$archive_regex/; @@ -675,7 +720,7 @@ sub rotate_backup() { log_message "Rotating '$vm_name' backups."; - my $local_dir = "$local_backup_dir/$vm_name"; + my $local_dir = "$backup_dir/$storage_class/$vm_name"; my $regex = qr/^\Q$vm_name\E_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2})/; my $now = Time::Piece->new; @@ -713,7 +758,8 @@ sub rotate_backup() { } my $archive_count = scalar(@archive_files); - my $archive_dir = "$local_dir/.archive"; + my $archive_dir = "$backup_dir/$archive_class"; + my $archive_vm_dir = "$archive_dir/$vm_name"; if ($archive_count > 0) { log_message "Archiving $archive_count backups."; @@ -724,11 +770,16 @@ sub rotate_backup() { mkdir $archive_dir; } } + unless (-e $archive_vm_dir) { + unless ($test) { + mkdir $archive_vm_dir; + } + } foreach my $archive_file (@archive_files) { log_message "$archive_file"; unless ($test) { - move("$local_dir/$archive_file", "$archive_dir/$archive_file"); + move("$local_dir/$archive_file", "$archive_vm_dir/$archive_file"); } } @@ -817,7 +868,7 @@ sub replicate_backups() { } 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\""; + my $rsync_command = "rsync $rsync_params \"$backup_dir/\" \"$replicate_dir\""; log_message $rsync_command; unless ($test) { @@ -831,7 +882,7 @@ sub replicate_backups() { } sub init_backup_dir() { - log_message "Initializing backup directory '$local_backup_dir'."; + log_message "Initializing backup directory '$backup_dir'."; if (-e $secure_file) { die "Backup directory already initialized.";