Skip to content

Instantly share code, notes, and snippets.

@christianbundy
Last active September 19, 2023 19:31
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save christianbundy/0d982648cbfe3dd4350cee8ab9e53828 to your computer and use it in GitHub Desktop.
Save christianbundy/0d982648cbfe3dd4350cee8ab9e53828 to your computer and use it in GitHub Desktop.

How To Fix FrankenDebian

Alternate title: How to Fix FrankenDebian's Monster.

Background

https://wiki.debian.org/DontBreakDebian#Don.27t_make_a_FrankenDebian

Environment

Once upon a time I thought it would be a good idea to switch from stable (Debian 9 "Stretch") to testing (Debian 10 "Buster"). It was not a good idea.

After learning that testing may not get security updates in a timely manner I switched back to stable. This has made a lot of people very angry and been widely regarded as a bad move.

         _,met$$$$$gg.           christianbundy@mainframe
      ,g$$$$$$$$$$$$$$$P.        OS: Debian 9.3 stretch
    ,g$$P""       """Y$$.".      Kernel: x86_64 Linux 4.14.0-2-amd64
   ,$$P'              `$$$.      Uptime: 1d 21h 45m
  ',$$P       ,ggs.     `$$b:    Packages: 1560
  `d$$'     ,$P"'   .    $$$     Shell: zsh 5.4.2
   $$P      d$'     ,    $$P     CPU: Intel Xeon CPU @ 2.5GHz
   $$:      $$.   -    ,d$$'     RAM: 2760MiB / 15042MiB
   $$\;      Y$b._   _,d$P'
   Y$$.    `.`"Y$$$$P"'
   `$$b      "-.__
    `Y$$
     `Y$$.
       `$$b.
         `Y$$b.
            `"Y$b._
                `""""

Fix

Sources

The most obvious (and very important) step is to fix your sources. You'll need to edit /etc/apt/sources.list (and /etc/apt/sources.list.d/*) to remove any and all references to the future release. In my case, that meant looking for testing and buster.

$ grep -nr '\(testing\|buster\|unstable\|sid\)' /etc/apt/sources.list*
/etc/apt/sources.list.d/nodesource.list.save:1:deb https://deb.nodesource.com/node_9.x buster main
/etc/apt/sources.list.d/nodesource.list.save:2:deb-src https://deb.nodesource.com/node_9.x buster main
/etc/apt/sources.list.d/docker.list:1:deb [arch=amd64] https://download.docker.com/linux/debian buster edge
/etc/apt/sources.list.save:1:deb http://http.debian.net/debian testing main
/etc/apt/sources.list.save:2:deb-src http://http.debian.net/debian testing main

Ignore the .save files, but make sure to replace all of the above instances with stretch. You can automate the in-place text substitution, but generally I'd recommend doing it manually unless you really know what you're doing. After you're done, run sudo apt-get update and make sure there aren't any [new] errors.

My /etc/apt/sources.list looks like this:

deb http://deb.debian.org/debian stretch main
deb http://deb.debian.org/debian stretch-updates main
deb http://security.debian.org stretch/updates main

Preferences

The least obvious (but equally important) step is to fix your apt pins. Similar to your sources, this is found in /etc/apt/preferences (and /etc/apt/preferences.d/*). Let's fix it!

$ grep -nr '\(testing\|buster\|unstable\|sid\)' /etc/apt/preferences*
/etc/apt/preferences:2:Pin: release a=testing

Unless you're doing some weird priority/pinning magic you can probably just remove everything from /etc/apt/preferences and go with the defaults.

Packages

Depending on how much of a monstrosity your FrankenDebian is, you may have a ton of packages with non-stable versions. That's not good, but it's fixable. First off, let's start with everyone's favorite: systemd.

$ apt show systemd -a
Package: systemd
Version: 236-3
Status: install ok installed
Priority: important
Section: admin
Maintainer: Debian systemd Maintainers <pkg-systemd-maintainers@lists.alioth.debian.org>
Installed-Size: 11.8 MB
Pre-Depends: libc6 (>= 2.8)
Depends: libacl1 (>= 2.2.51-8), libapparmor1 (>= 2.9.0-3+exp2), libaudit1 (>= 1:2.2.1), libblkid1 (>= 2.19.1), libc6 (>= 2.25), libcap2 (>= 1:2.10), libcryptsetup4 (>= 2:1.4.3), libgcrypt20 (>= 1.8.0), libgpg-error0 (>= 1.14), libidn11 (>= 1.13), libip4tc0 (>= 1.6.0+snapshot20161117), libkmod2 (>= 5~), liblz4-1 (>= 0.0~r130), liblzma5 (>= 5.1.1alpha+20120614), libmount1 (>= 2.26.2), libpam0g (>= 0.99.7.1), libseccomp2 (>= 2.3.1), libselinux1 (>= 2.1.9), libsystemd0 (= 236-3), util-linux (>= 2.27.1), mount (>= 2.26), adduser, procps
Recommends: libpam-systemd, dbus
Suggests: systemd-container, policykit-1
Breaks: apparmor (<< 2.9.2-1), ifupdown (<< 0.8.5~), laptop-mode-tools (<< 1.68~), systemd-shim (<< 10-3~), udev (<< 228-5)
Replaces: udev (<< 228-5)
Homepage: https://www.freedesktop.org/wiki/Software/systemd
Download-Size: unknown
APT-Manual-Installed: yes
APT-Sources: /var/lib/dpkg/status
Description: system and service manager
 systemd is a system and service manager for Linux. It provides aggressive
 parallelization capabilities, uses socket and D-Bus activation for starting
 services, offers on-demand starting of daemons, keeps track of processes using
 Linux control groups, maintains mount and automount points and implements an
 elaborate transactional dependency-based service control logic.
 .
 systemd is compatible with SysV and LSB init scripts and can work as a
 drop-in replacement for sysvinit.
 .
 Installing the systemd package will not switch your init system unless you
 boot with init=/bin/systemd or install systemd-sysv in addition.

Package: systemd
Version: 232-25+deb9u1
Priority: important
Section: admin
Maintainer: Debian systemd Maintainers <pkg-systemd-maintainers@lists.alioth.debian.org>
Installed-Size: 9,559 kB
Pre-Depends: libc6 (>= 2.8)
Depends: libacl1 (>= 2.2.51-8), libapparmor1 (>= 2.9.0-3+exp2), libaudit1 (>= 1:2.2.1), libblkid1 (>= 2.19.1), libc6 (>= 2.17), libcap2 (>= 1:2.10), libcryptsetup4 (>= 2:1.4.3), libgcrypt20 (>= 1.7.0), libgpg-error0 (>= 1.14), libidn11 (>= 1.13), libip4tc0 (>= 1.6.0+snapshot20161117), libkmod2 (>= 5~), liblz4-1 (>= 0.0~r127), liblzma5 (>= 5.1.1alpha+20120614), libmount1 (>= 2.26.2), libpam0g (>= 0.99.7.1), libseccomp2 (>= 2.3.1), libselinux1 (>= 2.1.9), libsystemd0 (= 232-25+deb9u1), util-linux (>= 2.27.1), mount (>= 2.26), adduser, procps
Recommends: libpam-systemd, dbus
Suggests: systemd-ui, systemd-container, policykit-1
Breaks: adjtimex (<< 1.29-6), aoetools (<< 36-1.1), apparmor (<< 2.10.95-1), arno-iptables-firewall (<< 2.0.1.f-1), atm-tools (<< 1:2.5.1-1.6), clvm (<< 2.02.156-1), cman (<< 3.1.8-1.3+rm), console-common (<< 0.7.89), ebtables (<< 2.0.10.4-3.5), eeepc-acpi-scripts (<< 1.1.12+nmu1), espeakup (<< 1:0.71-27.1), ferm (<< 2.2-3.1), fiaif (<< 1.23.1-4+rm), gfs2-cluster (<< 3.1.8-1), gfs2-utils (<< 3.1.8-1), gom (<< 0.30.2-7), hdparm (<< 9.48+ds-1), ifrename (<< 30~pre9-9), ifscheme (<< 1.7-4), ifupdown (<< 0.8.5~), ifupdown-extra (<< 0.27), ipsec-tools (<< 1:0.8.2+20140711-6), kbd (<< 2.0.3-2), keyboard-configuration (<< 1.141), laptop-mode-tools (<< 1.68~), live-tools (<< 1:20151214+nmu1), lvm2 (<< 2.02.104-1), mdadm (<< 3.4-2), mt-st (<< 1.3-1), multipath-tools (<< 0.5.0+git1.656f8865-3), natlog (<< 1.02.00-4), nbd-client (<< 1:3.14-1), netenv (<< 0.94.3-30+rm), nfs-common (<< 1:1.2.8-9.1), ocfs2-tools (<< 1.8.4-2), pidentd (<< 3.0.19.ds1-7.1), rdnssd (<< 1.0.1-5), rgmanager (<< 3.1.8-1.3+rm), rpcbind (<< 0.2.3-0.1), screen (<< 4.3.1-2), scsitools (<< 0.12-2.3), selinux-basics (<< 0.5.3), setserial (<< 2.17-49), shorewall (<< 5.0.3.1-1), shorewall-init (<< 5.0.3.1-1), shorewall-lite (<< 5.0.3.1-1), shorewall6 (<< 5.0.3.1-1), shorewall6-lite (<< 5.0.3.1-1), srptools (<< 1.0.3-1), switchconf (<< 0.0.15-1), systemd-shim (<< 10-3~), udev (<< 228-5), ufw (<< 0.34-1), virtualbox-guest-x11 (<< 5.0.12-dfsg-2), zfs-fuse (<< 0.7.0-13.1), zvbi (<< 0.2.35-10)
Replaces: udev (<< 228-5)
Homepage: https://www.freedesktop.org/wiki/Software/systemd
Tag: admin::boot, implemented-in::c, interface::daemon, role::program,
 works-with::software:running
Download-Size: 2,462 kB
APT-Sources: http://deb.debian.org/debian stretch/main amd64 Packages
Description: system and service manager
 systemd is a system and service manager for Linux. It provides aggressive
 parallelization capabilities, uses socket and D-Bus activation for starting
 services, offers on-demand starting of daemons, keeps track of processes using
 Linux control groups, maintains mount and automount points and implements an
 elaborate transactional dependency-based service control logic.
 .
 systemd is compatible with SysV and LSB init scripts and can work as a
 drop-in replacement for sysvinit.
 .
 Installing the systemd package will not switch your init system unless you
 boot with init=/bin/systemd or install systemd-sysv in addition.

We want the version where APT-Sources is set to our stretch repository, not the internal dpkg database. We'll use this to downgrade systemd and libsystemd at the same time:

sudo apt-get install libsystemd0=232-25+deb9u1 systemd=232-25+deb9u1

You'll get some terrifying warnings, and if you're lucky (like me!) you'll get an error about dependency issues. Run sudo apt --fix-broken install to figure out what the issue is and install the correct dependencies. You may have to do this multiple times, as the issue can cascade. Yes, this sucks, but here's an example:

$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
 util-linux : Breaks: mount (< 2.29.2-3~) but 2.29.2-1 is installed
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
$ sudo apt --fix-broken install
Reading package lists... Done
Building dependency tree
Reading state information... Done
Correcting dependencies... Done
The following packages will be REMOVED:
  mount systemd
WARNING: The following essential packages will be removed.
This should NOT be done unless you know exactly what you are doing!
  mount
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
1 not fully installed or removed.
After this operation, 12.2 MB disk space will be freed.
You are about to do something potentially harmful.
To continue type in the phrase 'Yes, do as I say!'
 ?] hell no
Abort.
$ sudo apt-get install util-linux=2.29.2-1
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
 fdisk : Breaks: util-linux (< 2.29.2-3~) but 2.29.2-1 is to be installed
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
$ sudo apt-get install util-linux=2.29.2-1 fdisk-
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  dosfstools util-linux-locales
The following packages will be REMOVED:
  fdisk
The following packages will be DOWNGRADED:
  util-linux
WARNING: The following essential packages will be removed.
This should NOT be done unless you know exactly what you are doing!
  fdisk
0 upgraded, 0 newly installed, 1 downgraded, 1 to remove and 0 not upgraded.
1 not fully installed or removed.
Need to get 0 B/981 kB of archives.
After this operation, 66.6 kB disk space will be freed.
You are about to do something potentially harmful.
To continue type in the phrase 'Yes, do as I say!'
 ?] Yes, do as I say!
debconf: delaying package configuration, since apt-utils is not installed
dpkg: warning: downgrading util-linux from 2.30.2-0.1 to 2.29.2-1
(Reading database ... 98229 files and directories currently installed.)
Preparing to unpack .../util-linux_2.29.2-1_amd64.deb ...
Unpacking util-linux (2.29.2-1) over (2.30.2-0.1) ...
Replaced by files in installed package fdisk (2.30.2-0.1) ...
(Reading database ... 98237 files and directories currently installed.)
Removing fdisk (2.30.2-0.1) ...
Setting up util-linux (2.29.2-1) ...
Setting up mount (2.29.2-1) ...
Processing triggers for mime-support (3.60) ...
Processing triggers for libc-bin (2.25-5) ...
Processing triggers for systemd (236-3) ...
Processing triggers for man-db (2.7.6.1-4) ...

Once systemd falls in line, you can move on to everything else:

sudo apt-get install $(apt-show-versions -a | grep ' stretch ' | awk '{ printf "%s=%s\n", $1, $2}')

This should produce a ton of output, but none of it should be particularly scary. If there are any conflicts (like above), fix them. It's complicated, but it should always be possible to resolve.

Finally, we can remove all remaining packages that aren't from stable or stretch:

sudo aptitude remove '?narrow(?narrow(?installed, !?essential), !?or(?archive(stable), ?archive(stretch)))' -F%p

If this creates a huge alert saying "THIS IS UNINSTALLING YOUR KERNEL", do yourself a favor and make sure Linux is installed before you reboot.

$ sudo apt-get install linux-image-amd64 linux-headers-amd64

Once this finishes, you'll want to update, dist-upgrade, and autoremove:

$ sudo apt-get dist-upgrade && sudo apt-get autoremove

🎉

Purge

You may look for old configuration files with dpkg -l | grep '^rc' | awk '{print $2}', and purge them with apt-get purge. If you're feeling lucky:

sudo apt-get purge $(dpkg -l | grep '^rc' | awk '{print $2}')

Backports

Debian stable is nice, but sometimes we need a package that's only available in testing/sid. There are two options:

  1. Create another FrankenDebian.
  2. Use Debian Backports.

If you chose the former, GOTO 1. If you'd like to join the rest of the [semi-]reasonable world in using Debian Backports, add this to your /etc/apt/sources.list:

deb http://ftp.debian.org/debian stretch-backports main

Checking which packages are available is as easy as sudo apt-get upgrade --dry-run -t stretch-backports, but we can make it prettier:

$ aptitude -t stretch-backports search "?narrow(?archive(stretch-backports), ?widen(?installed))" -F '%p %v => %V'
bind9-host                                                                                     1:9.10.3.dfsg. => 1:9.11.2.P1-1~
debootstrap                                                                                    1.0.89         => 1.0.92~bpo9+1 
distro-info-data                                                                               0.36           => 0.37~bpo9+1   
fonts-lyx                                                                                      2.2.2-1        => 2.2.3-2~bpo9+1
geoip-database                                                                                 20170512-1     => 20171107-1~bpo
git                                                                                            1:2.11.0-3+deb => 1:2.14.2-1~bpo
git-core                                                                                       1:2.11.0-3+deb => 1:2.14.2-1~bpo
git-man                                                                                        1:2.11.0-3+deb => 1:2.14.2-1~bpo
iproute2                                                                                       4.9.0-1+deb9u1 => 4.14.1-1~bpo9+
iptables                                                                                       1.6.0+snapshot => 1.6.1-2~bpo9+1
libfastjson4                                                                                   0.99.4-1       => 0.99.8-1~bpo9+
libibverbs-dev                                                                                 1.2.1-2        => 16.0-1~bpo9+1 
libibverbs1                                                                                    1.2.1-2        => 16.0-1~bpo9+1 
libip4tc0                                                                                      1.6.0+snapshot => 1.6.1-2~bpo9+1
libip6tc0                                                                                      1.6.0+snapshot => 1.6.1-2~bpo9+1
libiptc0                                                                                       1.6.0+snapshot => 1.6.1-2~bpo9+1
libjs-jquery-tablesorter                                                                       11-3           => 1:2.29.2+dfsg1
libldap-2.4-2                                                                                  2.4.44+dfsg-5+ => 2.4.45+dfsg-1~
libldap-common                                                                                 2.4.44+dfsg-5+ => 2.4.45+dfsg-1~
liblognorm5                                                                                    2.0.1-1.1+b1   => 2.0.3-1~bpo9+1
librdmacm1                                                                                     1.1.0-2        => 16.0-1~bpo9+1 
libsystemd0                                                                                    232-25+deb9u1  => 236-3~bpo9+1  
libtalloc2                                                                                     2.1.8-1        => 2.1.9-2~bpo9+1
libudev1                                                                                       232-25+deb9u1  => 236-3~bpo9+1  
libxtables12                                                                                   1.6.0+snapshot => 1.6.1-2~bpo9+1
linux-compiler-gcc-6-x86                                                                       4.9.65-3+deb9u => 4.14.13-1~bpo9
linux-headers-amd64                                                                            4.9+80+deb9u3  => 4.14+89~bpo9+1
linux-image-amd64                                                                              4.9+80+deb9u3  => 4.14+89~bpo9+1
linux-libc-dev                                                                                 4.9.65-3+deb9u => 4.14.13-1~bpo9
manpages                                                                                       4.10-2         => 4.14-1~bpo9+1 
manpages-dev                                                                                   4.10-2         => 4.14-1~bpo9+1 
rsyslog                                                                                        8.24.0-1       => 8.32.0-1~bpo9+
systemd                                                                                        232-25+deb9u1  => 236-3~bpo9+1  
tmux                                                                                           2.3-4          => 2.6-3~bpo9+1  
udev                                                                                           232-25+deb9u1  => 236-3~bpo9+1 

Need to upgrade Git? No problem.

sudo apt-get install -t stretch-backports git

Congratulations, you're back in business.

         _,met$$$$$gg.           christianbundy@mainframe.c.fraction-1254.internal
      ,g$$$$$$$$$$$$$$$P.        OS: Debian 9.3 stretch
    ,g$$P""       """Y$$.".      Kernel: x86_64 Linux 4.9.0-5-amd64
   ,$$P'              `$$$.      Uptime: 2m
  ',$$P       ,ggs.     `$$b:    Packages: 1224
  `d$$'     ,$P"'   .    $$$     Shell: zsh 5.3.1
   $$P      d$'     ,    $$P     CPU: Intel Xeon CPU @ 2.5GHz
   $$:      $$.   -    ,d$$'     RAM: 1622MiB / 15043MiB
   $$\;      Y$b._   _,d$P'
   Y$$.    `.`"Y$$$$P"'
   `$$b      "-.__
    `Y$$
     `Y$$.
       `$$b.
         `Y$$b.
            `"Y$b._
                `""""

License

GNU FDL 1.3

@David-Beetle
Copy link

Aye, great document. Would it be possible to add licensed? Maybe GNU FDL?

@christianbundy
Copy link
Author

@David-Beetle

I'd be happy to, thanks for the suggestion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment