run_once clause
When the run_once clause is present and set to a truthy value, the instruction it is attached to will only be executed the first time it is encountered.
This commit is contained in:
parent
14fca45cb7
commit
446280ab6e
3 changed files with 27 additions and 10 deletions
|
@ -8,9 +8,9 @@ I just don't forget about this whole thing.
|
||||||
|
|
||||||
A `reconstructed` inventory executes a list of instructions that is read
|
A `reconstructed` inventory executes a list of instructions that is read
|
||||||
from the `instructions` YAML field. Each instruction is a table with some
|
from the `instructions` YAML field. Each instruction is a table with some
|
||||||
minimal control flow (`when` and `loop` keywords that work mostly like their
|
minimal control flow (`when`, `loop` and `run_once` keywords that work mostly
|
||||||
playbook cousins), an `action` field that contains the name of the instruction
|
like their playbook cousins), an `action` field that contains the name of the
|
||||||
to execute, and whatever fields are needed for the instruction.
|
instruction to execute, and whatever fields are needed for the instruction.
|
||||||
|
|
||||||
The following actions are supported:
|
The following actions are supported:
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ instructions:
|
||||||
- action: stop
|
- action: stop
|
||||||
|
|
||||||
# Only create the managed groups if we *have* managed hosts
|
# Only create the managed groups if we *have* managed hosts
|
||||||
|
- action: block
|
||||||
|
run_once: true
|
||||||
|
block:
|
||||||
- action: create_group
|
- action: create_group
|
||||||
group: managed
|
group: managed
|
||||||
- loop: [by_environment, by_network, by_failover_stack, by_service]
|
- loop: [by_environment, by_network, by_failover_stack, by_service]
|
||||||
|
|
|
@ -40,6 +40,8 @@ DOCUMENTATION = """
|
||||||
- The C(when) field, if present, must contain a Jinja expression
|
- The C(when) field, if present, must contain a Jinja expression
|
||||||
representing a condition which will be checked before the instruction
|
representing a condition which will be checked before the instruction
|
||||||
is executed.
|
is executed.
|
||||||
|
- The C(run_once) field will ensure that the instuction it is attached
|
||||||
|
to will only run one time at most.
|
||||||
- The C(action) field must be set to one of the following values.
|
- The C(action) field must be set to one of the following values.
|
||||||
- The C(block) action is another form of flow control, which can be
|
- The C(block) action is another form of flow control, which can be
|
||||||
used to repeat multiple instructions or make them obey a single
|
used to repeat multiple instructions or make them obey a single
|
||||||
|
@ -91,7 +93,7 @@ DOCUMENTATION = """
|
||||||
default: host
|
default: host
|
||||||
"""
|
"""
|
||||||
|
|
||||||
INSTR_COMMON_FIELDS = ("when", "loop", "loop_var", "action")
|
INSTR_COMMON_FIELDS = ("when", "loop", "loop_var", "action", "run_once")
|
||||||
"""Fields that may be present on all instructions."""
|
"""Fields that may be present on all instructions."""
|
||||||
|
|
||||||
INSTR_OWN_FIELDS = {
|
INSTR_OWN_FIELDS = {
|
||||||
|
@ -231,6 +233,7 @@ class RcInstruction(abc.ABC):
|
||||||
self._loop = None
|
self._loop = None
|
||||||
self._loop_var = None
|
self._loop_var = None
|
||||||
self._action = action
|
self._action = action
|
||||||
|
self._executed_once = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Builds a compact debugging representation of the instruction, \
|
"""Builds a compact debugging representation of the instruction, \
|
||||||
|
@ -242,6 +245,8 @@ class RcInstruction(abc.ABC):
|
||||||
flow.append(
|
flow.append(
|
||||||
"loop=%s, loop_var=%s" % (repr(self._loop), repr(self._loop_var))
|
"loop=%s, loop_var=%s" % (repr(self._loop), repr(self._loop_var))
|
||||||
)
|
)
|
||||||
|
if self._executed_once is not None:
|
||||||
|
flow.append("run_once")
|
||||||
if flow:
|
if flow:
|
||||||
output = "{%s}" % (", ".join(flow),)
|
output = "{%s}" % (", ".join(flow),)
|
||||||
else:
|
else:
|
||||||
|
@ -269,6 +274,8 @@ class RcInstruction(abc.ABC):
|
||||||
output.append("{when: %s}" % (repr(self._condition),))
|
output.append("{when: %s}" % (repr(self._condition),))
|
||||||
if self._loop is not None:
|
if self._loop is not None:
|
||||||
output.append("{loop[%s]: %s}" % (self._loop_var, repr(self._loop)))
|
output.append("{loop[%s]: %s}" % (self._loop_var, repr(self._loop)))
|
||||||
|
if self._executed_once is not None:
|
||||||
|
output.append("{run_once}")
|
||||||
output.extend(self.dump_instruction())
|
output.extend(self.dump_instruction())
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
@ -331,6 +338,9 @@ class RcInstruction(abc.ABC):
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
"%s: 'loop_var' clause found without 'loop'" % (self._action,)
|
"%s: 'loop_var' clause found without 'loop'" % (self._action,)
|
||||||
)
|
)
|
||||||
|
# Handle instructions that may only be executed once
|
||||||
|
if record.get("run_once", False):
|
||||||
|
self._executed_once = False
|
||||||
# Process action-specific fields
|
# Process action-specific fields
|
||||||
self.parse_action(record)
|
self.parse_action(record)
|
||||||
|
|
||||||
|
@ -395,6 +405,10 @@ class RcInstruction(abc.ABC):
|
||||||
``True`` if execution must continue, ``False`` if it must be
|
``True`` if execution must continue, ``False`` if it must be
|
||||||
interrupted
|
interrupted
|
||||||
"""
|
"""
|
||||||
|
if self._executed_once is True:
|
||||||
|
return True
|
||||||
|
if self._executed_once is False:
|
||||||
|
self._executed_once = True
|
||||||
if self._loop is None:
|
if self._loop is None:
|
||||||
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_iteration(host_name, variables)
|
return self.run_iteration(host_name, variables)
|
||||||
|
|
Loading…
Reference in a new issue