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

如何通过Ansible在更新APT包时记录更新前后的版本到文件

如何通过Ansible在更新APT包时记录更新前后的版本到文件

哈哈,这个需求太实用了!我之前维护服务器的时候也经常需要记录包更新的版本变更,APT模块本身确实不会主动返回这些信息,不过咱们可以拆成几个步骤来实现,稳得很:

核心思路就是先查版本、再更包、再查版本、最后写记录,用dpkg-query来精准获取包版本(比解析APT输出靠谱多了),具体来看完整的Playbook示例:

---
- name: 升级包并记录版本变更
  hosts: your_target_hosts
  become: yes  # 需要root权限执行APT操作和写入系统日志路径
  vars:
    packages:
      - nginx
      - curl  # 替换成你要升级的包列表
    version_log_file: /var/log/package_upgrade_history.log  # 日志文件路径,可自定义

  tasks:
    - name: 获取升级前的包版本
      ansible.builtin.command: dpkg-query -W -f='${Package}\t${Version}' {{ item }}
      register: pre_upgrade_versions
      loop: "{{ packages }}"
      changed_when: false  # 这个操作不会修改系统,标记为无状态变更

    - name: 执行包升级操作
      ansible.builtin.apt:
        name: "{{ item }}"
        state: latest
        update_cache: true
        only_upgrade: true
      loop: "{{ packages }}"
      register: upgrade_results

    - name: 获取升级后的包版本
      ansible.builtin.command: dpkg-query -W -f='${Package}\t${Version}' {{ item }}
      register: post_upgrade_versions
      loop: "{{ packages }}"
      changed_when: false

    - name: 将版本变更记录写入日志文件
      ansible.builtin.lineinfile:
        path: "{{ version_log_file }}"
        line: "{{ ansible_date_time.iso8601 }} - 包名: {{ item.0.item }} | 升级前版本: {{ item.0.stdout.split('\t')[1] }} | 升级后版本: {{ item.1.stdout.split('\t')[1] }}"
        create: true  # 如果日志文件不存在则自动创建
      loop: "{{ pre_upgrade_versions.results | zip(post_upgrade_versions.results) | list }}"
      when: item.0.stdout.split('\t')[1] != item.1.stdout.split('\t')[1]  # 只记录确实发生版本变化的包

几个实用的小细节:

  • 只记录变更:最后一步的when条件会过滤掉没有版本变化的包,避免日志冗余;如果需要记录所有包(哪怕没更新),删掉这个条件就行。
  • 自定义日志格式:你可以把line字段改成自己喜欢的格式,比如JSON格式方便后续脚本解析:
    line: '{"timestamp": "{{ ansible_date_time.iso8601 }}", "package": "{{ item.0.item }}", "pre_version": "{{ item.0.stdout.split('\t')[1] }}", "post_version": "{{ item.1.stdout.split('\t')[1] }}"}'
    
  • 权限问题:如果日志路径是系统目录(比如/var/log),一定要加上become: yes确保有写入权限。
  • 处理未安装包:如果你的packages列表里可能有未安装的包,可以在第一步加个failed_when: false,然后在后续步骤判断是否已安装,不过你的only_upgrade: true配置已经确保只会处理已安装包,所以这个可以不用额外处理。

备注:内容来源于stack exchange,提问作者idiot one

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:28:08