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.85k stars 374 forks source link

Use _precondition without erroring #909

Closed sebastianelsner closed 1 year ago

sebastianelsner commented 1 year ago

I want an operation to run only if _precondition is "true". If it is not true, I don't want the operation to run and not produce errors. Currently, after the error the deploy stops.

The use case behind this request is to make third party software "installers" kind of "idempotent". It would be nice to separate the "precondition" from the execution of an installer.

This is the way I would do it right now:

    server.shell(
        name="Install Houdini",
        commands=[
            "if [! -d ./hfs19.5.403 ]; then "
            "./houdini_installer install "
            "--product Houdini "
            "--version 19.5.403 "
            "; fi"
        ],
    )

vs. this is a "nicer" way

    server.shell(
        name="Install Houdini",
         _precondition="! test -d ./hfs19.5.403",
        commands=[
            "./houdini_installer install "
            "--product Houdini "
            "--version 19.5.403 "
        ],
    )

This way an operation would also not show up as "Changed" in the summary.

Does this request make sense?

I have been using similar functionality in Puppet with the "onlyif => ..." module directive.

Fizzadar commented 1 year ago

Hi @sebastianelsner! Does the ./hfs19.5.403 file get created earlier on or as part of the install command? If install you could do the following:

from pyinfra.facts.files import Directory
from pyinfra.operations import server

if not host.get_fact(Directory, path="./hfs19.5.403"):
    server.shell(name="Install Houdini", ...)

This best fits the two phase diff-then-apply way pyinfra works.

sebastianelsner commented 1 year ago

Ah, I see! This solves my case. Thank you!