From a9af541e8128cf888aa22bf51a5a401a09fd4bb7 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Mon, 16 Jun 2025 05:17:38 -0700 Subject: [PATCH] Fixes #19529: fix CLI running of scripts (#19698) * 19529 fix custom script path * 19529 fix custom script path * 19529 fix custom script path * 19529 fix custom script path * 19680 add object_change migrator * 19680 optimize migration * 19680 optimize migration --- netbox/extras/forms/scripts.py | 18 ++---- .../migrations/0129_fix_script_paths.py | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 netbox/extras/migrations/0129_fix_script_paths.py diff --git a/netbox/extras/forms/scripts.py b/netbox/extras/forms/scripts.py index c237b9991..5f9820b44 100644 --- a/netbox/extras/forms/scripts.py +++ b/netbox/extras/forms/scripts.py @@ -1,13 +1,8 @@ -import os - -from django import forms -from django.conf import settings -from django.core.files.storage import storages -from django.utils.translation import gettext_lazy as _ - from core.choices import JobIntervalChoices from core.forms import ManagedFileForm -from extras.storage import ScriptFileSystemStorage +from django import forms +from django.core.files.storage import storages +from django.utils.translation import gettext_lazy as _ from utilities.datetime import local_now from utilities.forms.widgets import DateTimePicker, NumberWithOptions @@ -74,12 +69,7 @@ class ScriptFileForm(ManagedFileForm): storage = storages.create_storage(storages.backends["scripts"]) filename = self.cleaned_data['upload_file'].name - if isinstance(storage, ScriptFileSystemStorage): - full_path = os.path.join(settings.SCRIPTS_ROOT, filename) - else: - full_path = filename - - self.instance.file_path = full_path + self.instance.file_path = filename data = self.cleaned_data['upload_file'] storage.save(filename, data) diff --git a/netbox/extras/migrations/0129_fix_script_paths.py b/netbox/extras/migrations/0129_fix_script_paths.py new file mode 100644 index 000000000..1ac8af6d8 --- /dev/null +++ b/netbox/extras/migrations/0129_fix_script_paths.py @@ -0,0 +1,56 @@ +from django.conf import settings +from django.core.files.storage import storages +from django.db import migrations +from urllib.parse import urlparse + +from extras.storage import ScriptFileSystemStorage + + +def normalize(url): + parsed_url = urlparse(url) + if not parsed_url.path.endswith('/'): + return url + '/' + return url + + +def fix_script_paths(apps, schema_editor): + """ + Fix script paths for scripts that had incorrect path from NB 4.3. + """ + storage = storages.create_storage(storages.backends["scripts"]) + if not isinstance(storage, ScriptFileSystemStorage): + return + + ScriptModule = apps.get_model('extras', 'ScriptModule') + script_root_path = normalize(settings.SCRIPTS_ROOT) + for script in ScriptModule.objects.filter(file_path__startswith=script_root_path): + script.file_path = script.file_path[len(script_root_path):] + script.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0128_tableconfig'), + ] + + operations = [ + migrations.RunPython(code=fix_script_paths, reverse_code=migrations.RunPython.noop), + ] + + +def oc_fix_script_paths(objectchange, reverting): + script_root_path = normalize(settings.SCRIPTS_ROOT) + + for data in (objectchange.prechange_data, objectchange.postchange_data): + if data is None: + continue + + if file_path := data.get('file_path'): + if file_path.startswith(script_root_path): + data['file_path'] = file_path[len(script_root_path):] + + +objectchange_migrators = { + 'extras.scriptmodule': oc_fix_script_paths, +}