1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +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});
$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
{
if ($strCommand ne OP_NOOP)

View File

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

View File

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

View File

@ -790,10 +790,10 @@ sub BackRestFileTest
{
$iRun = 0;
for (my $bBackupRemote = 0; $bBackupRemote <= 0; $bBackupRemote++)
for (my $bBackupRemote = 0; $bBackupRemote <= 1; $bBackupRemote++)
{
# 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
if ($bBackupRemote && $bDbRemote)
@ -851,6 +851,8 @@ sub BackRestFileTest
{
system("echo 'TESTDATA' > ${strSourceFile}");
}
my $strSourceHash = $oFile->hash(PATH_ABSOLUTE, $strSourceFile);
# Run file copy in an eval block because some errors are expected
my $bReturn;
@ -937,6 +939,13 @@ sub BackRestFileTest
{
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";
}
}
}
}