From 91c5931c59cdaae28075d97d032cb64ac5b32d20 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Tue, 11 Mar 2025 15:27:34 -0700 Subject: [PATCH] upgrades: Run dpkg/apt fixes before dist upgrade Closes: #2490 Tests: - Unit tests works. - On a fresh stable container, enable auto updates. Run 'apt install mumble-server' and kill the apt process when it is unpacking. After this any apt install command will ask for running dpkg --configure -a. At this time, run the Testing dist upgrade. Dist upgrade starts successfully and then shows the message 'Fixing any broken apt/dpkg states...'. It also shows that packages that were not setup have been setup. Dist upgrades proceeds after that. Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/modules/upgrades/distupgrade.py | 8 ++++++++ plinth/modules/upgrades/tests/test_distupgrade.py | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/plinth/modules/upgrades/distupgrade.py b/plinth/modules/upgrades/distupgrade.py index 5d4f346d0..706dee034 100644 --- a/plinth/modules/upgrades/distupgrade.py +++ b/plinth/modules/upgrades/distupgrade.py @@ -223,6 +223,13 @@ def _apt_update(): _apt_run(['update']) +def _apt_fix(): + """Try to fix any problems with apt/dpkg before the upgrade.""" + logger.info('Fixing any broken apt/dpkg states...') + subprocess.run(['dpkg', '--configure', '-a'], check=False) + _apt_run(['--fix-broken', 'install']) + + def _apt_autoremove(): """Run 'apt autoremove'.""" logger.info('Running apt autoremove...') @@ -298,6 +305,7 @@ def perform(): _services_disable(), \ _apt_hold_packages(): _apt_update() + _apt_fix() _debconf_set_selections() _packages_remove_obsolete() _apt_full_upgrade() diff --git a/plinth/modules/upgrades/tests/test_distupgrade.py b/plinth/modules/upgrades/tests/test_distupgrade.py index b1e2dedae..91ab44aa2 100644 --- a/plinth/modules/upgrades/tests/test_distupgrade.py +++ b/plinth/modules/upgrades/tests/test_distupgrade.py @@ -283,6 +283,17 @@ def test_apt_update(apt_run): apt_run.assert_called_with(['update']) +@patch('plinth.modules.upgrades.distupgrade._apt_run') +@patch('subprocess.run') +def test_apt_fix(run, apt_run): + """Test that apt fixes work.""" + distupgrade._apt_fix() + assert run.call_args_list == [ + call(['dpkg', '--configure', '-a'], check=False) + ] + assert apt_run.call_args_list == [call(['--fix-broken', 'install'])] + + @patch('plinth.modules.upgrades.distupgrade._apt_run') def test_apt_autoremove(apt_run): """Test that apt autoremove works."""