profile picture

Michael Stapelberg

All Blog Posts

Filter by tag:
Go to page:

2019 › February

  • Motivation I have recently been looking into speeding up Debian Code Search. As a quick reminder, search engines answer queries by consulting an inverted index: a map from term to documents containing that term (called a “posting list”). See the Debian Code Search Bachelor Thesis (PDF) for a lot more details. Read more →

2018 › December

  • My use-case is seemingly very simple: I want to run a webserver in a Docker container, and it should be reachable via IPv4 and IPv6. The webserver has multiple virtual hosts, some of which just serve static files, while others proxy to, say, a Grafana instance, which is also running in a Docker container. Read more →

2018 › October

  • Our computer association NoName e.V. organizes a retro computing event called RGB2R every year, located in Heidelberg, Germany. This year’s version is called RGB2Rv18. This article describes the network setup I created for this year’s event. If you haven’t read it, the article about last year’s RGB2Rv17 network is also available. Read more →

2018 › June

  • This is taken care of: Gunnar Wolf has taken on maintenance of the Raspberry Pi image. Thank you! (Cross-posting this message I sent to pkg-raspi-maintainers for broader visibility.) I started building Raspberry Pi images because I thought there should be an easy, official way to install Debian on the Raspberry Pi. Read more →

2018 › May

  • Update (2021) Update (2021): After Dell didn’t update their Linux version for a while, I concluded it would be best to just install a standard Ubuntu Linux. All required drivers are upstreamed, and I never needed the Dell tools that come with their version. Read more →

2018 › April

  • This post is part of a series of posts about the kinX project. Latency measurement End-to-end latency consists of 3 parts: input latency (keyboard) processing latency (computer) output latency (monitor) During the development of the kinX keyboard controller, I realized that measuring processing latency was quite simple with my hardware: I could start a timer when sending a key press HID report to the computer and measure the elapsed time when I would receive a reply from the computer. Read more →

  • This post is part of a series of posts about the kinX project. Motivation The Kinesis Advantage comes with a built-in 2-port USB hub. That hub uses a proprietary connector to interface with a PS/2 keyboard controller, so it cannot be used with a USB keyboard controller. As the built-in hub is the natural place to connect the Logitech unified receiver dongle, not being able to use the hub is mildly annoying. Read more →

  • This post is part of a series of posts about the kinX project. Background 10 years ago I got a Kinesis Advantage keyboard. I wrote about the experience of learning to touch-type using the ergonomic NEO layout in my (German) post “Neo-Layout auf einer Kinesis-Tastatur”. Read more →

  • The kinX project is described in a series of blog posts: While not strictly a part of this series, “Hacking your own Kinesis keyboard controller” describes the first controller I built in 2013 (maybe interesting for context). The first post introduces the kinX, a keyboard controller with merely 0.33ms of input latency (including USB). Read more →

2018 › March

  • I have heard a number of times that sbuild is too hard to get started with, and hence people don’t use it. To reduce hurdles from using/contributing to Debian, I wanted to make sbuild easier to set up. sbuild ≥ 0.74.0 provides a Debian package called sbuild-debian-developer-setup. Once installed, run the sbuild-debian-developer-setup(1) command to create a chroot suitable for building packages for Debian unstable. Read more →

  • motivation To run the tests of my i3 Go package, I use the following command: go test -v go.i3wm.org/... To run the tests of my i3 Go package on a different architecture, the only thing I should need to change is to declare the architecture by setting GOARCH=arm64: Read more →

  • dput-ng ≥ 1.16 contains two usability changes which make uploading easier: When no arguments are specified, dput-ng auto-selects the most recent .changes file (with confirmation). Instead of erroring out when detecting an unsigned .changes file, debsign(1) is invoked to sign the .changes file before proceeding. With these changes, after building a package, you just need to type dput (in the correct directory of course) to sign and upload it. Read more →

2018 › January

  • If you want to follow along at home, clone this repository: % GBP_CONF_FILES=:debian/gbp.conf gbp clone https://anonscm.debian.org/git/pkg-go/packages/golang-github-go-macaron-inject.git Now, in the golang-github-go-macaron-inject directory, I’m aware of three ways to obtain an orig tarball (please correct me if there are more): Run gbp buildpackage, creating an orig tarball from git (upstream/0.0_git20160627.0.d8a0b86) The resulting sha1sum is d085a04b7b35856be24f8cc4a9a6d9799cdb59b4. Run pristine-tar checkout The resulting sha1sum is d51575c0b00db5fe2bbf8eea65bc7c4f767ee954. Run origtargz The resulting sha1sum is d51575c0b00db5fe2bbf8eea65bc7c4f767ee954. Have a look at the archive’s golang-github-go-macaron-inject_0.0~git20160627.0.d8a0b86-2.dsc, however: the file entry orig tarball reads: Read more →

  • Background A short summary of my backup strategy is: I run daily backups to my NAS. In order to recover from risks like my apartment burning down or my belongings being stolen, I like to keep one copy of my data off-site, updated less frequently. Read more →

  • I previously wrote about my Debian buster preview image for the Raspberry Pi 3. Now, I’m publishing an updated version, containing the following changes: WiFi works out of the box. Use e.g. ip link set dev wlan0 up, and iwlist wlan0 scan. Kernel boot messages are now displayed on an attached monitor (if any), not just on the serial console. Root file system resizing will now not touch the partition table if the user modified it. The image is now compressed using xz, reducing its size to 170M. As before, the image is built with vmdb2, the successor to vmdebootstrap. The input files are available at https://github.com/Debian/raspi3-image-spec. Read more →

2017 › December

  • Background Ever since I first used a MacBook Pro with Retina display back in 2013, I’ve been madly in love with hi-DPI displays. I had seen the device before, and marvelled at brilliant font quality with which scientific papers would be rendered. But it wasn’t until I had a chance to use the device for a few hours to make i3 compatible with hi-DPI displays that I realized what a difference it makes in the day-to-day life. Read more →

2017 › November

  • Our computer association NoName e.V. organizes a retro computing event called RGB2R every year, located in Heidelberg, Germany. This year’s version is called RGB2Rv17. This article describes the network setup I created for this year’s event. The intention is not so much to provide a fully working setup (even though the setup did work fine for us as-is), but rather inspire to you to create your own network, based vaguely on what’s provided here. Read more →

2017 › October

  • In the pkg-go team, we are currently discussing which workflows we should standardize on. One of the considerations is what goes into the “upstream” Git branch of our repositories: should it track the upstream Git repository, or should it contain orig tarball imports? Read more →

  • Because I found it frustratingly hard to make GitLab and dex talk to each other, this article walks you through what I did step-by-step. Let’s establish some terminology: dex is our OpenID Connect (OIDC) “Provider (OP)” in other words: the component which verifies usernames and passwords. Read more →

  • UNIX distributions used to come with the system source code in /usr/src. This is a concept which fascinates me: if you want to change something in any part of your system, just make your change in the corresponding directory, recomile, reinstall, and you can immediately see your changes in action. Read more →

  • I previously wrote about my Debian stretch preview image for the Raspberry Pi 3. Now, I’m publishing an updated version, containing the following changes: SSH host keys are generated on first boot. Old kernel versions are now removed from /boot/firmware when purged. The image is built with vmdb2, the successor to vmdebootstrap. The input files are available at https://github.com/Debian/raspi3-image-spec. The image uses the linux-image-arm64 4.13.4-3 kernel, which provides HDMI output. The image is now compressed using bzip2, reducing its size to 220M. A couple of issues remain, notably the lack of WiFi and bluetooth support (see wiki:RaspberryPi3 for details. Any help with fixing these issues is very welcome! Read more →

2017 › August

  • I strive to respect everybody’s personal preferences, so I usually steer clear of debates about which is the best programming language, text editor or operating system. However, recently I was asked a couple of times why I like and use a lot of Go, so here is a coherent article to fill in the blanks of my ad-hoc in-person ramblings :-). Read more →

2017 › May

  • Modern desktop environments like GNOME offer UI for this, but if you’re using a more bare-bones window manager, you’re on your own. This article outlines how to get a login page opened in your browser when you’re behind a portal. Read more →

2017 › April

  • A while ago, I got myself a bunch of HomeMatic home automation gear (valve drives, temperature and humidity sensors, power switches). The gear itself works reasonably well, but I found the management software painfully lacking. Hence, I re-implemented my own management software. In this article, I’ll describe my method, in the hope that others will pick up a few nifty tricks to make future re-implementation projects easier. Read more →

  • On 2017-01-18, I announced that https://manpages.debian.org had been modernized. Let me catch you up on a few things which happened in the meantime: Debian experimental was added to manpages.debian.org. I was surprised to learn that adding experimental only required 52MB of disk usage. Further, Debian contrib was added after realizing that contrib licenses are compatible with the DFSG. Indentation in some code examples was fixed upstream in mandoc. Address-bar search should now also work in Firefox, which apparently requires a title attribute on the opensearch XML file reference. manpages now specify their language in the HTML tag so that search engines can offer users the most appropriate version of the manpage. I contributed mandocd(8) to the mandoc project, which debiman now uses for significantly faster manpage conversion (useful for disaster recovery/development). An entire run previously took 2 hours on my workstation. With this change, it takes merely 22 minutes. The effects are even more pronounced on manziarly, the VM behind manpages.debian.org. Thanks to Peter Palfrader (weasel) from the Debian System Administrators (DSA) team, manpages.debian.org is now serving its manpages (and most of its redirects) from Debian’s static mirroring infrastructure. That way, planned maintenance won’t result in service downtime. I contributed README.static-mirroring.txt, which describes the infrastructure in more detail. The list above is not complete, but rather a selection of things I found worth pointing out to the larger public. Read more →

2017 › March

  • The Turris Omnia is an open source (an OpenWrt fork) open hardware internet router created and supported by nic.cz, the registry for the Czech Republic. It’s the successor to their Project Turris, but with better specs. I was made aware of the Turris Omnia while it was being crowd-funded on Indiegogo and decided to support the cause. I’ve been using OpenWrt on my wireless infrastructure for many years now, and finding a decent router with enough RAM and storage for the occasional experiment used to not be an easy task. As a result, I had been using a very stable but also very old tp-link WDR4300 for over 4 years. Read more →

  • I previously wrote about my Debian stretch preview image for the Raspberry Pi 3. Now, I’m publishing an updated version, containing the following changes: A new version of the upstream firmware makes the Ethernet MAC address persist across reboots. Updated initramfs files (without updating the kernel) are now correctly copied to the VFAT boot partition. The initramfs’s file system check now works as the required fsck binaries are now available. The root file system is now resized to fill the available space of the SD card on first boot. SSH access is now enabled, restricted via iptables to local network source addresses only. The image uses the linux-image-4.9.0-2-arm64 4.9.13-1 kernel. A couple of issues remain, notably the lack of HDMI, WiFi and bluetooth support (see wiki:RaspberryPi3 for details. Any help with fixing these issues is very welcome! Read more →

2017 › January

  • NOTE that the documented assumptions about fsync skipping are incorrect in the code below. Prefer using the renameio package. Writing files is simple, but correctly writing files atomically in a performant way might not be as trivial as one might think. Here’s an extensively commented function to atomically write compressed files (taken from debiman, the software behind manpages.debian.org): package main import ( "bufio" "compress/gzip" "io" "io/ioutil" "log" "os" "path/filepath" ) func tempDir(dest string) string { tempdir := os.Getenv("TMPDIR") if tempdir == "" { // Convenient for development: decreases the chance that we // cannot move files due to TMPDIR being on a different file // system than dest. tempdir = filepath.Dir(dest) } return tempdir } func writeAtomically(dest string, compress bool, write func(w io.Writer) error) (err error) { f, err := ioutil.TempFile(tempDir(dest), "atomic-") if err != nil { return err } defer func() { // Clean up (best effort) in case we are returning with an error: if err != nil { // Prevent file descriptor leaks. f.Close() // Remove the tempfile to avoid filling up the file system. os.Remove(f.Name()) } }() // Use a buffered writer to minimize write(2) syscalls. bufw := bufio.NewWriter(f) w := io.Writer(bufw) var gzipw *gzip.Writer if compress { // NOTE: gzip’s decompression phase takes the same time, // regardless of compression level. Hence, we invest the // maximum CPU time once to achieve the best compression. gzipw, err = gzip.NewWriterLevel(bufw, gzip.BestCompression) if err != nil { return err } defer gzipw.Close() w = gzipw } if err := write(w); err != nil { return err } if compress { if err := gzipw.Close(); err != nil { return err } } if err := bufw.Flush(); err != nil { return err } // Chmod the file world-readable (ioutil.TempFile creates files with // mode 0600) before renaming. if err := f.Chmod(0644); err != nil { return err } // fsync(2) after fchmod(2) orders writes as per // https://lwn.net/Articles/270891/. Can be skipped for performance // for idempotent applications (which only ever atomically write new // files and tolerate file loss) on an ordered file systems. ext3, // ext4, XFS, Btrfs, ZFS are ordered by default. f.Sync() if err := f.Close(); err != nil { return err } return os.Rename(f.Name(), dest) } func main() { if err := writeAtomically("demo.txt.gz", true, func(w io.Writer) error { _, err := w.Write([]byte("demo")) return err }); err != nil { log.Fatal(err) } } rsync(1) will fail when it lacks permission to read files. Hence, if you are synchronizing a repository of files while updating it, you’ll need to set TMPDIR to point to a directory on the same file system (for rename(2) to work) which is not covered by your rsync(1) invocation. Read more →

  • For manpages.debian.org, I looked at loading webfonts. I considered the following scenarios: # local? cached? Network Expected Observed 1 Yes / / perfect render perfect render 2 No Yes / perfect render perfect render 3 No No Fast FOUT FOIT 4 No No Slow FOUT some FOUT, some FOIT Scenario #1 and #2 are easy: the font is available, so if we inline the CSS into the HTML page, the browser should be able to render the page perfectly on the first try. Unfortunately, the more common scenarios are #3 and #4, since many people reach manpages.debian.org through a link to an individual manpage. Read more →

  • https://manpages.debian.org has been modernized! We have just launched a major update to our manpage repository. What used to be served via a CGI script is now a statically generated website, and therefore blazingly fast. While we were at it, we have restructured the paths so that we can serve all manpages, even those whose name conflicts with other binary packages (e.g. crontab(5) from cron, bcron or systemd-cron). Don’t worry: the old URLs are redirected correctly. Read more →

Go to page:

I run a blog since 2005, spreading knowledge and experience for over 20 years! :)

If you want to support my work, you can buy me a coffee.

Thank you for your support! ❤️