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

Working on remote protocol.

This commit is contained in:
David Steele 2014-06-06 21:16:24 -04:00
parent e71a986ef3
commit ae130229ef
6 changed files with 552 additions and 480 deletions

View File

@ -1,363 +0,0 @@
#!/usr/bin/perl
####################################################################################################################################
# pg_backrest_command.pl - Simple Postgres Backup and Restore Command Helper
####################################################################################################################################
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings;
use english;
use File::Basename;
use Getopt::Long;
use Carp;
use lib dirname($0) . '/..';
use pg_backrest_utility;
use pg_backrest_file;
####################################################################################################################################
# Operation constants - basic operations that are allowed in backrest command
####################################################################################################################################
use constant
{
OP_LIST => "list",
OP_EXISTS => "exists",
OP_HASH => "hash",
OP_REMOVE => "remove",
OP_MANIFEST => "manifest",
OP_COMPRESS => "compress",
OP_MOVE => "move",
OP_COPY_OUT => "copy_out",
OP_COPY_IN => "copy_in",
OP_PATH_CREATE => "path_create"
};
####################################################################################################################################
# Command line parameters
####################################################################################################################################
my $bIgnoreMissing = false; # Ignore errors due to missing file
my $bDestinationPathCreate = false; # Create destination path if it does not exist
my $bCompress = false; # Compress output
my $bUncompress = false; # Uncompress output
my $strExpression = undef; # Expression to use for filtering (undef = no filtering)
my $strPermission = undef; # Permission when creating directory or file (undef = default)
my $strSort = undef; # Sort order (undef = forward)
if (!GetOptions ("ignore-missing" => \$bIgnoreMissing,
"dest-path-create" => \$bDestinationPathCreate,
"compress" => \$bCompress,
"uncompress" => \$bUncompress,
"expression=s" => \$strExpression,
"permission=s" => \$strPermission,
"sort=s" => \$strSort))
{
print(STDERR "error in command line arguments");
exit COMMAND_ERR_PARAM;
}
####################################################################################################################################
# START MAIN
####################################################################################################################################
# Turn off logging
log_level_set(OFF, OFF);
# Get the operation
my $strOperation = $ARGV[0];
# Validate the operation
if (!defined($strOperation))
{
print(STDERR "operation is not defined");
exit COMMAND_ERR_PARAM;
}
# Make sure compress and uncompress are not both set
if ($bCompress && $bUncompress)
{
print(STDERR "compress and uncompress options cannot both be set");
exit COMMAND_ERR_PARAM;
}
# Create the file object
my $oFile = pg_backrest_file->new();
####################################################################################################################################
# LIST Command
####################################################################################################################################
if ($strOperation eq OP_LIST)
{
my $strPath = $ARGV[1];
if (!defined($strPath))
{
confess "path must be specified for ${strOperation} operation";
}
my $bFirst = true;
foreach my $strFile ($oFile->list(PATH_ABSOLUTE, $strPath, $strExpression, $strSort))
{
$bFirst ? $bFirst = false : print "\n";
print $strFile;
}
exit 0;
}
####################################################################################################################################
# EXISTS Command
####################################################################################################################################
if ($strOperation eq OP_EXISTS)
{
my $strFile = $ARGV[1];
if (!defined($strFile))
{
confess "filename must be specified for ${strOperation} operation";
}
print $oFile->exists(PATH_ABSOLUTE, $strFile) ? "Y" : "N";
exit 0;
}
####################################################################################################################################
# HASH Command
####################################################################################################################################
if ($strOperation eq OP_HASH)
{
my $strFile = $ARGV[1];
if (!defined($strFile))
{
confess "filename must be specified for ${strOperation} operation";
}
print $oFile->hash(PATH_ABSOLUTE, $strFile);
exit 0;
}
####################################################################################################################################
# REMOVE Command
####################################################################################################################################
if ($strOperation eq OP_REMOVE)
{
my $strFile = $ARGV[1];
if (!defined($strFile))
{
confess "filename must be specified for ${strOperation} operation";
}
print $oFile->remove(PATH_ABSOLUTE, $strFile, undef, $bIgnoreMissing) ? "Y" : "N";
exit 0;
}
####################################################################################################################################
# MANIFEST Command
####################################################################################################################################
if ($strOperation eq OP_MANIFEST)
{
my $strPath = $ARGV[1];
if (!defined($strPath))
{
confess "path must be specified for ${strOperation} operation";
}
my %oManifestHash;
$oFile->manifest(PATH_ABSOLUTE, $strPath, \%oManifestHash);
print "name\ttype\tuser\tgroup\tpermission\tmodification_time\tinode\tsize\tlink_destination";
foreach my $strName (sort(keys $oManifestHash{name}))
{
print "\n${strName}\t" .
$oManifestHash{name}{"${strName}"}{type} . "\t" .
(defined($oManifestHash{name}{"${strName}"}{user}) ? $oManifestHash{name}{"${strName}"}{user} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{group}) ? $oManifestHash{name}{"${strName}"}{group} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{permission}) ? $oManifestHash{name}{"${strName}"}{permission} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{modification_time}) ?
$oManifestHash{name}{"${strName}"}{modification_time} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{inode}) ? $oManifestHash{name}{"${strName}"}{inode} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{size}) ? $oManifestHash{name}{"${strName}"}{size} : "") . "\t" .
(defined($oManifestHash{name}{"${strName}"}{link_destination}) ?
$oManifestHash{name}{"${strName}"}{link_destination} : "");
}
exit 0;
}
####################################################################################################################################
# COMPRESS Command
####################################################################################################################################
if ($strOperation eq OP_COMPRESS)
{
my $strFile = $ARGV[1];
if (!defined($strFile))
{
confess "file must be specified for ${strOperation} operation";
}
$oFile->compress(PATH_ABSOLUTE, $strFile);
exit 0;
}
####################################################################################################################################
# MOVE Command
####################################################################################################################################
if ($strOperation eq OP_MOVE)
{
my $strFileSource = $ARGV[1];
if (!defined($strFileSource))
{
confess "source file source must be specified for ${strOperation} operation";
}
my $strFileDestination = $ARGV[2];
if (!defined($strFileDestination))
{
confess "destination file must be specified for ${strOperation} operation";
}
$oFile->move(PATH_ABSOLUTE, $strFileSource, PATH_ABSOLUTE, $strFileDestination, $bDestinationPathCreate);
exit 0;
}
####################################################################################################################################
# COPY_IN Command
####################################################################################################################################
if ($strOperation eq OP_COPY_IN)
{
my $strFileSource = $ARGV[1];
# Make sure the source file is defined
if (!defined($strFileSource))
{
confess "source file must be specified for ${strOperation} operation";
}
# Variable to hold errors
my $strError;
# Open the source file
my $hIn;
if (!open($hIn, "<", ${strFileSource}))
{
$strError = $!;
unless (-e $strFileSource)
{
print(STDERR "${strFileSource} does not exist");
exit COMMAND_ERR_FILE_MISSING;
}
}
else
{
# Determine if the file is already compressed
my $bAlreadyCompressed = ($strFileSource =~ "^.*\.$oFile->{strCompressExtension}\$");
# Copy the file to STDOUT
eval
{
$oFile->pipe($hIn, *STDOUT, $bCompress && !$bAlreadyCompressed, $bUncompress && $bAlreadyCompressed);
};
$strError = $@;
# Close the input file
close($hIn);
}
if ($strError)
{
print(STDERR "${strFileSource} could not be read: ${strError}");
exit COMMAND_ERR_FILE_READ;
}
exit 0;
}
####################################################################################################################################
# COPY_OUT Command
####################################################################################################################################
if ($strOperation eq OP_COPY_OUT)
{
my $strFileDestination = $ARGV[1];
# Make sure the source file is defined
if (!defined($strFileDestination))
{
confess "destination file must be specified for ${strOperation} operation";
}
# Determine if the file needs compression extension
if ($bCompress && $strFileDestination !~ "^.*\.$oFile->{strCompressExtension}\$")
{
$strFileDestination .= "." . $oFile->{strCompressExtension};
}
# Variable to hold errors
my $strError;
# Open the destination file
my $hOut;
if (!open($hOut, ">", ${strFileDestination}))
{
$strError = $!;
}
else
{
# Copy the file from STDIN
eval
{
$strError = $oFile->pipe(*STDIN, $hOut, $bCompress, $bUncompress);
};
$strError = $@;
# Close the input file
close($hOut);
}
if ($strError)
{
print(STDERR "${strFileDestination} could not be written: ${strError}");
exit COMMAND_ERR_FILE_READ;
}
exit 0;
}
####################################################################################################################################
# PATH_CREATE Command
####################################################################################################################################
if ($strOperation eq OP_PATH_CREATE)
{
my $strPath = $ARGV[1];
if (!defined($strPath))
{
confess "path must be specified for ${strOperation} operation";
}
$oFile->path_create(PATH_ABSOLUTE, $strPath, $strPermission);
exit 0;
}
print(STDERR "invalid operation ${strOperation}");
exit COMMAND_ERR_PARAM;

368
bin/pg_backrest_remote.pl Executable file
View File

@ -0,0 +1,368 @@
#!/usr/bin/perl
####################################################################################################################################
# pg_backrest_command.pl - Simple Postgres Backup and Restore Command Helper
####################################################################################################################################
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings;
use english;
use File::Basename;
use Getopt::Long;
use Carp;
use lib dirname($0) . '/..';
use pg_backrest_utility;
use pg_backrest_file;
use pg_backrest_remote;
####################################################################################################################################
# Operation constants - basic operations that are allowed in backrest command
####################################################################################################################################
use constant
{
OP_LIST => "list",
OP_EXISTS => "exists",
OP_HASH => "hash",
OP_REMOVE => "remove",
OP_MANIFEST => "manifest",
OP_COMPRESS => "compress",
OP_MOVE => "move",
OP_COPY_OUT => "copy_out",
OP_COPY_IN => "copy_in",
OP_PATH_CREATE => "path_create"
};
####################################################################################################################################
# Command line parameters
####################################################################################################################################
# my $bIgnoreMissing = false; # Ignore errors due to missing file
# my $bDestinationPathCreate = false; # Create destination path if it does not exist
# my $bCompress = false; # Compress output
# my $bUncompress = false; # Uncompress output
# my $strExpression = undef; # Expression to use for filtering (undef = no filtering)
# my $strPermission = undef; # Permission when creating directory or file (undef = default)
# my $strSort = undef; # Sort order (undef = forward)
#
# if (!GetOptions ("ignore-missing" => \$bIgnoreMissing,
# "dest-path-create" => \$bDestinationPathCreate,
# "compress" => \$bCompress,
# "uncompress" => \$bUncompress,
# "expression=s" => \$strExpression,
# "permission=s" => \$strPermission,
# "sort=s" => \$strSort))
# {
# print(STDERR "error in command line arguments");
# exit COMMAND_ERR_PARAM;
# }
####################################################################################################################################
# START MAIN
####################################################################################################################################
# Turn off logging
log_level_set(OFF, OFF);
my $oRemote = pg_backrest_remote->new();
$oRemote->welcome_send();
# # Get the operation
# my $strOperation = $ARGV[0];
#
# # Validate the operation
# if (!defined($strOperation))
# {
# print(STDERR "operation is not defined");
# exit COMMAND_ERR_PARAM;
# }
#
# # Make sure compress and uncompress are not both set
# if ($bCompress && $bUncompress)
# {
# print(STDERR "compress and uncompress options cannot both be set");
# exit COMMAND_ERR_PARAM;
# }
#
# # Create the file object
# my $oFile = pg_backrest_file->new();
#
# ####################################################################################################################################
# # LIST Command
# ####################################################################################################################################
# if ($strOperation eq OP_LIST)
# {
# my $strPath = $ARGV[1];
#
# if (!defined($strPath))
# {
# confess "path must be specified for ${strOperation} operation";
# }
#
# my $bFirst = true;
#
# foreach my $strFile ($oFile->list(PATH_ABSOLUTE, $strPath, $strExpression, $strSort))
# {
# $bFirst ? $bFirst = false : print "\n";
#
# print $strFile;
# }
#
# exit 0;
# }
#
# ####################################################################################################################################
# # EXISTS Command
# ####################################################################################################################################
# if ($strOperation eq OP_EXISTS)
# {
# my $strFile = $ARGV[1];
#
# if (!defined($strFile))
# {
# confess "filename must be specified for ${strOperation} operation";
# }
#
# print $oFile->exists(PATH_ABSOLUTE, $strFile) ? "Y" : "N";
#
# exit 0;
# }
#
# ####################################################################################################################################
# # HASH Command
# ####################################################################################################################################
# if ($strOperation eq OP_HASH)
# {
# my $strFile = $ARGV[1];
#
# if (!defined($strFile))
# {
# confess "filename must be specified for ${strOperation} operation";
# }
#
# print $oFile->hash(PATH_ABSOLUTE, $strFile);
#
# exit 0;
# }
#
# ####################################################################################################################################
# # REMOVE Command
# ####################################################################################################################################
# if ($strOperation eq OP_REMOVE)
# {
# my $strFile = $ARGV[1];
#
# if (!defined($strFile))
# {
# confess "filename must be specified for ${strOperation} operation";
# }
#
# print $oFile->remove(PATH_ABSOLUTE, $strFile, undef, $bIgnoreMissing) ? "Y" : "N";
#
# exit 0;
# }
#
# ####################################################################################################################################
# # MANIFEST Command
# ####################################################################################################################################
# if ($strOperation eq OP_MANIFEST)
# {
# my $strPath = $ARGV[1];
#
# if (!defined($strPath))
# {
# confess "path must be specified for ${strOperation} operation";
# }
#
# my %oManifestHash;
# $oFile->manifest(PATH_ABSOLUTE, $strPath, \%oManifestHash);
#
# print "name\ttype\tuser\tgroup\tpermission\tmodification_time\tinode\tsize\tlink_destination";
#
# foreach my $strName (sort(keys $oManifestHash{name}))
# {
# print "\n${strName}\t" .
# $oManifestHash{name}{"${strName}"}{type} . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{user}) ? $oManifestHash{name}{"${strName}"}{user} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{group}) ? $oManifestHash{name}{"${strName}"}{group} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{permission}) ? $oManifestHash{name}{"${strName}"}{permission} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{modification_time}) ?
# $oManifestHash{name}{"${strName}"}{modification_time} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{inode}) ? $oManifestHash{name}{"${strName}"}{inode} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{size}) ? $oManifestHash{name}{"${strName}"}{size} : "") . "\t" .
# (defined($oManifestHash{name}{"${strName}"}{link_destination}) ?
# $oManifestHash{name}{"${strName}"}{link_destination} : "");
# }
#
# exit 0;
# }
#
# ####################################################################################################################################
# # COMPRESS Command
# ####################################################################################################################################
# if ($strOperation eq OP_COMPRESS)
# {
# my $strFile = $ARGV[1];
#
# if (!defined($strFile))
# {
# confess "file must be specified for ${strOperation} operation";
# }
#
# $oFile->compress(PATH_ABSOLUTE, $strFile);
#
# exit 0;
# }
#
# ####################################################################################################################################
# # MOVE Command
# ####################################################################################################################################
# if ($strOperation eq OP_MOVE)
# {
# my $strFileSource = $ARGV[1];
#
# if (!defined($strFileSource))
# {
# confess "source file source must be specified for ${strOperation} operation";
# }
#
# my $strFileDestination = $ARGV[2];
#
# if (!defined($strFileDestination))
# {
# confess "destination file must be specified for ${strOperation} operation";
# }
#
# $oFile->move(PATH_ABSOLUTE, $strFileSource, PATH_ABSOLUTE, $strFileDestination, $bDestinationPathCreate);
#
# exit 0;
# }
#
# ####################################################################################################################################
# # COPY_IN Command
# ####################################################################################################################################
# if ($strOperation eq OP_COPY_IN)
# {
# my $strFileSource = $ARGV[1];
#
# # Make sure the source file is defined
# if (!defined($strFileSource))
# {
# confess "source file must be specified for ${strOperation} operation";
# }
#
# # Variable to hold errors
# my $strError;
#
# # Open the source file
# my $hIn;
#
# if (!open($hIn, "<", ${strFileSource}))
# {
# $strError = $!;
#
# unless (-e $strFileSource)
# {
# print(STDERR "${strFileSource} does not exist");
# exit COMMAND_ERR_FILE_MISSING;
# }
# }
# else
# {
# # Determine if the file is already compressed
# my $bAlreadyCompressed = ($strFileSource =~ "^.*\.$oFile->{strCompressExtension}\$");
#
# # Copy the file to STDOUT
# eval
# {
# $oFile->pipe($hIn, *STDOUT, $bCompress && !$bAlreadyCompressed, $bUncompress && $bAlreadyCompressed);
# };
#
# $strError = $@;
#
# # Close the input file
# close($hIn);
# }
#
# if ($strError)
# {
# print(STDERR "${strFileSource} could not be read: ${strError}");
# exit COMMAND_ERR_FILE_READ;
# }
#
# exit 0;
# }
#
# ####################################################################################################################################
# # COPY_OUT Command
# ####################################################################################################################################
# if ($strOperation eq OP_COPY_OUT)
# {
# my $strFileDestination = $ARGV[1];
#
# # Make sure the source file is defined
# if (!defined($strFileDestination))
# {
# confess "destination file must be specified for ${strOperation} operation";
# }
#
# # Determine if the file needs compression extension
# if ($bCompress && $strFileDestination !~ "^.*\.$oFile->{strCompressExtension}\$")
# {
# $strFileDestination .= "." . $oFile->{strCompressExtension};
# }
#
# # Variable to hold errors
# my $strError;
#
# # Open the destination file
# my $hOut;
#
# if (!open($hOut, ">", ${strFileDestination}))
# {
# $strError = $!;
# }
# else
# {
# # Copy the file from STDIN
# eval
# {
# $strError = $oFile->pipe(*STDIN, $hOut, $bCompress, $bUncompress);
# };
#
# $strError = $@;
#
# # Close the input file
# close($hOut);
# }
#
# if ($strError)
# {
# print(STDERR "${strFileDestination} could not be written: ${strError}");
# exit COMMAND_ERR_FILE_READ;
# }
#
# exit 0;
# }
#
# ####################################################################################################################################
# # PATH_CREATE Command
# ####################################################################################################################################
# if ($strOperation eq OP_PATH_CREATE)
# {
# my $strPath = $ARGV[1];
#
# if (!defined($strPath))
# {
# confess "path must be specified for ${strOperation} operation";
# }
#
# $oFile->path_create(PATH_ABSOLUTE, $strPath, $strPermission);
#
# exit 0;
# }
#
# print(STDERR "invalid operation ${strOperation}");
# exit COMMAND_ERR_PARAM;

View File

@ -22,6 +22,7 @@ use IO::String;
use lib dirname($0);
use pg_backrest_utility;
use pg_backrest_remote;
use Exporter qw(import);
our @EXPORT = qw(PATH_ABSOLUTE PATH_DB PATH_DB_ABSOLUTE PATH_BACKUP PATH_BACKUP_ABSOLUTE
@ -38,17 +39,10 @@ has strDefaultFilePermission => (is => 'ro', default => '0640');
# Command strings
has strCommand => (is => 'bare');
# Lock path
has strLockPath => (is => 'bare');
# Module variables
has strDbUser => (is => 'bare'); # Database user
has strDbHost => (is => 'bare'); # Database host
has oDbSSH => (is => 'bare'); # Database SSH object
has strRemote => (is => 'bare'); # Remote type (db or backup)
has oRemote => (is => 'bare'); # Remote object
has strBackupUser => (is => 'bare'); # Backup user
has strBackupHost => (is => 'bare'); # Backup host
has oBackupSSH => (is => 'bare'); # Backup SSH object
has strBackupPath => (is => 'bare'); # Backup base path
has strBackupClusterPath => (is => 'bare'); # Backup cluster path
@ -84,8 +78,7 @@ use constant
PATH_BACKUP_ABSOLUTE => 'backup:absolute',
PATH_BACKUP_CLUSTER => 'backup:cluster',
PATH_BACKUP_TMP => 'backup:tmp',
PATH_BACKUP_ARCHIVE => 'backup:archive',
PATH_LOCK_ERR => 'lock:err'
PATH_BACKUP_ARCHIVE => 'backup:archive'
};
####################################################################################################################################
@ -106,6 +99,15 @@ use constant
PIPE_STDERR => "<STDERR>"
};
####################################################################################################################################
# Remote Types
####################################################################################################################################
use constant
{
REMOTE_DB => PATH_DB,
REMOTE_BACKUP => PATH_BACKUP
};
####################################################################################################################################
# CONSTRUCTOR
####################################################################################################################################
@ -120,40 +122,19 @@ sub BUILD
$self->{strBackupClusterPath} = $self->{strBackupPath} . "/" . $self->{strStanza};
}
# Create the ssh options string
if (defined($self->{strBackupHost}) || defined($self->{strDbHost}))
# If remote is defined check parameters and open session
if (defined($self->{strRemote}))
{
if (defined($self->{strBackupHost}) && defined($self->{strDbHost}))
# Make sure remote is valid
if ($self->{strRemote} ne REMOTE_DB && $self->{strRemote} ne REMOTE_BACKUP)
{
confess &log(ASSERT, "backup and db hosts cannot both be remote");
confess &log(ASSERT, "strRemote must be \"" . REMOTE_DB . "\" or \"" . REMOTE_BACKUP . "\"");
}
my $strOptionSSHRequestTTY = "RequestTTY=yes";
my $strOptionSSHCompression = "Compression=no";
# if ($self->{bNoCompression})
# {
# $strOptionSSHCompression = "Compression=yes";
# }
# Connect SSH object if backup host is defined
if (!defined($self->{oBackupSSH}) && defined($self->{strBackupHost}))
# Remote object must be set
if (!defined($self->{oRemote}))
{
&log(TRACE, "connecting to backup ssh host " . $self->{strBackupHost});
$self->{oBackupSSH} = Net::OpenSSH->new($self->{strBackupHost}, timeout => 300, user => $self->{strBackupUser},
master_opts => [-o => $strOptionSSHCompression, -o => $strOptionSSHRequestTTY]);
$self->{oBackupSSH}->error and confess &log(ERROR, "unable to connect to $self->{strBackupHost}: " . $self->{oBackupSSH}->error);
}
# Connect SSH object if db host is defined
if (!defined($self->{oDbSSH}) && defined($self->{strDbHost}))
{
&log(TRACE, "connecting to database ssh host $self->{strDbHost}");
$self->{oDbSSH} = Net::OpenSSH->new($self->{strDbHost}, timeout => 300, user => $self->{strDbUser},
master_opts => [-o => $strOptionSSHCompression, -o => $strOptionSSHRequestTTY]);
$self->{oDbSSH}->error and confess &log(ERROR, "unable to connect to $self->{strDbHost}: " . $self->{oDbSSH}->error);
confess &log(ASSERT, "oRemote must be defined");
}
}
}
@ -180,8 +161,7 @@ sub clone
strBackupClusterPath => $self->{strBackupClusterPath},
bCompress => $self->{bCompress},
strStanza => $self->{strStanza},
iThreadIdx => $iThreadIdx,
strLockPath => $self->{strLockPath}
iThreadIdx => $iThreadIdx
);
}
@ -295,20 +275,6 @@ sub path_get
confess &log(ASSERT, "\$strStanza not yet defined");
}
# Get the lock error path
if ($strType eq PATH_LOCK_ERR)
{
my $strTempPath = $self->{strLockPath};
if (!defined($strTempPath))
{
return undef;
}
return ${strTempPath} . (defined($strFile) ? "/${strFile}" .
(defined($self->{iThreadIdx}) ? ".$self->{iThreadIdx}" : "") . ".err" : "");
}
# Get the backup tmp path
if ($strType eq PATH_BACKUP_TMP)
{
@ -359,32 +325,14 @@ sub path_get
####################################################################################################################################
# IS_REMOTE
#
# Determine whether any operations are being performed remotely. If $strPathType is defined, the function will return true if that
# path is remote. If $strPathType is not defined, then function will return true if any path is remote.
# Determine whether the path type is remote
####################################################################################################################################
sub is_remote
{
my $self = shift;
my $strPathType = shift;
# If the SSH object is defined then some paths are remote
if (defined($self->{oDbSSH}) || defined($self->{oBackupSSH}))
{
# If path type is not defined but the SSH object is, then some paths are remote
if (!defined($strPathType))
{
return true;
}
# If a host is defined for the path then it is remote
if (defined($self->{strBackupHost}) && $self->path_type_get($strPathType) eq PATH_BACKUP ||
defined($self->{strDbHost}) && $self->path_type_get($strPathType) eq PATH_DB)
{
return true;
}
}
return false;
return defined($self->{strRemote}) && $self->path_type_get($strPathType) eq $self->{strRemote};
}
####################################################################################################################################
@ -392,26 +340,25 @@ sub is_remote
#
# Get remote SSH object depending on the path type.
####################################################################################################################################
sub remote_get
{
my $self = shift;
my $strPathType = shift;
# Get the db SSH object
if ($self->path_type_get($strPathType) eq PATH_DB && defined($self->{oDbSSH}))
{
return $self->{oDbSSH};
}
# Get the backup SSH object
if ($self->path_type_get($strPathType) eq PATH_BACKUP && defined($self->{oBackupSSH}))
{
return $self->{oBackupSSH}
}
# Error when no ssh object is found
confess &log(ASSERT, "path type ${strPathType} does not have a defined ssh object");
}
# sub remote_get
# {
# my $self = shift;
#
# # Get the db SSH object
# if ($self->path_type_get($strPathType) eq PATH_DB && defined($self->{oDbSSH}))
# {
# return $self->{oDbSSH};
# }
#
# # Get the backup SSH object
# if ($self->path_type_get($strPathType) eq PATH_BACKUP && defined($self->{oBackupSSH}))
# {
# return $self->{oBackupSSH}
# }
#
# # Error when no ssh object is found
# confess &log(ASSERT, "path type ${strPathType} does not have a defined ssh object");
# }
####################################################################################################################################
# LINK_CREATE !!! NEEDS TO BE CONVERTED
@ -1189,9 +1136,11 @@ sub exists
# Run remotely
if ($bRemote)
{
# Build the command
my $strCommand = $self->{strCommand} . " exists ${strPathOp}";
# syswrite(self->{hIn}, )
# Build the command
# Run it remotely
my $oSSH = $self->remote_get($strPathType);
my $strOutput = $oSSH->capture($strCommand);

123
pg_backrest_remote.pm Normal file
View File

@ -0,0 +1,123 @@
####################################################################################################################################
# REMOTE MODULE
####################################################################################################################################
package pg_backrest_remote;
use threads;
use strict;
use warnings;
use Carp;
use Moose;
use Net::OpenSSH;
use File::Basename;
use lib dirname($0);
use pg_backrest_utility;
# Protocol strings
has strGreeting => (is => 'ro', default => 'pg_backrest_remote 0.20');
# Command strings
has strCommand => (is => 'bare');
# Module variables
has strHost => (is => 'bare'); # Host host
has strUser => (is => 'bare'); # User user
has oSSH => (is => 'bare'); # SSH object
# Process variables
has pId => (is => 'bare'); # SSH object
has hIn => (is => 'bare'); # SSH object
has hOut => (is => 'bare'); # SSH object
has hErr => (is => 'bare'); # SSH object
####################################################################################################################################
# CONSTRUCTOR
####################################################################################################################################
sub BUILD
{
my $self = shift;
if (defined($self->{strHost}))
{
# User must be defined
if (!defined($self->{strUser}))
{
confess &log(ASSERT, "strUser must be defined");
}
# User must be defined
if (!defined($self->{strCommand}))
{
confess &log(ASSERT, "strCommand must be defined");
}
# Set SSH Options
my $strOptionSSHRequestTTY = "RequestTTY=yes";
my $strOptionSSHCompression = "Compression=no";
# if ($self->{bNoCompression})
# {
# $strOptionSSHCompression = "Compression=yes";
# }
&log(TRACE, "connecting to remote ssh host " . $self->{strHost});
# Make SSH connection
$self->{oSSH} = Net::OpenSSH->new($self->{strHost}, timeout => 300, user => $self->{strUser},
master_opts => [-o => $strOptionSSHCompression, -o => $strOptionSSHRequestTTY]);
$self->{oSSH}->error and confess &log(ERROR, "unable to connect to $self->{strHost}: " . $self->{oSSH}->error);
# Execute remote command
($self->{hIn}, $self->{hOut}, $self->{hErr}, $self->{pId}) = $self->{oSSH}->open3($self->{strCommand});
}
}
####################################################################################################################################
# CLONE
####################################################################################################################################
sub clone
{
my $self = shift;
return pg_backrest_remote->new
(
strCommand => $self->{strCommand},
strHost => $self->{strUser},
strUser => $self->{strHost}
);
}
####################################################################################################################################
# GREETING_READ
####################################################################################################################################
sub greeting_read
{
my $self = shift;
my $hOut = shift;
# Make sure that the remote is running the right version
if (trim(readline($self->{hOut})) ne $self->{strGreeting})
{
confess &log(ERROR, "remote version mismatch");
}
}
####################################################################################################################################
# GREETING_WRITE
####################################################################################################################################
sub greeting_write
{
my $self = shift;
my $hOut = shift;
if (!syswrite(*STDOUT, "$self->{strGreeting}\n"))
{
confess "unable to write greeting";
}
}
no Moose;
__PACKAGE__->meta->make_immutable;

View File

@ -361,18 +361,4 @@ sub log
return $strMessage;
}
####################################################################################################################################
# EXECUTE - execute a command
####################################################################################################################################
#sub execute
#{
# my $strCommand = shift;
# my $strOutput;
#
# print("$strCommand");
# $strOutput = capture($strCommand) or confess &log(ERROR, "unable to execute command ${strCommand}: " . $_);
#
# return $strOutput;
#}
1;

View File

@ -17,8 +17,9 @@ use File::stat;
use Fcntl ':mode';
use lib dirname($0) . "/..";
use pg_backrest_file;
use pg_backrest_utility;
use pg_backrest_file;
use pg_backrest_remote;
use Exporter qw(import);
our @EXPORT = qw(BackRestFileTest);
@ -38,7 +39,7 @@ sub BackRestFileTest
my $iRun;
my $strStanza = "db";
my $strCommand = "/Users/dsteele/pg_backrest/bin/pg_backrest_command.pl";
my $strCommand = "/Users/dsteele/pg_backrest/bin/pg_backrest_remote.pl";
my $strHost = "127.0.0.1";
my $strUser = getpwuid($<);
my $strGroup = getgrgid($();
@ -48,6 +49,16 @@ sub BackRestFileTest
&log(INFO, "FILE MODULE ********************************************************************");
#-------------------------------------------------------------------------------------------------------------------------------
# Create remote
#-------------------------------------------------------------------------------------------------------------------------------
my $oRemote = pg_backrest_remote->new
(
strHost => $strHost,
strUser => $strUser,
strCommand => $strCommand,
);
#-------------------------------------------------------------------------------------------------------------------------------
# Test path_create()
#-------------------------------------------------------------------------------------------------------------------------------
@ -687,12 +698,10 @@ sub BackRestFileTest
my $oFile = pg_backrest_file->new
(
strStanza => $strStanza,
bNoCompression => true,
strCommand => $strCommand,
strBackupClusterPath => ${strTestPath},
strBackupPath => ${strTestPath},
strBackupHost => $bRemote ? $strHost : undef,
strBackupUser => $bRemote ? $strUser : undef
strRemote => $bRemote ? 'backup' : undef,
oRemote => $bRemote ? $oRemote : undef
);
# Loop through exists