1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-06-23 00:07:44 +02:00

copy() works with remote in either direction.

This commit is contained in:
David Steele
2014-06-14 20:47:32 -04:00
parent 79f85fe6c4
commit d568b6525b
4 changed files with 139 additions and 114 deletions

View File

@ -103,6 +103,16 @@ while ($strCommand ne OP_EXIT)
$oFile->copy(PIPE_STDIN, undef, PATH_ABSOLUTE, $oParamHash{destination_file}); $oFile->copy(PIPE_STDIN, undef, PATH_ABSOLUTE, $oParamHash{destination_file});
$oRemote->output_write(); $oRemote->output_write();
} }
elsif ($strCommand eq OP_FILE_COPY_OUT)
{
if (!defined($oParamHash{source_file}))
{
confess "source_file must be defined";
}
$oFile->copy(PATH_ABSOLUTE, $oParamHash{source_file}, PIPE_STDOUT, undef);
$oRemote->output_write();
}
else else
{ {
if ($strCommand ne OP_NOOP) if ($strCommand ne OP_NOOP)

View File

@ -119,16 +119,16 @@ use constant
#################################################################################################################################### ####################################################################################################################################
use constant use constant
{ {
OP_FILE_LIST => "list", OP_FILE_LIST => "File->list",
OP_FILE_EXISTS => "File->exists", OP_FILE_EXISTS => "File->exists",
OP_FILE_HASH => "hash", OP_FILE_HASH => "File->hash",
OP_FILE_REMOVE => "remove", OP_FILE_REMOVE => "File->remove",
OP_FILE_MANIFEST => "manifest", OP_FILE_MANIFEST => "File->manifest",
OP_FILE_COMPRESS => "compress", OP_FILE_COMPRESS => "File->compress",
OP_FILE_MOVE => "move", OP_FILE_MOVE => "File->move",
OP_FILE_COPY_OUT => "copy_out", OP_FILE_COPY_OUT => "File->copy_out",
OP_FILE_COPY_IN => "File->copy_in", OP_FILE_COPY_IN => "File->copy_in",
OP_FILE_PATH_CREATE => "path_create" OP_FILE_PATH_CREATE => "File->path_create"
}; };
#################################################################################################################################### ####################################################################################################################################
@ -599,105 +599,105 @@ sub move
# #
# Copies data from a file handle into a string. # Copies data from a file handle into a string.
#################################################################################################################################### ####################################################################################################################################
sub pipe_to_string # sub pipe_to_string
{ # {
my $self = shift; # my $self = shift;
my $hOut = shift; # my $hOut = shift;
#
my $strBuffer; # my $strBuffer;
my $hString = IO::String->new($strBuffer); # my $hString = IO::String->new($strBuffer);
$self->pipe($hOut, $hString); # $self->pipe($hOut, $hString);
#
return $strBuffer; # return $strBuffer;
} # }
#################################################################################################################################### ####################################################################################################################################
# PIPE Function # PIPE Function
# #
# Copies data from one file handle to another, optionally compressing or decompressing the data in stream. # Copies data from one file handle to another, optionally compressing or decompressing the data in stream.
#################################################################################################################################### ####################################################################################################################################
sub pipe # sub pipe
{ # {
my $self = shift; # my $self = shift;
my $hIn = shift; # my $hIn = shift;
my $hOut = shift; # my $hOut = shift;
my $bCompress = shift; # my $bCompress = shift;
my $bUncompress = shift; # my $bUncompress = shift;
#
# If compression is requested and the file is not already compressed # # If compression is requested and the file is not already compressed
if (defined($bCompress) && $bCompress) # if (defined($bCompress) && $bCompress)
{ # {
if (!gzip($hIn => $hOut)) # if (!gzip($hIn => $hOut))
{ # {
confess $GzipError; # confess $GzipError;
} # }
} # }
# If no compression is requested and the file is already compressed # # If no compression is requested and the file is already compressed
elsif (defined($bUncompress) && $bUncompress) # elsif (defined($bUncompress) && $bUncompress)
{ # {
if (!gunzip($hIn => $hOut)) # if (!gunzip($hIn => $hOut))
{ # {
confess $GunzipError; # confess $GunzipError;
} # }
} # }
# Else it's a straight copy # # Else it's a straight copy
else # else
{ # {
my $strBuffer; # my $strBuffer;
my $iResultRead; # my $iResultRead;
my $iResultWrite; # my $iResultWrite;
#
# Read from the input handle # # Read from the input handle
while (($iResultRead = sysread($hIn, $strBuffer, BLOCK_SIZE)) != 0) # while (($iResultRead = sysread($hIn, $strBuffer, BLOCK_SIZE)) != 0)
{ # {
if (!defined($iResultRead)) # if (!defined($iResultRead))
{ # {
confess $!; # confess $!;
last; # last;
} # }
else # else
{ # {
# Write to the output handle # # Write to the output handle
$iResultWrite = syswrite($hOut, $strBuffer, $iResultRead); # $iResultWrite = syswrite($hOut, $strBuffer, $iResultRead);
#
if (!defined($iResultWrite) || $iResultWrite != $iResultRead) # if (!defined($iResultWrite) || $iResultWrite != $iResultRead)
{ # {
confess $!; # confess $!;
last; # last;
} # }
} # }
} # }
} # }
} # }
#################################################################################################################################### ####################################################################################################################################
# WAIT_PID # WAIT_PID
#################################################################################################################################### ####################################################################################################################################
sub wait_pid # sub wait_pid
{ # {
my $self = shift; # my $self = shift;
my $pId = shift; # my $pId = shift;
my $strCommand = shift; # my $strCommand = shift;
my $hIn = shift; # my $hIn = shift;
my $hOut = shift; # my $hOut = shift;
my $hErr = shift; # my $hErr = shift;
#
# Close hIn # # Close hIn
close($hIn); # close($hIn);
#
# Read STDERR into a string # # Read STDERR into a string
my $strError = defined($hErr) ? $self->pipe_to_string($hErr) : "[unknown]"; # my $strError = defined($hErr) ? $self->pipe_to_string($hErr) : "[unknown]";
#
# Wait for the process to finish and report any errors # # Wait for the process to finish and report any errors
waitpid($pId, 0); # waitpid($pId, 0);
my $iExitStatus = ${^CHILD_ERROR_NATIVE} >> 8; # my $iExitStatus = ${^CHILD_ERROR_NATIVE} >> 8;
#
if ($iExitStatus != 0) # if ($iExitStatus != 0)
{ # {
confess &log(ERROR, "command '${strCommand}' returned " . $iExitStatus . ": " . # confess &log(ERROR, "command '${strCommand}' returned " . $iExitStatus . ": " .
(defined($strError) ? $strError : "[unknown]")); # (defined($strError) ? $strError : "[unknown]"));
} # }
} # }
#################################################################################################################################### ####################################################################################################################################
# COPY # COPY
@ -783,23 +783,38 @@ sub copy
# If source is remote and destination is local # If source is remote and destination is local
if ($bSourceRemote && !$bDestinationRemote) if ($bSourceRemote && !$bDestinationRemote)
{ {
$strRemote = 'in';
$hOut = $hDestinationFile; $hOut = $hDestinationFile;
if ($strSourcePathType eq PIPE_STDIN) if ($strSourcePathType eq PIPE_STDIN)
{ {
$strRemote = 'in';
$hIn = *STDIN; $hIn = *STDIN;
} }
else
{
$strRemote = 'in';
$strOperation = OP_FILE_COPY_OUT;
$oParamHash{source_file} = ${strSourceOp};
$hIn = $self->{oRemote}->{hOut};
}
} }
# Else if source is local and destination is remote # Else if source is local and destination is remote
elsif (!$bSourceRemote && $bDestinationRemote) elsif (!$bSourceRemote && $bDestinationRemote)
{ {
$strRemote = 'out';
$hIn = $hSourceFile; $hIn = $hSourceFile;
if ($strDestinationPathType eq PIPE_STDOUT)
{
$strRemote = 'out';
$hOut = *STDOUT;
}
else
{
$strRemote = 'out';
$strOperation = OP_FILE_COPY_IN; $strOperation = OP_FILE_COPY_IN;
$oParamHash{destination_file} = ${strDestinationOp}; $oParamHash{destination_file} = ${strDestinationOp};
$hOut = $self->{oRemote}->{hIn}; $hOut = $self->{oRemote}->{hIn};
}
# Build debug string # Build debug string
# $strDebug = "${strOperation}: remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . "): " . $strDebug; # $strDebug = "${strOperation}: remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . "): " . $strDebug;

View File

@ -386,7 +386,7 @@ sub output_read
# Capture any errors # Capture any errors
if ($bError) if ($bError)
{ {
print "error: " . $strOutput->message(); # print "error: " . $strOutput->message();
confess &log(ERROR, (defined($strErrorPrefix) ? "${strErrorPrefix}" : "") . confess &log(ERROR, (defined($strErrorPrefix) ? "${strErrorPrefix}" : "") .
(defined($strOutput) ? ": ${strOutput}" : "")); (defined($strOutput) ? ": ${strOutput}" : ""));
@ -407,12 +407,8 @@ sub output_read
# } # }
# } # }
print "output read wait\n";
while ($strLine = $self->read_line($self->{hOut}, false)) while ($strLine = $self->read_line($self->{hOut}, false))
{ {
print "read a line ${strLine}\n";
if ($strLine =~ /^ERROR.*/) if ($strLine =~ /^ERROR.*/)
{ {
$bError = true; $bError = true;
@ -424,15 +420,12 @@ sub output_read
if ($strLine =~ /^OK$/) if ($strLine =~ /^OK$/)
{ {
print "found OK\n";
last; last;
} }
$strOutput .= (defined($strOutput) ? "\n" : "") . substr($strLine, 1); $strOutput .= (defined($strOutput) ? "\n" : "") . substr($strLine, 1);
} }
print "and here\n";
# Capture any errors # Capture any errors
if ($bError) if ($bError)
{ {
@ -453,8 +446,6 @@ sub output_read
# Capture any errors # Capture any errors
if ($bError) if ($bError)
{ {
print "error: " . $strOutput->message();
confess &log(ERROR, (defined($strErrorPrefix) ? "${strErrorPrefix}" : "") . confess &log(ERROR, (defined($strErrorPrefix) ? "${strErrorPrefix}" : "") .
(defined($strOutput) ? ": ${strOutput}" : "")); (defined($strOutput) ? ": ${strOutput}" : ""));
} }

View File

@ -790,10 +790,10 @@ sub BackRestFileTest
{ {
$iRun = 0; $iRun = 0;
for (my $bBackupRemote = 0; $bBackupRemote <= 0; $bBackupRemote++) for (my $bBackupRemote = 0; $bBackupRemote <= 1; $bBackupRemote++)
{ {
# Loop through source compression # Loop through source compression
for (my $bDbRemote = 1; $bDbRemote <= 1; $bDbRemote++) for (my $bDbRemote = 0; $bDbRemote <= 1; $bDbRemote++)
{ {
# Backup and db cannot both be remote # Backup and db cannot both be remote
if ($bBackupRemote && $bDbRemote) if ($bBackupRemote && $bDbRemote)
@ -852,6 +852,8 @@ sub BackRestFileTest
system("echo 'TESTDATA' > ${strSourceFile}"); system("echo 'TESTDATA' > ${strSourceFile}");
} }
my $strSourceHash = $oFile->hash(PATH_ABSOLUTE, $strSourceFile);
# Run file copy in an eval block because some errors are expected # Run file copy in an eval block because some errors are expected
my $bReturn; my $bReturn;
@ -937,6 +939,13 @@ sub BackRestFileTest
{ {
confess "could not find destination file ${strDestinationFile}"; confess "could not find destination file ${strDestinationFile}";
} }
my $strDestinationHash = $oFile->hash(PATH_ABSOLUTE, $strDestinationFile);
if ($strSourceHash ne $strDestinationHash)
{
confess "source ${strSourceHash} and destination ${strDestinationHash} file hashes do not match";
}
} }
} }
} }