You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	The C library is now required.
This eliminates conditional loading and eases development of new library features.
This commit is contained in:
		| @@ -16,8 +16,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRest::Config::Define; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestBuild::Build::Common; | ||||
|   | ||||
| @@ -16,8 +16,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRest::Config::Define; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestBuild::Build::Common; | ||||
|   | ||||
| @@ -42,7 +42,7 @@ | ||||
| # CFGDEF_ALLOW_LIST: | ||||
| #   Lists the allowable settings for the option. | ||||
| #################################################################################################################################### | ||||
| package pgBackRest::Config::Data; | ||||
| package pgBackRestBuild::Config::Data; | ||||
| 
 | ||||
| use strict; | ||||
| use warnings FATAL => qw(all); | ||||
| @@ -13,7 +13,7 @@ use File::Basename qw(dirname); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| #################################################################################################################################### | ||||
|   | ||||
| @@ -17,21 +17,72 @@ use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Ini; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRest::Config::Define; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestBuild::Config::Data; | ||||
|  | ||||
| use BackRestDoc::Common::DocManifest; | ||||
|  | ||||
| use pgBackRestTest::Common::ExecuteTest; | ||||
| use pgBackRestTest::Common::HostTest; | ||||
| use pgBackRestTest::Common::HostGroupTest; | ||||
|  | ||||
| use BackRestDoc::Common::DocManifest; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # User that's building the docs | ||||
| #################################################################################################################################### | ||||
| use constant DOC_USER                                              => getpwuid($UID) eq 'root' ? 'ubuntu' : getpwuid($UID) . ''; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Generate indexed defines | ||||
| #################################################################################################################################### | ||||
| my $rhConfigDefineIndex = cfgDefine(); | ||||
|  | ||||
| foreach my $strKey (sort(keys(%{$rhConfigDefineIndex}))) | ||||
| { | ||||
|     # Build options for all possible db configurations | ||||
|     if (defined($rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX}) && | ||||
|         $rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX} eq CFGDEF_PREFIX_DB) | ||||
|     { | ||||
|         my $strPrefix = $rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX}; | ||||
|  | ||||
|         for (my $iIndex = 1; $iIndex <= CFGDEF_INDEX_DB; $iIndex++) | ||||
|         { | ||||
|             my $strKeyNew = "${strPrefix}${iIndex}" . substr($strKey, length($strPrefix)); | ||||
|  | ||||
|             $rhConfigDefineIndex->{$strKeyNew} = dclone($rhConfigDefineIndex->{$strKey}); | ||||
|  | ||||
|             $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX_TOTAL} = CFGDEF_INDEX_DB; | ||||
|             $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX} = $iIndex - 1; | ||||
|  | ||||
|             # Create the alternate name for option index 1 | ||||
|             if ($iIndex == 1) | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_ALT_NAME} = $strKey; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_REQUIRED} = false; | ||||
|             } | ||||
|  | ||||
|             if (defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}) && | ||||
|                 defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION})) | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION} = | ||||
|                     "${strPrefix}${iIndex}" . | ||||
|                     substr( | ||||
|                         $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION}, | ||||
|                         length($strPrefix)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         delete($rhConfigDefineIndex->{$strKey}); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         $rhConfigDefineIndex->{$strKey}{&CFGDEF_INDEX} = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # CONSTRUCTOR | ||||
| #################################################################################################################################### | ||||
| @@ -516,20 +567,17 @@ sub backrestConfig | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     # Get the config options hash | ||||
|                     my $rhOptionIndex = cfgDefineIndex(); | ||||
|  | ||||
|                     # Make sure the specified option exists | ||||
|                     # ??? This is too simplistic to handle new indexed options.  The check below works for now but it would be good | ||||
|                     # ??? to bring back more sophisticated checking in the future. | ||||
|                     # if (!defined($rhOptionIndex->{$strKey})) | ||||
|                     # if (!defined($rhConfigDefineIndex->{$strKey})) | ||||
|                     # { | ||||
|                     #     confess &log(ERROR, "option ${strKey} does not exist"); | ||||
|                     # } | ||||
|  | ||||
|                     # If this option is a hash and the value is already set then append to the array | ||||
|                     if (defined($rhOptionIndex->{$strKey}) && | ||||
|                         $rhOptionIndex->{$strKey}{&CFGDEF_TYPE} eq CFGDEF_TYPE_HASH && | ||||
|                     if (defined($rhConfigDefineIndex->{$strKey}) && | ||||
|                         $rhConfigDefineIndex->{$strKey}{&CFGDEF_TYPE} eq CFGDEF_TYPE_HASH && | ||||
|                         defined(${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey})) | ||||
|                     { | ||||
|                         my @oValue = (); | ||||
|   | ||||
| @@ -12,7 +12,7 @@ use Exporter qw(import); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRestBuild::Config::Data; | ||||
|  | ||||
| use BackRestDoc::Common::DocRender; | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,14 @@ | ||||
|     </intro> | ||||
|  | ||||
|     <release-list> | ||||
|         <release date="XXXX-XX-XX" version="1.27dev" title="UNDER DEVELOPMENT"> | ||||
|         <release date="XXXX-XX-XX" version="2.00dev" title="UNDER DEVELOPMENT"> | ||||
|             <release-core-list> | ||||
|                 <release-improvement-list> | ||||
|                     <release-item> | ||||
|                         <p>The C library is now required. This eliminates conditional loading and eases development of new library features.</p> | ||||
|                     </release-item> | ||||
|                 </release-improvement-list> | ||||
|  | ||||
|                 <release-development-list> | ||||
|                     <release-item> | ||||
|                         <p>Add <code>memGrowRaw()</code> to memory context module.</p> | ||||
|   | ||||
| @@ -290,7 +290,7 @@ | ||||
|         <!-- LibC installation - disabled for better testing of the C/Perl failback mechanism --> | ||||
|         <p><backrest/> includes an optional companion C library that enhances performance and enables the `checksum-page` option and encryption.  Pre-built packages are generally a better option than building the C library manually but the steps required are given below for completeness.  Depending on the distribution a number of packages may be required which will not be enumerated here.</p> | ||||
|  | ||||
|         <execute-list host="{[host-db-primary]}"> | ||||
|         <execute-list host="{[br-install-host]}"> | ||||
|             <title>Build and Install C Library</title> | ||||
|  | ||||
|             <execute user="root"> | ||||
|   | ||||
| @@ -16,6 +16,7 @@ use pgBackRest::Archive::Get::Get; | ||||
| use pgBackRest::Backup::Common; | ||||
| use pgBackRest::Backup::File; | ||||
| use pgBackRest::Backup::Info; | ||||
| use pgBackRest::Common::Cipher; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Exit; | ||||
| use pgBackRest::Common::Ini; | ||||
| @@ -25,7 +26,6 @@ use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::Db; | ||||
| use pgBackRest::DbVersion; | ||||
| use pgBackRest::LibCLoad; | ||||
| use pgBackRest::Manifest; | ||||
| use pgBackRest::Protocol::Local::Process; | ||||
| use pgBackRest::Protocol::Helper; | ||||
| @@ -654,7 +654,7 @@ sub process | ||||
|     # Generate a passphrase for the backup set if the repo is encrypted | ||||
|     if (defined($strCipherPassManifest) && !defined($strCipherPassBackupSet) && $strType eq CFGOPTVAL_BACKUP_TYPE_FULL) | ||||
|     { | ||||
|         $strCipherPassBackupSet = $oStorageRepo->cipherPassGen(); | ||||
|         $strCipherPassBackupSet = cipherPassGen(); | ||||
|     } | ||||
|  | ||||
|     # If backup label is not defined then create the label and path. | ||||
| @@ -705,19 +705,6 @@ sub process | ||||
|     my $hTablespaceMap = undef; | ||||
| 	my $hDatabaseMap = undef; | ||||
|  | ||||
|     # Only allow page checksums if the C library is available | ||||
|     if (!libC()) | ||||
|     { | ||||
|         # Warn if page checksums were expicitly requested | ||||
|         if (cfgOptionTest(CFGOPT_CHECKSUM_PAGE) && cfgOption(CFGOPT_CHECKSUM_PAGE)) | ||||
|         { | ||||
|             &log(WARN, "page checksums disabled - pgBackRest::LibC module is not present"); | ||||
|         } | ||||
|  | ||||
|         # Disable page checksums | ||||
|         cfgOptionSet(CFGOPT_CHECKSUM_PAGE, false); | ||||
|     } | ||||
|  | ||||
|     # If this is an offline backup | ||||
|     if (!cfgOption(CFGOPT_ONLINE)) | ||||
|     { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ use Exporter qw(import); | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::DbVersion qw(PG_PAGE_SIZE); | ||||
| use pgBackRest::LibCLoad; | ||||
| use pgBackRest::LibC qw(:checksum); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Package name constant | ||||
| @@ -23,16 +23,6 @@ use pgBackRest::LibCLoad; | ||||
| use constant BACKUP_FILTER_PAGECHECKSUM                             => __PACKAGE__; | ||||
|     push @EXPORT, qw(BACKUP_FILTER_PAGECHECKSUM); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Load the C library if present | ||||
| #################################################################################################################################### | ||||
| if (libC()) | ||||
| { | ||||
|     # Load the C library only if page checksums are required | ||||
|     require pgBackRest::LibC; | ||||
|     pgBackRest::LibC->import(qw(:checksum)); | ||||
| }; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # CONSTRUCTOR | ||||
| #################################################################################################################################### | ||||
|   | ||||
							
								
								
									
										48
									
								
								lib/pgBackRest/Common/Cipher.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/pgBackRest/Common/Cipher.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| #################################################################################################################################### | ||||
| # Cipher Miscellaneous | ||||
| #################################################################################################################################### | ||||
| package pgBackRest::Common::Cipher; | ||||
|  | ||||
| use strict; | ||||
| use warnings FATAL => qw(all); | ||||
| use Carp qw(confess); | ||||
| use English '-no_match_vars'; | ||||
|  | ||||
| use Exporter qw(import); | ||||
|     our @EXPORT = qw(); | ||||
|  | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::LibC qw(:random :encode); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cipherPassGen - generate a passphrase of the specified size (in bytes) | ||||
| #################################################################################################################################### | ||||
| sub cipherPassGen | ||||
| { | ||||
|     # Assign function parameters, defaults, and log debug info | ||||
|     my | ||||
|     ( | ||||
|         $strOperation, | ||||
|         $iKeySizeInBytes, | ||||
|     ) = | ||||
|         logDebugParam | ||||
|         ( | ||||
|             __PACKAGE__ . '::cipherPassGen', \@_, | ||||
|             {name => 'iKeySizeInBytes', default => 48}, | ||||
|         ); | ||||
|  | ||||
|     # Create and base64 encode the key | ||||
|     my $strCipherPass = encodeToStr(ENCODE_TYPE_BASE64, randomBytes($iKeySizeInBytes)); | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     return logDebugReturn | ||||
|     ( | ||||
|         $strOperation, | ||||
|         {name => 'strCipherPass', value => $strCipherPass, redact => true} | ||||
|     ); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cipherPassGen); | ||||
|  | ||||
| 1; | ||||
| @@ -20,13 +20,14 @@ use pgBackRest::Common::Io::Base; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Common::Wait; | ||||
| use pgBackRest::Config::LoadFailback; | ||||
| use pgBackRest::LibC qw(:config :configDefine); | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Export config constants and functions | ||||
| #################################################################################################################################### | ||||
| push(@EXPORT, @pgBackRest::Config::LoadFailback::EXPORT); | ||||
| push(@EXPORT, @{$pgBackRest::LibC::EXPORT_TAGS{config}}); | ||||
| push(@EXPORT, @{$pgBackRest::LibC::EXPORT_TAGS{configDefine}}); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # SOURCE Constants | ||||
|   | ||||
| @@ -1,571 +0,0 @@ | ||||
| #################################################################################################################################### | ||||
| # Configuration Definition Interface | ||||
| #################################################################################################################################### | ||||
| package pgBackRest::Config::Define; | ||||
|  | ||||
| use strict; | ||||
| use warnings FATAL => qw(all); | ||||
| use Carp qw(confess); | ||||
|  | ||||
| use Exporter qw(import); | ||||
|     our @EXPORT = qw(); | ||||
| use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Config::Data; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Generate indexed defines | ||||
| #################################################################################################################################### | ||||
| my $rhConfigDefineIndex = cfgDefine(); | ||||
|  | ||||
| foreach my $strKey (sort(keys(%{$rhConfigDefineIndex}))) | ||||
| { | ||||
|     # Build options for all possible db configurations | ||||
|     if (defined($rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX}) && | ||||
|         $rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX} eq CFGDEF_PREFIX_DB) | ||||
|     { | ||||
|         my $strPrefix = $rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX}; | ||||
|  | ||||
|         for (my $iIndex = 1; $iIndex <= CFGDEF_INDEX_DB; $iIndex++) | ||||
|         { | ||||
|             my $strKeyNew = "${strPrefix}${iIndex}" . substr($strKey, length($strPrefix)); | ||||
|  | ||||
|             $rhConfigDefineIndex->{$strKeyNew} = dclone($rhConfigDefineIndex->{$strKey}); | ||||
|  | ||||
|             $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX_TOTAL} = CFGDEF_INDEX_DB; | ||||
|             $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX} = $iIndex - 1; | ||||
|  | ||||
|             # Create the alternate name for option index 1 | ||||
|             if ($iIndex == 1) | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_ALT_NAME} = $strKey; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_REQUIRED} = false; | ||||
|             } | ||||
|  | ||||
|             if (defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}) && | ||||
|                 defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION})) | ||||
|             { | ||||
|                 $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION} = | ||||
|                     "${strPrefix}${iIndex}" . | ||||
|                     substr( | ||||
|                         $rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION}, | ||||
|                         length($strPrefix)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         delete($rhConfigDefineIndex->{$strKey}); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         $rhConfigDefineIndex->{$strKey}{&CFGDEF_INDEX} = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| my $iOptionTotal = scalar(keys(%{$rhConfigDefineIndex})); | ||||
|  | ||||
| sub cfgDefineIndex | ||||
| { | ||||
|     return dclone($rhConfigDefineIndex); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefineIndex); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Create maps to convert option ids to names and vice versa | ||||
| #################################################################################################################################### | ||||
| my $rhOptionNameId; | ||||
| my $rhOptionIdName; | ||||
| my $rhOptionNameAlt; | ||||
|  | ||||
| { | ||||
|     my $iIndex = 0; | ||||
|  | ||||
|     foreach my $strOption (sort(keys(%{$rhConfigDefineIndex}))) | ||||
|     { | ||||
|         $rhOptionNameId->{$strOption} = $iIndex; | ||||
|         $rhOptionNameAlt->{$strOption} = $strOption; | ||||
|         $rhOptionIdName->{$iIndex} = $strOption; | ||||
|  | ||||
|         if (defined(cfgDefOptionNameAlt($strOption))) | ||||
|         { | ||||
|             $rhOptionNameId->{cfgDefOptionNameAlt($strOption)} = $iIndex; | ||||
|             $rhOptionNameAlt->{cfgDefOptionNameAlt($strOption)} = $strOption; | ||||
|         } | ||||
|  | ||||
|         $iIndex++; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Get a define for the option from a command or default | ||||
| #################################################################################################################################### | ||||
| sub cfgOptionDefine | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = shift; | ||||
|     my $strDefine = shift; | ||||
|  | ||||
|     return | ||||
|         defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}) && | ||||
|         defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{$strDefine}) ? | ||||
|             $rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{$strDefine} : | ||||
|             $rhConfigDefineIndex->{$strOption}{$strDefine}; | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Functions that are noops in the Perl code since commands/options are always treated as strings | ||||
| #################################################################################################################################### | ||||
| sub cfgCommandId {return shift()} | ||||
| sub cfgCommandName {return shift()} | ||||
|  | ||||
| sub cfgOptionId | ||||
| { | ||||
|     my $strOptionName = shift; | ||||
|  | ||||
|     if (!defined($rhOptionNameId->{$strOptionName})) | ||||
|     { | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     return $rhOptionNameAlt->{$strOptionName}; | ||||
| } | ||||
|  | ||||
| sub cfgOptionName | ||||
| { | ||||
|     my $strOptionId = shift; | ||||
|  | ||||
|     if (defined($rhOptionIdName->{$strOptionId})) | ||||
|     { | ||||
|         return $rhOptionIdName->{$strOptionId}; | ||||
|     } | ||||
|  | ||||
|     return $rhOptionNameAlt->{$strOptionId}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgCommandId cfgCommandName cfgOptionId cfgOptionName); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgOptionTotal - total number of options | ||||
| #################################################################################################################################### | ||||
| sub cfgOptionTotal | ||||
| { | ||||
|     return $iOptionTotal; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgOptionTotal); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowList - does the option have a specific list of allowed values? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowList | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $bError = shift; | ||||
|  | ||||
|     my $rhAllowList = cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST); | ||||
|  | ||||
|     if (!defined($rhAllowList) && defined($bError) && $bError) | ||||
|     { | ||||
|         confess &log(ASSERT, "allow list not set for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     # The allow list must have values | ||||
|     if (defined($rhAllowList) && @{$rhAllowList} == 0) | ||||
|     { | ||||
|         confess &log(ASSERT, "allow list must have values for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     return defined($rhAllowList) ? true : false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowList); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowListValue - get an allow list value | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowListValue | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $iValueIdx = shift; | ||||
|  | ||||
|     # Index shouldn't be greater than the total number of values | ||||
|     if ($iValueIdx >= cfgDefOptionAllowListValueTotal($strCommand, $strOption, $iValueIdx)) | ||||
|     { | ||||
|         confess &log(ASSERT, "invalid allow list value index ${iValueIdx} for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     # Return value | ||||
|     return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)->[$iValueIdx]; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowListValue); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowListValueTotal - how many values are allowed for the option? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowListValueTotal | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     # Make sure the allow list exists | ||||
|     cfgDefOptionAllowList($strCommand, $strOption, true); | ||||
|  | ||||
|     # Return total elements in the list | ||||
|     return scalar(@{cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)}); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowListValueTotal); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowListValueValid - is the value valid for this option? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowListValueValid | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $strValue = shift; | ||||
|  | ||||
|     # Make sure the allow list exists | ||||
|     cfgDefOptionAllowList($strCommand, $strOption, true); | ||||
|  | ||||
|     # Check if the value is valid | ||||
|     foreach my $strValueMatch (@{cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)}) | ||||
|     { | ||||
|         if ($strValue eq $strValueMatch) | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowListValueValid); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowRange - does the option have min/max values? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowRange | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $bError = shift; | ||||
|  | ||||
|     my $rhAllowRange = cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE); | ||||
|  | ||||
|     if (!defined($rhAllowRange) && defined($bError) && $bError) | ||||
|     { | ||||
|         confess &log(ASSERT, "allow range not set for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     # The allow range must have two values | ||||
|     if (defined($rhAllowRange) && @{$rhAllowRange} != 2) | ||||
|     { | ||||
|         confess &log(ASSERT, "allow range must have two values for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     return defined($rhAllowRange) ? true : false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowRange); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowRangeMax - get max value in allowed range | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowRangeMax | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     # Make sure the allow range exists | ||||
|     cfgDefOptionAllowRange($strCommand, $strOption); | ||||
|  | ||||
|     # Return value | ||||
|     return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE)->[1]; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowRangeMax); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionAllowRangeMin - get min value in allowed range | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionAllowRangeMin | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     # Make sure the allow range exists | ||||
|     cfgDefOptionAllowRange($strCommand, $strOption); | ||||
|  | ||||
|     # Return value | ||||
|     return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE)->[0]; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionAllowRangeMin); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDefault - option default, if any | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDefault | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return cfgOptionDefine($strCommand, $strOption, CFGDEF_DEFAULT); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDefault); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDepend - does the option depend on another option being set or having a certain value? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDepend | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $bError = shift; | ||||
|  | ||||
|     my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND); | ||||
|  | ||||
|     if (!defined($rhDepend) && defined($bError) && $bError) | ||||
|     { | ||||
|         confess &log(ASSERT, "depend define not set for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     return defined($rhDepend) ? true : false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDepend); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDependOption - name of the option that this option depends on | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDependOption | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     # Make sure the depend define exists | ||||
|     cfgDefOptionDepend($strCommand, $strOption, true); | ||||
|  | ||||
|     # Error if the depend option does not exist | ||||
|     my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND); | ||||
|  | ||||
|     if (!defined($rhDepend->{&CFGDEF_DEPEND_OPTION})) | ||||
|     { | ||||
|         confess &log(ASSERT, "depend define option not set for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     return $rhDepend->{&CFGDEF_DEPEND_OPTION}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDependOption); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDependValue - get a depend option value | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDependValue | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $iValueIdx = shift; | ||||
|  | ||||
|     # Index shouldn't be greater than the total number of values | ||||
|     if ($iValueIdx >= cfgDefOptionDependValueTotal($strCommand, $strOption, $iValueIdx)) | ||||
|     { | ||||
|         confess &log(ASSERT, "invalid depend value index ${iValueIdx} for ${strCommand}, ${strOption}"); | ||||
|     } | ||||
|  | ||||
|     # Return value | ||||
|     return cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND)->{&CFGDEF_DEPEND_LIST}->[$iValueIdx]; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDependValue); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDependValueTotal - how many values are allowed for the depend option? | ||||
| # | ||||
| # 0 indicates that the value of the depend option doesn't matter, only that is is set. | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDependValueTotal | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     # Make sure the depend define exists | ||||
|     cfgDefOptionDepend($strCommand, $strOption, true); | ||||
|  | ||||
|     # It's OK for the list not to be defined | ||||
|     my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND); | ||||
|  | ||||
|     if (!defined($rhDepend->{&CFGDEF_DEPEND_LIST})) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     # Return total elements in the list | ||||
|     return scalar(@{$rhDepend->{&CFGDEF_DEPEND_LIST}}); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDependValueTotal); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionDependValueValid - is the depend valid valid? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionDependValueValid | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|     my $strValue = shift; | ||||
|  | ||||
|     # Make sure the depend define exists | ||||
|     cfgDefOptionDepend($strCommand, $strOption, true); | ||||
|  | ||||
|     # Check if the value is valid | ||||
|     foreach my $strValueMatch (@{cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND)->{&CFGDEF_DEPEND_LIST}}) | ||||
|     { | ||||
|         if ($strValue eq $strValueMatch) | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionDependValueValid); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgOptionIndex - index for option | ||||
| #################################################################################################################################### | ||||
| sub cfgOptionIndex | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_INDEX}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgOptionIndex); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgOptionIndexTotal - max index for options that are indexed (e.g., db) | ||||
| #################################################################################################################################### | ||||
| sub cfgOptionIndexTotal | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_INDEX_TOTAL}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgOptionIndexTotal); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionNameAlt - alternative or deprecated option name | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionNameAlt | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_ALT_NAME}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionNameAlt); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionNegate - is the boolean option negatable? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionNegate | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_NEGATE}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionNegate); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionPrefix - fixed prefix for indexed options | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionPrefix | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_PREFIX}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionPrefix); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionRequired - is the option required? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionRequired | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     my $rxDefine = cfgOptionDefine($strCommand, $strOption, CFGDEF_REQUIRED); | ||||
|     return defined($rxDefine) ? $rxDefine : true; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionRequired); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionSection - section to contain optio (global or stanza), all others are command-line only | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionSection | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_SECTION}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionSection); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionSecure - can the option be passed on the command-line? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionSecure | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_SECURE}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionSecure); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionType - data type of the option (e.g. boolean, string) | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionType | ||||
| { | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return $rhConfigDefineIndex->{$strOption}{&CFGDEF_TYPE}; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionType); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cfgDefOptionValid - is the option valid for the command? | ||||
| #################################################################################################################################### | ||||
| sub cfgDefOptionValid | ||||
| { | ||||
|     my $strCommand = shift; | ||||
|     my $strOption = cfgOptionName(shift); | ||||
|  | ||||
|     return | ||||
|         defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}) && | ||||
|         defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}) ? true : false; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(cfgDefOptionValid); | ||||
|  | ||||
| 1; | ||||
| @@ -1,37 +0,0 @@ | ||||
| #################################################################################################################################### | ||||
| # Load C or Perl Config Code | ||||
| #################################################################################################################################### | ||||
| package pgBackRest::Config::LoadFailback; | ||||
|  | ||||
| use strict; | ||||
| use warnings FATAL => qw(all); | ||||
| use Carp qw(confess); | ||||
|  | ||||
| use Exporter qw(import); | ||||
|     our @EXPORT = qw(); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::LibCLoad; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Load the C library if present, else failback to the Perl code | ||||
| #################################################################################################################################### | ||||
| if (libC()) | ||||
| { | ||||
|     require pgBackRest::LibC; | ||||
|     pgBackRest::LibC->import(qw(:config :configDefine)); | ||||
|     push(@EXPORT, @{$pgBackRest::LibC::EXPORT_TAGS{config}}); | ||||
|     push(@EXPORT, @{$pgBackRest::LibC::EXPORT_TAGS{configDefine}}); | ||||
| } | ||||
| else | ||||
| { | ||||
|     require pgBackRest::Config::Data; | ||||
|     pgBackRest::Config::Data->import(); | ||||
|     push(@EXPORT, @pgBackRest::Config::Data::EXPORT); | ||||
|  | ||||
|     require pgBackRest::Config::Define; | ||||
|     pgBackRest::Config::Define->import(); | ||||
|     push(@EXPORT, @pgBackRest::Config::Define::EXPORT); | ||||
| } | ||||
|  | ||||
| 1; | ||||
| @@ -1,39 +0,0 @@ | ||||
| #################################################################################################################################### | ||||
| # Determine if C Library is Present | ||||
| #################################################################################################################################### | ||||
| package pgBackRest::LibCLoad; | ||||
|  | ||||
| use strict; | ||||
| use warnings FATAL => qw(all); | ||||
| use Carp qw(confess); | ||||
|  | ||||
| use Exporter qw(import); | ||||
|     our @EXPORT = qw(); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Attempt to load the C Library | ||||
| #################################################################################################################################### | ||||
| my $bLibC = false; | ||||
|  | ||||
| eval | ||||
| { | ||||
|     # Attempt to load the C Library | ||||
|     require pgBackRest::LibC; | ||||
|     $bLibC = true; | ||||
|  | ||||
|     return 1; | ||||
| } or do {}; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # libC - is the C library present? | ||||
| #################################################################################################################################### | ||||
| sub libC | ||||
| { | ||||
|     return $bLibC; | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(libC); | ||||
|  | ||||
| 1; | ||||
| @@ -13,6 +13,7 @@ use English '-no_match_vars'; | ||||
| use Exporter qw(import); | ||||
|     our @EXPORT = qw(); | ||||
|  | ||||
| use pgBackRest::Common::Cipher; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Config::Config; | ||||
| @@ -450,9 +451,7 @@ sub infoObject | ||||
|         # else existed in the repo so a passphrase is generated to store in the file. If it exists and the repo is encrypted then | ||||
|         # the generated passphrase passed will not be used - the one from the info file will be read. | ||||
|         my $oParamRef = | ||||
|             {bIgnoreMissing => $bIgnoreMissing, | ||||
|              strCipherPassSub => defined(storageRepo()->cipherType()) ? | ||||
|                 storageRepo()->cipherPassGen() : undef}; | ||||
|             {bIgnoreMissing => $bIgnoreMissing, strCipherPassSub => defined(storageRepo()->cipherType()) ? cipherPassGen() : undef}; | ||||
|  | ||||
|         $oInfo = ($strPathType eq STORAGE_REPO_BACKUP ? | ||||
|             new pgBackRest::Backup::Info($strParentPath, false, $bRequired, $oParamRef) : | ||||
| @@ -498,9 +497,7 @@ sub infoObject | ||||
|             } | ||||
|  | ||||
|             my $oParamRef = | ||||
|                 {bLoad => false, | ||||
|                 strCipherPassSub => defined(storageRepo()->cipherType()) ? | ||||
|                     storageRepo()->cipherPassGen() : undef}; | ||||
|                 {bLoad => false, strCipherPassSub => defined(storageRepo()->cipherType()) ? cipherPassGen() : undef}; | ||||
|  | ||||
|             $oInfo = ($strPathType eq STORAGE_REPO_BACKUP ? | ||||
|                 new pgBackRest::Backup::Info($strParentPath, false, false, $oParamRef) : | ||||
|   | ||||
| @@ -909,39 +909,6 @@ sub encryptionValid | ||||
|     ); | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # cipherPassGen - generate a passphrase of the specified size (in bytes) | ||||
| #################################################################################################################################### | ||||
| sub cipherPassGen | ||||
| { | ||||
|     my $self = shift; | ||||
|  | ||||
|     # Assign function parameters, defaults, and log debug info | ||||
|     my | ||||
|     ( | ||||
|         $strOperation, | ||||
|         $iKeySizeInBytes, | ||||
|     ) = | ||||
|         logDebugParam | ||||
|         ( | ||||
|             __PACKAGE__ . '->cipherPassGen', \@_, | ||||
|             {name => 'iKeySizeInBytes', default => 48}, | ||||
|         ); | ||||
|  | ||||
|     require pgBackRest::LibC; | ||||
|     pgBackRest::LibC->import(qw(:random :encode)); | ||||
|  | ||||
|     # ??? Constant for base64 encoding can't used here because it is not loaded at parse time -- fix when the C library required | ||||
|     my $strCipherPass = encodeToStr(0, randomBytes($iKeySizeInBytes)); | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     return logDebugReturn | ||||
|     ( | ||||
|         $strOperation, | ||||
|         {name => 'strCipherPassSub', value => $strCipherPass, redact => true} | ||||
|     ); | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Getters | ||||
| #################################################################################################################################### | ||||
|   | ||||
| @@ -35,7 +35,7 @@ use constant BACKREST_BIN                                           => abs_path( | ||||
| # Defines the current version of the BackRest executable.  The version number is used to track features but does not affect what | ||||
| # repositories or manifests can be read - that's the job of the format number. | ||||
| #----------------------------------------------------------------------------------------------------------------------------------- | ||||
| use constant BACKREST_VERSION                                       => '1.27dev'; | ||||
| use constant BACKREST_VERSION                                       => '2.00dev'; | ||||
|     push @EXPORT, qw(BACKREST_VERSION); | ||||
|  | ||||
| # Format Format Number | ||||
|   | ||||
| @@ -19,7 +19,7 @@ use lib dirname($0) . '/../lib'; | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Storage::Local; | ||||
| use pgBackRest::Storage::Posix::Driver; | ||||
| use pgBackRest::Version; | ||||
|   | ||||
| @@ -16,8 +16,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRest::Config::Define; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestBuild::Build::Common; | ||||
|   | ||||
| @@ -16,8 +16,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRest::Config::Define; | ||||
| use pgBackRestBuild::Config::Data; | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestBuild::Build::Common; | ||||
|   | ||||
| @@ -6,7 +6,7 @@ package pgBackRest::LibCAuto; | ||||
| # Library version (.999 indicates development version) | ||||
| sub libcAutoVersion | ||||
| { | ||||
|     return '1.27.999'; | ||||
|     return '2.00.999'; | ||||
| } | ||||
|  | ||||
| # Configuration option value constants | ||||
|   | ||||
| @@ -43,9 +43,6 @@ use constant TESTDEF_EXPECT                                         => 'expect'; | ||||
| # Is this a C test (instead of Perl)? | ||||
| use constant TESTDEF_C                                              => 'c'; | ||||
|     push @EXPORT, qw(TESTDEF_C); | ||||
| # Is the C library required?  This only applies to unit tests, the C library is always supplied for integration tests. | ||||
| use constant TESTDEF_CLIB                                           => 'clib'; | ||||
|     push @EXPORT, qw(TESTDEF_CLIB); | ||||
| # Determines if each run in a test will be run in a new container | ||||
| use constant TESTDEF_INDIVIDUAL                                     => 'individual'; | ||||
|     push @EXPORT, qw(TESTDEF_INDIVIDUAL); | ||||
| @@ -142,7 +139,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'encode-perl', | ||||
|                     &TESTDEF_TOTAL => 1, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|                 }, | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'http-client', | ||||
| @@ -156,7 +152,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'ini', | ||||
|                     &TESTDEF_TOTAL => 10, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -316,7 +311,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'filter-cipher-block', | ||||
|                     &TESTDEF_TOTAL => 2, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -389,7 +383,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'local', | ||||
|                     &TESTDEF_TOTAL => 10, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -399,7 +392,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'helper', | ||||
|                     &TESTDEF_TOTAL => 5, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -445,7 +437,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'unit', | ||||
|                     &TESTDEF_TOTAL => 2, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -473,7 +464,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'push', | ||||
|                     &TESTDEF_TOTAL => 8, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -494,7 +484,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'info-unit', | ||||
|                     &TESTDEF_TOTAL => 4, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -504,7 +493,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'get', | ||||
|                     &TESTDEF_TOTAL => 2, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -533,7 +521,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'info-unit', | ||||
|                     &TESTDEF_TOTAL => 3, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
|                     { | ||||
| @@ -570,7 +557,6 @@ my $oTestDef = | ||||
|                 { | ||||
|                     &TESTDEF_NAME => 'all', | ||||
|                     &TESTDEF_TOTAL => 8, | ||||
|                     &TESTDEF_CLIB => true, | ||||
|                     &TESTDEF_CONTAINER => true, | ||||
|  | ||||
|                     &TESTDEF_COVERAGE => | ||||
| @@ -664,7 +650,7 @@ foreach my $hModule (@{$oTestDef->{&TESTDEF_MODULE}}) | ||||
|  | ||||
|         # Resolve variables that can be set in the module or the test | ||||
|         foreach my $strVar ( | ||||
|             TESTDEF_C, TESTDEF_CLIB, TESTDEF_CONTAINER, TESTDEF_EXPECT, TESTDEF_DB, TESTDEF_INDIVIDUAL, TESTDEF_VM) | ||||
|             TESTDEF_C, TESTDEF_CONTAINER, TESTDEF_EXPECT, TESTDEF_DB, TESTDEF_INDIVIDUAL, TESTDEF_VM) | ||||
|         { | ||||
|             $hTestDefHash->{$strModule}{$strTest}{$strVar} = coalesce( | ||||
|                 $hModuleTest->{$strVar}, $hModule->{$strVar}, $strVar eq TESTDEF_VM ? undef : false); | ||||
|   | ||||
| @@ -165,23 +165,20 @@ sub run | ||||
|                     {bSuppressStdErr => true}); | ||||
|  | ||||
|                 # Install Perl C Library | ||||
|                 if ($self->{oTest}->{&TEST_CLIB}) | ||||
|                 { | ||||
|                     my $oVm = vmGet(); | ||||
|                     my $strOS = $self->{oTest}->{&TEST_VM}; | ||||
|                     my $strBuildPath = $self->{strBackRestBase} . "/test/.vagrant/libc/$strOS/libc/"; | ||||
|                     my $strPerlAutoPath = $$oVm{$strOS}{&VMDEF_PERL_ARCH_PATH} . '/auto/pgBackRest/LibC'; | ||||
|                     my $strPerlModulePath = $$oVm{$strOS}{&VMDEF_PERL_ARCH_PATH} . '/pgBackRest'; | ||||
|                 my $oVm = vmGet(); | ||||
|                 my $strOS = $self->{oTest}->{&TEST_VM}; | ||||
|                 my $strBuildPath = $self->{strBackRestBase} . "/test/.vagrant/libc/$strOS/libc/"; | ||||
|                 my $strPerlAutoPath = $$oVm{$strOS}{&VMDEF_PERL_ARCH_PATH} . '/auto/pgBackRest/LibC'; | ||||
|                 my $strPerlModulePath = $$oVm{$strOS}{&VMDEF_PERL_ARCH_PATH} . '/pgBackRest'; | ||||
|  | ||||
|                     executeTest( | ||||
|                         "docker exec -i -u root ${strImage} bash -c '" . | ||||
|                         "mkdir -p -m 755 ${strPerlAutoPath} && " . | ||||
|                         "cp ${strBuildPath}/blib/arch/auto/pgBackRest/LibC/LibC.so ${strPerlAutoPath} && " . | ||||
|                         "cp ${strBuildPath}/blib/lib/auto/pgBackRest/LibC/autosplit.ix ${strPerlAutoPath} && " . | ||||
|                         "mkdir -p -m 755 ${strPerlModulePath} && " . | ||||
|                         "cp ${strBuildPath}/blib/lib/pgBackRest/LibC.pm ${strPerlModulePath} && " . | ||||
|                         "cp ${strBuildPath}/blib/lib/pgBackRest/LibCAuto.pm ${strPerlModulePath}'"); | ||||
|                 } | ||||
|                 executeTest( | ||||
|                     "docker exec -i -u root ${strImage} bash -c '" . | ||||
|                     "mkdir -p -m 755 ${strPerlAutoPath} && " . | ||||
|                     "cp ${strBuildPath}/blib/arch/auto/pgBackRest/LibC/LibC.so ${strPerlAutoPath} && " . | ||||
|                     "cp ${strBuildPath}/blib/lib/auto/pgBackRest/LibC/autosplit.ix ${strPerlAutoPath} && " . | ||||
|                     "mkdir -p -m 755 ${strPerlModulePath} && " . | ||||
|                     "cp ${strBuildPath}/blib/lib/pgBackRest/LibC.pm ${strPerlModulePath} && " . | ||||
|                     "cp ${strBuildPath}/blib/lib/pgBackRest/LibCAuto.pm ${strPerlModulePath}'"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -26,8 +26,6 @@ use constant TEST_DB                                                => 'db'; | ||||
|     push @EXPORT, qw(TEST_DB); | ||||
| use constant TEST_C                                                 => 'c'; | ||||
|     push @EXPORT, qw(TEST_C); | ||||
| use constant TEST_CLIB                                              => 'clib'; | ||||
|     push @EXPORT, qw(TEST_CLIB); | ||||
| use constant TEST_CONTAINER                                         => 'container'; | ||||
|     push @EXPORT, qw(TEST_CONTAINER); | ||||
| use constant TEST_MODULE                                            => 'module'; | ||||
| @@ -144,7 +142,6 @@ sub testListGet | ||||
|                                     { | ||||
|                                         &TEST_VM => $strTestOS, | ||||
|                                         &TEST_C => coalesce($hTest->{&TESTDEF_C}, $hModule->{&TESTDEF_C}, false), | ||||
|                                         &TEST_CLIB => coalesce($hTest->{&TESTDEF_CLIB}, $hModule->{&TESTDEF_CLIB}, false), | ||||
|                                         &TEST_CONTAINER => defined($hTest->{&TESTDEF_CONTAINER}) ? | ||||
|                                             $hTest->{&TESTDEF_CONTAINER} : $hModule->{&TESTDEF_CONTAINER}, | ||||
|                                         &TEST_PGSQL_BIN => $strPgSqlBin, | ||||
|   | ||||
| @@ -15,7 +15,7 @@ use English '-no_match_vars'; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::Config::Data; | ||||
| use pgBackRestBuild::Config::Data; | ||||
|  | ||||
| use constant CONFIGENVTEST                                          => 'ConfigEnvTest'; | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Archive::Info; | ||||
| use pgBackRest::Backup::Info; | ||||
| use pgBackRest::Common::Cipher; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Ini; | ||||
| use pgBackRest::Common::Lock; | ||||
| @@ -222,7 +223,7 @@ sub run | ||||
|         storageRepoCacheClear($self->stanza()); | ||||
|  | ||||
|         # Create an encrypted storage and generate an encyption sub passphrase to store in the file | ||||
|         my $strCipherPassSub = storageRepo()->cipherPassGen(); | ||||
|         my $strCipherPassSub = cipherPassGen(); | ||||
|  | ||||
|         # Error on encrypted repo but no passphrase passed to store in the file | ||||
|         $self->testException(sub {new pgBackRest::Archive::Info(storageRepo()->pathGet(STORAGE_REPO_ARCHIVE), false, | ||||
|   | ||||
| @@ -17,6 +17,7 @@ use Storable qw(dclone); | ||||
|  | ||||
| use pgBackRest::Archive::Info; | ||||
| use pgBackRest::Backup::Info; | ||||
| use pgBackRest::Common::Cipher; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Lock; | ||||
| use pgBackRest::Common::Log; | ||||
| @@ -225,7 +226,7 @@ sub run | ||||
|             {bIgnoreMissing => true})}, ERROR_ASSERT, | ||||
|             'a user passphrase and sub passphrase are both required when encrypting'); | ||||
|  | ||||
|         my $strCipherPassSub = storageRepo()->cipherPassGen(); | ||||
|         my $strCipherPassSub = cipherPassGen(); | ||||
|  | ||||
|         # Create encrypted files | ||||
|         $oBackupInfo = new pgBackRest::Backup::Info(storageRepo()->pathGet(STORAGE_REPO_BACKUP), false, false, | ||||
|   | ||||
| @@ -18,6 +18,7 @@ use Storable qw(dclone); | ||||
| use pgBackRest::Archive::Common; | ||||
| use pgBackRest::Archive::Info; | ||||
| use pgBackRest::Backup::Info; | ||||
| use pgBackRest::Common::Cipher; | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Ini; | ||||
| use pgBackRest::Common::Lock; | ||||
| @@ -325,7 +326,7 @@ sub run | ||||
|         # Get the encryption passphrase and create the new manifest | ||||
|         my $oBackupInfo = new pgBackRest::Backup::Info($self->{strBackupPath}); | ||||
|         $oBackupManifest = new pgBackRest::Manifest($strBackupManifestFile, {bLoad => false, strDbVersion => PG_VERSION_94, | ||||
|             strCipherPass => $oBackupInfo->cipherPassSub(), strCipherPassSub => storageRepo()->cipherPassGen()}); | ||||
|             strCipherPass => $oBackupInfo->cipherPassSub(), strCipherPassSub => cipherPassGen()}); | ||||
|  | ||||
|         $oBackupManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL, undef, $strBackupLabel); | ||||
|         $oBackupManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_ARCHIVE_CHECK, undef, true); | ||||
| @@ -518,11 +519,11 @@ sub run | ||||
|         # Create encrypted info files with prior passphrase then attempt to change | ||||
|         #--------------------------------------------------------------------------------------------------------------------------- | ||||
|         $oArchiveInfo = new pgBackRest::Archive::Info($self->{strArchivePath}, false, {bIgnoreMissing => true, | ||||
|             strCipherPassSub => storageRepo()->cipherPassGen()}); | ||||
|             strCipherPassSub => cipherPassGen()}); | ||||
|         $oArchiveInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), true); | ||||
|  | ||||
|         $oBackupInfo = new pgBackRest::Backup::Info($self->{strBackupPath}, false, false, {bIgnoreMissing => true, | ||||
|             strCipherPassSub => storageRepo()->cipherPassGen()}); | ||||
|             strCipherPassSub => cipherPassGen()}); | ||||
|         $oBackupInfo->create(PG_VERSION_93, $self->dbSysId(PG_VERSION_93), '937', '201306121', true); | ||||
|  | ||||
|          # Attempt to upgrade with a different passphrase | ||||
|   | ||||
		Reference in New Issue
	
	Block a user