From bffc6c49b31a98fc5a6ae68b80db0251da6e9441 Mon Sep 17 00:00:00 2001 From: David Steele Date: Tue, 16 Jan 2018 13:23:08 -0500 Subject: [PATCH] Add perl-bin option to specify the Perl binary location when /usr/bin/env perl won't work. --- build/lib/pgBackRestBuild/Config/Data.pm | 25 ++++++++++++++++++++ doc/xml/reference.xml | 10 ++++++++ doc/xml/release.xml | 4 ++++ lib/pgBackRest/Config/ConfigHelpData.pm | 22 +++++++++++++++++ libc/lib/pgBackRest/LibCAuto.pm | 1 + libc/xs/config/config.auto.xsh | 1 + src/config/config.auto.c | 8 +++++++ src/config/config.auto.h | 3 ++- src/config/config.c | 2 ++ src/config/define.auto.c | 30 ++++++++++++++++++++++++ src/config/define.auto.h | 1 + src/config/parse.auto.c | 9 +++++++ src/perl/exec.c | 12 ++++++++-- test/expect/help-help-001.log | 2 ++ test/src/module/config/configTest.c | 3 +++ test/src/module/perl/execTest.c | 7 ++++++ 16 files changed, 137 insertions(+), 3 deletions(-) diff --git a/build/lib/pgBackRestBuild/Config/Data.pm b/build/lib/pgBackRestBuild/Config/Data.pm index ed459eb29..fb55780bc 100644 --- a/build/lib/pgBackRestBuild/Config/Data.pm +++ b/build/lib/pgBackRestBuild/Config/Data.pm @@ -185,6 +185,8 @@ use constant CFGOPT_SPOOL_PATH => 'spool-pa push @EXPORT, qw(CFGOPT_SPOOL_PATH); # Perl +use constant CFGOPT_PERL_BIN => 'perl-bin'; + push @EXPORT, qw(CFGOPT_PERL_BIN); use constant CFGOPT_PERL_OPTION => 'perl-option'; push @EXPORT, qw(CFGOPT_PERL_OPTION); @@ -1071,6 +1073,29 @@ my %hConfigDefine = }, }, + &CFGOPT_PERL_BIN => + { + &CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL, + &CFGDEF_TYPE => CFGDEF_TYPE_STRING, + &CFGDEF_REQUIRED => false, + &CFGDEF_COMMAND => + { + &CFGCMD_ARCHIVE_GET => {}, + &CFGCMD_ARCHIVE_PUSH => {}, + &CFGCMD_BACKUP => {}, + &CFGCMD_CHECK => {}, + &CFGCMD_EXPIRE => {}, + &CFGCMD_INFO => {}, + &CFGCMD_LOCAL => {}, + &CFGCMD_REMOTE => {}, + &CFGCMD_RESTORE => {}, + &CFGCMD_STANZA_CREATE => {}, + &CFGCMD_STANZA_UPGRADE => {}, + &CFGCMD_START => {}, + &CFGCMD_STOP => {}, + }, + }, + &CFGOPT_PERL_OPTION => { &CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL, diff --git a/doc/xml/reference.xml b/doc/xml/reference.xml index 38c3cf5eb..3cae6f88b 100644 --- a/doc/xml/reference.xml +++ b/doc/xml/reference.xml @@ -183,9 +183,19 @@ /backup/db/spool + + + Path of Perl binary. + + Path of the Perl binary if /usr/bin/env perl won't work. + + /usr/bin/perl + + Max processes to use for compress/transfer. + Each process will perform compression and transfer to make the command run faster, but don't set process-max so high that it impacts database performance. 4 diff --git a/doc/xml/release.xml b/doc/xml/release.xml index 29c87f491..34b163bf5 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -24,6 +24,10 @@

Allow any non-boolean, non-command-line option to be negated. This allows specific options in pgbackrest.conf to be ignored (and set to default) which reduces the need to write new configuration files for specific needs. Note that boolean, non-command-line options are already negatable.

+ + +

Add perl-bin option to specify the Perl binary location when /usr/bin/env perl won't work.

+
diff --git a/lib/pgBackRest/Config/ConfigHelpData.pm b/lib/pgBackRest/Config/ConfigHelpData.pm index a36dd2638..92b1f18e9 100644 --- a/lib/pgBackRest/Config/ConfigHelpData.pm +++ b/lib/pgBackRest/Config/ConfigHelpData.pm @@ -556,6 +556,17 @@ my $oConfigHelpData = "the command line." }, + # PERL-BIN Option Help + #--------------------------------------------------------------------------------------------------------------------------- + 'perl-bin' => + { + section => 'general', + summary => + "Path of Perl binary.", + description => + "Path of the Perl binary if /usr/bin/env perl won't work." + }, + # PROCESS-MAX Option Help #--------------------------------------------------------------------------------------------------------------------------- 'process-max' => @@ -971,6 +982,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', @@ -1026,6 +1038,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'process-max' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', @@ -1121,6 +1134,7 @@ my $oConfigHelpData = "and archive-check is automatically disabled for the backup." }, + 'perl-bin' => 'section', 'process-max' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', @@ -1223,6 +1237,7 @@ my $oConfigHelpData = "Specifying --no-online prevents pgBackRest from connecting to PostgreSQL and will disable some checks." }, + 'perl-bin' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', @@ -1268,6 +1283,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', 'repo-path' => 'section', @@ -1349,6 +1365,7 @@ my $oConfigHelpData = "* json - Exhaustive machine-readable backup information in JSON format." }, + 'perl-bin' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', @@ -1423,6 +1440,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'process-max' => 'section', 'protocol-timeout' => 'section', 'recovery-option' => 'section', @@ -1590,6 +1608,7 @@ my $oConfigHelpData = "Specifying --no-online prevents pgBackRest from connecting to PostgreSQL when creating the stanza." }, + 'perl-bin' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', @@ -1730,6 +1749,7 @@ my $oConfigHelpData = "Specifying --no-online prevents pgBackRest from connecting to PostgreSQL when upgrading the stanza." }, + 'perl-bin' => 'section', 'protocol-timeout' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', @@ -1779,6 +1799,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', 'repo-path' => 'section', @@ -1843,6 +1864,7 @@ my $oConfigHelpData = 'log-path' => 'section', 'log-timestamp' => 'section', 'neutral-umask' => 'section', + 'perl-bin' => 'section', 'repo-cipher-pass' => 'section', 'repo-cipher-type' => 'section', 'repo-path' => 'section', diff --git a/libc/lib/pgBackRest/LibCAuto.pm b/libc/lib/pgBackRest/LibCAuto.pm index 796765f59..06d9120e2 100644 --- a/libc/lib/pgBackRest/LibCAuto.pm +++ b/libc/lib/pgBackRest/LibCAuto.pm @@ -160,6 +160,7 @@ sub libcAutoExportTag 'CFGOPT_NEUTRAL_UMASK', 'CFGOPT_ONLINE', 'CFGOPT_OUTPUT', + 'CFGOPT_PERL_BIN', 'CFGOPT_PERL_OPTION', 'CFGOPT_PROCESS', 'CFGOPT_PROCESS_MAX', diff --git a/libc/xs/config/config.auto.xsh b/libc/xs/config/config.auto.xsh index 7f525b17a..bc654f8ab 100644 --- a/libc/xs/config/config.auto.xsh +++ b/libc/xs/config/config.auto.xsh @@ -74,6 +74,7 @@ Option constants #define CFGOPT_NEUTRAL_UMASK cfgOptNeutralUmask #define CFGOPT_ONLINE cfgOptOnline #define CFGOPT_OUTPUT cfgOptOutput +#define CFGOPT_PERL_BIN cfgOptPerlBin #define CFGOPT_PERL_OPTION cfgOptPerlOption #define CFGOPT_PROCESS cfgOptProcess #define CFGOPT_PROCESS_MAX cfgOptProcessMax diff --git a/src/config/config.auto.c b/src/config/config.auto.c index ef8a270b6..bce8f6f44 100644 --- a/src/config/config.auto.c +++ b/src/config/config.auto.c @@ -903,6 +903,14 @@ ConfigOptionData configOptionData[CFG_OPTION_TOTAL] = CONFIG_OPTION_LIST CONFIG_OPTION_DEFINE_ID(cfgDefOptOutput) ) + //------------------------------------------------------------------------------------------------------------------------------ + CONFIG_OPTION + ( + CONFIG_OPTION_NAME("perl-bin") + CONFIG_OPTION_INDEX(0) + CONFIG_OPTION_DEFINE_ID(cfgDefOptPerlBin) + ) + //------------------------------------------------------------------------------------------------------------------------------ CONFIG_OPTION ( diff --git a/src/config/config.auto.h b/src/config/config.auto.h index 2846d4a82..992d7fed6 100644 --- a/src/config/config.auto.h +++ b/src/config/config.auto.h @@ -14,7 +14,7 @@ Command constants /*********************************************************************************************************************************** Option constants ***********************************************************************************************************************************/ -#define CFG_OPTION_TOTAL 139 +#define CFG_OPTION_TOTAL 140 /*********************************************************************************************************************************** Command enum @@ -90,6 +90,7 @@ typedef enum cfgOptNeutralUmask, cfgOptOnline, cfgOptOutput, + cfgOptPerlBin, cfgOptPerlOption, cfgOptProcess, cfgOptProcessMax, diff --git a/src/config/config.c b/src/config/config.c index 00d944f08..db1831ba5 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -528,6 +528,8 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value) break; } } + else + configOptionValue[optionId].value = NULL; // Free old value if (valueOld != NULL) diff --git a/src/config/define.auto.c b/src/config/define.auto.c index dc16c0a6b..26881af5c 100644 --- a/src/config/define.auto.c +++ b/src/config/define.auto.c @@ -1533,6 +1533,36 @@ ConfigDefineOptionData configDefineOptionData[] = CFGDEFDATA_OPTION_LIST ) ) + // ----------------------------------------------------------------------------------------------------------------------------- + CFGDEFDATA_OPTION + ( + CFGDEFDATA_OPTION_NAME("perl-bin") + CFGDEFDATA_OPTION_REQUIRED(false) + CFGDEFDATA_OPTION_SECTION(cfgDefSectionGlobal) + CFGDEFDATA_OPTION_TYPE(cfgDefOptTypeString) + + CFGDEFDATA_OPTION_INDEX_TOTAL(1) + CFGDEFDATA_OPTION_NEGATE(true) + CFGDEFDATA_OPTION_SECURE(false) + + CFGDEFDATA_OPTION_COMMAND_LIST + ( + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdArchiveGet) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdArchivePush) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdBackup) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdCheck) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdExpire) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdInfo) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdLocal) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdRemote) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdRestore) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdStanzaCreate) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdStanzaUpgrade) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdStart) + CFGDEFDATA_OPTION_COMMAND(cfgDefCmdStop) + ) + ) + // ----------------------------------------------------------------------------------------------------------------------------- CFGDEFDATA_OPTION ( diff --git a/src/config/define.auto.h b/src/config/define.auto.h index c1406bcb8..8ef4f5abb 100644 --- a/src/config/define.auto.h +++ b/src/config/define.auto.h @@ -92,6 +92,7 @@ typedef enum cfgDefOptNeutralUmask, cfgDefOptOnline, cfgDefOptOutput, + cfgDefOptPerlBin, cfgDefOptPerlOption, cfgDefOptProcess, cfgDefOptProcessMax, diff --git a/src/config/parse.auto.c b/src/config/parse.auto.c index ef40189fb..f980bb2aa 100644 --- a/src/config/parse.auto.c +++ b/src/config/parse.auto.c @@ -957,6 +957,15 @@ static const struct option optionList[] = .has_arg = required_argument, .val = PARSE_OPTION_FLAG | cfgOptOutput, }, + { + .name = "perl-bin", + .has_arg = required_argument, + .val = PARSE_OPTION_FLAG | cfgOptPerlBin, + }, + { + .name = "no-perl-bin", + .val = PARSE_OPTION_FLAG | PARSE_NEGATE_FLAG | cfgOptPerlBin, + }, { .name = "perl-option", .has_arg = required_argument, diff --git a/src/perl/exec.c b/src/perl/exec.c index ac082dcb8..e26403262 100644 --- a/src/perl/exec.c +++ b/src/perl/exec.c @@ -31,8 +31,16 @@ StringList *perlCommand() { // Begin arg list for perl exec StringList *perlArgList = strLstNew(); - strLstAdd(perlArgList, strNew(ENV_EXE)); - strLstAdd(perlArgList, strNew(PERL_EXE)); + + // Use specific perl bin if passed + if (cfgOption(cfgOptPerlBin) != NULL) + strLstAdd(perlArgList, strDup(cfgOptionStr(cfgOptPerlBin))); + // Otherwise use env to find it + else + { + strLstAdd(perlArgList, strNew(ENV_EXE)); + strLstAdd(perlArgList, strNew(PERL_EXE)); + } // Construct option list to pass to main String *mainCallParam = strNew(""); diff --git a/test/expect/help-help-001.log b/test/expect/help-help-001.log index 3a4e6e1c3..a34ceadb5 100644 --- a/test/expect/help-help-001.log +++ b/test/expect/help-help-001.log @@ -67,6 +67,7 @@ compress=n [default=3] [default=/etc/pgbackrest.conf] --lock-path path where lock files are stored [default=/tmp/pgbackrest] + --perl-bin path of Perl binary --protocol-timeout protocol timeout [default=1830] --stanza defines the stanza [current=main] @@ -163,6 +164,7 @@ compress=n [default=3] [default=/etc/pgbackrest.conf] --db-timeout database query timeout [default=1800] --neutral-umask use a neutral umask [default=y] + --perl-bin path of Perl binary --protocol-timeout protocol timeout [default=1830] --stanza defines the stanza diff --git a/test/src/module/config/configTest.c b/test/src/module/config/configTest.c index 5c87d5094..2e636727d 100644 --- a/test/src/module/config/configTest.c +++ b/test/src/module/config/configTest.c @@ -126,6 +126,9 @@ void testRun() TEST_RESULT_INT(cfgOptionSource(cfgOptProtocolTimeout), cfgSourceConfig, "protocol-timeout source is set"); TEST_ERROR(cfgOptionKv(cfgOptProtocolTimeout), AssertError, "option 'protocol-timeout' is not type 'KeyValue'"); + TEST_RESULT_VOID(cfgOptionSet(cfgOptProtocolTimeout, cfgSourceConfig, NULL), "set protocol-timeout to NULL"); + TEST_RESULT_PTR(cfgOption(cfgOptProtocolTimeout), NULL, "protocol-timeout is not set"); + TEST_ERROR( cfgOptionSet(cfgOptRecoveryOption, cfgSourceParam, varNewDbl(1.1)), AssertError, "option 'recovery-option' must be set with KeyValue variant"); diff --git a/test/src/module/perl/execTest.c b/test/src/module/perl/execTest.c index 6a61df619..3e29abf05 100644 --- a/test/src/module/perl/execTest.c +++ b/test/src/module/perl/execTest.c @@ -21,6 +21,13 @@ void testRun() cfgInit(); cfgCommandSet(cfgCmdInfo); cfgExeSet(strNew(TEST_BACKREST_EXE)); + cfgOptionSet(cfgOptPerlBin, cfgSourceParam, varNewStrZ("/usr/bin/perl")); + + TEST_RESULT_STR( + strPtr(strLstJoin(perlCommand(), "|")), + "/usr/bin/perl|" TEST_PERL_MAIN "', 'info')|[NULL]", "custom command with no options"); + + cfgOptionSet(cfgOptPerlBin, cfgSourceParam, NULL); TEST_RESULT_STR( strPtr(strLstJoin(perlCommand(), "|")),