You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-17 01:12:23 +02:00
Add command and exit modules.
This commit is contained in:
@ -62,7 +62,7 @@
|
|||||||
</release-item>
|
</release-item>
|
||||||
|
|
||||||
<release-item>
|
<release-item>
|
||||||
<p>Add <code>log</code> and <code>time</code> modules.</p>
|
<p>Add <code>command</code>, <code>exit</code>, <code>log</code>, and <code>time</code> modules.</p>
|
||||||
</release-item>
|
</release-item>
|
||||||
|
|
||||||
<release-item>
|
<release-item>
|
||||||
|
@ -3,8 +3,10 @@ CFLAGS=-I. -Wfatal-errors -Wall -Wextra -Wwrite-strings -Wno-clobbered -std=c99
|
|||||||
DESTDIR=
|
DESTDIR=
|
||||||
|
|
||||||
pgbackrest: \
|
pgbackrest: \
|
||||||
|
command/command.o \
|
||||||
common/error.o \
|
common/error.o \
|
||||||
common/errorType.o \
|
common/errorType.o \
|
||||||
|
common/exit.o \
|
||||||
common/ini.o \
|
common/ini.o \
|
||||||
common/log.o \
|
common/log.o \
|
||||||
common/memContext.o \
|
common/memContext.o \
|
||||||
@ -27,8 +29,10 @@ pgbackrest: \
|
|||||||
storage/storage.o \
|
storage/storage.o \
|
||||||
main.o
|
main.o
|
||||||
$(CC) $(CFLAGS) -o pgbackrest \
|
$(CC) $(CFLAGS) -o pgbackrest \
|
||||||
|
command/command.o \
|
||||||
common/error.o \
|
common/error.o \
|
||||||
common/errorType.o \
|
common/errorType.o \
|
||||||
|
common/exit.o \
|
||||||
common/ini.o \
|
common/ini.o \
|
||||||
common/log.o \
|
common/log.o \
|
||||||
common/memContext.o \
|
common/memContext.o \
|
||||||
|
83
src/command/command.c
Normal file
83
src/command/command.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Common Command Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/memContext.h"
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Begin the command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void cmdBegin()
|
||||||
|
{
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Basic info on command start
|
||||||
|
String *info = strNewFmt("%s command begin %s:", cfgCommandName(cfgCommand()), PGBACKREST_VERSION);
|
||||||
|
|
||||||
|
// Loop though options and add the ones that are interesting
|
||||||
|
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||||
|
{
|
||||||
|
const Variant *option = cfgOption(optionId);
|
||||||
|
|
||||||
|
// Skip the option if it is not valid, or default, or not set
|
||||||
|
if (!cfgOptionValid(optionId) ||
|
||||||
|
cfgOptionSource(optionId) == cfgSourceDefault ||
|
||||||
|
(option == NULL && !cfgOptionNegate(optionId)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If option was negated
|
||||||
|
if (cfgOptionNegate(optionId))
|
||||||
|
strCatFmt(info, " --no-%s", cfgOptionName(optionId));
|
||||||
|
// Else not negated
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||||
|
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||||
|
|
||||||
|
if (cfgDefOptionType(optionDefId) != cfgDefOptTypeBoolean)
|
||||||
|
{
|
||||||
|
if (cfgDefOptionSecure(optionDefId))
|
||||||
|
strCat(info, "=<redacted>");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const String *optionStr = varStrForce(option);
|
||||||
|
|
||||||
|
if (strchr(strPtr(optionStr), ' ') != NULL)
|
||||||
|
optionStr = strNewFmt("\"%s\"", strPtr(optionStr));
|
||||||
|
|
||||||
|
strCatFmt(info, "=%s", strPtr(optionStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(strPtr(info));
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
End the command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void cmdEnd(int code)
|
||||||
|
{
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Basic info on command end
|
||||||
|
String *info = strNewFmt("%s command end: ", cfgCommandName(cfgCommand()));
|
||||||
|
|
||||||
|
if (code == 0)
|
||||||
|
strCat(info, "completed successfully");
|
||||||
|
else
|
||||||
|
strCatFmt(info, "aborted with exception [%03d]", code);
|
||||||
|
|
||||||
|
LOG_INFO(strPtr(info));
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
}
|
13
src/command/command.h
Normal file
13
src/command/command.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Common Command Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMAND_H
|
||||||
|
#define COMMAND_H
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void cmdBegin();
|
||||||
|
void cmdEnd(int code);
|
||||||
|
|
||||||
|
#endif
|
28
src/common/exit.c
Normal file
28
src/common/exit.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Exit Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "command/command.h"
|
||||||
|
#include "common/exit.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Do cleanup and return result code
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
int
|
||||||
|
exitSafe(bool error)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
// Report error if one was thrown
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
LOG_ERROR(errorCode(), errorMessage());
|
||||||
|
result = errorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log command end
|
||||||
|
cmdEnd(result);
|
||||||
|
|
||||||
|
// Return result - caller should immediate pass this result to exit()
|
||||||
|
return result;
|
||||||
|
}
|
14
src/common/exit.h
Normal file
14
src/common/exit.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Exit Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_EXIT_H
|
||||||
|
#define COMMON_EXIT_H
|
||||||
|
|
||||||
|
#include "common/error.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
int exitSafe(bool error);
|
||||||
|
|
||||||
|
#endif
|
@ -5,7 +5,7 @@ Main
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/log.h"
|
#include "common/exit.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "config/load.h"
|
#include "config/load.h"
|
||||||
#include "perl/exec.h"
|
#include "perl/exec.h"
|
||||||
@ -29,12 +29,14 @@ int main(int argListSize, const char *argList[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute Perl for commands not implemented in C
|
// Execute Perl for commands not implemented in C
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
perlExec(perlCommand());
|
perlExec(perlCommand());
|
||||||
}
|
}
|
||||||
CATCH_ANY()
|
CATCH_ANY()
|
||||||
{
|
{
|
||||||
LOG_ERROR(errorCode(), errorMessage());
|
exit(exitSafe(true));
|
||||||
exit(errorCode());
|
|
||||||
}
|
}
|
||||||
TRY_END();
|
TRY_END();
|
||||||
|
|
||||||
|
exit(exitSafe(false));
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,16 @@ my $oTestDef =
|
|||||||
'common/log' => TESTDEF_COVERAGE_FULL,
|
'common/log' => TESTDEF_COVERAGE_FULL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&TESTDEF_NAME => 'exit',
|
||||||
|
&TESTDEF_TOTAL => 1,
|
||||||
|
&TESTDEF_C => true,
|
||||||
|
|
||||||
|
&TESTDEF_COVERAGE =>
|
||||||
|
{
|
||||||
|
'common/exit' => TESTDEF_COVERAGE_FULL,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
&TESTDEF_NAME => 'wait',
|
&TESTDEF_NAME => 'wait',
|
||||||
&TESTDEF_TOTAL => 1,
|
&TESTDEF_TOTAL => 1,
|
||||||
@ -633,6 +643,25 @@ my $oTestDef =
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
# Command tests
|
||||||
|
{
|
||||||
|
&TESTDEF_NAME => 'command',
|
||||||
|
&TESTDEF_CONTAINER => true,
|
||||||
|
|
||||||
|
&TESTDEF_TEST =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
&TESTDEF_NAME => 'command',
|
||||||
|
&TESTDEF_TOTAL => 1,
|
||||||
|
&TESTDEF_C => true,
|
||||||
|
|
||||||
|
&TESTDEF_COVERAGE =>
|
||||||
|
{
|
||||||
|
'command/command' => TESTDEF_COVERAGE_FULL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
# Archive tests
|
# Archive tests
|
||||||
{
|
{
|
||||||
&TESTDEF_NAME => 'archive',
|
&TESTDEF_NAME => 'archive',
|
||||||
|
54
test/src/module/command/commandTest.c
Normal file
54
test/src/module/command/commandTest.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Common Command Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "storage/storage.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Run
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void testRun()
|
||||||
|
{
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("cmdBegin() and cmdEnd()"))
|
||||||
|
{
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
cfgInit();
|
||||||
|
cfgCommandSet(cfgCmdArchiveGet);
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptCompress, true);
|
||||||
|
cfgOptionSet(cfgOptCompress, cfgSourceParam, varNewBool(true));
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptConfig, true);
|
||||||
|
cfgOptionNegateSet(cfgOptConfig, true);
|
||||||
|
cfgOptionSet(cfgOptConfig, cfgSourceParam, NULL);
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptDbHost, true);
|
||||||
|
cfgOptionSet(cfgOptDbHost, cfgSourceConfig, NULL);
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptBackupHost, true);
|
||||||
|
cfgOptionSet(cfgOptBackupHost, cfgSourceConfig, varNewStr(strNew("backup1")));
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptRepoPath, true);
|
||||||
|
cfgOptionSet(cfgOptRepoPath, cfgSourceConfig, varNewStr(strNew("/path/to the/repo")));
|
||||||
|
|
||||||
|
cfgOptionValidSet(cfgOptRepoS3Key, true);
|
||||||
|
cfgOptionSet(cfgOptRepoS3Key, cfgSourceConfig, varNewStr(strNew("SECRET-STUFF")));
|
||||||
|
|
||||||
|
cmdBegin();
|
||||||
|
testLogResult(
|
||||||
|
"P00 INFO: archive-get command begin " PGBACKREST_VERSION ": --backup-host=backup1 --compress --no-config "
|
||||||
|
"--repo-path=\"/path/to the/repo\" --repo-s3-key=<redacted>");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
cmdEnd(0);
|
||||||
|
testLogResult("P00 INFO: archive-get command end: completed successfully");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
cmdEnd(25);
|
||||||
|
testLogResult("P00 INFO: archive-get command end: aborted with exception [025]");
|
||||||
|
}
|
||||||
|
}
|
34
test/src/module/common/exitTest.c
Normal file
34
test/src/module/common/exitTest.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Exit Routines
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "config/config.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Run
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void testRun()
|
||||||
|
{
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("exitSafe()"))
|
||||||
|
{
|
||||||
|
cfgInit();
|
||||||
|
cfgCommandSet(cfgCmdArchivePush);
|
||||||
|
|
||||||
|
TEST_RESULT_INT(exitSafe(NULL), 0, "exit with no error")
|
||||||
|
testLogResult("P00 INFO: archive-push command end: completed successfully");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
THROW(RuntimeError, "test error message");
|
||||||
|
}
|
||||||
|
CATCH_ANY()
|
||||||
|
{
|
||||||
|
exitSafe(true);
|
||||||
|
testLogResult(
|
||||||
|
"P00 ERROR: [125]: test error message\n"
|
||||||
|
"P00 INFO: archive-push command end: aborted with exception [125]");
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user