返回

Ansible win_package 卸载 Chrome rc=19 错误排查与解决

windows

Ansible 使用 win_package 卸载 Chrome 时 rc=19 错误

问题

在使用 Ansible 的 win_package 模块尝试卸载 Google Chrome 时,即使程序实际已成功卸载,任务仍会返回 rc=19 错误代码。 这种非预期行为导致 Ansible 流程异常中断, 需要深入了解其原因并解决。 rc=19 代表的意义,以及如何排除此种特定情况的故障,是一个值得研究的课题。

问题分析

rc=19 错误码通常与安装或者卸载过程中,接收到错误的参数信息有关。尤其是在使用 Microsoft Installer (MSI) 或者其他 Windows 应用程序安装包时。 当直接执行 Chrome 的卸载程序,通过 Start-Process 调用,同样可以获得此代码,可以推测这并非是 win_package 模块的错误, 而是Chrome 卸载程序的正常行为,但此行为不应视为执行失败。

在提供的 Ansible 剧本中,关键点包括:通过 PowerShell 获取卸载信息(Get-ItemProperty), 提取 product ID 与卸载路径,以及使用 win_package 模块执行卸载。 其中使用了 --uninstall --multi-install --system-level --force-uninstall 这些卸载参数, 此类参数是 Chrome 自带卸载器的常见参数。由于 win_package 会根据返回代码判断任务的成功或失败,rc=19 造成了误判。

问题根源不在于 Chrome 未被卸载, 而在于 win_package 模块把 Chrome 卸载器 返回的 rc=19 代码解读为错误。

解决方案

以下方法可以规避 rc=19 造成的错误报告问题,并提供可操作的 Ansible 部署实践。

方案一:忽略特定返回码

通过 ignore_errors 来忽略特定错误代码,是一种快速简单的处理方式。 在任务执行时,只要输出结果达到目标要求(如:程序被正确卸载),即使 rc 返回非零值,也不应被认为是任务失败。 此方案的核心是在 Ansible 任务级别指定可以忽略的 rc 码,这在处理预期会返回非零码的情况时很有用。

    - name: Uninstall program with route (ignore rc=19)
      win_package:
        path: '{{uninstall_path}}'
        product_id: "{{product_id}}"
        arguments: '--uninstall --multi-install --system-level --force-uninstall'
        state: absent
      register: status
      ignore_errors: true
      failed_when: "status.rc != 0 and status.rc != 19"

操作步骤:

  1. 修改 win_package 任务定义。
  2. ignore_errors: true 添加至任务配置中。
  3. 添加 failed_when: "status.rc != 0 and status.rc != 19" 来实现只在 rc != 0 以及 rc != 19 时失败。

安全性考虑: 使用 ignore_errors 需要谨慎,如果忽略了 rc=0 外的其他错误码, 有可能会掩盖其他的故障。 这里增加了failed_when 条件来进行优化。

方案二:使用 PowerShell 脚本执行卸载

可以通过 PowerShell 命令执行卸载操作,并手动检测返回码。 该方案相对复杂,但是提供了更高的控制性。
这种方式允许使用 Start-Process 执行程序,然后检查 $LASTEXITCODE 变量,可以灵活判断结果,可以配合 win_shell 执行。

    - name: Uninstall Google Chrome via PowerShell
      ansible.windows.win_powershell:
        script: |
            $process = Start-Process -FilePath "{{uninstall_path}}" -ArgumentList '--uninstall --multi-install --system-level --force-uninstall' -Wait -PassThru
            $exitCode = $process.ExitCode
            if ($exitCode -eq 0 -or $exitCode -eq 19) {
               Write-Output "Successfully uninstalled or specific return code 19"
            } else {
               Write-Error "Uninstall failed with code: $exitCode"
               exit 1
            }
      register: uninstall_result
      failed_when: uninstall_result.failed

操作步骤:

  1. 使用 ansible.windows.win_powershell 执行 PowerShell 脚本。
  2. PowerShell 脚本中用 Start-Process 启动卸载程序。
  3. 获取 $process.ExitCode 的返回值,使用 if 条件来检测 $exitCode 的值, 成功则输出 “Successfully uninstalled” 信息, 否则将错误输出, 并退出。
  4. register 结果并设置 failed_when: uninstall_result.failed 来配合输出结果判断状态。

安全性考虑: 此方法需要编写和维护额外的 PowerShell 脚本。 应当严格审查任何外部执行脚本内容,保证其安全和可控性。

结论

在尝试通过 Ansible 的 win_package 模块卸载 Google Chrome 时遭遇的 rc=19 问题,源于卸载器自身的特定返回码。 针对此问题,本文提供了两种解决方案,可以根据实际场景选用:简单地忽略特定返回码,或者通过更灵活的 PowerShell 脚本进行卸载。 每种方案都提供了详细的步骤说明与代码示例。选择哪一种方法需要依据 Ansible 使用经验,安全性和维护成本等进行权衡, 请仔细评估后采用最合适的实践。