--- trunk/bin/BackupPC_burnArchiveCLI 2005/12/13 22:55:59 276 +++ trunk/bin/BackupPC_burnArchiveCLI 2006/03/01 12:11:23 335 @@ -1,8 +1,7 @@ #!/usr/bin/perl use strict; -#use lib "__INSTALLDIR__/lib"; -use lib "/data/backuppc-agi/lib"; +use lib "__INSTALLDIR__/lib"; use DBI; use BackupPC::Lib; @@ -16,6 +15,8 @@ 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 @@ -110,6 +111,8 @@ 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=?"); @@ -163,7 +166,7 @@ $writer->endTag("file"); } $writer->endTag("backup"); - } + } $writer->endTag("archive"); $writer->end(); @@ -254,6 +257,44 @@ 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 = ; + 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, @@ -276,6 +317,15 @@ order by archive_backup.backup_id, backup_parts.part_nr }); +my $sth_archive_backup_check = $dbh->prepare( qq{ + SELECT + sum(backups.parts) + 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) @@ -296,6 +346,27 @@ $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; @@ -318,108 +389,109 @@ } push @volumes, $v if ($v); + #warn "# volumes: ",Dumper(\@volumes),"\n"; + my $volumes = $#volumes + 1; my $volume_nr = 1; - foreach my $v (@volumes) { + my $copies = $Conf{BurnMultipleCopies} || 1; - print Dumper($v); + foreach my $copy_nr ( 1 .. $copies ) { - my $iso_size = 0; - my $disk_name = $dvd_nr; - # suffix added to multi-volume archives - my $volume_suffix = $dvd_nr; - - if ($volumes > 1) { - $volume_suffix = '_' . $volume_nr; - $disk_name .= ' ' . $volume_nr . '/' . $volumes; - } + foreach my $v (@volumes) { - print "Processing DVD #$dvd_nr, volume $volume_nr/$volumes\n"; + #print Dumper($v); - my $iso_file = my $xml_file = my $stage = - "${iso_dir}/${dvd_nr}"; + my $iso_size = 0; + my $disk_name = $dvd_nr; + # suffix added to multi-volume archives + my $volume_suffix = ''; - $iso_file .= $volume_suffix . '.iso'; - $xml_file .= '.xml'; - - $stage .= $volume_suffix . '.stage'; + if ($volumes > 1) { + $volume_suffix = '_' . $volume_nr; + $disk_name .= ' ' . $volume_nr . '/' . $volumes; + } - my $md5_file = "${stage}/${dvd_nr}${volume_suffix}.md5"; + print "Processing DVD #$dvd_nr, volume $volume_nr/$volumes\n"; - # - # check if ISO file exists - # + my $iso_file = my $xml_file = my $stage = + "${iso_dir}/${dvd_nr}"; - if (! -e $iso_file) { + $iso_file .= $volume_suffix . '.iso'; + $xml_file .= '.xml'; - # create stage directory - if (-e $stage) { - rmtree($stage) || die "can't remove $stage: $!"; - } - mkpath($stage); + $stage .= $volume_suffix . '.stage'; - # open file for md5sums - open(my $md5, "> $md5_file") || skip "can't open $md5_file: $!"; + my $md5_file = "${stage}/${dvd_nr}${volume_suffix}.md5"; - my $parts_on_this_volume = 0; + # + # check if ISO file exists + # - foreach my $p (@{ $v->{parts} }) { - my $tar_file = $p->{filename} || die "no filename in part", Dumper($p); - my $rel_path = $tar_file; + if (! -e $iso_file) { - if (-d "$tar_dir/$rel_path") { - $rel_path .= '/' . $p->{part_nr}; - mkpath("$stage/$rel_path") unless (-d "$stage/$rel_path"); + # create stage directory + if (-e $stage) { + rmtree($stage) || die "can't remove $stage: $!"; } - $rel_path .= '.tar.gz'; + mkpath($stage); - skip "can't find increment $rel_path: $!" unless (-r "$tar_dir/$rel_path"); + # open file for md5sums + open(my $md5, "> $md5_file") || skip "can't open $md5_file: $!"; - add_symlink("$tar_dir/$rel_path", "$stage/$rel_path"); + my $parts_on_this_volume = 0; - my $md5sum = $p->{md5} || die "no md5 in part ", Dumper($p); - chomp($md5sum); - print $md5 "$md5sum $rel_path\n" || die "can't write md5sum: $!"; + foreach my $p (@{ $v->{parts} }) { + my $tar_file = $p->{filename} || die "no filename in part", Dumper($p); + my $rel_path = $tar_file; - $parts_on_this_volume++; - } + if (-d "$tar_dir/$rel_path") { + mkpath("$stage/$rel_path") unless (-d "$stage/$rel_path"); + $rel_path .= '/' . $p->{part_nr}; + } + $rel_path .= '.tar.gz'; - # add file list and note in xml - dumpArchive2XML($dbh, $dvd_nr, $xml_file) unless (-f $xml_file); + skip "can't find increment $rel_path: $!" unless (-r "$tar_dir/$rel_path"); - add_symlink($xml_file, "$stage/${dvd_nr}.xml"); + add_symlink("$tar_dir/$rel_path", "$stage/$rel_path"); - # add css file for archive - my $css_file = $Conf{CgiImageDir} . '/archive.css'; - if (-r $css_file) { - add_symlink($css_file, "$stage/archive.css"); - } else { - print "WARNING: missing $css_file, not added to iso image!\n"; - } + my $md5sum = $p->{md5} || die "no md5 in part ", Dumper($p); + chomp($md5sum); + print $md5 "$md5sum $rel_path\n" || die "can't write md5sum: $!"; - print "Running mkisofs now for $parts_on_this_volume increments, disk $disk_name\n"; + $parts_on_this_volume++; + } - my $cmd = $bin->{'mkisofs'} . qq{ -A BackupPC -gui -J -r -T --input-charset ISO-8859-2 -V "$disk_name" -o ${iso_file}.tmp -f $stage }; + # add file list and note in xml + dumpArchive2XML($dbh, $dvd_nr, $xml_file) unless (-f $xml_file); - system($cmd) == 0 or skip "can't run $cmd: $?"; + add_symlink($xml_file, "$stage/${dvd_nr}.xml"); - rename $iso_file.'.tmp', $iso_file || skip "can't rename $iso_file: $!"; + # add css file for archive + my $css_file = $Conf{CgiImageDir} . '/archive.css'; + if (-r $css_file) { + add_symlink($css_file, "$stage/archive.css"); + } else { + print "WARNING: missing $css_file, not added to iso image!\n"; + } - $iso_size = (stat($iso_file))[7]; + print "Running mkisofs now for $parts_on_this_volume increments, disk $disk_name\n"; - print "Created $iso_file [$iso_size bytes] in ", fmt_time(time() - $t), "\n"; + my $cmd = $bin->{'mkisofs'} . qq{ -A BackupPC -gui -J -r -T --input-charset ISO-8859-2 -V "$disk_name" -o ${iso_file}.tmp -f $stage }; - # FIXME - #rmtree($stage) || warn "can't remove stage directory $stage: $!"; + system($cmd) == 0 or skip "can't run $cmd: $?"; - } else { - print "ISO $iso_file allready exists\n"; - } + rename $iso_file.'.tmp', $iso_file || skip "can't rename $iso_file: $!"; + + $iso_size = (stat($iso_file))[7]; - my $copies = $Conf{BurnMultipleCopies} || 1; + print "Created $iso_file [$iso_size bytes] in ", fmt_time(time() - $t), "\n"; - foreach my $copy_nr ( 1 .. $copies ) { + rmtree($stage) || warn "can't remove stage directory $stage: $!"; + + } else { + print "ISO $iso_file allready exists\n"; + } print "\nREADY TO BURN MEDIA $disk_name copy $copy_nr\n\nPlease insert blank media and press ENTER\n\n"; @@ -455,6 +527,8 @@ $sth->finish; $sth_archive_backup_parts->finish; $sth_archive_burned->finish; +$sth_archive_backup_check->finish; +$sth_archive_burned->finish; $dbh->disconnect;