Skip to content

Commit 5250431

Browse files
reckless: cleanup failed installation attempts
This is needed when installation is managed by an application that may not have access to the filesystem to clean up manually.
1 parent 667c06f commit 5250431

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

tests/test_reckless.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,18 @@ def test_install(node_factory):
250250
assert os.path.exists(plugin_path)
251251

252252

253+
def test_install_cleanup(node_factory):
254+
"""test failed installation and post install cleanup"""
255+
n = get_reckless_node(node_factory)
256+
n.start()
257+
r = reckless([f"--network={NETWORK}", "-v", "install", "testplugfail"], dir=n.lightning_dir)
258+
assert r.returncode == 0
259+
assert r.search_stdout('testplugfail failed to start')
260+
r.check_stderr()
261+
plugin_path = Path(n.lightning_dir) / 'reckless/testplugfail'
262+
assert not os.path.exists(plugin_path)
263+
264+
253265
@unittest.skipIf(VALGRIND, "virtual environment triggers memleak detection")
254266
def test_poetry_install(node_factory):
255267
"""test search, git clone, and installation to folder."""

tools/reckless

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,10 +1484,22 @@ def _enable_installed(installed: InstInfo, plugin_name: str) -> Union[str, None]
14841484
if enable(installed.name):
14851485
return f"{installed.source_loc}"
14861486

1487-
log.error(('dynamic activation failed: '
1488-
f'{installed.name} not found in reckless directory'))
1487+
log.error('dynamic activation failed')
14891488
return None
14901489

1490+
1491+
def cleanup_plugin_installation(plugin_name):
1492+
"""Remove traces of an installation attempt."""
1493+
inst_path = Path(RECKLESS_CONFIG.reckless_dir) / plugin_name
1494+
if not inst_path.exists():
1495+
log.warning(f'asked to clean up {inst_path}, but nothing is present.')
1496+
return
1497+
1498+
log.info(f'Cleaning up partial installation of {plugin_name} at {inst_path}')
1499+
shutil.rmtree(inst_path)
1500+
return
1501+
1502+
14911503
def install(plugin_name: str) -> Union[str, None]:
14921504
"""Downloads plugin from source repos, installs and activates plugin.
14931505
Returns the location of the installed plugin or "None" in the case of
@@ -1504,7 +1516,7 @@ def install(plugin_name: str) -> Union[str, None]:
15041516
direct_location, name = location_from_name(name)
15051517
src = None
15061518
if direct_location:
1507-
logging.debug(f"install of {name} requested from {direct_location}")
1519+
log.debug(f"install of {name} requested from {direct_location}")
15081520
src = InstInfo(name, direct_location, name)
15091521
# Treating a local git repo as a directory allows testing
15101522
# uncommitted changes.
@@ -1529,8 +1541,17 @@ def install(plugin_name: str) -> Union[str, None]:
15291541
except FileExistsError as err:
15301542
log.error(f'File exists: {err.filename}')
15311543
return None
1532-
return _enable_installed(installed, plugin_name)
1544+
except InstallationFailure as err:
1545+
cleanup_plugin_installation(plugin_name)
1546+
if log.capture:
1547+
log.warning(err)
1548+
return None
1549+
raise err
15331550

1551+
result = _enable_installed(installed, plugin_name)
1552+
if not result:
1553+
cleanup_plugin_installation(plugin_name)
1554+
return result
15341555

15351556

15361557
def uninstall(plugin_name: str) -> str:

0 commit comments

Comments
 (0)