Revert "Fix prompt mismatch issue for ios (#47004)"
This reverts commit 17cd01589a
.
This commit was not passing CI. Reverting
This commit is contained in:
parent
44ae37d78b
commit
7812c065f4
4 changed files with 9 additions and 111 deletions
|
@ -1,2 +0,0 @@
|
|||
bugfixes:
|
||||
- Fix prompt mismatch issue for ios (https://github.com/ansible/ansible/issues/47004)
|
|
@ -656,38 +656,3 @@ Example Ansible inventory file
|
|||
This is done to prevent secrets from leaking out, for example in ``ps`` output.
|
||||
|
||||
We recommend using SSH Keys, and if needed an ssh-agent, rather than passwords, where ever possible.
|
||||
|
||||
Miscellaneous Issues
|
||||
====================
|
||||
|
||||
|
||||
Intermittent failure while using ``network_cli`` connection type
|
||||
----------------------------------------------------------------
|
||||
|
||||
If the command prompt received in response is not matched correctly within
|
||||
the ``network_cli`` connection plugin the task might fail intermittently with truncated
|
||||
response or with the error message ``operation requires privilege escalation``.
|
||||
Starting in 2.7.1 a new buffer read timer is added to ensure prompts are matched properly
|
||||
and a complete response is send in output. The timer default value is 0.2 seconds and
|
||||
can be adjusted on a per task basis or can be set globally in seconds.
|
||||
|
||||
Example Per task timer setting
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: gather ios facts
|
||||
ios_facts:
|
||||
gather_subset: all
|
||||
register: result
|
||||
vars:
|
||||
ansible_buffer_read_timeout: 2
|
||||
|
||||
|
||||
To make this a global setting, add the following to your ``ansible.cfg`` file:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[persistent_connection]
|
||||
buffer_read_timeout = 2
|
||||
|
||||
This timer delay per command executed on remote host can be disabled by setting the value to zero.
|
||||
|
|
|
@ -157,21 +157,6 @@ options:
|
|||
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT
|
||||
vars:
|
||||
- name: ansible_command_timeout
|
||||
persistent_buffer_read_timeout:
|
||||
type: float
|
||||
description:
|
||||
- Configures, in seconds, the amount of time to wait for the data to be read
|
||||
from Paramiko channel after the command prompt is matched. This timeout
|
||||
value ensures that command prompt matched is correct and there is no more data
|
||||
left to be received from remote host.
|
||||
default: 0.1
|
||||
ini:
|
||||
- section: persistent_connection
|
||||
key: buffer_read_timeout
|
||||
env:
|
||||
- name: ANSIBLE_PERSISTENT_BUFFER_READ_TIMEOUT
|
||||
vars:
|
||||
- name: ansible_buffer_read_timeout
|
||||
"""
|
||||
|
||||
import getpass
|
||||
|
@ -179,7 +164,6 @@ import json
|
|||
import logging
|
||||
import re
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import traceback
|
||||
|
||||
|
@ -199,10 +183,6 @@ except ImportError:
|
|||
display = Display()
|
||||
|
||||
|
||||
class AnsibleCmdRespRecv(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Connection(NetworkConnectionBase):
|
||||
''' CLI (shell) SSH connections on Paramiko '''
|
||||
|
||||
|
@ -219,7 +199,6 @@ class Connection(NetworkConnectionBase):
|
|||
self._matched_pattern = None
|
||||
self._last_response = None
|
||||
self._history = list()
|
||||
self._command_response = None
|
||||
|
||||
self._terminal = None
|
||||
self.cliconf = None
|
||||
|
@ -363,39 +342,15 @@ class Connection(NetworkConnectionBase):
|
|||
'''
|
||||
Handles receiving of output from command
|
||||
'''
|
||||
self._matched_prompt = None
|
||||
self._matched_cmd_prompt = None
|
||||
recv = BytesIO()
|
||||
handled = False
|
||||
command_prompt_matched = False
|
||||
|
||||
self._matched_prompt = None
|
||||
self._matched_cmd_prompt = None
|
||||
matched_prompt_window = window_count = 0
|
||||
|
||||
command_timeout = self.get_option('persistent_command_timeout')
|
||||
self._validate_timeout_value(command_timeout, "persistent_command_timeout")
|
||||
|
||||
buffer_read_timeout = self.get_option('persistent_buffer_read_timeout')
|
||||
self._validate_timeout_value(buffer_read_timeout, "persistent_buffer_read_timeout")
|
||||
|
||||
while True:
|
||||
if command_prompt_matched:
|
||||
try:
|
||||
signal.signal(signal.SIGALRM, self._handle_buffer_read_timeout)
|
||||
signal.setitimer(signal.ITIMER_REAL, buffer_read_timeout)
|
||||
data = self._ssh_shell.recv(256)
|
||||
signal.alarm(0)
|
||||
# if data is still received on channel it indicates the prompt string
|
||||
# is wrongly matched in between response chunks, continue to read
|
||||
# remaining response.
|
||||
command_prompt_matched = False
|
||||
|
||||
# restart command_timeout timer
|
||||
signal.signal(signal.SIGALRM, self._handle_command_timeout)
|
||||
signal.alarm(command_timeout)
|
||||
|
||||
except AnsibleCmdRespRecv:
|
||||
return self._command_response
|
||||
else:
|
||||
data = self._ssh_shell.recv(256)
|
||||
data = self._ssh_shell.recv(256)
|
||||
|
||||
# when a channel stream is closed, received data will be empty
|
||||
if not data:
|
||||
|
@ -421,11 +376,7 @@ class Connection(NetworkConnectionBase):
|
|||
if self._find_prompt(window):
|
||||
self._last_response = recv.getvalue()
|
||||
resp = self._strip(self._last_response)
|
||||
self._command_response = self._sanitize(resp, command)
|
||||
if buffer_read_timeout == 0.0:
|
||||
return self._command_response
|
||||
else:
|
||||
command_prompt_matched = True
|
||||
return self._sanitize(resp, command)
|
||||
|
||||
def send(self, command, prompt=None, answer=None, newline=True, sendonly=False, prompt_retry_check=False, check_all=False):
|
||||
'''
|
||||
|
@ -447,17 +398,6 @@ class Connection(NetworkConnectionBase):
|
|||
display.vvvv(traceback.format_exc(), host=self._play_context.remote_addr)
|
||||
raise AnsibleConnectionFailure("timeout trying to send command: %s" % command.strip())
|
||||
|
||||
def _handle_buffer_read_timeout(self, signum, frame):
|
||||
display.vvvv("Response received, triggered 'persistent_buffer_read_timeout' timer of %s seconds"
|
||||
% self.get_option('persistent_buffer_read_timeout'), host=self._play_context.remote_addr)
|
||||
raise AnsibleCmdRespRecv()
|
||||
|
||||
def _handle_command_timeout(self, signum, frame):
|
||||
msg = 'command timeout triggered, timeout value is %s secs.\nSee the timeout setting options in the Network Debug and Troubleshooting Guide.'\
|
||||
% self.get_option('persistent_command_timeout')
|
||||
display.display(msg, log_only=True)
|
||||
raise AnsibleConnectionFailure(msg)
|
||||
|
||||
def _strip(self, data):
|
||||
'''
|
||||
Removes ANSI codes from device response
|
||||
|
@ -548,7 +488,3 @@ class Connection(NetworkConnectionBase):
|
|||
raise AnsibleConnectionFailure(errored_response)
|
||||
|
||||
return False
|
||||
|
||||
def _validate_timeout_value(self, timeout, timer_name):
|
||||
if timeout < 0:
|
||||
raise AnsibleConnectionFailure("'%s' timer value '%s' is invalid, value should be greater than or equal to zero." % (timer_name, timeout))
|
||||
|
|
|
@ -21,7 +21,6 @@ from __future__ import (absolute_import, division, print_function)
|
|||
__metaclass__ = type
|
||||
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
|
||||
from io import StringIO
|
||||
|
@ -29,7 +28,6 @@ from io import StringIO
|
|||
from ansible.compat.tests import unittest
|
||||
from ansible.compat.tests.mock import patch, MagicMock
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.playbook.play_context import PlayContext
|
||||
from ansible.plugins.connection import network_cli
|
||||
|
@ -142,14 +140,15 @@ class TestConnectionClass(unittest.TestCase):
|
|||
device#
|
||||
"""
|
||||
|
||||
mock__shell.recv.side_effect = [response, None]
|
||||
mock__shell.recv.return_value = response
|
||||
|
||||
output = conn.send(b'command', None, None, None)
|
||||
|
||||
mock__shell.sendall.assert_called_with(b'command\r')
|
||||
self.assertEqual(to_text(conn._command_response), 'command response')
|
||||
self.assertEqual(output, 'command response')
|
||||
|
||||
mock__shell.reset_mock()
|
||||
mock__shell.recv.side_effect = [b"ERROR: error message device#"]
|
||||
mock__shell.recv.return_value = b"ERROR: error message device#"
|
||||
|
||||
with self.assertRaises(AnsibleConnectionFailure) as exc:
|
||||
conn.send(b'command', None, None, None)
|
||||
|
|
Loading…
Reference in a new issue