change behaviour to load plugin

This commit is contained in:
ScarletEmanu 2026-06-17 11:15:57 +02:00
parent c777ee03f6
commit 5dbf954f40
2 changed files with 32 additions and 33 deletions

View File

@ -2,6 +2,7 @@ import argparse
import json
import os
import sys
import tempfile
import urllib.error
import urllib.parse
from argparse import ArgumentParser, Namespace
@ -56,7 +57,8 @@ class Arguments:
debug: bool = False
offline: bool = False
no_pkg_lookups: bool = False
plugin: str | None = None
plugin: Path | None = None
plugin_url: str | None = None
skip_version_check: bool = False
skip_wifi_check: bool = False
advanced: bool = False
@ -517,10 +519,17 @@ class ArchConfigHandler:
parser.add_argument(
'--plugin',
nargs='?',
type=str,
type=Path,
default=None,
help='File path to a plugin to load',
)
parser.add_argument(
'--plugin-url',
type=str,
nargs='?',
default=None,
help='Url to a plugin file to load',
)
parser.add_argument(
'--skip-version-check',
action='store_true',
@ -560,7 +569,11 @@ class ArchConfigHandler:
warn(f'Warning: --debug mode will write certain credentials to {logger.path}!')
if args.plugin:
plugin_path = Path(args.plugin)
load_plugin(args.plugin)
if args.plugin_url:
plugin_data = self._fetch_from_url(args.plugin_url)
plugin_path = self._write_plugin_to_temp_file(plugin_data)
load_plugin(plugin_path)
if args.creds_decryption_key is None:
@ -652,6 +665,19 @@ class ArchConfigHandler:
sys.exit(1)
def _write_plugin_to_temp_file(self, plugin_data: str) -> Path:
tmp_file = tempfile.NamedTemporaryFile(
mode='w',
suffix='.py',
prefix='archinstall_plugin_',
delete=False,
)
with tmp_file as f:
f.write(plugin_data)
return Path(tmp_file.name)
def _read_file(self, path: Path) -> str:
if not path.exists():
error(f'Could not find file {path}')

View File

@ -1,9 +1,6 @@
import hashlib
import importlib.util
import os
import sys
import urllib.parse
import urllib.request
from importlib import metadata
from pathlib import Path
@ -34,23 +31,6 @@ def plugin(f, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
plugins[f.__name__] = f
def _localize_path(path: Path) -> Path:
"""
Support structures for load_plugin()
"""
url = urllib.parse.urlparse(str(path))
if url.scheme and url.scheme in ('https', 'http'):
converted_path = Path(f'/tmp/{path.stem}_{hashlib.md5(os.urandom(12)).hexdigest()}.py')
with open(converted_path, 'w') as temp_file:
temp_file.write(urllib.request.urlopen(url.geturl()).read().decode('utf-8'))
return converted_path
else:
return path
def _import_via_path(path: Path, namespace: str | None = None) -> str:
if not namespace:
namespace = os.path.basename(path)
@ -82,17 +62,10 @@ def _import_via_path(path: Path, namespace: str | None = None) -> str:
def load_plugin(path: Path) -> None:
namespace: str | None = None
parsed_url = urllib.parse.urlparse(str(path))
info(f'Loading plugin from url {parsed_url}')
info(f'Loading plugin from {path}')
# The Profile was not a direct match on a remote URL
if not parsed_url.scheme:
# Path was not found in any known examples, check if it's an absolute path
if os.path.isfile(path):
namespace = _import_via_path(path)
elif parsed_url.scheme in ('https', 'http'):
localized = _localize_path(path)
namespace = _import_via_path(localized)
if os.path.isfile(path):
namespace = _import_via_path(path)
if namespace and namespace in sys.modules:
# Version dependency via __archinstall__version__ variable (if present) in the plugin