Upgrading NetBox with plugins installed
NetBox is an excellent open source IP Address Management (IPAM) and DataCenter Infrastructure Management (DCIM) with a huge amount of built-in functionality. For anything that isn’t covered out-of-the-box, there is also a wealth of third party plugins.
One of these plugins is NetBox Inventory which adds asset tracking functionality, however the installation instructions seem to forget to mention that you need to create an “/opt/netbox/local_requirements.txt” file with “netbox-inventory” in it (or append this to the file if it already exists) and this also isn’t covered by the official NetBox plugin installation documentation.
If this isn’t done, then NetBox upgrades will fail during the database migrations because the Python venv gets recreated by the /opt/netbox/upgrade.sh script and so the “netbox-inventory” package will be missing:
Skipping local dependencies (local_requirements.txt not found)
Applying database migrations (python3 netbox/manage.py migrate)...
Traceback (most recent call last):
File "/opt/netbox/netbox/netbox/settings.py", line 801, in <module>
plugin = importlib.import_module(plugin_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'netbox_inventory'
During handling of the above exception, another exception occurred:
netbox-inventory
Traceback (most recent call last):
File "/opt/netbox/netbox/manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/management/base.py", line 405, in run_from_argv
parser = self.create_parser(argv[0], argv[1])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/management/base.py", line 368, in create_parser
self.add_arguments(parser)
File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/management/commands/migrate.py", line 50, in add_arguments
choices=tuple(connections),
^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/utils/connection.py", line 73, in __iter__
return iter(self.settings)
^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/utils/functional.py", line 47, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/utils/connection.py", line 45, in settings
self._settings = self.configure_settings(self._settings)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/db/utils.py", line 148, in configure_settings
databases = super().configure_settings(databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/utils/connection.py", line 50, in configure_settings
settings = getattr(django_settings, self.settings_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/conf/__init__.py", line 81, in __getattr__
self._setup(name)
File "/opt/netbox/venv/lib/python3.12/site-packages/django/conf/__init__.py", line 68, in _setup
self._wrapped = Settings(settings_module)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/netbox/venv/lib/python3.12/site-packages/django/conf/__init__.py", line 166, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 999, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/opt/netbox/netbox/netbox/settings.py", line 804, in <module>
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Unable to import plugin netbox_inventory: Module not found. Check that the plugin module has been installed within the correct Python environment.