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:
parent
79f85fe6c4
commit
d568b6525b
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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}" : ""));
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user