|
1 | 1 | import inspect
|
2 |
| -import io |
3 | 2 | import logging
|
| 3 | +import os |
4 | 4 | import pkgutil
|
| 5 | +import subprocess |
5 | 6 | import sys
|
6 | 7 | import threading
|
7 | 8 |
|
|
10 | 11 |
|
11 | 12 | logger = logging.getLogger("netbox.plugins.netbox_script_manager")
|
12 | 13 |
|
| 14 | +# Timeout of git system commands in seconds |
| 15 | +GIT_TIMEOUT = 5 |
| 16 | + |
13 | 17 | # Fields not included when saving script input
|
14 | 18 | EXCLUDED_POST_FIELDS = ["csrfmiddlewaretoken", "_schedule_at", "_interval", "_run"]
|
15 | 19 |
|
|
21 | 25 |
|
22 | 26 | # The script root is appended with customscripts as this is the supported structure of the plugin
|
23 | 27 | # 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) |
25 | 29 |
|
26 | 30 | # The custom script root needs to be appended to the path for relative imports to work properly
|
27 | 31 | sys.path.append(script_root)
|
@@ -108,13 +112,21 @@ def prepare_post_data(request):
|
108 | 112 | return post_data
|
109 | 113 |
|
110 | 114 |
|
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 | + """ |
112 | 121 | 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()}") |
0 commit comments