是否可以在Ansible中捕获和处理SSH连接错误?

是否可以在Ansible中捕获和处理SSH连接错误?,ansible,ansible-playbook,Ansible,Ansible Playbook,我正在使用ansible升级网络设备的软件。安装完成后,我重新启动盒子,使用ansible的wait_for模块等待SSH恢复,然后使用do-until循环运行命令并等待特定的输出字符串: - name: Wait for box to come back up local_action: wait_for host={{ ansible_ssh_host | default(inventory_hostname) }} search_regex=OpenSSH po

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

- 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连接超时的错误

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   
TASK:[appliance|等待box重新启动]*********************************************
远程模块等待主机=10.1.1.1搜索\u regex=OpenSSH端口=22延迟=20超时=600
确定:[10.1.1.1->127.0.0.1]=>{“更改”:false,“经过”:93,“路径”:null,“端口”:22,“搜索正则表达式”:“OpenSSH”,“状态”:“已启动”}
任务:[设备|等待box进入运行阶段]************************************************
远程模块命令tmsh-q-a显示系统mcp使用外壳
运行1的结果是:{'cmd':'tmsh-q-a show sys mcp','end':'2015-10-01 10:58:27.025674','stdout':u','changed','True','threads':1',start':'2015-10-01 10:58:26.928485','delta':'0:00:00.097189','stderr':'无法连接到mcpd','rc':1','warnings':[]
--剪下重复的线条--
远程模块命令tmsh-q-a显示系统mcp使用外壳
致命:[10.1.1.1]=>SSH错误:SSH:连接到主机10.1.1.1端口22:连接超时
连接到10.1.1.1:22时
使用-vvv重新运行命令有时很有用,它会打印SSH调试输出以帮助诊断问题。
致命:所有主机都已失败--正在中止
播放重述*********************************************************************************************************
要重试,请使用:--limit@/home/loudsong/play.retry
10.1.1.1:正常=25更改=4无法访问=1失败=0

所以我真正需要的是让我的任务
等待box进入运行阶段
循环,直到它最终成功,不管目标设备是否完全无法访问。如果我能够捕捉到SSH连接错误,然后执行另一个
wait_for
任务,等待该框完成第二个重新启动周期,我也会很高兴。有人有什么建议吗?

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

- 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\u runner\u on_unreachable():

是否有任何编程方法可以知道该框将再次重新启动?如果我跟踪日志消息,我可以看到固件更新正在进行,因此很快就会再次重新启动。我想我可以等到它再次无法访问,然后开始第二次轮询。这并不是我想要做的:-/我更想的是,当它决定重新启动时,但在实际重新启动之前,它是否在任何地方记录了任何东西?