意外异常:调用 ansible2 时未定义名称 'basestring'

Unexpected Exception: name 'basestring' is not defined when invoking ansible2

我正在尝试执行 ansible 命令...

当我这样做时:

ansible-playbook -vvv -i my/inventory my/playbook.yml

我得到:

Unexpected Exception: name 'basestring' is not defined the full traceback was:

Traceback (most recent call last):
  File "/usr/local/bin/ansible-playbook", line 85, in <module>
    sys.exit(cli.run())
  File "/usr/local/lib/python3.4/site-packages/ansible/cli/playbook.py", line 150, in run
    results = pbex.run()
  File "/usr/local/lib/python3.4/site-packages/ansible/executor/playbook_executor.py", line 87, in run
    self._tqm.load_callbacks()
  File "/usr/local/lib/python3.4/site-packages/ansible/executor/task_queue_manager.py", line 149, in load_callbacks
    elif isinstance(self._stdout_callback, basestring):
NameError: name 'basestring' is not defined

这里是ansible --version:

ansible 2.0.0.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

这里是python --version

Python 3.4.3

低于版本 2.5 的 Ansible 需要 Python 控制主机上的 2.6 或 2.7:Control Node Requirements

basestring 在 Python 中不再可用 3. 来自 What’s New In Python 3.0:

The builtin basestring abstract type was removed. Use str instead. The str and bytes types don’t have functionality enough in common to warrant a shared base class. The 2to3 tool (see below) replaces every occurrence of basestring with str.

所以解决方案是升级 Ansible 或降级 Python。

basestring 在 Python 3 中不可用。:

python 2.x 和 3.x 可以通过以下方式解决:

try:
  basestring
except NameError:
  basestring = str

我 运行 使用 Python 3 和 Ansible 解决了这个问题,并通过分叉 dopy 项目并在我的 ansible 脚本中安装 dopy 来解决:

name: git+https://github.com/eodgooch/dopy@0.4.0#egg=dopy

如果您仍然遇到错误,请务必将 version 更改为 0.4.0 并从您的 Python 站点包目录中删除任何挥之不去的 dopy 包。

您也可以 pip3 install git+https://github.com/eodgooch/dopy@0.4.0#egg=dopy 而不是在您的 Ansible 任务中。

将 basestring 替换为 str。在 2.x 中有 basestring。但在 3.x 中,basestring 已替换为 "str".

问题可能是由于 python 版本。在 2.x 中,有 basestring,但在 3.x 中,它已被替换为 "str"。

另一种可能的解决方案是通过 pip install future 安装 future 并导入 from past.builtins import basestring.

from past.builtins import basestring

就我个人而言,我并不喜欢这个解决方案,因为:

  1. 它需要安装另一个依赖项。
  2. 混合 Python 3 和 2 代码可能存在其他向后兼容性问题。
  3. 它只会在您的代码中起作用——您不想修改 Ansible 源代码。

我提供它只是因为它是我过去用来使我自己的代码在 Python 2 和 3 中工作的东西。