import
Ansible 允许从特定目录进行未经检查的导入某些库。导入任何其他 Python 库需要处理导入错误。这支持了诸如 validate-modules 之类的健全性测试,并为用户提供了更好的错误消息。
重要
请参阅常见问题,以获得有关解决此测试报告的常见问题的解答。
处理导入错误
Ansible 在多个主机上执行,并且可以同时使用多个 Python 解释器,这些解释器甚至可能具有不同的版本。为了确保用户获得可操作且易于理解的错误,我们尝试确保模块/插件中的任何非核心导入都受到保护,以避免回溯,大多数用户无法理解回溯,更不用说使用它来解决问题了。
Ansible 执行此操作的另一个原因是导入代码进行检查。这使得 Ansible 可以轻松地基于代码进行测试、文档化、配置等,而无需在所有地方安装任何和所有要求,尤其是在您执行代码的上下文不是这种情况时。
以下代码显示了如何在导入时避免错误,然后使用提供的 missing_required_lib
来确保用户知道缺少哪个库、在哪个主机上缺少以及哪个特定的解释器需要它。
在模块中
而不是使用 import another_library
import traceback
from ansible.module_utils.basic import missing_required_lib
try:
import another_library
except ImportError:
HAS_ANOTHER_LIBRARY = False
ANOTHER_LIBRARY_IMPORT_ERROR = traceback.format_exc()
else:
HAS_ANOTHER_LIBRARY = True
ANOTHER_LIBRARY_IMPORT_ERROR = None
注意
上面的 missing_required_lib
导入将在下面使用。
然后在模块代码中,通常在 main
方法中
module = AnsibleModule(...)
if not HAS_ANOTHER_LIBRARY:
module.fail_json(
msg=missing_required_lib('another_library'),
exception=ANOTHER_LIBRARY_IMPORT_ERROR)
在插件中
而不是使用 import another_library
try:
import another_library
except ImportError as imp_exc:
ANOTHER_LIBRARY_IMPORT_ERROR = imp_exc
else:
ANOTHER_LIBRARY_IMPORT_ERROR = None
然后在插件代码中,例如在插件的 run
方法中(某些插件没有 run
方法,而需要在 __init__
方法中执行)
if ANOTHER_LIBRARY_IMPORT_ERROR:
raise AnsibleError('another_library must be installed to use this plugin') from ANOTHER_LIBRARY_IMPORT_ERROR
当用作基类时
重要
此解决方案建立在前两个示例的基础上。在继续此解决方案之前,请确保选择合适的解决方案。
有时,导入用于基类中,例如
from another_library import UsefulThing
class CustomThing(UsefulThing):
pass
一种选择是使整个类定义有条件
if not ANOTHER_LIBRARY_IMPORT_ERROR:
class CustomThing(UsefulThing):
pass
另一种选择是通过修改异常处理程序来定义一个替代基类
try:
from another_library import UsefulThing
except ImportError:
class UsefulThing:
pass
...
允许未经检查的导入
Ansible 允许从这些特定目录进行以下未经检查的导入
ansible-core
对于
lib/ansible/modules/
和lib/ansible/module_utils/
,仅允许从 Python 标准库进行未经检查的导入;对于
lib/ansible/plugins/
,仅允许从 Python 标准库、ansible-core 的公共依赖项以及 ansible-core 本身进行未经检查的导入;
集合
对于
plugins/modules/
和plugins/module_utils/
,仅允许从 Python 标准库进行未经检查的导入;对于
plugins/
中的其他目录(有关列表,请参见社区集合要求),仅允许从 Python 标准库、ansible-core 的公共依赖项以及 ansible-core 本身进行未经检查的导入。
ansible-core 的公共依赖项为
Jinja2
PyYAML
MarkupSafe(作为 Jinja2 的依赖项)
常见问题 (FAQ)
为什么我的模块或插件工作时会出现 ImportError
?
import
健全性测试与其他测试非常不同。按照设计,它只能看到 Python 标准库中的模块。这意味着您的模块或插件可以在您的 playbook、集成测试和单元测试中工作,但在 import
健全性测试中失败。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。
为什么测试没有使用我指定的 Python 解释器?
健全性测试将使用您指定的 Python 解释器。但是,它将使用该 Python 解释器创建自己的虚拟环境。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。
如何使用自定义虚拟环境?
这是不可能的,因为这样做会破坏测试的目的。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。
如何指定在哪里查找我的导入?
这是不可能的,因为这样做会破坏测试的目的。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。
如何指定要使用的需求文件?
这是不可能的,因为这样做会破坏测试的目的。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。
如何在不更改代码的情况下修复 ImportError
?
在不更改插件或模块的情况下,无法修复其中的 ImportError
。
所有出现的 ImportError
都必须在发生它的模块或插件中正确处理。