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

288 lines
11 KiB
Perl

####################################################################################################################################
# PROTOCOL REMOTE MINION MODULE
####################################################################################################################################
package pgBackRest::Protocol::RemoteMinion;
use parent 'pgBackRest::Protocol::CommonMinion';
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use File::Basename qw(dirname);
use lib dirname($0) . '/../lib';
use pgBackRest::Common::Exception;
use pgBackRest::Common::Log;
use pgBackRest::Archive;
use pgBackRest::Config::Config;
use pgBackRest::Db;
use pgBackRest::File;
use pgBackRest::Info;
use pgBackRest::Protocol::Common;
use pgBackRest::Protocol::CommonMinion;
####################################################################################################################################
# CONSTRUCTOR
####################################################################################################################################
sub new
{
my $class = shift; # Class name
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$strCommand, # Command the master process is running
$iBufferMax, # Maximum buffer size
$iCompressLevel, # Set compression level
$iCompressLevelNetwork, # Set compression level for network only compression,
$iProtocolTimeout # Protocol timeout
) =
logDebugParam
(
__PACKAGE__ . '->new', \@_,
{name => 'strCommand'},
{name => 'iBufferMax'},
{name => 'iCompressLevel'},
{name => 'iCompressNetworkLevel'},
{name => 'iProtocolTimeout'}
);
# Init object and store variables
my $self = $class->SUPER::new(CMD_REMOTE, $strCommand, $iBufferMax, $iCompressLevel,
$iCompressLevelNetwork, $iProtocolTimeout);
bless $self, $class;
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'self', value => $self}
);
}
####################################################################################################################################
# init
####################################################################################################################################
sub init
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my ($strOperation) = logDebugParam(__PACKAGE__ . '->init');
# Create objects
$self->{oFile} = new pgBackRest::File
(
optionGet(OPTION_STANZA, false),
optionGet(OPTION_REPO_PATH, false),
$self
);
$self->{oArchive} = new pgBackRest::Archive();
$self->{oInfo} = new pgBackRest::Info();
$self->{oJSON} = JSON::PP->new();
$self->{oDb} = new pgBackRest::Db();
# Return from function and log return values if any
return logDebugReturn($strOperation);
}
####################################################################################################################################
# commandProcess
####################################################################################################################################
sub commandProcess
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$strCommand,
) =
logDebugParam
(
__PACKAGE__ . '->commandProcess', \@_,
{name => 'strCommand', trace => true},
);
# Copy file
if ($strCommand eq OP_FILE_COPY || $strCommand eq OP_FILE_COPY_IN || $strCommand eq OP_FILE_COPY_OUT)
{
my $bResult;
my $strChecksum;
my $iFileSize;
# Copy a file locally
if ($strCommand eq OP_FILE_COPY)
{
($bResult, $strChecksum, $iFileSize) = $self->{oFile}->copy(
PATH_ABSOLUTE, $self->paramGet('source_file'),
PATH_ABSOLUTE, $self->paramGet('destination_file'),
$self->paramGet('source_compressed'),
$self->paramGet('destination_compress'),
$self->paramGet('ignore_missing_source', false),
undef,
$self->paramGet('mode', false),
$self->paramGet('destination_path_create') ? 'Y' : 'N',
$self->paramGet('user', false),
$self->paramGet('group', false),
$self->paramGet('append_checksum', false));
}
# Copy a file from STDIN
elsif ($strCommand eq OP_FILE_COPY_IN)
{
($bResult, $strChecksum, $iFileSize) = $self->{oFile}->copy(
PIPE_STDIN, undef,
PATH_ABSOLUTE, $self->paramGet('destination_file'),
$self->paramGet('source_compressed'),
$self->paramGet('destination_compress'),
undef, undef,
$self->paramGet('mode', false),
$self->paramGet('destination_path_create'),
$self->paramGet('user', false),
$self->paramGet('group', false),
$self->paramGet('append_checksum', false));
}
# Copy a file to STDOUT
elsif ($strCommand eq OP_FILE_COPY_OUT)
{
($bResult, $strChecksum, $iFileSize) = $self->{oFile}->copy(
PATH_ABSOLUTE, $self->paramGet('source_file'),
PIPE_STDOUT, undef,
$self->paramGet('source_compressed'),
$self->paramGet('destination_compress'));
}
$self->outputWrite(
($bResult ? 'Y' : 'N') . " " . (defined($strChecksum) ? $strChecksum : '?') . " " .
(defined($iFileSize) ? $iFileSize : '?'));
}
# List files in a path
elsif ($strCommand eq OP_FILE_LIST)
{
my $strOutput;
foreach my $strFile ($self->{oFile}->list(
PATH_ABSOLUTE, $self->paramGet('path'), $self->paramGet('expression', false),
$self->paramGet('sort_order'), $self->paramGet('ignore_missing')))
{
$strOutput .= (defined($strOutput) ? "\n" : '') . $strFile;
}
$self->outputWrite($strOutput);
}
# Create a path
elsif ($strCommand eq OP_FILE_PATH_CREATE)
{
$self->{oFile}->pathCreate(PATH_ABSOLUTE, $self->paramGet('path'), $self->paramGet('mode', false));
$self->outputWrite();
}
# Check if a file/path exists
elsif ($strCommand eq OP_FILE_EXISTS)
{
$self->outputWrite($self->{oFile}->exists(PATH_ABSOLUTE, $self->paramGet('path')) ? 'Y' : 'N');
}
# Wait
elsif ($strCommand eq OP_FILE_WAIT)
{
$self->outputWrite($self->{oFile}->wait(PATH_ABSOLUTE, $self->paramGet('wait')));
}
# Generate a manifest
elsif ($strCommand eq OP_FILE_MANIFEST)
{
my %oManifestHash;
$self->{oFile}->manifest(PATH_ABSOLUTE, $self->paramGet('path'), \%oManifestHash);
my $strOutput = "name\ttype\tuser\tgroup\tmode\tmodification_time\tinode\tsize\tlink_destination";
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}"}{mode}) ? $oManifestHash{name}{"${strName}"}{mode} : "") . "\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} : "");
}
$self->outputWrite($strOutput);
}
# Archive push checks
elsif ($strCommand eq OP_ARCHIVE_PUSH_CHECK)
{
my ($strArchiveId, $strChecksum) = $self->{oArchive}->pushCheck(
$self->{oFile},
$self->paramGet('wal-segment'),
$self->paramGet('partial'),
undef,
$self->paramGet('db-version'),
$self->paramGet('db-sys-id'));
$self->outputWrite("${strArchiveId}\t" . (defined($strChecksum) ? $strChecksum : 'Y'));
}
elsif ($strCommand eq OP_ARCHIVE_GET_BACKUP_INFO_CHECK)
{
$self->outputWrite(
$self->{oArchive}->getBackupInfoCheck(
$self->{oFile},
$self->paramGet('db-version'),
$self->paramGet('db-control-version'),
$self->paramGet('db-catalog-version'),
$self->paramGet('db-sys-id')));
}
elsif ($strCommand eq OP_ARCHIVE_GET_CHECK)
{
$self->outputWrite(
$self->{oArchive}->getCheck(
$self->{oFile},
$self->paramGet('db-version'),
$self->paramGet('db-sys-id')));
}
elsif ($strCommand eq OP_ARCHIVE_GET_ARCHIVE_ID)
{
$self->outputWrite($self->{oArchive}->getArchiveId($self->{oFile}));
}
# Info list stanza
elsif ($strCommand eq OP_INFO_STANZA_LIST)
{
$self->outputWrite($self->{oJSON}->encode($self->{oInfo}->stanzaList($self->{oFile}, $self->paramGet('stanza', false))));
}
elsif ($strCommand eq OP_DB_INFO)
{
my ($strDbVersion, $iControlVersion, $iCatalogVersion, $ullDbSysId) = $self->{oDb}->info($self->paramGet('db-path'));
$self->outputWrite("${strDbVersion}\t${iControlVersion}\t${iCatalogVersion}\t${ullDbSysId}");
}
elsif ($strCommand eq OP_DB_CONNECT)
{
$self->outputWrite($self->{oDb}->connect());
}
elsif ($strCommand eq OP_DB_EXECUTE_SQL)
{
$self->outputWrite(
$self->{oDb}->executeSql(
$self->paramGet('script'),
$self->paramGet('ignore-error', false),
$self->paramGet('result', false)));
}
# Command not processed
else
{
return false;
}
# Command processed
return true;
}
1;