按照我的理解, 源码学习肯定是一边看代码, 一边执行程序验证执行的命令是: ansible sz003 -a "ls -l"
下面是 ansible.py 源码, 学习分析以注释的形式出现
- ########################################################
- from __future__ import (absolute_import, division, print_function)
- # 表示基于 type 创建类, 可以忽略
- __metaclass__ = type
- # __requires__ 要求按照的模块, 可能是因为我没有使用 ansible 提供的开发环境脚本的原因, 要把这个注释掉才行
- #__requires__ = [ansible]
- try:
- import pkg_resources
- except Exception:
- # Use pkg_resources to find the correct versions of libraries and set
- # sys.path appropriately when there are multiversion installs. But we
- # have code that better expresses the errors in the places where the code
- # is actually used (the deps are optional for many code paths) so we dont
- # want to fail here.
- pass
- import os
- import shutil
- import sys
- import traceback
- from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
- from ansible.module_utils._text import to_text
- # 用来显示信息
- class LastResort(object):
- # OUTPUT OF LAST RESORT
- def display(self, msg, log_only=None):
- print(msg, file=sys.stderr)
- def error(self, msg, wrap_text=None):
- print(msg, file=sys.stderr)
- if __name__ == __main__:
- #
- # 从这里开始执行
- #
- display = LastResort()
- try: # bad ANSIBLE_CONFIG or config options can force ugly stacktrace
- import ansible.constants as C
- from ansible.utils.display import Display
- except AnsibleOptionsError as e:
- display.error(to_text(e), wrap_text=False)
- sys.exit(5)
- #
- # cli 是用来存储 ansible 执行命令的对象
- #
- cli = None
- #
- # 获取执行的文件名, 在下面的代码中, 根据文件名判断是实例 adhoc 对象还是 playbook 对象
- # ansible-playbook 这部分代码是类似
- #
- me = os.path.basename(sys.argv[0])
- print("me:"+me)
- try:
- display = Display()
- display.debug("starting run")
- sub = None
- target = me.split(-)
- if target[-1][0].isdigit():
- # Remove any version or python version info as downstreams
- # sometimes add that
- target = target[:-1]
- if len(target)> 1:
- sub = target[1]
- myclass = "%sCLI" % sub.capitalize()
- elif target[0] == ansible:
- sub = adhoc
- myclass = AdHocCLI
- else:
- raise AnsibleError("Unknown Ansible alias: %s" % me)
- try:
- #
- # 这里是获取 adhoc 还是 playbook
- #
- mycli = getattr(__import__("ansible.cli.%s" % sub, fromlist=[myclass]), myclass)
- except ImportError as e:
- # ImportError members have changed in py3
- if msg in dir(e):
- msg = e.msg
- else:
- msg = e.message
- if msg.endswith( %s % sub):
- raise AnsibleError("Ansible sub-program not implemented: %s" % me)
- else:
- raise
- try:
- #
- # 这里是处理参数, 也就是执行命令时输入的 sz003 -a "ls -l"
- #
- args = [to_text(a, errors=surrogate_or_strict) for a in sys.argv]
- except UnicodeError:
- display.error(Command line args are not in utf-8, unable to continue. Ansible currently only understands utf-8)
- display.display(u"The full traceback was:\n\n%s" % to_text(traceback.format_exc()))
- exit_code = 6
- else:
- #
- # 这里就是具体实例化了
- #
- cli = mycli(args)
- #
- # 整理参数
- #
- cli.parse()
- #
- # 执行命令
- #
- exit_code = cli.run()
- #
- # 下面大多数是处理异常代码, 最后面有清理临时目录操作
- #
- except AnsibleOptionsError as e:
- cli.parser.print_help()
- display.error(to_text(e), wrap_text=False)
- exit_code = 5
- except AnsibleParserError as e:
- display.error(to_text(e), wrap_text=False)
- exit_code = 4
- # TQM takes care of these, but leaving comment to reserve the exit codes
- # except AnsibleHostUnreachable as e:
- # display.error(str(e))
- # exit_code = 3
- # except AnsibleHostFailed as e:
- # display.error(str(e))
- # exit_code = 2
- except AnsibleError as e:
- display.error(to_text(e), wrap_text=False)
- exit_code = 1
- except KeyboardInterrupt:
- display.error("User interrupted execution")
- exit_code = 99
- except Exception as e:
- have_cli_options = cli is not None and cli.options is not None
- display.error("Unexpected Exception, this is probably a bug: %s" % to_text(e), wrap_text=False)
- if not have_cli_options or have_cli_options and cli.options.verbosity> 2:
- log_only = False
- if hasattr(e, orig_exc):
- display.vvv(\nexception type: %s % to_text(type(e.orig_exc)))
- why = to_text(e.orig_exc)
- if to_text(e) != why:
- display.vvv(\noriginal msg: %s % why)
- else:
- display.display("to see the full traceback, use -vvv")
- log_only = True
- display.display(u"the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
- exit_code = 250
- finally:
- #
- # 最后如注释说的, 清理临时目录
- #
- # Remove ansible tempdir
- shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
- sys.exit(exit_code)
明天就转到学习 ansible 具体执行命令的流程了, 也就是下面代码段
- cli = mycli(args)
- cli.parse()
- exit_code = cli.run()
来源: http://www.bubuko.com/infodetail-2542865.html