在盐执行模块中产生以在执行期间返回状态

时间:2014-10-15 14:47:39

标签: python yield salt-stack

我正在编写一些长期运行的盐执行模块,并希望监视这些模块的执行状态。例如,我使用该模块复制一个大小为TB的巨大文件,这可能需要几个小时。是否可以使用'yield'关键字返回进度,然后通过salt-api或salt-run查询此进度?这是一个例子:

from time import sleep
def longrunningmodule():
   yield 'Progress: 0%'
   sleep(100)
   yield 'Progress: 50%'
   sleep(100)
   yield 'Progress: 100%'

在这里运行salt模块:

$ salt 'node1' mytest.longrunningmodule --async
Executed command with job ID: 20141015143132465443

我是否可以使用此作业ID定期查询作业以检查进度?

2 个答案:

答案 0 :(得分:2)

我找到了间接的方法。虽然yield不会将结果发布到salt master,但salt事件总线可用于发布消息,而消息又可以通过salt-api访问。盐事件系统在此处描述http://docs.saltstack.com/en/latest/topics/event/index.html。更具体地说,这里提到从小兵到大师的射击事件:

http://docs.saltstack.com/en/latest/topics/event/index.html#firing-eventshttp://docs.saltstack.com/en/latest/topics/event/index.html#firing-events-from-code

此时第二种方式是错误的,不起作用。这在https://github.com/saltstack/salt/issues/8849描述。关于同一问题的评论之一描述了另一种方式:https://github.com/saltstack/salt/issues/8849#issuecomment-35973524

答案 1 :(得分:0)

简介

扩展the answer by dOps,进一步的研究使我基于SaltStack 事件反应器跑步者构建了一些东西。有关SaltStack相关术语的快速概述:

  • event 是从 minion master 的0MQ消息;
  • reactor 是一个SaltStack功能,允许在上运行(特殊) .sls 文件,作为反应(因此,名称, 对事件做出反应或);
  • runner 是一个可以在 master 上执行的Python脚本(与模块类似,可以在 minions上运行< / em>的)。

步骤

SaltStack 2014.7中,我构建了如下:

  1. 从模块发出事件 - 我看起来像下面的示例测试模块(例如SALT_ROOT/_modules/mymodule.py)。您可以使用sudo salt-run state.event(IIRC)在主服务器上查看它们以进行初始调试。

    def test(name=None):
            __salt__['event.send']('my_prefix/tester/mytest', {
                    'foo': 'bar',
                    'baz': True,
            })
            return "test done!"
    
  2. 修改/etc/salt/master并添加如下所示的块,然后重新启动 salt-master (例如sudo restart salt-master)。这样就可以注册自定义跑步者:

    # Add any additional locations to look for master runners:
    runner_dirs: ["MY_RUNNER_PATH"]
    
  3. 创建MY_RUNNER_PATH/save.py - 最终将事件记录到/tmp/salt-monitor文件的跑步者。您可以使用sudo salt-run save.data(IIRC)进行测试:

    import json
    import pprint
    
    def data(tag_pprint, data_pprint):
        contents = {}
        if not pprint.isreadable(tag_pprint):
            raise Exception(
                'param tag_pprint not readable: {0}'.format(tag_pprint))
        if not pprint.isreadable(data_pprint):
            raise Exception(
                'param data_pprint not readable: {0}'.format(data_pprint))
        contents = {
            'tag': eval(tag_pprint),
            'data': eval(data_pprint),
        }
        with open('/tmp/salt-monitor','ab') as f:
            f.write(json.dumps(contents)+"\n")
    
  4. 如下创建/etc/salt/master.d/reactor.conf文件(或者,据报道,这可以放在主/etc/salt/master配置文件中)。这将让我们将事件传递给我们在上面创建的跑步者。如果你将salt-master的日志级别设置为“调试”,你可以对此进行一些调试,但即便如此,日志中的信息也很少。我想你不必在这里重置salt-master,但不确定。 注意:缩进中的空格非常重要,这是YAML - 每个缩进级别有2个空格:

    reactor:
      - 'salt/job/*':
        - MY_REACTOR_PATH/save_event.sls
      - 'my_prefix/*':
        - MY_REACTOR_PATH/save_event.sls
    
  5. 创建MY_REACTOR_PATH/save_event.sls,如下所示。注意:我相信您必须在以后第一次更改此文件后重新启动salt-master。这可以类似于上面的第(4)点进行调试。

    event_save:
      runner.save.data:
        - tag_pprint: |
            {{ tag|pprint|replace("\n","\n        ") }}
        - data_pprint: |
            {{ data|pprint|replace("\n","\n        ") }}
    
  6. 日志

    理想情况下,使用日志级别&#39; debug&#39;在master上,你应该在/var/log/salt/master的日志中有一堆如下所示的行(它们可能与其他一些东西混合在一起,在下面的示例中,其中一些被...替换):

    2015-12-08 19:01:40,483 [salt.utils.event ][DEBUG   ] Sending event - data = {'_stamp': '2015-12-08T19:01:40.482376', 'pretag': None, 'cmd': '_minion_event', 'tag': 'my_prefix/tester/mytest', 'data': {'foo': 'bar', 'baz': True}, 'id': 'vbox-mc'}
    ...
    2015-12-08 19:01:40,491 [salt.utils.event ][DEBUG   ] Gathering reactors for tag my_prefix/tester/mytest
    2015-12-08 19:01:40,491 [salt.utils.event ][DEBUG   ] Compiling reactions for tag my_prefix/tester/mytest
    ...
    2015-12-08 19:01:40,498 [salt.template    ][DEBUG   ] Rendered data from file: /home/akavel/salt/reactors/save_event.sls:
    event_save:
      runner.save.data:
        - tag_pprint: |
            u'my_prefix/tester/mytest'
        - data_pprint: |
            {'_stamp': '2015-12-08T19:01:40.482376',
             'cmd': '_minion_event',
             'data': {'baz': True, 'foo': 'bar'},
             'id': 'vbox-mc',
             'pretag': None,
             'tag': 'my_prefix/tester/mytest'}
    
    
    2015-12-08 19:01:40,501 [salt.loaded.int.render.yaml][DEBUG   ] Results of YAML rendering:
    OrderedDict([('event_save', OrderedDict([('runner.save.data', [OrderedDict([('tag_pprint', "u'my_prefix/tester/mytest'\n")]), OrderedDict([('data_pprint', "{'_stamp': '2015-12-08T19:01:40.482376',\n 'cmd': '_minion_event',\n 'data': {'baz': True, 'foo': 'bar'},\n 'id': 'vbox-mc',\n 'pretag': None,\n 'tag': 'my_prefix/tester/mytest'}\n")])])]))])