1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Much improved param protocol.

This commit is contained in:
David Steele 2014-06-07 15:01:29 -04:00
parent e07a6b4e3f
commit e60e2b22ed
3 changed files with 127 additions and 35 deletions

View File

@ -74,22 +74,34 @@ my $oRemote = pg_backrest_remote->new();
# Write the greeting so remote process knows who we are
$oRemote->greeting_write();
# Get the first command
my ($strCommand, $strOptions) = $oRemote->command_read();
# Command string
my $strCommand = '';
# Loop until the exit command is received
while ($strCommand ne 'exit')
{
my %oParamHash;
$strCommand = $oRemote->command_read(\%oParamHash);
eval
{
# File->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
{
confess "invalid command: ${strCommand}";
if ($strCommand ne 'noop')
{
confess "invalid command: ${strCommand}";
}
}
};
@ -97,9 +109,6 @@ while ($strCommand ne 'exit')
{
$oRemote->error_write($@);
}
# Get the next command
($strCommand, $strOptions) = $oRemote->command_read();
}
# # Get the operation

View File

@ -1129,21 +1129,25 @@ sub exists
# Set error prefix, remote, and path
my $bExists = true;
my $bRemote = $self->is_remote($strPathType);
my $strPathOp = $self->path_get($strPathType, $strPath);
my $strErrorPrefix = "File->exists";
my $strTrace = "${strPathType}:${strPathOp}";
# Run remotely
if ($bRemote)
if ($self->is_remote($strPathType))
{
my $strCommandOptions = "${strPathOp}";
$strTrace = "${strErrorPrefix}: remote ($strCommandOptions): " . $strTrace;
# Build param hash
my %oParamHash;
$oParamHash{path} = ${strPathOp};
# Build trace string
$strTrace = "${strErrorPrefix}: remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . "): " . $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
else

View File

@ -64,7 +64,7 @@ sub BUILD
# $strOptionSSHCompression = "Compression=yes";
# }
&log(TRACE, "connecting to remote ssh host " . $self->{strHost});
# &log(TRACE, "connecting to remote ssh host " . $self->{strHost});
# Make SSH connection
$self->{oSSH} = Net::OpenSSH->new($self->{strHost}, timeout => 300, user => $self->{strUser},
@ -74,6 +74,8 @@ sub BUILD
# Execute remote command
($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;
# 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");
}
@ -182,7 +184,7 @@ sub output_read
{
my $self = shift;
&log(TRACE, "Remote->output_read");
# &log(TRACE, "Remote->output_read");
my $strLine;
my $strOutput;
@ -205,7 +207,7 @@ sub output_read
last;
}
$strOutput .= trim(substr($strLine, 1));
$strOutput .= (defined($strOutput) ? "\n" : "") . trim(substr($strLine, 1));
}
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
####################################################################################################################################
sub command_read
{
my $self = shift;
my $oParamHashRef = shift;
my $strOut = readline(*STDIN);
my $iPos = index($strOut, ':');
# &log(TRACE, "Remote->command_read");
my $strLine;
my $strCommand;
my $strOptions;
# If no colon then there are no options
if ($iPos == -1)
while ($strLine = readline(*STDIN))
{
$strCommand = lc(trim($strOut));
}
# Else parse options
else
{
$strCommand = lc(substr($strOut, 0, $iPos));
$strOptions = trim(substr($strOut, $iPos + 1));
$strLine = trim($strLine);
if (!defined($strCommand))
{
if ($strLine =~ /:$/)
{
$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 $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";
}