Skip to content

Commit 76e876e

Browse files
committed
Rework git sync to use system git
1 parent 63105f8 commit 76e876e

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

netbox_script_manager/util.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import inspect
2-
import io
32
import logging
3+
import os
44
import pkgutil
5+
import subprocess
56
import sys
67
import threading
78

@@ -10,6 +11,9 @@
1011

1112
logger = logging.getLogger("netbox.plugins.netbox_script_manager")
1213

14+
# Timeout of git system commands in seconds
15+
GIT_TIMEOUT = 5
16+
1317
# Fields not included when saving script input
1418
EXCLUDED_POST_FIELDS = ["csrfmiddlewaretoken", "_schedule_at", "_interval", "_run"]
1519

@@ -21,7 +25,7 @@
2125

2226
# The script root is appended with customscripts as this is the supported structure of the plugin
2327
# The main reason is to avoid name collisions with the built-in netbox apps
24-
custom_script_root = f"{script_root}/{CUSTOM_SCRIPT_SUBPACKAGE}"
28+
custom_script_root = os.path.join(script_root, CUSTOM_SCRIPT_SUBPACKAGE)
2529

2630
# The custom script root needs to be appended to the path for relative imports to work properly
2731
sys.path.append(script_root)
@@ -108,13 +112,21 @@ def prepare_post_data(request):
108112
return post_data
109113

110114

111-
def git_pull(path):
115+
def pull_scripts():
116+
"""
117+
Pulls the git repository at the custom script root.
118+
While dulwich could have been used here, there are some pretty stark limitations
119+
to what dulwich supports. The simplest approach was just to call the system git command.
120+
"""
112121
try:
113-
from dulwich import porcelain
114-
except ImportError as e:
115-
raise ImportError("The dulwich must be installed for git sync functionality to work.")
116-
117-
output_io = io.BytesIO()
118-
porcelain.pull(path, outstream=output_io, errstream=output_io)
119-
120-
return output_io
122+
result = subprocess.run(
123+
["git", "pull"],
124+
cwd=custom_script_root, # git recursively checks parent folders until it finds a git directory
125+
check=True,
126+
stdout=subprocess.PIPE,
127+
stderr=subprocess.STDOUT, # git uses stderr as stdout for some reason
128+
timeout=GIT_TIMEOUT, # As we currently don't background this, we need a fairly low timeout
129+
)
130+
return result.stdout.decode()
131+
except subprocess.CalledProcessError as e:
132+
raise ValueError(f"Failed to pull git repository at {custom_script_root}: {e.output.decode()}")

netbox_script_manager/views.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import io
21
import json
32
import uuid
43

@@ -176,17 +175,15 @@ def get_required_permission(self):
176175
return "netbox_script_manager.sync_scriptinstance"
177176

178177
def get(self, request):
179-
script_root = plugin_config.get("SCRIPT_ROOT")
180-
181178
try:
182-
output_io = util.git_pull(script_root)
179+
result = util.pull_scripts()
183180
except Exception as e:
184181
messages.error(request, f"Failed to pull git repository: {e}")
185182
return redirect("plugins:netbox_script_manager:scriptinstance_list")
186183

187-
message = [f"Pulled git repository: {script_root}"]
188-
if output_text := output_io.getvalue():
189-
message.append(f"<pre>{output_text.decode('utf-8')}</pre>")
184+
message = [f"Pulled git repository"]
185+
if result:
186+
message.append(f"<pre>{result}</pre>")
190187

191188
messages.info(request, mark_safe("\n".join(message)))
192189

0 commit comments

Comments
 (0)