salt的api学习记录(一)

现在终于开始学习salt的api了,有些小激动啊,我们执行命令的时候,后台到底是如何处理的,发生什么了事情,我对着一切有着强烈的好奇心啊。

这些是saltstack命令对应的api:

salt 		--->salt.client.LocalClient 
salt-cp 	--->salt.cli.cp.SaltCP 
salt-key	--->salt.key.KeyCLI
salt-call	--->salt.cli.caller.caller
salt-run	--->salt.runner.Runner 
salt-ssh	--->salt.client.ssh.SSH

首先学习的是salt命令对应的api:salt.client.LocalClient。

首先我们以一个简单的命令去讲解salt是如何处理。

salt ‘*‘ test.ping

这个首先会调用salt.cli.SaltCMD类实例化一个对象

主要代码如下:salt/cli/__init__.py

class SaltCMD(parsers.SaltCMDOptionParser):
    def run(self):
        ...    # 设置日志的
        # 调用salt.client.LocalClient api
        try:
            local = salt.client.LocalClient(self.get_config_file_path())
        except SaltClientError as exc:
            self.exit(2, ‘{0}\n‘.format(exc))
            return
         
        # self.options是命令行参数的集合
        # 通过optparse模块解析命令行参数
        # 批量执行的,salt -b
        if self.options.batch:
            batch = salt.cli.batch.Batch(self.config)
            # Printing the output is already taken care of in run() itself
            for res in batch.run():
                pass
         else:
             # 处理需要传递的参数,kwargs是参数字典,传递时使用**kwargs
             ....
             
             # 异步执行,不等待结果返回
            if self.config[‘async‘]:
                jid = local.cmd_async(**kwargs) # 返回jid
                print(‘Executed command with job ID: {0}‘.format(jid))
                return
            try:
                # 接下来是主要逻辑
                # 默认调用cmd_cli方法返回生成器,循环输出结果
                # 在cmd_cli里有个get_cli_event_returns方法会去调用gather_job_info
                # gather_job_info是去触发saltutil.find_job任务
                # 是去验证操作是否还在执行
                if local:
                    if self.options.subset: # 选择几个Minion调用cmd_cli
                        cmd_func = local.cmd_subset
                        kwargs[‘sub‘] = self.options.subset
                        kwargs[‘cli‘] = True
                    else:
                        cmd_func = local.cmd_cli

                    if self.options.static:
                        if self.options.verbose:
                            kwargs[‘verbose‘] = True
                        full_ret = local.cmd_full_return(**kwargs)
                        ret, out = self._format_ret(full_ret)
                        self._output_ret(ret, out)
                    elif self.config[‘fun‘] == ‘sys.doc‘:
                        ret = {}
                        out = ‘‘
                        for full_ret in local.cmd_cli(**kwargs):
                            ret_, out = self._format_ret(full_ret)
                            ret.update(ret_)
                        self._output_ret(ret, out)
                    else:
                        if self.options.verbose:
                            kwargs[‘verbose‘] = True
                        for full_ret in cmd_func(**kwargs):
                            ret, out = self._format_ret(full_ret)
                            self._output_ret(ret, out)

从上面代码片段我们知道SaltCMD主要是解析命令行参数,通过参数来决定调用salt.client.LocalClient的哪个方法,默认是调用cmd_cli方法。

那么真正处理操作的是LocalClient类,LocalClient主要包含的方法是cmd_*,get_*_returns,gather_job_info,run_job,pub。

首先学习下它怎么使用吧。使用的是ipython学习的

:import salt.client
# 初始化实例,参数必须是master的配置文件路径
:local = salt.client.LocalClient(‘/opt/app/salt/etc/master‘)
# cmd(tgt,fun,arg,expr_form=‘glob‘,...)
:local.cmd(‘192.168.110.132‘,‘test.ping‘)
#返回的结果
: {‘192.168.110.132‘: True}
# local.cmd_async(‘192.168.110.132‘,‘test.ping‘)
# 返回结果是个jid
: ‘20140813164423244819‘

cmd代码片段如下:

def cmd( 
            self,
            tgt,     # salt target ‘192.168.110.132‘ ‘os:Linux‘
            fun,     # 执行模块 test.ping
            arg=(),  # 模块参数
            timeout=None,
            expr_form=‘glob‘, # target的类型,
            ret=‘‘,    # returners
            kwarg=None,
            **kwargs):
     arg = condition_kwarg(arg, kwarg) # 将参数合并成一个列表
     # run_job返回的结果形式:
     #{‘jid‘: ‘20131219215650131543‘, ‘minions‘: [‘jerry‘,‘sdfsd‘,]}
     pub_data = self.run_job(tgt,
        fun,
        arg,
        expr_form,
        ret,
        timeout,
        **kwargs)
     if not pub_data:
        return pub_data
     
     # 需要等待timeout时间才会返回结果
     return self.get_returns(pub_data[‘jid‘],
        pub_data[‘minions‘],
        self._get_timeout(timeout))

其他的cmd_*形式都相似的,都会调用run_job方法,只不过返回结果不一样而已,比如cmd_async是异步执行的,不用等待,直接返回一个jid。cmd_cli返回的是生成器并会调用

gather_job_info方法去触发saltutil.find_job任务。cmd_cli是默认的处理方法。

run_job代码如下:

# run_job返回的结果形式:
# {‘jid‘: ‘20131219215650131543‘, ‘minions‘: [‘jerry‘,‘sdfsd‘,]}
def run_job(
            self,
            tgt,
            fun,
            arg=(),
            expr_form=‘glob‘,
            ret=‘‘,
            timeout=None,
            kwarg=None,
            **kwargs):
     arg = condition_kwarg(arg, kwarg)
     jid = ‘‘ # 这个可以自定义jid

     # Subscribe to all events and subscribe as early as possible
     self.event.subscribe(jid)    # 订阅event

     pub_data = self.pub(
            tgt,
            fun,
            arg,
            expr_form,
            ret,
            jid=jid,
            timeout=self._get_timeout(timeout),
            **kwargs)

      return self._check_pub_data(pub_data)

pub代码片段如下:

#payload_kwargs信息如下:
{
‘cmd‘: ‘publish‘,
‘tgt‘: tgt,
‘fun‘: fun,
‘arg‘: arg,
‘key‘: self.key,
‘tgt_type‘: expr_form,
‘ret‘: ret,
‘jid‘: jid,
‘user‘:‘root‘
}
master_uri = ‘tcp://‘ + salt.utils.ip_bracket(self.opts[‘interface‘]) +     ‘:‘ + str(self.opts[‘ret_port‘])
sreq = salt.transport.Channel.factory(self.opts, crypt=‘clear‘, master_uri=master_uri)

# 使用zeromq通信,使用的是rep/req socket
# payload信息
#{‘enc‘: ‘clear‘,
# ‘load‘: {‘jid‘: ‘20140807004713142582‘,
#  ‘minions‘: [‘192.168.79.47‘, ‘192.168.110.132‘, ‘192.168.110.133‘]}}

try:
    payload = sreq.send(payload_kwargs)
except SaltReqTimeoutError:
      log.error(
           ‘Salt request timed out. If this error persists, ‘
            ‘worker_threads may need to be increased.‘
       )
      return {}

讲了这么多,现在总结下流程。

salt ‘*‘ test.ping的流程,类似于卸妆的过程,看到最后的面目。

1、调用SaltCMD处理命令行参数,决定调用LocalClient的哪个方法(默认是cmd_cli)

2、调用LocalClient处理

3、默认调用cmd_cli方法处理

4、调用run_job方法处理

5、调用pub方法处理

6、使用zmq req/req socket通信

7、调用gather_job_info触发saltutil.find_job任务

8、一层层返回结果

从这个流程可知,其实最终调用的就是pub方法。

local.cmd_async(‘192.168.110.132‘,‘test.ping‘)
local.pub(‘192.168.110.132‘,‘test.ping‘)

salt命令行的API的讲解就到这里。

salt的api学习记录(一)

时间: 2024-08-04 03:42:07

salt的api学习记录(一)的相关文章

salt的api学习记录---minion的启动流程

最近在看minion的启动的源代码,一路曲折啊,经过一番努力,终于理解了流程.现在记录下,方便以后查阅. 总体来说流程如下: 1.解析命令行参数和minion配置文件,得到options和config字典 2.设置日志(salt.log.setup.setup_logfile_logger负责) 3.设置pidfile 4.根据master参数决定调用salt.minion.MultiMinion或者salt.minion.Minion初始化 5.调用tune_in方法 解析命令行参数和配置文件

salt的api学习记录---salt-cp命令的执行过程

最近重新看了下salt-cp实现的过程,源代码逻辑相对简单,明白了salt-cp为什么只能针对文本文件.配置文件的拷贝.现在就来看看对应的代码吧 源代码文件: salt/cli/cp.py class SaltCP(object):     def __init__(self, opts):         self.opts = opts          # 读取文件内容,返回单元素字典:文件名-->文件内容     def _file_dict(self, fn_):         ''

java.time包常用类API学习记录

Java8出来已那么多年了,java.time包之前一直没有使用过,最近正好有用到,在此做个记录. 上图列出了java.time包下的类,接下来我们详细看下其中每个类的用法. Clock:获取到当前时间点,包含时区信息,该类是抽象类,其实现类由其内部类实现,也可以自定义其实现类. Clock方法描述: getZone():获取创建日期时间的时区: withZone(ZoneId zone):返回一个指定时区clock副本: instant():返回instant实例: millis():获取当前

JAVA API 学习记录一 java.lang.*

Interface Appendable appendAppendable append(CharSequence csq)throws java.io.IOException向此 Appendable 追加指定的字符序列.有时可能没有追加整个序列,这取决于使用哪个类来实现字符序列 csq.例如,如果 csq 是 CharBuffer 的一个实例,则通过缓冲区的位置和限制来定义要追加的子序列.参数:csq - 要追加的字符串序列.如果 csq 为 null,则向该 Appendable 追加四个

Windows API 编程学习记录<二>

恩,开始写Windows API编程第二节吧. 上次介绍了几个关于Windows API编程最基本的概念,但是如果只是看这些概念,估计还是对Windows API不是很了解.这节我们就使用Windows API 让大家来了解下Windows API的用法. 第一个介绍的Windows API 当然是最经典的MessageBox,这个API 的作用就是在电脑上显示一个对话框,我们先来看看这个API的定义吧: int WINAPI MessageBox(HWND hWnd, LPCTSTR lpTe

Windows API 编程学习记录<三>

恩,开始写API编程的第三节,其实马上要考试了,但是不把这节写完,心里总感觉不舒服啊.写完赶紧去复习啊       在前两节中,我们介绍了Windows API 编程的一些基本概念和一个最基本API函数 MessageBox的使用,在这节中,我们就来正式编写一个Windows的窗口程序. 在具体编写代码之前,我们必须先要了解一下API 编写窗口程序具体的三个基本步骤:             1. 注册窗口类:             2.创建窗口:             3.显示窗口: 恩,

saltstack学习记录

安装 pip 安装 注意  依赖到zeromq3 minion过一段时间去请求master salt-api  可以访问salt去远程执行 ruby puppet   DSL配置   erb文件  模块  加载  模板支持最差 chef     定义直接是ruby代码   erb模板系统   原生支持 python saltstack   yaml配置文件    python程序模板   模板支持很好 python写模块 ipc 进程间通信 都使用key认证    安全 salt-key  -L

野兽的Angular Api 学习、翻译及理解 - - $anchorScroll、$controller、$document

野兽的ng api学习 -- $anchorScroll.$controller.$document $anchorScroll 根据HTML5的规则,当调用这个函数时,它检查当前的url的hash值并且滚动到相应的元素. 监听$location.hash()并且滚动到url指定的锚点的地方.可以通过$anchorScrollProvider.disableAutoScrolling()禁用. 依赖:$window   $location   $rootScope 使用:$anchorScrol

百度地图API学习之路(2)

(1)手势设定在 UiSettings 里面 UiSettings mUiSettings = mBaiduMap.getUiSettings();      mUiSettings.setZoomGesturesEnabled(true); //启用缩放手势      mUiSettings.setScrollGesturesEnabled(true); //启用平移手势      mUiSettings.setRotateGesturesEnabled(false); //关闭旋转手势