2014-06-07 04:16:24 +03:00
|
|
|
#!/usr/bin/perl
|
|
|
|
####################################################################################################################################
|
2014-06-30 00:23:34 +03:00
|
|
|
# pg_backrest_remote.pl - Simple Postgres Backup and Restore Remote
|
2014-06-07 04:16:24 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use File::Basename;
|
|
|
|
use Getopt::Long;
|
|
|
|
use Carp;
|
|
|
|
|
2014-06-07 23:13:41 +03:00
|
|
|
use lib dirname($0) . '/../lib';
|
|
|
|
use BackRest::Utility;
|
2014-06-07 23:25:20 +03:00
|
|
|
use BackRest::File;
|
|
|
|
use BackRest::Remote;
|
2014-06-15 02:50:54 +03:00
|
|
|
use BackRest::Exception;
|
2014-06-07 04:16:24 +03:00
|
|
|
|
|
|
|
####################################################################################################################################
|
2014-06-07 23:06:46 +03:00
|
|
|
# Operation constants
|
2014-06-07 04:16:24 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
use constant
|
|
|
|
{
|
2014-06-07 23:06:46 +03:00
|
|
|
OP_NOOP => 'noop',
|
|
|
|
OP_EXIT => 'exit'
|
2014-06-07 04:16:24 +03:00
|
|
|
};
|
|
|
|
|
2014-06-21 18:05:29 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
# PARAM_GET - helper function that returns the param or an error if required and it does not exist
|
|
|
|
####################################################################################################################################
|
|
|
|
sub param_get
|
|
|
|
{
|
|
|
|
my $oParamHashRef = shift;
|
|
|
|
my $strParam = shift;
|
|
|
|
my $bRequired = shift;
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2014-06-21 18:05:29 +03:00
|
|
|
my $strValue = ${$oParamHashRef}{$strParam};
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2014-06-21 18:05:29 +03:00
|
|
|
if (!defined($strValue) && (!defined($bRequired) || $bRequired))
|
|
|
|
{
|
|
|
|
confess "${strParam} must be defined";
|
|
|
|
}
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2014-06-21 18:05:29 +03:00
|
|
|
return $strValue;
|
|
|
|
}
|
|
|
|
|
2014-06-07 04:16:24 +03:00
|
|
|
####################################################################################################################################
|
|
|
|
# START MAIN
|
|
|
|
####################################################################################################################################
|
|
|
|
# Turn off logging
|
|
|
|
log_level_set(OFF, OFF);
|
|
|
|
|
2014-06-07 23:06:46 +03:00
|
|
|
# Create the remote object
|
2014-10-10 22:13:28 +03:00
|
|
|
my $oRemote = new BackRest::Remote();
|
2014-06-07 04:16:24 +03:00
|
|
|
|
2014-06-15 02:50:54 +03:00
|
|
|
# Create the file object
|
2014-10-10 22:13:28 +03:00
|
|
|
my $oFile = new BackRest::File
|
2014-06-15 02:50:54 +03:00
|
|
|
(
|
2014-10-10 22:13:28 +03:00
|
|
|
undef,
|
|
|
|
undef,
|
|
|
|
undef,
|
|
|
|
$oRemote
|
2014-06-15 02:50:54 +03:00
|
|
|
);
|
|
|
|
|
2014-06-07 18:51:27 +03:00
|
|
|
# Write the greeting so remote process knows who we are
|
|
|
|
$oRemote->greeting_write();
|
|
|
|
|
2014-06-07 22:01:29 +03:00
|
|
|
# Command string
|
2014-06-07 23:06:46 +03:00
|
|
|
my $strCommand = OP_NOOP;
|
2014-06-07 18:51:27 +03:00
|
|
|
|
|
|
|
# Loop until the exit command is received
|
2014-06-07 23:06:46 +03:00
|
|
|
while ($strCommand ne OP_EXIT)
|
2014-06-07 18:51:27 +03:00
|
|
|
{
|
2014-06-07 22:01:29 +03:00
|
|
|
my %oParamHash;
|
|
|
|
|
|
|
|
$strCommand = $oRemote->command_read(\%oParamHash);
|
|
|
|
|
2014-06-07 18:51:27 +03:00
|
|
|
eval
|
|
|
|
{
|
2015-03-01 02:07:29 +02:00
|
|
|
# Copy file
|
|
|
|
if ($strCommand eq OP_FILE_COPY ||
|
|
|
|
$strCommand eq OP_FILE_COPY_IN ||
|
|
|
|
$strCommand eq OP_FILE_COPY_OUT)
|
2014-06-07 18:51:27 +03:00
|
|
|
{
|
2015-03-01 02:07:29 +02:00
|
|
|
my $bResult;
|
|
|
|
my $strChecksum;
|
|
|
|
my $iFileSize;
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2015-03-01 02:07:29 +02:00
|
|
|
# Copy a file locally
|
|
|
|
if ($strCommand eq OP_FILE_COPY)
|
|
|
|
{
|
|
|
|
($bResult, $strChecksum, $iFileSize) =
|
|
|
|
$oFile->copy(PATH_ABSOLUTE, param_get(\%oParamHash, 'source_file'),
|
|
|
|
PATH_ABSOLUTE, param_get(\%oParamHash, 'destination_file'),
|
|
|
|
param_get(\%oParamHash, 'source_compressed'),
|
|
|
|
param_get(\%oParamHash, 'destination_compress'),
|
|
|
|
param_get(\%oParamHash, 'ignore_missing_source', false),
|
|
|
|
undef,
|
|
|
|
param_get(\%oParamHash, 'permission', false),
|
|
|
|
param_get(\%oParamHash, 'destination_path_create') ? 'Y' : 'N',
|
|
|
|
param_get(\%oParamHash, 'user', false),
|
2015-03-01 23:42:27 +02:00
|
|
|
param_get(\%oParamHash, 'group', false),
|
|
|
|
param_get(\%oParamHash, 'append_checksum', false));
|
2015-03-01 02:07:29 +02:00
|
|
|
}
|
|
|
|
# Copy a file from STDIN
|
|
|
|
elsif ($strCommand eq OP_FILE_COPY_IN)
|
|
|
|
{
|
|
|
|
($bResult, $strChecksum, $iFileSize) =
|
|
|
|
$oFile->copy(PIPE_STDIN, undef,
|
|
|
|
PATH_ABSOLUTE, param_get(\%oParamHash, 'destination_file'),
|
2015-03-02 05:23:52 +02:00
|
|
|
param_get(\%oParamHash, 'source_compressed'),
|
|
|
|
param_get(\%oParamHash, 'destination_compress'),
|
2015-03-01 02:07:29 +02:00
|
|
|
undef, undef,
|
|
|
|
param_get(\%oParamHash, 'permission', false),
|
|
|
|
param_get(\%oParamHash, 'destination_path_create'),
|
|
|
|
param_get(\%oParamHash, 'user', false),
|
2015-03-01 23:42:27 +02:00
|
|
|
param_get(\%oParamHash, 'group', false),
|
|
|
|
param_get(\%oParamHash, 'append_checksum', false));
|
2015-03-01 02:07:29 +02:00
|
|
|
}
|
|
|
|
# Copy a file to STDOUT
|
|
|
|
elsif ($strCommand eq OP_FILE_COPY_OUT)
|
|
|
|
{
|
|
|
|
($bResult, $strChecksum, $iFileSize) =
|
|
|
|
$oFile->copy(PATH_ABSOLUTE, param_get(\%oParamHash, 'source_file'),
|
|
|
|
PIPE_STDOUT, undef,
|
2015-03-02 05:23:52 +02:00
|
|
|
param_get(\%oParamHash, 'source_compressed'),
|
|
|
|
param_get(\%oParamHash, 'destination_compress'));
|
2015-03-01 02:07:29 +02:00
|
|
|
}
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2015-03-01 02:07:29 +02:00
|
|
|
$oRemote->output_write(($bResult ? 'Y' : 'N') . " " . (defined($strChecksum) ? $strChecksum : '?') . " " .
|
|
|
|
(defined($iFileSize) ? $iFileSize : '?'));
|
2014-06-13 04:56:20 +03:00
|
|
|
}
|
2014-06-30 00:23:34 +03:00
|
|
|
# List files in a path
|
2014-06-22 01:19:37 +03:00
|
|
|
elsif ($strCommand eq OP_FILE_LIST)
|
|
|
|
{
|
|
|
|
my $strOutput;
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2014-06-22 01:19:37 +03:00
|
|
|
foreach my $strFile ($oFile->list(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'),
|
|
|
|
param_get(\%oParamHash, 'expression', false),
|
2014-10-02 17:55:38 +03:00
|
|
|
param_get(\%oParamHash, 'sort_order'),
|
|
|
|
param_get(\%oParamHash, 'ignore_missing')))
|
2014-06-22 01:19:37 +03:00
|
|
|
{
|
|
|
|
if (defined($strOutput))
|
|
|
|
{
|
|
|
|
$strOutput .= "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
$strOutput .= $strFile;
|
|
|
|
}
|
2014-06-22 03:08:49 +03:00
|
|
|
|
2014-06-22 01:19:37 +03:00
|
|
|
$oRemote->output_write($strOutput);
|
|
|
|
}
|
2014-06-30 00:23:34 +03:00
|
|
|
# Create a path
|
2014-06-21 22:46:26 +03:00
|
|
|
elsif ($strCommand eq OP_FILE_PATH_CREATE)
|
2014-06-15 03:47:32 +03:00
|
|
|
{
|
2014-06-21 22:46:26 +03:00
|
|
|
$oFile->path_create(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), param_get(\%oParamHash, 'permission', false));
|
2014-06-15 03:47:32 +03:00
|
|
|
$oRemote->output_write();
|
|
|
|
}
|
2014-06-30 00:23:34 +03:00
|
|
|
# Check if a file/path exists
|
2014-06-21 22:46:26 +03:00
|
|
|
elsif ($strCommand eq OP_FILE_EXISTS)
|
|
|
|
{
|
|
|
|
$oRemote->output_write($oFile->exists(PATH_ABSOLUTE, param_get(\%oParamHash, 'path')) ? 'Y' : 'N');
|
|
|
|
}
|
2015-01-06 20:08:56 +02:00
|
|
|
# Wait
|
|
|
|
elsif ($strCommand eq OP_FILE_WAIT)
|
|
|
|
{
|
|
|
|
$oRemote->output_write($oFile->wait(PATH_ABSOLUTE));
|
|
|
|
}
|
2014-06-30 00:23:34 +03:00
|
|
|
# Generate a manifest
|
2014-06-22 23:05:00 +03:00
|
|
|
elsif ($strCommand eq OP_FILE_MANIFEST)
|
|
|
|
{
|
|
|
|
my %oManifestHash;
|
|
|
|
|
2015-01-06 20:08:56 +02:00
|
|
|
$oFile->manifest(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), \%oManifestHash);
|
2014-06-22 23:05:00 +03:00
|
|
|
|
2015-01-06 20:08:56 +02:00
|
|
|
my $strOutput = "name\ttype\tuser\tgroup\tpermission\tmodification_time\tinode\tsize\tlink_destination";
|
2014-06-22 23:05:00 +03:00
|
|
|
|
|
|
|
foreach my $strName (sort(keys $oManifestHash{name}))
|
|
|
|
{
|
|
|
|
$strOutput .= "\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}) ?
|
2015-01-06 20:08:56 +02:00
|
|
|
$oManifestHash{name}{"${strName}"}{link_destination} : "");
|
2014-06-22 23:05:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$oRemote->output_write($strOutput);
|
|
|
|
}
|
2014-06-30 00:23:34 +03:00
|
|
|
# Continue if noop or exit
|
|
|
|
elsif ($strCommand ne OP_NOOP && $strCommand ne OP_EXIT)
|
2014-06-07 18:51:27 +03:00
|
|
|
{
|
2014-06-30 00:23:34 +03:00
|
|
|
confess "invalid command: ${strCommand}";
|
2014-06-07 18:51:27 +03:00
|
|
|
}
|
|
|
|
};
|
2014-06-15 22:56:45 +03:00
|
|
|
|
2014-06-30 00:23:34 +03:00
|
|
|
# Process errors
|
2014-06-07 18:51:27 +03:00
|
|
|
if ($@)
|
|
|
|
{
|
|
|
|
$oRemote->error_write($@);
|
|
|
|
}
|
|
|
|
}
|