pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.91k stars 382 forks source link

Possibility to force execution of operation #653

Open giuppep opened 3 years ago

giuppep commented 3 years ago

Is your feature request related to a problem? Please describe

Pyinfra collects all facts before running operations. However sometimes an operation could modify this state during execution and as far as I could understand, there is no way to force pyinfra execute an operation.

Example: At the end of a deploy script we want to make sure that some directory X is owned by a given user:group. In the script there is a command that could change the owner of X. Since pyinfra evaluates all the facts before starting the deployment, if the ownership was correctly set before the current deployment started (e.g. by a previous successful deployment), then the files.directory("X", user="user", group="group") will not be executed at the end of the script.

Describe the solution you'd like

A flag to make pyinfra execute an operation regardless of whether the relevant facts determined it could be skipped.

giuppep commented 3 years ago

Hi, I noticed another use case where this could be useful

Let's say we have directory PARENT that belongs to user:group and this directory has a child CHILD that belongs to other_user:other_group.

If I want to make sure that all children of PARENT belong to user:group I would use

files.directory("PARENT", user="user", group="group", recursive=True)

however, given that the PARENT directory already belongs to user:group, chown -R is not run hence not updating the ownership of the children.

themanifold commented 3 years ago

I have need for this use case, also.

Fizzadar commented 1 year ago

I am wondering if nested operations might solve these cases?

My concern here is that each case is specific to the operation -this would require adding a force=True or similar argument to each operation with specific changes to the operation code depending on the facts used. A good example of this already are the [assume_present arguments](https://github.com/Fizzadar/pyinfra/blob/2.x/pyinfra/operations/files.py#L1292) in many of the files.* operations.

Not against this at all, the fact-then-execute setup does have some compromises like this and I'm keen to explore options.