-
Notifications
You must be signed in to change notification settings - Fork 45
IOS-XR: if a commit fails, read_until_prompt waits forever #4
Comments
Thank you for your interest to this library!
Firstly, we should check the output for the string "Failed to commit" and raise the "Failed to commit" exception. And we also should check "Uncommitted changes found" after "end" command. Right now we have function with these parameters
I can make these changes in this week, but if you really want to help me and make changes yourself - it will be really great!! You can pm me in telegram or slack and I can help you make PR for it. |
I'm happy to help. I will create a PR, and then the first thing I'll do is create a test that demonstrates the issue. Then we can discuss the test. Then I will add code to resolve the problem, which will include the handling you've discussed above. Sound good? |
Yes, it will be amazing! I will wait for the PR! |
Quick note to say I have not forgotten about this issue, but I've been extremely busy recently. |
Hello, @cjrh!
For taking this behavior I made these changes master...develop#diff-c089f96ea63362ebd55df599d9d7c153. The main:
Can you test it in your environment? After that, I will release it in master branch :) |
Forgot! I also added timeout params for managing timeout in all async operations :) You can use it only in init. The default timeout is 15 seconds: def __init__(self, host=u'', username=u'', password=u'', port=22, device_type=u'', known_hosts=None,
local_addr=None, client_keys=None, passphrase=None, timeout=15, loop=None): I thought about adding timeout exactly to operations (send_config_set and send_command) but I don't know if it's really necessary. Do you need this? |
@selfuryon Thanks! I will have a look towards the middle or end of this week. |
@cjrh Hello! Did you test new code? :) |
Sadly, I have not tested it yet. I did the workaround we discussed, where I made a subclass of the XR class and so far that has worked very well. sorry! |
This same stuck can happen on IOS. autocommand who but they forgot the... Well, now you connect, get logged in, and before the prompt ever appears, you're disconnected. Well now you're stuck, you're stuck at the find_base_prompt() forever... |
An issue occurs when a commit on IOS-XR results in an error. I see this with
CiscoIOSXR.send_config_set()
. After the code sends thecommit
, it then runsIOSLikeDevice._read_until_prompt()
, but if the commit fails, then_read_until_prompt()
will wait forever.Here is an example of an interactive session that produces a failed commit (I presume it doesn't really matter what produces the commit failure, as long as it fails):
(It fails because the policies mentioned in the config do not exist)
Note that the prompt does not return after "end" is entered: instead, the returned bytes are
Uncommitted changes found, commit them before exiting(yes/no/cancel)? [cancel]:
. This is the cause of the problem.This is the code in
CiscoIOSXR.send_config_set()
:The
commit
, and then theend
, is issued on the line marked above. This runs the method in theIOSLikeDevice
superclass:In the line marked above, if the commit has failed, and then
end
is sent (insideexit_config()
), the prompt will never be found, becauseread_until_prompt()
simply callsread_until_pattern(self._base_pattern)
:Eventually, the device returns all the bytes up to the end of the confirmation request:
And of course no prompt can be detected in this, and no more bytes are coming.
I will do a bit more debugging soon, but I just wanted to raise this issue now to get your thoughts. I'm happy to do the work to fix or improve the handling of errors during commit, if you could give your thoughts, or make any suggestions of how best to proceed?
One idea that I had while looking at the code was to add timeout handling inside
_read_until_pattern()
:only so that the output can be captured and logged. Currently, if the code waits here, and an
asyncio.wait_for()
triggers due to timeout in an outer scope, any bytes currently pending in theoutput
identifier will be lost. By capturing and logging those bytes (and then possibly reraising a TimeoutError), it should make it easier to diagnose why a timeout occurred.But for the specific case where we get the
Uncommitted changes found
problem, it is probably better to try to match that also inread_until_pattern
, so that it can be handled directly, rather than waiting for a timeout. I'm not sure yet, and would like to know what your thoughts are before I do any work on this.By the way, thanks for making this library!
The text was updated successfully, but these errors were encountered: