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