#!/usr/bin/perl
use strict;
-#use lib "__INSTALLDIR__/lib";
-use lib "/data/backuppc-agi/lib";
+use lib "__INSTALLDIR__/lib";
use DBI;
use BackupPC::Lib;
use Data::Dumper;
my $debug = 0;
+# set this to 1 to prompt for DVD removal for each selected item.
+my $prompt_for_delete = shift @ARGV;
$|=1;
# don't check for user
AND hosts.id=backups.hostid
AND shares.id=backups.shareid
AND archive_backup.archive_id = ?
+ ORDER BY
+ hosts.name, shares.name, backups.num
};
my $sth = $dbh->prepare("SELECT dvd_nr, total_size, note, username, date,id FROM archive WHERE dvd_nr=?");
$writer->endTag("file");
}
$writer->endTag("backup");
- }
+ }
$writer->endTag("archive");
$writer->end();
symlink $from, $to || skip("can't symlink $from to $to: $!");
}
+sub delete_dvd($) {
+ my $dvd_nr = shift || return;
+
+ print "Do you want to delete DVD #$dvd_nr now? [NO/yes]: ";
+ my $ok = <STDIN>;
+ chomp($ok);
+ if (lc($ok) eq 'yes') {
+ print "Deleting DVD #$dvd_nr from database...\n";
+
+ $dbh->begin_work;
+
+ my $sth_delete_dvd = $dbh->prepare( qq{
+ delete from archive where dvd_nr = ?
+ } );
+ $sth_delete_dvd->execute( $dvd_nr );
+ $dbh->do( qq{
+ select setval('dvd_nr', (select max(dvd_nr) from archive), true)
+ } );
+
+ # remove files for this DVD
+ map {
+ if (-d $_) {
+ print "\tremoving dir $_\n";
+ rmtree($_) || die "can't rmtree $_: $!";
+ } else {
+ print "\tremoving $_\n";
+ unlink($_) || die "can't rm $_: $!";
+ }
+ } glob ( "/$iso_dir/$dvd_nr.*" );
+
+ $dbh->commit;
+
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
my $sth_archive_backup_parts = $dbh->prepare( qq{
select
archive_backup.backup_id,
order by archive_backup.backup_id, backup_parts.part_nr
});
+my $sth_archive_backup_check = $dbh->prepare( qq{
+ SELECT
+ count(backups.id)
+ FROM backups
+ JOIN archive_backup on archive_backup.backup_id = backups.id
+ JOIN archive on archive_id = archive.id
+ WHERE dvd_nr = ?
+});
+
my $sth_archive_burned = $dbh->prepare( qq{
insert into archive_burned
(archive_id, iso_size, part, copy)
$sth_archive_backup_parts->execute($dvd_nr);
+ $sth_archive_backup_check->execute($dvd_nr);
+
+ my ($parts_nr, $check_nr) = ($sth_archive_backup_parts->rows, $sth_archive_backup_check->fetchrow_array);
+
+ if ($parts_nr != $check_nr) {
+ warn "ERROR: DVD #$dvd_nr is still not inconsistent state. Some backup parts are ",
+ ($parts_nr < $check_nr) ? "missing ($parts_nr < $check_nr)" : "extra ($parts_nr > $check_nr)",
+ " you should re-create this DVD after BackupPC_incPartsUpdate finish\n";
+ delete_dvd( $dvd_nr );
+ next;
+ }
+
+ if ($sth_archive_backup_parts->rows == 0) {
+ warn "ERROR: no backup parts found for $dvd_nr. You should re-create that DVD.\n";
+ next if delete_dvd( $dvd_nr );
+ }
+
+ if ($prompt_for_delete) {
+ next if delete_dvd( $dvd_nr );
+ }
+
my @volumes;
my $v; # emtpy volume
my $v_size = 0;
}
push @volumes, $v if ($v);
+ #warn "# volumes: ",Dumper(\@volumes),"\n";
+
my $volumes = $#volumes + 1;
my $volume_nr = 1;
foreach my $v (@volumes) {
- print Dumper($v);
+ #print Dumper($v);
my $iso_size = 0;
my $disk_name = $dvd_nr;
# suffix added to multi-volume archives
- my $volume_suffix = $dvd_nr;
+ my $volume_suffix = '';
if ($volumes > 1) {
$volume_suffix = '_' . $volume_nr;
my $rel_path = $tar_file;
if (-d "$tar_dir/$rel_path") {
- $rel_path .= '/' . $p->{part_nr};
mkpath("$stage/$rel_path") unless (-d "$stage/$rel_path");
+ $rel_path .= '/' . $p->{part_nr};
}
$rel_path .= '.tar.gz';
add_symlink("$tar_dir/$rel_path", "$stage/$rel_path");
my $md5sum = $p->{md5} || die "no md5 in part ", Dumper($p);
- print $md5 "$md5sum\s\s$rel_path\n" || die "can't write md5sum: $!";
+ chomp($md5sum);
+ print $md5 "$md5sum $rel_path\n" || die "can't write md5sum: $!";
$parts_on_this_volume++;
}
print "Created $iso_file [$iso_size bytes] in ", fmt_time(time() - $t), "\n";
- # FIXME
- #rmtree($stage) || warn "can't remove stage directory $stage: $!";
+ rmtree($stage) || warn "can't remove stage directory $stage: $!";
} else {
print "ISO $iso_file allready exists\n";
$sth->finish;
$sth_archive_backup_parts->finish;
$sth_archive_burned->finish;
+$sth_archive_backup_check->finish;
+$sth_archive_burned->finish;
$dbh->disconnect;