Upgraded to bullseye

I've upgraded my personal notebook – with a file system that has a continuous history back to a slackware in 1996 and thus always is the most rewarding thing to test upgrades on – to Debian bullseye today.

It's been a while since the last dist-upgrade messed up my X or rendered a machine unbootable, but they still never fail to be exciting. This one was no exception.

logind and systemd

The one major trouble as far as Debian proper is concerned was that the full-upgrade pulled in systemd again (which I still can't get myself to adopt on boxes I fiddle with a lot). This was because at some point I had purged elogind (which doesn't do anything on this box), and both a few KDE programs I have installed and the indispensable gparted need policykit-1, which in turn pulls in some logind; if you don't have one, apt will migrate you to systemd.

Well, it was easy to go back this time: Just say:

apt install elogind
apt install sysvinit-core

and all is back to normal again with the wonderful shell script goo during system startup. Hooray for elogind! I will admit I've not quite figured out what its actual use is, though. But that's probably because I've never quite figured out policykit, which in turn is probably because I think there's nothing wrong with sudo. But, as you'll see in a second, I might be swayed.

Sure enough: Power

I'm running all kinds of interesting scripts when the machine goes through various power states; for instance, I'm kill -STOP-ing a few pieces of moving eye candy when the box loses grid power, and I'm kill -CONT-ing them when the power is back. This happens through shell scripts I've dropped into /etc/pm/power.d, from where pm-utils has nicely been executing them for the last 10 years or so.

Alas, they didn't run any more after the upgrade. Instead, when I shut the lid, the box would sleep right again after waking up. This last thing was fixed quickly: Just tell elogind not to bother in /etc/elogind/logind.conf.

That the pre-sleep and post-wakeup scripts still ran soothed my first worry – that pm-utils might have had an RC- (release critical) bug and dropped out of Debian. Going through pm-utils' /usr/share/doc info made me worry again, though: the last upstream change there is from 2010, and the last Debian changelog entry is from 2019, mentioning an open RC bug. Uh-oh. It seems I might soon need to try harder with elogind.

But not just yet, as the trace to work this out was bug #772275 (oh yes, the bug page for pm-utils makes we worry, too): pm-utils used to receive the AC/Battery notification from acpi-support, and that clearly broke in some way. At least for me, and with this upgrade. Poking around a bit in /etc/apci didn't show an immediate hook; yes, there's power.sh, but that gets called a lot on my box if the moon is right (for Lenovo's crappy firmware at least), and one would need to figure out whether or not there's grid power oneself.

So, I dug a bit deeper and noticed that ever since I've moved from laptop-mode-tools to tlp, pm-utils were almost obsolete because tlp actually does everything it does all without pm-utils – but it doesn't let me run my beloved shell scripts (“by design“, its authors say). Hence, it's not byebye to pm-utils yet.

But I like the way that tlp uses to be notified of power events: through udev. Taking that thought a bit further so I don't have to do any manual state management (as pm-utils doesn't have the equivalent of tlp auto) and filter out power events for batteries (which I don't care about), I ended up introducing two new udev rules that look relatively generic to me:

ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains",\
  ATTR{online}=="1", RUN+="/usr/sbin/pm-powersave false"
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains",\
  ATTR{online}=="0", RUN+="/usr/sbin/pm-powersave true"

Drop this into /etc/udev/rules.d/10local.rules (or so), and pm-utils' power.d works again.

Another python2 grace time

But the real elephant in the room is that bullseye in effect drops Python version 2. While this certainly does not come as a surprise, it still hurts me a lot, because I have plenty of self-written larger or smaller python2 programs – my audiobook-reader, my local wikipedia, my work time accounting and a gazillion little other things. And there's things like editmoin that haven't been ported yet either.

Well, I had hoped I could keep the buster python2 packages around, perhaps even using the python-is-python2 package. But really, I don't think that's an option for a halfway lively system (which will use quite a few python3 packages). I gave up on that idea more or less as soon as I realised that the python-docutils-common dependency (and docutils I need left and right) will conflict between the docutils from buster and from bullseye. Trying to keep buster packages will clearly become incredibly fiddly.

So, instead I figured I ought to keep the legacy software alive while finally porting it as I go along (one, my one-line CLI, I actually have ported this morning) using a python2 “virtual” (yeah, right, virtual...) environment.

Yes, virtual environments are evil all around, not only because their content rots without anyone noticing; but then this is exactly about letting things rot in a halfway controlled fashion, so I claim this is a use case.

In case others mourn the demise of python2 in bullseye and want to go slowly when migrating, here's what to do:

  1. Make sure the python2 packages that still are in bullseye are in place. This would be python2.7, python2.7-dev, and presumably python-tk. Of course, you will want the virtualenv package, but that's already python3.

  2. Create the virtual environment:

    virtualenv -p python2.7 ~/.legacy-python
  3. Make it simple to use that. For that, add:

    alias enable-oldpython='export PATH=~/.legacy-python/bin:$PATH'

    to your .aliases (or whereever else you keep your aliases) and exec bash in the current shell to try that out. This is when you want want to run pip, or at any other time when you want your python to be what's in the virtual environment.

    But this won't work for hashbangs. To make that work, put a file like:

    export PATH=/home/<YOUR USERNAME>/.legacy-python/bin/:$PATH
    exec python "$@"

    somewhere into your path as, say, oldpython. Since I still have some system-wide things using python2, I ended up sticking this into /usr/local/bin. Given python2 has been out of security support for more than a year now, I might be regretting that; on the other hand, python's core hasn't had many security problems in the past 20 years, and so I figure I am fine. Caveat emptor, though.

  4. Then, run pip install and/or python setup.py install to your heart's delight. All this isn't forever, so this one time I found myself capable of forgetting the long run, later upgrades, and all that. Just remember: sudo and pip never mix, and they particularly badly mix here. Oh: I actually found myself apt-get source-ing python packages from buster and just running python setup.py install in them because in my book that's a good deal less obscure than pip.

Limping along with a private MoinMoin

But then came the bitter realisation: There's no moinmoin in bullseye any more. That's a killer for at least three servers I'm operating. And, really, looking at what the MoinMoin folks write on python3 (in particular at its list of dependencies), I shudder in the expectation of seeing something quite in line with my unpleasant experiences with mailman2 happen with MoinMoin.

On my box, however, I can live with an aging service (that only listens to localhost), and I can live with having moinmoin be a CGI. In case these considerations (typically, for a “notes and observations”-style wiki) apply to you as well, here's what I did to make the legacy moinmoin run in my bullseye apache2.

First, I installed moinmoin into the “virtual” python 2.7 I created above:

enable-oldpython  # the alias above
pip install moin  # no sudo!

Then I fixed the apache configuration to use that. So, I commented out the previous MoinMoin integration and replaced it with something like:

<Directory /home/<YOUR USER NAME>/.legacy-python/share/moin/server>
  AllowOverride None
  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
  Require all granted
<Directory /home/<YOUR USER NAME>/.legacy-python/lib/python2.7/site-packages/MoinMoin/web/static/htdocs>
  AllowOverride None
  Require all granted

ScriptAlias /meiner /home/<YOUR USER NAME>/.legacy-python/share/moin/server/moin.cgi
Alias /wiki/ /home/<YOUR USER NAME>/.legacy-python/lib/python2.7/site-packages/MoinMoin/web/static/htdocs
Alias /moin_static1911 /home/<YOUR USER NAME>/.legacy-python/lib/python2.7/site-packages/MoinMoin/web/static/htdocs

(you may need to use other numbers in moin_static1911 if your moin is newer than 1.9.11). Incidentally, the non-AllowOverrides are defensive to ward off chaos that may ensue by intervening .htaccess-es – I once had forgotten one in my home...

Finally, in ~/.legacy-python/share/moin/server/moin.cgi, fix the hashbang so it's actually your old, “virtual” python; the way I did it above, it would be:


Of course, only do that at home.

Kategorie: edv

Letzte Ergänzungen