Fix EOSDevice.close() leaking the Netmiko SSH session opened for file copy - #424
Open
jvanderaa wants to merge 2 commits into
Open
Fix EOSDevice.close() leaking the Netmiko SSH session opened for file copy#424jvanderaa wants to merge 2 commits into
jvanderaa wants to merge 2 commits into
Conversation
close() was a no-op, but open() creates a real SSH session for the file-transfer paths (file_copy, check_file_exists, get_remote_checksum, remote_file_copy). A caller holding many device objects accumulated one open socket per device. Disconnect when _connected is set, matching IOSDevice.close(). The guard also keeps close() safe on a device that only ever spoke eAPI, since native_ssh is assigned inside open(). Removes EOSSSHDevice.close(), now an exact duplicate of the parent: native_ssh on that class is a property returning native, so both bodies make the same call.
jvanderaa
requested review from
jeffkala,
pke11y and
pszulczewski
as code owners
August 12, 2026 15:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New Pull Request
Have you:
close()behavior.Closes #423
Change Notes
EOSDevice.close()waspass. It now disconnects the Netmiko SSH session when_connectedis set, matchingIOSDevice.close().The
_connectedguard matters:native_sshis only assigned insideopen(), so an unguarded disconnect would raiseAttributeErroron a device that has only ever spoken eAPI. With the guard, a pure-eAPI caller that never copies a file sees byte-for-byte the old no-op behavior.Also removes
EOSSSHDevice.close(), which became an exact duplicate of the parent —native_sshon that class is a property returningnative, so both bodies make the same call. Its docstring also claimedEOSDevice.closeis a no-op, which is no longer true. Happy to restore the override if reviewers prefer it kept explicit.Tests added to
tests/unit/test_devices/test_eos_device.py(there were previously none forclose()— it was only ever mocked out):test_close_disconnects_netmiko_sessiontest_close_is_noop_when_never_openedAttributeErroron an eAPI-only devicetest_close_is_idempotenttest_close_does_not_strand_the_deviceopen()rebuilds a torn-down sessionThe first two are the ones that failed before the fix; the last two guard properties that already held.
Justification
EOSDeviceis a hybrid driver.showandconfiggo over eAPI, butfile_copy,check_file_exists,get_remote_checksumandremote_file_copyeach callopen(), which builds a real Netmiko session. Nothing released it, so a caller holding many device objects accumulated one open socket per device.eAPI itself is stateless HTTP and needs no teardown, so the no-op was reasonable before file copy arrived over SSH — but it silently stopped being correct once it did.
Risk
Low. Nothing inside pyntc calls
EOSDevice.close(); the only in-library callers ofclose()are in theios,nxos,iosxr,aireosandjnprdrivers, each on their own class. So the behavior change is scoped to external callers and explicit teardown, which is exactly the leak being fixed.Every SSH-backed method calls
self.open()first, andopen()rebuilds the session when_connectedisFalse, so a closed device object stays reusable rather than being stranded. That is whattest_close_does_not_strand_the_devicelocks in.Found while building the
arista_eos_sshdriver (#419); filed separately to keep that PR scoped.