You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +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:
		| @@ -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,39 +254,31 @@ 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 (!optionTest(OPTION_TEST_NO_FORK) && fork()) | ||||
|         { | ||||
|             if (fork()) | ||||
|             { | ||||
|                 remote_exit(0); | ||||
|             } | ||||
|             remote_exit(0); | ||||
|         } | ||||
|         # Else the no-fork flag has been specified for testing | ||||
|         else | ||||
|         { | ||||
|             &log(INFO, 'No fork on archive local for TESTING'); | ||||
|         } | ||||
|  | ||||
|         # Start the async archive push | ||||
|         &log(INFO, 'starting async archive-push'); | ||||
|     } | ||||
|  | ||||
|     # 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'); | ||||
|     # } | ||||
|  | ||||
|     &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,93 +292,49 @@ 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, | ||||
|             remote_get(false, config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL), | ||||
|                               config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_COMPRESS_LEVEL_NETWORK)) | ||||
|         ); | ||||
|     # Create the file object | ||||
|     my $oFile = new BackRest::File | ||||
|     ( | ||||
|         optionGet(OPTION_STANZA), | ||||
|         $strRemote eq NONE ? optionGet(OPTION_REPO_PATH) : optionGet(OPTION_REPO_REMOTE_PATH), | ||||
|         $strRemote, | ||||
|         remote_get(false, optionGet(OPTION_COMPRESS_LEVEL), | ||||
|                           optionGet(OPTION_COMPRESS_LEVEL_NETWORK)) | ||||
|     ); | ||||
|  | ||||
|         # Init backup | ||||
|         backup_init | ||||
|         ( | ||||
|             undef, | ||||
|             $oFile, | ||||
|             undef, | ||||
|             $bCompress, | ||||
|             undef, | ||||
|             config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_MAX), | ||||
|             undef, | ||||
|             config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_THREAD_TIMEOUT) | ||||
|         ); | ||||
|     # Init backup | ||||
|     backup_init | ||||
|     ( | ||||
|         undef, | ||||
|         $oFile, | ||||
|         undef, | ||||
|         $bCompress, | ||||
|         undef, | ||||
|         1, #optionGet(OPTION_THREAD_MAX), | ||||
|         undef, | ||||
|         optionGet(OPTION_THREAD_TIMEOUT, false) | ||||
|     ); | ||||
|  | ||||
|         # Call the archive_xfer function and continue to loop as long as there are files to process | ||||
|         my $iLogTotal; | ||||
|     # Call the archive_xfer function and continue to loop as long as there are files to process | ||||
|     my $iLogTotal; | ||||
|  | ||||
|         while (!defined($iLogTotal) || $iLogTotal > 0) | ||||
|     while (!defined($iLogTotal) || $iLogTotal > 0) | ||||
|     { | ||||
|         $iLogTotal = archive_xfer($strArchivePath . "/archive/" . optionGet(OPTION_STANZA) . "/out", $strStopFile, | ||||
|                                   $strCommand, $iArchiveMaxMB); | ||||
|  | ||||
|         if ($iLogTotal > 0) | ||||
|         { | ||||
|             $iLogTotal = archive_xfer($strArchivePath . "/archive/" . optionGet(OPTION_STANZA), $strStopFile, | ||||
|                                       $strCommand, $iArchiveMaxMB); | ||||
|  | ||||
|             if ($iLogTotal > 0) | ||||
|             { | ||||
|                 &log(DEBUG, "${iLogTotal} archive logs were transferred, calling archive_xfer() again"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 &log(DEBUG, 'no more logs to transfer - exiting'); | ||||
|             } | ||||
|             &log(DEBUG, "${iLogTotal} archive logs were transferred, calling archive_xfer() again"); | ||||
|         } | ||||
|     # | ||||
|     # }; | ||||
|  | ||||
|     # # 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 $@; | ||||
|     #     } | ||||
|     # } | ||||
|         else | ||||
|         { | ||||
|             &log(DEBUG, 'no more logs to transfer - exiting'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     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,14 +325,15 @@ sub archive_push | ||||
|     } | ||||
|  | ||||
|     # Copy the archive file | ||||
|     $oFile->copy(PATH_DB_ABSOLUTE, $strSourceFile,             # Source file | ||||
|                  PATH_BACKUP_ARCHIVE, $strDestinationFile,     # Destination file | ||||
|                  false,                                        # Source is not compressed | ||||
|                  $bArchiveFile && $bCompress,                  # Destination compress is configurable | ||||
|                  undef, undef, undef,                          # Unused params | ||||
|                  true,                                         # Create path if it does not exist | ||||
|                  undef, undef,                                 # User and group | ||||
|                  $bArchiveFile);                               # Append checksum if archive 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 | ||||
|                  true,                                                      # Create path if it does not exist | ||||
|                  undef, undef,                                              # User and group | ||||
|                  $bArchiveFile);                                            # Append checksum if archive file | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| @@ -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,21 +36,28 @@ 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 | ||||
| #################################################################################################################################### | ||||
| use constant | ||||
| { | ||||
|     PATH_ABSOLUTE        => 'absolute', | ||||
|     PATH_DB              => 'db', | ||||
|     PATH_DB_ABSOLUTE     => 'db:absolute', | ||||
|     PATH_BACKUP          => 'backup', | ||||
|     PATH_BACKUP_ABSOLUTE => 'backup:absolute', | ||||
|     PATH_BACKUP_CLUSTER  => 'backup:cluster', | ||||
|     PATH_BACKUP_TMP      => 'backup:tmp', | ||||
|     PATH_BACKUP_ARCHIVE  => 'backup:archive' | ||||
|     PATH_ABSOLUTE           => 'absolute', | ||||
|     PATH_DB                 => 'db', | ||||
|     PATH_DB_ABSOLUTE        => 'db:absolute', | ||||
|     PATH_BACKUP             => 'backup', | ||||
|     PATH_BACKUP_ABSOLUTE    => 'backup:absolute', | ||||
|     PATH_BACKUP_CLUSTER     => 'backup:cluster', | ||||
|     PATH_BACKUP_TMP         => 'backup:tmp', | ||||
|     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,28 +277,39 @@ 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"; | ||||
|         } | ||||
|  | ||||
|         if (defined($strFile)) | ||||
|         $strArchivePath .= "/$self->{strStanza}"; | ||||
|  | ||||
|         if ($strType eq PATH_BACKUP_ARCHIVE) | ||||
|         { | ||||
|             $strArchive = substr(basename($strFile), 0, 24); | ||||
|             my $strArchive; | ||||
|  | ||||
|             if ($strArchive !~ /^([0-F]){24}$/) | ||||
|             if (defined($strFile)) | ||||
|             { | ||||
|                 return "${strArchivePath}/${strFile}"; | ||||
|             } | ||||
|         } | ||||
|                 $strArchive = substr(basename($strFile), 0, 24); | ||||
|  | ||||
|         return $strArchivePath . (defined($strArchive) ? '/' . substr($strArchive, 0, 16) : '') . | ||||
|                (defined($strFile) ? '/' . $strFile : ''); | ||||
|                 if ($strArchive !~ /^([0-F]){24}$/) | ||||
|                 { | ||||
|                     return "${strArchivePath}/${strFile}"; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             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(); | ||||
|     # 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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user