是否有可能在Ansible中捕获并处理SSH连接错误?

时间:2015-10-01 21:06:57

标签: ansible ansible-playbook

我正在使用ansible来升级网络设备的软件。安装完成后,我重新启动该框,然后使用ansible的wait_for模块等待SSH重新启动,然后使用do-until循环运行命令并等待特定的输出字符串:< / p>

- name: Wait for box to come back up
  local_action: wait_for host={{ ansible_ssh_host | default(inventory_hostname) }}
      search_regex=OpenSSH
      port=22
      delay=20
      timeout=600

- name: Wait for box to enter the running phase
  shell: tmsh -q -a show sys mcp
  changed_when: False
  ignore_errors: True
  register: mcp_wait
  until: mcp_wait.stdout.find("running") != -1
  retries: 1200
  delay: 10

问题是,对于某些软件升级,设备将重启两次。它启动,SSH启动,然后安装一些固件更新,并再次重新启动。这导致我的剧本错误。 wait_for任务成功,然后do-until任务开始循环,但第二次重启该框会导致此do-until命令失败并出现SSH Connection timed out错误。

TASK: [appliance | Wait for box to come back up] ******************************* 
<127.0.0.1> REMOTE_MODULE wait_for host=10.1.1.1 search_regex=OpenSSH port=22 delay=20 timeout=600
ok: [10.1.1.1 -> 127.0.0.1] => {"changed": false, "elapsed": 93, "path": null, "port": 22, "search_regex": "OpenSSH", "state": "started"}

TASK: [appliance | Wait for box to enter the running phase] *********************************** 
<10.1.1.1> REMOTE_MODULE command tmsh -q -a show sys mcp #USE_SHELL
Result from run 1 is: {'cmd': 'tmsh -q -a show sys mcp', 'end': '2015-10-01 10:58:27.025674', 'stdout': u'', 'changed': True, 'attempts': 1, 'start': '2015-10-01 10:58:26.928485', 'delta': '0:00:00.097189', 'stderr': 'Cannot connect to mcpd.', 'rc': 1, 'warnings': []}
--snipped repeated lines--
<10.1.1.1> REMOTE_MODULE command tmsh -q -a show sys mcp #USE_SHELL
fatal: [10.1.1.1] => SSH Error: ssh: connect to host 10.1.1.1 port 22: Connection timed out
    while connecting to 10.1.1.1:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/loudsong/play.retry

10.1.1.1               : ok=25   changed=4    unreachable=1    failed=0   

所以我真正需要的是让我的任务Wait for box to enter the running phase循环,直到它最终成功,无论目标设备是否完全无法访问。如果我能抓住SSH连接错误,然后执行另一个wait_for任务以等待该框完成第二个重启循环,我也会很高兴。有人有任何建议吗?

1 个答案:

答案 0 :(得分:2)

我最终解决的问题是将操作转换为本地操作:

- name: Wait till MCP enters the running phase
  local_action: command sshpass -p "{{ansible_ssh_pass|default('')}}" ssh root@{{inventory_hostname}} tmsh -q -a show sys mcp
  changed_when: False
  register: mcp_wait
  until: mcp_wait.stdout.find("running") != -1
  retries: 300

这样,任务将继续循环,尝试通过SSH远程执行命令,直到它在stdout中发现“正在运行”,即使该框无法访问。

顺便说一句,我确实看到Ansible允许你编写回调,这似乎可以让你捕获'无法访问'的事件。虽然我没有足够的追求,以确保它能解决我在问题中描述的问题。请参阅函数v2_runner_on_unreachable(): https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/callback/default.py