27 Jan 2026
Planet Grep
Staf Wagemakers: Moved my blog to [blog.wagemakers.be](https://blog.wagemakers.be)

If you follow my blog posts with an RSS reader, update the rss feed to: https://blog.wagemakers.be/atom.xml
…If you want to continue to follow me off-course ;-)
I moved my blog from GitHub to my own hosting ( powered by Procolix ).
Procolix sponsored my hosting for 20 years, till I decided to start my company Mask27.dev.
One reason is that Microsoft seems to like to put "copilot everywhere", including on repositories hosted on github. While I don't dislike AI ( artificial intelligence ), LLM ( Large Language Models ) are a nice piece of technology. The security, privacy, and other issues are overlooked or even just ignored.
The migration was a bit more complicated as usual, as nothing "is easy" ;-)
You'll find the pitfalls of moving my blog below as they might be useful for somebody else ( including the future me ).
Html redirect
I use Jekyll to generate my webpages on my blog. I might switch to HUGO in the future.
While there're Jekyll plugins available to preform a redirect, I decide to keep it simple and added a http header to _includes/head.html
<meta http-equiv="refresh" content="0; url=https://blog.wagemakers.be/blog/2026/01/26/blog-wagemakers-be/" />
Hardcoded links
I had some hardcoded links for image, url, etc on my blog posts.
I used the script below to update the links in my _post directory.
#!/bin/sh
set -o errexit
set -o pipefail
set -o nounset
for file in *; do
echo "... Processing file: ${file}"
sed -i ${file} -e s@https://stafwag.github.io/blog/blog/@https://blog.wagemakers.be/blog/@g
sed -i ${file} -e s@https://stafwag.github.io/blog/images/@https://blog.wagemakers.be/images/@g
sed -i ${file} -e s@\(https://stafwag.github.io/blog\)@\(https://blog.wagemakers.be\)@
done
Disqus
I use DISQUS as the comment system on my blog. As the HTML pages got a proper redirect, I could ask Disqus to reindex the pages so the old comments became available again.
More information is available at: https://help.disqus.com/en/articles/1717126-redirect-crawler
Without a redirect, you can download the URL in a csv and add a migration URL to the csv file and upload it to Disqus. You can find information about it in the link below.
https://help.disqus.com/en/articles/1717129-url-mapper
RSS redirect
I didn't find a good way to redirect for RSS feeds, which RSS readers use correctly.
If you know a good way to handle it, please let me know.
I tried to add an XML redirect as suggested at: https://www.rssboard.org/redirect-rss-feed. But this doesn't seem to work with the RSS readers I tested (NewsFlash, Akregator).
These are the steps I took.
HTML header
I added the following headers to _includes/head.html
<link rel="self" type="application/atom+xml" href="{{ site.url }}{{ site.baseurl }}/atom.xml" />
<link rel="alternate" type="application/atom+xml" title="Wagemakers Atom Feed" href="https://wagemakers.be/atom.xml">
<<link rel="self" type="application/rss+xml" href="{{ site.url }}{{ site.baseurl }}/atom.xml" />
<link rel="alternate" type="application/rss+xml" title="Wagemakers Atom Feed" href="https://wagemakers.be/atom.xml">
Custom feed.xml
When I switched from Octopress to "plain jekyll" I started to use the jekyll-feedplugin. But I still had the old RSS page from Octopress available, so I decided to use it to generate atom.xml and feed.xml in the link rel=self and link rel="alternate" directives.
Full code below or on GitHub: https://github.com/stafwag/blog/blob/gh-pages/feed.xml
---
layout: null
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[stafwag Blog]]></title>
<link href="https://blog.wagemakers.be//atom.xml" rel="self"/>
<link rel="alternate" href="https://blog.wagemakers.be/atom.xml" /> <link href="https://blog.wagemakers.be }}"/>
<link rel="self" type="application/atom+xml" href="https://blog.wagemakers.be//atom.xml" />
<link rel="alternate" type="application/atom+xml" href="https://blog.wagemakers.be/atom.xml" />
<link rel="self" type="application/rss+xml" href="https://blog.wagemakers.be//atom.xml" />
<link rel="alternate" type="application/rss+xml" href="https://blog.wagemakers.be/atom.xml" />
<updated>2026-01-26T20:10:56+01:00</updated>
<id>https://blog.wagemakers.be</id>
<author>
<name><![CDATA[Staf Wagemakers]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
{% for post in site.posts limit: 10000 %}
<entry>
<title type="html"><![CDATA[{% if site.titlecase %}{{ post.title | titlecase | cdata_escape }}{% else %}{{ post.title | cdata_escape }}{% endif %}]]></title>
<link href="{{ site.url }}{{ site.baseurl }}{{ post.url }}"/>
<updated></updated>
<id>https://blog.wagemakers.be/</id>
<content type="html"><![CDATA[]]></content>
</entry>
{% endfor %}
</feed>
Notify users
I created this blog post to notify the users ;-)
Have fun!
Links
- https://help.disqus.com/en/articles/1717129-url-mapper
- https://help.disqus.com/en/articles/1717126-redirect-crawler
- https://www.heerentanna.com/blog/move-disqus-comment-old-url-new.html
- https://www.rssboard.org/redirect-rss-feed
27 Jan 2026 2:46am GMT
Mattias Geniar: Catching SQL performance issues in PHPUnit and Pest, as part of your test infrastructure
I've been on a bit of a SQL performance kick lately. Over at Oh Dear , I wrote a 3-part series about finding, fixing, and automatically detecting SQL performance issues . The last part of that series covers how we catch regressions before they hit production by running checks in our test suite.
27 Jan 2026 2:46am GMT
FOSDEM organizers: Present a lightning lightning talk
The same as last year: come and take part in a very rapid set of talks! Thought of a last minute topic you want to share? Got your interesting talk rejected? Has something exciting happened in the last few weeks you want to talk about? Get that talk submitted to Lightning Lightning Talks! We have two sessions for participants to speak about subjects which are interesting, amusing, or just something the FOSDEM audience would appreciate: Saturday Sunday Selected speakers line up and present in one continuous automated stream, with an SLO of 99% talk uptime. To submit your talk for舰
27 Jan 2026 2:46am GMT
26 Jan 2026
Planet Lisp
TurtleWare: McCLIM and 7GUIs - Part 1: The Counter
Table of Contents
For the last two months I've been polishing the upcoming release of McCLIM. The most notable change is the rewriting of the input editing and accepting-values abstractions. As it happens, I got tired of it, so as a breather I've decided to tackle something I had in mind for some time to improve the McCLIM manual - namely the 7GUIs: A GUI Programming Benchmark.
This challenge presents seven distinct tasks commonly found in graphical interface requirements. In this post I'll address the first challenge - The Counter. It is a fairly easy task, a warm-up of sorts. The description states:
Challenge: Understanding the basic ideas of a language/toolkit.
The task is to build a frame containing a label or read-only textfield T and a button B. Initially, the value in T is "0" and each click of B increases the value in T by one.
Counter serves as a gentle introduction to the basics of the language, paradigm and toolkit for one of the simplest GUI applications imaginable. Thus, Counter reveals the required scaffolding and how the very basic features work together to build a GUI application. A good solution will have almost no scaffolding.
In this first post, to make things more interesting, I'll solve it in two ways:
- using contemporary abstractions like layouts and gadgets
- using CLIM-specific abstractions like presentations and translators
In CLIM it is possible to mix both paradigms for defining graphical interfaces. Layouts and gadgets are predefined components that are easy to use, while using application streams enables a high degree of flexibility and composability.
First, we define a package shared by both versions:
(eval-when (:compile-toplevel :load-toplevel :execute)
(unless (member :mcclim *features*)
(ql:quickload "mcclim")))
(defpackage "EU.TURTLEWARE.7GUIS/TASK1"
(:use "CLIM-LISP" "CLIM" "CLIM-EXTENSIONS")
(:export "COUNTER-V1" "COUNTER-V2"))
(in-package "EU.TURTLEWARE.7GUIS/TASK1")
Note that "CLIM-EXTENSIONS" package is McCLIM-specific.
Version 1: Using Gadgets and Layouts
Assuming that we are interested only in the functionality and we are willing to ignore the visual aspect of the program, the definition will look like this:
(define-application-frame counter-v1 ()
((value :initform 0 :accessor value))
(:panes
;; v type v initarg
(tfield :label :label (princ-to-string (value *application-frame*))
:background +white+)
(button :push-button :label "Count"
:activate-callback (lambda (gadget)
(declare (ignore gadget))
(with-application-frame (frame)
(incf (value frame))
(setf (label-pane-label (find-pane-named frame 'tfield))
(princ-to-string (value frame)))))))
(:layouts (default (vertically () tfield button))))
;;; Start the application (if not already running).
;; (find-application-frame 'counter-v1)

The macro define-application-frame is like defclass with additional clauses. In our program we store the current value as a slot with an accessor.
The clause :panes is responsible for defining named panes (sub-windows). The first element is the pane name, then we specify its type, and finally we specify initargs for it. Panes are created in a dynamic context where the application frame is already bound to *application-frame*, so we can use it there.
The clause :layouts allows us to arrange panes on the screen. There may be multiple layouts that can be changed at runtime, but we define only one. The macro vertically creates another (anonymous) pane that arranges one gadget below another.
Gadgets in CLIM operate directly on top of the event loop. When the pointer button is pressed, it is handled by activating the callback, that updates the frame's value and the label. Effects are visible immediately.
Now if we want the demo to look nicer, all we need to do is to fiddle a bit with spacing and bordering in the :layouts section:
(define-application-frame counter-v1 ()
((value :initform 0 :accessor value))
(:panes
(tfield :label :label (princ-to-string (value *application-frame*))
:background +white+)
(button :push-button :label "Count"
:activate-callback (lambda (gadget)
(declare (ignore gadget))
(with-application-frame (frame)
(incf (value frame))
(setf (label-pane-label (find-pane-named frame 'tfield))
(princ-to-string (value frame)))))))
(:layouts (default
(spacing (:thickness 10)
(horizontally ()
(100
(bordering (:thickness 1 :background +black+)
(spacing (:thickness 4 :background +white+) tfield)))
(15 (make-pane :label))
(100 button))))))
;;; Start the application (if not already running).
;; (find-application-frame 'counter-v1)

This gives us a layout that is roughly similar to the example presented on the 7GUIs page.
Version 2: Using the CLIM Command Loop
Unlike gadgets, stream panes in CLIM operate on top of the command loop. A single command may span multiple events after which we redisplay the stream to reflect the new state of the model. This is closer to the interaction type found in the command line interfaces:
(define-application-frame counter-v2 ()
((value :initform 0 :accessor value))
(:pane :application
:display-function (lambda (frame stream)
(format stream "~d" (value frame)))))
(define-counter-v2-command (com-incf-value :name "Count" :menu t)
()
(with-application-frame (frame)
(incf (value frame))))
;; (find-application-frame 'counter-v2)

Here we've used :pane option this is a syntactic sugar for when we have only one named pane. Skipping :layouts clause means that named panes will be stacked vertically one below another.
Defining the application frame defines a command-defining macro. When we define a command with define-counter-v2-command, then this command will be inserted into a command table associated with the frame. Passing the option :menu t causes the command to be available in the frame menu as a top-level entry.
After the command is executed (in this case it modifies the counter value), the application pane is redisplayed; that is a display function is called, and its output is captured. In more demanding scenarios it is possible to refine both the time of redisplay and the scope of changes.
Now we want the demo to look nicer and to have a button counterpart placed beside the counter value, to resemble the example more:
(define-presentation-type counter-button ())
(define-application-frame counter-v2 ()
((value :initform 0 :accessor value))
(:menu-bar nil)
(:pane :application
:width 250 :height 32
:borders nil :scroll-bars nil
:end-of-line-action :allow
:display-function (lambda (frame stream)
(formatting-item-list (stream :n-columns 2)
(formatting-cell (stream :min-width 100 :min-height 32)
(format stream "~d" (value frame)))
(formatting-cell (stream :min-width 100 :min-height 32)
(with-output-as-presentation (stream nil 'counter-button :single-box t)
(surrounding-output-with-border (stream :padding-x 20 :padding-y 0
:filled t :ink +light-grey+)
(format stream "Count"))))))))
(define-counter-v2-command (com-incf-value :name "Count" :menu t)
()
(with-application-frame (frame)
(incf (value frame))))
(define-presentation-to-command-translator act-incf-value
(counter-button com-incf-value counter-v2)
(object)
`())
;; (find-application-frame 'counter-v2)

The main addition is the definition of a new presentation type counter-button. This faux button is printed inside a cell and surrounded with a background. Later we define a translator that converts clicks on the counter button to the com-incf-value command. The translator body returns arguments for the command.
Presenting an object on the stream associates a semantic meaning with the output. We can now extend the application with new gestures (names :scroll-up and :scroll-down are McCLIM-specific):
(define-counter-v2-command (com-scroll-value :name "Increment")
((count 'integer))
(with-application-frame (frame)
(if (plusp count)
(incf (value frame) count)
(decf (value frame) (- count)))))
(define-presentation-to-command-translator act-scroll-up-value
(counter-button com-scroll-value counter-v2 :gesture :scroll-up)
(object)
`(10))
(define-presentation-to-command-translator act-scroll-dn-value
(counter-button com-scroll-value counter-v2 :gesture :scroll-down)
(object)
`(-10))
(define-presentation-action act-popup-value
(counter-button nil counter-v2 :gesture :describe)
(object frame)
(notify-user frame (format nil "Current value: ~a" (value frame))))
A difference between presentation to command translators and presentation actions is that the latter does not automatically progress the command loop. Actions are often used for side effects, help, inspection etc.
Conclusion
In this short post we've solved the first task from the 7GUIs challenge. We've used two techniques available in CLIM - using layouts and gadgets, and using display and command tables. Both techniques can be combined, but differences are visible at a glance:
- gadgets provide easy and reusable components for rudimentary interactions
- streams provide extensible and reusable abstractions for semantic interactions
This post only scratched the capabilities of the latter, but the second version demonstrates why the command loop and presentations scale better than gadget-only solutions.
Following tasks have gradually increasing level of difficulty that will help us to emphasize how useful are presentations and commands when we want to write maintainable applications with reusable user-defined graphical metaphors.
26 Jan 2026 12:00am GMT
Planet Debian
Otto Kekäläinen: Ubuntu Pro subscription - should you pay to use Linux?

Ubuntu Pro is a subscription offering for Ubuntu users who want to pay for the assurance of getting quick and high-quality security updates for Ubuntu. I tested it out to see how it works in practice, and to evaluate how well it works as a commercial open source service model for Linux.
Anyone running Ubuntu can subscribe to it at ubuntu.com/pro/subscribe by selecting the setup type "Desktops" for the price of $25 per year (+applicable taxes) for Enterprise users. There is also a free version for personal use. Once you have an account, you can find your activation token at ubuntu.com/pro/dashboard, and use it to activate Ubuntu Pro on your desktop or laptop Ubuntu machine by running sudo pro attach <token>:
$ sudo pro attach aabbcc112233aabbcc112233 Enabling default service esm-apps Updating package lists Ubuntu Pro: ESM Apps enabled Enabling default service esm-infra Updating package lists Ubuntu Pro: ESM Infra enabled Enabling default service livepatch Installing canonical-livepatch snap Canonical livepatch enabled. Unable to determine current instance-id This machine is now attached to 'Ubuntu Pro Desktop'
$ sudo pro attach aabbcc112233aabbcc112233
Enabling default service esm-apps
Updating package lists
Ubuntu Pro: ESM Apps enabled
Enabling default service esm-infra
Updating package lists
Ubuntu Pro: ESM Infra enabled
Enabling default service livepatch
Installing canonical-livepatch snap
Canonical livepatch enabled.
Unable to determine current instance-id
This machine is now attached to 'Ubuntu Pro Desktop'You can at any time confirm the Ubuntu Pro status by running:
$ sudo pro status --all SERVICE ENTITLED STATUS DESCRIPTION anbox-cloud yes disabled Scalable Android in the cloud cc-eal yes n/a Common Criteria EAL2 Provisioning Packages esm-apps yes enabled Expanded Security Maintenance for Applications esm-infra yes enabled Expanded Security Maintenance for Infrastructure fips yes n/a NIST-certified FIPS crypto packages fips-preview yes n/a Preview of FIPS crypto packages undergoing certification with NIST fips-updates yes disabled FIPS compliant crypto packages with stable security updates landscape yes enabled Management and administration tool for Ubuntu livepatch yes disabled Canonical Livepatch service realtime-kernel yes disabled Ubuntu kernel with PREEMPT_RT patches integrated ├ generic yes disabled Generic version of the RT kernel (default) ├ intel-iotg yes n/a RT kernel optimized for Intel IOTG platform └ raspi yes n/a 24.04 Real-time kernel optimised for Raspberry Pi ros yes n/a Security Updates for the Robot Operating System ros-updates yes n/a All Updates for the Robot Operating System usg yes disabled Security compliance and audit tools Enable services with: pro enable <service> Account: Otto Kekalainen Subscription: Ubuntu Pro Desktop Valid until: Thu Mar 3 08:08:38 2026 PDT Technical support level: essential
$ sudo pro status --all
SERVICE ENTITLED STATUS DESCRIPTION
anbox-cloud yes disabled Scalable Android in the cloud
cc-eal yes n/a Common Criteria EAL2 Provisioning Packages
esm-apps yes enabled Expanded Security Maintenance for Applications
esm-infra yes enabled Expanded Security Maintenance for Infrastructure
fips yes n/a NIST-certified FIPS crypto packages
fips-preview yes n/a Preview of FIPS crypto packages undergoing certification with NIST
fips-updates yes disabled FIPS compliant crypto packages with stable security updates
landscape yes enabled Management and administration tool for Ubuntu
livepatch yes disabled Canonical Livepatch service
realtime-kernel yes disabled Ubuntu kernel with PREEMPT_RT patches integrated
├ generic yes disabled Generic version of the RT kernel (default)
├ intel-iotg yes n/a RT kernel optimized for Intel IOTG platform
└ raspi yes n/a 24.04 Real-time kernel optimised for Raspberry Pi
ros yes n/a Security Updates for the Robot Operating System
ros-updates yes n/a All Updates for the Robot Operating System
usg yes disabled Security compliance and audit tools
Enable services with: pro enable <service>
Account: Otto Kekalainen
Subscription: Ubuntu Pro Desktop
Valid until: Thu Mar 3 08:08:38 2026 PDT
Technical support level: essentialFor a regular desktop/laptop user the most relevant service is the esm-apps, which delivers extended security updates to many applications typically used on desktop systems.
Another relevant command to confirm the current subscription status is:
$ sudo pro security-status 2828 packages installed: 2143 packages from Ubuntu Main/Restricted repository 660 packages from Ubuntu Universe/Multiverse repository 13 packages from third parties 12 packages no longer available for download To get more information about the packages, run pro security-status --help for a list of available options. This machine is receiving security patching for Ubuntu Main/Restricted repository until 2029. This machine is attached to an Ubuntu Pro subscription. Ubuntu Pro with 'esm-infra' enabled provides security updates for Main/Restricted packages until 2034. Ubuntu Pro with 'esm-apps' enabled provides security updates for Universe/Multiverse packages until 2034. You have received 26 security updates.
$ sudo pro security-status
2828 packages installed:
2143 packages from Ubuntu Main/Restricted repository
660 packages from Ubuntu Universe/Multiverse repository
13 packages from third parties
12 packages no longer available for download
To get more information about the packages, run
pro security-status --help
for a list of available options.
This machine is receiving security patching for Ubuntu Main/Restricted
repository until 2029.
This machine is attached to an Ubuntu Pro subscription.
Ubuntu Pro with 'esm-infra' enabled provides security updates for
Main/Restricted packages until 2034.
Ubuntu Pro with 'esm-apps' enabled provides security updates for
Universe/Multiverse packages until 2034. You have received 26 security
updates.This confirms the scope of the security support. You can even run sudo pro security-status --esm-apps to get a detailed breakdown of the installed software packages in scope for Expanded Security Maintenance (ESM).
Experiences from using Ubuntu Pro for over a year
Personally I have been using it on two laptop systems for well over a year now and everything seems to have worked well. I see apt is downloading software updates from https://esm.ubuntu.com/apps/ubuntu, but other than that there aren't any notable signs of Ubuntu Pro being in use. That is a good thing - after all one is paying for assurance that everything works with minimum disruptions, so the system that enables smooth sailing should stay in the background and not make too much noise of itself.
Using Landscape to manage multiple Ubuntu laptops

Landscape.canonical.com is a fleet management system that shows information like security update status and resource utilization for the computers you administer. Ubuntu Pro attached systems under one's account are not automatically visible in Landscape, but have to be enrolled in it.
To enroll an Ubuntu Pro attached desktop/laptop to Landscape, first install the required package with sudo apt install landscape-client and then run sudo landscape-config --account-name <account name> to start the configuration wizard. You can find your account name in the Landscape portal. On the last wizard question Request a new registration for this computer now? [y/N] hit y to accept. If successful, the new computer will be visible on the Landscape portal page "Pending computers", from where you can click to accept it.

If I had a large fleet of computers, Landscape might come in useful. Also it is obvious Landscape is intended primarily for managing server systems. For example, the default alarm trigger on systems being offline, which is common for laptops and desktop computers, is an alert-worthy thing only on server systems.
It is good to know that Landscape exists, but on desktop systems I would probably skip it, and only stick to the security updates offered by Ubuntu Pro without using Landscape.
Landscape is evolving
The screenshots above are from the current Landscape portal which I have been using so far. Recently Canonical has also launched a new web portal, with a fresh look:

This shows Canonical is actively investing in the service and it is likely going to sit at the center of their business model for years to come.
Other offerings by Canonical for individual users
Canonical, the company behind the world's most popular desktop Linux distribution Ubuntu, has been offering various commercial support services for corporate customers since the company launched back in 2005, but there haven't been any offerings available to individual users since Ubuntu One, with file syncing, a music store and more, was wound down back in 2014. Canonical and the other major Linux companies, Red Hat and SUSE, have always been very enterprise-oriented, presumably because achieving economies of scale is much easier when maintaining standardized corporate environments compared to dealing with a wide range of custom configurations that individual consumer customers might have. I remember some years ago Canonical offered desktop support under the Ubuntu Advantage product name, but the minimum subscription was for 5 desktop systems, which typically isn't an option for a regular home consumer.
I am glad to see Ubuntu Pro is now available and I honestly hope people using Ubuntu will opt into it. The more customers it has, the more it incentivizes Canonical to develop and maintain features that are important for desktop and home users.
Pay for Linux because you can, not because you have to
Open source is a great software development model for rapid innovation and adoption, but I don't think the business models in the space are yet quite mature. Users who get long-term value should participate more in funding open source maintenance work. While some donation platforms like GitHub Sponsors, OpenCollective and the like have gained popularity in recent years, none of them seem to generate recurring revenue comparable to the scale of how popular open source software is now in 2026.
I welcome more paid schemes, such as Ubuntu Pro, as I believe it is beneficial for the whole ecosystem. I also expect more service providers to enter this space and experiment with different open source business models and various forms of decentralized funding. Linux and open source are primarily free as in speech, but as a side effect license fees are hard to enforce and many use Linux without paying for it. The more people, corporations and even countries rely on it to stay sovereign in the information society, the more users should think about how they want to use Linux and who they want to pay to maintain it and other critical parts of the open source ecosystem.
26 Jan 2026 12:00am GMT
25 Jan 2026
Planet Debian
Anton Gladky: Introducing v2/changelogs FTP-Master API
v2/changelogs - FTP-Master API released and how can it be used to track your uploads
25 Jan 2026 5:50pm GMT
24 Jan 2026
Planet Debian
Gunnar Wolf: Finally some light for those who care about Debian on the Raspberry Pi

Finally, some light at the end of the tunnel!
As I have said in this blog and elsewhere, after putting quite a bit of work into generating the Debian Raspberry Pi images between late 2018 and 2023, I had to recognize I don't have the time and energy to properly care for it.
I even registered a GSoC project for it. I mentored Kurva Prashanth, who did good work on the vmdb2 scripts we use for the image generation - but in the end, was unable to push them to be built in Debian infrastructure. Maybe a different approach was needed! While I adopted the images as they were conceived by Michael Stapelberg, sometimes it's easier to start from scratch and build a fresh approach.
So, I'm not yet pointing at a stable, proven release, but to a good promise. And I hope I'm not being pushy by making this public: in the #debian-raspberrypi channel, waldi has shared the images he has created with the Debian Cloud Team's infrastructure.
So, right now, the images built so far support Raspberry Pi families 4 and 5 (notably, not the 500 computer I have, due to a missing Device Tree, but I'll try to help figure that bit out… Anyway, p400/500/500+ systems are not that usual). Work is underway to get the 3B+ to boot (some hackery is needed, as it only understands MBR partition schemes, so creating a hybrid image seems to be needed).

Sadly, I don't think the effort will be extended to cover older, 32-bit-only systems (RPi 0, 1 and 2).
Anyway, as this effort stabilizes, I will phase out my (stale!) work on raspi.debian.net, and will redirect it to point at the new images.
24 Jan 2026 4:24pm GMT
20 Jan 2026
Planet Lisp
Joe Marshall: Filter
One of the core ideas in functional programming is to filter a set of items by some criterion. It may be somewhat suprising to learn that lisp does not have a built-in function named "filter" "select", or "keep" that performs this operation. Instead, Common Lisp provides the "remove", "remove-if", and "remove-if-not" functions, which perform the complementary operation of removing items that satisfy or do not satisfy a given predicate.
The remove function, like similar sequence functions, takes an optional keyword :test-not argument that can be used to specify a test that must fail for an item to be considered for removal. Thus if you invert your logic for inclusion, you can use the remove function as a "filter" by specifying the predicate with :test-not.
> (defvar *nums* (map 'list (λ (n) (format nil "~r" n)) (iota 10)))
*NUMS*
;; Keep *nums* with four letters
> (remove 4 *nums* :key #'length :test-not #'=)
("zero" "four" "five" "nine")
;; Keep *nums* starting with the letter "t"
> (remove #\t *nums* :key (partial-apply-right #'elt 0) :test-not #'eql)
("two" "three")20 Jan 2026 11:46am GMT
16 Jan 2026
Planet Lisp
Scott L. Burson: FSet v2.2.0: JSON parsing/printing using Jzon
FSet v2.2.0, which is the version included in the recent Quicklisp release, has a new Quicklisp-loadable system, FSet/Jzon. It extends the Jzon JSON parser/printer to construct FSet collections when reading, and to be able to print them.
On parsing, JSON arrays produce FSet seqs; JSON objects produce FSet replay maps by default, but the parser can also be configured to produce ordinary maps or FSet tuples. For printing, any of these can be handled, as well as the standard Jzon types. The tuple representation provides a way to control the printing of `nil`, depending on the type of the corresponding key.
For details, see the GitLab MR.
NOTE: unfortunately, the v2.1.0 release had some bugs in the new seq code, and I didn't notice them until after v2.2.0 was in Quicklisp. If you're using seqs, I strongly recommend you pick up v2.2.2 or newer from GitLab or GitHub.
16 Jan 2026 8:05am GMT
12 Jan 2026
FOSDEM 2026
Birds of a Feather/Unconference rooms
As in previous years, some small rooms will be available for Unconference style "Birds of a Feather sessions". The concept is simple: Any project or community can reserve a timeslot (1 hour) during which they have the room just to themselves. These rooms are intended for ad-hoc discussions, meet-ups or brainstorming sessions. They are not a replacement for a developer room and they are certainly not intended for talks. To apply for a BOF session, enter your proposal at https://fosdem.org/submit. Select the BOF/Unconference track and mention in the Submission Notes your preferred timeslots and any times you are unavailable. Also舰
12 Jan 2026 11:00pm GMT
10 Jan 2026
FOSDEM 2026
Travel and transportation advisories
Attendees should be aware of potential transportation disruptions in the days leading up to FOSDEM. Rail travel Railway unions have announced a strike notice from Sunday January 25th, 22:00 until Friday January 30th, 22:00. This may affect travel to Brussels for FOSDEM and related fringe events. While there will be a guaranteed minimum service in place, train frequency may be significantly reduced. Also note that international connections might be affected as well. Road travel From Saturday January 31st (evening) until Sunday February 1st (noon), the E40 highway between Leuven and Brussels will be fully closed. Traffic will be diverted via舰
10 Jan 2026 11:00pm GMT
09 Jan 2026
FOSDEM 2026
FOSDEM Junior Registration
We are pleased to announce the schedule for FOSDEM Junior. Registration for the individual workshops is required. Links to the registration page can be found on the page of each activity. The full schedule can be viewed on the junior track schedule page.
09 Jan 2026 11:00pm GMT