Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attribute to ssh.command, that tells that return code of the command means 'no change' #1066

Open
ratermir opened this issue Feb 11, 2024 · 3 comments

Comments

@ratermir
Copy link

In the "ssh.command", there may be situations when I can check, whether the system is already in the desired state or not.

  1. If the system is in the desired state, I won't perform any action, only inform the caller (i.e. pyload in this case) that I did nothing.
  2. In the other case, I can apply desired changes and return normal status code (zero for the success, non-zero for an error).

In case of 1., I can return special return code and simultaneously I can inform pyload, that this code means "no change".

Let we have (for example) such SSH command:

snap list helm || ( snap install helm && exit 0 ) && exit 200

This command returns status 200 if there is no change (i.e. helm is already installed) and normal status - i.e. 0 if helm was installed or non - zero except 200 (I must guarantee that there is no other 200 than my check) in case of error.

It would be perfect to be able to instruct pyload, that the status 200 means "no change".
It could be done by additional attribute of the "ssh.command" command , it can be named for example "no_change_status", so in such case the "ssh.command" can look like this:

ssh.command( name="Install heml via snap", command="snap list helm || ( snap install helm && exit 0 ) && exit 200", no_change_status=200 )

@vojta001
Copy link

vojta001 commented Feb 12, 2024

For your particular example, you can write a custom Fact that checks whether a snap package is installed and only run snap install if needed.

@ratermir
Copy link
Author

Thank you to pointing out, but - according to my knowledge - the result will not be the same. By my proposed solution, in the result list will be seen that there is some desired state but the opertion made no change (i.e. the system is already in the required state), in your proposal there will not to be a trace about the operation in such case. Am I correct?
Btw for my particular examle, the best solution would be to implement "snap" operation :) I looked how the operations are programmed, but my Python knowledge are too few and I don't feel like to be able to do i well. So I will fill new request, so I will make new feature request.

@vojta001
Copy link

You are right, if the control flow is a part of the top-level file, the skipped operations won't show up. You can however wrap it in a simple operation just calling other operations.

the general idea is

import pyinfra

class SnapPackageInstalled(pyinfra.api.FactBase):
  pass # TODO check whether a package is installed

@pyinfra.api.operation
def install_snap_package(name):
  exists = pyinfra.host.get_fact(SnapPackageInstalled, name)
  if not exists:
    yield from pyinfra.operations.server.shell(f"snap install {name}") #TODO escape better

install_snap_package("helm")

@ratermir ratermir changed the title Add attribute to ssh.command, that in tells return code of the command, that indicates 'no change' Add attribute to ssh.command, that tells that return code of the command means 'no change' Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants