diff --git a/src/info/info.c b/src/info/info.c index 426833188..1b5b2031f 100644 --- a/src/info/info.c +++ b/src/info/info.c @@ -40,6 +40,7 @@ Object types struct Info { MemContext *memContext; // Mem context + const String *backrestVersion; // pgBackRest version const String *cipherPass; // Cipher passphrase if set }; @@ -141,6 +142,7 @@ infoNew(const String *cipherPass) // Cipher used to encrypt/decrypt subsequent dependent files. Value may be NULL. this->cipherPass = strDup(cipherPass); + this->backrestVersion = STRDEF(PROJECT_VERSION); } MEM_CONTEXT_NEW_END(); @@ -209,6 +211,15 @@ infoLoadCallback(void *data, const String *section, const String *key, const Str if (jsonToUInt(value) != REPOSITORY_FORMAT) THROW_FMT(FormatError, "expected format %d but found %d", REPOSITORY_FORMAT, cvtZToInt(strPtr(value))); } + // Store pgBackRest version + else if (strEq(key, INFO_KEY_VERSION_STR)) + { + MEM_CONTEXT_BEGIN(loadData->info->memContext) + { + loadData->info->backrestVersion = jsonToStr(value); + } + MEM_CONTEXT_END(); + } // Store checksum to be validated later else if (strEq(key, INFO_KEY_CHECKSUM_STR)) { @@ -451,6 +462,18 @@ infoCipherPass(const Info *this) FUNCTION_TEST_RETURN(this->cipherPass); } +const String * +infoBackrestVersion(const Info *this) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(INFO, this); + FUNCTION_TEST_END(); + + ASSERT(this != NULL); + + FUNCTION_TEST_RETURN(this->backrestVersion); +} + /*********************************************************************************************************************************** Load info file(s) and throw error for each attempt if none are successful ***********************************************************************************************************************************/ diff --git a/src/info/info.h b/src/info/info.h index a41a3a1b8..5f3233396 100644 --- a/src/info/info.h +++ b/src/info/info.h @@ -54,6 +54,7 @@ void infoSaveValue(InfoSave *infoSaveData, const String *section, const String * Getters ***********************************************************************************************************************************/ const String *infoCipherPass(const Info *this); +const String *infoBackrestVersion(const Info *this); /*********************************************************************************************************************************** Helper functions diff --git a/src/info/manifest.c b/src/info/manifest.c index d1cb8c6e5..2d0b5d325 100644 --- a/src/info/manifest.c +++ b/src/info/manifest.c @@ -803,6 +803,7 @@ manifestNewLoad(IoRead *read) MEM_CONTEXT_END(); this->info = infoNewLoad(read, manifestLoadCallback, &loadData); + this->data.backrestVersion = infoBackrestVersion(this->info); // Process file defaults for (unsigned int fileIdx = 0; fileIdx < manifestFileTotal(this); fileIdx++) diff --git a/src/info/manifest.h b/src/info/manifest.h index afe4bbf3d..93f55d9a6 100644 --- a/src/info/manifest.h +++ b/src/info/manifest.h @@ -38,6 +38,8 @@ Manifest data ***********************************************************************************************************************************/ typedef struct ManifestData { + const String *backrestVersion; // pgBackRest version + const String *backupLabel; // Backup label (unique identifier for the backup) const String *backupLabelPrior; // Backup label for backup this diff/incr is based on time_t backupTimestampCopyStart; // When did the file copy start? diff --git a/test/src/module/info/infoTest.c b/test/src/module/info/infoTest.c index ca2b0e78e..d8183f24e 100644 --- a/test/src/module/info/infoTest.c +++ b/test/src/module/info/infoTest.c @@ -118,11 +118,12 @@ testRun(void) "[backrest]\n" "backrest-checksum=\"BOGUS\"\n" "backrest-format=5\n" - "backrest-version=\"2.17\"\n"); + "backrest-version=\"2.17\"\n" + "bogus=\"BOGUS\"\n"); TEST_ERROR( infoNewLoad(ioBufferReadNew(contentLoad), harnessInfoLoadNewCallback, callbackContent), ChecksumError, - "invalid checksum, actual 'a9e578459485db14eb1093809a7964832be2779a' but expected 'BOGUS'"); + "invalid checksum, actual 'fe989a75dcf7a0261e57d210707c0db741462763' but expected 'BOGUS'"); TEST_RESULT_STR(strPtr(callbackContent), "", " check callback content"); // Crypto expected @@ -196,6 +197,7 @@ testRun(void) infoNewLoad(ioBufferReadNew(contentLoad), harnessInfoLoadNewCallback, callbackContent), "info with content and cipher"); TEST_RESULT_STR(strPtr(callbackContent), "[c] key=1\n[d] key=1\n", " check callback content"); TEST_RESULT_STR(strPtr(infoCipherPass(info)), "somepass", " check cipher pass set"); + TEST_RESULT_STR(strPtr(infoBackrestVersion(info)), PROJECT_VERSION, " check backrest version"); contentSave = bufNew(0); diff --git a/test/src/module/info/manifestTest.c b/test/src/module/info/manifestTest.c index 5f61cd8e4..7000ff74d 100644 --- a/test/src/module/info/manifestTest.c +++ b/test/src/module/info/manifestTest.c @@ -417,6 +417,7 @@ testRun(void) storagePutNP(storageNewWriteNP(storageTest, strNew(BACKUP_MANIFEST_FILE INFO_COPY_EXT)), content), "write copy"); TEST_ASSIGN(manifest, manifestLoadFile(storageTest, STRDEF(BACKUP_MANIFEST_FILE), cipherTypeNone, NULL), "load copy"); TEST_RESULT_UINT(manifestData(manifest)->pgSystemId, 1000000000000000094, " check file loaded"); + TEST_RESULT_STR(strPtr(manifestData(manifest)->backrestVersion), PROJECT_VERSION, " check backrest version"); storageRemoveP(storageTest, strNew(BACKUP_MANIFEST_FILE INFO_COPY_EXT), .errorOnMissing = true);