Skip to content

Commit 9fe7443

Browse files
smk4664gsnider2195
authored andcommitted
Close DB connections once forked processes have completed (nautobot#471)
* Fix issue with DB connections not closing * Update development/Dockerfile-fakenos Co-authored-by: Gary Snider <75227981+gsnider2195@users.noreply.github.com> * Update development/Dockerfile-fakenos Co-authored-by: Gary Snider <75227981+gsnider2195@users.noreply.github.com> * Add fakenos documentation --------- Co-authored-by: Gary Snider <75227981+gsnider2195@users.noreply.github.com>
1 parent 7fa47c2 commit 9fe7443

File tree

7 files changed

+98
-1
lines changed

7 files changed

+98
-1
lines changed

changes/366.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed Sync Devices and Sync Network Data jobs not releasing DB connections.

development/Dockerfile-fakenos

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Fakenos dockerfile for local development
2+
3+
# Accepts a desired Python version as build argument, default to 3.12
4+
ARG PYTHON_VER="3.12"
5+
6+
FROM docker.io/python:${PYTHON_VER}-slim
7+
8+
WORKDIR /usr/src/fakenos
9+
10+
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
11+
12+
RUN pip install git+https://github.com/fakenos/fakenos.git
13+
14+
# NOTE: fakenos does not recognize .yml files, must use .yaml
15+
RUN cat <<EOF > /usr/src/fakenos/fakenos_inventory.yaml
16+
hosts:
17+
fakerouter:
18+
username: admin
19+
password: admin
20+
platform: cisco_ios
21+
server:
22+
plugin: "ParamikoSshServer"
23+
configuration:
24+
address: "0.0.0.0"
25+
timeout: 1
26+
port: 22
27+
EOF
28+
29+
ARG PYTHON_VER="3.12"
30+
31+
# NOTE: fakenos does not correctly handle absolute paths
32+
WORKDIR /usr/local/lib/python${PYTHON_VER}/site-packages
33+
34+
CMD [ "fakenos", "--inventory", "/usr/src/fakenos/fakenos_inventory.yaml" ]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
services:
3+
fakerouter1:
4+
build:
5+
args:
6+
PYTHON_VER: "${PYTHON_VER}"
7+
context: "../"
8+
dockerfile: "development/Dockerfile-fakenos"
9+
image: "nautobot-device-onboarding/fakenos:py${PYTHON_VER}"
10+
pull_policy: "never"
11+
expose:
12+
- "22"
13+
fakerouter2: &fakerouter
14+
image: "nautobot-device-onboarding/fakenos:py${PYTHON_VER}"
15+
pull_policy: "never"
16+
expose:
17+
- "22"
18+
fakerouter3: *fakerouter
19+
fakerouter4: *fakerouter
20+
fakerouter5: *fakerouter
21+
fakerouter6: *fakerouter
22+
fakerouter7: *fakerouter
23+
fakerouter8: *fakerouter
24+
fakerouter9: *fakerouter
25+
fakerouter10: *fakerouter
26+
fakerouter11: *fakerouter
27+
fakerouter12: *fakerouter
28+
fakerouter13: *fakerouter

docs/dev/dev_environment.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ The [Invoke](http://www.pyinvoke.org/) library is used to provide some helper co
2222

2323
Using **Invoke** these configuration options can be overridden using [several methods](https://docs.pyinvoke.org/en/stable/concepts/configuration.html). Perhaps the simplest is setting an environment variable `INVOKE_NAUTOBOT_DEVICE_ONBOARDING_VARIABLE_NAME` where `VARIABLE_NAME` is the variable you are trying to override. The only exception is `compose_files`, because it is a list it must be overridden in a YAML file. There is an example `invoke.yml` (`invoke.example.yml`) in this directory which can be used as a starting point.
2424

25+
#### FakeNOS Support
26+
27+
To enable FakeNOS support in the development environment, you can add the `docker-compose.fakenos.yml` file to the list of compose files used by Invoke. This can be done by creating an `invoke.yml` file with the following contents at the root of the repo:
28+
29+
```yaml
30+
---
31+
nautobot_device_onboarding:
32+
compose_files:
33+
- docker-compose.redis.yml
34+
- docker-compose.postgres.yml
35+
- docker-compose.fakenos.yml
36+
- docker-compose.dev.yml
37+
```
38+
2539
### Docker Development Environment
2640
2741
!!! tip

nautobot_device_onboarding/nornir_plays/command_getter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
get_git_repo_parser_path,
3333
load_files_with_precedence,
3434
)
35-
from nautobot_device_onboarding.utils.helper import check_for_required_file, format_log_message
35+
from nautobot_device_onboarding.utils.helper import (
36+
check_for_required_file,
37+
close_threaded_db_connections,
38+
format_log_message,
39+
)
3640

3741
PARSER_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), "parsers"))
3842

@@ -114,6 +118,7 @@ def _get_commands_to_run(yaml_parsed_info, sync_vlans, sync_vrfs, sync_cables, s
114118
return deduplicate_command_list(all_commands)
115119

116120

121+
@close_threaded_db_connections
117122
def netmiko_send_commands(task: Task, command_getter_yaml_data: Dict, command_getter_job: str, logger, nautobot_job):
118123
"""Run commands specified in PLATFORM_COMMAND_MAP."""
119124
if not task.host.platform:

nautobot_device_onboarding/nornir_plays/processor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from nautobot_device_onboarding.nornir_plays.formatter import extract_show_data
1111
from nautobot_device_onboarding.nornir_plays.schemas import NETWORK_DATA_SCHEMA, NETWORK_DEVICES_SCHEMA
12+
from nautobot_device_onboarding.utils.helper import close_threaded_db_connections
1213

1314

1415
class CommandGetterProcessor(BaseLoggingProcessor):
@@ -29,6 +30,7 @@ def task_instance_started(self, task: Task, host: Host) -> None:
2930
"network_driver": host.platform,
3031
}
3132

33+
@close_threaded_db_connections
3234
def task_instance_completed(self, task: Task, host: Host, result: MultiResult) -> None:
3335
"""Processor for logging and data processing on task completed.
3436

nautobot_device_onboarding/utils/helper.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import socket
66

77
import netaddr
8+
from django.db import connections
89
from nautobot.dcim.filters import DeviceFilterSet
910
from nautobot.dcim.models import Device
1011
from netaddr.core import AddrFormatError
@@ -119,3 +120,15 @@ def check_for_required_file(directory, filename):
119120
return False
120121
except FileNotFoundError:
121122
return False
123+
124+
125+
def close_threaded_db_connections(func):
126+
"""Decorator to close database connections in threaded tasks."""
127+
128+
def inner(*args, **kwargs):
129+
try:
130+
func(*args, **kwargs)
131+
finally:
132+
connections.close_all()
133+
134+
return inner

0 commit comments

Comments
 (0)