ansible 非常好用,在目标机不安装任何agent的情况下,可以用简单的yaml语法实现复杂的运维功能。最近我有一个需求,需要调用jar包实现,但是目标机是空白的机器,上面没有安装jdk,只有系统和python。此时应该怎么做呢?

方案

开始的想法是实现一个ansible module,这个module先在ansible 控制机上完成jar包的运行,然后将jar包的运行结果拷贝到目标机上去。写了一些代码验证后发现ansible的module是在目标机上执行的,原有方案行不通。
阅读了ansible的相关资料后,采用了以下方案:

  1. 实现一个 ansible action plugin,action plugin是在 ansible 控制机上执行的,它会在控制机上运行jar。

  2. 实现一个 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.


阮粳籼
162 声望29 粉丝

hello world


引用和评论

0 条评论