pgbackrest.git / summary / log / commit / refs
commit d245f8eb425322f0efcd05ab4c12b3b45cc87138
Author: David Steele <david@pgmasters.net>
Date: Mon Jan 21 11:51:45 2019 +0000
The info command is implemented entirely in C.
The C info code has already been committed but this commit wires it into main.
Also remove the info Perl code and tests since they are no longer called.
doc/xml/release.xml | 4 +
lib/pgBackRest/Info.pm | 748 ---------------------
lib/pgBackRest/Protocol/Helper.pm | 4 -
lib/pgBackRest/Protocol/Remote/Minion.pm | 5 -
src/command/info/info.c | 8 +-
src/main.c | 7 +
src/perl/embed.auto.c | 679 -------------------
test/define.yaml | 7 -
test/expect/mock-all-001.log | 4 +-
test/expect/mock-all-003.log | 4 +-
.../pgBackRestTest/Module/Info/InfoUnitPerlTest.pm | 502 --------------
11 files changed, 16 insertions(+), 1956 deletions(-)
diff --git a/doc/xml/release.xml b/doc/xml/release.xml
index f8d87ce15..762401722 100644
--- a/doc/xml/release.xml
+++ b/doc/xml/release.xml
@@ -15,6 +15,10 @@
<release date="XXXX-XX-XX" version="2.09dev" title="UNDER DEVELOPMENT">
<release-core-list>
<release-improvement-list>
+ <release-item>
+ <p>The <cmd>info</cmd> command is implemented entirely in C.</p>
+ </release-item>
+
<release-item>
<p>Simplify <cmd>info</cmd> command text message when no stanza are present by replacing the repository path with <quote>the repository</quote>.</p>
</release-item>
diff --git a/lib/pgBackRest/Info.pm b/lib/pgBackRest/Info.pm
deleted file mode 100644
index e121197a1..000000000
--- a/lib/pgBackRest/Info.pm
+++ /dev/null
@@ -1,748 +0,0 @@
-####################################################################################################################################
-# INFO MODULE
-####################################################################################################################################
-package pgBackRest::Info;
-
-use strict;
-use warnings FATAL => qw(all);
-use Carp qw(confess);
-
-use English '-no_match_vars';
-use Exporter qw(import);
- our @EXPORT = qw();
-use File::Basename qw(dirname);
-
-use pgBackRest::Backup::Common;
-use pgBackRest::Backup::Info;
-use pgBackRest::Common::Exception;
-use pgBackRest::Common::Log;
-use pgBackRest::Common::Ini;
-use pgBackRest::Common::String;
-use pgBackRest::Backup::Common;
-use pgBackRest::Backup::Info;
-use pgBackRest::Config::Config;
-use pgBackRest::InfoCommon;
-use pgBackRest::Manifest;
-use pgBackRest::Protocol::Helper;
-use pgBackRest::Protocol::Storage::Helper;
-use pgBackRest::Storage::Helper;
-
-####################################################################################################################################
-# Info constants
-####################################################################################################################################
-use constant INFO_SECTION_BACKREST => 'backrest';
-use constant INFO_SECTION_ARCHIVE => 'archive';
-use constant INFO_SECTION_DB => 'database';
-use constant INFO_SECTION_INFO => 'info';
-use constant INFO_SECTION_REPO => 'repository';
-use constant INFO_SECTION_TIMESTAMP => 'timestamp';
-use constant INFO_SECTION_STATUS => 'status';
-use constant INFO_SECTION_CIPHER => 'cipher';
-
-use constant INFO_STANZA_NAME => 'name';
-
-use constant INFO_STANZA_STATUS_OK => 'ok';
-use constant INFO_STANZA_STATUS_ERROR => 'error';
-
-use constant INFO_STANZA_STATUS_OK_CODE => 0;
-use constant INFO_STANZA_STATUS_OK_MESSAGE => INFO_STANZA_STATUS_OK;
-use constant INFO_STANZA_STATUS_MISSING_STANZA_CODE => 1;
-use constant INFO_STANZA_STATUS_MISSING_STANZA_MESSAGE => 'missing stanza path';
-use constant INFO_STANZA_STATUS_NO_BACKUP_CODE => 2;
-use constant INFO_STANZA_STATUS_NO_BACKUP_MESSAGE => 'no valid backups';
-use constant INFO_STANZA_STATUS_MISSING_STANZA_DATA_CODE => 3;
-use constant INFO_STANZA_STATUS_MISSING_STANZA_DATA_MESSAGE => 'missing stanza data';
-
-use constant INFO_KEY_CODE => 'code';
-use constant INFO_KEY_DELTA => 'delta';
-use constant INFO_KEY_FORMAT => 'format';
-use constant INFO_KEY_ID => INFO_HISTORY_ID;
-use constant INFO_KEY_LABEL => 'label';
-use constant INFO_KEY_MAX => 'max';
-use constant INFO_KEY_MIN => 'min';
-use constant INFO_KEY_MESSAGE => 'message';
-use constant INFO_KEY_PRIOR => 'prior';
-use constant INFO_KEY_REFERENCE => 'reference';
-use constant INFO_KEY_SIZE => 'size';
-use constant INFO_KEY_START => 'start';
-use constant INFO_KEY_STOP => 'stop';
-use constant INFO_KEY_SYSTEM_ID => INFO_SYSTEM_ID;
-use constant INFO_KEY_TYPE => 'type';
-use constant INFO_KEY_VERSION => INFO_DB_VERSION;
-
-####################################################################################################################################
-# CONSTRUCTOR
-####################################################################################################################################
-sub new
-{
- my $class = shift; # Class name
-
- # Create the class hash
- my $self = {};
- bless $self, $class;
-
- # Assign function parameters, defaults, and log debug info
- my ($strOperation) = logDebugParam(__PACKAGE__ . '->new');
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'self', value => $self}
- );
-}
-
-####################################################################################################################################
-# process
-####################################################################################################################################
-sub process
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my ($strOperation) = logDebugParam(__PACKAGE__ . '->process');
-
- # Get stanza if specified
- my $strStanza = cfgOptionTest(CFGOPT_STANZA) ? cfgOption(CFGOPT_STANZA) : undef;
-
- # Get the stanza list with all info
- my $oyStanzaList = $self->stanzaList($strStanza);
-
- if (cfgOptionTest(CFGOPT_OUTPUT, CFGOPTVAL_INFO_OUTPUT_TEXT))
- {
- my $strOutput = $self->formatText($oyStanzaList);
-
- if (defined($strOutput))
- {
- syswrite(*STDOUT, $strOutput);
- }
- else
- {
- syswrite(*STDOUT, "No stanzas exist in the repository.\n");
- }
- }
- elsif (cfgOptionTest(CFGOPT_OUTPUT, CFGOPTVAL_INFO_OUTPUT_JSON))
- {
- my $oJSON = JSON::PP->new()->canonical()->pretty()->indent_length(4);
- $self->outputJSON($oJSON->encode($oyStanzaList));
- }
- else
- {
- confess &log(ASSERT, "invalid info output option '" . cfgOption(CFGOPT_OUTPUT) . "'");
- }
-
- # Return from function and log return values if any
- return logDebugReturn($strOperation);
-}
-
-####################################################################################################################################
-# outputJSON
-###################################################################################################################################
-sub outputJSON
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $strJSON,
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->outputJSON', \@_,
- {name => 'strJSON'},
- );
-
- syswrite(*STDOUT, $strJSON);
-
- # On some systems a linefeed will be appended by encode() but others will not have it. In our case there should always
- # be a terminating linefeed.
- if ($strJSON !~ /\n$/)
- {
- syswrite(*STDOUT, "\n");
- }
-}
-
-####################################################################################################################################
-# formatText
-#
-# Format --output=text info.
-####################################################################################################################################
-sub formatText
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $oyStanzaList,
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->formatText', \@_,
- {name => 'oyStanzaList', trace => true},
- );
-
- my $strOutput;
-
- foreach my $oStanzaInfo (@{$oyStanzaList})
- {
- # Output stanza name and status
- $strOutput .= (defined($strOutput) ? "\n" : '') . $self->formatTextStanza($oStanzaInfo) . "\n";
-
- # Get the current DB info (always last element in the array)
- my $hDbCurrent = @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}[-1];
-
- # Loop through the DB history array for the stanza from oldest to newest
- foreach my $hDbInfo (@{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}})
- {
-
- if ($hDbInfo->{&INFO_HISTORY_ID} == $hDbCurrent->{&INFO_HISTORY_ID})
- {
- $strOutput .= "\n db (current)";
- }
-
- # Get the archive information for the DB
- my $strOutputArchive;
- foreach my $hDbArchive (@{$oStanzaInfo->{&INFO_SECTION_ARCHIVE}})
- {
- if ($hDbArchive->{&INFO_SECTION_DB}{&INFO_HISTORY_ID} == $hDbInfo->{&INFO_HISTORY_ID})
- {
- # Output archive start / stop values
- $strOutputArchive .= "\n wal archive min/max (" . $hDbArchive->{&INFO_KEY_ID} . "): ";
-
- if (defined($hDbArchive->{&INFO_KEY_MIN}))
- {
- $strOutputArchive .= $hDbArchive->{&INFO_KEY_MIN} . ' / ' . $hDbArchive->{&INFO_KEY_MAX};
- }
- else
- {
- $strOutputArchive .= 'none present';
- }
-
- $strOutputArchive .= "\n";
- }
- }
-
- # Get information for each stanza backup for the DB, from oldest to newest
- my $strOutputBackup;
- foreach my $oBackupInfo (@{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}})
- {
- if ($oBackupInfo->{&INFO_SECTION_DB}{&INFO_KEY_ID} == $hDbInfo->{&INFO_HISTORY_ID})
- {
- $strOutputBackup .= "\n" . $self->formatTextBackup($oBackupInfo) . "\n";
- }
- }
-
- if (defined($strOutputArchive) || defined($strOutputBackup))
- {
- if ($hDbInfo->{&INFO_HISTORY_ID} != $hDbCurrent->{&INFO_HISTORY_ID})
- {
- $strOutput .= "\n db (prior)";
- }
-
- if (defined($strOutputArchive))
- {
- $strOutput .= $strOutputArchive;
- }
-
- if (defined($strOutputBackup))
- {
- $strOutput .= $strOutputBackup;
- }
- }
- }
- }
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'strOutput', value => $strOutput, trace => true}
- );
-}
-
-####################################################################################################################################
-# formatTextStanza
-#
-# Format --output=text stanza info.
-####################################################################################################################################
-sub formatTextStanza
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $oStanzaInfo,
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->formatTextStanza', \@_,
- {name => 'oStanzaInfo', trace => true},
- );
-
- # Output stanza name, status and cipher type
- my $strOutput =
- 'stanza: ' . $oStanzaInfo->{&INFO_STANZA_NAME} . "\n" .
- " status: " . ($oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_CODE} == 0 ? INFO_STANZA_STATUS_OK :
- INFO_STANZA_STATUS_ERROR . ' (' . $oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_MESSAGE} . ')') .
- (defined($oStanzaInfo->{&INFO_SECTION_CIPHER}) ? "\n cipher: " . $oStanzaInfo->{&INFO_SECTION_CIPHER} : '');
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'strOutput', value => $strOutput, trace => true}
- );
-}
-
-####################################################################################################################################
-# formatTextBackup
-#
-# Format --output=text backup info.
-####################################################################################################################################
-sub formatTextBackup
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $oBackupInfo,
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->formatTextBackup', \@_,
- {name => 'oBackupInfo', trace => true},
- );
-
- my $strOutput =
- ' ' . $$oBackupInfo{&INFO_KEY_TYPE} . ' backup: ' . $$oBackupInfo{&INFO_KEY_LABEL} . "\n" .
-
- ' timestamp start/stop: ' .
- timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_START}) .
- ' / ' .
- timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_STOP}) . "\n" .
-
- " wal start/stop: ";
-
- if (defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_START}) &&
- defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_STOP}))
- {
- $strOutput .=
- $oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_START} . ' / ' . $oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_STOP};
- }
- else
- {
- $strOutput .= 'n/a';
- }
-
- $strOutput .=
- "\n database size: " .
- (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) ?
- fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) : '') .
- ', backup size: ' .
- (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) ?
- fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) : '') . "\n" .
-
- ' repository size: ' .
- (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) ?
- fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) : '') .
- ', repository backup size: ' .
- (defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_DELTA}) ?
- fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_DELTA}) : '');
-
- # List the backup reference chain, if any, for this backup
- if (defined($oBackupInfo->{&INFO_KEY_REFERENCE}) && @{$oBackupInfo->{&INFO_KEY_REFERENCE}} > 0)
- {
- $strOutput .= "\n backup reference list: " . (join(', ', @{$$oBackupInfo{&INFO_KEY_REFERENCE}}));
- }
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'strOutput', value => $strOutput, trace => true}
- );
-}
-
-####################################################################################################################################
-# stanzaList
-####################################################################################################################################
-sub stanzaList
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $strStanza
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->stanzaList', \@_,
- {name => 'strStanza', required => false}
- );
-
- my @oyStanzaList;
-
- # Run remotely
- if (!isRepoLocal())
- {
- @oyStanzaList = @{protocolGet(CFGOPTVAL_REMOTE_TYPE_BACKUP)->cmdExecute(OP_INFO_STANZA_LIST, [$strStanza], true)};
- }
- # Run locally
- else
- {
- my @stryStanza = storageRepo()->list(cfgCommandName(CFGCMD_BACKUP), {bIgnoreMissing => true});
-
- foreach my $strStanzaFound (@stryStanza)
- {
- if (defined($strStanza) && $strStanza ne $strStanzaFound)
- {
- next;
- }
-
- my $oStanzaInfo = {};
- $$oStanzaInfo{&INFO_STANZA_NAME} = $strStanzaFound;
- ($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}, $$oStanzaInfo{&INFO_BACKUP_SECTION_DB}) =
- $self->backupList($strStanzaFound);
-
- # If there are no backups then set status to no backup
- if (defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}) && @{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}} == 0)
- {
- $$oStanzaInfo{&INFO_SECTION_STATUS} =
- {
- &INFO_KEY_CODE => INFO_STANZA_STATUS_NO_BACKUP_CODE,
- &INFO_KEY_MESSAGE => INFO_STANZA_STATUS_NO_BACKUP_MESSAGE
- };
- }
- # Else status is OK
- elsif (defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}))
- {
- $$oStanzaInfo{&INFO_SECTION_STATUS} =
- {
- &INFO_KEY_CODE => INFO_STANZA_STATUS_OK_CODE,
- &INFO_KEY_MESSAGE => INFO_STANZA_STATUS_OK_MESSAGE
- };
- }
-
- $$oStanzaInfo{&INFO_SECTION_CIPHER} = defined(storageRepo({strStanza => $strStanzaFound})->cipherType()) ?
- storageRepo({strStanza => $strStanzaFound})->cipherType() : CFGOPTVAL_REPO_CIPHER_TYPE_NONE;
-
- # Array to store tne min/max archive for each database for which there are archives
- my @oyDbArchiveList = ();
-
- if (!defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}))
- {
- $$oStanzaInfo{&INFO_SECTION_STATUS} =
- {
- &INFO_KEY_CODE => INFO_STANZA_STATUS_MISSING_STANZA_DATA_CODE,
- &INFO_KEY_MESSAGE => INFO_STANZA_STATUS_MISSING_STANZA_DATA_MESSAGE
- };
-
- $$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP} = [];
- $$oStanzaInfo{&INFO_BACKUP_SECTION_DB} = [];
- }
- else
- {
- # Get the current DB info (always last element in the array)
- my $hDbCurrent = @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}[-1];
- my $strDbCurrentVersion = $hDbCurrent->{&INFO_KEY_VERSION};
- my $ullDbCurrentSystemId = $hDbCurrent->{&INFO_KEY_SYSTEM_ID};
-
- # Loop through the DB history from oldest to newest
- foreach my $hDbInfo (@{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}})
- {
- my $strArchiveStanzaPath = "archive/" . $strStanzaFound;
- my $strDbVersion = $hDbInfo->{&INFO_KEY_VERSION};
- my $ullDbSysId = $hDbInfo->{&INFO_KEY_SYSTEM_ID};
-
- # With multiple DB versions, the backup.info history-id may not be the same as archive.info history-id, so the
- # archive path must be built by retrieving the archive id given the db version and system id of the backup
- my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet($strArchiveStanzaPath));
- my $strArchiveId = $oArchiveInfo->archiveId({strDbVersion => $hDbInfo->{&INFO_KEY_VERSION},
- ullDbSysId => $hDbInfo->{&INFO_KEY_SYSTEM_ID}});
- my $strArchivePath = "archive/${strStanzaFound}/${strArchiveId}";
-
- # Fill in the archive info if available
- my $hDbArchive = $self->dbArchiveSection($hDbInfo, $strArchiveId, $strArchivePath, $strDbCurrentVersion,
- $ullDbCurrentSystemId);
-
- if (defined($hDbArchive))
- {
- push(@oyDbArchiveList, $hDbArchive);
- }
- }
- }
-
- # Store the archive min/max for each database in the archive section
- $oStanzaInfo->{&INFO_SECTION_ARCHIVE} = \@oyDbArchiveList;
-
- push @oyStanzaList, $oStanzaInfo;
- }
-
- if (defined($strStanza) && @oyStanzaList == 0)
- {
- my $oStanzaInfo = {};
-
- $$oStanzaInfo{&INFO_STANZA_NAME} = $strStanza;
-
- $$oStanzaInfo{&INFO_SECTION_STATUS} =
- {
- &INFO_KEY_CODE => INFO_STANZA_STATUS_MISSING_STANZA_CODE,
- &INFO_KEY_MESSAGE => INFO_STANZA_STATUS_MISSING_STANZA_MESSAGE
- };
-
- $$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP} = [];
- $$oStanzaInfo{&INFO_BACKUP_SECTION_DB} = [];
-
- push @oyStanzaList, $oStanzaInfo;
- }
- }
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'oyStanzaList', value => \@oyStanzaList, log => false, ref => true}
- );
-}
-
-####################################################################################################################################
-# backupList
-###################################################################################################################################
-sub backupList
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $strStanza
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->backupList', \@_,
- {name => 'strStanza'}
- );
-
- # Load the backup.info but do not attempt to validate it
- my $oBackupInfo = undef;
-
- # Turn off console logging to control when to display the error
- logDisable();
-
- eval
- {
- $oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(cfgCommandName(CFGCMD_BACKUP) . "/${strStanza}"), false);
- logEnable();
- return true;
- }
- or do
- {
- logEnable();
-
- if (exceptionCode($EVAL_ERROR) == ERROR_FILE_MISSING)
- {
- return;
- }
- elsif (exceptionCode($EVAL_ERROR) == ERROR_CRYPTO)
- {
- # Confess the encryption error with additional hint
- confess &log(ERROR, exceptionMessage($EVAL_ERROR) .
- "\nHINT: use option --stanza if encryption settings are different for the stanza than the global settings",
- ERROR_CRYPTO);
- }
- else
- {
- # Confess unhandled errors
- confess $EVAL_ERROR;
- }
- };
-
- # Build the db list
- my @oyDbList;
-
- foreach my $iHistoryId ($oBackupInfo->keys(INFO_BACKUP_SECTION_DB_HISTORY))
- {
- my $oDbHash =
- {
- &INFO_HISTORY_ID => $iHistoryId + 0,
- &INFO_DB_VERSION =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_DB_HISTORY, $iHistoryId, INFO_BACKUP_KEY_DB_VERSION),
- &INFO_SYSTEM_ID =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_DB_HISTORY, $iHistoryId, INFO_BACKUP_KEY_SYSTEM_ID)
- };
-
- push(@oyDbList, $oDbHash);
- }
-
- # Build the backup list
- my @oyBackupList;
-
- foreach my $strBackup ($oBackupInfo->keys(INFO_BACKUP_SECTION_BACKUP_CURRENT))
- {
- my $oBackupHash =
- {
- &INFO_SECTION_ARCHIVE =>
- {
- &INFO_KEY_START =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_ARCHIVE_START, false),
- &INFO_KEY_STOP =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_ARCHIVE_STOP, false),
- },
- &INFO_SECTION_BACKREST =>
- {
- &INFO_KEY_FORMAT =>
- $oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INI_KEY_FORMAT),
- &INFO_KEY_VERSION =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INI_KEY_VERSION)
- },
- &INFO_SECTION_DB =>
- {
- &INFO_KEY_ID =>
- $oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_HISTORY_ID)
- },
- &INFO_SECTION_INFO =>
- {
- &INFO_SECTION_REPO =>
- {
- # Size of the backup in the repository, taking compression into account
- &INFO_KEY_SIZE =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_REPO_SIZE),
- # Size of this backup only (does not include referenced backups like repo->size)
- &INFO_KEY_DELTA =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_REPO_SIZE_DELTA),
- },
- # Original database size
- &INFO_KEY_SIZE =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_SIZE),
- # Amount of database backed up (will be equal for full backups)
- &INFO_KEY_DELTA =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_SIZE_DELTA),
- },
- &INFO_SECTION_TIMESTAMP =>
- {
- &INFO_KEY_START =>
- $oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TIMESTAMP_START),
- &INFO_KEY_STOP =>
- $oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TIMESTAMP_STOP),
- },
- &INFO_KEY_LABEL => $strBackup,
- &INFO_KEY_PRIOR =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_PRIOR, false),
- &INFO_KEY_REFERENCE =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_REFERENCE, false),
- &INFO_KEY_TYPE =>
- $oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TYPE)
- };
-
- push(@oyBackupList, $oBackupHash);
- }
-
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'oyBackupList', value => \@oyBackupList, log => false, ref => true},
- {name => 'oyDbList', value => \@oyDbList, log => false, ref => true}
- );
-}
-
-####################################################################################################################################
-# dbArchiveSection - fills the archive section for a db. Note this is a function in order to aid unit test coverage.
-####################################################################################################################################
-sub dbArchiveSection
-{
- my $self = shift;
-
- # Assign function parameters, defaults, and log debug info
- my
- (
- $strOperation,
- $hDbInfo,
- $strArchiveId,
- $strArchivePath,
- $strDbCurrentVersion,
- $ullDbCurrentSystemId,
- ) =
- logDebugParam
- (
- __PACKAGE__ . '->dbArchiveSection', \@_,
- {name => 'hDbInfo'},
- {name => 'strArchiveId'},
- {name => 'strArchivePath'},
- {name => 'strDbCurrentVersion'},
- {name => 'ullDbCurrentSystemId'},
- );
-
- my $hDbArchive = undef;
- my $strArchiveStart = undef;
- my $strArchiveStop = undef;
-
- if (storageRepo()->pathExists($strArchivePath))
- {
- my @stryWalMajor = storageRepo()->list($strArchivePath, {strExpression => '^[0-F]{16}$'});
-
- # Get first WAL segment
- foreach my $strWalMajor (@stryWalMajor)
- {
- my @stryWalFile = storageRepo()->list(
- "${strArchivePath}/${strWalMajor}",
- {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$"});
-
- if (@stryWalFile > 0)
- {
- $strArchiveStart = substr($stryWalFile[0], 0, 24);
- last;
- }
- }
-
- # Get last WAL segment
- foreach my $strWalMajor (sort({$b cmp $a} @stryWalMajor))
- {
- my @stryWalFile = storageRepo()->list(
- "${strArchivePath}/${strWalMajor}",
- {strExpression => "^[0-F]{24}-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$", strSortOrder => 'reverse'});
-
- if (@stryWalFile > 0)
- {
- $strArchiveStop = substr($stryWalFile[0], 0, 24);
- last;
- }
- }
- }
-
- # If there is an archive or the database is the current database then store it
- if (($strDbCurrentVersion eq $hDbInfo->{&INFO_KEY_VERSION} &&
- $ullDbCurrentSystemId == $hDbInfo->{&INFO_KEY_SYSTEM_ID}) ||
- defined($strArchiveStart) )
- {
- $hDbArchive =
- {
- &INFO_KEY_ID => $strArchiveId,
- &INFO_KEY_MIN => $strArchiveStart,
- &INFO_KEY_MAX => $strArchiveStop,
- &INFO_SECTION_DB =>
- {
- &INFO_HISTORY_ID => $hDbInfo->{&INFO_HISTORY_ID} + 0,
- },
- };
- }
- # Return from function and log return values if any
- return logDebugReturn
- (
- $strOperation,
- {name => 'hDbArchive', value => $hDbArchive, trace => true},
- );
-}
-
-1;
diff --git a/lib/pgBackRest/Protocol/Helper.pm b/lib/pgBackRest/Protocol/Helper.pm
index f71876b41..6ab3660e3 100644
--- a/lib/pgBackRest/Protocol/Helper.pm
+++ b/lib/pgBackRest/Protocol/Helper.pm
@@ -66,10 +66,6 @@ use constant OP_STORAGE_MOVE => 'storageM
use constant OP_STORAGE_PATH_GET => 'storagePathGet';
push @EXPORT, qw(OP_STORAGE_PATH_GET);
-# Info module
-use constant OP_INFO_STANZA_LIST => 'infoStanzList';
- push @EXPORT, qw(OP_INFO_STANZA_LIST);
-
# Restore module
use constant OP_RESTORE_FILE => 'restoreFile';
push @EXPORT, qw(OP_RESTORE_FILE);
diff --git a/lib/pgBackRest/Protocol/Remote/Minion.pm b/lib/pgBackRest/Protocol/Remote/Minion.pm
index 8415abfe1..64d48173a 100644
--- a/lib/pgBackRest/Protocol/Remote/Minion.pm
+++ b/lib/pgBackRest/Protocol/Remote/Minion.pm
@@ -19,7 +19,6 @@ use pgBackRest::Archive::Push::File;
use pgBackRest::Check::Check;
use pgBackRest::Config::Config;
use pgBackRest::Db;
-use pgBackRest::Info;
use pgBackRest::Protocol::Command::Minion;
use pgBackRest::Protocol::Helper;
use pgBackRest::Protocol::Storage::Helper;
@@ -71,7 +70,6 @@ sub init
my $oStorage = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_DB) ? storageDb() : storageRepo();
my $oCheck = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) ? new pgBackRest::Check::Check() : undef;
- my $oInfo = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) ? new pgBackRest::Info() : undef;
my $oDb = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_DB) ? new pgBackRest::Db() : undef;
# Create anonymous subs for each command
@@ -122,9 +120,6 @@ sub init
&OP_STORAGE_PATH_GET => sub {$oStorage->pathGet(@{shift()})},
&OP_STORAGE_HASH_SIZE => sub {$oStorage->hashSize(@{shift()})},
- # Info commands
- &OP_INFO_STANZA_LIST => sub {$oInfo->stanzaList(@{shift()})},
-
# Wait command
&OP_WAIT => sub {waitRemainder(@{shift()})},
};
diff --git a/src/command/info/info.c b/src/command/info/info.c
index dcf462083..8e41b0269 100644
--- a/src/command/info/info.c
+++ b/src/command/info/info.c
@@ -636,13 +636,7 @@ cmdInfo(void)
MEM_CONTEXT_TEMP_BEGIN()
{
- if (!cfgOptionTest(cfgOptRepoHost)) // {uncovered - Perl code is covered in integration tests}
- {
- ioHandleWriteOneStr(STDOUT_FILENO, infoRender());
- }
- // Else do it in Perl
- else
- perlExec(); // {+uncovered}
+ ioHandleWriteOneStr(STDOUT_FILENO, infoRender());
}
MEM_CONTEXT_TEMP_END();
diff --git a/src/main.c b/src/main.c
index 3fd3c4d36..2e7dcddf7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -97,6 +97,13 @@ main(int argListSize, const char *argList[])
perlExec();
}
+ // Info command
+ // -------------------------------------------------------------------------------------------------------------------------
+ else if (cfgCommand() == cfgCmdInfo)
+ {
+ cmdInfo();
+ }
+
// Execute Perl for commands not implemented in C
// -------------------------------------------------------------------------------------------------------------------------
else
diff --git a/src/perl/embed.auto.c b/src/perl/embed.auto.c
index 70ea9d4f1..4992e9556 100644
--- a/src/perl/embed.auto.c
+++ b/src/perl/embed.auto.c
@@ -10320,678 +10320,6 @@ static const EmbeddedModule embeddedModule[] =
"\n"
"1;\n"
},
- {
- .name = "pgBackRest/Info.pm",
- .data =
- "\n\n\n"
- "package pgBackRest::Info;\n"
- "\n"
- "use strict;\n"
- "use warnings FATAL => qw(all);\n"
- "use Carp qw(confess);\n"
- "\n"
- "use English '-no_match_vars';\n"
- "use Exporter qw(import);\n"
- "our @EXPORT = qw();\n"
- "use File::Basename qw(dirname);\n"
- "\n"
- "use pgBackRest::Backup::Common;\n"
- "use pgBackRest::Backup::Info;\n"
- "use pgBackRest::Common::Exception;\n"
- "use pgBackRest::Common::Log;\n"
- "use pgBackRest::Common::Ini;\n"
- "use pgBackRest::Common::String;\n"
- "use pgBackRest::Backup::Common;\n"
- "use pgBackRest::Backup::Info;\n"
- "use pgBackRest::Config::Config;\n"
- "use pgBackRest::InfoCommon;\n"
- "use pgBackRest::Manifest;\n"
- "use pgBackRest::Protocol::Helper;\n"
- "use pgBackRest::Protocol::Storage::Helper;\n"
- "use pgBackRest::Storage::Helper;\n"
- "\n\n\n\n"
- "use constant INFO_SECTION_BACKREST => 'backrest';\n"
- "use constant INFO_SECTION_ARCHIVE => 'archive';\n"
- "use constant INFO_SECTION_DB => 'database';\n"
- "use constant INFO_SECTION_INFO => 'info';\n"
- "use constant INFO_SECTION_REPO => 'repository';\n"
- "use constant INFO_SECTION_TIMESTAMP => 'timestamp';\n"
- "use constant INFO_SECTION_STATUS => 'status';\n"
- "use constant INFO_SECTION_CIPHER => 'cipher';\n"
- "\n"
- "use constant INFO_STANZA_NAME => 'name';\n"
- "\n"
- "use constant INFO_STANZA_STATUS_OK => 'ok';\n"
- "use constant INFO_STANZA_STATUS_ERROR => 'error';\n"
- "\n"
- "use constant INFO_STANZA_STATUS_OK_CODE => 0;\n"
- "use constant INFO_STANZA_STATUS_OK_MESSAGE => INFO_STANZA_STATUS_OK;\n"
- "use constant INFO_STANZA_STATUS_MISSING_STANZA_CODE => 1;\n"
- "use constant INFO_STANZA_STATUS_MISSING_STANZA_MESSAGE => 'missing stanza path';\n"
- "use constant INFO_STANZA_STATUS_NO_BACKUP_CODE => 2;\n"
- "use constant INFO_STANZA_STATUS_NO_BACKUP_MESSAGE => 'no valid backups';\n"
- "use constant INFO_STANZA_STATUS_MISSING_STANZA_DATA_CODE => 3;\n"
- "use constant INFO_STANZA_STATUS_MISSING_STANZA_DATA_MESSAGE => 'missing stanza data';\n"
- "\n"
- "use constant INFO_KEY_CODE => 'code';\n"
- "use constant INFO_KEY_DELTA => 'delta';\n"
- "use constant INFO_KEY_FORMAT => 'format';\n"
- "use constant INFO_KEY_ID => INFO_HISTORY_ID;\n"
- "use constant INFO_KEY_LABEL => 'label';\n"
- "use constant INFO_KEY_MAX => 'max';\n"
- "use constant INFO_KEY_MIN => 'min';\n"
- "use constant INFO_KEY_MESSAGE => 'message';\n"
- "use constant INFO_KEY_PRIOR => 'prior';\n"
- "use constant INFO_KEY_REFERENCE => 'reference';\n"
- "use constant INFO_KEY_SIZE => 'size';\n"
- "use constant INFO_KEY_START => 'start';\n"
- "use constant INFO_KEY_STOP => 'stop';\n"
- "use constant INFO_KEY_SYSTEM_ID => INFO_SYSTEM_ID;\n"
- "use constant INFO_KEY_TYPE => 'type';\n"
- "use constant INFO_KEY_VERSION => INFO_DB_VERSION;\n"
- "\n\n\n\n"
- "sub new\n"
- "{\n"
- "my $class = shift;\n"
- "\n\n"
- "my $self = {};\n"
- "bless $self, $class;\n"
- "\n\n"
- "my ($strOperation) = logDebugParam(__PACKAGE__ . '->new');\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'self', value => $self}\n"
- ");\n"
- "}\n"
- "\n\n\n\n"
- "sub process\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my ($strOperation) = logDebugParam(__PACKAGE__ . '->process');\n"
- "\n\n"
- "my $strStanza = cfgOptionTest(CFGOPT_STANZA) ? cfgOption(CFGOPT_STANZA) : undef;\n"
- "\n\n"
- "my $oyStanzaList = $self->stanzaList($strStanza);\n"
- "\n"
- "if (cfgOptionTest(CFGOPT_OUTPUT, CFGOPTVAL_INFO_OUTPUT_TEXT))\n"
- "{\n"
- "my $strOutput = $self->formatText($oyStanzaList);\n"
- "\n"
- "if (defined($strOutput))\n"
- "{\n"
- "syswrite(*STDOUT, $strOutput);\n"
- "}\n"
- "else\n"
- "{\n"
- "syswrite(*STDOUT, \"No stanzas exist in the repository.\\n\");\n"
- "}\n"
- "}\n"
- "elsif (cfgOptionTest(CFGOPT_OUTPUT, CFGOPTVAL_INFO_OUTPUT_JSON))\n"
- "{\n"
- "my $oJSON = JSON::PP->new()->canonical()->pretty()->indent_length(4);\n"
- "$self->outputJSON($oJSON->encode($oyStanzaList));\n"
- "}\n"
- "else\n"
- "{\n"
- "confess &log(ASSERT, \"invalid info output option '\" . cfgOption(CFGOPT_OUTPUT) . \"'\");\n"
- "}\n"
- "\n\n"
- "return logDebugReturn($strOperation);\n"
- "}\n"
- "\n\n\n\n"
- "sub outputJSON\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$strJSON,\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->outputJSON', \\@_,\n"
- "{name => 'strJSON'},\n"
- ");\n"
- "\n"
- "syswrite(*STDOUT, $strJSON);\n"
- "\n\n\n"
- "if ($strJSON !~ /\\n$/)\n"
- "{\n"
- "syswrite(*STDOUT, \"\\n\");\n"
- "}\n"
- "}\n"
- "\n\n\n\n\n\n"
- "sub formatText\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$oyStanzaList,\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->formatText', \\@_,\n"
- "{name => 'oyStanzaList', trace => true},\n"
- ");\n"
- "\n"
- "my $strOutput;\n"
- "\n"
- "foreach my $oStanzaInfo (@{$oyStanzaList})\n"
- "{\n"
- "\n"
- "$strOutput .= (defined($strOutput) ? \"\\n\" : '') . $self->formatTextStanza($oStanzaInfo) . \"\\n\";\n"
- "\n\n"
- "my $hDbCurrent = @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}[-1];\n"
- "\n\n"
- "foreach my $hDbInfo (@{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}})\n"
- "{\n"
- "\n"
- "if ($hDbInfo->{&INFO_HISTORY_ID} == $hDbCurrent->{&INFO_HISTORY_ID})\n"
- "{\n"
- "$strOutput .= \"\\n db (current)\";\n"
- "}\n"
- "\n\n"
- "my $strOutputArchive;\n"
- "foreach my $hDbArchive (@{$oStanzaInfo->{&INFO_SECTION_ARCHIVE}})\n"
- "{\n"
- "if ($hDbArchive->{&INFO_SECTION_DB}{&INFO_HISTORY_ID} == $hDbInfo->{&INFO_HISTORY_ID})\n"
- "{\n"
- "\n"
- "$strOutputArchive .= \"\\n wal archive min/max (\" . $hDbArchive->{&INFO_KEY_ID} . \"): \";\n"
- "\n"
- "if (defined($hDbArchive->{&INFO_KEY_MIN}))\n"
- "{\n"
- "$strOutputArchive .= $hDbArchive->{&INFO_KEY_MIN} . ' / ' . $hDbArchive->{&INFO_KEY_MAX};\n"
- "}\n"
- "else\n"
- "{\n"
- "$strOutputArchive .= 'none present';\n"
- "}\n"
- "\n"
- "$strOutputArchive .= \"\\n\";\n"
- "}\n"
- "}\n"
- "\n\n"
- "my $strOutputBackup;\n"
- "foreach my $oBackupInfo (@{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}})\n"
- "{\n"
- "if ($oBackupInfo->{&INFO_SECTION_DB}{&INFO_KEY_ID} == $hDbInfo->{&INFO_HISTORY_ID})\n"
- "{\n"
- "$strOutputBackup .= \"\\n\" . $self->formatTextBackup($oBackupInfo) . \"\\n\";\n"
- "}\n"
- "}\n"
- "\n"
- "if (defined($strOutputArchive) || defined($strOutputBackup))\n"
- "{\n"
- "if ($hDbInfo->{&INFO_HISTORY_ID} != $hDbCurrent->{&INFO_HISTORY_ID})\n"
- "{\n"
- "$strOutput .= \"\\n db (prior)\";\n"
- "}\n"
- "\n"
- "if (defined($strOutputArchive))\n"
- "{\n"
- "$strOutput .= $strOutputArchive;\n"
- "}\n"
- "\n"
- "if (defined($strOutputBackup))\n"
- "{\n"
- "$strOutput .= $strOutputBackup;\n"
- "}\n"
- "}\n"
- "}\n"
- "}\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'strOutput', value => $strOutput, trace => true}\n"
- ");\n"
- "}\n"
- "\n\n\n\n\n\n"
- "sub formatTextStanza\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$oStanzaInfo,\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->formatTextStanza', \\@_,\n"
- "{name => 'oStanzaInfo', trace => true},\n"
- ");\n"
- "\n\n"
- "my $strOutput =\n"
- "'stanza: ' . $oStanzaInfo->{&INFO_STANZA_NAME} . \"\\n\" .\n"
- "\" status: \" . ($oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_CODE} == 0 ? INFO_STANZA_STATUS_OK :\n"
- "INFO_STANZA_STATUS_ERROR . ' (' . $oStanzaInfo->{&INFO_SECTION_STATUS}{&INFO_KEY_MESSAGE} . ')') .\n"
- "(defined($oStanzaInfo->{&INFO_SECTION_CIPHER}) ? \"\\n cipher: \" . $oStanzaInfo->{&INFO_SECTION_CIPHER} : '');\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'strOutput', value => $strOutput, trace => true}\n"
- ");\n"
- "}\n"
- "\n\n\n\n\n\n"
- "sub formatTextBackup\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$oBackupInfo,\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->formatTextBackup', \\@_,\n"
- "{name => 'oBackupInfo', trace => true},\n"
- ");\n"
- "\n"
- "my $strOutput =\n"
- "' ' . $$oBackupInfo{&INFO_KEY_TYPE} . ' backup: ' . $$oBackupInfo{&INFO_KEY_LABEL} . \"\\n\" .\n"
- "\n"
- "' timestamp start/stop: ' .\n"
- "timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_START}) .\n"
- "' / ' .\n"
- "timestampFormat(undef, $$oBackupInfo{&INFO_SECTION_TIMESTAMP}{&INFO_KEY_STOP}) . \"\\n\" .\n"
- "\n"
- "\" wal start/stop: \";\n"
- "\n"
- "if (defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_START}) &&\n"
- "defined($oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_STOP}))\n"
- "{\n"
- "$strOutput .=\n"
- "$oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_START} . ' / ' . $oBackupInfo->{&INFO_SECTION_ARCHIVE}{&INFO_KEY_STOP};\n"
- "}\n"
- "else\n"
- "{\n"
- "$strOutput .= 'n/a';\n"
- "}\n"
- "\n"
- "$strOutput .=\n"
- "\"\\n database size: \" .\n"
- "(defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) ?\n"
- "fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_SIZE}) : '') .\n"
- "', backup size: ' .\n"
- "(defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) ?\n"
- "fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_KEY_DELTA}) : '') . \"\\n\" .\n"
- "\n"
- "' repository size: ' .\n"
- "(defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) ?\n"
- "fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_SIZE}) : '') .\n"
- "', repository backup size: ' .\n"
- "(defined($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_DELTA}) ?\n"
- "fileSizeFormat($$oBackupInfo{&INFO_SECTION_INFO}{&INFO_SECTION_REPO}{&INFO_KEY_DELTA}) : '');\n"
- "\n\n"
- "if (defined($oBackupInfo->{&INFO_KEY_REFERENCE}) && @{$oBackupInfo->{&INFO_KEY_REFERENCE}} > 0)\n"
- "{\n"
- "$strOutput .= \"\\n backup reference list: \" . (join(', ', @{$$oBackupInfo{&INFO_KEY_REFERENCE}}));\n"
- "}\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'strOutput', value => $strOutput, trace => true}\n"
- ");\n"
- "}\n"
- "\n\n\n\n"
- "sub stanzaList\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$strStanza\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->stanzaList', \\@_,\n"
- "{name => 'strStanza', required => false}\n"
- ");\n"
- "\n"
- "my @oyStanzaList;\n"
- "\n\n"
- "if (!isRepoLocal())\n"
- "{\n"
- "@oyStanzaList = @{protocolGet(CFGOPTVAL_REMOTE_TYPE_BACKUP)->cmdExecute(OP_INFO_STANZA_LIST, [$strStanza], true)};\n"
- "}\n"
- "\n"
- "else\n"
- "{\n"
- "my @stryStanza = storageRepo()->list(cfgCommandName(CFGCMD_BACKUP), {bIgnoreMissing => true});\n"
- "\n"
- "foreach my $strStanzaFound (@stryStanza)\n"
- "{\n"
- "if (defined($strStanza) && $strStanza ne $strStanzaFound)\n"
- "{\n"
- "next;\n"
- "}\n"
- "\n"
- "my $oStanzaInfo = {};\n"
- "$$oStanzaInfo{&INFO_STANZA_NAME} = $strStanzaFound;\n"
- "($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}, $$oStanzaInfo{&INFO_BACKUP_SECTION_DB}) =\n"
- "$self->backupList($strStanzaFound);\n"
- "\n\n"
- "if (defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}) && @{$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}} == 0)\n"
- "{\n"
- "$$oStanzaInfo{&INFO_SECTION_STATUS} =\n"
- "{\n"
- "&INFO_KEY_CODE => INFO_STANZA_STATUS_NO_BACKUP_CODE,\n"
- "&INFO_KEY_MESSAGE => INFO_STANZA_STATUS_NO_BACKUP_MESSAGE\n"
- "};\n"
- "}\n"
- "\n"
- "elsif (defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}))\n"
- "{\n"
- "$$oStanzaInfo{&INFO_SECTION_STATUS} =\n"
- "{\n"
- "&INFO_KEY_CODE => INFO_STANZA_STATUS_OK_CODE,\n"
- "&INFO_KEY_MESSAGE => INFO_STANZA_STATUS_OK_MESSAGE\n"
- "};\n"
- "}\n"
- "\n"
- "$$oStanzaInfo{&INFO_SECTION_CIPHER} = defined(storageRepo({strStanza => $strStanzaFound})->cipherType()) ?\n"
- "storageRepo({strStanza => $strStanzaFound})->cipherType() : CFGOPTVAL_REPO_CIPHER_TYPE_NONE;\n"
- "\n\n"
- "my @oyDbArchiveList = ();\n"
- "\n"
- "if (!defined($$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP}))\n"
- "{\n"
- "$$oStanzaInfo{&INFO_SECTION_STATUS} =\n"
- "{\n"
- "&INFO_KEY_CODE => INFO_STANZA_STATUS_MISSING_STANZA_DATA_CODE,\n"
- "&INFO_KEY_MESSAGE => INFO_STANZA_STATUS_MISSING_STANZA_DATA_MESSAGE\n"
- "};\n"
- "\n"
- "$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP} = [];\n"
- "$$oStanzaInfo{&INFO_BACKUP_SECTION_DB} = [];\n"
- "}\n"
- "else\n"
- "{\n"
- "\n"
- "my $hDbCurrent = @{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}}[-1];\n"
- "my $strDbCurrentVersion = $hDbCurrent->{&INFO_KEY_VERSION};\n"
- "my $ullDbCurrentSystemId = $hDbCurrent->{&INFO_KEY_SYSTEM_ID};\n"
- "\n\n"
- "foreach my $hDbInfo (@{$oStanzaInfo->{&INFO_BACKUP_SECTION_DB}})\n"
- "{\n"
- "my $strArchiveStanzaPath = \"archive/\" . $strStanzaFound;\n"
- "my $strDbVersion = $hDbInfo->{&INFO_KEY_VERSION};\n"
- "my $ullDbSysId = $hDbInfo->{&INFO_KEY_SYSTEM_ID};\n"
- "\n\n\n"
- "my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet($strArchiveStanzaPath));\n"
- "my $strArchiveId = $oArchiveInfo->archiveId({strDbVersion => $hDbInfo->{&INFO_KEY_VERSION},\n"
- "ullDbSysId => $hDbInfo->{&INFO_KEY_SYSTEM_ID}});\n"
- "my $strArchivePath = \"archive/${strStanzaFound}/${strArchiveId}\";\n"
- "\n\n"
- "my $hDbArchive = $self->dbArchiveSection($hDbInfo, $strArchiveId, $strArchivePath, $strDbCurrentVersion,\n"
- "$ullDbCurrentSystemId);\n"
- "\n"
- "if (defined($hDbArchive))\n"
- "{\n"
- "push(@oyDbArchiveList, $hDbArchive);\n"
- "}\n"
- "}\n"
- "}\n"
- "\n\n"
- "$oStanzaInfo->{&INFO_SECTION_ARCHIVE} = \\@oyDbArchiveList;\n"
- "\n"
- "push @oyStanzaList, $oStanzaInfo;\n"
- "}\n"
- "\n"
- "if (defined($strStanza) && @oyStanzaList == 0)\n"
- "{\n"
- "my $oStanzaInfo = {};\n"
- "\n"
- "$$oStanzaInfo{&INFO_STANZA_NAME} = $strStanza;\n"
- "\n"
- "$$oStanzaInfo{&INFO_SECTION_STATUS} =\n"
- "{\n"
- "&INFO_KEY_CODE => INFO_STANZA_STATUS_MISSING_STANZA_CODE,\n"
- "&INFO_KEY_MESSAGE => INFO_STANZA_STATUS_MISSING_STANZA_MESSAGE\n"
- "};\n"
- "\n"
- "$$oStanzaInfo{&INFO_BACKUP_SECTION_BACKUP} = [];\n"
- "$$oStanzaInfo{&INFO_BACKUP_SECTION_DB} = [];\n"
- "\n"
- "push @oyStanzaList, $oStanzaInfo;\n"
- "}\n"
- "}\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'oyStanzaList', value => \\@oyStanzaList, log => false, ref => true}\n"
- ");\n"
- "}\n"
- "\n\n\n\n"
- "sub backupList\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$strStanza\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->backupList', \\@_,\n"
- "{name => 'strStanza'}\n"
- ");\n"
- "\n\n"
- "my $oBackupInfo = undef;\n"
- "\n\n"
- "logDisable();\n"
- "\n"
- "eval\n"
- "{\n"
- "$oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(cfgCommandName(CFGCMD_BACKUP) . \"/${strStanza}\"), false);\n"
- "logEnable();\n"
- "return true;\n"
- "}\n"
- "or do\n"
- "{\n"
- "logEnable();\n"
- "\n"
- "if (exceptionCode($EVAL_ERROR) == ERROR_FILE_MISSING)\n"
- "{\n"
- "return;\n"
- "}\n"
- "elsif (exceptionCode($EVAL_ERROR) == ERROR_CRYPTO)\n"
- "{\n"
- "\n"
- "confess &log(ERROR, exceptionMessage($EVAL_ERROR) .\n"
- "\"\\nHINT: use option --stanza if encryption settings are different for the stanza than the global settings\",\n"
- "ERROR_CRYPTO);\n"
- "}\n"
- "else\n"
- "{\n"
- "\n"
- "confess $EVAL_ERROR;\n"
- "}\n"
- "};\n"
- "\n\n"
- "my @oyDbList;\n"
- "\n"
- "foreach my $iHistoryId ($oBackupInfo->keys(INFO_BACKUP_SECTION_DB_HISTORY))\n"
- "{\n"
- "my $oDbHash =\n"
- "{\n"
- "&INFO_HISTORY_ID => $iHistoryId + 0,\n"
- "&INFO_DB_VERSION =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_DB_HISTORY, $iHistoryId, INFO_BACKUP_KEY_DB_VERSION),\n"
- "&INFO_SYSTEM_ID =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_DB_HISTORY, $iHistoryId, INFO_BACKUP_KEY_SYSTEM_ID)\n"
- "};\n"
- "\n"
- "push(@oyDbList, $oDbHash);\n"
- "}\n"
- "\n\n"
- "my @oyBackupList;\n"
- "\n"
- "foreach my $strBackup ($oBackupInfo->keys(INFO_BACKUP_SECTION_BACKUP_CURRENT))\n"
- "{\n"
- "my $oBackupHash =\n"
- "{\n"
- "&INFO_SECTION_ARCHIVE =>\n"
- "{\n"
- "&INFO_KEY_START =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_ARCHIVE_START, false),\n"
- "&INFO_KEY_STOP =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_ARCHIVE_STOP, false),\n"
- "},\n"
- "&INFO_SECTION_BACKREST =>\n"
- "{\n"
- "&INFO_KEY_FORMAT =>\n"
- "$oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INI_KEY_FORMAT),\n"
- "&INFO_KEY_VERSION =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INI_KEY_VERSION)\n"
- "},\n"
- "&INFO_SECTION_DB =>\n"
- "{\n"
- "&INFO_KEY_ID =>\n"
- "$oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_HISTORY_ID)\n"
- "},\n"
- "&INFO_SECTION_INFO =>\n"
- "{\n"
- "&INFO_SECTION_REPO =>\n"
- "{\n"
- "\n"
- "&INFO_KEY_SIZE =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_REPO_SIZE),\n"
- "\n"
- "&INFO_KEY_DELTA =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_REPO_SIZE_DELTA),\n"
- "},\n"
- "\n"
- "&INFO_KEY_SIZE =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_SIZE),\n"
- "\n"
- "&INFO_KEY_DELTA =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_BACKUP_SIZE_DELTA),\n"
- "},\n"
- "&INFO_SECTION_TIMESTAMP =>\n"
- "{\n"
- "&INFO_KEY_START =>\n"
- "$oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TIMESTAMP_START),\n"
- "&INFO_KEY_STOP =>\n"
- "$oBackupInfo->numericGet(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TIMESTAMP_STOP),\n"
- "},\n"
- "&INFO_KEY_LABEL => $strBackup,\n"
- "&INFO_KEY_PRIOR =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_PRIOR, false),\n"
- "&INFO_KEY_REFERENCE =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_REFERENCE, false),\n"
- "&INFO_KEY_TYPE =>\n"
- "$oBackupInfo->get(INFO_BACKUP_SECTION_BACKUP_CURRENT, $strBackup, INFO_BACKUP_KEY_TYPE)\n"
- "};\n"
- "\n"
- "push(@oyBackupList, $oBackupHash);\n"
- "}\n"
- "\n\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'oyBackupList', value => \\@oyBackupList, log => false, ref => true},\n"
- "{name => 'oyDbList', value => \\@oyDbList, log => false, ref => true}\n"
- ");\n"
- "}\n"
- "\n\n\n\n"
- "sub dbArchiveSection\n"
- "{\n"
- "my $self = shift;\n"
- "\n\n"
- "my\n"
- "(\n"
- "$strOperation,\n"
- "$hDbInfo,\n"
- "$strArchiveId,\n"
- "$strArchivePath,\n"
- "$strDbCurrentVersion,\n"
- "$ullDbCurrentSystemId,\n"
- ") =\n"
- "logDebugParam\n"
- "(\n"
- "__PACKAGE__ . '->dbArchiveSection', \\@_,\n"
- "{name => 'hDbInfo'},\n"
- "{name => 'strArchiveId'},\n"
- "{name => 'strArchivePath'},\n"
- "{name => 'strDbCurrentVersion'},\n"
- "{name => 'ullDbCurrentSystemId'},\n"
- ");\n"
- "\n"
- "my $hDbArchive = undef;\n"
- "my $strArchiveStart = undef;\n"
- "my $strArchiveStop = undef;\n"
- "\n"
- "if (storageRepo()->pathExists($strArchivePath))\n"
- "{\n"
- "my @stryWalMajor = storageRepo()->list($strArchivePath, {strExpression => '^[0-F]{16}$'});\n"
- "\n\n"
- "foreach my $strWalMajor (@stryWalMajor)\n"
- "{\n"
- "my @stryWalFile = storageRepo()->list(\n"
- "\"${strArchivePath}/${strWalMajor}\",\n"
- "{strExpression => \"^[0-F]{24}-[0-f]{40}(\\\\.\" . COMPRESS_EXT . \"){0,1}\\$\"});\n"
- "\n"
- "if (@stryWalFile > 0)\n"
- "{\n"
- "$strArchiveStart = substr($stryWalFile[0], 0, 24);\n"
- "last;\n"
- "}\n"
- "}\n"
- "\n\n"
- "foreach my $strWalMajor (sort({$b cmp $a} @stryWalMajor))\n"
- "{\n"
- "my @stryWalFile = storageRepo()->list(\n"
- "\"${strArchivePath}/${strWalMajor}\",\n"
- "{strExpression => \"^[0-F]{24}-[0-f]{40}(\\\\.\" . COMPRESS_EXT . \"){0,1}\\$\", strSortOrder => 'reverse'});\n"
- "\n"
- "if (@stryWalFile > 0)\n"
- "{\n"
- "$strArchiveStop = substr($stryWalFile[0], 0, 24);\n"
- "last;\n"
- "}\n"
- "}\n"
- "}\n"
- "\n\n"
- "if (($strDbCurrentVersion eq $hDbInfo->{&INFO_KEY_VERSION} &&\n"
- "$ullDbCurrentSystemId == $hDbInfo->{&INFO_KEY_SYSTEM_ID}) ||\n"
- "defined($strArchiveStart) )\n"
- "{\n"
- "$hDbArchive =\n"
- "{\n"
- "&INFO_KEY_ID => $strArchiveId,\n"
- "&INFO_KEY_MIN => $strArchiveStart,\n"
- "&INFO_KEY_MAX => $strArchiveStop,\n"
- "&INFO_SECTION_DB =>\n"
- "{\n"
- "&INFO_HISTORY_ID => $hDbInfo->{&INFO_HISTORY_ID} + 0,\n"
- "},\n"
- "};\n"
- "}\n"
- "\n"
- "return logDebugReturn\n"
- "(\n"
- "$strOperation,\n"
- "{name => 'hDbArchive', value => $hDbArchive, trace => true},\n"
- ");\n"
- "}\n"
- "\n"
- "1;\n"
- },
{
.name = "pgBackRest/InfoCommon.pm",
.data =
@@ -13701,9 +13029,6 @@ static const EmbeddedModule embeddedModule[] =
"use constant OP_STORAGE_PATH_GET => 'storagePathGet';\n"
"push @EXPORT, qw(OP_STORAGE_PATH_GET);\n"
"\n\n"
- "use constant OP_INFO_STANZA_LIST => 'infoStanzList';\n"
- "push @EXPORT, qw(OP_INFO_STANZA_LIST);\n"
- "\n\n"
"use constant OP_RESTORE_FILE => 'restoreFile';\n"
"push @EXPORT, qw(OP_RESTORE_FILE);\n"
"\n\n"
@@ -14833,7 +14158,6 @@ static const EmbeddedModule embeddedModule[] =
"use pgBackRest::Check::Check;\n"
"use pgBackRest::Config::Config;\n"
"use pgBackRest::Db;\n"
- "use pgBackRest::Info;\n"
"use pgBackRest::Protocol::Command::Minion;\n"
"use pgBackRest::Protocol::Helper;\n"
"use pgBackRest::Protocol::Storage::Helper;\n"
@@ -14874,7 +14198,6 @@ static const EmbeddedModule embeddedModule[] =
"my $oStorage = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_DB) ? storageDb() : storageRepo();\n"
"\n"
"my $oCheck = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) ? new pgBackRest::Check::Check() : undef;\n"
- "my $oInfo = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) ? new pgBackRest::Info() : undef;\n"
"my $oDb = cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_DB) ? new pgBackRest::Db() : undef;\n"
"\n\n"
"my $hCommandMap =\n"
@@ -14919,8 +14242,6 @@ static const EmbeddedModule embeddedModule[] =
"&OP_STORAGE_PATH_GET => sub {$oStorage->pathGet(@{shift()})},\n"
"&OP_STORAGE_HASH_SIZE => sub {$oStorage->hashSize(@{shift()})},\n"
"\n\n"
- "&OP_INFO_STANZA_LIST => sub {$oInfo->stanzaList(@{shift()})},\n"
- "\n\n"
"&OP_WAIT => sub {waitRemainder(@{shift()})},\n"
"};\n"
"\n\n"
diff --git a/test/define.yaml b/test/define.yaml
index b9a523f55..3b9603301 100644
--- a/test/define.yaml
+++ b/test/define.yaml
@@ -582,13 +582,6 @@ unit:
- name: info
test:
- # ----------------------------------------------------------------------------------------------------------------------------
- - name: unit-perl
- total: 2
-
- coverage:
- Info: full
-
# ----------------------------------------------------------------------------------------------------------------------------
- name: info
total: 1
diff --git a/test/expect/mock-all-001.log b/test/expect/mock-all-001.log
index 96d8a8015..7f0695ebe 100644
--- a/test/expect/mock-all-001.log
+++ b/test/expect/mock-all-001.log
@@ -4951,7 +4951,7 @@ stanza: db
timestamp start/stop: [TIMESTAMP-STR]
wal start/stop: n/a
database size: 176KB, backup size: 176KB
- repository size: 2.3KB, repository backup size: 2.3KB
+ repository size: 2.4KB, repository backup size: 2.4KB
info db stanza - normal output (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --stanza=db --output=json info
@@ -5599,7 +5599,7 @@ stanza: db
timestamp start/stop: [TIMESTAMP-STR]
wal start/stop: n/a
database size: 176KB, backup size: 176KB
- repository size: 2.3KB, repository backup size: 2.3KB
+ repository size: 2.4KB, repository backup size: 2.4KB
diff backup: [BACKUP-DIFF-5]
timestamp start/stop: [TIMESTAMP-STR]
diff --git a/test/expect/mock-all-003.log b/test/expect/mock-all-003.log
index 72fe7483e..80b49ed77 100644
--- a/test/expect/mock-all-003.log
+++ b/test/expect/mock-all-003.log
@@ -2589,7 +2589,7 @@ stanza: db
timestamp start/stop: [TIMESTAMP-STR]
wal start/stop: n/a
database size: 160KB, backup size: 41B
- repository size: 160.6KB, repository backup size: 192B
+ repository size: 160.7KB, repository backup size: 192B
backup reference list: [BACKUP-FULL-2]
incr backup: [BACKUP-INCR-3]
@@ -3179,7 +3179,7 @@ stanza: db
timestamp start/stop: [TIMESTAMP-STR]
wal start/stop: n/a
database size: 144.1KB, backup size: 9B
- repository size: 2.5KB, repository backup size: 48B
+ repository size: 2.6KB, repository backup size: 48B
backup reference list: [BACKUP-FULL-3]
info all stanzas - normal output (db-master host)
diff --git a/test/lib/pgBackRestTest/Module/Info/InfoUnitPerlTest.pm b/test/lib/pgBackRestTest/Module/Info/InfoUnitPerlTest.pm
deleted file mode 100644
index 8a13d7127..000000000
--- a/test/lib/pgBackRestTest/Module/Info/InfoUnitPerlTest.pm
+++ /dev/null
@@ -1,502 +0,0 @@
-####################################################################################################################################
-# Unit tests for Info module
-####################################################################################################################################
-package pgBackRestTest::Module::Info::InfoUnitPerlTest;
-use parent 'pgBackRestTest::Env::HostEnvTest';
-
-####################################################################################################################################
-# Perl includes
-####################################################################################################################################
-use strict;
-use warnings FATAL => qw(all);
-use Carp qw(confess);
-use English '-no_match_vars';
-
-use File::Basename qw(dirname);
-use Storable qw(dclone);
-
-use pgBackRest::Backup::Common;
-use pgBackRest::Backup::Info;
-use pgBackRest::Common::Exception;
-use pgBackRest::Common::Lock;
-use pgBackRest::Common::Log;
-use pgBackRest::Config::Config;
-use pgBackRest::DbVersion;
-use pgBackRest::Info;
-use pgBackRest::InfoCommon;
-use pgBackRest::Manifest;
-use pgBackRest::Protocol::Helper;
-use pgBackRest::Protocol::Storage::Helper;
-use pgBackRest::Storage::Local;
-
-use pgBackRestTest::Common::ExecuteTest;
-use pgBackRestTest::Common::RunTest;
-use pgBackRestTest::Env::ExpireEnvTest;
-use pgBackRestTest::Common::FileTest;
-use pgBackRestTest::Env::Host::HostBackupTest;
-use pgBackRestTest::Env::HostEnvTest;
-
-####################################################################################################################################
-# initModule
-####################################################################################################################################
-use constant STANZA_ENCRYPT => 'encrypt';
-
-####################################################################################################################################
-# initModule
-####################################################################################################################################
-sub initModule
-{
- my $self = shift;
-
- $self->{strRepoPath} = $self->testPath() . '/repo';
- $self->{strArchivePath} = "$self->{strRepoPath}/archive/" . $self->stanza();
- $self->{strBackupPath} = "$self->{strRepoPath}/backup/" . $self->stanza();
- $self->{strDbPath} = $self->testPath() . '/db';
- $self->{strArchivePathEncrypt} = "$self->{strRepoPath}/archive/" . STANZA_ENCRYPT;
- $self->{strBackupPathEncrypt} = "$self->{strRepoPath}/backup/" . STANZA_ENCRYPT;
-}
-
-####################################################################################################################################
-# initTest
-####################################################################################################################################
-sub initTest
-{
- my $self = shift;
-
- # Create parent path for pg_control
- storageTest()->pathCreate(($self->{strDbPath} . '/' . DB_PATH_GLOBAL), {bCreateParent => true});
-
- # Create archive info path
- storageTest()->pathCreate($self->{strArchivePath}, {bIgnoreExists => true, bCreateParent => true});
-
- # Create backup info path
- storageTest()->pathCreate($self->{strBackupPath}, {bIgnoreExists => true, bCreateParent => true});
-}
-
-####################################################################################################################################
-# initStanzaCreate - initialize options and create the stanza object
-####################################################################################################################################
-sub initStanzaCreate
-{
- my $self = shift;
- my $strStanza = shift;
- my $bEncrypted = shift;
- my $strDbVersion = shift;
-
- # Set options for stanzaCreate
- my $rhConfig = $self->configTestClear();
-
- if (!defined($strStanza))
- {
- $strStanza = $self->stanza();
- }
-
- if (defined($bEncrypted) && $bEncrypted == true)
- {
- $self->optionTestSet(CFGOPT_REPO_CIPHER_TYPE, CFGOPTVAL_REPO_CIPHER_TYPE_AES_256_CBC);
- $self->optionTestSet(CFGOPT_REPO_CIPHER_PASS, 'x');
- }
-
- if (!defined($strDbVersion))
- {
- $strDbVersion = PG_VERSION_94;
- }
-
- $self->optionTestSet(CFGOPT_STANZA, $strStanza);
- $self->optionTestSet(CFGOPT_PG_PATH, $self->{strDbPath});
- $self->optionTestSet(CFGOPT_REPO_PATH, $self->{strRepoPath});
- $self->optionTestSet(CFGOPT_LOG_PATH, $self->testPath());
- $self->optionTestSetBool(CFGOPT_ONLINE, false);
- $self->optionTestSet(CFGOPT_DB_TIMEOUT, 5);
- $self->optionTestSet(CFGOPT_PROTOCOL_TIMEOUT, 6);
-
- $self->configTestLoad(CFGCMD_STANZA_CREATE);
- $self->configTestSet($rhConfig);
-
- my $oTestObject = "oExpireTest";
-
- # Create the test object
- if (defined($bEncrypted) && $bEncrypted == true)
- {
- $oTestObject = "oExpireTestEncrypt";
- }
-
- $self->{$oTestObject} = new pgBackRestTest::Env::ExpireEnvTest(undef, $self->backrestExe(), storageRepo(), undef, $self);
- $self->{$oTestObject}->stanzaCreate($strStanza, $strDbVersion);
-}
-
-####################################################################################################################################
-# initStanzaUpgrade - initialize options and create the stanza object
-####################################################################################################################################
-sub initStanzaUpgrade
-{
- my $self = shift;
-
- # Set options for stanzaCreate
- my $rhConfig = $self->configTestClear();
-
- $self->optionTestSet(CFGOPT_STANZA, $self->stanza());
- $self->optionTestSet(CFGOPT_PG_PATH, $self->{strDbPath});
- $self->optionTestSet(CFGOPT_REPO_PATH, $self->{strRepoPath});
- $self->optionTestSet(CFGOPT_LOG_PATH, $self->testPath());
- $self->optionTestSetBool(CFGOPT_ONLINE, false);
- $self->optionTestSet(CFGOPT_DB_TIMEOUT, 5);
- $self->optionTestSet(CFGOPT_PROTOCOL_TIMEOUT, 6);
-
- $self->configTestLoad(CFGCMD_STANZA_UPGRADE);
- $self->configTestSet($rhConfig);
-
- # Create the test object
- $self->{oExpireTest} = new pgBackRestTest::Env::ExpireEnvTest(undef, $self->backrestExe(), storageRepo(), undef, $self);
-
- $self->{oExpireTest}->stanzaUpgrade($self->stanza(), PG_VERSION_95);
-}
-
-####################################################################################################################################
-# run
-####################################################################################################################################
-sub run
-{
- my $self = shift;
-
- # Used to create backups and WAL to test
- use constant SECONDS_PER_DAY => 86400;
- my $lBaseTime = 1486137448 - (60 * SECONDS_PER_DAY);
-
- # Create the initial backup "day" number - backup day is incremented for each backup
- my $iLastBackup = 5;
-
- ################################################################################################################################
- if ($self->begin("Info"))
- {
- $self->configTestLoad(CFGCMD_INFO);
-
- my $oInfo = new pgBackRest::Info();
-
- # Output No stanzas exist in default text option
- #---------------------------------------------------------------------------------------------------------------------------
- $self->testResult(sub {$oInfo->process()}, undef, 'No stanzas exist and default text option');
-
- # Invalid option
- #---------------------------------------------------------------------------------------------------------------------------
- cfgOptionSet(CFGOPT_OUTPUT, BOGUS);
-
- $self->testException(sub {$oInfo->process()}, ERROR_ASSERT, "invalid info output option '" . BOGUS . "'");
-
- # Output json option with no stanza defined
- #---------------------------------------------------------------------------------------------------------------------------
- $self->optionTestSet(CFGOPT_OUTPUT, CFGOPTVAL_INFO_OUTPUT_JSON);
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->testResult(sub {$oInfo->process()}, undef, 'json option');
-
- # Add linefeed to JSON
- #---------------------------------------------------------------------------------------------------------------------------
- my $strJson = '[{"archive" : 1}]';
- $self->testResult(sub {$oInfo->outputJSON($strJson)}, 1, 'add linefeed to json');
-
- # Missing stanza path
- #---------------------------------------------------------------------------------------------------------------------------
- my $hyStanza = $oInfo->stanzaList(BOGUS);
-
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: bogus\n status: error (missing stanza path)\n",
- 'missing stanza path');
-
- # formatBackupText - coverage for certain conditions
- #---------------------------------------------------------------------------------------------------------------------------
- my $oBackupHash =
- {
- 'archive' =>
- {
- 'start' => 1,
- 'stop' => undef
- },
- 'timestamp' =>
- {
- 'start' => 1481039848,
- 'stop' => 1481039848,
- },
- 'label' => 'BACKUPLABEL',
- 'reference' => ['BACKUPREFERENCE'],
- 'type' => 'BACKUPTYPE',
- };
-
- $self->testResult(sub {$oInfo->formatTextBackup($oBackupHash)},
- " BACKUPTYPE backup: BACKUPLABEL\n" .
- " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" .
- " wal start/stop: n/a\n" .
- " database size: , backup size: \n" .
- " repository size: , repository backup size: \n" .
- " backup reference list: BACKUPREFERENCE",
- 'formatTextBackup');
-
- # Test !isRepoLocal branch
- #---------------------------------------------------------------------------------------------------------------------------
- cfgOptionSet(CFGOPT_REPO_HOST, false);
- cfgOptionSet(CFGOPT_REPO_HOST_CONFIG, BOGUS);
- $self->testException(sub {$oInfo->stanzaList(BOGUS)}, ERROR_ASSERT, "option repo1-host-cmd is required");
-
- # dbArchiveSection() -- no archive
- #---------------------------------------------------------------------------------------------------------------------------
- my $hDbInfo =
- {
- &INFO_HISTORY_ID => 1,
- &INFO_DB_VERSION => PG_VERSION_94,
- &INFO_SYSTEM_ID => $self->dbSysId(PG_VERSION_94),
- };
-
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94,
- $self->dbSysId(PG_VERSION_94))}, "{database => {id => 1}, id => 9.4-1, max => [undef], min => [undef]}",
- 'no archive, db-ver match, db-sys match');
-
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94,
- $self->dbSysId(PG_VERSION_95))}, undef, 'no archive, db-ver match, db-sys mismatch');
-
- $hDbInfo->{&INFO_DB_VERSION} = PG_VERSION_95;
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94,
- $self->dbSysId(PG_VERSION_94))}, undef, 'no archive, db-ver mismatch, db-sys match');
-
- $hDbInfo->{&INFO_SYSTEM_ID} = $self->dbSysId(PG_VERSION_95);
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, PG_VERSION_94 . '-1', $self->{strArchivePath}, PG_VERSION_94,
- $self->dbSysId(PG_VERSION_94))}, undef, 'no archive, db-ver mismatch, db-sys mismatch');
-
- # Create more than one stanza but no data
- #---------------------------------------------------------------------------------------------------------------------------
- $self->optionTestSet(CFGOPT_STANZA, $self->stanza());
- $self->optionTestSet(CFGOPT_REPO_PATH, $self->{strRepoPath});
- $self->configTestLoad(CFGCMD_INFO);
-
- # Create archive and backup paths but no info files
- storageTest()->pathCreate("$self->{strRepoPath}/archive/" . BOGUS, {bIgnoreExists => true, bCreateParent => true});
- storageTest()->pathCreate("$self->{strRepoPath}/backup/" . BOGUS, {bIgnoreExists => true, bCreateParent => true});
-
- # Get a list of all stanzas in the repo
- $hyStanza = $oInfo->stanzaList();
-
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: bogus\n status: error (missing stanza data)\n cipher: none\n\n" .
- "stanza: db\n status: error (missing stanza data)\n cipher: none\n",
- 'fomatText() multiple stanzas missing data');
-
- # Define the stanza option
- #---------------------------------------------------------------------------------------------------------------------------
- $self->optionTestSet(CFGOPT_STANZA, $self->stanza());
- $self->optionTestClear(CFGOPT_OUTPUT);
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->testResult(sub {$oInfo->process()}, undef, 'stanza set');
-
- # Create the stanza - no WAL or backups
- #---------------------------------------------------------------------------------------------------------------------------
- $self->initStanzaCreate();
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->testResult(sub {$oInfo->formatText($oInfo->stanzaList())},
- "stanza: bogus\n status: error (missing stanza data)\n cipher: none\n\n" .
- "stanza: db\n status: error (no valid backups)\n cipher: none\n\n" .
- " db (current)\n wal archive min/max (9.4-1): none present\n",
- "formatText() multiple stanzas, one missing data");
-
- $hyStanza = $oInfo->stanzaList($self->stanza());
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: db\n status: error (no valid backups)\n cipher: none\n\n" .
- " db (current)\n wal archive min/max (9.4-1): none present\n",
- "formatText() one stanza");
-
- # Create a backup and list backup for just one stanza
- #---------------------------------------------------------------------------------------------------------------------------
- $self->{oExpireTest}->backupCreate($self->stanza(), CFGOPTVAL_BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, -1, -1);
-
- $hyStanza = $oInfo->stanzaList($self->stanza());
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: db\n status: ok\n cipher: none\n\n db (current)\n wal archive min/max (9.4-1): none present\n\n" .
- " full backup: 20161206-155728F\n" .
- " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" .
- " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "formatText() one stanza");
-
- # Coverage for major WAL paths with no WAL
- #---------------------------------------------------------------------------------------------------------------------------
- storageTest()->pathCreate($self->{strArchivePath} . "/9.4-1/0000000100000000", {bIgnoreExists => true});
- storageTest()->pathCreate($self->{strArchivePath} . "/9.4-1/0000000200000000", {bIgnoreExists => true});
- $hyStanza = $oInfo->stanzaList($self->stanza());
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: db\n status: ok\n cipher: none\n\n db (current)\n wal archive min/max (9.4-1): none present\n\n" .
- " full backup: 20161206-155728F\n" .
- " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" .
- " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "formatText() major WAL paths with no WAL");
-
- # Upgrade postgres version and backup with WAL
- #---------------------------------------------------------------------------------------------------------------------------
- undef($self->{oExpireTest});
- $self->initStanzaUpgrade();
-
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->{oExpireTest}->backupCreate($self->stanza(), CFGOPTVAL_BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, 1, 1);
- $self->{oExpireTest}->backupCreate($self->stanza(), CFGOPTVAL_BACKUP_TYPE_DIFF, $lBaseTime += SECONDS_PER_DAY, 1, 1);
-
- # Remove the 9.4-1 path for condition test coverage
- storageTest()->remove($self->{strArchivePath} . "/9.4-1/", {bRecurse => true});
-
- $hyStanza = $oInfo->stanzaList($self->stanza());
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: db\n status: ok\n cipher: none\n" .
- "\n db (prior)\n" .
- " full backup: 20161206-155728F\n" .
- " timestamp start/stop: 2016-12-06 15:57:28 / 2016-12-06 15:57:28\n" .
- " wal start/stop: n/a\n" .
- " database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n" .
- "\n db (current)\n" .
- " wal archive min/max (9.5-2): 000000010000000000000000 / 000000010000000000000003\n\n" .
- " full backup: 20161207-155728F\n" .
- " timestamp start/stop: 2016-12-07 15:57:28 / 2016-12-07 15:57:28\n" .
- " wal start/stop: 000000010000000000000000 / 000000010000000000000000\n" .
- " database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n\n" .
- " diff backup: 20161207-155728F_20161208-155728D\n" .
- " timestamp start/stop: 2016-12-08 15:57:28 / 2016-12-08 15:57:28\n" .
- " wal start/stop: 000000010000000000000002 / 000000010000000000000002\n" .
- " database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "formatText() multiple DB versions");
-
- # Remove backup from db (prior)
- #---------------------------------------------------------------------------------------------------------------------------
- # Load the backup.info file
- my $oBackupInfo = new pgBackRest::Backup::Info($self->{strBackupPath});
- my @stryPath = $oBackupInfo->list(backupRegExpGet(true));
-
- # Remove the db prior full backup from the info file and save it
- $oBackupInfo->delete($stryPath[0]);
- $oBackupInfo->save();
-
- # Remove the backup directory
- storageTest()->remove($self->{strBackupPath} . "/" . $stryPath[0], {bRecurse => true});
-
- $hyStanza = $oInfo->stanzaList($self->stanza());
- $self->testResult(sub {$oInfo->formatText($hyStanza)},
- "stanza: db\n status: ok\n cipher: none\n" .
- "\n db (current)\n" .
- " wal archive min/max (9.5-2): 000000010000000000000000 / 000000010000000000000003\n\n" .
- " full backup: 20161207-155728F\n" .
- " timestamp start/stop: 2016-12-07 15:57:28 / 2016-12-07 15:57:28\n" .
- " wal start/stop: 000000010000000000000000 / 000000010000000000000000\n" .
- " database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n\n" .
- " diff backup: 20161207-155728F_20161208-155728D\n" .
- " timestamp start/stop: 2016-12-08 15:57:28 / 2016-12-08 15:57:28\n" .
- " wal start/stop: 000000010000000000000002 / 000000010000000000000002\n" .
- " database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "db (prior) removed");
-
- # dbArchiveSection() -- with archive
- #---------------------------------------------------------------------------------------------------------------------------
- $hDbInfo->{&INFO_HISTORY_ID} = 2;
- $hDbInfo->{&INFO_DB_VERSION} = PG_VERSION_95;
- $hDbInfo->{&INFO_SYSTEM_ID} = $self->dbSysId(PG_VERSION_95);
-
- my $strArchiveId = PG_VERSION_95 . '-2';
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId",
- PG_VERSION_95, $self->dbSysId(PG_VERSION_95))},
- "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}",
- 'archive, db-ver match, db-sys-id match');
-
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId",
- PG_VERSION_95, $self->dbSysId(PG_VERSION_94))},
- "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}",
- 'archive, db-ver match, db-sys-id mismatch');
-
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId",
- PG_VERSION_94, $self->dbSysId(PG_VERSION_95))},
- "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}",
- 'archive, db-ver mismatch, db-sys-id match');
-
- $self->testResult(sub {$oInfo->dbArchiveSection($hDbInfo, $strArchiveId, "$self->{strArchivePath}/$strArchiveId",
- PG_VERSION_94, $self->dbSysId(PG_VERSION_94))},
- "{database => {id => 2}, id => 9.5-2, max => 000000010000000000000003, min => 000000010000000000000000}",
- 'archive, db-ver mismatch, db-sys-id mismatch');
-
- # Set last backup run in this test set
- $iLastBackup = 8;
- }
-
- ################################################################################################################################
- if ($self->begin("Info - encryption"))
- {
- # create an unencrypted and an encrypted repo and run a backup in each
- #--------------------------------------------------------------------------------------------------------------------------
- $self->initStanzaCreate();
- $self->{oExpireTest}->backupCreate($self->stanza(), CFGOPTVAL_BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, -1, -1);
- $iLastBackup++;
- my $strUnencryptBackup = ($iLastBackup < 10) ? "0$iLastBackup" : $iLastBackup;
-
- $self->initStanzaCreate(STANZA_ENCRYPT, true);
- $self->{oExpireTestEncrypt}->backupCreate(
- STANZA_ENCRYPT, CFGOPTVAL_BACKUP_TYPE_FULL, $lBaseTime += SECONDS_PER_DAY, -1, -1);
- $iLastBackup++;
- my $strEncryptBackup = ($iLastBackup < 10) ? "0$iLastBackup" : $iLastBackup;;
-
- # Clear the main storage repo settings
- storageRepoCacheClear(STORAGE_REPO);
-
- # Clear the stanza setting and set the main storage repo basePath to the testing repo path
- $self->optionTestClear(CFGOPT_STANZA);
- $self->optionTestSet(CFGOPT_REPO_PATH, $self->{strRepoPath});
-
- # Recreate the main storage repo with default unencrypted repo setting and test basePath
- storageRepo();
-
- # Test the info command without option --stanza being configured
- #--------------------------------------------------------------------------------------------------------------------------
- $self->configTestLoad(CFGCMD_INFO);
- my $oInfo = new pgBackRest::Info();
-
- $self->testException(sub {$oInfo->stanzaList()}, ERROR_CRYPTO,
- "unable to parse '" . $self->{strBackupPathEncrypt} . "/backup.info'" .
- "\nHINT: Is or was the repo encrypted?" .
- "\nHINT: use option --stanza if encryption settings are different for the stanza than the global settings");
-
- # Test the info command with option --stanza configured
- #--------------------------------------------------------------------------------------------------------------------------
- $self->optionTestSet(CFGOPT_STANZA, $self->stanza());
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->testResult(sub {$oInfo->formatText($oInfo->stanzaList($self->stanza()))},
- "stanza: db\n status: ok\n cipher: none\n\n db (current)\n wal archive min/max (9.4-1): none present\n\n" .
- " full backup: 201612" . $strUnencryptBackup . "-155728F\n" .
- " timestamp start/stop: 2016-12-" . $strUnencryptBackup . " 15:57:28 / 2016-12-" . $strUnencryptBackup .
- " 15:57:28\n" .
- " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "formatText() unencrypted stanza");
-
- $self->optionTestSet(CFGOPT_STANZA, STANZA_ENCRYPT);
- $self->configTestLoad(CFGCMD_INFO);
-
- $self->testResult(sub {$oInfo->formatText($oInfo->stanzaList(STANZA_ENCRYPT))},
- "stanza: " . STANZA_ENCRYPT ."\n status: ok\n cipher: aes-256-cbc\n\n db (current)" .
- "\n wal archive min/max (9.4-1): none present\n\n" .
- " full backup: 201612" . $strEncryptBackup . "-155728F\n" .
- " timestamp start/stop: 2016-12-" . $strEncryptBackup . " 15:57:28 / 2016-12-" . $strEncryptBackup .
- " 15:57:28\n" .
- " wal start/stop: n/a\n database size: 0B, backup size: 0B\n" .
- " repository size: 0B, repository backup size: 0B\n",
- "formatText() encrypted stanza");
-
- # Change the permissions of the backup file so it cannot be read and confirm correct error reported
- #---------------------------------------------------------------------------------------------------------------------------
- forceStorageMode(
- storageRepo({strStanza => STANZA_ENCRYPT}), $self->{strBackupPathEncrypt} . "/backup.inf*", '220');
- $self->testException(sub {$oInfo->backupList(STANZA_ENCRYPT)}, ERROR_FILE_OPEN,
- "unable to open '" . $self->{strBackupPathEncrypt} . "/backup.info': Permission denied");
- }
-}
-
-1;
[parent: f79af47bd4ff]