Skip to content

Commit

Permalink
Store and use (re)deploy data for all operation command generation
Browse files Browse the repository at this point in the history
Attaching the deploy data *at operation call time* allows us to reuse it
when/if the operation is re-evaluated during execution.
  • Loading branch information
Fizzadar committed May 4, 2024
1 parent f078e92 commit bae35c7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
13 changes: 8 additions & 5 deletions pyinfra/api/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,16 @@ class Host:
current_op_hash: Optional[str] = None
current_op_global_arguments: Optional["AllArguments"] = None

# Current context inside a @deploy function (op gen stage)
# Current context inside a @deploy function which become part of the op data
in_deploy: bool = False
current_deploy_name: Optional[str] = None
current_deploy_kwargs = None
current_deploy_data = None

# @deploy decorator data is a bit different - we need to handle the case
# where we're evaluating an operation at runtime (current_op_) but also
# when ordering operations (current_) outside of an operation context.
current_op_deploy_data: Optional[dict[str, Any]] = None
current_deploy_data: Optional[dict[str, Any]] = None

# Current context during operation execution
executing_op_hash: Optional[str] = None
Expand Down Expand Up @@ -216,9 +221,7 @@ def log_styled(self, message, log_func=logger.info, **kwargs):
self.log(message_styled, log_func=log_func)

def get_deploy_data(self):
if self.current_deploy_data:
return self.current_deploy_data
return {}
return self.current_op_deploy_data or self.current_deploy_data or {}

def noop(self, description):
"""
Expand Down
7 changes: 7 additions & 0 deletions pyinfra/api/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ def decorated_func(*args: P.args, **kwargs: P.kwargs) -> OperationMeta:
if has_run:
return OperationMeta(op_hash, is_change=False)

# Grab a reference to any *current* deploy data as this may change when
# we later evaluate the operation at runtime.This means we put back the
# expected deploy data.
current_deploy_data = host.current_deploy_data

# "Run" operation - here we make a generator that will yield out actual commands to execute
# and, if we're diff-ing, we then iterate the generator now to determine if any changes
# *would* be made based on the *current* remote state.
Expand All @@ -260,6 +265,7 @@ def command_generator() -> Iterator[PyinfraCommand]:
host.in_op = _set_in_op
host.current_op_hash = op_hash
host.current_op_global_arguments = global_arguments
host.current_op_deploy_data = current_deploy_data

try:
for command in func(*args, **kwargs):
Expand All @@ -270,6 +276,7 @@ def command_generator() -> Iterator[PyinfraCommand]:
host.in_op = False
host.current_op_hash = None
host.current_op_global_arguments = None
host.current_op_deploy_data = None

op_is_change = None
if state.should_check_for_changes():
Expand Down

0 comments on commit bae35c7

Please sign in to comment.