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

如何用Ansible的get_url模块幂等性下载并更新二进制文件?

问题

我想用Ansible的get_url模块幂等性地下载二进制文件,编写的Playbook如下:

- name: calculate hash for existing file
  stat:
    path: /usr/bin/yq
    checksum_algorithm: sha256
  register: resultStat

- name: (re)download file
  become: true
  get_url:
    url: https://github.com/mikefarah/yq/releases/download/v4.34.1/yq_linux_amd64
    #url: https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
    dest: /usr/bin/yq
    checksum: "{{ '' if not resultStat.stat.exists else 'sha256:' + resultStat.stat.checksum }}"
    #force: true
    owner: root
    group: root
    mode: '0755'

首次运行及重复运行时均正常,具备幂等性。但将下载链接切换为指向latest版本的链接后,期望旧文件被删除并下载新版本。根据Ansible官方文档描述:

若传递checksum参数且目标位置存在文件,会计算目标文件的校验和;若与传入的checksum一致则跳过下载(除非force为true);若不一致则删除目标文件。

实际测试中,添加force: true时旧文件会被删除,但随后报错“The checksum for /usr/bin/yq did not match ...”;不添加force: true时,文件完全不会更新。请问该如何解决此问题?

解决方案

问题核心在于:使用latest版本链接时,你传递的checksum是本地旧文件的哈希值,而下载的新版本文件哈希必然和旧文件不一致,导致校验失败。要实现自动更新到latest版本并保持幂等性,需获取最新版本对应的官方校验值,再用该值进行下载校验。

方法1:动态获取最新版本的校验和(推荐)

修改Playbook,先从GitHub官方接口获取yq最新版本的sha256校验值,再传递给get_url模块:

- name: Get latest yq release info
  uri:
    url: https://api.github.com/repos/mikefarah/yq/releases/latest
    return_content: true
  register: yq_latest_release

- name: Extract yq_linux_amd64 sha256 checksum
  set_fact:
    yq_checksum: "{{ yq_latest_release.json.body | regex_search('yq_linux_amd64.sha256: (\\w+)', '\\1') | first }}"

- name: Download or update yq to latest version
  become: true
  get_url:
    url: https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
    dest: /usr/bin/yq
    checksum: "sha256:{{ yq_checksum }}"
    owner: root
    group: root
    mode: '0755'

逻辑说明:

  • 通过GitHub API获取最新release的详情,其中包含各平台文件的校验和
  • 提取对应架构文件的sha256值
  • 用官方校验值执行下载,只有当本地文件与最新版本校验值不一致时,才会重新下载,完全符合幂等性要求

方法2:跳过本地校验,依赖HTTP标识(不推荐)

如果不想动态获取校验和,可以设置force: true并移除checksum参数,让get_url依赖HTTP的ETag或文件大小判断是否更新:

- name: (re)download latest yq
  become: true
  get_url:
    url: https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
    dest: /usr/bin/yq
    force: true
    owner: root
    group: root
    mode: '0755'

这种方法可靠性较低,因为ETag或文件大小可能不会随版本更新而变化,导致无法正确触发更新。

原方法失效原因

  • 不加force: true时:get_url发现本地文件哈希与你传递的旧哈希一致,直接跳过下载,不会检查远程文件是否更新
  • 加force: true时:虽然会删除旧文件并下载新文件,但下载完成后会用旧文件的哈希校验新文件,自然不匹配而报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:35:23