mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-05 15:05:48 +02:00
All config options can now be provided on the command-line.
Lots of name changes, but more thought needed there. Still needs cleanup.
This commit is contained in:
parent
7675a11ded
commit
882f068254
@ -11,17 +11,12 @@ use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
use File::Basename;
|
||||
use Pod::Usage;
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Utility;
|
||||
use BackRest::Param;
|
||||
use BackRest::Config;
|
||||
use BackRest::Remote;
|
||||
use BackRest::File;
|
||||
use BackRest::Backup;
|
||||
use BackRest::Restore;
|
||||
use BackRest::Db;
|
||||
|
||||
####################################################################################################################################
|
||||
# Usage
|
||||
@ -102,10 +97,10 @@ sub remote_get
|
||||
{
|
||||
$oRemote = new BackRest::Remote
|
||||
(
|
||||
config_key_load($strRemote eq DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST, true),
|
||||
config_key_load($strRemote eq DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_USER, true),
|
||||
config_key_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_REMOTE, true),
|
||||
config_key_load(CONFIG_SECTION_GENERAL, CONFIG_KEY_BUFFER_SIZE, true),
|
||||
$strRemote eq DB ? optionGet(OPTION_DB_HOST) : optionGet(OPTION_BACKUP_HOST),
|
||||
$strRemote eq DB ? optionGet(OPTION_DB_USER) : optionGet(OPTION_BACKUP_USER),
|
||||
optionGet(OPTION_COMMAND_REMOTE),
|
||||
optionGet(OPTION_BUFFER_SIZE),
|
||||
$iCompressLevel, $iCompressLevelNetwork
|
||||
);
|
||||
|
||||
@ -118,7 +113,7 @@ sub remote_get
|
||||
$oLocal = new BackRest::Remote
|
||||
(
|
||||
undef, undef, undef,
|
||||
config_key_load(CONFIG_SECTION_GENERAL, CONFIG_KEY_BUFFER_SIZE, true),
|
||||
optionGet(OPTION_BUFFER_SIZE),
|
||||
$iCompressLevel, $iCompressLevelNetwork
|
||||
);
|
||||
}
|
||||
@ -168,18 +163,24 @@ eval {
|
||||
####################################################################################################################################
|
||||
# Load command line parameters and config
|
||||
####################################################################################################################################
|
||||
config_load();
|
||||
configLoad();
|
||||
|
||||
# Set the log levels
|
||||
log_level_set(optionGet(OPTION_LOG_LEVEL_FILE), optionGet(OPTION_LOG_LEVEL_CONSOLE));
|
||||
|
||||
# Set test options
|
||||
!optionGet(OPTION_TEST) or test_set(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY));
|
||||
|
||||
####################################################################################################################################
|
||||
# DETERMINE IF THERE IS A REMOTE
|
||||
####################################################################################################################################
|
||||
# First check if backup is remote
|
||||
if (defined(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST)))
|
||||
if (optionTest(OPTION_BACKUP_HOST))
|
||||
{
|
||||
$strRemote = BACKUP;
|
||||
}
|
||||
# Else check if db is remote
|
||||
elsif (defined(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_HOST)))
|
||||
elsif (optionTest(OPTION_DB_HOST))
|
||||
{
|
||||
# Don't allow both sides to be remote
|
||||
if (defined($strRemote))
|
||||
@ -206,22 +207,13 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
}
|
||||
|
||||
# If an archive section has been defined, use that instead of the backup section when operation is OP_ARCHIVE_PUSH
|
||||
my $bArchiveLocal = defined(config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_PATH));
|
||||
my $strSection = $bArchiveLocal ? CONFIG_SECTION_ARCHIVE : CONFIG_SECTION_BACKUP;
|
||||
my $strArchivePath = config_key_load($strSection, CONFIG_KEY_PATH);
|
||||
|
||||
# Get the async compress flag. If compress_async=y then compression is off for the initial push when archiving locally
|
||||
my $bCompressAsync = false;
|
||||
|
||||
if ($bArchiveLocal)
|
||||
{
|
||||
config_key_load($strSection, CONFIG_KEY_COMPRESS_ASYNC, true, 'n') eq 'n' ? false : true;
|
||||
}
|
||||
my $bArchiveAsync = optionTest(OPTION_ARCHIVE_ASYNC);
|
||||
my $strArchivePath = optionGet(OPTION_REPO_PATH);
|
||||
|
||||
# If logging locally then create the stop archiving file name
|
||||
my $strStopFile;
|
||||
|
||||
if ($bArchiveLocal)
|
||||
if ($bArchiveAsync)
|
||||
{
|
||||
$strStopFile = "${strArchivePath}/lock/" . optionGet(OPTION_STANZA) . "-archive.stop";
|
||||
}
|
||||
@ -240,16 +232,16 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
}
|
||||
|
||||
# Get the compress flag
|
||||
my $bCompress = $bCompressAsync ? false : config_key_load($strSection, CONFIG_KEY_COMPRESS, true, 'y') eq 'y' ? true : false;
|
||||
my $bCompress = $bArchiveAsync ? false : optionGet(OPTION_COMPRESS);
|
||||
|
||||
# Create the file object
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
optionGet(OPTION_STANZA),
|
||||
config_key_load($strSection, CONFIG_KEY_PATH, true),
|
||||
$bArchiveLocal ? NONE : $strRemote,
|
||||
remote_get($bArchiveLocal, config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL),
|
||||
config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL_NETWORK))
|
||||
$bArchiveAsync || $strRemote eq NONE ? optionGet(OPTION_REPO_PATH) : optionGet(OPTION_REPO_REMOTE_PATH),
|
||||
$bArchiveAsync ? NONE : $strRemote,
|
||||
remote_get($bArchiveAsync, optionGet(OPTION_COMPRESS_LEVEL),
|
||||
optionGet(OPTION_COMPRESS_LEVEL_NETWORK))
|
||||
);
|
||||
|
||||
# Init backup
|
||||
@ -262,38 +254,30 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
undef
|
||||
);
|
||||
|
||||
&log(INFO, 'pushing archive log ' . $ARGV[1] . ($bArchiveLocal ? ' asynchronously' : ''));
|
||||
&log(INFO, 'pushing archive log ' . $ARGV[1] . ($bArchiveAsync ? ' asynchronously' : ''));
|
||||
|
||||
archive_push(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_PATH), $ARGV[1]);
|
||||
archive_push(optionGet(OPTION_DB_PATH, false), $ARGV[1], $bArchiveAsync);
|
||||
|
||||
# Exit if we are archiving async
|
||||
if (!$bArchiveLocal)
|
||||
if (!$bArchiveAsync)
|
||||
{
|
||||
remote_exit(0);
|
||||
}
|
||||
|
||||
# Fork and exit the parent process so the async process can continue
|
||||
if (!optionTest(OPTION_TEST_NO_FORK))
|
||||
{
|
||||
if (fork())
|
||||
if (!optionTest(OPTION_TEST_NO_FORK) && fork())
|
||||
{
|
||||
remote_exit(0);
|
||||
}
|
||||
}
|
||||
# Else the no-fork flag has been specified for testing
|
||||
else
|
||||
{
|
||||
&log(INFO, 'No fork on archive local for TESTING');
|
||||
}
|
||||
}
|
||||
|
||||
# If no backup host is defined it makes no sense to run archive-push without a specified archive file so throw an error
|
||||
# if (!defined(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST)))
|
||||
# {
|
||||
# &log(ERROR, 'archive-push called without an archive file or backup host');
|
||||
# }
|
||||
|
||||
# Start the async archive push
|
||||
&log(INFO, 'starting async archive-push');
|
||||
}
|
||||
|
||||
# Create a lock file to make sure async archive-push does not run more than once
|
||||
my $strLockPath = "${strArchivePath}/lock/" . optionGet(OPTION_STANZA) . "-archive.lock";
|
||||
@ -308,19 +292,17 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
my $strCommand = $^X . ' ' . $0 . " --stanza=" . optionGet(OPTION_STANZA);
|
||||
|
||||
# Get the new operational flags
|
||||
my $bCompress = config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_COMPRESS, true, 'y') eq 'y' ? true : false;
|
||||
my $iArchiveMaxMB = config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_ARCHIVE_MAX_MB);
|
||||
my $bCompress = optionGet(OPTION_COMPRESS);
|
||||
my $iArchiveMaxMB = optionGet(OPTION_ARCHIVE_MAX_MB, false);
|
||||
|
||||
# eval
|
||||
# {
|
||||
# Create the file object
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
optionGet(OPTION_STANZA),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true),
|
||||
$strRemote eq NONE ? optionGet(OPTION_REPO_PATH) : optionGet(OPTION_REPO_REMOTE_PATH),
|
||||
$strRemote,
|
||||
remote_get(false, config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL),
|
||||
config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL_NETWORK))
|
||||
remote_get(false, optionGet(OPTION_COMPRESS_LEVEL),
|
||||
optionGet(OPTION_COMPRESS_LEVEL_NETWORK))
|
||||
);
|
||||
|
||||
# Init backup
|
||||
@ -331,9 +313,9 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
undef,
|
||||
$bCompress,
|
||||
undef,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX),
|
||||
1, #optionGet(OPTION_THREAD_MAX),
|
||||
undef,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT)
|
||||
optionGet(OPTION_THREAD_TIMEOUT, false)
|
||||
);
|
||||
|
||||
# Call the archive_xfer function and continue to loop as long as there are files to process
|
||||
@ -341,7 +323,7 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
|
||||
while (!defined($iLogTotal) || $iLogTotal > 0)
|
||||
{
|
||||
$iLogTotal = archive_xfer($strArchivePath . "/archive/" . optionGet(OPTION_STANZA), $strStopFile,
|
||||
$iLogTotal = archive_xfer($strArchivePath . "/archive/" . optionGet(OPTION_STANZA) . "/out", $strStopFile,
|
||||
$strCommand, $iArchiveMaxMB);
|
||||
|
||||
if ($iLogTotal > 0)
|
||||
@ -353,48 +335,6 @@ if (operationTest(OP_ARCHIVE_PUSH))
|
||||
&log(DEBUG, 'no more logs to transfer - exiting');
|
||||
}
|
||||
}
|
||||
#
|
||||
# };
|
||||
|
||||
# # If there were errors above then start compressing
|
||||
# if ($@)
|
||||
# {
|
||||
# if ($bCompressAsync)
|
||||
# {
|
||||
# &log(ERROR, "error during transfer: $@");
|
||||
# &log(WARN, "errors during transfer, starting compression");
|
||||
#
|
||||
# # Run file_init_archive - this is the minimal config needed to run archive pulling !!! need to close the old file
|
||||
# my $oFile = BackRest::File->new
|
||||
# (
|
||||
# # strStanza => $strStanza,
|
||||
# # bNoCompression => false,
|
||||
# # strBackupPath => config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true),
|
||||
# # strCommand => $0,
|
||||
# # strCommandCompress => config_key_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_COMPRESS, $bCompress),
|
||||
# # strCommandDecompress => config_key_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_DECOMPRESS, $bCompress)
|
||||
# );
|
||||
#
|
||||
# backup_init
|
||||
# (
|
||||
# undef,
|
||||
# $oFile,
|
||||
# undef,
|
||||
# $bCompress,
|
||||
# undef,
|
||||
# !$bChecksum,
|
||||
# config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX),
|
||||
# undef,
|
||||
# config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT)
|
||||
# );
|
||||
#
|
||||
# archive_compress($strArchivePath . "/archive/${strStanza}", $strCommand, 256);
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# confess $@;
|
||||
# }
|
||||
# }
|
||||
|
||||
lock_file_remove();
|
||||
remote_exit(0);
|
||||
@ -421,11 +361,11 @@ if (operationTest(OP_ARCHIVE_GET))
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
optionGet(OPTION_STANZA),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true),
|
||||
$strRemote eq BACKUP ? optionGet(OPTION_REPO_REMOTE_PATH) : optionGet(OPTION_REPO_PATH),
|
||||
$strRemote,
|
||||
remote_get(false,
|
||||
config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL),
|
||||
config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL_NETWORK))
|
||||
optionGet(OPTION_COMPRESS_LEVEL),
|
||||
optionGet(OPTION_COMPRESS_LEVEL_NETWORK))
|
||||
);
|
||||
|
||||
# Init the backup object
|
||||
@ -439,7 +379,7 @@ if (operationTest(OP_ARCHIVE_GET))
|
||||
&log(INFO, 'getting archive log ' . $ARGV[1]);
|
||||
|
||||
# Get the archive file
|
||||
remote_exit(archive_get(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_PATH), $ARGV[1], $ARGV[2]));
|
||||
remote_exit(archive_get(optionGet(OPTION_DB_PATH, false), $ARGV[1], $ARGV[2]));
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -448,11 +388,11 @@ if (operationTest(OP_ARCHIVE_GET))
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
optionGet(OPTION_STANZA),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true),
|
||||
$strRemote eq BACKUP ? optionGet(OPTION_REPO_REMOTE_PATH) : optionGet(OPTION_REPO_PATH),
|
||||
$strRemote,
|
||||
remote_get(false,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_COMPRESS_LEVEL),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_COMPRESS_LEVEL_NETWORK))
|
||||
optionGet(OPTION_COMPRESS_LEVEL),
|
||||
optionGet(OPTION_COMPRESS_LEVEL_NETWORK))
|
||||
);
|
||||
|
||||
####################################################################################################################################
|
||||
@ -466,20 +406,21 @@ if (operationTest(OP_RESTORE))
|
||||
}
|
||||
|
||||
# Open the log file
|
||||
log_file_set(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH, true) . '/log/' . optionGet(OPTION_STANZA) . '-restore');
|
||||
log_file_set(optionGet(OPTION_REPO_PATH) . '/log/' . optionGet(OPTION_STANZA) . '-restore');
|
||||
|
||||
# Set the lock path
|
||||
my $strLockPath = config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH, true) . '/lock/' .
|
||||
my $strLockPath = optionGet(OPTION_REPO_PATH) . '/lock/' .
|
||||
optionGet(OPTION_STANZA) . '-' . operationGet() . '.lock';
|
||||
|
||||
# Do the restore
|
||||
use BackRest::Restore;
|
||||
new BackRest::Restore
|
||||
(
|
||||
config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_PATH, true),
|
||||
optionGet(OPTION_DB_PATH),
|
||||
optionGet(OPTION_SET),
|
||||
config_section_load(CONFIG_SECTION_TABLESPACE_MAP),
|
||||
optionGet(OPTION_RESTORE_TABLESPACE_MAP, false),
|
||||
$oFile,
|
||||
config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_THREAD_MAX, true),
|
||||
optionGet(OPTION_THREAD_MAX),
|
||||
optionGet(OPTION_DELTA),
|
||||
optionGet(OPTION_FORCE),
|
||||
optionGet(OPTION_TYPE),
|
||||
@ -487,7 +428,7 @@ if (operationTest(OP_RESTORE))
|
||||
optionGet(OPTION_TARGET_EXCLUSIVE, false),
|
||||
optionGet(OPTION_TARGET_RESUME, false),
|
||||
optionGet(OPTION_TARGET_TIMELINE, false),
|
||||
config_section_load(CONFIG_SECTION_RECOVERY_OPTION),
|
||||
optionGet(OPTION_RESTORE_RECOVERY_SETTING, false),
|
||||
optionGet(OPTION_STANZA),
|
||||
$0,
|
||||
optionGet(OPTION_CONFIG)
|
||||
@ -500,7 +441,7 @@ if (operationTest(OP_RESTORE))
|
||||
# GET MORE CONFIG INFO
|
||||
####################################################################################################################################
|
||||
# Open the log file
|
||||
log_file_set(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true) . '/log/' . optionGet(OPTION_STANZA));
|
||||
log_file_set(optionGet(OPTION_REPO_PATH) . '/log/' . optionGet(OPTION_STANZA));
|
||||
|
||||
# Make sure backup and expire operations happen on the backup side
|
||||
if ($strRemote eq BACKUP)
|
||||
@ -509,11 +450,10 @@ if ($strRemote eq BACKUP)
|
||||
}
|
||||
|
||||
# Get the operational flags
|
||||
my $bCompress = config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_COMPRESS, true, 'y') eq 'y' ? true : false;
|
||||
my $bCompress = optionGet(OPTION_COMPRESS);
|
||||
|
||||
# Set the lock path
|
||||
my $strLockPath = config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true) . '/lock/' .
|
||||
optionGet(OPTION_STANZA) . '-' . operationGet() . '.lock';
|
||||
my $strLockPath = optionGet(OPTION_REPO_PATH) . '/lock/' . optionGet(OPTION_STANZA) . '-' . operationGet() . '.lock';
|
||||
|
||||
if (!lock_file_create($strLockPath))
|
||||
{
|
||||
@ -522,15 +462,16 @@ if (!lock_file_create($strLockPath))
|
||||
}
|
||||
|
||||
# Initialize the db object
|
||||
use BackRest::Db;
|
||||
my $oDb;
|
||||
|
||||
if (!optionGet(OPTION_NO_START_STOP))
|
||||
{
|
||||
$oDb = new BackRest::Db
|
||||
(
|
||||
config_key_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_PSQL),
|
||||
config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_HOST),
|
||||
config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_USER)
|
||||
optionGet(OPTION_COMMAND_PSQL),
|
||||
optionGet(OPTION_DB_HOST, false),
|
||||
optionGet(OPTION_DB_USER, optionTest(OPTION_DB_HOST))
|
||||
);
|
||||
}
|
||||
|
||||
@ -540,11 +481,11 @@ backup_init
|
||||
$oDb,
|
||||
$oFile,
|
||||
optionGet(OPTION_TYPE),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_COMPRESS, true, 'y') eq 'y' ? true : false,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_HARDLINK, true, 'y') eq 'y' ? true : false,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_ARCHIVE_REQUIRED, true, 'y') eq 'y' ? true : false,
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT),
|
||||
optionGet(OPTION_COMPRESS),
|
||||
optionGet(OPTION_HARDLINK),
|
||||
optionGet(OPTION_THREAD_MAX),
|
||||
optionGet(OPTION_ARCHIVE_REQUIRED),
|
||||
optionGet(OPTION_THREAD_TIMEOUT, false),
|
||||
optionGet(OPTION_NO_START_STOP),
|
||||
optionTest(OPTION_FORCE)
|
||||
);
|
||||
@ -554,8 +495,8 @@ backup_init
|
||||
####################################################################################################################################
|
||||
if (operationTest(OP_BACKUP))
|
||||
{
|
||||
backup(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_PATH),
|
||||
config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_START_FAST, true, 'n') eq 'y' ? true : false);
|
||||
use BackRest::Backup;
|
||||
backup(optionGet(OPTION_DB_PATH), optionGet(OPTION_START_FAST));
|
||||
|
||||
operationSet(OP_EXPIRE);
|
||||
}
|
||||
@ -568,10 +509,10 @@ if (operationTest(OP_EXPIRE))
|
||||
backup_expire
|
||||
(
|
||||
$oFile->path_get(PATH_BACKUP_CLUSTER),
|
||||
config_key_load(CONFIG_SECTION_RETENTION, CONFIG_KEY_FULL_RETENTION),
|
||||
config_key_load(CONFIG_SECTION_RETENTION, CONFIG_KEY_DIFFERENTIAL_RETENTION),
|
||||
config_key_load(CONFIG_SECTION_RETENTION, CONFIG_KEY_ARCHIVE_RETENTION_TYPE),
|
||||
config_key_load(CONFIG_SECTION_RETENTION, CONFIG_KEY_ARCHIVE_RETENTION)
|
||||
optionGet(OPTION_RETENTION_FULL, false),
|
||||
optionGet(OPTION_RETENTION_DIFF, false),
|
||||
optionGet(OPTION_RETENTION_ARCHIVE_TYPE, false),
|
||||
optionGet(OPTION_RETENTION_ARCHIVE, false)
|
||||
);
|
||||
|
||||
lock_file_remove();
|
||||
|
@ -16,7 +16,6 @@ use Thread::Queue;
|
||||
use lib dirname($0);
|
||||
use BackRest::Utility;
|
||||
use BackRest::Exception;
|
||||
use BackRest::Param;
|
||||
use BackRest::Config;
|
||||
use BackRest::Manifest;
|
||||
use BackRest::File;
|
||||
@ -300,6 +299,7 @@ sub archive_push
|
||||
{
|
||||
my $strDbClusterPath = shift;
|
||||
my $strSourceFile = shift;
|
||||
my $bAsync = shift;
|
||||
|
||||
# If the source file path is not absolute then it is relative to the data path
|
||||
if (index($strSourceFile, '/',) != 0)
|
||||
@ -325,8 +325,9 @@ sub archive_push
|
||||
}
|
||||
|
||||
# Copy the archive file
|
||||
$oFile->copy(PATH_DB_ABSOLUTE, $strSourceFile, # Source file
|
||||
PATH_BACKUP_ARCHIVE, $strDestinationFile, # Destination file
|
||||
$oFile->copy(PATH_DB_ABSOLUTE, $strSourceFile, # Source type/file
|
||||
$bAsync ? PATH_BACKUP_ARCHIVE_OUT : PATH_BACKUP_ARCHIVE, # Destination type
|
||||
$strDestinationFile, # Destination file
|
||||
false, # Source is not compressed
|
||||
$bArchiveFile && $bCompress, # Destination compress is configurable
|
||||
undef, undef, undef, # Unused params
|
||||
@ -356,7 +357,7 @@ sub archive_xfer
|
||||
|
||||
foreach my $strFile (sort(keys $oManifestHash{name}))
|
||||
{
|
||||
if ($strFile =~ /^[0-F]{16}\/[0-F]{24}.*/ || $strFile =~ /^[0-F]{8}\.history$/)
|
||||
if ($strFile =~ /^[0-F]{24}.*/ || $strFile =~ /^[0-F]{8}\.history$/)
|
||||
{
|
||||
push @stryFile, $strFile;
|
||||
|
||||
@ -385,36 +386,11 @@ sub archive_xfer
|
||||
}
|
||||
|
||||
# Modify process name to indicate async archiving
|
||||
# !!! This got broken when history files were added - exclude history files to fix
|
||||
$0 = "${strCommand} archive-push-async ";
|
||||
# $0 = "${strCommand} archive-push-async " . substr($stryFile[0], 17, 24) . '-' . substr($stryFile[scalar @stryFile - 1], 17, 24);
|
||||
$0 = "${strCommand} archive-push-async " . $stryFile[0] . '-' . $stryFile[scalar @stryFile - 1];
|
||||
|
||||
# Output files to be moved to backup
|
||||
&log(INFO, "archive to be copied to backup total ${lFileTotal}, size " . file_size_format($lFileSize));
|
||||
|
||||
# # Init the thread variables
|
||||
# $iThreadLocalMax = thread_init(int($lFileTotal / $iThreadThreshold) + 1);
|
||||
# my $iThreadIdx = 0;
|
||||
#
|
||||
# &log(DEBUG, "actual threads ${iThreadLocalMax}/${iThreadMax}");
|
||||
#
|
||||
# # Distribute files among the threads
|
||||
# foreach my $strFile (sort @stryFile)
|
||||
# {
|
||||
# $oThreadQueue[$iThreadIdx]->enqueue($strFile);
|
||||
#
|
||||
# $iThreadIdx = ($iThreadIdx + 1 == $iThreadLocalMax) ? 0 : $iThreadIdx + 1;
|
||||
# }
|
||||
#
|
||||
# # End each thread queue and start the thread
|
||||
# for ($iThreadIdx = 0; $iThreadIdx < $iThreadLocalMax; $iThreadIdx++)
|
||||
# {
|
||||
# $oThreadQueue[$iThreadIdx]->enqueue(undef);
|
||||
# $oThread[$iThreadIdx] = threads->create(\&archive_pull_copy_thread, $iThreadIdx, $strArchivePath);
|
||||
# }
|
||||
#
|
||||
# backup_thread_complete($iThreadTimeout);
|
||||
|
||||
# Transfer each file
|
||||
foreach my $strFile (sort @stryFile)
|
||||
{
|
||||
@ -456,143 +432,10 @@ sub archive_xfer
|
||||
unlink($strArchiveFile) or confess &log(ERROR, "unable to remove ${strArchiveFile}");
|
||||
}
|
||||
|
||||
# Find the archive paths that need to be removed
|
||||
my $strPathMax = substr((sort {$b cmp $a} @stryFile)[0], 0, 16);
|
||||
|
||||
&log(DEBUG, "local archive path max = ${strPathMax}");
|
||||
|
||||
foreach my $strPath ($oFile->list(PATH_DB_ABSOLUTE, $strArchivePath, "^[0-F]{16}\$"))
|
||||
{
|
||||
if ($strPath lt $strPathMax)
|
||||
{
|
||||
&log(DEBUG, "removing local archive path ${strPath}");
|
||||
rmdir($strArchivePath . '/' . $strPath) or &log(WARN, "unable to remove archive path ${strPath}, is it empty?");
|
||||
}
|
||||
|
||||
# If the dir is not empty check if the files are in the manifest
|
||||
# If they are error - there has been some issue
|
||||
# If not, they are new - continue processing without error - they'll be picked up on the next run
|
||||
}
|
||||
|
||||
# Return number of files indicating that processing should continue
|
||||
return $lFileTotal;
|
||||
}
|
||||
|
||||
# sub archive_pull_copy_thread
|
||||
# {
|
||||
# my @args = @_;
|
||||
#
|
||||
# my $iThreadIdx = $args[0];
|
||||
# my $strArchivePath = $args[1];
|
||||
#
|
||||
# my $oFileThread = $oFile->clone($iThreadIdx); # Thread local file object
|
||||
#
|
||||
# # When a KILL signal is received, immediately abort
|
||||
# $SIG{'KILL'} = sub {threads->exit();};
|
||||
#
|
||||
# while (my $strFile = $oThreadQueue[$iThreadIdx]->dequeue())
|
||||
# {
|
||||
# &log(INFO, "thread ${iThreadIdx} backing up archive file ${strFile}");
|
||||
#
|
||||
# my $strArchiveFile = "${strArchivePath}/${strFile}";
|
||||
#
|
||||
# # Copy the file
|
||||
# $oFileThread->file_copy(PATH_DB_ABSOLUTE, $strArchiveFile,
|
||||
# PATH_BACKUP_ARCHIVE, basename($strFile),
|
||||
# undef, undef,
|
||||
# undef); # cannot set permissions remotely yet $oFile->{strDefaultFilePermission});
|
||||
#
|
||||
# # Remove the source archive file
|
||||
# unlink($strArchiveFile) or confess &log(ERROR, "unable to remove ${strArchiveFile}");
|
||||
# }
|
||||
# }
|
||||
|
||||
sub archive_compress
|
||||
{
|
||||
my $strArchivePath = shift;
|
||||
my $strCommand = shift;
|
||||
my $iFileCompressMax = shift;
|
||||
|
||||
# Load the archive manifest - all the files that need to be pushed
|
||||
my %oManifestHash = $oFile->manifest_get(PATH_DB_ABSOLUTE, $strArchivePath);
|
||||
|
||||
# Get all the files to be compressed and calculate the total size
|
||||
my @stryFile;
|
||||
my $lFileSize = 0;
|
||||
my $lFileTotal = 0;
|
||||
|
||||
foreach my $strFile (sort(keys $oManifestHash{name}))
|
||||
{
|
||||
if ($strFile =~ /^[0-F]{16}\/[0-F]{24}(\-[0-f]+){0,1}$/)
|
||||
{
|
||||
push @stryFile, $strFile;
|
||||
|
||||
$lFileSize += $oManifestHash{name}{"${strFile}"}{size};
|
||||
$lFileTotal++;
|
||||
|
||||
if ($lFileTotal >= $iFileCompressMax)
|
||||
{
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($lFileTotal == 0)
|
||||
{
|
||||
&log(DEBUG, 'no archive logs to be compressed');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$0 = "${strCommand} archive-compress-async " . substr($stryFile[0], 17, 24) . '-' . substr($stryFile[scalar @stryFile - 1], 17, 24);
|
||||
|
||||
# Output files to be compressed
|
||||
&log(INFO, "archive to be compressed total ${lFileTotal}, size " . file_size_format($lFileSize));
|
||||
|
||||
# Init the thread variables
|
||||
$iThreadLocalMax = thread_init($iThreadMax);
|
||||
my $iThreadIdx = 0;
|
||||
|
||||
# Distribute files among the threads
|
||||
foreach my $strFile (sort @stryFile)
|
||||
{
|
||||
$oThreadQueue[$iThreadIdx]->enqueue($strFile);
|
||||
|
||||
$iThreadIdx = ($iThreadIdx + 1 == $iThreadLocalMax) ? 0 : $iThreadIdx + 1;
|
||||
}
|
||||
|
||||
# End each thread queue and start the thread
|
||||
for ($iThreadIdx = 0; $iThreadIdx < $iThreadLocalMax; $iThreadIdx++)
|
||||
{
|
||||
$oThreadQueue[$iThreadIdx]->enqueue(undef);
|
||||
$oThread[$iThreadIdx] = threads->create(\&archive_pull_compress_thread, $iThreadIdx, $strArchivePath);
|
||||
}
|
||||
|
||||
# Complete the threads
|
||||
backup_thread_complete($iThreadTimeout);
|
||||
}
|
||||
|
||||
sub archive_pull_compress_thread
|
||||
{
|
||||
my @args = @_;
|
||||
|
||||
my $iThreadIdx = $args[0];
|
||||
my $strArchivePath = $args[1];
|
||||
|
||||
my $oFileThread = $oFile->clone($iThreadIdx); # Thread local file object
|
||||
|
||||
# When a KILL signal is received, immediately abort
|
||||
$SIG{'KILL'} = sub {threads->exit();};
|
||||
|
||||
while (my $strFile = $oThreadQueue[$iThreadIdx]->dequeue())
|
||||
{
|
||||
&log(INFO, "thread ${iThreadIdx} compressing archive file ${strFile}");
|
||||
|
||||
# Compress the file
|
||||
$oFileThread->file_compress(PATH_DB_ABSOLUTE, "${strArchivePath}/${strFile}");
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BACKUP_REGEXP_GET - Generate a regexp depending on the backups that need to be found
|
||||
####################################################################################################################################
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,10 +10,18 @@ use Carp qw(confess);
|
||||
use Net::OpenSSH;
|
||||
use File::Basename;
|
||||
use IPC::System::Simple qw(capture);
|
||||
use Exporter qw(import);
|
||||
|
||||
use lib dirname($0);
|
||||
use BackRest::Utility;
|
||||
|
||||
####################################################################################################################################
|
||||
# Postmaster process Id file
|
||||
####################################################################################################################################
|
||||
use constant FILE_POSTMASTER_PID => 'postmaster.pid';
|
||||
|
||||
our @EXPORT = qw(FILE_POSTMASTER_PID);
|
||||
|
||||
####################################################################################################################################
|
||||
# CONSTRUCTOR
|
||||
####################################################################################################################################
|
||||
|
@ -6,13 +6,7 @@ package BackRest::Exception;
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
####################################################################################################################################
|
||||
# Exports
|
||||
####################################################################################################################################
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw(ERROR_ASSERT ERROR_CHECKSUM ERROR_CONFIG ERROR_OPERATION_REQUIRED ERROR_OPTION_REQUIRED ERROR_OPTION_INVALID
|
||||
ERROR_OPTION_INVALID_VALUE ERROR_POSTMASTER_RUNNING ERROR_PROTOCOL ERROR_RESTORE_PATH_NOT_EMPTY ERROR_FORMAT);
|
||||
|
||||
####################################################################################################################################
|
||||
# Exception Codes
|
||||
@ -22,16 +16,26 @@ use constant
|
||||
ERROR_ASSERT => 100,
|
||||
ERROR_CHECKSUM => 101,
|
||||
ERROR_CONFIG => 102,
|
||||
ERROR_FORMAT => 103,
|
||||
ERROR_OPERATION_REQUIRED => 104,
|
||||
ERROR_OPTION_REQUIRED => 105,
|
||||
ERROR_FILE_INVALID => 103,
|
||||
ERROR_FORMAT => 104,
|
||||
ERROR_OPERATION_REQUIRED => 105,
|
||||
ERROR_OPTION_INVALID => 106,
|
||||
ERROR_OPTION_INVALID_VALUE => 107,
|
||||
ERROR_POSTMASTER_RUNNING => 108,
|
||||
ERROR_PROTOCOL => 109,
|
||||
ERROR_RESTORE_PATH_NOT_EMPTY => 110
|
||||
ERROR_OPTION_INVALID_RANGE => 108,
|
||||
ERROR_OPTION_INVALID_PAIR => 109,
|
||||
ERROR_OPTION_DUPLICATE_KEY => 110,
|
||||
ERROR_OPTION_NEGATE => 111,
|
||||
ERROR_OPTION_REQUIRED => 112,
|
||||
ERROR_POSTMASTER_RUNNING => 113,
|
||||
ERROR_PROTOCOL => 114,
|
||||
ERROR_RESTORE_PATH_NOT_EMPTY => 115
|
||||
};
|
||||
|
||||
our @EXPORT = qw(ERROR_ASSERT ERROR_CHECKSUM ERROR_CONFIG ERROR_FILE_INVALID ERROR_FORMAT ERROR_OPERATION_REQUIRED
|
||||
ERROR_OPTION_INVALID ERROR_OPTION_INVALID_VALUE ERROR_OPTION_INVALID_RANGE ERROR_OPTION_INVALID_PAIR
|
||||
ERROR_OPTION_DUPLICATE_KEY ERROR_OPTION_NEGATE ERROR_OPTION_REQUIRED ERROR_POSTMASTER_RUNNING ERROR_PROTOCOL
|
||||
ERROR_RESTORE_PATH_NOT_EMPTY);
|
||||
|
||||
####################################################################################################################################
|
||||
# CONSTRUCTOR
|
||||
####################################################################################################################################
|
||||
|
@ -14,25 +14,13 @@ use File::Path qw(make_path remove_tree);
|
||||
use Digest::SHA;
|
||||
use File::stat;
|
||||
use Fcntl ':mode';
|
||||
use Exporter qw(import);
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
use BackRest::Remote;
|
||||
|
||||
# Exports
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw(PATH_ABSOLUTE PATH_DB PATH_DB_ABSOLUTE PATH_BACKUP PATH_BACKUP_ABSOLUTE
|
||||
PATH_BACKUP_CLUSTER PATH_BACKUP_TMP PATH_BACKUP_ARCHIVE
|
||||
|
||||
COMMAND_ERR_FILE_MISSING COMMAND_ERR_FILE_READ COMMAND_ERR_FILE_MOVE COMMAND_ERR_FILE_TYPE
|
||||
COMMAND_ERR_LINK_READ COMMAND_ERR_PATH_MISSING COMMAND_ERR_PATH_CREATE COMMAND_ERR_PARAM
|
||||
|
||||
PIPE_STDIN PIPE_STDOUT PIPE_STDERR
|
||||
|
||||
OP_FILE_OWNER OP_FILE_WAIT OP_FILE_LIST OP_FILE_EXISTS OP_FILE_HASH OP_FILE_REMOVE OP_FILE_MANIFEST
|
||||
OP_FILE_COMPRESS OP_FILE_MOVE OP_FILE_COPY OP_FILE_COPY_OUT OP_FILE_COPY_IN OP_FILE_PATH_CREATE);
|
||||
|
||||
####################################################################################################################################
|
||||
# COMMAND Error Constants
|
||||
####################################################################################################################################
|
||||
@ -48,6 +36,9 @@ use constant
|
||||
COMMAND_ERR_PATH_READ => 8
|
||||
};
|
||||
|
||||
our @EXPORT = qw(COMMAND_ERR_FILE_MISSING COMMAND_ERR_FILE_READ COMMAND_ERR_FILE_MOVE COMMAND_ERR_FILE_TYPE COMMAND_ERR_LINK_READ
|
||||
COMMAND_ERR_PATH_MISSING COMMAND_ERR_PATH_CREATE COMMAND_ERR_PARAM);
|
||||
|
||||
####################################################################################################################################
|
||||
# PATH_GET Constants
|
||||
####################################################################################################################################
|
||||
@ -60,9 +51,13 @@ use constant
|
||||
PATH_BACKUP_ABSOLUTE => 'backup:absolute',
|
||||
PATH_BACKUP_CLUSTER => 'backup:cluster',
|
||||
PATH_BACKUP_TMP => 'backup:tmp',
|
||||
PATH_BACKUP_ARCHIVE => 'backup:archive'
|
||||
PATH_BACKUP_ARCHIVE => 'backup:archive',
|
||||
PATH_BACKUP_ARCHIVE_OUT => 'backup:archive:out'
|
||||
};
|
||||
|
||||
push @EXPORT, qw(PATH_ABSOLUTE PATH_DB PATH_DB_ABSOLUTE PATH_BACKUP PATH_BACKUP_ABSOLUTE PATH_BACKUP_CLUSTER PATH_BACKUP_TMP
|
||||
PATH_BACKUP_ARCHIVE PATH_BACKUP_ARCHIVE_OUT);
|
||||
|
||||
####################################################################################################################################
|
||||
# STD Pipe Constants
|
||||
####################################################################################################################################
|
||||
@ -73,6 +68,8 @@ use constant
|
||||
PIPE_STDERR => '<STDERR>'
|
||||
};
|
||||
|
||||
push @EXPORT, qw(PIPE_STDIN PIPE_STDOUT PIPE_STDERR);
|
||||
|
||||
####################################################################################################################################
|
||||
# Operation constants
|
||||
####################################################################################################################################
|
||||
@ -94,6 +91,9 @@ use constant
|
||||
OP_FILE_LINK_CREATE => 'File->link_create'
|
||||
};
|
||||
|
||||
push @EXPORT, qw(OP_FILE_OWNER OP_FILE_WAIT OP_FILE_LIST OP_FILE_EXISTS OP_FILE_HASH OP_FILE_REMOVE OP_FILE_MANIFEST
|
||||
OP_FILE_COMPRESS OP_FILE_MOVE OP_FILE_COPY OP_FILE_COPY_OUT OP_FILE_COPY_IN OP_FILE_PATH_CREATE);
|
||||
|
||||
####################################################################################################################################
|
||||
# CONSTRUCTOR
|
||||
####################################################################################################################################
|
||||
@ -225,10 +225,11 @@ sub path_get
|
||||
confess &log(ASSERT, "absolute path ${strType}:${strFile} must start with /");
|
||||
}
|
||||
|
||||
# Only allow temp files for PATH_BACKUP_ARCHIVE and PATH_BACKUP_TMP and any absolute path
|
||||
# Only allow temp files for PATH_BACKUP_ARCHIVE, PATH_BACKUP_ARCHIVE_OUT, PATH_BACKUP_TMP and any absolute path
|
||||
$bTemp = defined($bTemp) ? $bTemp : false;
|
||||
|
||||
if ($bTemp && !($strType eq PATH_BACKUP_ARCHIVE || $strType eq PATH_BACKUP_TMP || $bAbsolute))
|
||||
if ($bTemp && !($strType eq PATH_BACKUP_ARCHIVE || $strType eq PATH_BACKUP_ARCHIVE_OUT || $strType eq PATH_BACKUP_TMP ||
|
||||
$bAbsolute))
|
||||
{
|
||||
confess &log(ASSERT, 'temp file not supported on path ' . $strType);
|
||||
}
|
||||
@ -276,16 +277,22 @@ sub path_get
|
||||
}
|
||||
|
||||
# Get the backup archive path
|
||||
if ($strType eq PATH_BACKUP_ARCHIVE)
|
||||
if ($strType eq PATH_BACKUP_ARCHIVE_OUT || $strType eq PATH_BACKUP_ARCHIVE)
|
||||
{
|
||||
my $strArchivePath = "$self->{strBackupPath}/archive/$self->{strStanza}";
|
||||
my $strArchive;
|
||||
my $strArchivePath = "$self->{strBackupPath}/archive";
|
||||
|
||||
if ($bTemp)
|
||||
{
|
||||
return "${strArchivePath}/file.tmp" . (defined($self->{iThreadIdx}) ? ".$self->{iThreadIdx}" : '');
|
||||
return "${strArchivePath}/temp/$self->{strStanza}-archive" .
|
||||
(defined($self->{iThreadIdx}) ? "-$self->{iThreadIdx}" : '') . ".tmp";
|
||||
}
|
||||
|
||||
$strArchivePath .= "/$self->{strStanza}";
|
||||
|
||||
if ($strType eq PATH_BACKUP_ARCHIVE)
|
||||
{
|
||||
my $strArchive;
|
||||
|
||||
if (defined($strFile))
|
||||
{
|
||||
$strArchive = substr(basename($strFile), 0, 24);
|
||||
@ -299,6 +306,11 @@ sub path_get
|
||||
return $strArchivePath . (defined($strArchive) ? '/' . substr($strArchive, 0, 16) : '') .
|
||||
(defined($strFile) ? '/' . $strFile : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
return "${strArchivePath}/out" . (defined($strFile) ? '/' . $strFile : '');
|
||||
}
|
||||
}
|
||||
|
||||
if ($strType eq PATH_BACKUP_CLUSTER)
|
||||
{
|
||||
|
@ -31,6 +31,13 @@ our @EXPORT = qw(MANIFEST_PATH MANIFEST_FILE MANIFEST_LINK
|
||||
MANIFEST_SUBKEY_GROUP MANIFEST_SUBKEY_LINK MANIFEST_SUBKEY_MODE MANIFEST_SUBKEY_MODIFICATION_TIME
|
||||
MANIFEST_SUBKEY_PATH MANIFEST_SUBKEY_REFERENCE MANIFEST_SUBKEY_SIZE MANIFEST_SUBKEY_USER);
|
||||
|
||||
####################################################################################################################################
|
||||
# File/path constants
|
||||
####################################################################################################################################
|
||||
use constant FILE_MANIFEST => 'backup.manifest';
|
||||
|
||||
push @EXPORT, qw(FILE_MANIFEST);
|
||||
|
||||
####################################################################################################################################
|
||||
# MANIFEST Constants
|
||||
####################################################################################################################################
|
||||
|
@ -1,785 +0,0 @@
|
||||
####################################################################################################################################
|
||||
# PARAM MODULE
|
||||
####################################################################################################################################
|
||||
package BackRest::Param;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
use Pod::Usage;
|
||||
use File::Basename;
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Storable qw(dclone);
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
|
||||
use Exporter qw(import);
|
||||
|
||||
our @EXPORT = qw(configLoad optionGet optionTest optionRuleGet operationGet operationTest operationSet
|
||||
|
||||
OP_ARCHIVE_GET OP_ARCHIVE_PUSH OP_BACKUP OP_RESTORE OP_EXPIRE
|
||||
|
||||
BACKUP_TYPE_FULL BACKUP_TYPE_DIFF BACKUP_TYPE_INCR
|
||||
|
||||
RECOVERY_TYPE_NAME RECOVERY_TYPE_TIME RECOVERY_TYPE_XID RECOVERY_TYPE_PRESERVE RECOVERY_TYPE_NONE
|
||||
RECOVERY_TYPE_DEFAULT
|
||||
|
||||
OPTION_CONFIG OPTION_STANZA OPTION_TYPE OPTION_DELTA OPTION_SET OPTION_NO_START_STOP OPTION_FORCE OPTION_TARGET
|
||||
OPTION_TARGET_EXCLUSIVE OPTION_TARGET_RESUME OPTION_TARGET_TIMELINE OPTION_THREAD_MAX
|
||||
|
||||
OPTION_VERSION OPTION_HELP OPTION_TEST OPTION_TEST_DELAY OPTION_TEST_NO_FORK
|
||||
|
||||
OPTION_DEFAULT_RESTORE_SET);
|
||||
|
||||
####################################################################################################################################
|
||||
# Operation constants - basic operations that are allowed in backrest
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
OP_ARCHIVE_GET => 'archive-get',
|
||||
OP_ARCHIVE_PUSH => 'archive-push',
|
||||
OP_BACKUP => 'backup',
|
||||
OP_RESTORE => 'restore',
|
||||
OP_EXPIRE => 'expire'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# BACKUP Type Constants
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
BACKUP_TYPE_FULL => 'full',
|
||||
BACKUP_TYPE_DIFF => 'diff',
|
||||
BACKUP_TYPE_INCR => 'incr'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# RECOVERY Type Constants
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
RECOVERY_TYPE_NAME => 'name',
|
||||
RECOVERY_TYPE_TIME => 'time',
|
||||
RECOVERY_TYPE_XID => 'xid',
|
||||
RECOVERY_TYPE_PRESERVE => 'preserve',
|
||||
RECOVERY_TYPE_NONE => 'none',
|
||||
RECOVERY_TYPE_DEFAULT => 'default'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Option constants
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
# Command-line-only options
|
||||
OPTION_CONFIG => 'config',
|
||||
OPTION_DELTA => 'delta',
|
||||
OPTION_FORCE => 'force',
|
||||
OPTION_NO_START_STOP => 'no-start-stop',
|
||||
OPTION_SET => 'set',
|
||||
OPTION_STANZA => 'stanza',
|
||||
OPTION_TARGET => 'target',
|
||||
OPTION_TARGET_EXCLUSIVE => 'target-exclusive',
|
||||
OPTION_TARGET_RESUME => 'target-resume',
|
||||
OPTION_TARGET_TIMELINE => 'target-timeline',
|
||||
OPTION_TYPE => 'type',
|
||||
|
||||
# Command-line-only/conf file options
|
||||
OPTION_THREAD_MAX => 'thread-max',
|
||||
|
||||
# Command-line-only help/version options
|
||||
OPTION_HELP => 'help',
|
||||
OPTION_VERSION => 'version',
|
||||
|
||||
# Command-line-only test options
|
||||
OPTION_TEST => 'test',
|
||||
OPTION_TEST_DELAY => 'test-delay',
|
||||
OPTION_TEST_NO_FORK => 'no-fork'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Option Defaults
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
OPTION_DEFAULT_CONFIG => '/etc/pg_backrest.conf',
|
||||
OPTION_DEFAULT_THREAD_MAX => 1,
|
||||
|
||||
OPTION_DEFAULT_BACKUP_FORCE => false,
|
||||
OPTION_DEFAULT_BACKUP_NO_START_STOP => false,
|
||||
OPTION_DEFAULT_BACKUP_TYPE => BACKUP_TYPE_INCR,
|
||||
|
||||
OPTION_DEFAULT_RESTORE_DELTA => false,
|
||||
OPTION_DEFAULT_RESTORE_FORCE => false,
|
||||
OPTION_DEFAULT_RESTORE_SET => 'latest',
|
||||
OPTION_DEFAULT_RESTORE_TYPE => RECOVERY_TYPE_DEFAULT,
|
||||
OPTION_DEFAULT_RESTORE_TARGET_EXCLUSIVE => false,
|
||||
OPTION_DEFAULT_RESTORE_TARGET_RESUME => false,
|
||||
|
||||
OPTION_DEFAULT_HELP => false,
|
||||
OPTION_DEFAULT_VERSION => false,
|
||||
|
||||
OPTION_DEFAULT_TEST => false,
|
||||
OPTION_DEFAULT_TEST_DELAY => 5,
|
||||
OPTION_DEFAULT_TEST_NO_FORK => false
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Option Rules
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
OPTION_RULE_ALLOW_LIST => 'allow-list',
|
||||
OPTION_RULE_DEFAULT => 'default',
|
||||
OPTION_RULE_DEPEND => 'depend',
|
||||
OPTION_RULE_DEPEND_OPTION => 'depend-option',
|
||||
OPTION_RULE_DEPEND_LIST => 'depend-list',
|
||||
OPTION_RULE_DEPEND_VALUE => 'depend-value',
|
||||
OPTION_RULE_REQUIRED => 'required',
|
||||
OPTION_RULE_OPERATION => 'operation',
|
||||
OPTION_RULE_TYPE => 'type'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Option Types
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
OPTION_TYPE_STRING => 'string',
|
||||
OPTION_TYPE_BOOLEAN => 'boolean',
|
||||
OPTION_TYPE_INTEGER => 'integer',
|
||||
OPTION_TYPE_FLOAT => 'float'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Option Rule Hash
|
||||
####################################################################################################################################
|
||||
my %oOptionRule =
|
||||
(
|
||||
&OPTION_CONFIG =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_CONFIG
|
||||
},
|
||||
|
||||
&OPTION_DELTA =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_DELTA,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_FORCE =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_FORCE,
|
||||
},
|
||||
|
||||
&OP_BACKUP =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_BACKUP_FORCE,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_NO_START_STOP,
|
||||
&OPTION_RULE_DEPEND_VALUE => true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_NO_START_STOP =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_BACKUP =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_BACKUP_NO_START_STOP
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_SET =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_TYPE,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_STANZA =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING
|
||||
},
|
||||
|
||||
&OPTION_TARGET =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TYPE,
|
||||
&OPTION_RULE_DEPEND_LIST =>
|
||||
{
|
||||
&RECOVERY_TYPE_NAME => true,
|
||||
&RECOVERY_TYPE_TIME => true,
|
||||
&RECOVERY_TYPE_XID => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_TARGET_EXCLUSIVE =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_TARGET_EXCLUSIVE,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TYPE,
|
||||
&OPTION_RULE_DEPEND_LIST =>
|
||||
{
|
||||
&RECOVERY_TYPE_TIME => true,
|
||||
&RECOVERY_TYPE_XID => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_TARGET_RESUME =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_TARGET_RESUME,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TYPE,
|
||||
&OPTION_RULE_DEPEND_LIST =>
|
||||
{
|
||||
&RECOVERY_TYPE_NAME => true,
|
||||
&RECOVERY_TYPE_TIME => true,
|
||||
&RECOVERY_TYPE_XID => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_TARGET_TIMELINE =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_REQUIRED => false,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TYPE,
|
||||
&OPTION_RULE_DEPEND_LIST =>
|
||||
{
|
||||
&RECOVERY_TYPE_DEFAULT => true,
|
||||
&RECOVERY_TYPE_NAME => true,
|
||||
&RECOVERY_TYPE_TIME => true,
|
||||
&RECOVERY_TYPE_XID => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_TYPE =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_STRING,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_BACKUP =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_BACKUP_TYPE,
|
||||
&OPTION_RULE_ALLOW_LIST =>
|
||||
{
|
||||
&BACKUP_TYPE_FULL => true,
|
||||
&BACKUP_TYPE_DIFF => true,
|
||||
&BACKUP_TYPE_INCR => true,
|
||||
}
|
||||
},
|
||||
|
||||
&OP_RESTORE =>
|
||||
{
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_RESTORE_TYPE,
|
||||
&OPTION_RULE_ALLOW_LIST =>
|
||||
{
|
||||
&RECOVERY_TYPE_NAME => true,
|
||||
&RECOVERY_TYPE_TIME => true,
|
||||
&RECOVERY_TYPE_XID => true,
|
||||
&RECOVERY_TYPE_PRESERVE => true,
|
||||
&RECOVERY_TYPE_NONE => true,
|
||||
&RECOVERY_TYPE_DEFAULT => true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_THREAD_MAX =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_INTEGER,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_THREAD_MAX,
|
||||
&OPTION_RULE_OPERATION =>
|
||||
{
|
||||
&OP_BACKUP => true,
|
||||
&OP_RESTORE => true
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_HELP =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_HELP
|
||||
},
|
||||
|
||||
&OPTION_VERSION =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_VERSION
|
||||
},
|
||||
|
||||
&OPTION_TEST =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_TEST
|
||||
},
|
||||
|
||||
&OPTION_TEST_DELAY =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_FLOAT,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_TEST_DELAY,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TEST,
|
||||
&OPTION_RULE_DEPEND_VALUE => true
|
||||
}
|
||||
},
|
||||
|
||||
&OPTION_TEST_NO_FORK =>
|
||||
{
|
||||
&OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN,
|
||||
&OPTION_RULE_DEFAULT => OPTION_DEFAULT_TEST_NO_FORK,
|
||||
&OPTION_RULE_DEPEND =>
|
||||
{
|
||||
&OPTION_RULE_DEPEND_OPTION => OPTION_TEST
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
####################################################################################################################################
|
||||
# Global variables
|
||||
####################################################################################################################################
|
||||
my %oOption; # Option hash
|
||||
my $strOperation; # Operation (backup, archive-get, ...)
|
||||
|
||||
####################################################################################################################################
|
||||
# configLoad
|
||||
#
|
||||
# Load configuration.
|
||||
####################################################################################################################################
|
||||
sub configLoad
|
||||
{
|
||||
# Clear option in case it was loaded before
|
||||
%oOption = ();
|
||||
|
||||
# Build hash with all valid command-line options
|
||||
my %oOption;
|
||||
|
||||
foreach my $strKey (keys(%oOptionRule))
|
||||
{
|
||||
my $strOption = $strKey;
|
||||
|
||||
if (!defined($oOptionRule{$strKey}{&OPTION_RULE_TYPE}))
|
||||
{
|
||||
confess &log(ASSERT, "Option ${strKey} does not have a defined type", ERROR_ASSERT);
|
||||
}
|
||||
elsif ($oOptionRule{$strKey}{&OPTION_RULE_TYPE} ne OPTION_TYPE_BOOLEAN)
|
||||
{
|
||||
$strOption .= '=s';
|
||||
}
|
||||
|
||||
$oOption{$strOption} = $strOption;
|
||||
}
|
||||
|
||||
# Get command-line options
|
||||
my %oOptionTest;
|
||||
|
||||
GetOptions(\%oOptionTest, %oOption)
|
||||
or pod2usage(2);
|
||||
|
||||
# Validate and store options
|
||||
optionValid(\%oOptionTest);
|
||||
|
||||
# Display version and exit if requested
|
||||
if (optionGet(OPTION_VERSION) || optionGet(OPTION_HELP))
|
||||
{
|
||||
print 'pg_backrest ' . version_get() . "\n";
|
||||
|
||||
if (!OPTION_get(OPTION_HELP))
|
||||
{
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Display help and exit if requested
|
||||
if (optionGet(OPTION_HELP))
|
||||
{
|
||||
print "\n";
|
||||
pod2usage();
|
||||
}
|
||||
|
||||
# Set test options
|
||||
!optionGet(OPTION_TEST) or test_set(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY));
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionValid
|
||||
#
|
||||
# Make sure the command-line options are valid based on the operation.
|
||||
####################################################################################################################################
|
||||
sub optionValid
|
||||
{
|
||||
my $oOptionTest = shift;
|
||||
|
||||
# Check that the operation is present and valid
|
||||
$strOperation = $ARGV[0];
|
||||
|
||||
if (!defined($strOperation))
|
||||
{
|
||||
confess &log(ERROR, "operation must be specified", ERROR_OPERATION_REQUIRED);
|
||||
}
|
||||
|
||||
if ($strOperation ne OP_ARCHIVE_GET &&
|
||||
$strOperation ne OP_ARCHIVE_PUSH &&
|
||||
$strOperation ne OP_BACKUP &&
|
||||
$strOperation ne OP_RESTORE &&
|
||||
$strOperation ne OP_EXPIRE)
|
||||
{
|
||||
confess &log(ERROR, "invalid operation ${strOperation}");
|
||||
}
|
||||
|
||||
# Keep track of unresolved dependencies
|
||||
my $bDependUnresolved = true;
|
||||
my %oOptionResolved;
|
||||
|
||||
# Loop through all possible options
|
||||
while ($bDependUnresolved)
|
||||
{
|
||||
# Assume that all dependencies will be resolved in this loop
|
||||
$bDependUnresolved = false;
|
||||
|
||||
foreach my $strOption (sort(keys(%oOptionRule)))
|
||||
{
|
||||
# Skip the option if it has been resolved in a prior loop
|
||||
if (defined($oOptionResolved{$strOption}))
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Check dependency for the operation then for the option
|
||||
my $oDepend;
|
||||
my $bDependResolved = true;
|
||||
|
||||
if (defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}) &&
|
||||
defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) &&
|
||||
ref($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) eq 'HASH')
|
||||
{
|
||||
$oDepend = $oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}{&OPTION_RULE_DEPEND};
|
||||
}
|
||||
|
||||
if (!defined($oDepend))
|
||||
{
|
||||
$oDepend = $oOptionRule{$strOption}{&OPTION_RULE_DEPEND};
|
||||
}
|
||||
|
||||
if (defined($oDepend))
|
||||
{
|
||||
# Make sure the depend option has been resolved, otherwise skip this option for now
|
||||
my $strDependOption = $$oDepend{&OPTION_RULE_DEPEND_OPTION};
|
||||
|
||||
if (!defined($oOptionResolved{$strDependOption}))
|
||||
{
|
||||
$bDependUnresolved = true;
|
||||
next;
|
||||
}
|
||||
|
||||
# Check if the depend option has a value
|
||||
my $strDependValue = $oOption{$strDependOption};
|
||||
my $strError = "option '${strOption}' not valid without option '${strDependOption}'";
|
||||
|
||||
$bDependResolved = defined($strDependValue) ? true : false;
|
||||
|
||||
if (!$bDependResolved && defined($$oOptionTest{$strOption}))
|
||||
{
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
|
||||
# If a depend value exists, make sure the option value matches
|
||||
if ($bDependResolved && defined($$oDepend{&OPTION_RULE_DEPEND_VALUE}) &&
|
||||
$$oDepend{&OPTION_RULE_DEPEND_VALUE} ne $strDependValue)
|
||||
{
|
||||
$bDependResolved = false;
|
||||
|
||||
if (defined($$oOptionTest{$strOption}))
|
||||
{
|
||||
if ($oOptionRule{$strDependOption}{&OPTION_RULE_TYPE} eq OPTION_TYPE_BOOLEAN)
|
||||
{
|
||||
if (!$$oDepend{&OPTION_RULE_DEPEND_VALUE})
|
||||
{
|
||||
confess &log(ASSERT, "no error has been created for unused case where depend value = false");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$strError .= " = '$$oDepend{&OPTION_RULE_DEPEND_VALUE}'";
|
||||
}
|
||||
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
# If a depend list exists, make sure the value is in the list
|
||||
if ($bDependResolved && defined($$oDepend{&OPTION_RULE_DEPEND_LIST}) &&
|
||||
!defined($$oDepend{&OPTION_RULE_DEPEND_LIST}{$strDependValue}))
|
||||
{
|
||||
$bDependResolved = false;
|
||||
|
||||
if (defined($$oOptionTest{$strOption}))
|
||||
{
|
||||
my @oyValue;
|
||||
|
||||
foreach my $strValue (sort(keys($$oDepend{&OPTION_RULE_DEPEND_LIST})))
|
||||
{
|
||||
push(@oyValue, "'${strValue}'");
|
||||
}
|
||||
|
||||
$strError .= @oyValue == 1 ? " = $oyValue[0]" : " in (" . join(", ", @oyValue) . ")";
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Is the option defined?
|
||||
if (defined($$oOptionTest{$strOption}))
|
||||
{
|
||||
my $strValue = $$oOptionTest{$strOption};
|
||||
|
||||
# Test option type
|
||||
if ($oOptionRule{$strOption}{&OPTION_RULE_TYPE} eq OPTION_TYPE_INTEGER ||
|
||||
$oOptionRule{$strOption}{&OPTION_RULE_TYPE} eq OPTION_TYPE_FLOAT)
|
||||
{
|
||||
# Test that the string is a valid float or integer by adding 1 to it. It's pretty hokey but it works and it
|
||||
# beats requiring Scalar::Util::Numeric to do it properly.
|
||||
eval
|
||||
{
|
||||
my $strTest = $strValue + 1;
|
||||
};
|
||||
|
||||
my $bError = $@ ? true : false;
|
||||
|
||||
# Check that integers are really integers
|
||||
if (!$bError && $oOptionRule{$strOption}{&OPTION_RULE_TYPE} eq OPTION_TYPE_INTEGER &&
|
||||
(int($strValue) . 'S') ne ($strValue . 'S'))
|
||||
{
|
||||
$bError = true;
|
||||
}
|
||||
|
||||
# Error if the value did not pass tests
|
||||
!$bError
|
||||
or confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Process an allow list for the operation then for the option
|
||||
my $oAllow;
|
||||
|
||||
if (defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}) &&
|
||||
defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) &&
|
||||
ref($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) eq 'HASH')
|
||||
{
|
||||
$oAllow = $oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}{&OPTION_RULE_ALLOW_LIST};
|
||||
}
|
||||
|
||||
if (!defined($oAllow))
|
||||
{
|
||||
$oAllow = $oOptionRule{$strOption}{&OPTION_RULE_ALLOW_LIST};
|
||||
}
|
||||
|
||||
if (defined($oAllow) && !defined($$oAllow{$$oOptionTest{$strOption}}))
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Set option value
|
||||
$oOption{$strOption} = $strValue;
|
||||
}
|
||||
# Else set the default if required
|
||||
elsif (!defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}) ||
|
||||
defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}))
|
||||
{
|
||||
# Check for default in operation then option
|
||||
my $strDefault;
|
||||
|
||||
if (defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}) &&
|
||||
defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) &&
|
||||
ref($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) eq 'HASH')
|
||||
{
|
||||
$strDefault = $oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}{&OPTION_RULE_DEFAULT}
|
||||
}
|
||||
|
||||
if (!defined($strDefault))
|
||||
{
|
||||
$strDefault = $oOptionRule{$strOption}{&OPTION_RULE_DEFAULT};
|
||||
}
|
||||
|
||||
# If default is defined
|
||||
if (defined($strDefault))
|
||||
{
|
||||
# Only set default if dependency is resolved
|
||||
$oOption{$strOption} = $strDefault if $bDependResolved;
|
||||
}
|
||||
# Else error
|
||||
else
|
||||
{
|
||||
# Check for required in operation then option
|
||||
my $bRequired;
|
||||
|
||||
if (defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}) &&
|
||||
defined($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) &&
|
||||
ref($oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}) eq 'HASH')
|
||||
{
|
||||
$bRequired = $oOptionRule{$strOption}{&OPTION_RULE_OPERATION}{$strOperation}{&OPTION_RULE_REQUIRED};
|
||||
}
|
||||
|
||||
if (!defined($bRequired))
|
||||
{
|
||||
$bRequired = $oOptionRule{$strOption}{&OPTION_RULE_REQUIRED};
|
||||
}
|
||||
|
||||
if (!defined($bRequired) || $bRequired)
|
||||
{
|
||||
if ($bDependResolved)
|
||||
{
|
||||
confess &log(ERROR, "${strOperation} operation requires option: ${strOption}", ERROR_OPTION_REQUIRED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oOptionResolved{$strOption} = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# operationGet
|
||||
#
|
||||
# Get the current operation.
|
||||
####################################################################################################################################
|
||||
sub operationGet
|
||||
{
|
||||
return $strOperation;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# operationTest
|
||||
#
|
||||
# Test the current operation.
|
||||
####################################################################################################################################
|
||||
sub operationTest
|
||||
{
|
||||
my $strOperationTest = shift;
|
||||
|
||||
return $strOperationTest eq $strOperation;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# operationSet
|
||||
#
|
||||
# Set current operation (usually for triggering follow-on operations).
|
||||
####################################################################################################################################
|
||||
sub operationSet
|
||||
{
|
||||
my $strValue = shift;
|
||||
|
||||
$strOperation = $strValue;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionGet
|
||||
#
|
||||
# Get option value.
|
||||
####################################################################################################################################
|
||||
sub optionGet
|
||||
{
|
||||
my $strOption = shift;
|
||||
my $bRequired = shift;
|
||||
|
||||
if (!defined($oOption{$strOption}) && (!defined($bRequired) || $bRequired))
|
||||
{
|
||||
confess &log(ASSERT, "option ${strOption} is required");
|
||||
}
|
||||
|
||||
return $oOption{$strOption};
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionTest
|
||||
#
|
||||
# Test a option value.
|
||||
####################################################################################################################################
|
||||
sub optionTest
|
||||
{
|
||||
my $strOption = shift;
|
||||
my $strValue = shift;
|
||||
|
||||
if (defined($strValue))
|
||||
{
|
||||
return optionGet($strOption) eq $strValue;
|
||||
}
|
||||
|
||||
return defined($oOption{$strOption});
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionRuleGet
|
||||
#
|
||||
# Get the option rules.
|
||||
####################################################################################################################################
|
||||
sub optionRuleGet
|
||||
{
|
||||
return dclone(\%oOptionRule);
|
||||
}
|
||||
|
||||
1;
|
@ -17,10 +17,15 @@ use lib dirname($0);
|
||||
use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
use BackRest::ThreadGroup;
|
||||
use BackRest::Param;
|
||||
use BackRest::Config;
|
||||
use BackRest::Manifest;
|
||||
use BackRest::File;
|
||||
use BackRest::Db;
|
||||
|
||||
####################################################################################################################################
|
||||
# Recovery.conf file
|
||||
####################################################################################################################################
|
||||
use constant FILE_RECOVERY_CONF => 'recovery.conf';
|
||||
|
||||
####################################################################################################################################
|
||||
# CONSTRUCTOR
|
||||
@ -479,7 +484,7 @@ sub recovery
|
||||
my $strPgKey = $strKey;
|
||||
$strPgKey =~ s/\-/\_/g;
|
||||
|
||||
if ($strKey eq CONFIG_KEY_RESTORE_COMMAND)
|
||||
if ($strPgKey eq 'restore_command')
|
||||
{
|
||||
$bRestoreCommandOverride = true;
|
||||
}
|
||||
|
@ -430,22 +430,22 @@ sub log_level_set
|
||||
|
||||
if (defined($strLevelFileParam))
|
||||
{
|
||||
if (!defined($oLogLevelRank{"${strLevelFileParam}"}{rank}))
|
||||
if (!defined($oLogLevelRank{uc($strLevelFileParam)}{rank}))
|
||||
{
|
||||
confess &log(ERROR, "file log level ${strLevelFileParam} does not exist");
|
||||
}
|
||||
|
||||
$strLogLevelFile = $strLevelFileParam;
|
||||
$strLogLevelFile = uc($strLevelFileParam);
|
||||
}
|
||||
|
||||
if (defined($strLevelConsoleParam))
|
||||
{
|
||||
if (!defined($oLogLevelRank{"${strLevelConsoleParam}"}{rank}))
|
||||
if (!defined($oLogLevelRank{uc($strLevelConsoleParam)}{rank}))
|
||||
{
|
||||
confess &log(ERROR, "console log level ${strLevelConsoleParam} does not exist");
|
||||
}
|
||||
|
||||
$strLogLevelConsole = $strLevelConsoleParam;
|
||||
$strLogLevelConsole = uc($strLevelConsoleParam);
|
||||
}
|
||||
}
|
||||
|
||||
@ -626,6 +626,8 @@ sub ini_load
|
||||
}
|
||||
|
||||
close($hFile);
|
||||
|
||||
return($oConfig);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
|
@ -21,7 +21,6 @@ use DBI;
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
use BackRest::Param;
|
||||
use BackRest::Config;
|
||||
use BackRest::Manifest;
|
||||
use BackRest::File;
|
||||
@ -192,15 +191,11 @@ sub BackRestTestBackup_ClusterStop
|
||||
$strPath = defined($strPath) ? $strPath : BackRestTestCommon_DbCommonPathGet();
|
||||
$bImmediate = defined($bImmediate) ? $bImmediate : false;
|
||||
|
||||
# If postmaster process is running then stop the cluster
|
||||
if (-e $strPath . '/postmaster.pid')
|
||||
{
|
||||
# Disconnect user session
|
||||
BackRestTestBackup_PgDisconnect();
|
||||
|
||||
BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/pg_ctl stop -D ${strPath} -w -s -m " .
|
||||
($bImmediate ? 'immediate' : 'fast'));
|
||||
}
|
||||
# Drop the cluster
|
||||
BackRestTestCommon_ClusterStop
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -285,16 +280,19 @@ sub BackRestTestBackup_Drop
|
||||
# Stop the cluster if one is running
|
||||
BackRestTestBackup_ClusterStop(BackRestTestCommon_DbCommonPathGet(), $bImmediate);
|
||||
|
||||
# Remove the backrest private directory
|
||||
while (-e BackRestTestCommon_BackupPathGet())
|
||||
{
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_BackupPathGet(), true, true);
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_BackupPathGet(), false, true);
|
||||
hsleep(.1);
|
||||
}
|
||||
# Drop the test path
|
||||
BackRestTestCommon_Drop();
|
||||
|
||||
# Remove the test directory
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_TestPathGet());
|
||||
# # Remove the backrest private directory
|
||||
# while (-e BackRestTestCommon_RepoPathGet())
|
||||
# {
|
||||
# BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), true, true);
|
||||
# BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), false, true);
|
||||
# hsleep(.1);
|
||||
# }
|
||||
#
|
||||
# # Remove the test directory
|
||||
# BackRestTestCommon_PathRemove(BackRestTestCommon_TestPathGet());
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -313,7 +311,7 @@ sub BackRestTestBackup_Create
|
||||
BackRestTestBackup_Drop(true);
|
||||
|
||||
# Create the test directory
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_TestPathGet(), '0770');
|
||||
BackRestTestCommon_Create();
|
||||
|
||||
# Create the db paths
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_DbPathGet());
|
||||
@ -328,16 +326,19 @@ sub BackRestTestBackup_Create
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_DbTablespacePathGet(2, 2));
|
||||
|
||||
# Create the archive directory
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_ArchivePathGet());
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_LocalPathGet());
|
||||
}
|
||||
|
||||
# Create the backup directory
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('mkdir -m 700 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('mkdir -m 700 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_BackupPathGet());
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_RepoPathGet());
|
||||
}
|
||||
|
||||
# Create the cluster
|
||||
@ -812,7 +813,7 @@ sub BackRestTestBackup_BackupBegin
|
||||
&log(INFO, " ${strType} backup" . (defined($strComment) ? " (${strComment})" : ''));
|
||||
|
||||
BackRestTestCommon_ExecuteBegin(BackRestTestCommon_CommandMainGet() . ' --config=' .
|
||||
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
($bRemote ? BackRestTestCommon_RepoPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
"/pg_backrest.conf" . ($bSynthetic ? " --no-start-stop" : '') .
|
||||
($strType ne 'incr' ? " --type=${strType}" : '') .
|
||||
" --stanza=${strStanza} backup" . ($bTestPoint ? " --test --test-delay=${fTestDelay}": ''),
|
||||
@ -951,7 +952,7 @@ sub BackRestTestBackup_BackupCompare
|
||||
# Change permissions on the backup path so it can be read
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
|
||||
my %oActualManifest;
|
||||
@ -973,7 +974,7 @@ sub BackRestTestBackup_BackupCompare
|
||||
# Change permissions on the backup path back before unit tests continue
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
|
||||
$oFile->remove(PATH_ABSOLUTE, "${strTestPath}/expected.manifest");
|
||||
@ -1005,7 +1006,7 @@ sub BackRestTestBackup_ManifestMunge
|
||||
# Change permissions on the backup path so it can be read/written
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 770 ' . $oFile->path_get(PATH_BACKUP_CLUSTER, $strBackup) . '/backup.manifest', true);
|
||||
}
|
||||
|
||||
@ -1089,7 +1090,7 @@ sub BackRestTestBackup_ManifestMunge
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 750 ' . $oFile->path_get(PATH_BACKUP_CLUSTER, $strBackup) . '/backup.manifest', true);
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1139,10 +1140,10 @@ sub BackRestTestBackup_Restore
|
||||
# Change permissions on the backup path so it can be read
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
|
||||
my $oExpectedManifest = new BackRest::Manifest(BackRestTestCommon_BackupPathGet() .
|
||||
my $oExpectedManifest = new BackRest::Manifest(BackRestTestCommon_RepoPathGet() .
|
||||
"/backup/${strStanza}/${strBackup}/backup.manifest", true);
|
||||
|
||||
$oExpectedManifestRef = $oExpectedManifest->{oManifest};
|
||||
@ -1150,7 +1151,7 @@ sub BackRestTestBackup_Restore
|
||||
# Change permissions on the backup path back before unit tests continue
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1205,20 +1206,20 @@ sub BackRestTestBackup_RestoreCompare
|
||||
# Change permissions on the backup path so it can be read
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 750 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
|
||||
my $oExpectedManifest = new BackRest::Manifest(BackRestTestCommon_BackupPathGet() .
|
||||
my $oExpectedManifest = new BackRest::Manifest(BackRestTestCommon_RepoPathGet() .
|
||||
"/backup/${strStanza}/${strBackup}/backup.manifest", true);
|
||||
|
||||
$oLastManifest = new BackRest::Manifest(BackRestTestCommon_BackupPathGet() .
|
||||
$oLastManifest = new BackRest::Manifest(BackRestTestCommon_RepoPathGet() .
|
||||
"/backup/${strStanza}/" . ${$oExpectedManifestRef}{'backup'}{'prior'} .
|
||||
'/backup.manifest', true);
|
||||
|
||||
# Change permissions on the backup path back before unit tests continue
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_BackupPathGet(), true);
|
||||
BackRestTestCommon_Execute('chmod 700 ' . BackRestTestCommon_RepoPathGet(), true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1326,16 +1327,16 @@ sub BackRestTestBackup_Test
|
||||
&log(INFO, 'BACKUP MODULE ******************************************************************');
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
# Create remote
|
||||
# Create remotes
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
my $oRemote = BackRest::Remote->new
|
||||
(
|
||||
$strHost, # Host
|
||||
$strUserBackRest, # User
|
||||
BackRestTestCommon_CommandRemoteGet(), # Command
|
||||
CONFIG_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
OPTION_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
);
|
||||
|
||||
my $oLocal = new BackRest::Remote
|
||||
@ -1343,9 +1344,9 @@ sub BackRestTestBackup_Test
|
||||
undef, # Host
|
||||
undef, # User
|
||||
undef, # Command
|
||||
CONFIG_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
OPTION_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
);
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -1379,7 +1380,7 @@ sub BackRestTestBackup_Test
|
||||
$oFile = (new BackRest::File
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
$bRemote ? 'backup' : undef,
|
||||
$bRemote ? $oRemote : $oLocal
|
||||
))->clone();
|
||||
@ -1497,7 +1498,7 @@ sub BackRestTestBackup_Test
|
||||
$oFile = (BackRest::File->new
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
$bRemote ? 'backup' : undef,
|
||||
$bRemote ? $oRemote : $oLocal
|
||||
))->clone();
|
||||
@ -1635,7 +1636,7 @@ sub BackRestTestBackup_Test
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
$bRemote ? 'backup' : undef,
|
||||
$bRemote ? $oRemote : $oLocal
|
||||
);
|
||||
@ -1673,7 +1674,7 @@ sub BackRestTestBackup_Test
|
||||
|
||||
# Create the backup command
|
||||
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' .
|
||||
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
($bRemote ? BackRestTestCommon_RepoPathGet() : BackRestTestCommon_DbPathGet()) .
|
||||
"/pg_backrest.conf --no-start-stop --stanza=${strStanza} backup";
|
||||
|
||||
# Full backup
|
||||
@ -1689,9 +1690,9 @@ sub BackRestTestBackup_Test
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
$strType = 'full';
|
||||
|
||||
my $strTmpPath = BackRestTestCommon_BackupPathGet() . "/temp/${strStanza}.tmp";
|
||||
my $strTmpPath = BackRestTestCommon_RepoPathGet() . "/temp/${strStanza}.tmp";
|
||||
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strFullBackup}",
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_RepoPathGet() . "/backup/${strStanza}/${strFullBackup}",
|
||||
$strTmpPath, $bRemote);
|
||||
|
||||
$strFullBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
|
||||
@ -1742,9 +1743,9 @@ sub BackRestTestBackup_Test
|
||||
$strType = 'incr';
|
||||
|
||||
# Move database from backup to temp
|
||||
$strTmpPath = BackRestTestCommon_BackupPathGet() . "/temp/${strStanza}.tmp";
|
||||
$strTmpPath = BackRestTestCommon_RepoPathGet() . "/temp/${strStanza}.tmp";
|
||||
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strBackup}",
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_RepoPathGet() . "/backup/${strStanza}/${strBackup}",
|
||||
$strTmpPath, $bRemote);
|
||||
|
||||
# Add tablespace 2
|
||||
@ -1760,9 +1761,9 @@ sub BackRestTestBackup_Test
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
$strType = 'diff';
|
||||
|
||||
$strTmpPath = BackRestTestCommon_BackupPathGet() . "/temp/${strStanza}.tmp";
|
||||
$strTmpPath = BackRestTestCommon_RepoPathGet() . "/temp/${strStanza}.tmp";
|
||||
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strBackup}",
|
||||
BackRestTestCommon_PathMove(BackRestTestCommon_RepoPathGet() . "/backup/${strStanza}/${strBackup}",
|
||||
$strTmpPath, $bRemote);
|
||||
|
||||
$strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
|
||||
@ -1927,7 +1928,7 @@ sub BackRestTestBackup_Test
|
||||
my $oFile = new BackRest::File
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
$bRemote ? 'backup' : undef,
|
||||
$bRemote ? $oRemote : $oLocal
|
||||
);
|
||||
@ -2242,7 +2243,7 @@ sub BackRestTestBackup_Test
|
||||
$bTargetExclusive = undef;
|
||||
$bTargetResume = undef;
|
||||
$strTargetTimeline = 3;
|
||||
$oRecoveryHashRef = {&CONFIG_KEY_STANDBY_MODE => 'on'};
|
||||
$oRecoveryHashRef = {'standy-mode' => 'on'};
|
||||
$oRecoveryHashRef = undef;
|
||||
$strComment = undef;
|
||||
$iExpectedExitStatus = undef;
|
||||
@ -2286,7 +2287,7 @@ sub BackRestTestBackup_Test
|
||||
my $oFile = (BackRest::File->new
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
undef,
|
||||
undef
|
||||
))->clone();
|
||||
@ -2413,7 +2414,7 @@ sub BackRestTestBackup_Test
|
||||
my $oFile = (BackRest::File->new
|
||||
(
|
||||
$strStanza,
|
||||
BackRestTestCommon_BackupPathGet(),
|
||||
BackRestTestCommon_RepoPathGet(),
|
||||
undef,
|
||||
undef
|
||||
))->clone();
|
||||
|
@ -26,8 +26,8 @@ use BackRest::File;
|
||||
use BackRest::Manifest;
|
||||
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw(BackRestTestCommon_Setup BackRestTestCommon_ExecuteBegin BackRestTestCommon_ExecuteEnd
|
||||
BackRestTestCommon_Execute BackRestTestCommon_ExecuteBackRest
|
||||
our @EXPORT = qw(BackRestTestCommon_Create BackRestTestCommon_Drop BackRestTestCommon_Setup BackRestTestCommon_ExecuteBegin
|
||||
BackRestTestCommon_ExecuteEnd BackRestTestCommon_Execute BackRestTestCommon_ExecuteBackRest
|
||||
BackRestTestCommon_PathCreate BackRestTestCommon_PathMode BackRestTestCommon_PathRemove
|
||||
BackRestTestCommon_FileCreate BackRestTestCommon_FileRemove BackRestTestCommon_PathCopy BackRestTestCommon_PathMove
|
||||
BackRestTestCommon_ConfigCreate BackRestTestCommon_ConfigRemap BackRestTestCommon_ConfigRecovery
|
||||
@ -35,8 +35,9 @@ our @EXPORT = qw(BackRestTestCommon_Setup BackRestTestCommon_ExecuteBegin BackRe
|
||||
BackRestTestCommon_StanzaGet BackRestTestCommon_CommandMainGet BackRestTestCommon_CommandRemoteGet
|
||||
BackRestTestCommon_HostGet BackRestTestCommon_UserGet BackRestTestCommon_GroupGet
|
||||
BackRestTestCommon_UserBackRestGet BackRestTestCommon_TestPathGet BackRestTestCommon_DataPathGet
|
||||
BackRestTestCommon_BackupPathGet BackRestTestCommon_ArchivePathGet BackRestTestCommon_DbPathGet
|
||||
BackRestTestCommon_DbCommonPathGet BackRestTestCommon_DbTablespacePathGet BackRestTestCommon_DbPortGet);
|
||||
BackRestTestCommon_RepoPathGet BackRestTestCommon_LocalPathGet BackRestTestCommon_DbPathGet
|
||||
BackRestTestCommon_DbCommonPathGet BackRestTestCommon_ClusterStop BackRestTestCommon_DbTablespacePathGet
|
||||
BackRestTestCommon_DbPortGet);
|
||||
|
||||
my $strPgSqlBin;
|
||||
my $strCommonStanza;
|
||||
@ -49,8 +50,8 @@ my $strCommonGroup;
|
||||
my $strCommonUserBackRest;
|
||||
my $strCommonTestPath;
|
||||
my $strCommonDataPath;
|
||||
my $strCommonBackupPath;
|
||||
my $strCommonArchivePath;
|
||||
my $strCommonRepoPath;
|
||||
my $strCommonLocalPath;
|
||||
my $strCommonDbPath;
|
||||
my $strCommonDbCommonPath;
|
||||
my $strCommonDbTablespacePath;
|
||||
@ -67,6 +68,56 @@ my $hOut;
|
||||
my $pId;
|
||||
my $strCommand;
|
||||
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestCommon_ClusterStop
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_ClusterStop
|
||||
{
|
||||
my $strPath = shift;
|
||||
my $bImmediate = shift;
|
||||
|
||||
# Set default
|
||||
$strPath = defined($strPath) ? $strPath : BackRestTestCommon_DbCommonPathGet();
|
||||
$bImmediate = defined($bImmediate) ? $bImmediate : false;
|
||||
|
||||
# If postmaster process is running then stop the cluster
|
||||
if (-e $strPath . '/postmaster.pid')
|
||||
{
|
||||
BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/pg_ctl stop -D ${strPath} -w -s -m " .
|
||||
($bImmediate ? 'immediate' : 'fast'));
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestCommon_Drop
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_Drop
|
||||
{
|
||||
# Drop the cluster if it exists
|
||||
BackRestTestCommon_ClusterStop(BackRestTestCommon_DbCommonPathGet(), true);
|
||||
|
||||
# Remove the backrest private directory
|
||||
while (-e BackRestTestCommon_RepoPathGet())
|
||||
{
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), true, true);
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), false, true);
|
||||
hsleep(.1);
|
||||
}
|
||||
|
||||
# Remove the test directory
|
||||
BackRestTestCommon_PathRemove(BackRestTestCommon_TestPathGet());
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestCommon_Create
|
||||
####################################################################################################################################
|
||||
sub BackRestTestCommon_Create
|
||||
{
|
||||
# Create the test directory
|
||||
BackRestTestCommon_PathCreate(BackRestTestCommon_TestPathGet(), '0770');
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# BackRestTestCommon_Run
|
||||
####################################################################################################################################
|
||||
@ -403,8 +454,8 @@ sub BackRestTestCommon_Setup
|
||||
}
|
||||
|
||||
$strCommonDataPath = "${strBasePath}/test/data";
|
||||
$strCommonBackupPath = "${strCommonTestPath}/backrest";
|
||||
$strCommonArchivePath = "${strCommonTestPath}/archive";
|
||||
$strCommonRepoPath = "${strCommonTestPath}/backrest";
|
||||
$strCommonLocalPath = "${strCommonTestPath}/local";
|
||||
$strCommonDbPath = "${strCommonTestPath}/db";
|
||||
$strCommonDbCommonPath = "${strCommonTestPath}/db/common";
|
||||
$strCommonDbTablespacePath = "${strCommonTestPath}/db/tablespace";
|
||||
@ -442,12 +493,12 @@ sub BackRestTestCommon_ConfigRemap
|
||||
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute("mv " . BackRestTestCommon_BackupPathGet() . "/pg_backrest.conf ${strRemoteConfigFile}", true);
|
||||
BackRestTestCommon_Execute("mv " . BackRestTestCommon_RepoPathGet() . "/pg_backrest.conf ${strRemoteConfigFile}", true);
|
||||
ini_load($strRemoteConfigFile, \%oRemoteConfig);
|
||||
}
|
||||
|
||||
# Rewrite remap section
|
||||
delete($oConfig{"${strStanza}:tablespace:map"});
|
||||
delete($oConfig{"${strStanza}:restore:tablespace-map"});
|
||||
|
||||
foreach my $strRemap (sort(keys $oRemapHashRef))
|
||||
{
|
||||
@ -455,17 +506,17 @@ sub BackRestTestCommon_ConfigRemap
|
||||
|
||||
if ($strRemap eq 'base')
|
||||
{
|
||||
$oConfig{$strStanza}{path} = $strRemapPath;
|
||||
$oConfig{$strStanza}{'db-path'} = $strRemapPath;
|
||||
${$oManifestRef}{'backup:path'}{base} = $strRemapPath;
|
||||
|
||||
if ($bRemote)
|
||||
{
|
||||
$oRemoteConfig{$strStanza}{path} = $strRemapPath;
|
||||
$oRemoteConfig{$strStanza}{'db-path'} = $strRemapPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oConfig{"${strStanza}:tablespace:map"}{$strRemap} = $strRemapPath;
|
||||
$oConfig{"${strStanza}:restore:tablespace-map"}{$strRemap} = $strRemapPath;
|
||||
|
||||
${$oManifestRef}{'backup:path'}{"tablespace:${strRemap}"} = $strRemapPath;
|
||||
${$oManifestRef}{'backup:tablespace'}{$strRemap}{'path'} = $strRemapPath;
|
||||
@ -480,7 +531,7 @@ sub BackRestTestCommon_ConfigRemap
|
||||
if ($bRemote)
|
||||
{
|
||||
ini_save($strRemoteConfigFile, \%oRemoteConfig);
|
||||
BackRestTestCommon_Execute("mv ${strRemoteConfigFile} " . BackRestTestCommon_BackupPathGet() . '/pg_backrest.conf', true);
|
||||
BackRestTestCommon_Execute("mv ${strRemoteConfigFile} " . BackRestTestCommon_RepoPathGet() . '/pg_backrest.conf', true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,7 +557,7 @@ sub BackRestTestCommon_ConfigRecovery
|
||||
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_Execute("mv " . BackRestTestCommon_BackupPathGet() . "/pg_backrest.conf ${strRemoteConfigFile}", true);
|
||||
BackRestTestCommon_Execute("mv " . BackRestTestCommon_RepoPathGet() . "/pg_backrest.conf ${strRemoteConfigFile}", true);
|
||||
ini_load($strRemoteConfigFile, \%oRemoteConfig);
|
||||
}
|
||||
|
||||
@ -525,7 +576,7 @@ sub BackRestTestCommon_ConfigRecovery
|
||||
if ($bRemote)
|
||||
{
|
||||
ini_save($strRemoteConfigFile, \%oRemoteConfig);
|
||||
BackRestTestCommon_Execute("mv ${strRemoteConfigFile} " . BackRestTestCommon_BackupPathGet() . '/pg_backrest.conf', true);
|
||||
BackRestTestCommon_Execute("mv ${strRemoteConfigFile} " . BackRestTestCommon_RepoPathGet() . '/pg_backrest.conf', true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,34 +591,35 @@ sub BackRestTestCommon_ConfigCreate
|
||||
my $bChecksum = shift;
|
||||
my $bHardlink = shift;
|
||||
my $iThreadMax = shift;
|
||||
my $bArchiveLocal = shift;
|
||||
my $bArchiveAsync = shift;
|
||||
my $bCompressAsync = shift;
|
||||
|
||||
my %oParamHash;
|
||||
|
||||
if (defined($strRemote))
|
||||
{
|
||||
$oParamHash{'global:command'}{'remote'} = $strCommonCommandRemote;
|
||||
$oParamHash{'global:command'}{'command-remote'} = $strCommonCommandRemote;
|
||||
}
|
||||
|
||||
$oParamHash{'global:command'}{'psql'} = $strCommonCommandPsql;
|
||||
$oParamHash{'global:command'}{'command-psql'} = $strCommonCommandPsql;
|
||||
|
||||
if (defined($strRemote) && $strRemote eq BACKUP)
|
||||
{
|
||||
$oParamHash{'global:backup'}{'host'} = $strCommonHost;
|
||||
$oParamHash{'global:backup'}{'user'} = $strCommonUserBackRest;
|
||||
$oParamHash{'global:backup'}{'backup-host'} = $strCommonHost;
|
||||
$oParamHash{'global:backup'}{'backup-user'} = $strCommonUserBackRest;
|
||||
}
|
||||
elsif (defined($strRemote) && $strRemote eq DB)
|
||||
{
|
||||
$oParamHash{$strCommonStanza}{'host'} = $strCommonHost;
|
||||
$oParamHash{$strCommonStanza}{'user'} = $strCommonUser;
|
||||
$oParamHash{$strCommonStanza}{'db-host'} = $strCommonHost;
|
||||
$oParamHash{$strCommonStanza}{'db-user'} = $strCommonUser;
|
||||
}
|
||||
|
||||
$oParamHash{'global:log'}{'level-console'} = 'error';
|
||||
$oParamHash{'global:log'}{'level-file'} = 'trace';
|
||||
$oParamHash{'global:log'}{'log-level-console'} = 'error';
|
||||
$oParamHash{'global:log'}{'log-level-file'} = 'trace';
|
||||
|
||||
if ($strLocal eq BACKUP)
|
||||
{
|
||||
$oParamHash{'global:general'}{'repo-path'} = $strCommonRepoPath;
|
||||
}
|
||||
elsif ($strLocal eq DB)
|
||||
{
|
||||
@ -575,17 +627,24 @@ sub BackRestTestCommon_ConfigCreate
|
||||
{
|
||||
$oParamHash{'global:log'}{'level-console'} = 'trace';
|
||||
|
||||
if (!$bArchiveLocal)
|
||||
if ($bArchiveAsync)
|
||||
{
|
||||
$oParamHash{'global:restore'}{path} = BackRestTestCommon_ArchivePathGet();
|
||||
$oParamHash{'global:archive'}{path} = BackRestTestCommon_LocalPathGet();
|
||||
}
|
||||
|
||||
$oParamHash{'global:restore'}{'thread-max'} = $iThreadMax;
|
||||
|
||||
$oParamHash{'global:general'}{'repo-remote-path'} = $strCommonRepoPath;
|
||||
$oParamHash{'global:general'}{'repo-path'} = $strCommonLocalPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oParamHash{'global:general'}{'repo-path'} = $strCommonRepoPath;
|
||||
}
|
||||
|
||||
if ($bArchiveLocal)
|
||||
if ($bArchiveAsync)
|
||||
{
|
||||
$oParamHash{'global:archive'}{path} = BackRestTestCommon_ArchivePathGet();
|
||||
$oParamHash{'global:archive'}{'archive-async'} = 'y';
|
||||
|
||||
if (!$bCompressAsync)
|
||||
{
|
||||
@ -600,12 +659,12 @@ sub BackRestTestCommon_ConfigCreate
|
||||
|
||||
if (($strLocal eq BACKUP) || ($strLocal eq DB && !defined($strRemote)))
|
||||
{
|
||||
$oParamHash{'db:command:option'}{'psql'} = "--port=${iCommonDbPort}";
|
||||
$oParamHash{'db:command'}{'command-psql-option'} = "--port=${iCommonDbPort}";
|
||||
$oParamHash{'global:backup'}{'thread-max'} = $iThreadMax;
|
||||
|
||||
if (defined($bHardlink) && !$bHardlink)
|
||||
if (defined($bHardlink) && $bHardlink)
|
||||
{
|
||||
$oParamHash{'global:backup'}{'hardlink'} = 'n';
|
||||
$oParamHash{'global:backup'}{'hardlink'} = 'y';
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,8 +678,7 @@ sub BackRestTestCommon_ConfigCreate
|
||||
# $oParamHash{'global:backup'}{'checksum'} = 'y';
|
||||
# }
|
||||
|
||||
$oParamHash{$strCommonStanza}{'path'} = $strCommonDbCommonPath;
|
||||
$oParamHash{'global:backup'}{'path'} = $strCommonBackupPath;
|
||||
$oParamHash{$strCommonStanza}{'db-path'} = $strCommonDbCommonPath;
|
||||
|
||||
# Write out the configuration file
|
||||
my $strFile = BackRestTestCommon_TestPathGet() . '/pg_backrest.conf';
|
||||
@ -634,12 +692,12 @@ sub BackRestTestCommon_ConfigCreate
|
||||
}
|
||||
elsif ($strLocal eq 'backup' && !defined($strRemote))
|
||||
{
|
||||
rename($strFile, BackRestTestCommon_BackupPathGet() . '/pg_backrest.conf')
|
||||
or die "unable to move ${strFile} to " . BackRestTestCommon_BackupPathGet() . '/pg_backrest.conf path';
|
||||
rename($strFile, BackRestTestCommon_RepoPathGet() . '/pg_backrest.conf')
|
||||
or die "unable to move ${strFile} to " . BackRestTestCommon_RepoPathGet() . '/pg_backrest.conf path';
|
||||
}
|
||||
else
|
||||
{
|
||||
BackRestTestCommon_Execute("mv ${strFile} " . BackRestTestCommon_BackupPathGet() . '/pg_backrest.conf', true);
|
||||
BackRestTestCommon_Execute("mv ${strFile} " . BackRestTestCommon_RepoPathGet() . '/pg_backrest.conf', true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -696,14 +754,14 @@ sub BackRestTestCommon_DataPathGet
|
||||
return $strCommonDataPath;
|
||||
}
|
||||
|
||||
sub BackRestTestCommon_BackupPathGet
|
||||
sub BackRestTestCommon_RepoPathGet
|
||||
{
|
||||
return $strCommonBackupPath;
|
||||
return $strCommonRepoPath;
|
||||
}
|
||||
|
||||
sub BackRestTestCommon_ArchivePathGet
|
||||
sub BackRestTestCommon_LocalPathGet
|
||||
{
|
||||
return $strCommonArchivePath;
|
||||
return $strCommonLocalPath;
|
||||
}
|
||||
|
||||
sub BackRestTestCommon_DbPathGet
|
||||
|
@ -12,6 +12,7 @@ use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
use File::Basename qw(dirname);
|
||||
use Cwd qw(abs_path);
|
||||
use Scalar::Util 'blessed';
|
||||
#use Data::Dumper qw(Dumper);
|
||||
#use Scalar::Util qw(blessed);
|
||||
@ -21,7 +22,7 @@ use Scalar::Util 'blessed';
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
use BackRest::Param;
|
||||
use BackRest::Config;
|
||||
|
||||
use BackRestTest::CommonTest;
|
||||
|
||||
@ -41,8 +42,9 @@ sub optionSetBoolTest
|
||||
{
|
||||
my $oOption = shift;
|
||||
my $strKey = shift;
|
||||
my $bValue = shift;
|
||||
|
||||
$$oOption{boolean}{$strKey} = true;
|
||||
$$oOption{boolean}{$strKey} = defined($bValue) ? $bValue : true;
|
||||
}
|
||||
|
||||
sub operationSetTest
|
||||
@ -87,12 +89,7 @@ sub argvWriteTest
|
||||
{
|
||||
foreach my $strKey (keys $$oOption{option})
|
||||
{
|
||||
$ARGV[@ARGV] = "--${strKey}=";
|
||||
|
||||
if (defined($$oOption{option}{$strKey}))
|
||||
{
|
||||
$ARGV[@ARGV - 1] .= $$oOption{option}{$strKey};
|
||||
}
|
||||
$ARGV[@ARGV] = "--${strKey}=$$oOption{option}{$strKey}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +100,7 @@ sub argvWriteTest
|
||||
%$oOption = ();
|
||||
}
|
||||
|
||||
sub configLoadExpectError
|
||||
sub configLoadExpect
|
||||
{
|
||||
my $oOption = shift;
|
||||
my $strOperation = shift;
|
||||
@ -135,7 +132,8 @@ sub configLoadExpectError
|
||||
{
|
||||
if ($oMessage->code() != $iExpectedError)
|
||||
{
|
||||
confess "expected error ${iExpectedError} from configLoad but got " . $oMessage->code();
|
||||
confess "expected error ${iExpectedError} from configLoad but got " . $oMessage->code() .
|
||||
" '" . $oMessage->message() . "'";
|
||||
}
|
||||
|
||||
my $strError;
|
||||
@ -162,6 +160,22 @@ sub configLoadExpectError
|
||||
{
|
||||
$strError = "'${strErrorParam1}' is not valid for '${strErrorParam2}' option";
|
||||
}
|
||||
elsif ($iExpectedError == ERROR_OPTION_INVALID_RANGE)
|
||||
{
|
||||
$strError = "'${strErrorParam1}' is not valid for '${strErrorParam2}' option";
|
||||
}
|
||||
elsif ($iExpectedError == ERROR_OPTION_INVALID_PAIR)
|
||||
{
|
||||
$strError = "'${strErrorParam1}' not valid key/value for '${strErrorParam2}' option";
|
||||
}
|
||||
elsif ($iExpectedError == ERROR_OPTION_NEGATE)
|
||||
{
|
||||
$strError = "option '${strErrorParam1}' cannot be both set and negated";
|
||||
}
|
||||
elsif ($iExpectedError == ERROR_FILE_INVALID)
|
||||
{
|
||||
$strError = "'${strErrorParam1}' is not a file";
|
||||
}
|
||||
else
|
||||
{
|
||||
confess "must construct message for error ${iExpectedError}, use this as an example: '" . $oMessage->message() . "'";
|
||||
@ -193,13 +207,28 @@ sub optionTestExpect
|
||||
{
|
||||
my $strOption = shift;
|
||||
my $strExpectedValue = shift;
|
||||
my $strExpectedKey = shift;
|
||||
|
||||
if (defined($strExpectedValue))
|
||||
{
|
||||
my $strActualValue = optionGet($strOption);
|
||||
|
||||
if (defined($strExpectedKey))
|
||||
{
|
||||
# use Data::Dumper;
|
||||
# &log(INFO, Dumper($strActualValue));
|
||||
# exit 0;
|
||||
|
||||
$strActualValue = $$strActualValue{$strExpectedKey};
|
||||
}
|
||||
|
||||
if (!defined($strActualValue))
|
||||
{
|
||||
confess "expected option ${strOption} to have value ${strExpectedValue} but [undef] found instead";
|
||||
}
|
||||
|
||||
$strActualValue eq $strExpectedValue
|
||||
or confess "expected option ${strOption} to have value ${strExpectedValue}, but ${strActualValue} found instead";
|
||||
or confess "expected option ${strOption} to have value ${strExpectedValue} but ${strActualValue} found instead";
|
||||
}
|
||||
elsif (optionTest($strOption))
|
||||
{
|
||||
@ -219,73 +248,84 @@ sub BackRestTestConfig_Test
|
||||
my $bCreate;
|
||||
my $strStanza = 'main';
|
||||
my $oOption = {};
|
||||
my $oConfig = {};
|
||||
my @oyArray;
|
||||
my $strConfigFile = BackRestTestCommon_TestPathGet() . '/pg_backrest.conf';
|
||||
|
||||
use constant BOGUS => 'bogus';
|
||||
|
||||
# Print test banner
|
||||
&log(INFO, 'CONFIG MODULE ******************************************************************');
|
||||
BackRestTestCommon_Drop();
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
# Test config
|
||||
# Test command-line options
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
if ($strTest eq 'all' || $strTest eq 'option')
|
||||
{
|
||||
$iRun = 0;
|
||||
&log(INFO, "Option module\n");
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup with no stanza'))
|
||||
{
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_REQUIRED, OPTION_STANZA);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_REQUIRED, OPTION_STANZA);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup with boolean stanza'))
|
||||
{
|
||||
optionSetBoolTest($oOption, OPTION_STANZA);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP, , ERROR_OPERATION_REQUIRED);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPERATION_REQUIRED);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup type defaults to ' . BACKUP_TYPE_INCR))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_TYPE, BACKUP_TYPE_INCR);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup type set to ' . BACKUP_TYPE_FULL))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_TYPE, BACKUP_TYPE_FULL);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_TYPE, BACKUP_TYPE_FULL);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup type invalid'))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_TYPE, BOGUS);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_TYPE);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_TYPE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup invalid force'))
|
||||
{
|
||||
# $oOption = {};
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_FORCE);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP, ERROR_OPTION_INVALID, OPTION_FORCE, OPTION_NO_START_STOP);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID, OPTION_FORCE, OPTION_NO_START_STOP);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup valid force'))
|
||||
{
|
||||
# $oOption = {};
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_NO_START_STOP);
|
||||
optionSetBoolTest($oOption, OPTION_FORCE);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_NO_START_STOP, true);
|
||||
optionTestExpect(OPTION_FORCE, true);
|
||||
}
|
||||
@ -293,25 +333,28 @@ sub BackRestTestConfig_Test
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup invalid value for ' . OPTION_TEST_DELAY))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_TEST);
|
||||
optionSetTest($oOption, OPTION_TEST_DELAY, BOGUS);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_TEST_DELAY);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_TEST_DELAY);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup invalid ' . OPTION_TEST_DELAY))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_TEST_DELAY, 5);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_INVALID, OPTION_TEST_DELAY, OPTION_TEST);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID, OPTION_TEST_DELAY, OPTION_TEST);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'backup check ' . OPTION_TEST_DELAY . ' undef'))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_TEST_DELAY);
|
||||
}
|
||||
|
||||
@ -322,7 +365,7 @@ sub BackRestTestConfig_Test
|
||||
optionSetTest($oOption, OPTION_TARGET, BOGUS);
|
||||
|
||||
@oyArray = (RECOVERY_TYPE_NAME, RECOVERY_TYPE_TIME, RECOVERY_TYPE_XID);
|
||||
configLoadExpectError($oOption, OP_RESTORE , ERROR_OPTION_INVALID, OPTION_TARGET, OPTION_TYPE, \@oyArray);
|
||||
configLoadExpect($oOption, OP_RESTORE, ERROR_OPTION_INVALID, OPTION_TARGET, OPTION_TYPE, \@oyArray);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'restore ' . OPTION_TARGET))
|
||||
@ -331,7 +374,7 @@ sub BackRestTestConfig_Test
|
||||
optionSetTest($oOption, OPTION_TYPE, RECOVERY_TYPE_NAME);
|
||||
optionSetTest($oOption, OPTION_TARGET, BOGUS);
|
||||
|
||||
configLoadExpectError($oOption, OP_RESTORE);
|
||||
configLoadExpect($oOption, OP_RESTORE);
|
||||
optionTestExpect(OPTION_TYPE, RECOVERY_TYPE_NAME);
|
||||
optionTestExpect(OPTION_TARGET, BOGUS);
|
||||
optionTestExpect(OPTION_TARGET_TIMELINE);
|
||||
@ -340,43 +383,48 @@ sub BackRestTestConfig_Test
|
||||
if (BackRestTestCommon_Run(++$iRun, 'invalid string ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_THREAD_MAX, BOGUS);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_THREAD_MAX);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_THREAD_MAX);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'invalid float ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_THREAD_MAX, '0.0');
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP , ERROR_OPTION_INVALID_VALUE, '0.0', OPTION_THREAD_MAX);
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, '0.0', OPTION_THREAD_MAX);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'valid ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_THREAD_MAX, '2');
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'valid float ' . OPTION_TEST_DELAY))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_TEST);
|
||||
optionSetTest($oOption, OPTION_TEST_DELAY, '0.25');
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'valid int ' . OPTION_TEST_DELAY))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_TEST);
|
||||
optionSetTest($oOption, OPTION_TEST_DELAY, 3);
|
||||
|
||||
configLoadExpectError($oOption, OP_BACKUP);
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'restore valid ' . OPTION_TARGET_TIMELINE))
|
||||
@ -384,7 +432,383 @@ sub BackRestTestConfig_Test
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_TARGET_TIMELINE, 2);
|
||||
|
||||
configLoadExpectError($oOption, OP_RESTORE);
|
||||
configLoadExpect($oOption, OP_RESTORE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'invalid ' . OPTION_BUFFER_SIZE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_BUFFER_SIZE, '512');
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE, ERROR_OPTION_INVALID_RANGE, '512', OPTION_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' invalid option' . OPTION_RETENTION_ARCHIVE_TYPE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_RETENTION_ARCHIVE_TYPE, BOGUS);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID, OPTION_RETENTION_ARCHIVE_TYPE, OPTION_RETENTION_ARCHIVE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' invalid value ' . OPTION_RETENTION_ARCHIVE_TYPE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_RETENTION_ARCHIVE, 3);
|
||||
optionSetTest($oOption, OPTION_RETENTION_ARCHIVE_TYPE, BOGUS);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_RETENTION_ARCHIVE_TYPE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' valid value ' . OPTION_RETENTION_ARCHIVE_TYPE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_RETENTION_ARCHIVE, 1);
|
||||
optionSetTest($oOption, OPTION_RETENTION_ARCHIVE_TYPE, BACKUP_TYPE_FULL);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_RETENTION_ARCHIVE, 1);
|
||||
optionTestExpect(OPTION_RETENTION_ARCHIVE_TYPE, BACKUP_TYPE_FULL);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_RESTORE . ' invalid value ' . OPTION_RESTORE_RECOVERY_SETTING))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_RESTORE_RECOVERY_SETTING, '=');
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE, ERROR_OPTION_INVALID_PAIR, '=', OPTION_RESTORE_RECOVERY_SETTING);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_RESTORE . ' invalid value ' . OPTION_RESTORE_RECOVERY_SETTING))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_RESTORE_RECOVERY_SETTING, '=' . BOGUS);
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE, ERROR_OPTION_INVALID_PAIR, '=' . BOGUS, OPTION_RESTORE_RECOVERY_SETTING);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_RESTORE . ' invalid value ' . OPTION_RESTORE_RECOVERY_SETTING))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_RESTORE_RECOVERY_SETTING, BOGUS . '=');
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE, ERROR_OPTION_INVALID_PAIR, BOGUS . '=', OPTION_RESTORE_RECOVERY_SETTING);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_RESTORE . ' valid value ' . OPTION_RESTORE_RECOVERY_SETTING))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_RESTORE_RECOVERY_SETTING, 'primary-conn-info=db.domain.net');
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE);
|
||||
optionTestExpect(OPTION_RESTORE_RECOVERY_SETTING, 'db.domain.net', 'primary-conn-info');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' valid value ' . OPTION_COMMAND_PSQL))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_COMMAND_PSQL, '/psql -X %option%');
|
||||
optionSetTest($oOption, OPTION_COMMAND_PSQL_OPTION, '--port 5432');
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_COMMAND_PSQL, '/psql -X --port 5432');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' default value ' . OPTION_COMMAND_REMOTE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_COMMAND_PSQL, '/psql -X %option%');
|
||||
optionSetTest($oOption, OPTION_COMMAND_PSQL_OPTION, '--port 5432');
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_COMMAND_REMOTE, dirname(abs_path($0)) . '/pg_backrest_remote.pl');
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
# Test mixed command-line/config
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
if ($strTest eq 'all' || $strTest eq 'config')
|
||||
{
|
||||
$iRun = 0;
|
||||
&log(INFO, "Config module\n");
|
||||
|
||||
BackRestTestCommon_Create();
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'set and negate option ' . OPTION_CONFIG))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, '/dude/dude.conf');
|
||||
optionSetBoolTest($oOption, OPTION_CONFIG, false);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_NEGATE, OPTION_CONFIG);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'option ' . OPTION_CONFIG))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetBoolTest($oOption, OPTION_CONFIG, false);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_CONFIG);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'default option ' . OPTION_CONFIG))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_CONFIG, OPTION_DEFAULT_CONFIG);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'config file is a path'))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, BackRestTestCommon_TestPathGet());
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_FILE_INVALID, BackRestTestCommon_TestPathGet());
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'load from config stanza section - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{"$strStanza:" . &OP_BACKUP}{&OPTION_THREAD_MAX} = 2;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 2);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'load from config stanza inherited section - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{"$strStanza:" . &CONFIG_SECTION_GENERAL}{&OPTION_THREAD_MAX} = 3;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 3);
|
||||
}
|
||||
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'load from config global section - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &OP_BACKUP}{&OPTION_THREAD_MAX} = 2;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 2);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'load from config global inherited section - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_GENERAL}{&OPTION_THREAD_MAX} = 5;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 5);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'default - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 1);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'command-line override - option ' . OPTION_THREAD_MAX))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_GENERAL}{&OPTION_THREAD_MAX} = 9;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_THREAD_MAX, 7);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_THREAD_MAX, 7);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'invalid boolean - option ' . OPTION_HARDLINK))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &OP_BACKUP}{&OPTION_HARDLINK} = 'Y';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, 'Y', OPTION_HARDLINK);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'invalid value - option ' . OPTION_LOG_LEVEL_CONSOLE))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_LOG}{&OPTION_LOG_LEVEL_CONSOLE} = BOGUS;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP, ERROR_OPTION_INVALID_VALUE, BOGUS, OPTION_LOG_LEVEL_CONSOLE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'valid value - option ' . OPTION_LOG_LEVEL_CONSOLE))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_LOG}{&OPTION_LOG_LEVEL_CONSOLE} = lc(INFO);
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, 'archive-push - option ' . OPTION_LOG_LEVEL_CONSOLE))
|
||||
{
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_ARCHIVE_PUSH);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_EXPIRE . ' ' . OPTION_RETENTION_FULL))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_RETENTION}{&OPTION_RETENTION_FULL} = 2;
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_EXPIRE);
|
||||
optionTestExpect(OPTION_RETENTION_FULL, 2);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' option ' . OPTION_COMPRESS))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_BACKUP}{&OPTION_COMPRESS} = 'n';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_COMPRESS, false);
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_RESTORE . ' option ' . OPTION_RESTORE_RECOVERY_SETTING))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_RESTORE_RECOVERY_SETTING}{'archive-command'} = '/path/to/pg_backrest.pl';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_RESTORE);
|
||||
optionTestExpect(OPTION_RESTORE_RECOVERY_SETTING, '/path/to/pg_backrest.pl', 'archive-command');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' option ' . OPTION_DB_PATH))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$strStanza}{&OPTION_DB_PATH} = '/path/to/db';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_DB_PATH, '/path/to/db');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_ARCHIVE_PUSH . ' option ' . OPTION_DB_PATH))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$strStanza}{&OPTION_DB_PATH} = '/path/to/db';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_ARCHIVE_PUSH);
|
||||
optionTestExpect(OPTION_DB_PATH, '/path/to/db');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' option ' . OPTION_REPO_PATH))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_GENERAL}{&OPTION_REPO_PATH} = '/repo';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_REPO_PATH, '/repo');
|
||||
}
|
||||
|
||||
if (BackRestTestCommon_Run(++$iRun, OP_BACKUP . ' valid value ' . OPTION_COMMAND_PSQL))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_COMMAND}{&OPTION_COMMAND_PSQL} = '/psql -X %option%';
|
||||
$$oConfig{&CONFIG_GLOBAL . ':' . &CONFIG_SECTION_COMMAND}{&OPTION_COMMAND_PSQL_OPTION} = '--port=5432';
|
||||
ini_save($strConfigFile, $oConfig);
|
||||
|
||||
optionSetTest($oOption, OPTION_STANZA, $strStanza);
|
||||
optionSetTest($oOption, OPTION_DB_PATH, '/db');
|
||||
optionSetTest($oOption, OPTION_CONFIG, $strConfigFile);
|
||||
|
||||
configLoadExpect($oOption, OP_BACKUP);
|
||||
optionTestExpect(OPTION_COMMAND_PSQL, '/psql -X --port=5432');
|
||||
}
|
||||
|
||||
# Cleanup
|
||||
if (BackRestTestCommon_Cleanup())
|
||||
{
|
||||
&log(INFO, 'cleanup');
|
||||
BackRestTestCommon_Drop(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,9 +97,9 @@ sub BackRestTestFile_Test
|
||||
$strHost, # Host
|
||||
$strUser, # User
|
||||
BackRestTestCommon_CommandRemoteGet(), # Command
|
||||
CONFIG_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
OPTION_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
);
|
||||
|
||||
my $oLocal = new BackRest::Remote
|
||||
@ -107,9 +107,9 @@ sub BackRestTestFile_Test
|
||||
undef, # Host
|
||||
undef, # User
|
||||
undef, # Command
|
||||
CONFIG_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
CONFIG_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
OPTION_DEFAULT_BUFFER_SIZE, # Buffer size
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL, # Compress level
|
||||
OPTION_DEFAULT_COMPRESS_LEVEL_NETWORK, # Compress network level
|
||||
);
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -65,7 +65,7 @@ my $strLogLevel = 'info'; # Log level for tests
|
||||
my $strModule = 'all';
|
||||
my $strModuleTest = 'all';
|
||||
my $iModuleTestRun = undef;
|
||||
my $iThreadMax = 4;
|
||||
my $iThreadMax = 1;
|
||||
my $bDryRun = false;
|
||||
my $bNoCleanup = false;
|
||||
my $strPgSqlBin;
|
||||
|
Loading…
x
Reference in New Issue
Block a user