mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Much improved param protocol.
This commit is contained in:
parent
e07a6b4e3f
commit
e60e2b22ed
@ -74,22 +74,34 @@ my $oRemote = pg_backrest_remote->new();
|
|||||||
# Write the greeting so remote process knows who we are
|
# Write the greeting so remote process knows who we are
|
||||||
$oRemote->greeting_write();
|
$oRemote->greeting_write();
|
||||||
|
|
||||||
# Get the first command
|
# Command string
|
||||||
my ($strCommand, $strOptions) = $oRemote->command_read();
|
my $strCommand = '';
|
||||||
|
|
||||||
# Loop until the exit command is received
|
# Loop until the exit command is received
|
||||||
while ($strCommand ne 'exit')
|
while ($strCommand ne 'exit')
|
||||||
{
|
{
|
||||||
|
my %oParamHash;
|
||||||
|
|
||||||
|
$strCommand = $oRemote->command_read(\%oParamHash);
|
||||||
|
|
||||||
eval
|
eval
|
||||||
{
|
{
|
||||||
# File->exists
|
# File->exists
|
||||||
if ($strCommand eq OP_EXISTS)
|
if ($strCommand eq OP_EXISTS)
|
||||||
{
|
{
|
||||||
$oRemote->output_write($oFile->exists(PATH_ABSOLUTE, $strOptions) ? "Y" : "N");
|
if (!defined($oParamHash{path}))
|
||||||
|
{
|
||||||
|
confess "path must be defined";
|
||||||
|
}
|
||||||
|
|
||||||
|
$oRemote->output_write($oFile->exists(PATH_ABSOLUTE, $oParamHash{path}) ? "Y" : "N");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
confess "invalid command: ${strCommand}";
|
if ($strCommand ne 'noop')
|
||||||
|
{
|
||||||
|
confess "invalid command: ${strCommand}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,9 +109,6 @@ while ($strCommand ne 'exit')
|
|||||||
{
|
{
|
||||||
$oRemote->error_write($@);
|
$oRemote->error_write($@);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the next command
|
|
||||||
($strCommand, $strOptions) = $oRemote->command_read();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# # Get the operation
|
# # Get the operation
|
||||||
|
@ -1129,21 +1129,25 @@ sub exists
|
|||||||
|
|
||||||
# Set error prefix, remote, and path
|
# Set error prefix, remote, and path
|
||||||
my $bExists = true;
|
my $bExists = true;
|
||||||
my $bRemote = $self->is_remote($strPathType);
|
|
||||||
my $strPathOp = $self->path_get($strPathType, $strPath);
|
my $strPathOp = $self->path_get($strPathType, $strPath);
|
||||||
|
|
||||||
my $strErrorPrefix = "File->exists";
|
my $strErrorPrefix = "File->exists";
|
||||||
my $strTrace = "${strPathType}:${strPathOp}";
|
my $strTrace = "${strPathType}:${strPathOp}";
|
||||||
|
|
||||||
# Run remotely
|
# Run remotely
|
||||||
if ($bRemote)
|
if ($self->is_remote($strPathType))
|
||||||
{
|
{
|
||||||
my $strCommandOptions = "${strPathOp}";
|
# Build param hash
|
||||||
$strTrace = "${strErrorPrefix}: remote ($strCommandOptions): " . $strTrace;
|
my %oParamHash;
|
||||||
|
|
||||||
|
$oParamHash{path} = ${strPathOp};
|
||||||
|
|
||||||
|
# Build trace string
|
||||||
|
$strTrace = "${strErrorPrefix}: remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . "): " . $strTrace;
|
||||||
&log(TRACE, $strTrace);
|
&log(TRACE, $strTrace);
|
||||||
|
|
||||||
$bExists = $self->{oRemote}->command_execute("EXISTS", $strCommandOptions, $strTrace) eq "Y";
|
# Execute the command
|
||||||
|
$bExists = $self->{oRemote}->command_execute("exists", \%oParamHash, $strTrace) eq "Y";
|
||||||
}
|
}
|
||||||
# Run locally
|
# Run locally
|
||||||
else
|
else
|
||||||
|
@ -64,7 +64,7 @@ sub BUILD
|
|||||||
# $strOptionSSHCompression = "Compression=yes";
|
# $strOptionSSHCompression = "Compression=yes";
|
||||||
# }
|
# }
|
||||||
|
|
||||||
&log(TRACE, "connecting to remote ssh host " . $self->{strHost});
|
# &log(TRACE, "connecting to remote ssh host " . $self->{strHost});
|
||||||
|
|
||||||
# Make SSH connection
|
# Make SSH connection
|
||||||
$self->{oSSH} = Net::OpenSSH->new($self->{strHost}, timeout => 300, user => $self->{strUser},
|
$self->{oSSH} = Net::OpenSSH->new($self->{strHost}, timeout => 300, user => $self->{strUser},
|
||||||
@ -74,6 +74,8 @@ sub BUILD
|
|||||||
|
|
||||||
# Execute remote command
|
# Execute remote command
|
||||||
($self->{hIn}, $self->{hOut}, $self->{hErr}, $self->{pId}) = $self->{oSSH}->open3($self->{strCommand});
|
($self->{hIn}, $self->{hOut}, $self->{hErr}, $self->{pId}) = $self->{oSSH}->open3($self->{strCommand});
|
||||||
|
|
||||||
|
$self->greeting_read();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ sub greeting_read
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
# Make sure that the remote is running the right version
|
# Make sure that the remote is running the right version
|
||||||
if (trim(readline($self->{hOut})) ne $self->{strGreeting})
|
if (readline($self->{hOut}) ne $self->{strGreeting} . "\n")
|
||||||
{
|
{
|
||||||
confess &log(ERROR, "remote version mismatch");
|
confess &log(ERROR, "remote version mismatch");
|
||||||
}
|
}
|
||||||
@ -182,7 +184,7 @@ sub output_read
|
|||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
&log(TRACE, "Remote->output_read");
|
# &log(TRACE, "Remote->output_read");
|
||||||
|
|
||||||
my $strLine;
|
my $strLine;
|
||||||
my $strOutput;
|
my $strOutput;
|
||||||
@ -205,7 +207,7 @@ sub output_read
|
|||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
$strOutput .= trim(substr($strLine, 1));
|
$strOutput .= (defined($strOutput) ? "\n" : "") . trim(substr($strLine, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($strOutput, $bError, $iErrorCode);
|
return ($strOutput, $bError, $iErrorCode);
|
||||||
@ -227,32 +229,80 @@ sub output_write
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
####################################################################################################################################
|
||||||
|
# COMMAND_PARAM_STRING
|
||||||
|
####################################################################################################################################
|
||||||
|
sub command_param_string
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $oParamHashRef = shift;
|
||||||
|
|
||||||
|
my $strParamList;
|
||||||
|
|
||||||
|
foreach my $strParam (sort(keys $oParamHashRef))
|
||||||
|
{
|
||||||
|
$strParamList .= (defined($strParamList) ? "," : "") . "${strParam}=" .
|
||||||
|
(defined(${$oParamHashRef}{"${strParam}"}) ? ${$oParamHashRef}{"${strParam}"} : "[undef]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $strParamList;
|
||||||
|
}
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# COMMAND_READ
|
# COMMAND_READ
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
sub command_read
|
sub command_read
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
my $oParamHashRef = shift;
|
||||||
|
|
||||||
my $strOut = readline(*STDIN);
|
# &log(TRACE, "Remote->command_read");
|
||||||
my $iPos = index($strOut, ':');
|
|
||||||
|
my $strLine;
|
||||||
my $strCommand;
|
my $strCommand;
|
||||||
my $strOptions;
|
|
||||||
|
while ($strLine = readline(*STDIN))
|
||||||
# If no colon then there are no options
|
|
||||||
if ($iPos == -1)
|
|
||||||
{
|
{
|
||||||
$strCommand = lc(trim($strOut));
|
$strLine = trim($strLine);
|
||||||
}
|
|
||||||
# Else parse options
|
if (!defined($strCommand))
|
||||||
else
|
{
|
||||||
{
|
if ($strLine =~ /:$/)
|
||||||
$strCommand = lc(substr($strOut, 0, $iPos));
|
{
|
||||||
$strOptions = trim(substr($strOut, $iPos + 1));
|
$strCommand = substr($strLine, 0, length($strLine) - 1);
|
||||||
|
# print "command ${strCommand} continues\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$strCommand = $strLine;
|
||||||
|
# print "command ${strCommand}\n";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($strLine eq 'end')
|
||||||
|
{
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $iPos = index($strLine, "=");
|
||||||
|
|
||||||
|
if ($iPos == -1)
|
||||||
|
{
|
||||||
|
confess "param \"${strLine}\" is missing = character";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $strParam = substr($strLine, 0, $iPos);
|
||||||
|
my $strValue = substr($strLine, $iPos + 1);
|
||||||
|
|
||||||
|
${$oParamHashRef}{"${strParam}"} = ${strValue};
|
||||||
|
|
||||||
|
# print "${strParam}=${strValue}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $strCommand, $strOptions;
|
return $strCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
@ -262,11 +312,40 @@ sub command_write
|
|||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $strCommand = shift;
|
my $strCommand = shift;
|
||||||
my $strOptions = shift;
|
my $oParamRef = shift;
|
||||||
|
|
||||||
&log(TRACE, "Remote->command_write: $strCommand" . (defined($strOptions) ? ":$strOptions" : ""));
|
my $strOutput = $strCommand;
|
||||||
|
|
||||||
if (!syswrite($self->{hIn}, "$strCommand" . (defined($strOptions) ? ":${strOptions}" : "") . "\n"))
|
if (defined($oParamRef))
|
||||||
|
{
|
||||||
|
$strOutput = "${strCommand}:\n";
|
||||||
|
|
||||||
|
foreach my $strParam (sort(keys $oParamRef))
|
||||||
|
{
|
||||||
|
if ($strParam =~ /=/)
|
||||||
|
{
|
||||||
|
confess &log(ASSERT, "param \"${strParam}\" cannot contain = character");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $strValue = ${$oParamRef}{"${strParam}"};
|
||||||
|
|
||||||
|
if ($strParam =~ /\n\$/)
|
||||||
|
{
|
||||||
|
confess &log(ASSERT, "param \"${strParam}\" value cannot end with LF");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined(${strValue}))
|
||||||
|
{
|
||||||
|
$strOutput .= "${strParam}=${strValue}\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$strOutput .= "end";
|
||||||
|
}
|
||||||
|
|
||||||
|
# &log(TRACE, "Remote->command_write:\n" . trim($strOutput));
|
||||||
|
|
||||||
|
if (!syswrite($self->{hIn}, "${strOutput}\n"))
|
||||||
{
|
{
|
||||||
confess "unable to write command";
|
confess "unable to write command";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user