Public bug reported: When migrateToDeb822Sources() cannot migrate any of the remaining .list files (for example because every one uses [signed-by=], bug 2167655), aborting the upgrade afterwards loses those sources. The original .list files and their .migrate backups are both deleted, and only the commented-out .list.disabled stubs remain, so the repositories stay disabled on the release that is still installed.
Version: ubuntu-release-upgrader 26.10.11 (26.04.1 to 26.10), python3-apt 3.1.0ubuntu1.1. Steps to reproduce 1. On 26.04, with the Ubuntu sources in deb822 format, add a third-party source as a one-line .list file that uses signed-by, for example /etc/apt/sources.list.d/dbeaver.list containing: deb [signed-by=/usr/share/keyrings/dbeaver.gpg.key] https://dbeaver.io/debs/dbeaver-ce / 2. Run do-release-upgrade and abort once the sources have been rewritten, for example by declining "Do you want to start the upgrade?". Here the abort followed apt update failing on the Ubuntu Pro ESM sources (bug 2084208). 3. List /etc/apt/sources.list.d. Expected: dbeaver.list is back as it was, and dbeaver.list.disabled is gone. Actual: dbeaver.list and dbeaver.list.migrate are both gone, and dbeaver.list.disabled holds the entry commented out. main.log, timestamps trimmed: DEBUG migrateToDeb822Sources() DEBUG Could not migrate deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/claude-desktop-archive-keyring.asc] https://downloads.claude.ai/claude-desktop/apt/stable stable main from /etc/apt/sources.list.d/claude-desktop.list, disabling instead. DEBUG Could not migrate deb [signed-by=/usr/share/keyrings/dbeaver.gpg.key] https://dbeaver.io/debs/dbeaver-ce / from /etc/apt/sources.list.d/dbeaver.list, disabling instead. ... DEBUG abort called Cause migrateToDeb822Sources() backs every file up as *.migrate, writes <file>.disabled for entries python-apt marks invalid, and removes the original .list files. abort() then calls restoreMigratedSources() and cleanBackupSources(). restoreMigratedSources() returns immediately when no .sources file was generated: def restoreMigratedSources(self): if not self._generated_sources_files: return When every .list entry was invalid, nothing was generated, so the *.migrate files are never renamed back, and cleanBackupSources() then deletes them. The .disabled stubs stay. ubuntu/main at d09d661750e4 has the same code: https://git.launchpad.net/ubuntu-release-upgrader/tree/DistUpgrade/DistUpgradeController.py?id=d09d661750e42d2cb6da3c9ada3d772f22e2bbb3#n768 Suggested fix: in restoreMigratedSources(), rename the *.migrate files back whether or not any .sources files were generated, and remove the .disabled files this run wrote. Related: bug 2167655 (signed-by sources are never migrated), bug 2130273 (the same files deleted at the end of a completed upgrade, where a maintainer noted that the upgrader does not restore the original), and bug 2166117 (abort leaves sources unrestored in a different case). _Drafted by Claude (Anthropic AI assistant)._ ** Affects: ubuntu-release-upgrader (Ubuntu) Importance: Undecided Status: New -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2171068 Title: Aborting a release upgrade deletes .list sources that could not be migrated to deb822 To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+bug/2171068/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
