reckless: add uv python env installation method
What changed, and why it matters
This commit adds a new way for Core Lightning's reckless plugin installer to set up Python plugins using 'uv', a fast Python package manager. It is a feature addition with no apparent security relevance in the code itself.
No security action required. Review as normal feature code if auditing reckless installer behavior.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces install_python_uv() in tools/reckless and registers a new ‘pythonuv’ Installer. It symlinks pyproject.toml, runs ‘uv -v sync’ to create a virtual environment, removes the original entrypoint, and creates a wrapper. It also adds poetry.lock as a dependency file for poetryvenv. No vulnerability or security fix is present in the diff.
Changed components
tools/recklessInspect captured patch +37 / −1
diff --git a/tools/reckless b/tools/reckless
index 880ea8d3..c33b4ce7 100755
--- a/tools/reckless
+++ b/tools/reckless
@@ -986,6 +986,37 @@ def cargo_installation(cloned_plugin: InstInfo):
return cloned_plugin
+def install_python_uv(cloned_plugin: InstInfo):
+ """This uses the rust-based python plugin manager uv to manage the python
+ installation and create a virtual environment."""
+
+ source = Path(cloned_plugin.source_loc) / 'source' / cloned_plugin.name
+ # This virtual env path matches the other python installations and allows
+ # creating the wrapper in the same manner. Otherwise uv would build it in
+ # the source/{name} subdirectory.
+ cloned_plugin.venv = Path('.venv')
+
+ # We want the virtual env at the head of our directory structure and uv
+ # will need a pyproject.toml there in order to get started.
+ (Path(cloned_plugin.source_loc) / 'pyproject.toml').\
+ symlink_to(source / 'pyproject.toml')
+
+ call = ['uv', '-v', 'sync']
+ uv = run(call, cwd=str(cloned_plugin.source_loc), stdout=PIPE, stderr=PIPE,
+ text=True, check=False)
+ if uv.returncode != 0:
+ for line in uv.stderr.splitlines():
+ log.debug(line)
+ log.error('Failed to install virtual environment')
+ raise InstallationFailure('Failed to create virtual environment!')
+
+ # Delete entrypoint symlink so that a venv wrapper can take it's place
+ (Path(cloned_plugin.source_loc) / cloned_plugin.entry).unlink()
+
+ create_wrapper(cloned_plugin)
+ return cloned_plugin
+
+
python3venv = Installer('python3venv', exe='python3',
manager='pip', entry='{name}.py')
python3venv.add_entrypoint('{name}')
@@ -997,6 +1028,7 @@ poetryvenv = Installer('poetryvenv', exe='python3',
manager='poetry', entry='{name}.py')
poetryvenv.add_entrypoint('{name}')
poetryvenv.add_entrypoint('__init__.py')
+poetryvenv.add_dependency_file('poetry.lock')
poetryvenv.add_dependency_file('pyproject.toml')
poetryvenv.dependency_call = install_to_python_virtual_environment
@@ -1007,6 +1039,9 @@ pyprojectViaPip.add_entrypoint('__init__.py')
pyprojectViaPip.add_dependency_file('pyproject.toml')
pyprojectViaPip.dependency_call = install_to_python_virtual_environment
+pythonuv = Installer('pythonuv', exe='python3', manager='uv', entry="{name}.py")
+pythonuv.add_dependency_file('uv.lock')
+pythonuv.dependency_call = install_python_uv
# Nodejs plugin installer
nodejs = Installer('nodejs', exe='node',
@@ -1020,7 +1055,8 @@ rust_cargo = Installer('rust', manager='cargo', entry='Cargo.toml')
rust_cargo.add_dependency_file('Cargo.toml')
rust_cargo.dependency_call = cargo_installation
-INSTALLERS = [python3venv, poetryvenv, pyprojectViaPip, nodejs, rust_cargo]
+INSTALLERS = [pythonuv, python3venv, poetryvenv, pyprojectViaPip, nodejs,
+ rust_cargo]
def help_alias(targets: list):
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.