openwisp / openwisp/openwisp-controller
[bug] SSH connection leaked when update_config() raises an exception
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 773
- Forks
- 315
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 14
Description
● Describe the bug
In DeviceConnection.update_config(), the SSH connection is only closed
in the else block, which means it is never disconnected when an
exception occurs during a config push. Over time this leaks SSH file
descriptors and can crash the controller process with:
OSError: [Errno 24] Too many open files
● Steps To Reproduce
- Set up a device with an SSH
DeviceConnection - Make the config push fail intentionally (e.g. wrong credentials, unreachable device, or network drop mid-transfer)
- Observe that no
disconnect()is called — the SSH session stays open - Repeat for multiple devices; file descriptor count keeps growing
● Root cause (file + line)
File: openwisp_controller/connection/base/models.py
Lines: 365–373
def update_config(self):
self.connect()
if self.is_working:
try:
self.connector_instance.update_config()
except Exception as e:
logger.exception(e)
else:
self.disconnect() # ← only runs when NO exception is raised
The else block in a try/except/else only executes when the try
block completes without raising. Any exception causes disconnect()
to be skipped entirely.
● Expected behavior
The SSH connection should always be closed after update_config()
completes — whether it succeeded or failed — to prevent file descriptor
leaks on production controllers.
● Proposed fix
Change else to finally:
def update_config(self):
self.connect()
if self.is_working:
try:
self.connector_instance.update_config()
except Exception as e:
logger.exception(e)
finally:
self.disconnect() # ← runs always, success OR failure
● Screenshots
Not applicable (code-level bug).
● System Information
- OS: Ubuntu 24.04 LTS
- Python Version: Python 3.10+
- Django Version: Django 4.2+
- Browser and Browser Version (if applicable): Not applicable
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in openwisp_controller/connection/base/models.py around lines 365–373 and read the DeviceConnection.update_config() flow. Reproduce a failed config push, then verify the SSH connection is disconnected on both successful and exceptional completion without leaving file descriptors open.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100