Skip to content

Commit 9f0a246

Browse files
committed
fix plugin problem
1 parent dcc38fe commit 9f0a246

2 files changed

Lines changed: 30 additions & 11 deletions

File tree

archinstall/lib/args.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ def _parse_args(self) -> Arguments:
447447
warn(f'Warning: --debug mode will write certain credentials to {logger.path}!')
448448

449449
if args.plugin:
450-
plugin_path = Path(args.plugin)
451-
load_plugin(plugin_path)
450+
# Pass plugin as string to preserve URL format (avoid Path normalization)
451+
load_plugin(args.plugin)
452452

453453
if args.creds_decryption_key is None:
454454
if os.environ.get('ARCHINSTALL_CREDS_DECRYPTION_KEY'):

archinstall/lib/plugins.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import importlib.util
33
import os
44
import sys
5+
import urllib.error
56
import urllib.parse
67
import urllib.request
78
from importlib import metadata
@@ -34,17 +35,33 @@ def plugin(f, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
3435
plugins[f.__name__] = f
3536

3637

37-
def _localize_path(path: Path) -> Path:
38+
def _localize_path(path: str | Path) -> Path:
3839
"""
3940
Support structures for load_plugin()
4041
"""
41-
url = urllib.parse.urlparse(str(path))
42+
# Keep as string to preserve URL format (Path normalization breaks URLs)
43+
path_str = str(path)
44+
url = urllib.parse.urlparse(path_str)
4245

4346
if url.scheme and url.scheme in ('https', 'http'):
44-
converted_path = Path(f'/tmp/{path.stem}_{hashlib.md5(os.urandom(12)).hexdigest()}.py')
47+
# Extract filename from the URL path component
48+
# Use os.path.basename instead of path.stem to handle URLs correctly
49+
url_path = url.path
50+
filename = os.path.basename(url_path) if url_path else 'plugin'
51+
# Remove .py extension if present for the temporary filename format
52+
filename_base = filename.replace('.py', '') if filename.endswith('.py') else filename
53+
54+
converted_path = Path(f'/tmp/{filename_base}_{hashlib.md5(os.urandom(12)).hexdigest()}.py')
4555

4656
with open(converted_path, 'w') as temp_file:
47-
temp_file.write(urllib.request.urlopen(url.geturl()).read().decode('utf-8'))
57+
# Use the original path string directly instead of reconstructing from parsed URL
58+
# This avoids issues with url.geturl() producing malformed URLs
59+
try:
60+
response = urllib.request.urlopen(path_str)
61+
temp_file.write(response.read().decode('utf-8'))
62+
except urllib.error.URLError as e:
63+
error(f'Failed to download plugin from {path_str}: {e}')
64+
raise
4865

4966
return converted_path
5067
else:
@@ -80,18 +97,20 @@ def _import_via_path(path: Path, namespace: str | None = None) -> str:
8097
return namespace
8198

8299

83-
def load_plugin(path: Path) -> None:
100+
def load_plugin(path: str | Path) -> None:
84101
namespace: str | None = None
85-
parsed_url = urllib.parse.urlparse(str(path))
102+
# Keep URL as string to preserve scheme (avoid Path normalization)
103+
path_str = str(path) if isinstance(path, Path) else path
104+
parsed_url = urllib.parse.urlparse(path_str)
86105
info(f'Loading plugin from url {parsed_url}')
87106

88107
# The Profile was not a direct match on a remote URL
89108
if not parsed_url.scheme:
90109
# Path was not found in any known examples, check if it's an absolute path
91-
if os.path.isfile(path):
92-
namespace = _import_via_path(path)
110+
if os.path.isfile(path_str):
111+
namespace = _import_via_path(Path(path_str))
93112
elif parsed_url.scheme in ('https', 'http'):
94-
localized = _localize_path(path)
113+
localized = _localize_path(path_str)
95114
namespace = _import_via_path(localized)
96115

97116
if namespace and namespace in sys.modules:

0 commit comments

Comments
 (0)