You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-08-10 22:21:39 +02:00
The pgbackrest executable is now a C binary instead of Perl.
This allows certain time-critical commands (like async archive-push) to run more quickly.
This commit is contained in:
293
bin/pgbackrest
293
bin/pgbackrest
@@ -1,293 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
####################################################################################################################################
|
||||
# pgBackRest - Reliable PostgreSQL Backup & Restore
|
||||
####################################################################################################################################
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
####################################################################################################################################
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
# Convert die to confess to capture the stack trace
|
||||
$SIG{__DIE__} = sub { Carp::confess @_ };
|
||||
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Exit;
|
||||
use pgBackRest::Common::Lock;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
use pgBackRest::Protocol::Helper;
|
||||
|
||||
####################################################################################################################################
|
||||
# Run in eval block to catch errors
|
||||
####################################################################################################################################
|
||||
eval
|
||||
{
|
||||
################################################################################################################################
|
||||
# Load command line parameters and config
|
||||
################################################################################################################################
|
||||
my $bConfigResult = configLoad();
|
||||
|
||||
# Display help and version
|
||||
if (cfgCommandTest(CFGCMD_HELP) || cfgCommandTest(CFGCMD_VERSION))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Config::ConfigHelp;
|
||||
pgBackRest::Config::ConfigHelp->import();
|
||||
|
||||
# Generate help and exit
|
||||
configHelp($ARGV[1], $ARGV[2], cfgCommandTest(CFGCMD_VERSION), $bConfigResult);
|
||||
exitSafe(0);
|
||||
}
|
||||
|
||||
# Set test options
|
||||
if (cfgOptionTest(CFGOPT_TEST) && cfgOption(CFGOPT_TEST))
|
||||
{
|
||||
testSet(cfgOption(CFGOPT_TEST), cfgOption(CFGOPT_TEST_DELAY), cfgOption(CFGOPT_TEST_POINT, false));
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process archive-push command
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_ARCHIVE_PUSH))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Archive::Push::Push;
|
||||
pgBackRest::Archive::Push::Push->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Push::Push()->process($ARGV[1]));
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process archive-get command
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_ARCHIVE_GET))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Archive::Get::Get;
|
||||
pgBackRest::Archive::Get::Get->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Get::Get()->process());
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process remote commands
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_REMOTE))
|
||||
{
|
||||
# Set log levels
|
||||
cfgOptionSet(CFGOPT_LOG_LEVEL_STDERR, PROTOCOL, true);
|
||||
logLevelSet(OFF, OFF, cfgOption(CFGOPT_LOG_LEVEL_STDERR));
|
||||
|
||||
if (cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) && !cfgOptionTest(CFGOPT_REPO_TYPE, CFGOPTVAL_REPO_TYPE_S3) &&
|
||||
!-e cfgOption(CFGOPT_REPO_PATH))
|
||||
{
|
||||
confess &log(ERROR, 'repo-path \'' . cfgOption(CFGOPT_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Protocol::Remote::Minion;
|
||||
pgBackRest::Protocol::Remote::Minion->import();
|
||||
|
||||
# Create the remote object
|
||||
my $oRemote = new pgBackRest::Protocol::Remote::Minion(cfgOption(CFGOPT_BUFFER_SIZE), cfgOption(CFGOPT_PROTOCOL_TIMEOUT));
|
||||
|
||||
# Acquire a remote lock (except for commands that are read-only or local processes)
|
||||
my $strLockName;
|
||||
|
||||
if (!(cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_ARCHIVE_GET)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_INFO)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_RESTORE)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_CHECK)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_LOCAL))))
|
||||
{
|
||||
$strLockName = cfgOption(CFGOPT_COMMAND);
|
||||
}
|
||||
|
||||
# Process remote requests
|
||||
exitSafe($oRemote->process($strLockName));
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process local commands
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_LOCAL))
|
||||
{
|
||||
# Set log levels
|
||||
cfgOptionSet(CFGOPT_LOG_LEVEL_STDERR, PROTOCOL, true);
|
||||
logLevelSet(OFF, OFF, cfgOption(CFGOPT_LOG_LEVEL_STDERR));
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Protocol::Local::Minion;
|
||||
pgBackRest::Protocol::Local::Minion->import();
|
||||
|
||||
# Create the local object
|
||||
my $oLocal = new pgBackRest::Protocol::Local::Minion();
|
||||
|
||||
# Process local requests
|
||||
exitSafe($oLocal->process());
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process check command
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_CHECK))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Check::Check;
|
||||
pgBackRest::Check::Check->import();
|
||||
|
||||
exitSafe(new pgBackRest::Check::Check()->process());
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process start/stop commands
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_START))
|
||||
{
|
||||
lockStart();
|
||||
exitSafe(0);
|
||||
}
|
||||
elsif (cfgCommandTest(CFGCMD_STOP))
|
||||
{
|
||||
lockStop();
|
||||
exitSafe(0);
|
||||
}
|
||||
|
||||
# Check that the repo path exists
|
||||
require pgBackRest::Protocol::Storage::Helper;
|
||||
pgBackRest::Protocol::Storage::Helper->import();
|
||||
|
||||
if (isRepoLocal() && !cfgOptionTest(CFGOPT_REPO_TYPE, CFGOPTVAL_REPO_TYPE_S3) && !storageRepo()->pathExists(''))
|
||||
{
|
||||
confess &log(ERROR, 'repo-path \'' . cfgOption(CFGOPT_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Process info command
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_INFO))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Info;
|
||||
pgBackRest::Info->import();
|
||||
|
||||
exitSafe(new pgBackRest::Info()->process());
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Acquire the command lock
|
||||
################################################################################################################################
|
||||
lockAcquire(cfgCommandName(cfgCommandGet()));
|
||||
|
||||
################################################################################################################################
|
||||
# Open the log file
|
||||
################################################################################################################################
|
||||
require pgBackRest::Storage::Helper;
|
||||
pgBackRest::Storage::Helper->import();
|
||||
|
||||
logFileSet(
|
||||
storageLocal(), cfgOption(CFGOPT_LOG_PATH) . '/' . cfgOption(CFGOPT_STANZA) . '-' . lc(cfgCommandName(cfgCommandGet())));
|
||||
|
||||
################################################################################################################################
|
||||
# Process stanza-create command
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_STANZA_CREATE) || cfgCommandTest(CFGCMD_STANZA_UPGRADE))
|
||||
{
|
||||
if (!isRepoLocal())
|
||||
{
|
||||
confess &log(ERROR, cfgCommandName(cfgCommandGet()) . ' command must be run on the backup host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Stanza;
|
||||
pgBackRest::Stanza->import();
|
||||
|
||||
exitSafe(new pgBackRest::Stanza()->process());
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# RESTORE
|
||||
################################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_RESTORE))
|
||||
{
|
||||
if (!isDbLocal())
|
||||
{
|
||||
confess &log(ERROR, 'restore command must be run on the db host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Restore;
|
||||
pgBackRest::Restore->import();
|
||||
|
||||
# Do the restore
|
||||
new pgBackRest::Restore()->process();
|
||||
|
||||
exitSafe(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
############################################################################################################################
|
||||
# Make sure backup and expire commands happen on the backup side
|
||||
############################################################################################################################
|
||||
if (!isRepoLocal())
|
||||
{
|
||||
confess &log(ERROR, 'backup and expire commands must be run on the backup host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# BACKUP
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_BACKUP))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Backup::Backup;
|
||||
pgBackRest::Backup::Backup->import();
|
||||
|
||||
new pgBackRest::Backup::Backup()->process();
|
||||
|
||||
cfgCommandSet(CFGCMD_EXPIRE);
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# EXPIRE
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_EXPIRE))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Expire;
|
||||
pgBackRest::Expire->import();
|
||||
|
||||
new pgBackRest::Expire()->process();
|
||||
}
|
||||
}
|
||||
|
||||
lockRelease();
|
||||
exitSafe(0);
|
||||
|
||||
# uncoverable statement - exit should happen above
|
||||
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
|
||||
exit ERROR_ASSERT; # uncoverable statement
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Check for errors
|
||||
####################################################################################################################################
|
||||
or do
|
||||
{
|
||||
# Perl 5.10 seems to have a problem propogating errors up through a large call stack, so in the case that the error arrives
|
||||
# blank just use the last logged error instead. Don't do this in all cases because newer Perls seem to work fine and there are
|
||||
# other errors that could be arriving in $EVAL_ERROR.
|
||||
exitSafe(undef, defined($EVAL_ERROR) && length($EVAL_ERROR) > 0 ? $EVAL_ERROR : logErrorLast());
|
||||
};
|
||||
|
||||
# uncoverable statement - errors should be handled in the do block above
|
||||
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
|
||||
exit ERROR_ASSERT; # uncoverable statement
|
@@ -16,6 +16,10 @@
|
||||
<release-item>
|
||||
<p>The C library is now required. This eliminates conditional loading and eases development of new library features.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>The <file>{[project-exe]}</file> executable is now a C binary instead of Perl. This allows certain time-critical commands (like async <cmd>archive-push</cmd>) to run more quickly.</p>
|
||||
</release-item>
|
||||
</release-improvement-list>
|
||||
|
||||
<release-development-list>
|
||||
|
@@ -234,9 +234,6 @@
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>mkdir /root/pgbackrest-release-{[version]}</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>cp -r /backrest/bin /root/pgbackrest-release-{[version]}</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root" show="n">
|
||||
<exe-cmd>cp -r /backrest/build /root/pgbackrest-release-{[version]}</exe-cmd>
|
||||
</execute>
|
||||
@@ -264,12 +261,6 @@
|
||||
<execute user="root">
|
||||
<exe-cmd>find {[perl-lib-path]}/pgBackRest -type d -exec chmod 755 {} +</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root">
|
||||
<exe-cmd>cp /root/pgbackrest-release-{[version]}/bin/{[project-exe]} {[perl-bin-path]}/{[project-exe]}</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root">
|
||||
<exe-cmd>chmod 755 {[perl-bin-path]}/{[project-exe]}</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root">
|
||||
<exe-cmd>mkdir -m 770 /var/log/pgbackrest</exe-cmd>
|
||||
</execute>
|
||||
@@ -287,8 +278,8 @@
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<!-- 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>
|
||||
<!-- LibC installation -->
|
||||
<p><backrest/> includes a 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="{[br-install-host]}">
|
||||
<title>Build and Install C Library</title>
|
||||
@@ -304,6 +295,20 @@
|
||||
<exe-cmd>make -C /root/pgbackrest-release-{[version]}/libc install</exe-cmd>
|
||||
</execute>
|
||||
</execute-list>
|
||||
|
||||
<!-- Bin installation -->
|
||||
<p>Although most of <backrest/> is written in Perl, the main executable is written in C. This allows certain time-critical commands (like async <cmd>archive-push</cmd>) to run more quickly.</p>
|
||||
|
||||
<execute-list host="{[br-install-host]}">
|
||||
<title>Build and Install Binary</title>
|
||||
|
||||
<execute user="root" err-suppress="y">
|
||||
<exe-cmd>make -C /root/pgbackrest-release-{[version]}/src</exe-cmd>
|
||||
</execute>
|
||||
<execute user="root">
|
||||
<exe-cmd>make -C /root/pgbackrest-release-{[version]}/src install</exe-cmd>
|
||||
</execute>
|
||||
</execute-list>
|
||||
</block-define>
|
||||
|
||||
<block-define id="br-install-repo">
|
||||
|
@@ -43,7 +43,7 @@ sub new
|
||||
logDebugParam
|
||||
(
|
||||
__PACKAGE__ . '->new', \@_,
|
||||
{name => 'strBackRestBin', default => BACKREST_BIN, trace => true},
|
||||
{name => 'strBackRestBin', default => backrestBin(), trace => true},
|
||||
);
|
||||
|
||||
# Return from function and log return values if any
|
||||
|
@@ -56,7 +56,7 @@ sub new
|
||||
__PACKAGE__ . '->new', \@_,
|
||||
{name => 'strWalPath'},
|
||||
{name => 'strSpoolPath'},
|
||||
{name => 'strBackRestBin', default => BACKREST_BIN},
|
||||
{name => 'strBackRestBin', default => backrestBin()},
|
||||
);
|
||||
|
||||
# Return from function and log return values if any
|
||||
|
@@ -187,7 +187,7 @@ sub configLoad
|
||||
# calculated correctly in the C Library -- perhaps in the future this value will be passed in or set some other way
|
||||
if (cfgOptionValid(CFGOPT_BACKUP_CMD) && cfgOptionTest(CFGOPT_BACKUP_HOST) && !cfgOptionTest(CFGOPT_BACKUP_CMD))
|
||||
{
|
||||
cfgOptionSet(CFGOPT_BACKUP_CMD, BACKREST_BIN);
|
||||
cfgOptionSet(CFGOPT_BACKUP_CMD, backrestBin());
|
||||
$oOption{cfgOptionName(CFGOPT_BACKUP_CMD)}{source} = CFGDEF_SOURCE_DEFAULT;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ sub configLoad
|
||||
if (cfgOptionTest(cfgOptionIdFromIndex(CFGOPT_DB_HOST, $iOptionIdx)) &&
|
||||
!cfgOptionTest(cfgOptionIdFromIndex(CFGOPT_DB_CMD, $iOptionIdx)))
|
||||
{
|
||||
cfgOptionSet(cfgOptionIdFromIndex(CFGOPT_DB_CMD, $iOptionIdx), BACKREST_BIN);
|
||||
cfgOptionSet(cfgOptionIdFromIndex(CFGOPT_DB_CMD, $iOptionIdx), backrestBin());
|
||||
$oOption{cfgOptionIdFromIndex(CFGOPT_DB_CMD, $iOptionIdx)}{source} = CFGDEF_SOURCE_DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -1153,7 +1153,7 @@ sub cfgCommandWrite
|
||||
my $bDisplayOnly = shift;
|
||||
|
||||
# Set defaults
|
||||
$strExeString = defined($strExeString) ? $strExeString : BACKREST_BIN;
|
||||
$strExeString = defined($strExeString) ? $strExeString : backrestBin();
|
||||
$bIncludeConfig = defined($bIncludeConfig) ? $bIncludeConfig : false;
|
||||
$bIncludeCommand = defined($bIncludeCommand) ? $bIncludeCommand : true;
|
||||
|
||||
|
308
lib/pgBackRest/Main.pm
Normal file
308
lib/pgBackRest/Main.pm
Normal file
@@ -0,0 +1,308 @@
|
||||
####################################################################################################################################
|
||||
# pgBackRest - Reliable PostgreSQL Backup & Restore
|
||||
####################################################################################################################################
|
||||
package pgBackRest::Main;
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
####################################################################################################################################
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
# Convert die to confess to capture the stack trace
|
||||
$SIG{__DIE__} = sub { Carp::confess @_ };
|
||||
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Exit;
|
||||
use pgBackRest::Common::Lock;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
use pgBackRest::Protocol::Helper;
|
||||
use pgBackRest::Version;
|
||||
|
||||
####################################################################################################################################
|
||||
# Main entry point for the library
|
||||
####################################################################################################################################
|
||||
sub main
|
||||
{
|
||||
my $strBackRestBin = shift;
|
||||
@ARGV = @_;
|
||||
|
||||
################################################################################################################################
|
||||
# Run in eval block to catch errors
|
||||
################################################################################################################################
|
||||
eval
|
||||
{
|
||||
############################################################################################################################
|
||||
# Load command line parameters and config
|
||||
############################################################################################################################
|
||||
backrestBinSet($strBackRestBin);
|
||||
my $bConfigResult = configLoad();
|
||||
|
||||
# Display help and version
|
||||
if (cfgCommandTest(CFGCMD_HELP) || cfgCommandTest(CFGCMD_VERSION))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Config::ConfigHelp;
|
||||
pgBackRest::Config::ConfigHelp->import();
|
||||
|
||||
# Generate help and exit
|
||||
configHelp($ARGV[1], $ARGV[2], cfgCommandTest(CFGCMD_VERSION), $bConfigResult);
|
||||
exitSafe(0);
|
||||
}
|
||||
|
||||
# Set test options
|
||||
if (cfgOptionTest(CFGOPT_TEST) && cfgOption(CFGOPT_TEST))
|
||||
{
|
||||
testSet(cfgOption(CFGOPT_TEST), cfgOption(CFGOPT_TEST_DELAY), cfgOption(CFGOPT_TEST_POINT, false));
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process archive-push command
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_ARCHIVE_PUSH))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Archive::Push::Push;
|
||||
pgBackRest::Archive::Push::Push->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Push::Push()->process($ARGV[1]));
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process archive-get command
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_ARCHIVE_GET))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Archive::Get::Get;
|
||||
pgBackRest::Archive::Get::Get->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Get::Get()->process());
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process remote commands
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_REMOTE))
|
||||
{
|
||||
# Set log levels
|
||||
cfgOptionSet(CFGOPT_LOG_LEVEL_STDERR, PROTOCOL, true);
|
||||
logLevelSet(OFF, OFF, cfgOption(CFGOPT_LOG_LEVEL_STDERR));
|
||||
|
||||
if (cfgOptionTest(CFGOPT_TYPE, CFGOPTVAL_REMOTE_TYPE_BACKUP) &&
|
||||
!cfgOptionTest(CFGOPT_REPO_TYPE, CFGOPTVAL_REPO_TYPE_S3) &&
|
||||
!-e cfgOption(CFGOPT_REPO_PATH))
|
||||
{
|
||||
confess &log(ERROR, 'repo-path \'' . cfgOption(CFGOPT_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Protocol::Remote::Minion;
|
||||
pgBackRest::Protocol::Remote::Minion->import();
|
||||
|
||||
# Create the remote object
|
||||
my $oRemote = new pgBackRest::Protocol::Remote::Minion(
|
||||
cfgOption(CFGOPT_BUFFER_SIZE), cfgOption(CFGOPT_PROTOCOL_TIMEOUT));
|
||||
|
||||
# Acquire a remote lock (except for commands that are read-only or local processes)
|
||||
my $strLockName;
|
||||
|
||||
if (!(cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_ARCHIVE_GET)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_INFO)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_RESTORE)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_CHECK)) ||
|
||||
cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_LOCAL))))
|
||||
{
|
||||
$strLockName = cfgOption(CFGOPT_COMMAND);
|
||||
}
|
||||
|
||||
# Process remote requests
|
||||
exitSafe($oRemote->process($strLockName));
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process local commands
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_LOCAL))
|
||||
{
|
||||
# Set log levels
|
||||
cfgOptionSet(CFGOPT_LOG_LEVEL_STDERR, PROTOCOL, true);
|
||||
logLevelSet(OFF, OFF, cfgOption(CFGOPT_LOG_LEVEL_STDERR));
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Protocol::Local::Minion;
|
||||
pgBackRest::Protocol::Local::Minion->import();
|
||||
|
||||
# Create the local object
|
||||
my $oLocal = new pgBackRest::Protocol::Local::Minion();
|
||||
|
||||
# Process local requests
|
||||
exitSafe($oLocal->process());
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process check command
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_CHECK))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Check::Check;
|
||||
pgBackRest::Check::Check->import();
|
||||
|
||||
exitSafe(new pgBackRest::Check::Check()->process());
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process start/stop commands
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_START))
|
||||
{
|
||||
lockStart();
|
||||
exitSafe(0);
|
||||
}
|
||||
elsif (cfgCommandTest(CFGCMD_STOP))
|
||||
{
|
||||
lockStop();
|
||||
exitSafe(0);
|
||||
}
|
||||
|
||||
# Check that the repo path exists
|
||||
require pgBackRest::Protocol::Storage::Helper;
|
||||
pgBackRest::Protocol::Storage::Helper->import();
|
||||
|
||||
if (isRepoLocal() && !cfgOptionTest(CFGOPT_REPO_TYPE, CFGOPTVAL_REPO_TYPE_S3) && !storageRepo()->pathExists(''))
|
||||
{
|
||||
confess &log(ERROR, 'repo-path \'' . cfgOption(CFGOPT_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Process info command
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_INFO))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Info;
|
||||
pgBackRest::Info->import();
|
||||
|
||||
exitSafe(new pgBackRest::Info()->process());
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# Acquire the command lock
|
||||
############################################################################################################################
|
||||
lockAcquire(cfgCommandName(cfgCommandGet()));
|
||||
|
||||
############################################################################################################################
|
||||
# Open the log file
|
||||
############################################################################################################################
|
||||
require pgBackRest::Storage::Helper;
|
||||
pgBackRest::Storage::Helper->import();
|
||||
|
||||
logFileSet(
|
||||
storageLocal(),
|
||||
cfgOption(CFGOPT_LOG_PATH) . '/' . cfgOption(CFGOPT_STANZA) . '-' . lc(cfgCommandName(cfgCommandGet())));
|
||||
|
||||
############################################################################################################################
|
||||
# Process stanza-create command
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_STANZA_CREATE) || cfgCommandTest(CFGCMD_STANZA_UPGRADE))
|
||||
{
|
||||
if (!isRepoLocal())
|
||||
{
|
||||
confess &log(ERROR,
|
||||
cfgCommandName(cfgCommandGet()) . ' command must be run on the backup host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Stanza;
|
||||
pgBackRest::Stanza->import();
|
||||
|
||||
exitSafe(new pgBackRest::Stanza()->process());
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
# RESTORE
|
||||
############################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_RESTORE))
|
||||
{
|
||||
if (!isDbLocal())
|
||||
{
|
||||
confess &log(ERROR, 'restore command must be run on the db host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
# Load module dynamically
|
||||
require pgBackRest::Restore;
|
||||
pgBackRest::Restore->import();
|
||||
|
||||
# Do the restore
|
||||
new pgBackRest::Restore()->process();
|
||||
|
||||
exitSafe(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
########################################################################################################################
|
||||
# Make sure backup and expire commands happen on the backup side
|
||||
########################################################################################################################
|
||||
if (!isRepoLocal())
|
||||
{
|
||||
confess &log(ERROR, 'backup and expire commands must be run on the backup host', ERROR_HOST_INVALID);
|
||||
}
|
||||
|
||||
########################################################################################################################
|
||||
# BACKUP
|
||||
########################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_BACKUP))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Backup::Backup;
|
||||
pgBackRest::Backup::Backup->import();
|
||||
|
||||
new pgBackRest::Backup::Backup()->process();
|
||||
|
||||
cfgCommandSet(CFGCMD_EXPIRE);
|
||||
}
|
||||
|
||||
########################################################################################################################
|
||||
# EXPIRE
|
||||
########################################################################################################################
|
||||
if (cfgCommandTest(CFGCMD_EXPIRE))
|
||||
{
|
||||
# Load module dynamically
|
||||
require pgBackRest::Expire;
|
||||
pgBackRest::Expire->import();
|
||||
|
||||
new pgBackRest::Expire()->process();
|
||||
}
|
||||
}
|
||||
|
||||
lockRelease();
|
||||
exitSafe(0);
|
||||
|
||||
# uncoverable statement - exit should happen above
|
||||
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
|
||||
exit ERROR_ASSERT; # uncoverable statement
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Check for errors
|
||||
################################################################################################################################
|
||||
or do
|
||||
{
|
||||
# Perl 5.10 seems to have a problem propogating errors up through a large call stack, so in the case that the error arrives
|
||||
# blank just use the last logged error instead. Don't do this in all cases because newer Perls seem to work fine and there
|
||||
# are other errors that could be arriving in $EVAL_ERROR.
|
||||
exitSafe(undef, defined($EVAL_ERROR) && length($EVAL_ERROR) > 0 ? $EVAL_ERROR : logErrorLast());
|
||||
};
|
||||
|
||||
# uncoverable statement - errors should be handled in the do block above
|
||||
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
|
||||
exit ERROR_ASSERT; # uncoverable statement
|
||||
}
|
||||
|
||||
1;
|
@@ -41,7 +41,7 @@ sub new
|
||||
__PACKAGE__ . '->new', \@_,
|
||||
{name => 'strHostType'},
|
||||
{name => 'iSelectTimeout', default => int(cfgOption(CFGOPT_PROTOCOL_TIMEOUT) / 2)},
|
||||
{name => 'strBackRestBin', default => BACKREST_BIN},
|
||||
{name => 'strBackRestBin', default => backrestBin()},
|
||||
{name => 'bConfessError', default => true},
|
||||
);
|
||||
|
||||
|
@@ -27,8 +27,12 @@ use constant BACKREST_CONF => BACKREST_
|
||||
#
|
||||
# Stores the exe location.
|
||||
#-----------------------------------------------------------------------------------------------------------------------------------
|
||||
use constant BACKREST_BIN => abs_path($0);
|
||||
push @EXPORT, qw(BACKREST_BIN);
|
||||
my $strBackRestBin;
|
||||
|
||||
sub backrestBin {return $strBackRestBin};
|
||||
sub backrestBinSet {$strBackRestBin = shift}
|
||||
|
||||
push @EXPORT, qw(backrestBin backrestBinSet);
|
||||
|
||||
# BackRest Version Number
|
||||
#
|
||||
|
14
src/Makefile
Normal file
14
src/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
CC=gcc
|
||||
CFLAGS=-I. -Wfatal-errors -Wall -Wextra -Wwrite-strings -Wno-clobbered -std=c99 -funroll-loops -ftree-vectorize
|
||||
DESTDIR=
|
||||
|
||||
pgbackrest: main.o \
|
||||
common/error.o common/errorType.o common/memContext.o common/type/list.o common/type/string.o common/type/stringList.o \
|
||||
perl/exec.o
|
||||
$(CC) $(CFLAGS) -o pgbackrest main.o \
|
||||
common/error.o common/errorType.o common/memContext.o common/type/list.o common/type/string.o common/type/stringList.o \
|
||||
perl/exec.o
|
||||
|
||||
install: pgbackrest
|
||||
sudo install -d $(DESTDIR)/usr/bin
|
||||
sudo install -m 755 pgbackrest $(DESTDIR)/usr/bin
|
10
src/main.c
Normal file
10
src/main.c
Normal file
@@ -0,0 +1,10 @@
|
||||
/***********************************************************************************************************************************
|
||||
Main
|
||||
***********************************************************************************************************************************/
|
||||
#include "perl/exec.h"
|
||||
|
||||
int main(int argListSize, char *argList[])
|
||||
{
|
||||
// Execute Perl since nothing is implemented in C (yet)
|
||||
perlExec(perlCommand(argListSize, argList));
|
||||
}
|
104
src/perl/exec.c
Normal file
104
src/perl/exec.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/***********************************************************************************************************************************
|
||||
Execute Perl for Legacy Functionality
|
||||
***********************************************************************************************************************************/
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "common/error.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/type.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constants used to build perl options
|
||||
***********************************************************************************************************************************/
|
||||
#define PERL_EXE "perl"
|
||||
#define ENV_EXE "/usr/bin/env"
|
||||
|
||||
#define PARAM_PERL_OPTION "perl-option"
|
||||
#define PARAM_PERL_OPTION_ID 1000
|
||||
|
||||
#define PGBACKREST_MODULE PGBACKREST_NAME "::Main"
|
||||
#define PGBACKREST_MAIN PGBACKREST_MODULE "::main"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Build list of perl options to use for exec
|
||||
***********************************************************************************************************************************/
|
||||
StringList *perlCommand(int argListSize, char *argList[])
|
||||
{
|
||||
// Setup arg list for perl exec
|
||||
StringList *perlArgList = strLstNew();
|
||||
strLstAdd(perlArgList, strNew(ENV_EXE));
|
||||
strLstAdd(perlArgList, strNew(PERL_EXE));
|
||||
|
||||
// Setup Perl main call
|
||||
String *mainParamBuffer = strNew("");
|
||||
|
||||
// Setup pgbackrest bin
|
||||
String *binParamBuffer = strNew("");
|
||||
|
||||
// Reset optind to 1 in case getopt_long has been called before
|
||||
optind = 1;
|
||||
|
||||
// Struct with all valid options
|
||||
static struct option optionList[] =
|
||||
{
|
||||
{PARAM_PERL_OPTION, required_argument, NULL, PARAM_PERL_OPTION_ID},
|
||||
{0, 0, NULL, 0},
|
||||
};
|
||||
|
||||
// Parse options
|
||||
int option;
|
||||
int optionIdx;
|
||||
opterr = false;
|
||||
|
||||
while ((option = getopt_long(argListSize, argList, "-", optionList, &optionIdx)) != -1)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case 1:
|
||||
case '?':
|
||||
strCat(mainParamBuffer, ", ");
|
||||
strCatFmt(mainParamBuffer, "'%s'", argList[optind - 1]);
|
||||
break;
|
||||
|
||||
case PARAM_PERL_OPTION_ID:
|
||||
strLstAdd(perlArgList, strNew(optarg));
|
||||
|
||||
strCatFmt(binParamBuffer, " --" PARAM_PERL_OPTION "=\"%s\"", optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finish Perl main call
|
||||
String *mainBuffer = strNewFmt(
|
||||
PGBACKREST_MAIN "('%s%s'%s)", argList[0], strPtr(binParamBuffer), strPtr(mainParamBuffer));
|
||||
|
||||
strFree(binParamBuffer);
|
||||
strFree(mainParamBuffer);
|
||||
|
||||
// Finish arg list for perl exec
|
||||
strLstAdd(perlArgList, strNew("-M" PGBACKREST_MODULE));
|
||||
strLstAdd(perlArgList, strNew("-e"));
|
||||
strLstAdd(perlArgList, mainBuffer);
|
||||
strLstAdd(perlArgList, NULL);
|
||||
|
||||
return perlArgList;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Exec supplied Perl options
|
||||
***********************************************************************************************************************************/
|
||||
void perlExec(StringList *perlArgList)
|
||||
{
|
||||
// Exec perl with supplied arguments
|
||||
execvp(strPtr(strLstGet(perlArgList, 0)), (char **)strLstPtr(perlArgList));
|
||||
|
||||
// The previous command only returns on error so throw it
|
||||
int errNo = errno;
|
||||
THROW(AssertError, "unable to exec %s: %s", strPtr(strLstGet(perlArgList, 0)), strerror(errNo));
|
||||
} // {uncoverable - perlExec() does not return}
|
15
src/perl/exec.h
Normal file
15
src/perl/exec.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/***********************************************************************************************************************************
|
||||
Execute Perl for Legacy Functionality
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef PERL_EXEC_H
|
||||
#define PERL_EXEC_H
|
||||
|
||||
#include "common/type.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
StringList *perlCommand(int argListSize, char *argList[]);
|
||||
void perlExec(StringList *perlArgList);
|
||||
|
||||
#endif
|
12
src/version.h
Normal file
12
src/version.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/***********************************************************************************************************************************
|
||||
Version Numbers and Names
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Official name of the software, also used for Perl package name
|
||||
***********************************************************************************************************************************/
|
||||
#define PGBACKREST_NAME "pgBackRest"
|
||||
|
||||
#endif
|
@@ -265,6 +265,25 @@ my $oTestDef =
|
||||
},
|
||||
]
|
||||
},
|
||||
# Perl tests
|
||||
{
|
||||
&TESTDEF_NAME => 'perl',
|
||||
&TESTDEF_CONTAINER => true,
|
||||
|
||||
&TESTDEF_TEST =>
|
||||
[
|
||||
{
|
||||
&TESTDEF_NAME => 'exec',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
'perl/exec' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
# Help tests
|
||||
{
|
||||
&TESTDEF_NAME => 'help',
|
||||
|
@@ -22,6 +22,7 @@ use pgBackRest::DbVersion;
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestTest::Common::ContainerTest;
|
||||
use pgBackRestTest::Common::DefineTest;
|
||||
@@ -164,21 +165,11 @@ sub run
|
||||
"-test",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
# Install Perl C Library
|
||||
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}'");
|
||||
# Install bin and Perl C Library
|
||||
if (!$self->{oTest}->{&TEST_C})
|
||||
{
|
||||
jobInstallC($self->{strBackRestBase}, $self->{oTest}->{&TEST_VM}, $strImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,10 +192,10 @@ sub run
|
||||
{
|
||||
$strCommand =
|
||||
($self->{oTest}->{&TEST_CONTAINER} ? 'docker exec -i -u ' . TEST_USER . " ${strImage} " : '') .
|
||||
(vmCoverage($self->{oTest}->{&TEST_VM}) ? testRunExe(
|
||||
abs_path($0), dirname($self->{strCoveragePath}), $self->{strBackRestBase}, $self->{oTest}->{&TEST_MODULE},
|
||||
$self->{oTest}->{&TEST_NAME}, defined($self->{oTest}->{&TEST_RUN}) ? $self->{oTest}->{&TEST_RUN} : 'all') :
|
||||
abs_path($0)) .
|
||||
testRunExe(
|
||||
vmCoverage($self->{oTest}->{&TEST_VM}), undef, abs_path($0),
|
||||
dirname($self->{strCoveragePath}), $self->{strBackRestBase}, $self->{oTest}->{&TEST_MODULE},
|
||||
$self->{oTest}->{&TEST_NAME}, defined($self->{oTest}->{&TEST_RUN}) ? $self->{oTest}->{&TEST_RUN} : 'all') .
|
||||
" --test-path=${strVmTestPath}" .
|
||||
" --vm=$self->{oTest}->{&TEST_VM}" .
|
||||
" --vm-id=$self->{iVmIdx}" .
|
||||
@@ -224,13 +215,7 @@ sub run
|
||||
|
||||
if (!$self->{bDryRun} || $self->{bVmOut})
|
||||
{
|
||||
# Set permissions on the Docker test directory. This can be removed once users/groups are sync'd between
|
||||
# Docker and the host VM.
|
||||
if ($self->{oTest}->{&TEST_CONTAINER})
|
||||
{
|
||||
executeTest("docker exec ${strImage} chown " . TEST_USER . ':' . TEST_GROUP . " -R ${strVmTestPath}");
|
||||
}
|
||||
|
||||
# If testing C code
|
||||
if ($self->{oTest}->{&TEST_C})
|
||||
{
|
||||
my $strCSrcPath = "$self->{strBackRestBase}/src";
|
||||
@@ -244,6 +229,9 @@ sub run
|
||||
# Skip all files except .c files (including .auto.c)
|
||||
next if $strFile !~ /(?<!\.auto)\.c$/;
|
||||
|
||||
# !!! Skip main for now until it can be rewritten
|
||||
next if $strFile =~ /main\.c$/;
|
||||
|
||||
if (!defined($hTestCoverage->{substr($strFile, 0, length($strFile) - 2)}))
|
||||
{
|
||||
push(@stryCFile, "${strCSrcPath}/${strFile}");
|
||||
@@ -293,8 +281,6 @@ sub run
|
||||
{
|
||||
my $bSelected = false;
|
||||
|
||||
# use Data::Dumper; confess "RUN: " . Dumper($self->{oTest}->{&TEST_RUN});
|
||||
|
||||
if (!defined($self->{oTest}->{&TEST_RUN}) || @{$self->{oTest}->{&TEST_RUN}} == 0 ||
|
||||
grep(/^$iTestIdx$/, @{$self->{oTest}->{&TEST_RUN}}))
|
||||
{
|
||||
@@ -336,9 +322,7 @@ sub run
|
||||
{
|
||||
exec => $oExec,
|
||||
test => $strTest,
|
||||
# idx => $self->{iTestIdx},
|
||||
# container => $self->{oTest}->{&TEST_CONTAINER},
|
||||
start_time => $fTestStartTime
|
||||
start_time => $fTestStartTime,
|
||||
};
|
||||
|
||||
$bRun = true;
|
||||
@@ -501,4 +485,37 @@ sub end
|
||||
);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Install C binary and library
|
||||
####################################################################################################################################
|
||||
sub jobInstallC
|
||||
{
|
||||
my $strBasePath = shift;
|
||||
my $strVm = shift;
|
||||
my $strImage = shift;
|
||||
|
||||
# Install Perl C Library
|
||||
my $oVm = vmGet();
|
||||
my $strBuildPath = "${strBasePath}/test/.vagrant";
|
||||
my $strBuildLibCPath = "$strBuildPath/libc/${strVm}/libc";
|
||||
my $strBuildBinPath = "$strBuildPath/bin/${strVm}/src";
|
||||
my $strPerlAutoPath = $oVm->{$strVm}{&VMDEF_PERL_ARCH_PATH} . '/auto/pgBackRest/LibC';
|
||||
my $strPerlModulePath = $oVm->{$strVm}{&VMDEF_PERL_ARCH_PATH} . '/pgBackRest';
|
||||
|
||||
executeTest(
|
||||
"docker exec -i -u root ${strImage} bash -c '" .
|
||||
"mkdir -p -m 755 ${strPerlAutoPath} && " .
|
||||
# "cp ${strBuildLibCPath}/blib/arch/auto/pgBackRest/LibC/LibC.bs ${strPerlAutoPath} && " .
|
||||
"cp ${strBuildLibCPath}/blib/arch/auto/pgBackRest/LibC/LibC.so ${strPerlAutoPath} && " .
|
||||
"cp ${strBuildLibCPath}/blib/lib/auto/pgBackRest/LibC/autosplit.ix ${strPerlAutoPath} && " .
|
||||
"mkdir -p -m 755 ${strPerlModulePath} && " .
|
||||
"cp ${strBuildLibCPath}/blib/lib/pgBackRest/LibC.pm ${strPerlModulePath} && " .
|
||||
"cp ${strBuildLibCPath}/blib/lib/pgBackRest/LibCAuto.pm ${strPerlModulePath} && " .
|
||||
"cp ${strBuildBinPath}/" . BACKREST_EXE . ' /usr/bin/' . BACKREST_EXE . ' && ' .
|
||||
'chmod 755 /usr/bin/' . BACKREST_EXE . ' && ' .
|
||||
"ln -s ${strBasePath}/lib/pgBackRest /usr/share/perl5/pgBackRest'");
|
||||
}
|
||||
|
||||
push(@EXPORT, qw(jobInstallC));
|
||||
|
||||
1;
|
||||
|
@@ -21,6 +21,7 @@ use pgBackRest::Common::String;
|
||||
use pgBackRest::Common::Wait;
|
||||
use pgBackRest::Storage::Posix::Driver;
|
||||
use pgBackRest::Storage::Local;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestTest::Common::DefineTest;
|
||||
use pgBackRestTest::Common::ExecuteTest;
|
||||
@@ -112,7 +113,8 @@ sub process
|
||||
$self->{iVmId},
|
||||
$self->{strBasePath},
|
||||
$self->{strTestPath},
|
||||
$self->{strBackRestExeOriginal},
|
||||
$self->{strBackRestExeC},
|
||||
$self->{strBackRestExeHelper},
|
||||
$self->{strPgBinPath},
|
||||
$self->{strPgVersion},
|
||||
$self->{strModule},
|
||||
@@ -133,7 +135,8 @@ sub process
|
||||
{name => 'iVmId'},
|
||||
{name => 'strBasePath'},
|
||||
{name => 'strTestPath'},
|
||||
{name => 'strBackRestExeOriginal'},
|
||||
{name => 'strBackRestExeC'},
|
||||
{name => 'strBackRestExeHelper'},
|
||||
{name => 'strPgBinPath', required => false},
|
||||
{name => 'strPgVersion', required => false},
|
||||
{name => 'strModule'},
|
||||
@@ -233,27 +236,23 @@ sub begin
|
||||
return false;
|
||||
}
|
||||
|
||||
my $strExe = $self->backrestExeOriginal();
|
||||
# Generate backrest exe
|
||||
$self->{strBackRestExe} = testRunExe(
|
||||
$self->coverage(), $self->{strBackRestExeC}, $self->{strBackRestExeHelper}, dirname($self->testPath()), $self->basePath(),
|
||||
$self->module(), $self->moduleTest(), $self->runCurrent(), true);
|
||||
|
||||
# If coverage is requested then prepend the coverage code
|
||||
if ($self->coverage())
|
||||
{
|
||||
$strExe = testRunExe(
|
||||
$strExe, dirname($self->testPath()), $self->basePath(), $self->module(), $self->moduleTest(), $self->runCurrent(),
|
||||
true);
|
||||
}
|
||||
backrestBinSet($self->{strBackRestExe});
|
||||
|
||||
# Create an ExpectTest object
|
||||
if ($self->doExpect())
|
||||
{
|
||||
$self->{oExpect} = new pgBackRestTest::Common::LogTest(
|
||||
$self->module(), $self->moduleTest(), $self->runCurrent(), $self->doLogForce(), $strDescription, $strExe,
|
||||
$self->pgBinPath(), $self->testPath());
|
||||
$self->module(), $self->moduleTest(), $self->runCurrent(), $self->doLogForce(), $strDescription,
|
||||
$self->{strBackRestExe}, $self->pgBinPath(), $self->testPath());
|
||||
|
||||
&log(INFO, ' expect log: ' . $self->{oExpect}->{strFileName});
|
||||
}
|
||||
|
||||
$self->{strBackRestExe} = $strExe;
|
||||
|
||||
if (!$self->{bFirstTest})
|
||||
{
|
||||
@@ -537,7 +536,9 @@ push @EXPORT, qw(testRunGet);
|
||||
####################################################################################################################################
|
||||
sub testRunExe
|
||||
{
|
||||
my $strExe = shift;
|
||||
my $bCoverage = shift;
|
||||
my $strExeC = shift;
|
||||
my $strExeHelper = shift;
|
||||
my $strCoveragePath = shift;
|
||||
my $strBackRestBasePath = shift;
|
||||
my $strModule = shift;
|
||||
@@ -545,31 +546,43 @@ sub testRunExe
|
||||
my $iRun = shift;
|
||||
my $bLog = shift;
|
||||
|
||||
# Limit Perl modules tested to what is defined in the test coverage (if it exists)
|
||||
my $hTestCoverage = (testDefModuleTest($strModule, $strTest))->{&TESTDEF_COVERAGE};
|
||||
my $strExe = defined($strExeC) ? $strExeC : undef;
|
||||
my $strPerlModule;
|
||||
my $strPerlModuleLog;
|
||||
|
||||
if (defined($hTestCoverage))
|
||||
if ($bCoverage)
|
||||
{
|
||||
foreach my $strCoverageModule (sort(keys(%{$hTestCoverage})))
|
||||
# Limit Perl modules tested to what is defined in the test coverage (if it exists)
|
||||
my $hTestCoverage = (testDefModuleTest($strModule, $strTest))->{&TESTDEF_COVERAGE};
|
||||
my $strPerlModuleLog;
|
||||
|
||||
if (defined($hTestCoverage))
|
||||
{
|
||||
$strPerlModule .= ',.*/' . $strCoverageModule . '\.p.$';
|
||||
$strPerlModuleLog .= (defined($strPerlModuleLog) ? ', ' : '') . $strCoverageModule;
|
||||
foreach my $strCoverageModule (sort(keys(%{$hTestCoverage})))
|
||||
{
|
||||
$strPerlModule .= ',.*/' . $strCoverageModule . '\.p.$';
|
||||
$strPerlModuleLog .= (defined($strPerlModuleLog) ? ', ' : '') . $strCoverageModule;
|
||||
}
|
||||
}
|
||||
|
||||
# Build the exe
|
||||
if (defined($strPerlModule))
|
||||
{
|
||||
$strExe .=
|
||||
(defined($strExeC) ? ' --perl-option=' : 'perl ') .
|
||||
"-MDevel::Cover=-silent,1,-dir,${strCoveragePath},-select${strPerlModule},+inc" .
|
||||
",${strBackRestBasePath},-coverage,statement,branch,condition,path,subroutine" .
|
||||
(defined($strExeC) ? '' : " ${strExeHelper}");
|
||||
|
||||
if (defined($bLog) && $bLog)
|
||||
{
|
||||
&log(INFO, " coverage: ${strPerlModuleLog}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Build the exe
|
||||
if (defined($strPerlModule))
|
||||
if (!defined($strExeC) && !defined($strPerlModule))
|
||||
{
|
||||
$strExe =
|
||||
"perl -MDevel::Cover=-silent,1,-dir,${strCoveragePath},-select${strPerlModule},+inc,${strBackRestBasePath}" .
|
||||
",-coverage,statement,branch,condition,path,subroutine ${strExe}";
|
||||
|
||||
if (defined($bLog) && $bLog)
|
||||
{
|
||||
&log(INFO, " coverage: ${strPerlModuleLog}");
|
||||
}
|
||||
$strExe = $strExeHelper;
|
||||
}
|
||||
|
||||
return $strExe;
|
||||
@@ -592,7 +605,6 @@ push(@EXPORT, qw(storageTest));
|
||||
####################################################################################################################################
|
||||
sub archBits {return vmArchBits(shift->{strVm})}
|
||||
sub backrestExe {return shift->{strBackRestExe}}
|
||||
sub backrestExeOriginal {return shift->{strBackRestExeOriginal}}
|
||||
sub backrestUser {return shift->{strBackRestUser}}
|
||||
sub basePath {return shift->{strBasePath}}
|
||||
sub coverage {vmCoverage(shift->{strVm})}
|
||||
|
@@ -22,6 +22,7 @@ use pgBackRest::Version;
|
||||
|
||||
use pgBackRestTest::Common::ContainerTest;
|
||||
use pgBackRestTest::Common::ExecuteTest;
|
||||
use pgBackRestTest::Common::JobTest;
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
use pgBackRestTest::Common::VmTest;
|
||||
|
||||
@@ -79,21 +80,8 @@ sub new
|
||||
# Set permissions on the test path
|
||||
$self->executeSimple('chown -R ' . $self->userGet() . ':'. TEST_GROUP . ' ' . $self->testPath(), undef, 'root');
|
||||
|
||||
# Install Perl C Library
|
||||
my $oVm = vmGet();
|
||||
my $strBuildPath = testRunGet()->basePath() . "/test/.vagrant/libc/$self->{strOS}/libc";
|
||||
my $strPerlAutoPath = $$oVm{$self->{strOS}}{&VMDEF_PERL_ARCH_PATH} . '/auto/pgBackRest/LibC';
|
||||
my $strPerlModulePath = $$oVm{$self->{strOS}}{&VMDEF_PERL_ARCH_PATH} . '/pgBackRest';
|
||||
|
||||
$self->executeSimple(
|
||||
"mkdir -p -m 755 ${strPerlAutoPath} && " .
|
||||
# "cp ${strBuildPath}/blib/arch/auto/pgBackRest/LibC/LibC.bs ${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}",
|
||||
undef, 'root');
|
||||
# Install bin and Perl C Library
|
||||
jobInstallC(testRunGet()->basePath(), $self->{strOS}, $strContainer);
|
||||
|
||||
# Return from function and log return values if any
|
||||
return logDebugReturn
|
||||
|
@@ -77,7 +77,6 @@ sub initTest
|
||||
sub run
|
||||
{
|
||||
my $self = shift;
|
||||
my $oArchiveBase = new pgBackRest::Archive::Base();
|
||||
|
||||
# Define test file
|
||||
my $strFileContent = 'TESTDATA';
|
||||
@@ -92,6 +91,8 @@ sub run
|
||||
################################################################################################################################
|
||||
if ($self->begin("Archive::Base::getCheck()"))
|
||||
{
|
||||
my $oArchiveBase = new pgBackRest::Archive::Base();
|
||||
|
||||
# Create and save archive.info file
|
||||
my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet(STORAGE_REPO_ARCHIVE), false,
|
||||
{bLoad => false, bIgnoreMissing => true});
|
||||
|
@@ -17,6 +17,7 @@ use Cwd qw(abs_path);
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
|
||||
@@ -356,8 +357,9 @@ sub run
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
|
||||
my $strCommand = cfgCommandWrite(CFGCMD_ARCHIVE_GET);
|
||||
my $strExpectedCommand = abs_path($0) . " --backup-host=db.mydomain.com \"--db1-path=/db path/main\"" .
|
||||
" --repo-path=/repo --stanza=app " . cfgCommandName(CFGCMD_ARCHIVE_GET);
|
||||
my $strExpectedCommand =
|
||||
backrestBin() . " --backup-host=db.mydomain.com \"--db1-path=/db path/main\" --repo-path=/repo --stanza=app " .
|
||||
cfgCommandName(CFGCMD_ARCHIVE_GET);
|
||||
|
||||
if ($strCommand ne $strExpectedCommand)
|
||||
{
|
||||
@@ -372,7 +374,7 @@ sub run
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_DB_CMD, abs_path($0));
|
||||
$self->optionTestExpect(CFGOPT_DB_CMD, backrestBin());
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' missing option ' . cfgOptionName(CFGOPT_DB_PATH)))
|
||||
|
22
test/patch/debian-package.patch
Normal file
22
test/patch/debian-package.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
--- pgbackrest.install
|
||||
+++ pgbackrest.install
|
||||
@@ -1,3 +1,2 @@
|
||||
-bin/pgbackrest usr/bin/
|
||||
debian/pgbackrest.conf etc/
|
||||
lib/pgBackRest usr/share/perl5/
|
||||
--- rules
|
||||
+++ rules
|
||||
@@ -22,6 +22,7 @@
|
||||
${MANTEMPLATE} > ${CURDIR}/doc/output/man/pgbackrest.1
|
||||
cd $(CURDIR)/libc; perl Makefile.PL PREFIX=/usr NO_PACKLIST=1
|
||||
make -C $(CURDIR)/libc/
|
||||
+ make -C $(CURDIR)/src
|
||||
dh_auto_build
|
||||
|
||||
override_dh_auto_test:
|
||||
@@ -36,4 +37,5 @@
|
||||
|
||||
override_dh_auto_install:
|
||||
make -C libc install DESTDIR=$(CURDIR)/debian/pgbackrest
|
||||
+ make -C src install DESTDIR=$(CURDIR)/debian/pgbackrest
|
||||
dh_auto_install
|
70
test/src/module/perl/execTest.c
Normal file
70
test/src/module/perl/execTest.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Perl Exec
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
#define TEST_ENV_EXE "/usr/bin/env"
|
||||
#define TEST_PERL_EXE "perl"
|
||||
#define TEST_BACKREST_EXE "/path/to/pgbackrest"
|
||||
#define TEST_PERL_MAIN \
|
||||
"-MpgBackRest::Main|-e|pgBackRest::Main::main('" TEST_BACKREST_EXE ""
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void testRun()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("perlCommand()"))
|
||||
{
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
char *cmdLineParam[128];
|
||||
int cmdLineParamSize = 0;
|
||||
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)TEST_BACKREST_EXE;
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "')|[NULL]", "simple command");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)"--option";
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--option')|[NULL]", "simple option");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)"--option2=value";
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--option', '--option2=value')|[NULL]",
|
||||
"option with = before value");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)"--option3";
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)"value";
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--option', '--option2=value', '--option3', 'value')|[NULL]",
|
||||
"option with space before value");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cmdLineParam[cmdLineParamSize++] = (char *)"--perl-option=-I.";
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN " --perl-option=\"-I.\"', '--option', '--option2=value', "
|
||||
"'--option3', 'value')|[NULL]",
|
||||
"perl option");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("perlExec()"))
|
||||
{
|
||||
StringList *param = strLstAdd(strLstAdd(strLstNew(), strNew(BOGUS_STR)), NULL);
|
||||
|
||||
TEST_ERROR(perlExec(param), AssertError, "unable to exec BOGUS: No such file or directory");
|
||||
}
|
||||
}
|
125
test/test.pl
125
test/test.pl
@@ -386,23 +386,96 @@ eval
|
||||
$oStorageTest->pathCreate($strCoveragePath, {strMode => '0770', bIgnoreMissing => true, bCreateParent => true});
|
||||
}
|
||||
|
||||
# Build the C Library and Packages
|
||||
# Build the binary, library and packages
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
if (!$bDryRun)
|
||||
{
|
||||
my $oVm = vmGet();
|
||||
my $strVagrantPath = "${strBackRestBase}/test/.vagrant";
|
||||
|
||||
# Build the binary
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $strBinPath = "${strVagrantPath}/bin";
|
||||
my $strBinSmart = "${strBinPath}/build.timestamp";
|
||||
my @stryBinSrcPath = ('src');
|
||||
|
||||
# Find the lastest modified time for dirs that affect the bin build
|
||||
my $lTimestampLast = $oStorageBackRest->exists($strBinSmart) ? $oStorageBackRest->info($strBinSmart)->mtime : 0;
|
||||
|
||||
foreach my $strBinSrcPath (@stryBinSrcPath)
|
||||
{
|
||||
my $hManifest = $oStorageBackRest->manifest($strBinSrcPath);
|
||||
|
||||
foreach my $strFile (sort(keys(%{$hManifest})))
|
||||
{
|
||||
if ($hManifest->{$strFile}{type} eq 'f' && $hManifest->{$strFile}{modification_time} > $lTimestampLast)
|
||||
{
|
||||
$lTimestampLast = $hManifest->{$strFile}{modification_time};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Rebuild if the modification time of the smart file does equal the last changes in source paths
|
||||
if (!$bSmart || !$oStorageBackRest->exists($strBinSmart) ||
|
||||
$oStorageBackRest->info($strBinSmart)->mtime < $lTimestampLast)
|
||||
{
|
||||
if ($bSmart)
|
||||
{
|
||||
&log(INFO, 'bin dependencies have changed, rebuilding...');
|
||||
}
|
||||
|
||||
executeTest("sudo rm -rf ${strBinPath}");
|
||||
executeTest('sudo rm -rf /usr/bin/' . BACKREST_EXE);
|
||||
}
|
||||
|
||||
# Loop through VMs to do the C Library builds
|
||||
my $bLogDetail = $strLogLevel eq 'detail';
|
||||
my @stryBuildVm = $strVm eq VM_ALL ? VM_LIST : ($strVm);
|
||||
|
||||
foreach my $strBuildVM (sort(@stryBuildVm))
|
||||
{
|
||||
my $strBuildPath = "${strBinPath}/${strBuildVM}/src";
|
||||
|
||||
if (!$oStorageBackRest->pathExists($strBuildPath))
|
||||
{
|
||||
&log(INFO, "build bin for ${strBuildVM} (${strBuildPath})");
|
||||
|
||||
executeTest(
|
||||
"docker run -itd -h test-build --name=test-build" .
|
||||
" -v ${strBackRestBase}:${strBackRestBase} " . containerRepo() . ":${strBuildVM}-build",
|
||||
{bSuppressStdErr => true});
|
||||
|
||||
foreach my $strBinSrcPath (@stryBinSrcPath)
|
||||
{
|
||||
$oStorageBackRest->pathCreate(
|
||||
"${strBinPath}/${strBuildVM}/${strBinSrcPath}", {bIgnoreExists => true, bCreateParent => true});
|
||||
executeTest("cp -r ${strBackRestBase}/${strBinSrcPath}/* ${strBinPath}/${strBuildVM}/${strBinSrcPath}");
|
||||
}
|
||||
|
||||
executeTest(
|
||||
"docker exec -i test-build make --silent --directory ${strBuildPath}",
|
||||
{bShowOutputAsync => $bLogDetail});
|
||||
|
||||
executeTest(
|
||||
"docker exec -i test-build make --silent --directory ${strBuildPath} install",
|
||||
{bShowOutputAsync => $bLogDetail});
|
||||
|
||||
executeTest("docker rm -f test-build");
|
||||
}
|
||||
}
|
||||
|
||||
# Write files to indicate the last time a build was successful
|
||||
$oStorageBackRest->put($strBinSmart);
|
||||
utime($lTimestampLast, $lTimestampLast, $strBinSmart) or
|
||||
confess "unable to set time for ${strBinSmart}" . (defined($!) ? ":$!" : '');
|
||||
|
||||
# Build the C Library
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $strVagrantPath = "${strBackRestBase}/test/.vagrant";
|
||||
my $strLibCPath = "${strVagrantPath}/libc";
|
||||
my $strLibCSmart = "${strLibCPath}/build.timestamp";
|
||||
my @stryLibCSrcPath = ('libc', 'src');
|
||||
|
||||
# VM Info
|
||||
my $oVm = vmGet();
|
||||
|
||||
# Find the lastest modified time for dirs that affect the libc build
|
||||
my $lTimestampLast = $oStorageBackRest->exists($strLibCSmart) ? $oStorageBackRest->info($strLibCSmart)->mtime : 0;
|
||||
|
||||
foreach my $strLibCSrcPath (@stryLibCSrcPath)
|
||||
{
|
||||
my $hManifest = $oStorageBackRest->manifest($strLibCSrcPath);
|
||||
@@ -431,8 +504,8 @@ eval
|
||||
}
|
||||
|
||||
# Loop through VMs to do the C Library builds
|
||||
my $bLogDetail = $strLogLevel eq 'detail';
|
||||
my @stryBuildVm = $strVm eq VM_ALL ? VM_LIST : ($strVm eq $strVmHost ? ($strVm) : ($strVm, $strVmHost));
|
||||
$bLogDetail = $strLogLevel eq 'detail';
|
||||
@stryBuildVm = $strVm eq VM_ALL ? VM_LIST : ($strVm eq $strVmHost ? ($strVm) : ($strVm, $strVmHost));
|
||||
|
||||
foreach my $strBuildVM (sort(@stryBuildVm))
|
||||
{
|
||||
@@ -441,7 +514,7 @@ eval
|
||||
|
||||
if (!$oStorageBackRest->pathExists($strBuildPath))
|
||||
{
|
||||
&log(INFO, "build/test C library for ${strBuildVM} (${strBuildPath})");
|
||||
&log(INFO, "build C library for ${strBuildVM} (${strBuildPath})");
|
||||
|
||||
if ($bContainerExists)
|
||||
{
|
||||
@@ -518,7 +591,7 @@ eval
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $strPackagePath = "${strVagrantPath}/package";
|
||||
my $strPackageSmart = "${strPackagePath}/build.timestamp";
|
||||
my @stryPackageSrcPath = ('bin', 'lib');
|
||||
my @stryPackageSrcPath = ('lib');
|
||||
|
||||
# Find the lastest modified time for additional dirs that affect the package build
|
||||
foreach my $strPackageSrcPath (@stryPackageSrcPath)
|
||||
@@ -574,6 +647,21 @@ eval
|
||||
"bash -c 'cp -r /root/package-src/debian ${strBuildPath}' && sudo chown -R " . TEST_USER .
|
||||
" ${strBuildPath}");
|
||||
|
||||
# Patch files in debian package builds
|
||||
#
|
||||
# Use these commands to create a new patch (may need to modify first line):
|
||||
# BRDIR=/backrest;BRVM=u16;BRPATCHFILE=${BRDIR?}/test/patch/debian-package.patch
|
||||
# DBDIR=${BRDIR?}/test/.vagrant/package/${BRVM}/src/debian
|
||||
# diff -Naur ${DBDIR?}.old ${DBDIR}.new > ${BRPATCHFILE?}
|
||||
my $strDebianPackagePatch = "${strBackRestBase}/test/patch/debian-package.patch";
|
||||
|
||||
if ($oStorageBackRest->exists($strDebianPackagePatch))
|
||||
{
|
||||
executeTest("cp -r ${strBuildPath}/debian ${strBuildPath}/debian.old");
|
||||
executeTest("patch -d ${strBuildPath}/debian < ${strDebianPackagePatch}");
|
||||
executeTest("cp -r ${strBuildPath}/debian ${strBuildPath}/debian.new");
|
||||
}
|
||||
|
||||
# If dev build then disable static release date used for reproducibility
|
||||
if ($bVersionDev)
|
||||
{
|
||||
@@ -633,22 +721,12 @@ eval
|
||||
{
|
||||
my $strBasePath = dirname(dirname(abs_path($0)));
|
||||
|
||||
&log(INFO, "Performing static code analysis using perl -cw");
|
||||
|
||||
# Check the exe for warnings
|
||||
my $strWarning = trim(executeTest("perl -cw ${strBasePath}/bin/pgbackrest 2>&1"));
|
||||
|
||||
if ($strWarning ne "${strBasePath}/bin/pgbackrest syntax OK")
|
||||
{
|
||||
confess &log(ERROR, "${strBasePath}/bin/pgbackrest failed syntax check:\n${strWarning}");
|
||||
}
|
||||
|
||||
&log(INFO, "Performing static code analysis using perlcritic");
|
||||
|
||||
executeTest('perlcritic --quiet --verbose=8 --brutal --top=10' .
|
||||
' --verbose "[%p] %f: %m at line %l, column %c. %e. (Severity: %s)\n"' .
|
||||
" \"--profile=${strBasePath}/test/lint/perlcritic.policy\"" .
|
||||
" ${strBasePath}/bin/pgbackrest ${strBasePath}/lib/*" .
|
||||
" ${strBasePath}/lib/*" .
|
||||
" ${strBasePath}/test/test.pl ${strBasePath}/test/lib/*" .
|
||||
" ${strBasePath}/doc/doc.pl ${strBasePath}/doc/lib/*");
|
||||
}
|
||||
@@ -956,7 +1034,8 @@ eval
|
||||
$strVm, $iVmId, # Vm info
|
||||
$strBackRestBase, # Base backrest directory
|
||||
$strTestPath, # Path where the tests will run
|
||||
"${strBackRestBase}/bin/" . BACKREST_EXE, # Path to the backrest executable
|
||||
'/usr/bin/' . BACKREST_EXE, # Path to the backrest executable
|
||||
"${strBackRestBase}/bin/" . BACKREST_EXE, # Path to the backrest Perl helper
|
||||
$strDbVersion ne 'minimal' ? $strPgSqlBin: undef, # Db bin path
|
||||
$strDbVersion ne 'minimal' ? $strDbVersion: undef, # Db version
|
||||
$stryModule[0], $stryModuleTest[0], \@iyModuleTestRun, # Module info
|
||||
|
Reference in New Issue
Block a user