如何使用子进程运行ansible playbooks

2024-05-13 18:53:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我是ansible的新手,无论我做了什么尝试,我都无法通过python脚本调用一个简单的剧本。在

代码示例:

import subprocess


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "sample.yml",
           "-v"]

    subprocess.run(cmd)


def main():
    sample("hostname,", "user")


if __name__ == '__main__':
    main()

标准输出示例:

^{pr2}$

脚本一直保持这样直到我终止它。在

当我从命令行$ ansible-playbook sample.yml -i "hostname," -e "user=user"执行ansible play book时,我得到了预期的STDOUT:

PLAY [all] **********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [hostname]

TASK [debug] ********************************************************************************************************************************************************************************************************************************
ok: [hostname] => {
    "msg": "I'm on hostname"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
hostname              : ok=2    changed=0    unreachable=0    failed=0

我的目标是用一个主机覆盖组这就是我使用语法-i "hostname,"的原因。在

样品样品.yml文件:

---
- hosts: all
  remote_user: '{{ ansible_user }}'
  any_errors_fatal: true
  tasks:
    - debug:
        msg: "I'm on {{ ansible_host }}"

我错在哪里了?在


Tags: sample脚本cmdformathost示例mainyml
2条回答

缺少传递命令行参数。见sys.argv。剩下的代码没问题。在

from sys import argv
import subprocess
[...]

def main():
    script, hostname, user = argv
    sample(hostname, user)
[...]

注释

1)为了测试剧本,额外的参数应该是ansible_user

^{pr2}$

2)对于sample("hostname,", "user"),剧本始终以"hostname"作为"user"运行

3)可以用-l代替-i,避免昏迷

$ ansible-playbook sample.yml -l "hostname" -e "ansible_user=user"

4)看看Ansible Runner。在

因此,唯一能使其同时适用于WSL和LinuxOS的是:

#!/usr/bin/python3

import pprint
import subprocess
import sys


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "-e ANSIBLE_HOST_KEY_CHECKING=False",
           "sample.yml",
           "-v"]

    proc = subprocess.Popen(cmd,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            )

    try:
        outs, errs = proc.communicate(timeout=15)
        pprint.pprint(outs.decode().split('\n'))
    except subprocess.SubprocessError as errs:
        proc.kill()
        sys.exit("Error: {}".format(errs))

def main():
    sample("hostname", "user")


if __name__ == '__main__':
    main()

您可以简单地将其执行为:

^{pr2}$

更新:如果您想同时与Python2和Python3兼容,则需要将代码最小化:

import pprint
import subprocess
import sys


def sample(host, user):
    cmd = ["ansible-playbook",
           "-i {},".format(host),
           "-e ansible_user={}".format(user),
           "-e ANSIBLE_HOST_KEY_CHECKING=False",
           "sample.yml",
           "-v"]

    proc = subprocess.Popen(cmd,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            )

    try:
        if sys.version_info > (3, 0):
            # Python 3 code in this block
            outs, errs = proc.communicate(timeout=15)
            pprint.pprint(outs.decode().split('\n'))
        else:
            # Python 2 code in this block
            outs, errs = proc.communicate()
            pprint.pprint(outs.decode().split('\n'))
    except subprocess.SubprocessError as errs:
        proc.kill()
        sys.exit("Error: {}".format(errs))


def main():
    sample("hostname", "user")


if __name__ == '__main__':
    main()

然后您可以简单地用以下方法进行测试:

$ python test.py
['Using /etc/ansible/ansible.cfg as config file',
 '',
 'PLAY [all] *********************************************************************',
 '',
 'TASK [Gathering Facts] *********************************************************',
 'ok: [hostname]',
 '',
 'TASK [debug] *******************************************************************',
 'ok: [hostname] => {',
 '    "msg": "I\'m on hostname"',
 '}',
 '',
 'PLAY RECAP *********************************************************************',
 'hostname              : ok=2    changed=0    unreachable=0    failed=0   ',
 '',
 '']

对于Python3来说:

$ python3 test.py
['Using /etc/ansible/ansible.cfg as config file',
 '',
 'PLAY [all] '
 '*********************************************************************',
 '',
 'TASK [Gathering Facts] '
 '*********************************************************',
 'ok: [hostname]',
 '',
 'TASK [debug] '
 '*******************************************************************',
 'ok: [hostname] => {',
 '    "msg": "I\'m on hostname"',
 '}',
 '',
 'PLAY RECAP '
 '*********************************************************************',
 'hostname              : ok=2    changed=0    unreachable=0    '
 'failed=0   ',
 '',
 '']
````

One problem that I have noticed here a minor problem is that [pycharm][1] installed on WindowsOS and running with Python2/3 2/3 Ubuntu wsl://UBUNTU/usr/bin/python is unfortunately stays frozen as shown above, but if you execute the code from terminal everything works as expected.

I have installed WSL not WSL2 maybe this problem is fixed on WSL2.


  [1]: https://www.jetbrains.com/pycharm/

相关问题 更多 >