diff --git a/plinth/modules/upgrades/__init__.py b/plinth/modules/upgrades/__init__.py index 56f1553ec..22a046f84 100644 --- a/plinth/modules/upgrades/__init__.py +++ b/plinth/modules/upgrades/__init__.py @@ -46,6 +46,8 @@ BACKPORTS_REQUESTED_KEY = 'upgrades_backports_requested' DIST_UPGRADE_ENABLED_KEY = 'upgrades_dist_upgrade_enabled' +PKG_HOLD_DIAG_CHECK_ID = 'upgrades-package-holds' + logger = logging.getLogger(__name__) @@ -166,6 +168,17 @@ class UpgradesApp(app_module.App): results.append(_diagnose_held_packages()) return results + def repair(self, failed_checks: list) -> bool: + """Handle repair for custom diagnostic.""" + remaining_checks = [] + for check in failed_checks: + if check.check_id == PKG_HOLD_DIAG_CHECK_ID: + privileged.release_held_packages() + else: + remaining_checks.append(check) + + return super().repair(remaining_checks) + def setup_repositories(_): """Setup apt repositories for backports.""" @@ -307,7 +320,7 @@ def test_dist_upgrade(): def _diagnose_held_packages(): """Check if any packages have holds.""" - check = DiagnosticCheck('upgrades-package-holds', + check = DiagnosticCheck(PKG_HOLD_DIAG_CHECK_ID, gettext_noop('Check for package holds'), Result.NOT_DONE) if (package.is_package_manager_busy() diff --git a/plinth/modules/upgrades/privileged.py b/plinth/modules/upgrades/privileged.py index 53521de41..37f21a804 100644 --- a/plinth/modules/upgrades/privileged.py +++ b/plinth/modules/upgrades/privileged.py @@ -19,6 +19,8 @@ from plinth.modules.snapshot import is_apt_snapshots_enabled from plinth.modules.snapshot import is_supported as snapshot_is_supported from plinth.modules.snapshot import load_augeas as snapshot_load_augeas +logger = logging.getLogger(__name__) + SOURCES_LIST = '/etc/apt/sources.list' BACKPORTS_SOURCES_LIST = '/etc/apt/sources.list.d/freedombox2.list' @@ -94,6 +96,25 @@ def _release_held_freedombox(): apt_unhold_freedombox() +@privileged +def release_held_packages(): + """Release any packages that are being held.""" + if is_package_manager_busy(): + logger.warning('Package manager is busy, skipping releasing holds.') + return + + if service_is_running('freedombox-dist-upgrade'): + logger.warning('Distribution upgrade in progress, skipping releasing ' + 'holds.') + return + + output = subprocess.check_output(['apt-mark', 'showhold']).decode().strip() + holds = output.split('\n') + logger.info('Releasing package holds: %s', holds) + subprocess.run(['apt-mark', 'unhold', *holds], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, check=True) + + @privileged def run(): """Run unattended-upgrades."""