ansible 非常好用,在目标机不安装任何agent的情况下,可以用简单的yaml语法实现复杂的运维功能。最近我有一个需求,需要调用jar包实现,但是目标机是空白的机器,上面没有安装jdk,只有系统和python。此时应该怎么做呢?
方案
开始的想法是实现一个ansible module,这个module先在ansible 控制机上完成jar包的运行,然后将jar包的运行结果拷贝到目标机上去。写了一些代码验证后发现ansible的module是在目标机上执行的,原有方案行不通。
阅读了ansible的相关资料后,采用了以下方案:
实现一个 ansible action plugin,action plugin是在 ansible 控制机上执行的,它会在控制机上运行jar。
实现一个 ansible role,这个role做两件事情。
调用刚实现的 action plugin,然后记录结果到某个文件;并通过 ansible copy将结果文件拷贝到目标机。
action plugin
action plugin是一种特殊的module,它在控制机上运行,实现模版如下,可以在处理逻辑处写上自己的处理代码。可以根据自己的处理结果填写result字典,如果失败要填写result['failed'],修改成功了要填写result['changed']。
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
# 调用 ActionBase的run
if task_vars is None:
task_vars = dict()
result = super(ActionModule, self).run(tmp, task_vars)
# 获取入参
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
# 失败填写返回结果
if dest is not None:
result['failed'] = True
result['msg'] = "'dest' cannot be specified on a template"
# 处理逻辑
# 成功填写返回结果
result['changed'] = True
result['msg'] = "change success"
return result
action plugin存放路径
自定义的plugin,需要配置ansible.cfg,在其中填写action_plugins参数。
action_plugins = /myplugin/action_plugins
如果这个plugin的复用性不强,像本方案,会定义一个role使用它,那么我建议直接在该role下创建一个action_plugins目录,把刚实现的action plugin的py文件放到这个目录下,可以减少一个配置项。
用role粘合action plugin和copy
我也可以在action plugin中用python实现copy到目标机的功能,重复造轮子意义不大,ansible 的role可以把多种要素粘合起来,被外面调用,调用者不用关注role的实现细节。
---
- name: run my jar
action: myplugin src="/home/my.jar" dest="/home/result.txt"
- name: copy result file to target
copy:
src: "/home/result.txt"
dest: "/tmp/myjar/result.txt"
结语
这是我的一次尝试,大家有什么新的思路可以回帖给我,很希望和大家一起来学习ansible.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。