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:
parent
e71a986ef3
commit
ae130229ef
@ -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
368
bin/pg_backrest_remote.pl
Executable 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;
|
@ -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
123
pg_backrest_remote.pm
Normal 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;
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user