我正在编写一些长期运行的盐执行模块,并希望监视这些模块的执行状态。例如,我使用该模块复制一个大小为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定期查询作业以检查进度?
答案 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-events和http://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相关术语的快速概述:
在SaltStack 2014.7中,我构建了如下:
从模块发出事件 - 我看起来像下面的示例测试模块(例如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!"
修改/etc/salt/master
并添加如下所示的块,然后重新启动 salt-master (例如sudo restart salt-master
)。这样就可以注册自定义跑步者:
# Add any additional locations to look for master runners:
runner_dirs: ["MY_RUNNER_PATH"]
创建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")
如下创建/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
创建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 ") }}
理想情况下,使用日志级别' debug'在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")])])]))])