web/modules/dobby/Dobby/BackupLog.pm | 59 ++++++++++++++++++++++- web/modules/dobby/Dobby/CLI/BackupCommands.pm | 33 ++++++++++--- web/modules/dobby/Dobby/Files.pm | 65 ++++++++++++++++---------- 3 files changed, 122 insertions(+), 35 deletions(-)
New commits: commit 91ba3471fd4e9b1327aa7660bc786bd1bace64b7 Author: Miroslav Suchý msuchy@redhat.com Date: Mon Oct 22 16:00:17 2012 +0200
log into control file empty directories
diff --git a/web/modules/dobby/Dobby/BackupLog.pm b/web/modules/dobby/Dobby/BackupLog.pm index 9b010dd..3928531 100644 --- a/web/modules/dobby/Dobby/BackupLog.pm +++ b/web/modules/dobby/Dobby/BackupLog.pm @@ -22,7 +22,7 @@ use Storable qw/freeze thaw/; use XML::LibXML;
our @ISA = qw/RHN::SimpleStruct/; -our @simple_struct_fields = qw/start finish sid tablespaces archive_logs control_file type cold_files base_dir/; +our @simple_struct_fields = qw/start finish sid tablespaces archive_logs control_file type cold_files cold_dirs base_dir/;
# UGLY HACK for now; use Storable instead of a real data structure. # ugh. @@ -69,6 +69,11 @@ sub fromXml() { $log->add_cold_file($fe->fromXml($fileentry)); }
+ foreach my $direntry ($doc->getElementsByTagName('direntry')){ + my $de = new Dobby::BackupLog::DirEntry(); + $log->add_cold_file($de->fromXml($direntry)); + } + foreach my $tablespaceentry ($doc->getElementsByTagName('tablespaceentry')){ my $te = new Dobby::BackupLog::TablespaceEntry(); $log->add_tablespace_entry($te->fromXml($tablespaceentry)); @@ -110,6 +115,12 @@ sub toXml { $cold_files-> appendChild($file_entry->toXml($doc)); } } + my $cold_dirs = $doc->createElement('colddirs'); + if (defined($self->cold_dirs)) { + for my $dir_entry (@{$self->cold_dirs}) { + $cold_dirs-> appendChild($dir_entry->toXml($doc)); + } + }
my $tablespaces = $doc->createElement('tablespaces'); if (defined($self->tablespaces)) { @@ -119,6 +130,7 @@ sub toXml { }
$root->appendChild($cold_files); + $root->appendChild($cold_dirs); $root->appendChild($tablespaces); $root->appendChild($sid); $root->appendChild($start); @@ -171,9 +183,17 @@ sub add_tablespace_entry { sub add_cold_file { my $self = shift;
- my $cold_files = $self->cold_files; - push @$cold_files, @_; - $self->cold_files($cold_files); + foreach my $file (@_) { + if ($file->isa("Dobby::BackupLog::FileEntry")) { + my $cold_files = $self->cold_files; + push @$cold_files, @_; + $self->cold_files($cold_files); + } elsif ($file->isa("Dobby::BackupLog::DirEntry")) { + my $cold_dirs = $self->cold_dirs; + push @$cold_dirs, @_; + $self->cold_dirs($cold_dirs); + } + } }
package Dobby::BackupLog::TablespaceEntry; @@ -302,4 +322,35 @@ sub fromXml { return $self; }
+package Dobby::BackupLog::DirEntry; +use RHN::SimpleStruct; + +our @ISA = qw/RHN::SimpleStruct/; +our @simple_struct_fields = qw/from/; + +#convert the object to XML +sub toXml { + my $self = shift; + my $doc = shift; + + my $entry = $doc->createElement('direntry'); + + my $from = $doc->createElement('from'); + Dobby::BackupLog::addTextValue($from, $doc, $self->from); + + $entry->appendChild($from); + + return $entry; +} + +#fill out the object with the values +#from the XML Dom. +sub fromXml { + my $self = shift; + my $element = shift; + + $self->from(Dobby::BackupLog::getTextValue($element, 'from')); + + return $self; +} 1; diff --git a/web/modules/dobby/Dobby/CLI/BackupCommands.pm b/web/modules/dobby/Dobby/CLI/BackupCommands.pm index 440757d..ceb2a0f 100644 --- a/web/modules/dobby/Dobby/CLI/BackupCommands.pm +++ b/web/modules/dobby/Dobby/CLI/BackupCommands.pm @@ -73,7 +73,11 @@ sub directory_contents { } push @files, map {[$_, cut_dir($_, $cut_off_dir)]} grep { -f $_ } map { File::Spec->catfile($dir, $_) } @dir_content;
- return @files; + if (@files) { + return @files; + } else { #directory is empty, return directory itself + return ([$dir, $cut_off_dir]) if ($dir ne $cut_off_dir); + } }
sub command_backup { @@ -111,6 +115,7 @@ sub command_backup { }
for my $ret (@files) { + next unless $ret; my ($file, $rel_dir) = @{$ret}; my $file_entry = Dobby::Files->backup_file($rel_dir, $file, $backup_dir); $log->add_cold_file($file_entry); @@ -271,12 +276,20 @@ sub command_restore { # it, so the contents are correct. print "Removing unnecessary files... "; for my $ret (@existing_files) { + next unless $ret; my ($file, $rel_dir) = @{$ret}; next if exists $seen_files{+$file};
unlink $file or warn "Error unlinking $file: $!"; } + print "done.\n";
+ print "Restoring empty directories... "; + for my $dir_entry (@{$log->cold_dirs}) { + if (my @dirs = File::Path::mkpath($dir_entry->from, 0, 0700)) { + chown $uid, $gid, @dirs; + } + } print "done.\n";
print "Restoration complete, you may now start the database.\n"; diff --git a/web/modules/dobby/Dobby/Files.pm b/web/modules/dobby/Dobby/Files.pm index df548d8..10afd37 100644 --- a/web/modules/dobby/Dobby/Files.pm +++ b/web/modules/dobby/Dobby/Files.pm @@ -100,27 +100,33 @@ sub gunzip_copy { sub backup_file { my ($class, $rel_dir, $file, $backup_dir) = @_;
- my $real_dest_dir = File::Spec->catdir($backup_dir, $rel_dir); - File::Path::mkpath($real_dest_dir) or (-d $real_dest_dir) or die ("Error: could not create directory $real_dest_dir\n"); - my $dest = sprintf("%s/%s.gz", $real_dest_dir, basename($file)); - $dest =~ s(//+)(/)g; - my $then = time; - - my $file_entry = new Dobby::BackupLog::FileEntry; - $file_entry->start(time); - - print " $file -> $dest ... "; - my $hexdigest = Dobby::Files->gzip_copy($file, $dest); - print "done.\n"; - - $file_entry->original_size(-s $file); - $file_entry->compressed_size(-s $dest); - $file_entry->from($file); - $file_entry->to($dest); - $file_entry->finish(time); - $file_entry->digest($hexdigest); - - return $file_entry; + if (-d $file) { #empty directory + my $dir_entry = new Dobby::BackupLog::DirEntry; + $dir_entry->from($file); + print " Empty directory $file\n"; + return $dir_entry; + } else { + my $file_entry = new Dobby::BackupLog::FileEntry; + my $real_dest_dir = File::Spec->catdir($backup_dir, $rel_dir); + File::Path::mkpath($real_dest_dir) or (-d $real_dest_dir) or die ("Error: could not create directory $real_dest_dir\n"); + my $dest = sprintf("%s/%s.gz", $real_dest_dir, basename($file)); + $dest =~ s(//+)(/)g; + my $then = time; + + $file_entry->start(time); + + print " $file -> $dest ... "; + my $hexdigest = Dobby::Files->gzip_copy($file, $dest); + print "done.\n"; + + $file_entry->original_size(-s $file); + $file_entry->compressed_size(-s $dest); + $file_entry->from($file); + $file_entry->to($dest); + $file_entry->finish(time); + $file_entry->digest($hexdigest); + return $file_entry; + } }
1;
commit 03fcb2f7ba4c0c7f14266663fab3a3e6219c6706 Author: Miroslav Suchý msuchy@redhat.com Date: Mon Oct 22 15:58:56 2012 +0200
correctly set ownership of restored files
diff --git a/web/modules/dobby/Dobby/CLI/BackupCommands.pm b/web/modules/dobby/Dobby/CLI/BackupCommands.pm index 03eb937..440757d 100644 --- a/web/modules/dobby/Dobby/CLI/BackupCommands.pm +++ b/web/modules/dobby/Dobby/CLI/BackupCommands.pm @@ -130,6 +130,7 @@ sub command_restore { my $restore_dir = shift;
my $backend = PXT::Config->get('db_backend'); + my $cfg = new PXT::Config("dobby"); $cli->usage("BACKUP_DIR") unless $restore_dir and -d $restore_dir; my $restore_log = File::Spec->catfile($restore_dir, "backup-log.dat"); $cli->fatal("Error: restoration failed, unable to locate $restore_log") unless -r $restore_log; @@ -212,11 +213,10 @@ sub command_restore {
printf " -> %s...", $tmpdst; if (not $missing) { - $digest = eval { Dobby::Files->gunzip_copy($src, $tmpdst) }; + $digest = eval { Dobby::Files->gunzip_copy($src, $tmpdst, $uid, $gid) }; if (not defined $digest and $@) { $err_msg = $@; } - chown $uid, $gid, $src; }
$seen_files{+$dst} = 1; diff --git a/web/modules/dobby/Dobby/Files.pm b/web/modules/dobby/Dobby/Files.pm index 62e15fa..df548d8 100644 --- a/web/modules/dobby/Dobby/Files.pm +++ b/web/modules/dobby/Dobby/Files.pm @@ -17,7 +17,7 @@ use strict; package Dobby::Files; use Digest::MD5; use Compress::Zlib; -use File::Basename qw/basename/; +use File::Basename qw/basename dirname/; use File::Spec; use File::Path;
@@ -50,13 +50,20 @@ sub gzip_copy { # integrity of the archive)
sub gunzip_copy { - my $class = shift; - my $src = shift; - my $dst = shift; + my ($class, $src, $dst, $uid, $gid) = @_; + if (defined($uid) or defined($gid)) { + # if not defined set it to -1 i.e. no change + $uid = -1 if not defined $uid; + $gid = -1 if not defined $gid; + }
my $write; local * OUT; if ($dst) { + my $dst_directory = dirname($dst); + if (my @dirs = File::Path::mkpath($dst_directory, 0, 0700)) { + chown $uid, $gid, @dirs; + } open OUT, '>', $dst or die "open $dst: $!\n"; $write = 1 } @@ -84,6 +91,8 @@ sub gunzip_copy {
$gz->gzclose; close OUT if $write; + chown $uid, $gid, $dst; + chmod 0640, $dst;
return $ctx->hexdigest; }
commit 6d136b39293bea0be6e0c22f41ba73c8df9cdff4 Author: Miroslav Suchý msuchy@redhat.com Date: Mon Oct 22 15:58:51 2012 +0200
set ownership of restored files under PG
diff --git a/web/modules/dobby/Dobby/CLI/BackupCommands.pm b/web/modules/dobby/Dobby/CLI/BackupCommands.pm index 076242d..03eb937 100644 --- a/web/modules/dobby/Dobby/CLI/BackupCommands.pm +++ b/web/modules/dobby/Dobby/CLI/BackupCommands.pm @@ -129,6 +129,7 @@ sub command_restore { my $command = shift; my $restore_dir = shift;
+ my $backend = PXT::Config->get('db_backend'); $cli->usage("BACKUP_DIR") unless $restore_dir and -d $restore_dir; my $restore_log = File::Spec->catfile($restore_dir, "backup-log.dat"); $cli->fatal("Error: restoration failed, unable to locate $restore_log") unless -r $restore_log; @@ -180,6 +181,8 @@ sub command_restore { return 1; }
+ my $intended_username = $cfg->get("${backend}_user"); + my ($username, undef, $uid, $gid) = getpwnam($intended_username); for my $file_entry (@{$log->cold_files}) { # to and from reverse since their names come from the backup # script itself. @@ -213,6 +216,7 @@ sub command_restore { if (not defined $digest and $@) { $err_msg = $@; } + chown $uid, $gid, $src; }
$seen_files{+$dst} = 1; @@ -258,6 +262,7 @@ sub command_restore { for my $entry (@rename_queue) { rename $entry->[0] => $entry->[1] or warn "Rename $entry->[0] => $entry->[1] error: $!"; system("/sbin/restorecon", $entry->[1]); + } print "done.\n";
commit f03c5a7bd6da2977b25aafa5779a1134e3237564 Author: Miroslav Suchý msuchy@redhat.com Date: Mon Oct 22 15:57:50 2012 +0200
restore selinux context after restore
diff --git a/web/modules/dobby/Dobby/CLI/BackupCommands.pm b/web/modules/dobby/Dobby/CLI/BackupCommands.pm index b62e0d6..076242d 100644 --- a/web/modules/dobby/Dobby/CLI/BackupCommands.pm +++ b/web/modules/dobby/Dobby/CLI/BackupCommands.pm @@ -257,6 +257,7 @@ sub command_restore { print "Extraction and verification complete, renaming files... "; for my $entry (@rename_queue) { rename $entry->[0] => $entry->[1] or warn "Rename $entry->[0] => $entry->[1] error: $!"; + system("/sbin/restorecon", $entry->[1]); } print "done.\n";
commit 0ce4f30d21c2dacf8d27e252e4daddba69ec8435 Author: Miroslav Suchý msuchy@redhat.com Date: Mon Oct 22 15:57:02 2012 +0200
implement "db-control restore" on PG
diff --git a/web/modules/dobby/Dobby/CLI/BackupCommands.pm b/web/modules/dobby/Dobby/CLI/BackupCommands.pm index 5af2f77..b62e0d6 100644 --- a/web/modules/dobby/Dobby/CLI/BackupCommands.pm +++ b/web/modules/dobby/Dobby/CLI/BackupCommands.pm @@ -61,6 +61,7 @@ sub cut_dir {
sub directory_contents { my ($cli, $dir, $cut_off_dir) = @_; + $cut_off_dir = $dir if not defined $cut_off_dir;
my @files; opendir DIR, $dir or $cli->fatal("opendir $dir: $!"); @@ -160,7 +161,7 @@ sub command_restore { my @existing_files; if ($command eq 'restore') { push @existing_files, directory_contents($cli, $d->data_dir); - push @existing_files, directory_contents($cli, $d->archive_log_dir); + push @existing_files, directory_contents($cli, $d->archive_log_dir) if $d->archive_log_dir; }
my $df = df($d->data_dir, "1024"); @@ -214,7 +215,7 @@ sub command_restore { } }
- $seen_files{+basename($dst)} = 1; + $seen_files{+$dst} = 1; push @rename_queue, [ $tmpdst, $dst ]; } elsif ($command eq 'examine') { @@ -263,8 +264,9 @@ sub command_restore { # in the backup set. if we've seen it before, then we overwrote # it, so the contents are correct. print "Removing unnecessary files... "; - for my $file (@existing_files) { - next if exists $seen_files{+basename($file)}; + for my $ret (@existing_files) { + my ($file, $rel_dir) = @{$ret}; + next if exists $seen_files{+$file};
unlink $file or warn "Error unlinking $file: $!"; }
spacewalk-commits@lists.fedorahosted.org