Skip to content

23rd December 2025

Militancy

Antifascism

  • New: Añadir web sistemapunk.

Life navigation

Life chores management

Signal

  • New: Add note on AWS use.

    It runs on AWS. On October 2025 there was an AWS outage and signal fell

Technology

Coding

Vim Snippets

  • New: Create quickmarks across files.

    Use capital letters for the mark.

    http://vim.wikia.com/wiki/Using_marks

    Marks can span across files. To use such marks one has to use upper-case registers i.e. A-Z. Lower-case registers are used only within files and do not span files. That's to say, if you were to set a mark in a file foo.c in register "a" and then move to another file and hit 'a, the cursor will not jump back to the previous location. If you want a mark which will take you to a different file then you will need to use an upper-case register. For example, use mA instead of ma.

Python Snippets

  • New: Get value of enum by value.

    from enum import Enum
    
    class Color(Enum):
        RED = 1
        GREEN = 2
        BLUE = 3
    

    Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.RED won’t do because the exact color is not known at program-writing time). Enum allows such access:

    Color(1)
    <Color.RED: 1>
    
    Color(3)
    <Color.BLUE: 3>
    

    If you want to access enum members by name, use item access:

    Color['RED']
    <Color.RED: 1>
    
    Color['GREEN']
    <Color.GREEN: 2>
    

    ```

  • New: Get the directory of a python script.

    This can be useful to create relative paths between the script parts in a way that you can still run the script from another directory.

    from pathlib import Path
    
    script_dir = Path(__file__).parent
    script_path = script_dir / '../another-file'
    

DevSecOps

Velero

  • New: Debug a failed backup.

    To get the available backups you can use:

    velero get backups
    

    Check the ones that have Failed in the name and then see the logs with:

    velero backup logs backup-1h-20251215113154 | grep -v 'level=info'
    

vector

  • New: Introduce vector.

    Vector is a lightweight, ultra-fast tool for building observability pipelines

    Installation

    On debian

    First, add the Vector repo:

    bash -c "$(curl -L https://setup.vector.dev)"
    

    Then you can install the vector package:

    sudo apt-get install vector
    

    Tweak the configuration and then enable the service.

    To be sure that vector is able to push to loki create the /usr/local/bin/wait-for-loki.sh file

    while true; do
      response=$(curl -s http://localhost:3100/ready 2>/dev/null)
      if [ "$response" = "ready" ]; then
        break
      fi
      sleep 1
    done
    

    Make it executable chmod +x /usr/local/bin/wait-for-loki.sh

    Then update your vector.service (/usr/lib/systemd/system/vector.service)

    ExecStartPre=/usr/local/bin/wait-for-loki.sh
    ExecStartPre=/usr/bin/vector validate
    

    Run systemctl daemon-reload to reload the service configuration.

    Configuration

    The config lives at /etc/vector/vector.yaml.

    Docker

    First add vector to the docker group: usermod -a -G docker vector

    sources:
      docker:
        type: docker_logs
    
    transforms:
      docker_labels:
        type: remap
        inputs:
          - docker
        source: |
          .service_name = get(.label, ["com.docker.compose.project"]) ?? "unknown"
    sinks:
      loki_docker:
        type: loki
        inputs:
          - docker_labels
        endpoint: http://localhost:3100/
        encoding:
          codec: json
        labels:
          source: docker
          host: "{{ host }}"
          container: "{{ container_name }}"
          service_name: "{{ service_name }}"
    

    journald

    To avoid the services that run docker to be indexed twice

    sources:
      journald:
        type: journald
    
    transforms:
      journald_filter:
        type: filter
        inputs:
          - journald
        condition: |
          # Exclude docker-compose systemd services
          !contains(string!(.SYSLOG_IDENTIFIER), "docker-compose") &&
          !contains(string!(.SYSLOG_IDENTIFIER), "docker")
    
      journald_labels:
        type: remap
        inputs:
          - journald_filter
        source: |
          .service_name = ._SYSTEMD_UNIT || "unknown"
    
    sinks:
      loki_systemd:
        type: loki
        inputs:
          - journald_labels
        endpoint: http://localhost:3100/
        encoding:
          codec: json
        labels:
          source: journald
          host: "{{ host }}"
          service_name: "{{ service_name }}"
    

    ZFS

    Prepare the file to be readable by vector:

    chown root:vector /proc/spl/kstat/zfs/dbgmsg
    chmod 640 /proc/spl/kstat/zfs/dbgmsg
    
    sources:
      zfs_log:
        type: file
        include:
          - /proc/spl/kstat/zfs/dbgmsg
      zfs_files:
        type: loki
        inputs:
          - zfs_log
        endpoint: http://localhost:3100/
        encoding:
          codec: json
        labels:
          source: file
          service_name: zfs
          host: "{{ host }}"
          filename: "{{ file }}"
    sinks:
    
    Troubleshooting

    Unable to open checkpoint file. path="/var/lib/vector/journald/checkpoint.txt"

    ERROR source{component_kind="source" component_id=journald component_type=journald}: vector::internal_events::journald: Unable to open checkpoint file. path="/var/lib/vector/journald/checkpoint.txt" error=Permission denied (os error 13) error_type="io_failed" stage="receiving"
    
    sudo mkdir -p /var/lib/vector/journald
    sudo chown -R vector:vector /var/lib/vector
    sudo chmod 755 /var/lib/vector
    sudo chmod 755 /var/lib/vector/journald
    

    References

unison

  • New: Installation.

    If you are on debian or ubuntu, the version of the repositories does not allow you to run the program with the file watcher, so you may need to build it yourself:

    First install the dependencies:

    sudo apt-get install ocaml-native-compilers
    
    export UNISON_VERSION=2.53.8
    echo "Install Unison." \
        && pushd /tmp \
        && wget https://github.com/bcpierce00/unison/archive/v$UNISON_VERSION.tar.gz \
        && tar -xzvf v$UNISON_VERSION.tar.gz \
        && rm v$UNISON_VERSION.tar.gz \
        && pushd unison-$UNISON_VERSION \
        && make \
        && cp -t /usr/local/bin ./src/unison ./src/unison-fsmonitor \
        && popd \
        && rm -rf unison-$UNISON_VERSION \
        && popd
    

    Then remove the ocaml compilers as they take quite some space:

    sudo apt-get remove ocaml-native-compilers
    
  • New: Run in the background watching changes.

    Create the systemd service in: ~/.config/systemd/user/unison.service (assuming that your profile is orgfiles)

    [Unit]
    Description=unison
    
    [Service]
    ExecStart=/usr/local/bin/unison orgfiles
    Restart=on-failure
    RestartSec=3
    
    [Install]
    WantedBy=default.target
    

Operating Systems

Linux Snippets

  • New: Debugging Inotify Watch Exhaustion: "No space left on device".

    If you get No space left on device errors in systemd logs, but disk space is fine:

    systemd[755863]: my-service.service: Failed to add control inotify watch descriptor for control group: No space left on device
    

    This is actually an inotify watches exhaustion issue, not disk space.

    Diagnosis

    Check Current Limits

    cat /proc/sys/fs/inotify/max_user_watches
    

    Count Current Watch Usage

    find /proc/*/fdinfo/* -exec grep -c "^inotify" {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}'
    
    for pid in $(ps -eo pid --no-headers); do
      if [[ -d /proc/$pid/fd ]]; then
        total=0
        for fd in /proc/$pid/fd/*; do
          if [[ -L "$fd" ]] && readlink "$fd" 2>/dev/null | grep -q "anon_inotify"; then
            fdnum=$(basename "$fd")
            watches=$(grep -c "^inotify" /proc/$pid/fdinfo/$fdnum 2>/dev/null || echo 0)
            total=$((total + watches))
          fi
        done
        if [[ $total -gt 0 ]]; then
          cmd=$(ps -p $pid -o comm --no-headers 2>/dev/null || echo "unknown")
          echo "$total $pid $cmd"
        fi
      fi
    done 2>/dev/null | sort -nr | head -10
    

    Find High File Descriptor Processes

    Often the culprits have many open files:

    for pid in $(ps -eo pid --no-headers); do
      if [[ -d /proc/$pid/fd ]]; then
        fd_count=$(ls /proc/$pid/fd 2>/dev/null | wc -l)
        if [[ $fd_count -gt 100 ]]; then
          cmd=$(ps -p $pid -o comm --no-headers 2>/dev/null)
          echo "$fd_count FDs: $pid $cmd"
        fi
      fi
    done
    

    Common Culprits

    • Media servers: Jellyfin, Plex
    • Download managers: Sonarr, Radarr, Lidarr
    • File sync: Syncthing, Nextcloud
    • Development tools: IDEs, file watchers
    • Container platforms: Docker, containerd

    Solutions

    1. Increase Limits (Quick Fix)

    echo 500000 > /proc/sys/fs/inotify/max_user_watches
    
    echo 'fs.inotify.max_user_watches=500000' >> /etc/sysctl.conf
    sysctl -p
    

    Memory cost: ~540 bytes per watch (500k watches ≈ 270MB kernel memory)

    2. Configure Applications

    Better long-term solution:

    Sonarr/Radarr/Lidarr:

    • Settings → Media Management → Disable "Scan for changes"
    • Use scheduled scans instead

    Jellyfin:

    • Admin → Dashboard → Libraries → Disable real-time monitoring
    • Use periodic library scans

    Syncthing:

    • Use polling instead of inotify for large directories
    • Add .stignore for unnecessary paths
  • New: Manage bluetooth.

    List devices

    Once you've paired your devices you can see them with:

    bluetoothctl devices
    

    To check the ones that are connected use:

    bluetoothctl devices Connected
    

    Connect device

    From the list above you will see the device ID, then you can:

    bluetoothctl connect device_ID
    

    But it's better to use blueman-manager because it handles better the connections and disconnections

    Multidevice connection

    Sometimes the laptop is not able to send the audio streams back to the connected device. Restart the controlling device with:

    systemctl --user restart wireplumber.service
    
  • New: Bluetooth Pairing Troubleshooting: When BLE Devices Won't Connect.

    Bluetooth Low Energy (BLE) devices like wireless earbuds appear in device scans but fail to pair with "Device not available" errors, even though they're visible to other devices.

    The root ’cause may be that the HCI controller corruption causing discovery operations to fail. The Bluetooth hardware gets stuck in a state where it rejects pairing attempts with error code -16 (EBUSY).

    Symptoms

    • hcitool lescan shows the device
    • bluetoothctl scan shows device briefly or not at all
    • bluetoothctl pair [MAC] returns "Device not available"
    • dmesg shows HCI opcode failures like: Bluetooth: hci0: Opcode 0x0401 failed: -16

    Solution

    Complete Bluetooth stack reset:

    sudo systemctl stop bluetooth
    
    sudo rmmod btusb
    
    sudo modprobe btusb
    
    sudo systemctl start bluetooth
    

    If that doesn't work. Try forcing bluetoothctl to see LE devices specifically:

    $: bluetoothctl  # this will open the bluetooth cli
    menu scan
    clear
    transport le
    back
    scan on
    
  • New: How to Increase Touchpad Sensitivity on Linux.

    Adjust touchpad sensitivity settings for better responsiveness and control on Linux systems.

    First, identify your touchpad device:

    xinput list
    

    Check current properties:

    xinput list-props "Synaptics TM3381-002"
    

    Increase pointer sensitivity (range: -1.0 to 1.0):

    xinput set-prop "Synaptics TM3381-002" "libinput Accel Speed" 1
    

    Make scrolling more sensitive:

    xinput set-prop "Synaptics TM3381-002" "libinput Scrolling Pixel Distance" 10
    

    Once you have the correct values make it permanent across reboots by adding them to your startup scripts.

  • New: How to Disable Trackpoint on Linux.

    The trackpoint (that red nub in the middle of ThinkPad keyboards) can be accidentally triggered while typing, or if you replace the keyboard it might make the mouse slide randomly without any user intervention. Here's how to disable it on Linux systems.

    with xinput

    Get the property of your trackpoint with xinput list | grep -i track

    Then disable the trackpoint with xinput set-prop "TPPS/2 Elan TrackPoint" "Device Enabled" 0

    To make it persistent add that line to your desktop startup scripts. It can be run by a non privileged user.

    With udev rules

    The problem with this approach is that the event number may change across reboots

    First, find your trackpoint in the system:

    cat /proc/bus/input/devices | grep -A5 -B5 -i trackpoint
    

    Look for entries like "TPPS/2 Elan TrackPoint" or similar. Note the event number (e.g., event14).

    Create a udev rule to ignore the trackpoint device:

    sudo sh -c 'echo "KERNEL==\"event[0-9]*\", SUBSYSTEM==\"input\", ATTRS{name}==\"*TrackPoint*\", ENV{LIBINPUT_IGNORE_DEVICE}=\"1\"" > /etc/udev/rules.d/90-disable-trackpoint.rules'
    

    Replace event[0-9]* with your specific event number if needed.

    Reload udev rules:

    sudo udevadm control --reload-rules
    sudo udevadm trigger
    

    Test that the trackpoint no longer responds to input. The udev method typically works immediately and persists across reboots.

    This may have an ugly side effect, that you won't any longer be able to use the touchpad mouse buttons. Sadly the trackpoint and those buttons are controlled by the same device.

    The solution is to use the touchpad instead (see below).

    Be able to click using the touchpad

    Activate tap for clicking in touchpad by pasting following lines in /etc/X11/xorg.confg.d/30-touchpad.conf

    Section "InputClass"
        Identifier "touchpad"
        Driver "libinput"
        MatchIsTouchpad "on"
        Option "Tapping" "on"
        Option "TappingButtonMap" "lrm"
    EndSection
    

    The lrm means that:

    • 1 finger tap is a left click
    • 2 finger tap is a right click
    • 3 finger tap is a middle click

    You'll need to logout and back in for the change to be applied.

Watchtower

Hardware

Kobo

  • New: Kobo Forma suddenly drains battery in days.

    The solution was to a factory restore, disconnect the wifi and detect which ebook is being the problem.

    Some of the user suggestions - My battery started doing this many 3 times now. Every time it was a certain book. The first time was something I downloaded from the kobo store, I removed my recent batch of downloads and it was fine (still not sure which is the offending book tbh). The next two were sideloaded borrowbox books. I think its something to do with a download not being downloaded correctly/having all the correct information. The kobos system tries to keep getting the information it wants but fails and keeps doing this in a cycle causing it to drain the battery

    • I haven't bought any new books lately, but I've been reading a ton of library books. About when the battery drain started, I had returned a few books directly from the Kobo, instead of doing it on my phone in the Libby app. That's got to be the problem.

    I disabled the wifi, turned off my Kobo, turned it back on, then restarted the wifi, BUT I did it in Settings, instead of with the quick toggle at the top of the Home screen (when you touch the wifi signal strength indicator). It took longer for the wifi to fully connect than it had all the times I've tried this over the last week. Then I did a Sync, which went through quickly.

    It's been 8+ hours, and my Kobo is still at 89%, which is where it was when I started the process!

    • i did find out that it wasn't going to sleep or powering off if I just closed the cover anymore. It will sleep/ power off if the cover is not closed. I haven't changed any settings so I'm not sure why this started happening. I've had to power it off manually before closing the cover to make sure there is no battery drain.

    • Basically, the Forma will either go to sleep on its own or I'll put it to sleep and the battery is at some reasonable amount. Usually overnight, but once while it was sitting on the desk next to me for about an hour, the battery will drain down to nothing. It will shut all the way down and sometimes display the warning that it needs charging. Other times, I don't even get that warning.

    References

Science

Artificial Intelligence

OCR

Other

  • New: Introduce aerc email command line client.

    aerc is an email client that runs in your terminal.

    Some of its more interesting features include:

    • Editing emails in an embedded terminal tmux-style, allowing you to check on incoming emails and reference other threads while you compose your replies
    • Render HTML emails with an interactive terminal web browser, highlight patches with diffs, and browse with an embedded less session
    • Vim-style keybindings and ex-command system, allowing for powerful automation at a single keystroke
    • First-class support for working with git & email
    • Open a new tab with a terminal emulator and a shell running for easy access to nearby git repos for parallel work
    • Support for multiple accounts, with IMAP, Maildir, Notmuch, Mbox and JMAP backends. Along with IMAP, JMAP, SMTP, and sendmail transfer protocols.
    • Asynchronous IMAP and JMAP support ensures the UI never gets locked up by a flaky network.
    • Efficient network usage - aerc only downloads the information which is necessary to present the UI, making for a snappy and bandwidth-efficient experience
    • Email threading (with and/or without IMAP server support).
    • PGP signing, encryption and verification using GNUpg.
    • 100% free and open source software!

    Installation

    Source

    Download the latest version Compile it with the repo instructions

    Debian

    The debian version is very old, compile it directly

    sudo apt-get install aerc
    

    Documentation

    The docs are few and hard to read online, but there are throughout in local.

    If you're lost you can always run again the tutorial with :help tutorial

    Configuration

    On its first run, aerc will copy the default config files to ~/.config/aerc on Linux. When you start the program for the first time a wizard will configure an account and start up the tutorial.

    Read Bence post, it's a nice guideline.

    notmuch

    Notmuch can be used directly as a backend for several email clients, including alot, dodo, Emacs, vim and (more importantly for us) aerc. While it can be used on its own, we are going to use it for its search index, and ability to seamlessly operate over multiple accounts' maildir folder. This will provide us with the ability to search all of our email regardless of account, and to show a unified overview of certain folders, e.g. a unified inbox. If you are only setting this up for a single account, I still recommend using notmuch for its search capabilities.

    Gmail

    If these guidelines don't work, try this others.

    Monitorization

    If you are using the mailsync scripts proposed above or on Bence's post you can check if the service failed with:

    groups:
      - name: email
        rules:
          - alert: MailsyncError
            expr: |
              count_over_time({user_service_name=~"mailsync-.*"} |= `Failed` [15m]) > 0
            for: 0m
            labels:
              severity: warning
            annotations:
              summary: "Error syncing the email with service {{ $labels.user_service_name }} at {{ $labels.host}}"
    

    It assumes that you have the user_service_name label defined in your logs. I create them with vector with the next config:

    transforms:
      journald_labels:
        type: remap
        inputs:
          - journald_filter
        source: |
          .service_name = ._SYSTEMD_UNIT || "unknown"
          .user_service_name = .USER_UNIT || ._SYSTEMD_USER_UNIT || "unknown"
    

    Usage

    aerc has many commands that can be bound to keybindings, to see them all check man 1 aerc.

    Main page

    • , : Cycles to the previous or next tab
    • k, j: Scrolls up and down between messages
    • , : Scrolls half a page up or down
    • g, G: Selects the first or last message, respectively
    • K, J: Switches between folders in the sidebar
    • : Opens the selected message

    You can also search the selected folder with /, or filter with . When searching you can use n and p to jump to the next and previous result. Filtering hides any non-matching message.

    Message viewer

    Press to open a message. By default, the message viewer will display your message using less(1). This should also have familiar, vim-like keybindings for scrolling around in your message.

    Multipart messages (messages with attachments, or messages with several alternative formats) show a part selector on the bottom of the message viewer.

    • , : Cycle between parts of a multipart message
    • q: Close the message viewer
    • f: next message
    • b: previous message

    To show HTML messages, uncomment the text/html filter in your aerc.conf file (which is probably in ~/.config/aerc/) and install its dependencies: w3m and dante-utils.

    You can also do many tasks you could do in the message list from here, like replying to emails, deleting the email, or view the next and previous message (J and K).

    Some interesting commands are:

    • :unsubscribe: Attempt to automatically unsubscribe the user from the mailing list through use of the List-Unsubscribe header. If supported, aerc may open a compose window pre-filled with the unsubscribe information or open the unsubscribe URL in a web browser.

    Composing messages

    • C: Compose a new message
    • rr: Reply-all to a message
    • rq: Reply-all to a message, and pre-fill the editor with a quoted version of the message being replied to
    • Rr: Reply to a message
    • Rq: Reply to a message, and pre-fill the editor with a quoted version of the message being replied to

    The message composer will appear. You should see To, From, and Subject lines, as well as your $EDITOR. You can use or and to cycle between these fields (tab won't cycle between fields once you enter the editor, but and will).

    References

    Interesting configurations

  • New: Introduce autorandr.

    autorandr is a command line tool to automatically select a display configuration based on connected devices.

    Installation

    apt-get install autorandr
    

    Usage

    Save your current display configuration and setup with:

    autorandr --save mobile
    

    Connect an additional display, configure your setup and save it:

    autorandr --save docked
    

    Now autorandr can detect which hardware setup is active:

    $ autorandr
      mobile
      docked (detected)
    

    To automatically reload your setup:

    $ autorandr --change
    

    To manually load a profile:

    $ autorandr --load <profile>
    

    or simply:

    $ autorandr <profile>