You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible中获取最高版本Worker文件并传递给script模块?

问题:自动选择版本号最高的Worker脚本执行

我在Ansible控制节点的scripts目录下有多个形如Worker1_0、Worker1_5、Worker2_1的文件,文件名中的数字对应版本号。需要编写一个Role,自动定位该目录下版本号最高的文件,并通过script模块在远程节点执行它。


已尝试的操作及问题

1. 查找匹配文件

使用find模块获取所有符合Worker*模式的文件:

- name: Find Worker
  find:
    paths: "{{ scripts_path }}"
    patterns: "Worker*"
    file_type: file
  register: worker
  delegate_to: localhost
  run_once: true

该任务成功返回了目标文件列表。

2. 整理并排序文件路径

尝试通过过滤器整理路径并排序:

- name: Show Output
  debug:
    msg: {{ worker | json_query('files[*].path') | sort | reverse }}

输出结果如下,看似完成了排序,但不确定该方式是否正确:

ok: [SERVER] => {
    "msg": [
        "/srv/git/scripts/Worker3_8",
        "/srv/git/scripts/Worker3_5"
    ]
}

3. 尝试执行最高版本脚本失败

使用with_first_found传递排序后的列表时报错:

- name: Execute Script on Remote server
  ansible.builtin.script:
    cmd: "{{ item }} "
  with_first_found: "{{ worker | json_query('files[*].path') | sort | reverse }}"
  register: script_output

错误信息:

FAILED! => {"msg": "No file was found when using first_found."}

解决方案

核心问题解析

  1. 字符串排序的局限性:直接用sort | reverse是按字符串字典序排序,若版本号出现两位数(如Worker1_10),会出现Worker1_10排在Worker1_2之后的错误,因为字符串比较中"10"小于"2"。
  2. with_first_found用法错误:该查找器默认在远程节点查找文件,而目标脚本位于控制节点,因此无法找到文件。

正确实现步骤

步骤1:按版本号数值排序文件

通过拆分文件名提取版本号,转换为整数后排序,确保数值排序逻辑正确:

- name: Sort Worker scripts by version number
  set_fact:
    sorted_worker_scripts: "{{ worker.files | sort(
        attribute='basename',
        key=lambda fname: [
            int(fname.basename.split('_')[1]),
            int(fname.basename.split('_')[2].split('.')[0])
        ],
        reverse=True
    ) }}"
  delegate_to: localhost
  run_once: true

注:这里假设文件名严格遵循WorkerX_Y格式,拆分出主版本X和次版本Y并转为整数排序。

步骤2:获取最新版本脚本路径

- name: Get path of latest Worker script
  set_fact:
    latest_worker_script: "{{ sorted_worker_scripts[0].path }}"
  delegate_to: localhost
  run_once: true

步骤3:在远程节点执行脚本

直接传入最新脚本路径到script模块:

- name: Execute latest Worker script on remote
  ansible.builtin.script:
    cmd: "{{ latest_worker_script }}"
  register: script_output

简化方案(适用于版本号无多位数场景)

如果可以确保版本号不会出现两位数导致的排序问题,可直接取排序后的第一个元素:

- name: Get latest Worker script path
  set_fact:
    latest_worker_script: "{{ worker | json_query('files[*].path') | sort | reverse | first }}"
  delegate_to: localhost
  run_once: true

- name: Execute latest Worker script
  ansible.builtin.script:
    cmd: "{{ latest_worker_script }}"
  register: script_output

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 22:12:47