Changed how variables work again
Script variables are not longer saved before entering a block. Only variables declared as locals and loop variables are saved. This allows a block to use `set_var` to change a variable.
This commit is contained in:
parent
46e675dedb
commit
0519be9316
1 changed files with 43 additions and 32 deletions
|
@ -111,31 +111,45 @@ INSTR_FIELDS = {k: set(v + INSTR_COMMON_FIELDS) for k, v in INSTR_OWN_FIELDS.ite
|
||||||
class VariableStorage(MutableMapping):
|
class VariableStorage(MutableMapping):
|
||||||
def __init__(self, host_vars):
|
def __init__(self, host_vars):
|
||||||
self._host_vars = host_vars
|
self._host_vars = host_vars
|
||||||
self._script_stack = [{}]
|
self._script_vars = {}
|
||||||
|
self._script_stack = []
|
||||||
self._cache = host_vars.copy()
|
self._cache = host_vars.copy()
|
||||||
|
|
||||||
def _script_stack_push(self):
|
def _script_stack_push(self, variables):
|
||||||
self._script_stack.append(self._script_stack[-1].copy())
|
data = {}
|
||||||
|
for v in variables:
|
||||||
|
if v in self._script_vars:
|
||||||
|
se = (True, self._script_vars[v])
|
||||||
|
else:
|
||||||
|
se = (False, None)
|
||||||
|
data[v] = se
|
||||||
|
self._script_stack.append(data)
|
||||||
|
|
||||||
def _script_stack_pop(self):
|
def _script_stack_pop(self):
|
||||||
self._script_stack.pop()
|
restore = self._script_stack.pop()
|
||||||
|
for vn, vv in restore.items():
|
||||||
|
existed, value = vv
|
||||||
|
if existed:
|
||||||
|
self._script_vars[vn] = value
|
||||||
|
elif vn in self._script_vars:
|
||||||
|
del self._script_vars[vn]
|
||||||
self._cache = self._host_vars.copy()
|
self._cache = self._host_vars.copy()
|
||||||
self._cache.update(self._script_stack[-1])
|
self._cache.update(self._script_vars)
|
||||||
|
|
||||||
def _set_host_var(self, name, value):
|
def _set_host_var(self, name, value):
|
||||||
self._host_vars[name] = value
|
self._host_vars[name] = value
|
||||||
if name not in self._script_stack[-1]:
|
if name not in self._script_vars:
|
||||||
self._cache[name] = value
|
self._cache[name] = value
|
||||||
|
|
||||||
def __getitem__(self, k):
|
def __getitem__(self, k):
|
||||||
return self._cache[k]
|
return self._cache[k]
|
||||||
|
|
||||||
def __setitem__(self, k, v):
|
def __setitem__(self, k, v):
|
||||||
self._script_stack[-1][k] = v
|
self._script_vars[k] = v
|
||||||
self._cache[k] = v
|
self._cache[k] = v
|
||||||
|
|
||||||
def __delitem__(self, k):
|
def __delitem__(self, k):
|
||||||
del self._script_stack[-1][k]
|
del self._script_vars[k]
|
||||||
if k in self._host_vars:
|
if k in self._host_vars:
|
||||||
self._cache[k] = self._host_vars[k]
|
self._cache[k] = self._host_vars[k]
|
||||||
else:
|
else:
|
||||||
|
@ -339,9 +353,7 @@ class RcInstruction(abc.ABC):
|
||||||
self._display.vvvv("%s : running action %s" % (host_name, self._action))
|
self._display.vvvv("%s : running action %s" % (host_name, self._action))
|
||||||
return self.run_once(host_name, variables)
|
return self.run_once(host_name, variables)
|
||||||
# Save previous loop variable state
|
# Save previous loop variable state
|
||||||
had_loop_var = self._loop_var in variables
|
variables._script_stack_push([self._loop_var])
|
||||||
if had_loop_var:
|
|
||||||
old_loop_var = variables[self._loop_var]
|
|
||||||
try:
|
try:
|
||||||
# Loop over all values
|
# Loop over all values
|
||||||
for value in self.evaluate_loop(host_name, variables):
|
for value in self.evaluate_loop(host_name, variables):
|
||||||
|
@ -355,10 +367,7 @@ class RcInstruction(abc.ABC):
|
||||||
return True
|
return True
|
||||||
finally:
|
finally:
|
||||||
# Restore loop variable state
|
# Restore loop variable state
|
||||||
if had_loop_var:
|
variables._script_stack_pop()
|
||||||
variables[self._loop_var] = old_loop_var
|
|
||||||
else:
|
|
||||||
del variables[self._loop_var]
|
|
||||||
|
|
||||||
def run_once(self, host_name, variables):
|
def run_once(self, host_name, variables):
|
||||||
"""Check the condition if it exists, then run the instruction.
|
"""Check the condition if it exists, then run the instruction.
|
||||||
|
@ -795,26 +804,28 @@ class RciBlock(RcInstruction):
|
||||||
or self._always is None
|
or self._always is None
|
||||||
or self._locals is None
|
or self._locals is None
|
||||||
)
|
)
|
||||||
variables._script_stack_push()
|
variables._script_stack_push(self._locals.keys())
|
||||||
self._templar.available_variables = variables
|
|
||||||
for key, value in self._locals.items():
|
|
||||||
result = self._templar.template(value)
|
|
||||||
variables[key] = result
|
|
||||||
self._display.vvv("- set block-local %s to %s" % (key, result))
|
|
||||||
try:
|
try:
|
||||||
|
self._templar.available_variables = variables
|
||||||
|
for key, value in self._locals.items():
|
||||||
|
result = self._templar.template(value)
|
||||||
|
variables[key] = result
|
||||||
|
self._display.vvv("- set block-local %s to %s" % (key, result))
|
||||||
try:
|
try:
|
||||||
self._display.vvv("- running 'block' instructions")
|
try:
|
||||||
return self.run_block(self._block, host_name, variables)
|
self._display.vvv("- running 'block' instructions")
|
||||||
except AnsibleError as e:
|
return self.run_block(self._block, host_name, variables)
|
||||||
if not self._rescue:
|
except AnsibleError as e:
|
||||||
self._display.vvv("- block failed")
|
if not self._rescue:
|
||||||
raise
|
self._display.vvv("- block failed")
|
||||||
self._display.vvv("- block failed, running 'rescue' instructions")
|
raise
|
||||||
variables["reconstructed_error"] = str(e)
|
self._display.vvv("- block failed, running 'rescue' instructions")
|
||||||
return self.run_block(self._rescue, host_name, variables)
|
variables["reconstructed_error"] = str(e)
|
||||||
|
return self.run_block(self._rescue, host_name, variables)
|
||||||
|
finally:
|
||||||
|
self._display.vvv("- block exited, running 'always' instructions")
|
||||||
|
self.run_block(self._always, host_name, variables)
|
||||||
finally:
|
finally:
|
||||||
self._display.vvv("- block exited, running 'always' instructions")
|
|
||||||
self.run_block(self._always, host_name, variables)
|
|
||||||
variables._script_stack_pop()
|
variables._script_stack_pop()
|
||||||
|
|
||||||
def run_block(self, block, host_name, variables):
|
def run_block(self, block, host_name, variables):
|
||||||
|
|
Loading…
Reference in a new issue