mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
700 lines
24 KiB
Perl
700 lines
24 KiB
Perl
####################################################################################################################################
|
|
# DOC HTML PAGE MODULE
|
|
####################################################################################################################################
|
|
package BackRestDoc::Html::DocHtmlPage;
|
|
|
|
use strict;
|
|
use warnings FATAL => qw(all);
|
|
use Carp qw(confess);
|
|
|
|
use Data::Dumper;
|
|
use Exporter qw(import);
|
|
our @EXPORT = qw();
|
|
use File::Basename qw(dirname);
|
|
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::Html::DocHtmlBuilder;
|
|
use BackRestDoc::Html::DocHtmlElement;
|
|
|
|
####################################################################################################################################
|
|
# Operation constants
|
|
####################################################################################################################################
|
|
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';
|
|
use constant OP_DOC_HTML_PAGE_SECTION_PROCESS => OP_DOC_HTML_PAGE . '->sectionProcess';
|
|
|
|
####################################################################################################################################
|
|
# CONSTRUCTOR
|
|
####################################################################################################################################
|
|
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 $strOperation,
|
|
$self->{oSite},
|
|
$self->{strPageId},
|
|
$self->{bExe}
|
|
) =
|
|
logDebugParam
|
|
(
|
|
OP_DOC_HTML_PAGE_NEW, \@_,
|
|
{name => 'oSite'},
|
|
{name => 'strPageId'},
|
|
{name => 'bExe', default => true}
|
|
);
|
|
#
|
|
# 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};
|
|
|
|
# Return from function and log return values if any
|
|
return logDebugReturn
|
|
(
|
|
$strOperation,
|
|
{name => 'self', value => $self}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# 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
|
|
#
|
|
# Generate the site html
|
|
####################################################################################################################################
|
|
sub process
|
|
{
|
|
my $self = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my $strOperation = logDebugParam(OP_DOC_HTML_PAGE_PROCESS);
|
|
|
|
# Working variables
|
|
my $oPage = $self->{oDoc};
|
|
|
|
# Initialize page
|
|
my $strTitle = ${$self->{oRender}}{strProjectName} .
|
|
(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);
|
|
}
|
|
}
|
|
|
|
# Generate header
|
|
my $oPageHeader = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-header');
|
|
|
|
$oPageHeader->
|
|
addNew(HTML_DIV, 'page-header-title',
|
|
{strContent => $strTitle});
|
|
|
|
if (defined($strSubTitle))
|
|
{
|
|
$oPageHeader->
|
|
addNew(HTML_DIV, 'page-header-subtitle',
|
|
{strContent => $strSubTitle});
|
|
}
|
|
|
|
# Generate menu
|
|
my $oMenuBody = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-menu')->addNew(HTML_DIV, 'menu-body');
|
|
|
|
if ($self->{strPageId} ne 'index')
|
|
{
|
|
my $oPage = ${$self->{oSite}->{oSite}}{page}{'index'};
|
|
|
|
$oMenuBody->
|
|
addNew(HTML_DIV, 'menu')->
|
|
addNew(HTML_A, 'menu-link', {strContent => $$oPage{strMenuTitle}, strRef => '{[backrest-url-root]}'});
|
|
}
|
|
|
|
foreach my $strPageId(sort(keys(${$self->{oSite}->{oSite}}{page})))
|
|
{
|
|
if ($strPageId ne $self->{strPageId} && $strPageId ne 'index')
|
|
{
|
|
my $oPage = ${$self->{oSite}->{oSite}}{page}{$strPageId};
|
|
|
|
$oMenuBody->
|
|
addNew(HTML_DIV, 'menu')->
|
|
addNew(HTML_A, 'menu-link', {strContent => $$oPage{strMenuTitle}, strRef => "${strPageId}.html"});
|
|
}
|
|
}
|
|
|
|
# Generate table of contents
|
|
my $oPageTocBody;
|
|
|
|
if (!defined($oPage->paramGet('toc', false)) || $oPage->paramGet('toc') eq 'y')
|
|
{
|
|
my $oPageToc = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-toc');
|
|
|
|
$oPageToc->
|
|
addNew(HTML_DIV, 'page-toc-title',
|
|
{strContent => "Table of Contents"});
|
|
|
|
$oPageTocBody = $oPageToc->
|
|
addNew(HTML_DIV, 'page-toc-body');
|
|
}
|
|
|
|
# Generate body
|
|
my $oPageBody = $oHtmlBuilder->bodyGet()->addNew(HTML_DIV, 'page-body');
|
|
|
|
# Render sections
|
|
foreach my $oSection ($oPage->nodeList('section'))
|
|
{
|
|
my ($oChildSectionElement, $oChildSectionTocElement) =
|
|
$self->sectionProcess($oSection, undef, 1);
|
|
|
|
$oPageBody->add($oChildSectionElement);
|
|
|
|
if (defined($oPageTocBody))
|
|
{
|
|
$oPageTocBody->add($oChildSectionTocElement);
|
|
}
|
|
}
|
|
|
|
my $oPageFooter = $oHtmlBuilder->bodyGet()->
|
|
addNew(HTML_DIV, 'page-footer',
|
|
{strContent => ${$self->{oSite}->{oSite}}{common}{strFooter}});
|
|
|
|
# Return from function and log return values if any
|
|
return logDebugReturn
|
|
(
|
|
$strOperation,
|
|
{name => 'strHtml', value => $oHtmlBuilder->htmlGet(), trace => true}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# sectionProcess
|
|
####################################################################################################################################
|
|
sub sectionProcess
|
|
{
|
|
my $self = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my
|
|
(
|
|
$strOperation,
|
|
$oSection,
|
|
$strAnchor,
|
|
$iDepth
|
|
) =
|
|
logDebugParam
|
|
(
|
|
OP_DOC_HTML_PAGE_SECTION_PROCESS, \@_,
|
|
{name => 'oSection'},
|
|
{name => 'strAnchor', required => false},
|
|
{name => 'iDepth'}
|
|
);
|
|
|
|
&log(INFO, (' ' x ($iDepth - 1)) . 'process section: ' . $oSection->paramGet('id'));
|
|
|
|
if ($iDepth > 3)
|
|
{
|
|
confess &log(ASSERT, "section depth of ${iDepth} exceeds maximum");
|
|
}
|
|
|
|
# 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");
|
|
|
|
# Create the section element
|
|
my $oSectionElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "section${iDepth}");
|
|
|
|
# Add the section anchor
|
|
$oSectionElement->addNew(HTML_A, undef, {strId => $strAnchor});
|
|
|
|
# Add the section title to section and toc
|
|
my $strSectionTitle = $oRender->processText($oSection->nodeGet('title')->textGet());
|
|
|
|
$oSectionElement->
|
|
addNew(HTML_DIV, "section${iDepth}-title",
|
|
{strContent => $strSectionTitle});
|
|
|
|
my $oTocSectionTitleElement = $oSectionTocElement->
|
|
addNew(HTML_DIV, "section${iDepth}-toc-title");
|
|
|
|
$oTocSectionTitleElement->
|
|
addNew(HTML_A, undef,
|
|
{strContent => $strSectionTitle, strRef => "#${strAnchor}"});
|
|
|
|
# Add the section intro if it exists
|
|
if (defined($oSection->textGet(false)))
|
|
{
|
|
$oSectionElement->
|
|
addNew(HTML_DIV, "section-intro",
|
|
{strContent => $oRender->processText($oSection->textGet())});
|
|
}
|
|
|
|
# Add the section body
|
|
my $oSectionBodyElement = $oSectionElement->addNew(HTML_DIV, "section-body");
|
|
|
|
# Process each child
|
|
my $oSectionBodyExe;
|
|
|
|
foreach my $oChild ($oSection->nodeList())
|
|
{
|
|
&log(INFO, (' ' x $iDepth) . 'process child ' . $oChild->nameGet());
|
|
|
|
# Execute a command
|
|
if ($oChild->nameGet() eq 'execute-list')
|
|
{
|
|
my $oSectionBodyExecute = $oSectionBodyElement->addNew(HTML_DIV, "execute");
|
|
my $bFirst = true;
|
|
|
|
$oSectionBodyExecute->
|
|
addNew(HTML_DIV, "execute-title",
|
|
{strContent => $oRender->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);
|
|
|
|
if ($bExeShow)
|
|
{
|
|
$oExecuteBodyElement->
|
|
addNew(HTML_DIV, "execute-body-cmd" . ($bFirst ? '-first' : ''),
|
|
{strContent => $strCommand});
|
|
|
|
if (defined($strOutput))
|
|
{
|
|
my $strHighLight = $self->{oSite}->variableReplace($oExecute->fieldGet('exe-highlight', false));
|
|
my $bHighLightOld;
|
|
my $bHighLightFound = false;
|
|
my $strHighLightOutput;
|
|
|
|
foreach my $strLine (split("\n", $strOutput))
|
|
{
|
|
my $bHighLight = defined($strHighLight) && $strLine =~ /$strHighLight/;
|
|
|
|
if (defined($bHighLightOld) && $bHighLight != $bHighLightOld)
|
|
{
|
|
$oExecuteBodyElement->
|
|
addNew(HTML_DIV, 'execute-body-output' . ($bHighLightOld ? '-highlight' : '') .
|
|
($bExeExpectedError ? '-error' : ''), {strContent => $strHighLightOutput});
|
|
|
|
undef($strHighLightOutput);
|
|
}
|
|
|
|
$strHighLightOutput .= "${strLine}\n";
|
|
$bHighLightOld = $bHighLight;
|
|
|
|
$bHighLightFound = $bHighLightFound ? true : $bHighLight ? true : false;
|
|
}
|
|
|
|
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}");
|
|
}
|
|
|
|
$bFirst = true;
|
|
}
|
|
}
|
|
|
|
$bFirst = false;
|
|
}
|
|
}
|
|
# Add code block
|
|
elsif ($oChild->nameGet() eq 'code-block')
|
|
{
|
|
$oSectionBodyElement->
|
|
addNew(HTML_DIV, 'code-block',
|
|
{strContent => $oChild->valueGet()});
|
|
}
|
|
# Add descriptive text
|
|
elsif ($oChild->nameGet() eq 'p')
|
|
{
|
|
$oSectionBodyElement->
|
|
addNew(HTML_DIV, 'section-body-text',
|
|
{strContent => $oRender->processText($oChild->textGet())});
|
|
}
|
|
# Add option descriptive text
|
|
elsif ($oChild->nameGet() eq 'option-description')
|
|
{
|
|
my $strOption = $oChild->paramGet("key");
|
|
my $oDescription = ${$self->{oReference}->{oConfigHash}}{&CONFIG_HELP_OPTION}{$strOption}{&CONFIG_HELP_DESCRIPTION};
|
|
|
|
if (!defined($oDescription))
|
|
{
|
|
confess &log(ERROR, "unable to find ${strOption} option in sections - try adding command?");
|
|
}
|
|
|
|
$oSectionBodyElement->
|
|
addNew(HTML_DIV, 'section-body-text',
|
|
{strContent => $oRender->processText($oDescription)});
|
|
}
|
|
# Add/remove backrest config options
|
|
elsif ($oChild->nameGet() eq 'backrest-config')
|
|
{
|
|
$oSectionBodyElement->add($self->backrestConfigProcess($oChild, $iDepth));
|
|
}
|
|
# Add/remove postgres config options
|
|
elsif ($oChild->nameGet() eq 'postgres-config')
|
|
{
|
|
$oSectionBodyElement->add($self->postgresConfigProcess($oChild, $iDepth));
|
|
}
|
|
# Add a subsection
|
|
elsif ($oChild->nameGet() eq 'section')
|
|
{
|
|
my ($oChildSectionElement, $oChildSectionTocElement) =
|
|
$self->sectionProcess($oChild, $strAnchor, $iDepth + 1);
|
|
|
|
$oSectionBodyElement->add($oChildSectionElement);
|
|
$oSectionTocElement->add($oChildSectionTocElement);
|
|
}
|
|
# Skip children that have already been processed and error on others
|
|
elsif ($oChild->nameGet() ne 'title')
|
|
{
|
|
confess &log(ASSERT, 'unable to find child type ' . $oChild->nameGet());
|
|
}
|
|
}
|
|
|
|
# Return from function and log return values if any
|
|
return logDebugReturn
|
|
(
|
|
$strOperation,
|
|
{name => 'oSectionElement', value => $oSectionElement, trace => true},
|
|
{name => 'oSectionTocElement', value => $oSectionTocElement, trace => true}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# backrestConfigProcess
|
|
####################################################################################################################################
|
|
sub backrestConfigProcess
|
|
{
|
|
my $self = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my
|
|
(
|
|
$strOperation,
|
|
$oConfig,
|
|
$iDepth
|
|
) =
|
|
logDebugParam
|
|
(
|
|
OP_DOC_HTML_PAGE_BACKREST_CONFIG_PROCESS, \@_,
|
|
{name => 'oConfig'},
|
|
{name => 'iDepth'}
|
|
);
|
|
|
|
# Get filename
|
|
my $strFile = $self->{oSite}->variableReplace($oConfig->paramGet('file'));
|
|
|
|
&log(INFO, (' ' x $iDepth) . 'process backrest config: ' . $strFile);
|
|
|
|
foreach my $oOption ($oConfig->nodeList('backrest-config-option'))
|
|
{
|
|
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));
|
|
|
|
if (!defined($strValue))
|
|
{
|
|
delete(${$self->{config}}{$strFile}{$strSection}{$strKey});
|
|
|
|
if (keys(${$self->{config}}{$strFile}{$strSection}) == 0)
|
|
{
|
|
delete(${$self->{config}}{$strFile}{$strSection});
|
|
}
|
|
|
|
&log(INFO, (' ' x ($iDepth + 1)) . "reset ${strSection}->${strKey}");
|
|
}
|
|
else
|
|
{
|
|
${$self->{config}}{$strFile}{$strSection}{$strKey} = $strValue;
|
|
&log(INFO, (' ' x ($iDepth + 1)) . "set ${strSection}->${strKey} = ${strValue}");
|
|
}
|
|
}
|
|
|
|
# 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
|
|
(
|
|
$strOperation,
|
|
{name => 'oConfigElement', value => $oConfigElement, trace => true}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# postgresConfigProcess
|
|
####################################################################################################################################
|
|
sub postgresConfigProcess
|
|
{
|
|
my $self = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my
|
|
(
|
|
$strOperation,
|
|
$oConfig,
|
|
$iDepth
|
|
) =
|
|
logDebugParam
|
|
(
|
|
OP_DOC_HTML_PAGE_POSTGRES_CONFIG_PROCESS, \@_,
|
|
{name => 'oConfig'},
|
|
{name => 'iDepth'}
|
|
);
|
|
|
|
# Get filename
|
|
my $strFile = $self->{oSite}->variableReplace($oConfig->paramGet('file'));
|
|
|
|
if (!defined(${$self->{'pg-config'}}{$strFile}{base}))
|
|
{
|
|
${$self->{'pg-config'}}{$strFile}{base} = fileStringRead($strFile);
|
|
}
|
|
|
|
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
|
|
(
|
|
$strOperation,
|
|
{name => 'oConfigElement', value => $oConfigElement, trace => true}
|
|
);
|
|
}
|
|
|
|
1;
|