1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-30 05:39:12 +02:00

First passing test with new protocol.

This commit is contained in:
David Steele 2014-06-07 11:51:27 -04:00
parent ae130229ef
commit 1bc80c50ed
5 changed files with 263 additions and 24 deletions

View File

@ -65,9 +65,42 @@ use constant
# Turn off logging # Turn off logging
log_level_set(OFF, OFF); log_level_set(OFF, OFF);
# Creat the file object
my $oFile = pg_backrest_file->new();
# Create the remote object for writing to stdout
my $oRemote = pg_backrest_remote->new(); my $oRemote = pg_backrest_remote->new();
$oRemote->welcome_send(); # Write the greeting so remote process knows who we are
$oRemote->greeting_write();
# Get the first command
my ($strCommand, $strOptions) = $oRemote->command_read();
# Loop until the exit command is received
while ($strCommand ne 'exit')
{
eval
{
# File->exists
if ($strCommand eq OP_EXISTS)
{
$oRemote->output_write($oFile->exists(PATH_ABSOLUTE, $strOptions) ? "Y" : "N");
}
else
{
confess "invalid command: ${strCommand}";
}
};
if ($@)
{
$oRemote->error_write($@);
}
# Get the next command
($strCommand, $strOptions) = $oRemote->command_read();
}
# # Get the operation # # Get the operation
# my $strOperation = $ARGV[0]; # my $strOperation = $ARGV[0];

38
lib/BackRest/Exception.pm Normal file
View File

@ -0,0 +1,38 @@
####################################################################################################################################
# EXCEPTION MODULE
####################################################################################################################################
package BackRest::Exception;
use threads;
use strict;
use warnings;
use Carp;
use Moose;
# Module variables
has iCode => (is => 'bare'); # Exception code
has strMessage => (is => 'bare'); # Exception message
####################################################################################################################################
# CODE
####################################################################################################################################
sub code
{
my $self = shift;
return $self->{iCode};
}
####################################################################################################################################
# MESSAGE
####################################################################################################################################
sub message
{
my $self = shift;
return $self->{strMessage};
}
no Moose;
__PACKAGE__->meta->make_immutable;

View File

@ -21,6 +21,8 @@ use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
use IO::String; use IO::String;
use lib dirname($0); use lib dirname($0);
use lib dirname($0) . "/../lib";
use BackRest::Exception;
use pg_backrest_utility; use pg_backrest_utility;
use pg_backrest_remote; use pg_backrest_remote;
@ -1126,7 +1128,7 @@ sub exists
my $strPath = shift; my $strPath = shift;
# Set error prefix, remote, and path # Set error prefix, remote, and path
my $bExists = false; my $bExists = true;
my $strErrorPrefix = "File->exists"; my $strErrorPrefix = "File->exists";
my $bRemote = $self->is_remote($strPathType); my $bRemote = $self->is_remote($strPathType);
my $strPathOp = $self->path_get($strPathType, $strPath); my $strPathOp = $self->path_get($strPathType, $strPath);
@ -1136,19 +1138,17 @@ sub exists
# Run remotely # Run remotely
if ($bRemote) if ($bRemote)
{ {
my $strCommand = $self->{strCommand} . " exists ${strPathOp}"; my $strCommand = "EXISTS:${strPathOp}";
# syswrite(self->{hIn}, ) $self->{oRemote}->command_write($strCommand);
# Build the command
# Run it remotely # Run it remotely
my $oSSH = $self->remote_get($strPathType); my ($strOutput, $bError, $iErrorCode) = $self->{oRemote}->output_read();
my $strOutput = $oSSH->capture($strCommand);
# Capture any errors # Capture any errors
if ($oSSH->error) if ($bError)
{ {
confess &log(ERROR, "${strErrorPrefix} remote (${strCommand}): " . (defined($strOutput) ? $strOutput : $oSSH->error)); confess &log(ERROR, "${strErrorPrefix} remote (${strCommand}): " . $strOutput);
} }
$bExists = $strOutput eq "Y"; $bExists = $strOutput eq "Y";
@ -1156,9 +1156,19 @@ sub exists
# Run locally # Run locally
else else
{ {
if (-e $strPathOp) # Stat the file/path to determine if it exists
my $oStat = lstat($strPathOp);
# Evaluate error
if (!defined($oStat))
{ {
$bExists = true; # If the error is not entry missing, then throw error
if (!$!{ENOENT})
{
confess &log(ERROR, $!, COMMAND_ERR_FILE_READ);
}
$bExists = false;
} }
} }

View File

@ -13,10 +13,12 @@ use Net::OpenSSH;
use File::Basename; use File::Basename;
use lib dirname($0); use lib dirname($0);
use lib dirname($0) . "/../lib";
use BackRest::Exception;
use pg_backrest_utility; use pg_backrest_utility;
# Protocol strings # Protocol strings
has strGreeting => (is => 'ro', default => 'pg_backrest_remote 0.20'); has strGreeting => (is => 'ro', default => 'PG_BACKREST_REMOTE 0.20');
# Command strings # Command strings
has strCommand => (is => 'bare'); has strCommand => (is => 'bare');
@ -96,7 +98,6 @@ sub clone
sub greeting_read sub greeting_read
{ {
my $self = shift; my $self = shift;
my $hOut = 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 (trim(readline($self->{hOut})) ne $self->{strGreeting})
@ -111,7 +112,6 @@ sub greeting_read
sub greeting_write sub greeting_write
{ {
my $self = shift; my $self = shift;
my $hOut = shift;
if (!syswrite(*STDOUT, "$self->{strGreeting}\n")) if (!syswrite(*STDOUT, "$self->{strGreeting}\n"))
{ {
@ -119,5 +119,151 @@ sub greeting_write
} }
} }
####################################################################################################################################
# STRING_WRITE
####################################################################################################################################
sub string_write
{
my $self = shift;
my $hOut = shift;
my $strBuffer = shift;
$strBuffer =~ s/\n/\n\./g;
if (!syswrite($hOut, "." . $strBuffer))
{
confess "unable to write string";
}
}
####################################################################################################################################
# ERROR_WRITE
####################################################################################################################################
sub error_write
{
my $self = shift;
my $oMessage = shift;
my $iCode;
my $strMessage;
if (blessed($oMessage))
{
if ($oMessage->isa("BackRest::Exception"))
{
$iCode = $oMessage->code();
$strMessage = $oMessage->message();
}
else
{
$strMessage = 'unknown error object';
}
}
else
{
$strMessage = $oMessage;
}
if (defined($strMessage))
{
$self->string_write(*STDOUT, trim($strMessage));
}
if (!syswrite(*STDOUT, "\nERROR" . (defined($iCode) ? " $iCode" : "") . "\n"))
{
confess "unable to write error";
}
}
####################################################################################################################################
# OUTPUT_READ
####################################################################################################################################
sub output_read
{
my $self = shift;
my $strLine;
my $strOutput;
my $bError = false;
my $iErrorCode;
while ($strLine = readline($self->{hOut}))
{
if ($strLine =~ /^ERROR.*/)
{
$bError = true;
last;
}
if (trim($strLine) =~ /^OK$/)
{
last;
}
$strOutput .= trim(substr($strLine, 1));
}
return ($strOutput, $bError, $iErrorCode);
}
####################################################################################################################################
# OUTPUT_WRITE
####################################################################################################################################
sub output_write
{
my $self = shift;
my $strOutput = shift;
$self->string_write(*STDOUT, $strOutput);
if (!syswrite(*STDOUT, "\nOK\n"))
{
confess "unable to write output";
}
}
####################################################################################################################################
# COMMAND_READ
####################################################################################################################################
sub command_read
{
my $self = shift;
my $strOut = readline(*STDIN);
my $iPos = index($strOut, ':');
my $strCommand;
my $strOptions;
# If no colon then there are no options
if ($iPos == -1)
{
$strCommand = lc(trim($strOut));
}
# Else parse options
else
{
$strCommand = lc(substr($strOut, 0, $iPos));
$strOptions = trim(substr($strOut, $iPos + 1));
}
return $strCommand, $strOptions;
}
####################################################################################################################################
# COMMAND_WRITE
####################################################################################################################################
sub command_write
{
my $self = shift;
my $strCommand = shift;
my $strOptions = shift;
if (!syswrite($self->{hIn}, "$strCommand" . (defined($strOptions) ? ":${strOptions}" : "") . "\n"))
{
confess "unable to write command";
}
}
no Moose; no Moose;
__PACKAGE__->meta->make_immutable; __PACKAGE__->meta->make_immutable;

View File

@ -11,6 +11,10 @@ use Carp;
use IPC::System::Simple qw(capture); use IPC::System::Simple qw(capture);
use Fcntl qw(:DEFAULT :flock); use Fcntl qw(:DEFAULT :flock);
use File::Path qw(remove_tree); use File::Path qw(remove_tree);
use File::Basename;
use lib dirname($0) . "/../lib";
use BackRest::Exception;
use Exporter qw(import); use Exporter qw(import);
@ -319,6 +323,9 @@ sub log
{ {
my $strLevel = shift; my $strLevel = shift;
my $strMessage = shift; my $strMessage = shift;
my $iCode = shift;
my $strMessageFormat = $strMessage;
if (!defined($oLogLevelRank{"${strLevel}"}{rank})) if (!defined($oLogLevelRank{"${strLevel}"}{rank}))
{ {
@ -327,37 +334,42 @@ sub log
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
if (!defined($strMessage)) if (!defined($strMessageFormat))
{ {
$strMessage = "(undefined)"; $strMessageFormat = "(undefined)";
} }
if ($strLevel eq "TRACE") if ($strLevel eq "TRACE")
{ {
$strMessage = " " . $strMessage; $strMessageFormat = " " . $strMessageFormat;
} }
elsif ($strLevel eq "DEBUG") elsif ($strLevel eq "DEBUG")
{ {
$strMessage = " " . $strMessage; $strMessageFormat = " " . $strMessageFormat;
} }
$strMessage = sprintf("%4d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec) . $strMessageFormat = sprintf("%4d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec) .
(" " x (7 - length($strLevel))) . "${strLevel} " . (" " x (2 - length(threads->tid()))) . (" " x (7 - length($strLevel))) . "${strLevel} " . (" " x (2 - length(threads->tid()))) .
threads->tid() . ": ${strMessage}\n"; threads->tid() . ": ${strMessageFormat}\n";
if ($oLogLevelRank{"${strLevel}"}{rank} <= $oLogLevelRank{"${strLogLevelConsole}"}{rank}) if ($oLogLevelRank{"${strLevel}"}{rank} <= $oLogLevelRank{"${strLogLevelConsole}"}{rank})
{ {
print $strMessage; print $strMessageFormat;
} }
if ($oLogLevelRank{"${strLevel}"}{rank} <= $oLogLevelRank{"${strLogLevelFile}"}{rank}) if ($oLogLevelRank{"${strLevel}"}{rank} <= $oLogLevelRank{"${strLogLevelFile}"}{rank})
{ {
if (defined($hLogFile)) if (defined($hLogFile))
{ {
print $hLogFile $strMessage; print $hLogFile $strMessageFormat;
} }
} }
if (defined($iCode))
{
return BackRest::Exception->new(iCode => $iCode, strMessage => $strMessage);
}
return $strMessage; return $strMessage;
} }