mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-04-29 10:10:19 +00:00
packages: Purge packages on uninstall
The primary reason for the existence of uninstall feature is to clean up the existing working or non-working setup and re-install freshly. It is not to remove the effects of the installed app since disable works well for that. It is seldom to free up space since even on a microSD card, the space occupied by most apps is negligible. Tests: - Unit tests pass - Functional tests for all apps pass (except for known failures). Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
dff1d94163
commit
85bfe40c87
@ -175,7 +175,7 @@ class Packages(app_module.FollowerComponent):
|
|||||||
self.conflicts_action not in (None, self.ConflictsAction.IGNORE):
|
self.conflicts_action not in (None, self.ConflictsAction.IGNORE):
|
||||||
logger.info('Removing conflicting packages: %s',
|
logger.info('Removing conflicting packages: %s',
|
||||||
packages_to_remove)
|
packages_to_remove)
|
||||||
uninstall(packages_to_remove)
|
uninstall(packages_to_remove, purge=False)
|
||||||
|
|
||||||
install(self.get_actual_packages(),
|
install(self.get_actual_packages(),
|
||||||
skip_recommends=self.skip_recommends)
|
skip_recommends=self.skip_recommends)
|
||||||
@ -198,7 +198,8 @@ class Packages(app_module.FollowerComponent):
|
|||||||
packages_set -= set(component.get_actual_packages())
|
packages_set -= set(component.get_actual_packages())
|
||||||
|
|
||||||
# Preserve order of packages for ease of testing
|
# Preserve order of packages for ease of testing
|
||||||
uninstall([package for package in packages if package in packages_set])
|
uninstall([package for package in packages if package in packages_set],
|
||||||
|
purge=True)
|
||||||
|
|
||||||
def diagnose(self):
|
def diagnose(self):
|
||||||
"""Run diagnostics and return results."""
|
"""Run diagnostics and return results."""
|
||||||
@ -341,10 +342,11 @@ class Transaction:
|
|||||||
logger.exception('Error installing package: %s', exception)
|
logger.exception('Error installing package: %s', exception)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self, purge):
|
||||||
"""Run an apt-get transaction to uninstall given packages."""
|
"""Run an apt-get transaction to uninstall given packages."""
|
||||||
try:
|
try:
|
||||||
privileged.remove(app_id=self.app_id, packages=self.package_names)
|
privileged.remove(app_id=self.app_id, packages=self.package_names,
|
||||||
|
purge=purge)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
logger.exception('Error uninstalling package: %s', exception)
|
logger.exception('Error uninstalling package: %s', exception)
|
||||||
raise
|
raise
|
||||||
@ -416,7 +418,7 @@ def install(package_names, skip_recommends=False, force_configuration=None,
|
|||||||
force_missing_configuration)
|
force_missing_configuration)
|
||||||
|
|
||||||
|
|
||||||
def uninstall(package_names):
|
def uninstall(package_names, purge):
|
||||||
"""Uninstall a set of packages."""
|
"""Uninstall a set of packages."""
|
||||||
try:
|
try:
|
||||||
operation = operation_module.Operation.get_operation()
|
operation = operation_module.Operation.get_operation()
|
||||||
@ -437,7 +439,7 @@ def uninstall(package_names):
|
|||||||
from . import package
|
from . import package
|
||||||
transaction = package.Transaction(operation.app_id, package_names)
|
transaction = package.Transaction(operation.app_id, package_names)
|
||||||
operation.thread_data['transaction'] = transaction
|
operation.thread_data['transaction'] = transaction
|
||||||
transaction.uninstall()
|
transaction.uninstall(purge)
|
||||||
|
|
||||||
|
|
||||||
def is_package_manager_busy():
|
def is_package_manager_busy():
|
||||||
|
|||||||
@ -71,7 +71,7 @@ def install(app_id: str, packages: list[str], skip_recommends: bool = False,
|
|||||||
|
|
||||||
|
|
||||||
@privileged
|
@privileged
|
||||||
def remove(app_id: str, packages: list[str]):
|
def remove(app_id: str, packages: list[str], purge: bool):
|
||||||
"""Remove packages using apt-get."""
|
"""Remove packages using apt-get."""
|
||||||
try:
|
try:
|
||||||
_assert_managed_packages(app_id, packages)
|
_assert_managed_packages(app_id, packages)
|
||||||
@ -81,7 +81,8 @@ def remove(app_id: str, packages: list[str]):
|
|||||||
subprocess.run(['dpkg', '--configure', '-a'], check=False)
|
subprocess.run(['dpkg', '--configure', '-a'], check=False)
|
||||||
with action_utils.apt_hold_freedombox():
|
with action_utils.apt_hold_freedombox():
|
||||||
run_apt_command(['--fix-broken', 'install'])
|
run_apt_command(['--fix-broken', 'install'])
|
||||||
returncode = run_apt_command(['remove'] + packages)
|
options = [] if not purge else ['--purge']
|
||||||
|
returncode = run_apt_command(['remove'] + options + packages)
|
||||||
|
|
||||||
if returncode:
|
if returncode:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
|
|||||||
@ -130,7 +130,7 @@ def test_packages_setup_with_conflicts(install, uninstall, packages_installed):
|
|||||||
component = Packages('test-component', ['bash'], conflicts=['exim4-base'],
|
component = Packages('test-component', ['bash'], conflicts=['exim4-base'],
|
||||||
conflicts_action=Packages.ConflictsAction.REMOVE)
|
conflicts_action=Packages.ConflictsAction.REMOVE)
|
||||||
component.setup(old_version=0)
|
component.setup(old_version=0)
|
||||||
uninstall.assert_has_calls([call(['exim4-base'])])
|
uninstall.assert_has_calls([call(['exim4-base'], purge=False)])
|
||||||
install.assert_has_calls([call(['bash'], skip_recommends=False)])
|
install.assert_has_calls([call(['bash'], skip_recommends=False)])
|
||||||
|
|
||||||
uninstall.reset_mock()
|
uninstall.reset_mock()
|
||||||
@ -162,7 +162,7 @@ def test_packages_uninstall(uninstall):
|
|||||||
app = TestApp()
|
app = TestApp()
|
||||||
app.add(component)
|
app.add(component)
|
||||||
app.uninstall()
|
app.uninstall()
|
||||||
uninstall.assert_has_calls([call(['python3', 'bash'])])
|
uninstall.assert_has_calls([call(['python3', 'bash'], purge=True)])
|
||||||
|
|
||||||
|
|
||||||
@patch('plinth.package.uninstall')
|
@patch('plinth.package.uninstall')
|
||||||
@ -218,9 +218,10 @@ def test_packages_uninstall_exclusion(cache, uninstall):
|
|||||||
TestApp2()
|
TestApp2()
|
||||||
TestApp3()
|
TestApp3()
|
||||||
app1.uninstall()
|
app1.uninstall()
|
||||||
uninstall.assert_has_calls(
|
uninstall.assert_has_calls([
|
||||||
[call(['package11', 'package3']),
|
call(['package11', 'package3'], purge=True),
|
||||||
call(['package12', 'package3'])])
|
call(['package12', 'package3'], purge=True)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
@patch('apt.Cache')
|
@patch('apt.Cache')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user