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

Runner's stats and playbook pause (ctrl+c) combination #1359

Open
mkyrc opened this issue May 10, 2024 · 0 comments
Open

Runner's stats and playbook pause (ctrl+c) combination #1359

mkyrc opened this issue May 10, 2024 · 0 comments
Labels
needs_triage New item that needs to be triaged

Comments

@mkyrc
Copy link

mkyrc commented May 10, 2024

Hello,
I'd like to solve the issue with playbook with pause task combined with calling playbook by ansible_runner.run_command(). We need to call ansible-playbook from python code and read playbook results/stats (not scanning stdout and reading lines after "RECAP").

Based on run_command() documentation - "Run an (Ansible) commands in the foreground and return a Runner object when complete." I'd like to get Runner's stats value. Note: Method description is wrong, because this method doesn't return Runner, it returns only a tuple of response, error string and return code.

Based on source code I prepared my custom Python code (a very limited part of the code - just to show the problem):

    def runner_run_command_test(self):

        runner_opts = {
            "executable_cmd": "ansible-playbook",
            "cmdline_args": ["ansible/playbooks/test.pb.yaml"],
            # "envvars": env,
            # "input_fd": sys.stdin,
            # "error_fd": sys.stderr,
            # "output_fd": sys.stdout,
            # "runner_mode": "pexpect",
            # "runner_mode": "subprocess",
        }

        resp = {}
        try:
            runner = ansible_runner.interface.init_command_config(**runner_opts)
            runner.run()

            resp = {
                "stats": runner.stats,  # << focus on stats
                "rc": runner.rc,
                "satus": runner.status,
                # "response": runner.stdout.read(),
                "error": runner.stderr.read(),
            }
        except KeyboardInterrupt:
            print("User interrupted.")

        print(f"result:\n{resp}")

        return resp

test playbook:

---
- name: "F5: test PB"
  hosts: localhost
  gather_facts: false

  tasks:
    - name: "TSK #1: test message"
      ansible.builtin.debug:
        msg: "this is test message"

    - name: "TSK #2: continue?"
      ansible.builtin.pause:
        seconds: 5

    - name: "TSK #3: test message"
      ansible.builtin.debug:
        msg: "this is test message"

With above runner_opts settings I got this response (including correct stats):

PLAY [F5: test PB] *************************************************************

TASK [TSK #1: test message] ****************************************************
ok: [localhost] => {
    "msg": "this is test message"
}

TASK [TSK #2: continue?] *******************************************************
Pausing for 5 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [localhost]

TASK [TSK #3: test message] ****************************************************
ok: [localhost] => {
    "msg": "this is test message"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Result: {'stats': {'skipped': {}, 'ok': {'localhost': 3}, 'dark': {}, 'failures': {}, 'ignored': {}, 'rescued': {}, 'processed': {'localhost': 1}, 'changed': {}}, 'rc': 0, 'satus': 'successful', 'error': ''}

problem: 'Ctrl+C' within pause task is interrupting playbook process and it's not send to pause task as expected

TASK [TSK #2: continue?] *******************************************************
Pausing for 5 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
^CUser interrupted.
Result: {}

problem with input_fb setting: when we add input_fd settings the all playbook outputs are not displaying continuously but at ones after all tasks are called. there is no possibility to see/stop pause task part. requested stats are there:

runner_opts = {
            "executable_cmd": "ansible-playbook",
            "cmdline_args": ["ansible/playbooks/test.pb.yaml"],
            "input_fd": sys.stdin,
        }

result summary:

Result: {'stats': {'skipped': {}, 'ok': {'localhost': 3}, 'dark': {}, 'failures': {}, 'ignored': {}, 'rescued': {}, 'processed': {'localhost': 1}, 'changed': {}}, 'rc': 0, 'satus': 'successful', 'error':  '' }

problem with input_fd and output_fd setting: with this settings is pause working as expected, also playbook output is displayed continuously, but stats is missing (it's None)

runner_opts = {
            "executable_cmd": "ansible-playbook",
            "cmdline_args": ["ansible/playbooks/test.pb.yaml"],
            "input_fd": sys.stdin,
            "output_fd": sys.stdout,
        }

result summary (stats is None):

Result: {'stats': None, 'rc': 0, 'satus': 'successful', 'error': ''}

stats property source code is not very helpful (for me).

Result
It seems, that "runner_mode": "subprocess" setting (enabled with input_fd) is required to send 'Ctrl+C' to task. But I need also output_fd for continuously output and this setting 'currupt' stats data. Documentation is not very clear why it happens.

Any ideas how to solve this issue?

Versions:

  • Python 3.10.12
  • ansible-runner==2.3.6
  • ansible==8.6.1
  • ansible-core==2.15.6

UPDATE:
When we use run() instead of run_command() we can get stats correctly, but no input to stdin is possible to send (ctrl+c imn pause task is not working)

@github-actions github-actions bot added the needs_triage New item that needs to be triaged label May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs_triage New item that needs to be triaged
Projects
None yet
Development

No branches or pull requests

1 participant