Ansible的runner源码剖析第二部分(初始化类的学习)
版本ansible1.9.1
# -*- coding=utf-8 -*-
class Runner(object):
''' core API interface to ansible '''
# see bin/ansible for how this is used...
def __init__(self,
host_list=C.DEFAULT_HOST_LIST, # ex: /etc/ansible/hosts, legacy usage #初始化默认参数,如果没指定走/etc/ansible/hosts文件
module_path=None, # ex: /usr/share/ansible #Ansible的路径一般不用写
module_name=C.DEFAULT_MODULE_NAME, # ex: copy #模块名字必须指定
module_args=C.DEFAULT_MODULE_ARGS, # ex: "src=/tmp/a dest=/tmp/b" #模块的参数,对应了ansible命令行中的-a后面带的内容
forks=C.DEFAULT_FORKS, # parallelism level
#进程的数目,如果你填入了20,它会判断你的list_hosts里面是否有20个IP,没有的话根据主机的数量来派生进程,如果多的话,就用multiprocess的pool进程池来调用
timeout=C.DEFAULT_TIMEOUT, # SSH timeout #SSH的超时时间
pattern=C.DEFAULT_PATTERN, # which hosts? ex: 'all', 'acme.example.org'#指定hostfile文件中执行的分组
remote_user=C.DEFAULT_REMOTE_USER, # ex: 'username' #远程执行的用户
remote_pass=C.DEFAULT_REMOTE_PASS, # ex: 'password123' or None if using key #远程执行的密码
remote_port=None, # if SSH on different ports #远程执行的端口,如果ssh端口被变更过的话
private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, # if not using keys/passwords #自钥地址,用来秘钥验证的
background=0, # async poll every X seconds, else 0 for non-async #0代表不异步,其余数代表多少秒后根据任务id去取数据
basedir=None, # directory of playbook, if applicable #指定playbook的存放目录
setup_cache=None, # used to share fact data w/ other tasks #用于与其他任务共享实时数据
vars_cache=None, # used to store variables about hosts #存储有关主机的变量
transport=C.DEFAULT_TRANSPORT, # 'ssh', 'paramiko', 'local' #3种传输模式,ssh,paramiko,local
conditional='True', # run only if this fact expression evals to true #状态的判断,
callbacks=None, # used for output #指定回调输出
module_vars=None, # a playbooks internals thing #playbooks内部的东西
play_vars=None, # #和playbook相关的变量
play_file_vars=None, #
role_vars=None, #
role_params=None, #
default_vars=None, # #默认变量
extra_vars=None, # extra vars specified with he playbook(s)#playbook指定额外的变量
is_playbook=False, # running from playbook or not? #是否以playbook运行
inventory=None, # reference to Inventory object #引用inventory对象
subset=None, # subset pattern #子集模式
check=False, # don't make any changes, just try to probe for potential changes #不做任何改变,仅仅尝试
diff=False, # whether to show diffs for template files that change #是否显示更改的模板文件差异
environment=None, # environment variables (as dict) to use inside the command #环境变量以字典方式传递进来
complex_args=None, # structured data in addition to module_args, must be a dict #结构化数据,参数
error_on_undefined_vars=C.DEFAULT_UNDEFINED_VAR_BEHAVIOR, # ex. False
accelerate=False, # use accelerated connection #使用加速ssh连接
accelerate_ipv6=False, # accelerated connection w/ IPv6
accelerate_port=None, # port to use with accelerated connection #使用加速连接使用的端口
vault_pass=None,
run_hosts=None, # an optional list of pre-calculated hosts to run on #
no_log=False, # option to enable/disable logging for a given task #是否开启任务日志
run_once=False, # option to enable/disable host bypass loop for a given task
become=False, # whether to run privelege escalation or not #是否运行特权升级sudo
become_method=C.DEFAULT_BECOME_METHOD,
become_user=C.DEFAULT_BECOME_USER, # ex: 'root' #sudo用户
become_pass=C.DEFAULT_BECOME_PASS, # ex: 'password123' or None #sudo密码
become_exe=C.DEFAULT_BECOME_EXE, # ex: /usr/local/bin/sudo #sudo命令行
):
# used to lock multiprocess inputs and outputs at various levels
self.output_lockfile = OUTPUT_LOCKFILE #输出文件锁
self.process_lockfile = PROCESS_LOCKFILE #进程锁
if not complex_args: #为空的话初始化为空字典
complex_args = {}
# storage & defaults
self.check = check
self.diff = diff
self.setup_cache = utils.default(setup_cache, lambda: ansible.cache.FactCache())
self.vars_cache = utils.default(vars_cache, lambda: collections.defaultdict(dict))
self.basedir = utils.default(basedir, lambda: os.getcwd())
self.callbacks = utils.default(callbacks, lambda: DefaultRunnerCallbacks())
self.generated_jid = str(random.randint(0, 999999999999))
self.transport = transport
self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list))
# utils.default详细见下方的备注执行lambda函数,self.inventory就是Inventory对象,初始化通过host_list来执行,这个对象下包含了主机信息以及各种变量
self.module_vars = utils.default(module_vars, lambda: {})
self.play_vars = utils.default(play_vars, lambda: {})
self.play_file_vars = utils.default(play_file_vars, lambda: {})
self.role_vars = utils.default(role_vars, lambda: {})
self.role_params = utils.default(role_params, lambda: {})
self.default_vars = utils.default(default_vars, lambda: {})
self.extra_vars = utils.default(extra_vars, lambda: {})
self.always_run = None
self.connector = connection.Connector(self)
self.conditional = conditional
self.delegate_to = None
self.module_name = module_name
self.forks = int(forks)
self.pattern = pattern
self.module_args = module_args
self.timeout = timeout
self.remote_user = remote_user
self.remote_pass = remote_pass
self.remote_port = remote_port
self.private_key_file = private_key_file
self.background = background
self.become = become
self.become_method = become_method
self.become_user_var = become_user
self.become_user = None
self.become_pass = become_pass
self.become_exe = become_exe
self.is_playbook = is_playbook
self.environment = environment
self.complex_args = complex_args
self.error_on_undefined_vars = error_on_undefined_vars
self.accelerate = accelerate
self.accelerate_port = accelerate_port
self.accelerate_ipv6 = accelerate_ipv6
self.callbacks.runner = self
self.omit_token = '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest()
self.vault_pass = vault_pass
self.no_log = no_log
self.run_once = run_once
if self.transport == 'smart':
# 判断传输模式,确定最后是否使用paramiko,ansible1.2.1/1.3版本里面有smart的东西,前向兼容
# If the transport is 'smart', check to see if certain conditions
# would prevent us from using ssh, and fallback to paramiko.
# 'smart' is the default since 1.2.1/1.3
self.transport = "ssh"
#判断系统平台和远程执行密码来确定传输模式
if sys.platform.startswith('darwin') and self.remote_pass:
# due to a current bug in sshpass on OSX, which can trigger
# a kernel panic even for non-privileged users, we revert to
# paramiko on that OS when a SSH password is specified
self.transport = "paramiko"
else:
# see if SSH can support ControlPersist if not use paramiko #执行命令ssh -o ControlPersist加速模式,确定传输模式
cmd = subprocess.Popen(['ssh','-o','ControlPersist'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = cmd.communicate()
if "Bad configuration option" in err:
self.transport = "paramiko"
# save the original transport, in case it gets
# changed later via options like accelerate
self.original_transport = self.transport
# misc housekeeping
if subset and self.inventory._subset is None:
# don't override subset when passed from playbook
self.inventory.subset(subset)
# If we get a pre-built list of hosts to run on, from say a playbook, use them.
# Also where we will store the hosts to run on once discovered
self.run_hosts = run_hosts
if self.transport == 'local':
#传输模式本地的话,pwd和os模块联合方法取出当前系统执行用户,linux下的方法
self.remote_user = pwd.getpwuid(os.geteuid())[0]
#模块路径指定的话,切割模块路径
if module_path is not None:
for i in module_path.split(os.pathsep):
utils.plugins.module_finder.add_directory(i)
utils.plugins.push_basedir(self.basedir)
# ensure we are using unique tmp paths
# 初始化基本随机数生成器
random.seed()
# *****************************************************
utils.default#判断第一个参数是否存在,不存在执行第二个参数函数
def default(value, function):
# syntactic sugar around lazy evaluation of defaults
if value is None:
return function()
return value