1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-12-03 22:39:18 +02:00

Added documentation in the user guide for delta restores, expiration, dedicated backup hosts, starting and stopping pgBackRest, and replication.

This commit is contained in:
David Steele
2015-11-22 16:44:01 -05:00
parent 8ddfdcdd3b
commit fa05715dec
33 changed files with 10520 additions and 1263 deletions

View File

@@ -2,6 +2,7 @@
# DOC HTML PAGE MODULE
####################################################################################################################################
package BackRestDoc::Html::DocHtmlPage;
use parent 'BackRestDoc::Common::DocExecute';
use strict;
use warnings FATAL => qw(all);
@@ -15,15 +16,11 @@ use File::Copy;
use Storable qw(dclone);
use lib dirname($0) . '/../lib';
use BackRest::Common::Ini;
use BackRest::Common::Log;
use BackRest::Common::String;
use BackRest::Config::ConfigHelp;
use BackRest::FileCommon;
use lib dirname($0) . '/../test/lib';
use BackRestTest::Common::ExecuteTest;
use BackRestDoc::Common::DocManifest;
use BackRestDoc::Html::DocHtmlBuilder;
use BackRestDoc::Html::DocHtmlElement;
@@ -33,7 +30,6 @@ use BackRestDoc::Html::DocHtmlElement;
use constant OP_DOC_HTML_PAGE => 'DocHtmlPage';
use constant OP_DOC_HTML_PAGE_BACKREST_CONFIG_PROCESS => OP_DOC_HTML_PAGE . '->backrestConfigProcess';
use constant OP_DOC_HTML_PAGE_EXECUTE => OP_DOC_HTML_PAGE . '->execute';
use constant OP_DOC_HTML_PAGE_NEW => OP_DOC_HTML_PAGE . '->new';
use constant OP_DOC_HTML_PAGE_POSTGRES_CONFIG_PROCESS => OP_DOC_HTML_PAGE . '->postgresConfigProcess';
use constant OP_DOC_HTML_PAGE_PROCESS => OP_DOC_HTML_PAGE . '->process';
@@ -46,35 +42,25 @@ sub new
{
my $class = shift; # Class name
# Create the class hash
my $self = {};
bless $self, $class;
$self->{strClass} = $class;
# Assign function parameters, defaults, and log debug info
my
(
my $strOperation,
$self->{oSite},
$self->{strPageId},
$self->{bExe}
$strOperation,
$oManifest,
$strRenderOutKey,
$bExe
) =
logDebugParam
(
OP_DOC_HTML_PAGE_NEW, \@_,
{name => 'oSite'},
{name => 'strPageId'},
{name => 'bExe', default => true}
{name => 'oManifest'},
{name => 'strRenderOutKey'},
{name => 'bExe'}
);
#
# use Data::Dumper;
# confess Dumper(${$self->{oSite}->{oSite}}{common}{oRender});
# Copy page data to self
$self->{oPage} = ${$self->{oSite}->{oSite}}{page}{$self->{strPageId}};
$self->{oDoc} = ${$self->{oPage}}{'oDoc'};
$self->{oRender} = ${$self->{oSite}->{oSite}}{common}{oRender};
$self->{oReference} = ${$self->{oSite}->{oSite}}{common}{oReference};
# Create the class hash
my $self = $class->SUPER::new(RENDER_TYPE_HTML, $oManifest, $strRenderOutKey, $bExe);
bless $self, $class;
# Return from function and log return values if any
return logDebugReturn
@@ -84,100 +70,6 @@ sub new
);
}
####################################################################################################################################
# execute
####################################################################################################################################
sub execute
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$oCommand,
$iIndent
) =
logDebugParam
(
OP_DOC_HTML_PAGE_EXECUTE, \@_,
{name => 'oCommand'},
{name => 'iIndent', default => 1}
);
# Working variables
my $strOutput;
# Command variables
my $strCommand = trim($oCommand->fieldGet('exe-cmd'));
my $strUser = $oCommand->fieldGet('exe-user', false);
my $bSuppressError = defined($oCommand->fieldGet('exe-err-suppress', false)) ? $oCommand->fieldGet('exe-err-suppress') : false;
my $bSuppressStdErr = defined($oCommand->fieldGet('exe-err-suppress-stderr', false)) ?
$oCommand->fieldGet('exe-err-suppress-stderr') : false;
my $bExeSkip = defined($oCommand->fieldGet('exe-skip', false)) ? $oCommand->fieldGet('exe-skip') : false;
my $bExeOutput = defined($oCommand->fieldGet('exe-output', false)) ? $oCommand->fieldGet('exe-output') : false;
my $bExeRetry = defined($oCommand->fieldGet('exe-retry', false)) ? $oCommand->fieldGet('exe-retry') : false;
my $strExeVar = defined($oCommand->fieldGet('exe-var', false)) ? $oCommand->fieldGet('exe-var') : undef;
my $iExeExpectedError = defined($oCommand->fieldGet('exe-err-expect', false)) ? $oCommand->fieldGet('exe-err-expect') : undef;
if ($bExeRetry)
{
sleep(1);
}
$strUser = defined($strUser) ? $strUser : 'postgres';
$strCommand = $self->{oSite}->variableReplace(
($strUser eq 'vagrant' ? '' : 'sudo ' . ($strUser eq 'root' ? '' : "-u ${strUser} ")) . $strCommand);
&log(INFO, (' ' x $iIndent) . "execute: $strCommand");
if (!$bExeSkip)
{
if ($self->{bExe})
{
my $oExec = new BackRestTest::Common::ExecuteTest($strCommand,
{bSuppressError => $bSuppressError,
bSuppressStdErr => $bSuppressStdErr,
iExpectedExitStatus => $iExeExpectedError});
$oExec->begin();
$oExec->end();
if ($bExeOutput && defined($oExec->{strOutLog}) && $oExec->{strOutLog} ne '')
{
$strOutput = trim($oExec->{strOutLog});
$strOutput =~ s/^[0-9]{4}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-6][0-9]:[0-6][0-9]\.[0-9]{3} T[0-9]{2} //smg;
}
if (defined($strExeVar))
{
$self->{oSite}->variableSet($strExeVar, trim($oExec->{strOutLog}));
}
if (defined($iExeExpectedError))
{
$strOutput .= trim($oExec->{strErrorLog});
}
}
elsif ($bExeOutput)
{
$strOutput = 'Output suppressed for testing';
}
}
if (defined($strExeVar) && !defined($self->{oSite}->variableGet($strExeVar)))
{
$self->{oSite}->variableSet($strExeVar, '[Unset Variable]');
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => '$strCommand', value => $strCommand, trace => true},
{name => '$strOutput', value => $strOutput, trace => true}
);
}
####################################################################################################################################
# process
#
@@ -194,23 +86,13 @@ sub process
my $oPage = $self->{oDoc};
# Initialize page
my $strTitle = ${$self->{oRender}}{strProjectName} .
my $strTitle = "{[project]}" .
(defined($oPage->paramGet('title', false)) ? ' ' . $oPage->paramGet('title') : '');
my $strSubTitle = $oPage->paramGet('subtitle', false);
my $oHtmlBuilder = new BackRestDoc::Html::DocHtmlBuilder("${$self->{oRender}}{strProjectName} - Reliable PostgreSQL Backup",
$strTitle . (defined($strSubTitle) ? " - ${strSubTitle}" : ''));
# Execute cleanup commands
if (defined($self->{oDoc}->nodeGet('cleanup', false)))
{
&log(INFO, "do cleanup");
foreach my $oExecute ($oPage->nodeGet('cleanup')->nodeList('execute'))
{
$self->execute($oExecute);
}
}
my $oHtmlBuilder = new BackRestDoc::Html::DocHtmlBuilder("{[project]} - Reliable PostgreSQL Backup",
$strTitle . (defined($strSubTitle) ? " - ${strSubTitle}" : ''),
$self->{bPretty});
# Generate header
my $oPageHeader = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-header');
@@ -229,24 +111,24 @@ sub process
# Generate menu
my $oMenuBody = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-menu')->addNew(HTML_DIV, 'menu-body');
if ($self->{strPageId} ne 'index')
if ($self->{strRenderOutKey} ne 'index')
{
my $oPage = ${$self->{oSite}->{oSite}}{page}{'index'};
my $oRenderOut = $self->{oManifest}->renderOutGet(RENDER_TYPE_HTML, 'index');
$oMenuBody->
addNew(HTML_DIV, 'menu')->
addNew(HTML_A, 'menu-link', {strContent => $$oPage{strMenuTitle}, strRef => '{[backrest-url-root]}'});
addNew(HTML_A, 'menu-link', {strContent => $$oRenderOut{menu}, strRef => '{[project-url-root]}'});
}
foreach my $strPageId(sort(keys(${$self->{oSite}->{oSite}}{page})))
foreach my $strRenderOutKey ($self->{oManifest}->renderOutList(RENDER_TYPE_HTML))
{
if ($strPageId ne $self->{strPageId} && $strPageId ne 'index')
if ($strRenderOutKey ne $self->{strRenderOutKey} && $strRenderOutKey ne 'index')
{
my $oPage = ${$self->{oSite}->{oSite}}{page}{$strPageId};
my $oRenderOut = $self->{oManifest}->renderOutGet(RENDER_TYPE_HTML, $strRenderOutKey);
$oMenuBody->
addNew(HTML_DIV, 'menu')->
addNew(HTML_A, 'menu-link', {strContent => $$oPage{strMenuTitle}, strRef => "${strPageId}.html"});
addNew(HTML_A, 'menu-link', {strContent => $$oRenderOut{menu}, strRef => "${strRenderOutKey}.html"});
}
}
@@ -284,7 +166,7 @@ sub process
my $oPageFooter = $oHtmlBuilder->bodyGet()->
addNew(HTML_DIV, 'page-footer',
{strContent => ${$self->{oSite}->{oSite}}{common}{strFooter}});
{strContent => '{[html-footer]}'});
# Return from function and log return values if any
return logDebugReturn
@@ -317,7 +199,7 @@ sub sectionProcess
{name => 'iDepth'}
);
&log(INFO, (' ' x ($iDepth - 1)) . 'process section: ' . $oSection->paramGet('id'));
&log($iDepth == 1 ? INFO : DEBUG, (' ' x ($iDepth + 1)) . 'process section: ' . $oSection->paramGet('id'));
if ($iDepth > 3)
{
@@ -326,7 +208,6 @@ sub sectionProcess
# Working variables
$strAnchor = (defined($strAnchor) ? "${strAnchor}-" : '') . $oSection->paramGet('id');
my $oRender = $self->{oRender};
# Create the section toc element
my $oSectionTocElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "section${iDepth}-toc");
@@ -338,7 +219,7 @@ sub sectionProcess
$oSectionElement->addNew(HTML_A, undef, {strId => $strAnchor});
# Add the section title to section and toc
my $strSectionTitle = $oRender->processText($oSection->nodeGet('title')->textGet());
my $strSectionTitle = $self->processText($oSection->nodeGet('title')->textGet());
$oSectionElement->
addNew(HTML_DIV, "section${iDepth}-title",
@@ -356,7 +237,7 @@ sub sectionProcess
{
$oSectionElement->
addNew(HTML_DIV, "section-intro",
{strContent => $oRender->processText($oSection->textGet())});
{strContent => $self->processText($oSection->textGet())});
}
# Add the section body
@@ -367,39 +248,51 @@ sub sectionProcess
foreach my $oChild ($oSection->nodeList())
{
&log(INFO, (' ' x $iDepth) . 'process child ' . $oChild->nameGet());
&log(DEBUG, (' ' x ($iDepth + 2)) . 'process child ' . $oChild->nameGet());
# Execute a command
if ($oChild->nameGet() eq 'execute-list')
{
my $oSectionBodyExecute = $oSectionBodyElement->addNew(HTML_DIV, "execute");
my $bFirst = true;
my $strHostName = $self->{oManifest}->variableReplace($oChild->paramGet('host'));
$oSectionBodyExecute->
addNew(HTML_DIV, "execute-title",
{strContent => $oRender->processText($oChild->nodeGet('title')->textGet()) . ':'});
{strContent => "<span class=\"host\">${strHostName}</span> <b>&#x21d2;</b> " .
$self->processText($oChild->nodeGet('title')->textGet())});
my $oExecuteBodyElement = $oSectionBodyExecute->addNew(HTML_DIV, "execute-body");
foreach my $oExecute ($oChild->nodeList('execute'))
{
my $bExeShow = defined($oExecute->fieldGet('exe-no-show', false)) ? false : true;
my $bExeExpectedError = defined($oExecute->fieldGet('exe-err-expect', false)) ? true : false;
my ($strCommand, $strOutput) = $self->execute($oExecute, $iDepth + 1);
my $bExeShow = !$oExecute->paramTest('show', 'n');
my $bExeExpectedError = defined($oExecute->paramGet('err-expect', false));
my ($strCommand, $strOutput) = $self->execute($oSection, $strHostName, $oExecute, $iDepth + 3);
if ($bExeShow)
{
# Add continuation chars and proper spacing
$strCommand =~ s/\n/\n /smg;
$oExecuteBodyElement->
addNew(HTML_DIV, "execute-body-cmd" . ($bFirst ? '-first' : ''),
{strContent => $strCommand});
addNew(HTML_PRE, "execute-body-cmd",
{strContent => $strCommand, bPre => true});
my $strHighLight = $self->{oManifest}->variableReplace($oExecute->fieldGet('exe-highlight', false));
my $bHighLightFound = false;
if (defined($strOutput))
{
my $strHighLight = $self->{oSite}->variableReplace($oExecute->fieldGet('exe-highlight', false));
my $bHighLightOld;
my $bHighLightFound = false;
my $strHighLightOutput;
if ($oExecute->fieldTest('exe-highlight-type', 'error'))
{
$bExeExpectedError = true;
}
foreach my $strLine (split("\n", $strOutput))
{
my $bHighLight = defined($strHighLight) && $strLine =~ /$strHighLight/;
@@ -407,13 +300,14 @@ sub sectionProcess
if (defined($bHighLightOld) && $bHighLight != $bHighLightOld)
{
$oExecuteBodyElement->
addNew(HTML_DIV, 'execute-body-output' . ($bHighLightOld ? '-highlight' : '') .
($bExeExpectedError ? '-error' : ''), {strContent => $strHighLightOutput});
addNew(HTML_PRE, 'execute-body-output' .
($bHighLightOld ? '-highlight' . ($bExeExpectedError ? '-error' : '') : ''),
{strContent => $strHighLightOutput, bPre => true});
undef($strHighLightOutput);
}
$strHighLightOutput .= "${strLine}\n";
$strHighLightOutput .= (defined($strHighLightOutput) ? "\n" : '') . $strLine;
$bHighLightOld = $bHighLight;
$bHighLightFound = $bHighLightFound ? true : $bHighLight ? true : false;
@@ -422,19 +316,18 @@ sub sectionProcess
if (defined($bHighLightOld))
{
$oExecuteBodyElement->
addNew(HTML_DIV, 'execute-body-output' . ($bHighLightOld ? '-highlight' : ''),
{strContent => $strHighLightOutput});
undef($strHighLightOutput);
}
if ($self->{bExe} && defined($strHighLight) && !$bHighLightFound)
{
confess &log(ERROR, "unable to find a match for highlight: ${strHighLight}");
addNew(HTML_PRE, 'execute-body-output' .
($bHighLightOld ? '-highlight' . ($bExeExpectedError ? '-error' : '') : ''),
{strContent => $strHighLightOutput, bPre => true});
}
$bFirst = true;
}
if ($self->{bExe} && $self->isRequired($oSection) && defined($strHighLight) && !$bHighLightFound)
{
confess &log(ERROR, "unable to find a match for highlight: ${strHighLight}");
}
}
$bFirst = false;
@@ -452,7 +345,7 @@ sub sectionProcess
{
$oSectionBodyElement->
addNew(HTML_DIV, 'section-body-text',
{strContent => $oRender->processText($oChild->textGet())});
{strContent => $self->processText($oChild->textGet())});
}
# Add option descriptive text
elsif ($oChild->nameGet() eq 'option-description')
@@ -467,17 +360,27 @@ sub sectionProcess
$oSectionBodyElement->
addNew(HTML_DIV, 'section-body-text',
{strContent => $oRender->processText($oDescription)});
{strContent => $self->processText($oDescription)});
}
# Add/remove backrest config options
elsif ($oChild->nameGet() eq 'backrest-config')
{
$oSectionBodyElement->add($self->backrestConfigProcess($oChild, $iDepth));
my $oConfigElement = $self->backrestConfigProcess($oSection, $oChild, $iDepth + 3);
if (defined($oConfigElement))
{
$oSectionBodyElement->add($oConfigElement);
}
}
# Add/remove postgres config options
elsif ($oChild->nameGet() eq 'postgres-config')
{
$oSectionBodyElement->add($self->postgresConfigProcess($oChild, $iDepth));
my $oConfigElement = $self->postgresConfigProcess($oSection, $oChild, $iDepth + 3);
if (defined($oConfigElement))
{
$oSectionBodyElement->add($oConfigElement);
}
}
# Add a subsection
elsif ($oChild->nameGet() eq 'section')
@@ -488,10 +391,10 @@ sub sectionProcess
$oSectionBodyElement->add($oChildSectionElement);
$oSectionTocElement->add($oChildSectionTocElement);
}
# Skip children that have already been processed and error on others
elsif ($oChild->nameGet() ne 'title')
# Check if the child can be processed by a parent
else
{
confess &log(ASSERT, 'unable to find child type ' . $oChild->nameGet());
$self->sectionChildProcess($oSection, $oChild, $iDepth + 1);
}
}
@@ -515,69 +418,45 @@ sub backrestConfigProcess
my
(
$strOperation,
$oSection,
$oConfig,
$iDepth
) =
logDebugParam
(
OP_DOC_HTML_PAGE_BACKREST_CONFIG_PROCESS, \@_,
{name => 'oSection'},
{name => 'oConfig'},
{name => 'iDepth'}
);
# Get filename
my $strFile = $self->{oSite}->variableReplace($oConfig->paramGet('file'));
# Generate the config
my $oConfigElement;
my ($strFile, $strConfig, $bShow) = $self->backrestConfig($oSection, $oConfig, $iDepth);
&log(INFO, (' ' x $iDepth) . 'process backrest config: ' . $strFile);
foreach my $oOption ($oConfig->nodeList('backrest-config-option'))
if ($bShow)
{
my $strSection = $oOption->fieldGet('backrest-config-option-section');
my $strKey = $oOption->fieldGet('backrest-config-option-key');
my $strValue = $self->{oSite}->variableReplace(trim($oOption->fieldGet('backrest-config-option-value'), false));
my $strHostName = $self->{oManifest}->variableReplace($oConfig->paramGet('host'));
if (!defined($strValue))
{
delete(${$self->{config}}{$strFile}{$strSection}{$strKey});
# Render the config
$oConfigElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "config");
if (keys(${$self->{config}}{$strFile}{$strSection}) == 0)
{
delete(${$self->{config}}{$strFile}{$strSection});
}
$oConfigElement->
addNew(HTML_DIV, "config-title",
{strContent => "<span class=\"host\">${strHostName}</span>:<span class=\"file\">${strFile}</span>" .
" <b>&#x21d2;</b> " . $self->processText($oConfig->nodeGet('title')->textGet())});
&log(INFO, (' ' x ($iDepth + 1)) . "reset ${strSection}->${strKey}");
}
else
{
${$self->{config}}{$strFile}{$strSection}{$strKey} = $strValue;
&log(INFO, (' ' x ($iDepth + 1)) . "set ${strSection}->${strKey} = ${strValue}");
}
my $oConfigBodyElement = $oConfigElement->addNew(HTML_DIV, "config-body");
#
# $oConfigBodyElement->
# addNew(HTML_DIV, "config-body-title",
# {strContent => "${strFile}:"});
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-output",
{strContent => $strConfig});
}
# Save the ini file
executeTest("sudo chmod 777 $strFile", {bSuppressError => true});
iniSave($strFile, $self->{config}{$strFile}, true);
# Generate config element
my $oConfigElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "config");
$oConfigElement->
addNew(HTML_DIV, "config-title",
{strContent => $self->{oRender}->processText($oConfig->nodeGet('title')->textGet()) . ':'});
my $oConfigBodyElement = $oConfigElement->addNew(HTML_DIV, "config-body");
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-title",
{strContent => "${strFile}:"});
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-output",
{strContent => fileStringRead($strFile)});
executeTest("sudo chown postgres:postgres $strFile");
executeTest("sudo chmod 640 $strFile");
# Return from function and log return values if any
return logDebugReturn
(
@@ -597,97 +476,46 @@ sub postgresConfigProcess
my
(
$strOperation,
$oSection,
$oConfig,
$iDepth
) =
logDebugParam
(
OP_DOC_HTML_PAGE_POSTGRES_CONFIG_PROCESS, \@_,
{name => 'oSection'},
{name => 'oConfig'},
{name => 'iDepth'}
);
# Get filename
my $strFile = $self->{oSite}->variableReplace($oConfig->paramGet('file'));
# Generate the config
my $oConfigElement;
my ($strFile, $strConfig, $bShow) = $self->postgresConfig($oSection, $oConfig, $iDepth);
if (!defined(${$self->{'pg-config'}}{$strFile}{base}))
if ($bShow)
{
${$self->{'pg-config'}}{$strFile}{base} = fileStringRead($strFile);
# Render the config
my $strHostName = $self->{oManifest}->variableReplace($oConfig->paramGet('host'));
$oConfigElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "config");
$oConfigElement->
addNew(HTML_DIV, "config-title",
{strContent => "<span class=\"host\">${strHostName}</span>:<span class=\"file\">${strFile}</span>" .
" <b>&#x21d2;</b> " . $self->processText($oConfig->nodeGet('title')->textGet())});
my $oConfigBodyElement = $oConfigElement->addNew(HTML_DIV, "config-body");
# $oConfigBodyElement->
# addNew(HTML_DIV, "config-body-title",
# {strContent => "append to ${strFile}:"});
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-output",
{strContent => defined($strConfig) ? $strConfig : '<No PgBackRest Settings>'});
$oConfig->fieldSet('actual-config', $strConfig);
}
my $oConfigHash = $self->{'pg-config'}{$strFile};
my $oConfigHashNew;
if (!defined($$oConfigHash{old}))
{
$oConfigHashNew = {};
$$oConfigHash{old} = {}
}
else
{
$oConfigHashNew = dclone($$oConfigHash{old});
}
&log(INFO, (' ' x $iDepth) . 'process postgres config: ' . $strFile);
foreach my $oOption ($oConfig->nodeList('postgres-config-option'))
{
my $strKey = $oOption->paramGet('key');
my $strValue = $self->{oSite}->variableReplace(trim($oOption->valueGet()));
if ($strValue eq '')
{
delete($$oConfigHashNew{$strKey});
&log(INFO, (' ' x ($iDepth + 1)) . "reset ${strKey}");
}
else
{
$$oConfigHashNew{$strKey} = $strValue;
&log(INFO, (' ' x ($iDepth + 1)) . "set ${strKey} = ${strValue}");
}
}
# Generate config text
my $strConfig;
foreach my $strKey (sort(keys(%$oConfigHashNew)))
{
if (defined($strConfig))
{
$strConfig .= "\n";
}
$strConfig .= "${strKey} = $$oConfigHashNew{$strKey}";
}
# Save the conf file
executeTest("sudo chown vagrant $strFile");
fileStringWrite($strFile, $$oConfigHash{base} .
(defined($strConfig) ? "\n# pgBackRest Configuration\n${strConfig}" : ''));
executeTest("sudo chown postgres $strFile");
# Generate config element
my $oConfigElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "config");
$oConfigElement->
addNew(HTML_DIV, "config-title",
{strContent => $self->{oRender}->processText($oConfig->nodeGet('title')->textGet()) . ':'});
my $oConfigBodyElement = $oConfigElement->addNew(HTML_DIV, "config-body");
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-title",
{strContent => "append to ${strFile}:"});
$oConfigBodyElement->
addNew(HTML_DIV, "config-body-output",
{strContent => defined($strConfig) ? $strConfig : '<No PgBackRest Settings>'});
$$oConfigHash{old} = $oConfigHashNew;
# Return from function and log return values if any
return logDebugReturn
(