1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-08-24 17:47:38 +03:00

Added execution cache for document generation.

Added an execution cache so that documentation can be generated without setting up the full container environment. This is useful for packaging, keeps the documentation consistent for a release, and speeds up generation when no changes are made in the execution list.
This commit is contained in:
David Steele
2016-06-02 09:32:56 -04:00
parent df6086bd24
commit eaa981c5aa
15 changed files with 1017 additions and 347 deletions

View File

@@ -19,6 +19,7 @@ use pgBackRest::Common::Log;
use pgBackRest::Common::String;
use pgBackRest::Config::Config;
use pgBackRest::FileCommon;
use pgBackRest::Version;
use lib dirname($0) . '/../test/lib';
use pgBackRestTest::Common::ExecuteTest;
@@ -55,6 +56,16 @@ sub new
my $self = $class->SUPER::new($strType, $oManifest, $strRenderOutKey);
bless $self, $class;
if (defined($self->{oSource}{hyCache}))
{
$self->{bCache} = true;
$self->{iCacheIdx} = 0;
}
else
{
$self->{bCache} = false;
}
$self->{bExe} = $bExe;
# Return from function and log return values if any
@@ -65,6 +76,75 @@ sub new
);
}
####################################################################################################################################
# executeKey
#
# Get a unique key for the execution step to determine if the cache is valid.
####################################################################################################################################
sub executeKey
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$strHostName,
$oCommand,
) =
logDebugParam
(
__PACKAGE__ . '->executeKey', \@_,
{name => 'strHostName', trace => true},
{name => 'oCommand', trace => true},
);
# Add user to command
my $strCommand = $self->{oManifest}->variableReplace(trim($oCommand->fieldGet('exe-cmd')));
my $strUser = $self->{oManifest}->variableReplace($oCommand->paramGet('user', false, 'postgres'));
$strCommand = ($strUser eq 'vagrant' ? '' : ('sudo ' . ($strUser eq 'root' ? '' : "-u $strUser "))) . $strCommand;
# Format and split command
$strCommand =~ s/[ ]*\n[ ]*/ \\\n /smg;
my @stryCommand = split("\n", $strCommand);
my $hCacheKey =
{
host => $strHostName,
cmd => \@stryCommand,
output => JSON::PP::false,
};
if (defined($oCommand->paramGet('err-expect', false)))
{
$$hCacheKey{'err-expect'} = $oCommand->paramGet('err-expect');
}
if ($oCommand->paramTest('output', 'y') || $oCommand->paramTest('show', 'y') || $oCommand->paramTest('variable-key'))
{
$$hCacheKey{'output'} = JSON::PP::true;
}
if (defined($oCommand->fieldGet('exe-highlight', false)))
{
$$hCacheKey{'output'} = JSON::PP::true;
$$hCacheKey{highlight}{'filter'} = $oCommand->paramTest('filter', 'n') ? JSON::PP::false : JSON::PP::true;
$$hCacheKey{highlight}{'filter-context'} = $oCommand->paramGet('filter-context', false, 2);
my @stryHighlight;
$stryHighlight[0] = $self->{oManifest}->variableReplace($oCommand->fieldGet('exe-highlight'));
$$hCacheKey{highlight}{list} = \@stryHighlight;
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'hExecuteKey', value => $hCacheKey, trace => true}
);
}
####################################################################################################################################
# execute
####################################################################################################################################
@@ -79,7 +159,8 @@ sub execute
$oSection,
$strHostName,
$oCommand,
$iIndent
$iIndent,
$bCache,
) =
logDebugParam
(
@@ -87,51 +168,40 @@ sub execute
{name => 'oSection'},
{name => 'strHostName'},
{name => 'oCommand'},
{name => 'iIndent', default => 1}
{name => 'iIndent', default => 1},
{name => 'bCache', default => true},
);
# Working variables
my $strCommand;
my $hCacheKey = $self->executeKey($strHostName, $oCommand);
my $strCommand = join("\n", @{$$hCacheKey{cmd}});
my $strOutput;
if ($oCommand->fieldTest('actual-command'))
if (!$oCommand->paramTest('show', 'n') && $self->{bExe} && $self->isRequired($oSection))
{
$strCommand = $oCommand->fieldGet('actual-command');
$strOutput = $oCommand->fieldGet('actual-output', false);
}
else
{
# Command variables
$strCommand = trim($oCommand->fieldGet('exe-cmd'));
my $strUser = $self->{oManifest}->variableReplace($oCommand->paramGet('user', false, 'postgres'));
my $bExeOutput = $oCommand->paramTest('output', 'y');
my $strVariableKey = $oCommand->paramGet('variable-key', false);
my $iExeExpectedError = $oCommand->paramGet('err-expect', false);
$strCommand = $self->{oManifest}->variableReplace(
($strUser eq 'vagrant' ? '' :
('sudo ' . ($strUser eq 'root' ? '' : "-u ${strUser} "))) . $strCommand);
# Add continuation chars and proper spacing
$strCommand =~ s/[ ]*\n[ ]*/ \\\n /smg;
if (!$oCommand->paramTest('show', 'n') && $self->{bExe} && $self->isRequired($oSection))
# Make sure that no lines are greater than 80 chars
foreach my $strLine (split("\n", $strCommand))
{
# Make sure that no lines are greater than 80 chars
foreach my $strLine (split("\n", $strCommand))
if (length(trim($strLine)) > 80)
{
if (length(trim($strLine)) > 80)
{
confess &log(ERROR, "command has a line > 80 characters:\n${strCommand}\noffending line: ${strLine}");
}
confess &log(ERROR, "command has a line > 80 characters:\n${strCommand}\noffending line: ${strLine}");
}
}
}
&log(DEBUG, (' ' x $iIndent) . "execute: $strCommand");
&log(DEBUG, (' ' x $iIndent) . "execute: $strCommand");
if (!$oCommand->paramTest('skip', 'y'))
if (!$oCommand->paramTest('skip', 'y'))
{
if ($self->{bExe} && $self->isRequired($oSection))
{
if ($self->{bExe} && $self->isRequired($oSection))
my ($bCacheHit, $strCacheType, $hCacheKey, $hCacheValue) = $self->cachePop('exe', $hCacheKey);
if ($bCacheHit)
{
$strOutput = defined($$hCacheValue{output}) ? join("\n", @{$$hCacheValue{output}}) : undef;
}
else
{
# Check that the host is valid
my $oHost = $self->{host}{$strHostName};
@@ -142,13 +212,13 @@ sub execute
}
my $oExec = $oHost->execute($strCommand,
{iExpectedExitStatus => $iExeExpectedError,
{iExpectedExitStatus => $$hCacheKey{'err-expect'},
bSuppressError => $oCommand->paramTest('err-suppress', 'y'),
iRetrySeconds => $oCommand->paramGet('retry', false)});
$oExec->begin();
$oExec->end();
if ($bExeOutput && defined($oExec->{strOutLog}) && $oExec->{strOutLog} ne '')
if (defined($oExec->{strOutLog}) && $oExec->{strOutLog} ne '')
{
$strOutput = $oExec->{strOutLog};
@@ -160,28 +230,36 @@ sub execute
$strOutput =~ s/^ //smg;
$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;
}
# my @stryOutput = split("\n", $strOutput);
# $$hCacheValue{stdout} = \@stryOutput;
}
if (defined($iExeExpectedError))
if (defined($$hCacheKey{'err-expect'}) && defined($oExec->{strErrorLog}) && $oExec->{strErrorLog} ne '')
{
$strOutput .= trim($oExec->{strErrorLog});
# my $strError = $oExec->{strErrorLog};
# $strError =~ s/^\n+|\n$//g;
# my @stryError = split("\n", $strError);
# $$hCacheValue{stderr} = \@stryError;
$strOutput .= $oExec->{strErrorLog};
}
# Output is assigned to a var
if (defined($strVariableKey))
# if (defined($$hCacheValue{stderr}))
# {
# $strOutput .= join("\n", @{$$hCacheValue{stderr}});
# }
if ($$hCacheKey{output} && defined($$hCacheKey{highlight}) && $$hCacheKey{highlight}{filter} && defined($strOutput))
{
$self->{oManifest}->variableSet($strVariableKey, trim($oExec->{strOutLog}));
}
elsif (!$oCommand->paramTest('filter', 'n') && $bExeOutput && defined($strOutput))
{
my $strHighLight = $self->{oManifest}->variableReplace($oCommand->fieldGet('exe-highlight', false));
my $strHighLight = @{$$hCacheKey{highlight}{list}}[0];
if (!defined($strHighLight))
{
confess &log(ERROR, 'filter requires highlight definition: ' . $strCommand);
}
my $iFilterContext = $oCommand->paramGet('filter-context', false, 2);
my $iFilterContext = $$hCacheKey{highlight}{'filter-context'};
my @stryOutput = split("\n", $strOutput);
undef($strOutput);
@@ -248,20 +326,40 @@ sub execute
}
}
}
if (!$$hCacheKey{output})
{
$strOutput = undef;
}
if (defined($strOutput))
{
my @stryOutput = split("\n", $strOutput);
$$hCacheValue{output} = \@stryOutput;
}
if ($bCache)
{
$self->cachePush($strCacheType, $hCacheKey, $hCacheValue);
}
}
elsif ($bExeOutput)
# Output is assigned to a var
if ($oCommand->paramTest('variable-key'))
{
$strOutput = 'Output suppressed for testing';
$self->{oManifest}->variableSet($oCommand->paramGet('variable-key'), trim($strOutput), true);
}
}
if (defined($strVariableKey) && !defined($self->{oManifest}->variableGet($strVariableKey)))
elsif ($$hCacheKey{output})
{
$self->{oManifest}->variableSet($strVariableKey, '[Test Variable]');
$strOutput = 'Output suppressed for testing';
}
}
$oCommand->fieldSet('actual-command', $strCommand);
$oCommand->fieldSet('actual-output', $strOutput);
# Default variable output when it was not set by execution
if ($oCommand->paramTest('variable-key') && !defined($self->{oManifest}->variableGet($oCommand->paramGet('variable-key'))))
{
$self->{oManifest}->variableSet($oCommand->paramGet('variable-key'), '[Test Variable]', true);
}
# Return from function and log return values if any
@@ -273,6 +371,76 @@ sub execute
);
}
####################################################################################################################################
# configKey
####################################################################################################################################
sub configKey
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$oConfig,
) =
logDebugParam
(
__PACKAGE__ . '->hostKey', \@_,
{name => 'oConfig', trace => true},
);
my $hCacheKey =
{
host => $self->{oManifest}->variableReplace($oConfig->paramGet('host')),
file => $self->{oManifest}->variableReplace($oConfig->paramGet('file')),
};
if ($oConfig->paramTest('reset', 'y'))
{
$$hCacheKey{reset} = JSON::PP::true;
}
# Add all options to the key
my $strOptionTag = $oConfig->nameGet() eq 'backrest-config' ? 'backrest-config-option' : 'postgres-config-option';
foreach my $oOption ($oConfig->nodeList($strOptionTag))
{
my $hOption = {};
if ($oOption->paramTest('remove', 'y'))
{
$$hOption{remove} = JSON::PP::true;
}
if (defined($oOption->valueGet(false)))
{
$$hOption{value} = $self->{oManifest}->variableReplace($oOption->valueGet());
}
my $strKey = $self->{oManifest}->variableReplace($oOption->paramGet('key'));
if ($oConfig->nameGet() eq 'backrest-config')
{
my $strSection = $self->{oManifest}->variableReplace($oOption->paramGet('section'));
$$hCacheKey{option}{$strSection}{$strKey} = $hOption;
}
else
{
$$hCacheKey{option}{$strKey} = $hOption;
}
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'hCacheKey', value => $hCacheKey, trace => true}
);
}
####################################################################################################################################
# backrestConfig
####################################################################################################################################
@@ -297,22 +465,21 @@ sub backrestConfig
);
# Working variables
my $strFile;
my $strConfig;
my $hCacheKey = $self->configKey($oConfig);
my $strFile = $$hCacheKey{file};
my $strConfig = undef;
if ($oConfig->fieldTest('actual-file'))
&log(DEBUG, (' ' x $iDepth) . 'process backrest config: ' . $$hCacheKey{file});
if ($self->{bExe} && $self->isRequired($oSection))
{
$strFile = $oConfig->fieldGet('actual-file');
$strConfig = $oConfig->fieldGet('actual-config');
}
else
{
# Get filename
$strFile = $self->{oManifest}->variableReplace($oConfig->paramGet('file'));
my ($bCacheHit, $strCacheType, $hCacheKey, $hCacheValue) = $self->cachePop('cfg-' . BACKREST_EXE, $hCacheKey);
&log(DEBUG, (' ' x $iDepth) . 'process backrest config: ' . $strFile);
if ($self->{bExe} && $self->isRequired($oSection))
if ($bCacheHit)
{
$strConfig = defined($$hCacheValue{config}) ? join("\n", @{$$hCacheValue{config}}) : undef;
}
else
{
# Check that the host is valid
my $strHostName = $self->{oManifest}->variableReplace($oConfig->paramGet('host'));
@@ -326,7 +493,7 @@ sub backrestConfig
# Reset all options
if ($oConfig->paramTest('reset', 'y'))
{
delete(${$self->{config}}{$strHostName}{$strFile})
delete(${$self->{config}}{$strHostName}{$$hCacheKey{file}})
}
foreach my $oOption ($oConfig->nodeList('backrest-config-option'))
@@ -342,11 +509,11 @@ sub backrestConfig
if (!defined($strValue))
{
delete(${$self->{config}}{$strHostName}{$strFile}{$strSection}{$strKey});
delete(${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey});
if (keys(%{${$self->{config}}{$strHostName}{$strFile}{$strSection}}) == 0)
if (keys(%{${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}}) == 0)
{
delete(${$self->{config}}{$strHostName}{$strFile}{$strSection});
delete(${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection});
}
&log(DEBUG, (' ' x ($iDepth + 1)) . "reset ${strSection}->${strKey}");
@@ -364,10 +531,10 @@ sub backrestConfig
# If this option is a hash and the value is already set then append to the array
if ($$oOption{$strKey}{&OPTION_RULE_TYPE} eq OPTION_TYPE_HASH &&
defined(${$self->{config}}{$strHostName}{$strFile}{$strSection}{$strKey}))
defined(${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey}))
{
my @oValue = ();
my $strHashValue = ${$self->{config}}{$strHostName}{$strFile}{$strSection}{$strKey};
my $strHashValue = ${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey};
# If there is only one key/value
if (ref(\$strHashValue) eq 'SCALAR')
@@ -381,12 +548,12 @@ sub backrestConfig
}
push(@oValue, $strValue);
${$self->{config}}{$strHostName}{$strFile}{$strSection}{$strKey} = \@oValue;
${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey} = \@oValue;
}
# else just set the value
else
{
${$self->{config}}{$strHostName}{$strFile}{$strSection}{$strKey} = $strValue;
${$self->{config}}{$strHostName}{$$hCacheKey{file}}{$strSection}{$strKey} = $strValue;
}
&log(DEBUG, (' ' x ($iDepth + 1)) . "set ${strSection}->${strKey} = ${strValue}");
@@ -396,19 +563,25 @@ sub backrestConfig
my $strLocalFile = "/home/vagrant/data/db-master/etc/pgbackrest.conf";
# Save the ini file
iniSave($strLocalFile, $self->{config}{$strHostName}{$strFile}, true);
iniSave($strLocalFile, $self->{config}{$strHostName}{$$hCacheKey{file}}, true);
$strConfig = fileStringRead($strLocalFile);
$oHost->copyTo($strLocalFile, $$hCacheKey{file}, $oConfig->paramGet('owner', false, 'postgres:postgres'), '640');
$oHost->copyTo($strLocalFile, $strFile, $oConfig->paramGet('owner', false, 'postgres:postgres'), '640');
my $strConfig = fileStringRead($strLocalFile);
my @stryConfig = undef;
if (trim($strConfig) ne '')
{
@stryConfig = split("\n", $strConfig);
}
$$hCacheValue{config} = \@stryConfig;
$self->cachePush($strCacheType, $hCacheKey, $hCacheValue);
}
else
{
$strConfig = 'Config suppressed for testing';
}
$oConfig->fieldSet('actual-file', $strFile);
$oConfig->fieldSet('actual-config', $strConfig);
}
else
{
$strConfig = 'Config suppressed for testing';
}
# Return from function and log return values if any
@@ -445,20 +618,19 @@ sub postgresConfig
);
# Working variables
my $strFile;
my $hCacheKey = $self->configKey($oConfig);
my $strFile = $$hCacheKey{file};
my $strConfig;
if ($oConfig->fieldTest('actual-file'))
if ($self->{bExe} && $self->isRequired($oSection))
{
$strFile = $oConfig->fieldGet('actual-file');
$strConfig = $oConfig->fieldGet('actual-config');
}
else
{
# Get filename
$strFile = $self->{oManifest}->variableReplace($oConfig->paramGet('file'));
my ($bCacheHit, $strCacheType, $hCacheKey, $hCacheValue) = $self->cachePop('cfg-postgresql', $hCacheKey);
if ($self->{bExe} && $self->isRequired($oSection))
if ($bCacheHit)
{
$strConfig = defined($$hCacheValue{config}) ? join("\n", @{$$hCacheValue{config}}) : undef;
}
else
{
# Check that the host is valid
my $strHostName = $self->{oManifest}->variableReplace($oConfig->paramGet('host'));
@@ -470,14 +642,14 @@ sub postgresConfig
}
my $strLocalFile = '/home/vagrant/data/db-master/etc/postgresql.conf';
$oHost->copyFrom($strFile, $strLocalFile);
$oHost->copyFrom($$hCacheKey{file}, $strLocalFile);
if (!defined(${$self->{'pg-config'}}{$strHostName}{$strFile}{base}) && $self->{bExe})
if (!defined(${$self->{'pg-config'}}{$strHostName}{$$hCacheKey{file}}{base}) && $self->{bExe})
{
${$self->{'pg-config'}}{$strHostName}{$strFile}{base} = fileStringRead($strLocalFile);
${$self->{'pg-config'}}{$strHostName}{$$hCacheKey{file}}{base} = fileStringRead($strLocalFile);
}
my $oConfigHash = $self->{'pg-config'}{$strHostName}{$strFile};
my $oConfigHash = $self->{'pg-config'}{$strHostName}{$$hCacheKey{file}};
my $oConfigHashNew;
if (!defined($$oConfigHash{old}))
@@ -490,7 +662,7 @@ sub postgresConfig
$oConfigHashNew = dclone($$oConfigHash{old});
}
&log(DEBUG, (' ' x $iDepth) . 'process postgres config: ' . $strFile);
&log(DEBUG, (' ' x $iDepth) . 'process postgres config: ' . $$hCacheKey{file});
foreach my $oOption ($oConfig->nodeList('postgres-config-option'))
{
@@ -527,18 +699,25 @@ sub postgresConfig
fileStringWrite($strLocalFile, $$oConfigHash{base} .
(defined($strConfig) ? "\n# pgBackRest Configuration\n${strConfig}\n" : ''));
$oHost->copyTo($strLocalFile, $strFile, 'postgres:postgres', '640');
$oHost->copyTo($strLocalFile, $$hCacheKey{file}, 'postgres:postgres', '640');
}
$$oConfigHash{old} = $oConfigHashNew;
}
else
{
$strConfig = 'Config suppressed for testing';
}
$oConfig->fieldSet('actual-file', $strFile);
$oConfig->fieldSet('actual-config', $strConfig);
my @stryConfig = undef;
if (trim($strConfig) ne '')
{
@stryConfig = split("\n", $strConfig);
}
$$hCacheValue{config} = \@stryConfig;
$self->cachePush($strCacheType, $hCacheKey, $hCacheValue);
}
}
else
{
$strConfig = 'Config suppressed for testing';
}
# Return from function and log return values if any
@@ -551,6 +730,178 @@ sub postgresConfig
);
}
####################################################################################################################################
# hostKey
####################################################################################################################################
sub hostKey
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$oHost,
) =
logDebugParam
(
__PACKAGE__ . '->hostKey', \@_,
{name => 'oHost', trace => true},
);
my $hCacheKey =
{
name => $self->{oManifest}->variableReplace($oHost->paramGet('name')),
user => $self->{oManifest}->variableReplace($oHost->paramGet('user')),
image => $self->{oManifest}->variableReplace($oHost->paramGet('image')),
};
if (defined($oHost->paramGet('os', false)))
{
$$hCacheKey{os} = $self->{oManifest}->variableReplace($oHost->paramGet('os'));
}
if (defined($oHost->paramGet('mount', false)))
{
$$hCacheKey{mount} = $self->{oManifest}->variableReplace($oHost->paramGet('mount'));
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'hCacheKey', value => $hCacheKey, trace => true}
);
}
####################################################################################################################################
# cachePop
####################################################################################################################################
sub cachePop
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$strCacheType,
$hCacheKey,
) =
logDebugParam
(
__PACKAGE__ . '->hostKey', \@_,
{name => 'strCacheType', trace => true},
{name => 'hCacheKey', trace => true},
);
my $bCacheHit = false;
my $oCacheValue = undef;
if ($self->{bCache})
{
my $oJSON = JSON::PP->new()->canonical()->allow_nonref();
# &log(WARN, "checking cache for\ncurrent key: " . $oJSON->encode($hCacheKey));
my $hCache = ${$self->{oSource}{hyCache}}[$self->{iCacheIdx}];
if (!defined($hCache))
{
confess &log(ERROR, 'unable to get index from cache', -1);
}
if (!defined($$hCache{key}))
{
confess &log(ERROR, 'unable to get key from cache', -1);
}
if (!defined($$hCache{type}))
{
confess &log(ERROR, 'unable to get type from cache', -1);
}
if ($$hCache{type} ne $strCacheType)
{
confess &log(ERROR, 'types do not match, cache is invalid', -1);
}
if ($oJSON->encode($$hCache{key}) ne $oJSON->encode($hCacheKey))
{
confess &log(ERROR,
"keys at index $self->{iCacheIdx} do not match, cache is invalid." .
"\ncache key: " . $oJSON->encode($$hCache{key}) .
"\ncurrent key: " . $oJSON->encode($hCacheKey), -1);
}
$bCacheHit = true;
$oCacheValue = $$hCache{value};
$self->{iCacheIdx}++;
}
else
{
if ($self->{oManifest}{bCacheOnly})
{
confess &log(ERROR, 'Cache only operation forced by --cache-only option');
}
}
# Return from function and log return values if any
return logDebugReturn
(
$strOperation,
{name => 'bCacheHit', value => $bCacheHit, trace => true},
{name => 'strCacheType', value => $strCacheType, trace => true},
{name => 'hCacheKey', value => $hCacheKey, trace => true},
{name => 'oCacheValue', value => $oCacheValue, trace => true},
);
}
####################################################################################################################################
# cachePush
####################################################################################################################################
sub cachePush
{
my $self = shift;
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$strType,
$hCacheKey,
$oCacheValue,
) =
logDebugParam
(
__PACKAGE__ . '->hostKey', \@_,
{name => 'strType', trace => true},
{name => 'hCacheKey', trace => true},
{name => 'oCacheValue', required => false, trace => true},
);
if ($self->{bCache})
{
confess &log(ASSERT, "cachePush should not be called when cache is already present");
}
# Create the cache entry
my $hCache =
{
key => $hCacheKey,
type => $strType,
};
if (defined($oCacheValue))
{
$$hCache{value} = $oCacheValue;
}
push @{$self->{oSource}{hyCache}}, $hCache;
# Return from function and log return values if any
return logDebugReturn($strOperation);
}
####################################################################################################################################
# sectionChildProcesss
####################################################################################################################################
@@ -579,55 +930,62 @@ sub sectionChildProcess
# Execute a command
if ($oChild->nameGet() eq 'host-add')
{
if ($self->{bExe} && $self->isRequired($oSection) && !$oChild->paramTest('created', true))
if ($self->{bExe} && $self->isRequired($oSection))
{
my $strName = $self->{oManifest}->variableReplace($oChild->paramGet('name'));
my $strUser = $self->{oManifest}->variableReplace($oChild->paramGet('user'));
my $strImage = $self->{oManifest}->variableReplace($oChild->paramGet('image'));
my $strOS = $self->{oManifest}->variableReplace($oChild->paramGet('os', false));
my $strMount = $self->{oManifest}->variableReplace($oChild->paramGet('mount', false));
my ($bCacheHit, $strCacheType, $hCacheKey, $hCacheValue) = $self->cachePop('host', $self->hostKey($oChild));
if (defined($self->{host}{$strName}))
if ($bCacheHit)
{
confess &log(ERROR, 'cannot add host ${strName} because the host already exists');
$self->{oManifest}->variableSet("host-$$hCacheKey{name}-ip", $$hCacheValue{ip}, true);
}
my $oHost = new pgBackRestTest::Common::HostTest($strName, $strImage, $strUser, $strOS, $strMount);
$self->{host}{$strName} = $oHost;
$self->{oManifest}->variableSet("host-${strName}-ip", $oHost->{strIP});
# Execute cleanup commands
foreach my $oExecute ($oChild->nodeList('execute'))
else
{
$self->execute($oSection, $strName, $oExecute, $iDepth + 1);
}
$oHost->executeSimple("sh -c 'echo \"\" >> /etc/hosts\'", undef, 'root');
$oHost->executeSimple("sh -c 'echo \"# Test Hosts\" >> /etc/hosts'", undef, 'root');
# Add all other host IPs to this host
foreach my $strOtherHostName (sort(keys(%{$self->{host}})))
{
if ($strOtherHostName ne $strName)
if (defined($self->{host}{$$hCacheKey{name}}))
{
my $oOtherHost = $self->{host}{$strOtherHostName};
$oHost->executeSimple("sh -c 'echo \"$oOtherHost->{strIP} ${strOtherHostName}\" >> /etc/hosts'", undef, 'root');
confess &log(ERROR, 'cannot add host ${strName} because the host already exists');
}
}
# Add this host IP to all other hosts
foreach my $strOtherHostName (sort(keys(%{$self->{host}})))
{
if ($strOtherHostName ne $strName)
my $oHost =
new pgBackRestTest::Common::HostTest(
$$hCacheKey{name}, $$hCacheKey{image}, $$hCacheKey{user}, $$hCacheKey{os}, $$hCacheKey{mount});
$self->{host}{$$hCacheKey{name}} = $oHost;
$self->{oManifest}->variableSet("host-$$hCacheKey{name}-ip", $oHost->{strIP}, true);
$$hCacheValue{ip} = $oHost->{strIP};
# Execute cleanup commands
foreach my $oExecute ($oChild->nodeList('execute'))
{
my $oOtherHost = $self->{host}{$strOtherHostName};
$oOtherHost->executeSimple("sh -c 'echo \"$oHost->{strIP} ${strName}\" >> /etc/hosts'", undef, 'root');
$self->execute($oSection, $$hCacheKey{name}, $oExecute, $iDepth + 1, false);
}
}
$oChild->paramSet('created', true);
$oHost->executeSimple("sh -c 'echo \"\" >> /etc/hosts\'", undef, 'root');
$oHost->executeSimple("sh -c 'echo \"# Test Hosts\" >> /etc/hosts'", undef, 'root');
# Add all other host IPs to this host
foreach my $strOtherHostName (sort(keys(%{$self->{host}})))
{
if ($strOtherHostName ne $$hCacheKey{name})
{
my $oOtherHost = $self->{host}{$strOtherHostName};
$oHost->executeSimple("sh -c 'echo \"$oOtherHost->{strIP} ${strOtherHostName}\" >> /etc/hosts'", undef, 'root');
}
}
# Add this host IP to all other hosts
foreach my $strOtherHostName (sort(keys(%{$self->{host}})))
{
if ($strOtherHostName ne $$hCacheKey{name})
{
my $oOtherHost = $self->{host}{$strOtherHostName};
$oOtherHost->executeSimple("sh -c 'echo \"$oHost->{strIP} $$hCacheKey{name}\" >> /etc/hosts'", undef, 'root');
}
}
$self->cachePush($strCacheType, $hCacheKey, $hCacheValue);
}
}
}
# Skip children that have already been processed and error on others