Posts in Linux (20 found)
David Bushell 4 days ago

D-Bus Hell

The time has come to address the elephant in the comments. Whenever my blog hits a place with a comments section the most predictable comment I see — besides some variation of “this idiot is utterly delusional!” † — is this one: lol I read the domain as “D-Bus Hell” Random commenter I’d prefer if they focused on my actual blog content but I can’t get annoyed at people for seeing the wrong words. There’s a reason has a hyphen, and who can forget Susan’s party? I’d probably read “D-Bus Hell” myself, if I forgot my own name. † Why is Hacker News like that? But for the sake of the record I would like to point you to your nearest WHOIS tool: Don’t ask me what I was doing at ten minutes to midnight registering a domain name. Is there a more appropriate time? The significant point is the date: May 2004. That was 22 years ago. Now if I may direct your attention to the D-Bus project Wikipedia page : Release November 2006; 19 years ago D-Bus - Wikipedia I rest my case. The D-Bus project doesn’t even have it’s own domain name, for crying out loud! So next time you see a post about D-Bus, maybe drop a comment saying: “reminds me of that dummy with a blog and a giant logo spelling out his full name!” Or something to that effect. (I’m joking, don’t do that.) To date I’ve resisted the siren call of nominative determinism so I can’t answer to whether D-Bus is actually hell or not. I considered writing a D-Bus review as a joke, but then I decided to watch paint dry. I’ve never heard Linux nerds express any strong opinions on the topic (for which they’re prone to do; see Systemd, Wayland, etc.) I did go down the Wikipedia rabbit hole of cognitive psychology and linguistics. There’s an interesting read on Rebracketing where a word like “Hamburger” becomes “ham + burger” which was altered from the origin: “Hamburg + er” . This is a form of Folk etymology where words can change due to unfamiliarity. My surname could simply come from “bushel”. An imperial unit of volume still favoured by fantasy novels, before the Trollocs attack and shit gets real. “Bushel” dates back to Middle English with origins in the Old French word “boissel”. At the risk of being part French, I’m inclined to believe an alternate theory that my name derives from “Bossall” a hamlet in North Yorkshire. But that would make me part Yorkshireman. I’m not sure which is worse. It’s not a very common surname. If this Geneanet heat map has any credibility, the name favours the south of England. That might support the French theory? Liverpool has the highest number of Bushells though. Bushells is also an Australian brand of tea founded by tea dealer Alfred Bushell in 1883. Alfred was born in Worcestershire, England (pronounced: Wrcstrshr ). Interestingly, Wikipedia notes: After the Norman conquest of England; the Domesday Book noted in 1086 that in seven of the twelve hundreds covering Worcestershire, the Crown had no authority. Worcestershire - Wikipedia The Domesday Book always references Bossall (the Yorkshire hamlet) as Boscele or Bosciale ; names that are Anglo Saxon in origin. When I say “Bushell” over the phone my pronunciation is often mistaken for saying “Buchel”. Some sources say they’re from the same Anglo Saxon origin. These distribution maps for Bushell and Buchel cast doubt on that idea (if Forebears data is accurate). “Büchel” also has different origins if you stick an umlaut on it. I suspect I’m dealing with multiple different names of Anglo Saxon and Norman origin. There are many spelling variations of “Bushell” and similar names in historic records (though few have survived). Most people were illiterate until recent decades so spelling variations are not surprising. It seems probable to me that whenever families adopted a spelling, a variation from the wrong lineage could’ve been written due to phonetic differences. Even if I traced my ancestry back hundreds of years, I’d likely reach a moment when a scribe wrote “Bushell” in some form and my ancestor just shrugged because he couldn’t read. The etymology of “David” is well known despite being much older. Its roots are Hebrew meaning “beloved” and has found its way across Judaism, Christianity, and Islam. D-Bus is “Desktop Bus” if you were too lazy to click the link. Domain names are a strange system. They’re temporary URIs that are leased and inevitably lost. I’ve spent half my life publishing content on . I started using it seriously once I had a design portfolio. If you’re curious you can see past versions at: legacy.dbushell.com In hindsight if I knew I was going to build a career around my website I’d have chosen something more memorable. Imagine all the common words that were still untouched in 2004? wasn’t taken until 2005! I don’t actually go by “Dave” myself but like the “D-Bus” thing it’s not my choice to make. For a brief moment I did consider moving to another domain. I would have had to maintain redirects forever. It’s not a sensible “SEO” manoeuvre either, if that matters anymore… Now that I’m running my business from valleyfold.co.uk I’m happy I stuck with for my personal space. Anyway, next time you spot the “D-Bus” comment please direct them there! Better yet, take up this blog challenge: write about the etymology behind your name and domain name. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
Unsung 1 weeks ago

“Yeah… I was very tired that night.”

The (un)installation bug from the previous post was an overeager directory delete, but a more common problem I’ve seen is this one. Here’s an example from iTunes 2.0 : The installer tries to erase a previous version of iTunes using (with root privileges) the command. However it doesn’t take into account that volume names can contain spaces. […] When the diskname (partition name) starts with a space the following happens: So removes (all mount points!) and a nonexistent path , but no errors are displayed because they are /dev/​nulled. And a very similar thing a decade later, from Steam’s Linux installer: I launched Steam. It did not launch, it offered to let me browse, and still could not find it when I pointed to the new location. Steam crashed. I restarted it. It re-installed itself and everything looked great. Until I looked and saw that steam had apparently deleted everything owned by my user recursively from the root directory. Including my 3TB external drive I back everything up to that was mounted under /media. The culprit was identified by another user a few messages down: could be evaluated as is empty These are the sort of classic user-generated content meets string concatenation/​interpolation bugs that haunt engineers’s dreams. The solution: If a user gives you a string, you have to wrap it as safely as possible so that it could never break apart into pieces in transit. So you wrap the path with quotation marks. (I believe you can actually do this everywhere in Linux – will work as well as – except no one ever does so as it’s quite annoying.) But then, a string with quotation marks would escape containment, so you have to escape those by changing to . And then, naturally, you also have to escape any freefloating backslashes to . Of course, there are usually functions that take care of all of the above; you just have to remember to use them, as well as think about the edge cases like a variable being empty to begin with. This all is a distant version of SQL injection – perhaps most well-known from this XKCD comic – and a more modern prompt injection . There’s even a version of it in UI design: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/1.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/3.1600w.avif" type="image/avif"> Here, the wrapping isn’t for security reasons, but to help people understand where the command ends and the string begins. But this introduces a new challenge, as any type of visual wrapping – quotation marks, bolding, italicization – can draw undue attention to the string itself. So, sometimes you just leave it be and hope for the best: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/4.1600w.avif" type="image/avif"> But let’s go back to the installation issues. I bet there are were tons more string interpolation and escaping bugs that we simply never learned about. Yet, as users of a project called Bumblebee learned in 2011, nothing beats the destructive power of a simple typo. The best way to start here is with the summary of the fix to the bug, because that is the best encapsulation of the story: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/yeah-i-was-very-tired-that-night/5.1600w.avif" type="image/avif"> Yeah, you read it right. Here’s the original bug report : An extra space at line 351: causes the install.sh script to do an on the directory for people installing in ubuntu. Totally uncool dude!!! The script deletes everything under . I just had to reinstall linux on my pc to recover. Removing the space will fix this. Probably should do it quickly!!! Reader, the bug was fixed quickly.

0 views
Kev Quirk 2 weeks ago

2026-09-29 16:03: I think it's time... #Ubuntu

I think it's time... #Ubuntu Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Kev Quirk 2 weeks ago

I Switched to Brave Browser

I've been whinging about wanting to move away from Firefox for nearly a year now. It started with Mozilla's announcement about their AI strategy and my initial thoughts . Then they doubled-down and it raised my heckles even more . Then I had a long old whinge about how fucked they seem to be. I took Vivaldi for a spin , but I couldn't get used to it. It just tries to do too much, and has way too much going on with the UI, and dark/light theme switching still doesn't work despite it apparently being fixed. So I made my peace with Firefox and stuck with it. I kept Vivaldi on my machine as a backup, and over the last 6 months or so, I've found myself having to open it more and more due to something not working in Firefox. This was far from a daily occurrence, but it happened often enough for it to become annoying. But I still couldn't use Vivaldi full time. It's worth stating that things not working isn't the fault of Firefox. It's developers not testing their web apps with Firefox, since it has such a small market share. I decided to install Brave a couple months ago just to see how things went. I had some messing around to do up front, like hiding all the crypto and AI nonsense, but once that was gone, it's been fine. Everything works how I expect, both on Ubuntu and Android. The UI is similar to Firefox, and most importantly, it doesn't try to boil the ocean. I renders webpages, then gets out of my way. I don't need it to check RSS feeds, or emails, or have toolbars on every edge of the screen. Even dark mode switching works! I haven't felt the need to open Firefox since starting this exeperiment, so I think Brave is gonna stick. Yes yes yes. Brave was founded by an absolute scumbag . But there's scumbags everywhere, in all walks of life. Contrary to what some people on the internet will say, my use of Brave doesn't mean I agree with, or support, Bendan Eich's world views. I consider his personal views to be separate from Brave. You may disagree, and that's fine. But Brave is objectively a good piece of software that does what I need it to do, and does it well. So I'm gonna continue using it for the forseable future. If Firefox get their act together and become relevant again, I may jump back, but for now it will remain my secondary browser. I do still have Vivaldi installed too. So I will continue to check in on it now and then, and if I decide they're on a par with Brave on Linux (mainly light/dark theme switching is what's missing), then I'll definitely make the switch as I feel their moral compass is far more aligned with my own. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Farid Zakaria 2 weeks ago

Every package is already installed

tl;dr; omnibin is a FUSE filesystem that puts every binary nixpkgs ever shipped on your . Nothing is installed. Nothing needs building. 0 bytes on disk until something actually reads a file. 😈 It’s 2026, why am I still installing packages individually? 1 Why must I go through the ritual of adding a package to my , running or succumb to the hellscape of . Nix gives us the power of having packages installed side-by-side without conflict. Why do I have to pick which ones I want to install? Why can’t I just have them all? What if the machine just had all of them? That is over fifty thousand 2 top-level binaries available on my , from 2013 to 2026 built by Nixpkgs , available on-demand, without installing anything. This is the magic 🧙‍♂️ of Nix , but it’s not restricted to Nix. Everyone seems to still love Docker and OCI , why am I still picking which base image to use? Why can’t I just have them all? Is this the ultimate agent harness? It’s a container with everything in it, right from the start. Try it at fmzakari/omnibin . Of course, I cannot forget our NixOS friends. You no longer have to curate your or , you can just have them all. What is “package management” if every package is already installed? Turns out that Hydra writes a file next to every single narinfo on cache.nixos.org that describes the contents of the archive as JSON: That metadata turns out to be the perfect index for a FUSE filesystem that can lazily fetch the NARs from the cache and unpack them on-demand. 🤓 None of this would mean anything without nixpkgs-multiverse , which already resolves any in nixpkgs history to the store path Hydra built for it on cache.nixos.org . When you combine the two, you get a filesystem that can answer the question “where is ” and then fetch it from the cache and unpack it for you, all without ever having to install it. I crawled all of it the files in under twelve minutes. 🤯 Once you have that, the filesystem writes itself: That is CPython 3.6.2, from 2017. That downloaded nothing , it is answered from the pre-crawled index. Agents are “a thing”. Making them useful is a thing. Making them useful without installing anything is a thing. If your agent tried to and stat every single entry, it would have a really bad time. There are 881,933 binaries in the tree, and it would take a long time to stat them all. To help the agents out a bit, lists only the bare names, one per executable, each resolving to the newest package that provides it. The versioned forms all resolve, but they are not listed. For example, resolves to the latest Python 3, which is 3.14.6 at the time of writing, but resolves to the 2017 version. For everything else there is the index, which is sitting right there in the mount: That UX is a little rough, so you can also use the CLI to query the index: Lastly, there is a /omnibin/README.md whose entire job is to tell whatever is exploring the filesystem to stop exploring the filesystem and query the database instead. 🤖 At this point it should be obvious, but you pay for this on startup for the first access. The first run took 2.7 seconds to fetch the NARs and unpack them, the second run was instantaneous because the store paths were already present. Other than that? Not really, which is pretty amazing. For any long-lived machine, you would expect your to already be warmed up with the packages you need, so the first access penalty is not a big deal. I remember one of the first things that blew my mind and sold me on Nix, was seeing a demo by @burke on comma . The capability to test a package, at a single nixpkgs revision, without “installing it”; revolutionary! I believe this to be a spiritual successor and I hope to imbue others with the same sense of wonder and amazement that I felt back then as a beacon of the power of Nix. The repo is at github.com/fzakaria/omnibin . Please responsibly. Yes, I am a little inspired after watching DHH’s keynote at RailsConf 2026 . I feel the same way about package management.  ↩ There are actually 881,933 binaries in the tree, but only lists the latest version of each binary. The versioned forms are still available, but they are not listed.  ↩ Yes, I am a little inspired after watching DHH’s keynote at RailsConf 2026 . I feel the same way about package management.  ↩ There are actually 881,933 binaries in the tree, but only lists the latest version of each binary. The versioned forms are still available, but they are not listed.  ↩

0 views

Shrinking a Fedora virtual disk

I have a weird setup for my laptop. In summary, I have been irrationally scared of running Fedora on bare, dual-GPU metal, so I run it in a virtual machine with Hyper-V on Windows as a hypervisor. The idea was to let Windows manage GPUs and power management stuff like hibernation, and then use Fedora as my main UI to the computer. This has worked surprisingly well, but that’s only because my expectations were low to begin with. The VM can barely access the hardware of the underlying machine: it can’t use the GPU, it can’t use the front-facing camera, Linux starts thrashing weirdly when the VM runs out of memory, among other quirks I’ve learned to work around. Thus, I’ve wanted to re-install on bare metal for a while, but! problem! Come on a journey with me. It’s got a hero with hubris, mistakes, tension, and a cliffhanger. (Continue reading the full article on the web.)

0 views
alikhil 3 weeks ago

My MikroTik workaround for LaLiga Cloudflare blocks

Spain loves football. Spain also has plenty of people watching football on pirate streams. Those streams often sit behind Cloudflare, where one IP address can belong to a lot of completely unrelated websites. LaLiga spent a while trying to get Cloudflare to take the pirate streams down. That did not work out. Then LaLiga got a court order that lets Spanish ISPs block IP addresses during matches. So they block the IPs used by the streams, and legitimate sites behind Cloudflare go down with them. Message shown by a Spanish ISP when you try to load a website hosted on an IP address it has blocked. The result is annoying. A random site does not load. An API starts timing out. You can spend an hour debugging your own setup before noticing that there is a LaLiga match on. I used to fix it by enabling a rule on my MikroTik that sends Cloudflare traffic through a VPN. Every match, same small ritual. Recently I found ¿Hay ahora fútbol? , a site with one useful question: is football on right now, and is Cloudflare probably broken again? It also exposes its signal over DNS. That was enough to automate the whole thing. The router keeps a list of Cloudflare IP ranges. When Hayahora reports a large set of blocked IPs, it enables one disabled mangle rule. New connections from my LAN to Cloudflare then go through my existing VPN. When the DNS answer goes back to normal, the rule turns itself off. Only Cloudflare traffic takes the detour. The VPN is not my default route, and the rest of the network keeps using my normal ISP connection. My setup uses RouterOS 7 and an existing policy-based IPsec connection marked . If your VPN uses a different connection mark, replace below. Get the VPN working first; this post only adds the automatic switch. First, refresh a firewall address list named every day. I use Davie3’s list , but any maintained Cloudflare IP-list import will do. Then add this rule. It starts disabled on purpose. Finally, this script checks Hayahora every five minutes. More than ten DNS answers is my signal that a blocking event is active. The same threshold is used by the TRMNL LaLiga plugin . You might wonder why this does an HTTP request to Google DNS instead of using RouterOS’s native . returns only one record. I need the full answer set to keep the threshold, so one record does not send all Cloudflare traffic through the VPN by accident. This is a blunt workaround. While the rule is enabled, every new connection from my LAN to a Cloudflare IP goes through the VPN. That is fine for me during a match, but it sends all Cloudflare traffic through the VPN, not just traffic to the site that failed. The DNS data is an observation, not an official blocklist. And connections that already exist keep their old route until they reconnect. Still, it has saved me from one more round of “why is this website broken only tonight?” If football is on and the block is active, I am French automatically.

0 views
Farid Zakaria 3 weeks ago

A build graph that rolls dice

We are right around the corner from NixCon 2026 . Another year where I sadly won’t be present. I looked at the lineup and saw quite a few talks on dynamic derivations, along with some recent other posts on the topic such as cargo-dyndrv which had me thinking about revisting the topic since my earlier posts on the subject. I wanted to better understand the implications of dynamic derivations and how they change the build graph. Originally, I was focused on how it could replace the lang2nix style of build graph generation, but I realized that the implications are much broader than that. The graph does not need to be known up front. It can be defined as the build progresses. 🧐 What do I mean? Traditionally, Nix requires you to ask it to build anything and it will tell you exactly the steps it will take ahead of time as the “derivations” that comprise the build graph. This is an important property of Nix. It is what makes it possible to reason about builds without running them by understanding what will be built. Many Nix tools rely on this property via . For instance, nix-diff tells you why two closures differ without building either . Why does dynamic derivations change this? In functional languages it’s very easy to get abstract and use fancy words like “applicative” and “monadic” to describe the difference between types of computation. The difference is subtle, but it is profound. Nix traditionally was an “applicative” build system. Dynamic derivations make it a “monadic” build system. The difference is that in an applicative build system, the entire build graph is known up front, while in a monadic build system, the graph can be defined as the build progresses. 1 One way to think about the difference is to look at the type signatures of the two operations that define them: (applicative) takes a value known ahead of time and returns the result . You can see the entire graph before you run it. (monadic) takes , a function , to return . You cannot see the entire graph before you run it. Applicative can be thought of writing the shopping list before you leave the house. You read the recipe, you write down every ingredient, you drive to the store once. The list is a function of the recipe and nothing else. Monadic is a recipe with a step that says taste it, and if it is too salty, go buy a potato . You cannot write that shopping list up front. Whether the potato is on it depends on the saltiness, and the saltiness does not exist until you have already done some of the cooking. Nix used to be solely the former, dynamic derivations add the latter. Okay, I guess I should have said “Nix is now monadic in the scheduler”. Nix has always had bind in the evaluator. We have been doing monadic builds for years. We call it import from derivation . on a derivation output is a bind in exactly the sense above: what to build next is a function of a value that does not exist yet. The Nix evaluator cannot produce the graph without that value, and the only way to get it is to stop evaluating and run a builder. Unfortunately, this has a lot of footguns, such as causing to take ten seconds , and why nixpkgs bans the technique outright . Whereas import from derivation is a bind in the evaluator, dynamic derivations now adds bind in the scheduler. The difference is that the scheduler can run builders in parallel, ship them to remote machines, and it can substitute their results from a cache. The evaluator cannot do any of that. Dynamic derivations do not add the bind. The bind was always there. What changes is which layer performs it. 🤓 Many of the examples of dynamic derivations have been focused on build graph generation via lang2nix tooling, but I wanted to explore the implications of dynamic derivations in a more general sense. In the true monadic sense, the build graph can be defined as the build progresses. The next step in the build graph can depend on the result of a previous step. Here is a really simple example, & , that rolls a die and either stops or continues the chain by adding a new derivation step to the build graph. The depth of the chain is random, and the result of the build is how deep we got. Only the leftmost box exists when you run . Everything to the right of it is written by a builder, while the build is already underway. The general idea of this derivation is: Either way the file copied into is a , so works the same on a chain that stopped and a chain that kept going. 2 We can see the build graph grow in the denominator as the build progresses. If we try to introspect the graph with or , we get nothing. Since the graph is not known yet, our tools cannot see it. Dynamic derivations introduce a second graph that exists only after the build, and the ecosystem has no way to introspect it yet. I ran the build 900 times and logged the length of the chain. Rolling a six-sided die is one of the most classic ways to simulate geometric decay and we can see the results in the histogram below. The mean is 6.18, median 4, longest 46. The math maths. Every dynamic derivations demo so far, mine included, has been a build system: MakeNix for C, NpmNix for node, cargo-dyndrv for Rust, nix-ninja for ninja. That is a reasonable place to start but it does not capture the full power of the primitive. What other ideas can we explore? Mario. In Super Mario Derivations the attribute path is the button sequence and I have to supply the press count. The dynamic version emulates until Mario dies. The stopping condition is data, discovered mid-build, and the run is however long it turns out to be. Searching a state space. Swap the die for a predicate and you have a search where each frontier node is a derivation. Model checking, puzzle solvers, a fuzzer that only expands inputs which found new coverage. States you reach twice collapse onto one store path, and they survive a reboot. Crawling. Fetch a page, parse the links, emit one derivation per link. The frontier is discovered rather than declared, the crawl resumes because the store remembers every page already fetched, and the dependency graph of the result is the link graph. What are the bounds of this primitive? I don’t know. The size of the graph now is only limited by whether Nix stops emitting successors. There is no depth limit for the store layer, no equivalent. My longest honest chain in the die-roll was 46 deep, but I had rigged examples that went to 500. How far can it go? I am so brainwashed to thinking about making a plan before I start for my build systems, that the idea of making it up as I go is a little scary. 😨 The paper Build Systems à la Carte is the defacto read on this topic.  ↩ We actually need a depth parameter to avoid infinite recursion and so that the store-path of the derivations are different since they are content-addressed.  ↩ roll a six and we write a derivation that echoes the depth. Ordinary, nothing dynamic about it. This terminates the build graph. roll anything else and we write a passthrough : a derivation whose only job is , where is . The paper Build Systems à la Carte is the defacto read on this topic.  ↩ We actually need a depth parameter to avoid infinite recursion and so that the store-path of the derivations are different since they are content-addressed.  ↩

0 views
Luke Hsiao 3 weeks ago

Turning a $40 Surface Go into an always-on camera monitor

TL;DR I wanted an always-on screen showing a camera feed. Something that boots straight into the stream with no prompts, survives Wi-Fi drops and camera hiccups, and can be maintained remotely. A used Surface Go 3 running Omarchy turned out to be a great fit, with only a few setup steps. I have my home kitted out with UniFi PoE cameras. Inspired by Casey Neistat’s studio door camera , I made a similar setup: a camera pointed outside with a screen mounted on a wall inside. In practice, this is meaningfully more convenient than a peephole (we also don’t have any windows with a good view of the entrance). When someone knocks, we can glance at the monitor from just about anywhere in the room and see who it is. Until now, I was just using a cheap Amazon Fire HD 8 tablet. My thinking at the time was to make this as simple as possible: get a cheap Android tablet, run VLC for the RTSP stream, attach it to the wall with Command Strips, leave it plugged in, done. This had some downsides. The Fire HD 8 is underpowered, so we could only use a medium-resolution stream (720p), and the stream would lag behind by a few seconds. The simplicity of the VLC setup meant that anytime our network went down for an upgrade or the stream cut out momentarily, we’d have to reconnect manually. That worked for about three years. Then, I suspect, being permanently plugged in at 100% charge took its toll. Over the past week, the stream grew increasingly unreliable, mostly because the tablet failed to connect to my home Wi-Fi. I suspect the Wi-Fi card is dying. So, this presented an opportunity for an upgrade. My main goal was reliability. I wanted anyone in my family to be able to turn this on and get it working with as little interaction as possible. That meant I wanted them to literally just turn it on, walk away, and be greeted by the stream playing in full screen. I also wanted the stream to recover automatically from network and camera feed drops robustly. In addition, I wanted something better suited to this unusual always-on, always-streaming, always-plugged-in design. This eliminated OLED screens; this would be a worst-case scenario for burn-in. It also made devices with battery charge limits more appealing, since those limits could mitigate battery deterioration from always being plugged in. I also wanted something that didn’t feel awful to use, unlike Amazon’s bloated, ad-riddled version of Android for its Fire tablets. I wanted something I could keep getting software updates for forever. That pushed me toward a device I could run Linux on, rather than another Android tablet with an unavoidable end-of-life date. Finally, I still wanted this to be cheap. After doing some research, I settled on something like a Microsoft Surface Go 2. Powerful enough hardware and a nice enough display to handle a high-resolution HEVC stream. Able to run Linux. And, perhaps most importantly, BIOS-level support for battery limiting —when set, the battery stops charging when it reaches 50% of its capacity. Then, the stars aligned even more: I found a base (4 GB, 64 GB eMMC) Surface Go 3 on my local Facebook Marketplace for just $40. Score. Updating the BIOS Whenever I buy a used device I intend to put Linux on, I always update the BIOS using the Windows installation first. Most manufacturers do not have a way to update the BIOS without Windows. In the case of this tablet , released in 2021, I was able to bump my BIOS from a 2022 version to a recent release. BIOS updates often improve system stability and performance. Next, I prepared the UEFI settings for installing Omarchy and using the tablet as a kiosk. To get into the BIOS, hold Volume Up when hitting the power button. For this install, I have no data on the device. I specifically want it to be easy to boot, so that means skipping Omarchy’s default full-disk encryption. At the time of writing, this meant hitting at the disk-formatting confirmation prompt . This tablet only has a single USB-C port, so I needed a USB-C hub to plug in my mouse, keyboard, and USB drive simultaneously. I didn’t have the Surface keyboard (part of why I got a good deal on Marketplace). This one bit me. Omarchy always logs in automatically on encrypted installs because the LUKS prompt is the auth gate. On an unencrypted install, it logs in automatically exactly once. Then a one-shot service deletes , and SDDM shows a login screen forever after. To re-enable autologin, we just put the file back under a filename nothing will remove: Next, in the Omarchy menu, we set up . With that, the boot chain is fully unattended. Turning the machine on will take us straight to the desktop. is already installed in Omarchy. We can use a user service to launch the stream. We can keep the secrets out of the unit. Then, in : Then enable and check it: We can run on a different workspace, since the original workspace is now playing full-screen video. The recovery logic is all in . makes exit on a stalled connection rather than show a frozen frame, and makes it exit when the stream ends. relaunches it, starting with a 2-second delay and backing off toward 30 seconds during a long outage. Wi-Fi needs no special handling: reconnects on its own, and simply fails until it does. stops taps on the touchscreen from pausing or seeking, and uses VAAPI, which matters for heat on a fanless tablet. is there because Omarchy ships a default rule that floats the app ID in an 875×600 window. So, we can give the kiosk its own rule instead, appended to : A simple or a click on the “Stay Awake” icon in the taskbar will do the trick. This can also be done via the CLI: These settings are useful despite our Hyprland rule because the rule only applies while is playing. Without them, the tablet might still lock or sleep during downtime. These settings persist across reboots by default. Once the tablet is deployed, SSH is the intended way to interact with it. Omarchy has easy ways to set up SSH and Tailscale . The SSH setup installs OpenSSH, opens port 22 in (with a rate limit), handles key authorization, and disables password auth. Then, once Tailscale was set up, I disabled key expiry for this node. I like Omarchy for this because it is a rolling distro (based on Arch), which makes it easy to keep up to date. Just SSHing into the machine and running periodically does the trick. When a reboot is necessary, that’s no problem since the RTSP service will reconnect to the stream automatically on boot. Demo of the unattended boot. This turned out as nicely as I had hoped. All my goals were met, for cheap! Enable the battery limiter (Boot configuration -> Battery Limit: Enabled). Disable Secure Boot (Security -> Secure Boot: Off) (currently required to install Omarchy). Change the boot order to put the USB drive first.

0 views
Alex White's Blog 1 months ago

I've got a switching problem

The past two weeks I've developed a problem. Almost every other day I've been switching between two tech extremes, my MacBook + iPad Pro + iPhone + Apple Watch setup and my Ubuntu ThinkPad + GrapheneOS Pixel + Supernote Nomad + Fitbit/Pixel Watch setup. It's gotten to the point that I imagine someone at Google Fi must be looking at my insane amount of eSim transfers and just thinking "what the hell is wrong with this guy?". I think there's a number of reasons why my mind has been causing me to do this, but it all comes down to one goal: dumping Apple once and for all. There's the obvious case for privacy, escaping the walled garden and freeing myself from iCloud subscriptions. I also want to get out of such an expensive line of products, and open myself up to more Chinese domestic products (Xiaomi, Huawei, etc) in case I do end up moving to the country. Finally, I just find my Linux based computing devices to be faster. Somehow my Pixel 9 Pro is leagues snappier than my iPhone 17 Pro Max, and my ThinkPad P14s Gen 4 (feels like) it can run circles around my MacBook M1 Pro. Ever since Liquid Glass, my Apple devices just feel sluggish. But then why do I keep switching back to Apple? Primarily guilt, I spent too much on these damn Apple devices to not use them. Maybe someday I'll just bite the bullet and sell the Apple devices, until then, sorry Google Fi, I'm gonna need some more eSims provisioned.

0 views
Alex White's Blog 1 months ago

From Omarchy to Pop_OS!

I fell for the hype for a bit and was playing around with Omarchy on my ThinkPad. While I did like some of the opioniated setup (the theming system is very cool), a number of things bothered me. First and foremost, the controversy surrounding DHH is hard to ignore. I wasn't particularly well versed in it, but after doing some research I didn't feel great about using the distro. The second issue was the amount of AI. I said in my original article that some of the AI integration was pretty cool, and I still think so. Debugging a system crash with a model or leveraging AI to understand complex config files is a great use. But the problem is that everything is AI. It's a vibe coded Arch config, and that doesn't instill a ton of confidence when it comes to a daily driver. All that to say, I'm now testing out Pop_OS! with the new Cosmic desktop. I've used Pop_OS! before, back when it was basically a GNOME shell extension. I even own a System76 laptop and Launch Heavy keyboard. I support what the company is doing, and their CEO as done actual good (like fighting against age verification in OSS). It's a product I can feel good about supporting. So far, I'm pretty impressed! Cosmic has come a long way since the last time I tried out a beta. The theming is goregous and very customizable, workspaces is done very well, and the tiling is better than what's on offer in Omarchy land. I love that things were crafted rather than slopped together, and being built on Rust is a strong foundation. There's still some things missing, but overall I look forward to daily driving Pop_OS! and Cosmic. Heck, I might even try revitalizing my interest in coding by creating a app or two using their UI kit!

0 views
Jeff Geerling 1 months ago

Rebuilding a 1995 GPS Time Server so I don't get Telstra'd

In June I purchased this TrueTime XL-AK time server , so I could learn more of the history of GPS-based time. I received it on June 22, and just 16 days later a similar GPS time server took down Australia's cell service for 12 hours ! I made a short video about it but put off digging into the TrueTime... until now. Over the past couple weeks, I've 'restomodded' this device with a Raspberry Pi, to build a stratum 1 NTP Time server, which I'd like to eventually add to the NTP Pool . I found a way to drop in a Pi 5 and GNSS HAT, display the time and GPS status on the built-in 16x2 LCD, show the status on the bicolor LED, and make this box useful again.

0 views
Kev Quirk 1 months ago

2026-09-02 09:16: I've recently switched to Gnome's default apps for email etc. So instead of #Thunderbird doing...

I've recently switched to Gnome's default apps for email etc. So instead of #Thunderbird doing all the things, I have Geary, Calendar, and Contacts. Most of the time I only need email, so it's nice having a much simplified UX. I also like how integrated into Gnome they all are. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
neilzone 1 months ago

Automating local backups of UniFi OS Server on Linux with uos-backup

Earlier today, I migrated my self-hosted UniFi controller from Network Manager to UniFi OS Server . One of the annoyances of the new setup is that it does not allow automated local backups - just automated backups to Ubiquiti’s cloud. Fortunately, one can work around this. In the UniFi interface, I set up a new local user, , to use for this automated backup. I am using . is a simple Python scripts which someone has kindly written and shared. I did the following, on the machine I wanted to use to take and store the backups. Get the code: Change to the directory with the code: Edit the python script, for the correct URL, username for my new backup user, and password. Check that the requirements are met: Copy the script to : Make it executable: Create the directory to store the backups. This is the directory specified in the script; you can create a directory with a different path, and then just update the script according Test that the script works: Even though I had just set up a new user, I had managed to get the username and password wrong in the script, and this step helped me debug it. I checked in /var/lib/uos-server/ to check that I had backup files. Set up the systemd services: I then added the backup directory path to restic, so that it gets picked up with my automated restic backups too.

0 views
Farid Zakaria 2 months ago

nixpkgs-multiverse is audacitymaxxing

Every package manager on earth picks one version for you. Nixpkgs picked one too. It never had to. I shared nixpkgs-multiverse recently: one flake input that hands you every version of every package that ever shipped in Nixpkgs. I love how unbelievable audacious Nix lets me be, audacitymaxxing . As of this writing, you have access to 31,783 packages and 304,484 distinct package version pairs pulled from 1,537 revisions. 🤯 The fact most distributions only give you one version of each package is not a bug. It is often considered a feature: a single self-consistent set of software that boots and runs together. It falls directly out of a shared global filesystem, the filesystem hierarchy standard (FHS), like , and . The purpose and existence of Nix is to eschew from that convention and allow multiple versions of the same package to coexist. Nixpkgs is a distribution built on that capability, and yet, it has been doing the same thing as every other distribution: picking one version of everything. nixpkgs-multiverse only supports, at the moment , top-level attributes that are packages but already the sheer volume of installable software dwarfs . 1 Nix’s answer to the FHS was audacious in 2003 and is still audacious now. A package lives at , where the hash is derived from every input that went into building it: the intensional model . How audacious are we? How about 246 distinct CPython versions, from 2.6.8 forward, all installable side by side, all built and cached, all addressable by version number instead of commit hash. 2 To re-iterate, these are distinct versions of CPython, including their transitive dependencies. There is no or or that is shared between them. 3 They work just as reliably as when they were first released, and they are all still installable today and can be substituted from the cache. People want to pin to a version. Upgrading software can be disruptive, and some people have to stay on a particular version but that should not impede the rest of the world from moving forward. The nixpkgs-multiverse helped solve one of the oldest devenv.sh issues, cachix/devenv#16 , the desire to pin a specific package. “It is not really practical to pin a separate version of nixpkgs for every different version of a tool needed in a dev environment. Normally we have at least 20-30 different tools all with a specific pinned version that we would want to specify.” – itpropro The issue, “Pinning a specific package”, was opened on 2022-11-10 and is now closed. devenv now documents the multiverse as the solution. 💪 The audacity of the multiverse is not technical. Nix took care of that. There is no clever trick in here; it’s 5 MB of JSON, about 200 lines of Nix and a behind a memo table. The audacity is in the premise. Two smaller things landed that I like and which was driven by feedback from the community. A soak period. gives you the whole of as it stood N days before an anchor, a cooldown window, in the spirit of Determinate Systems’ cooldowns , except the anchor can be any selector takes. Provenance. Every package set carries where it came from, so a you were handed can be interrogated rather than guessed at. The data was fetched from the Repology repository size map.  ↩ The data for other distributions was fetched from Repology .  ↩ Unless they happen to dedupe due to their hash.  ↩ The data was fetched from the Repology repository size map.  ↩ The data for other distributions was fetched from Repology .  ↩ Unless they happen to dedupe due to their hash.  ↩

0 views
Jason Tucker 2 months ago

Exploring the world of Proxmox and installing Home Assistant OS on it

For the last few years I've been running Unraid on my Dell server for all of my media storage. There is a lot in there, immich photos, tv movie "linux isos" and a lot of docker containers for the various acquisition and management tools needed to move all the data around on the server and organize it. All of which has been Docker based with no VMs going on. I started to look into Proxmox for the desktop "server" that I have Home Assistant running on. I had HA running on HAOS and as Home Assistant writes about it: This isn't a tutorial on how to install Proxmox VE, there are other places to find such things Home Assistant: Proxmox VE Quick Start Guide is a great place to start. I'm just going to give you an overview of what I did mainly so I can read this again in a few months when I may end up redoing everything, who knows! So I wanted to try my hand at Proxmox VE and moving over Home Assistant to this platform didn't look to be too hard. I started off by doing a fresh backup of my HAOS install and then saving the encryption key by downloading the emergency kit and storing it somewhere safe. Home Assistant backups are encrypted so you want to make sure you have that key somewhere safe. After that I downloaded the ISO for Proxmox VE 9.2.6 and put it on a usb drive. My method of choice for this is putting Ventoy on a usb with a bunch of isos on it and storing it on top of my server in case I ever need to repair it I at least have a place to start. I put the drive in and went into the BIOS to make sure all of the virtualization options ( Intel VT-d or AMD IOMMU ) were enabled and then booted the usb and started installing Proxmox VE. This being my first time in Proxmox VE, but not my first time in a hypervisor, I knew that I was going to have to do a lot of reading and learning. I started out by watching WunderTech's Proxmox VE video to get myself up to speed. One takeaway I had was getting my backups and snapshots in order and setting up a NFS share on my Unraid server so Proxmox VE could see it. I then watched one of my favorite creators on YouTube, Techno Tim and his video on Proxmox VE as well. One thing I've learned is there are 2 camps when it comes to Proxmox, the folks that use it in homelab and set up the Proxmox Post Install Script and then the enterprise folks that just pay the fee to have the support they need. Me in this instance I'm the former so we loaded up SSH and ran the script and pressed Y a bunch of times to get us to the end. The write up on Derek's blog is quite helpful in using the helper scripts to get Home Assistant up and running. Once I was done with that I restored from backup and had a working Proxmox VE with Home Assistant on it. On the surface Proxmox VE is a great platform and simple to set up. I know it's quite deep when you get into the weeds. I'm going to next be exploring Home Assistant Backup vs Proxmox Backup reading this post on just that How To Backup Home Assistant In Proxmox so I can start using Snapshots and Backups and what the difference is between the two in Proxmox VE. One thing I'm really looking forward to is messing around with the recent Quartermaster integration with Proxmox VE which is more and more becoming an amazing Homelab remote control in your pocket. Here are the command line steps I did to get Quartermaster set up in Proxmox VE. If you ever need to redo this (e.g. lost the secret), you'd delete and recreate the token: pveum user token remove root@pam quartermaster pveum user token add root@pam quartermaster --comment 'Quartermaster client' Here is what it looks like in Quartermaster when it's all done. In the comments, what are you doing with Proxmox? What should I do next? Remember, you can leave a comment just by signing up for free for my blog, not obligated to pay for anything. Created the API token (secret is only ever shown in this output) pveum user token add root@pam quartermaster --comment 'Quartermaster client' Granted PVEAuditor + PVEVMUser on path / with propagate enabled pveum acl modify / --tokens 'root@pam!quartermaster' --roles PVEAuditor,PVEVMUser --propagate 1 Verified the ACL entries pveum acl list | grep quartermaster

0 views
Rob Zolkos 2 months ago

A Year on Omarchy. No Regrets.

I was at home, checking which Omarchy theme I was using, when I glanced at the About window and saw the OS age: over a year. That surprised me more than it probably should have. Not because Omarchy had been difficult, but because it had not been. A year had come and gone with very little fuss, which is about the best review I can give a daily work machine. I had tweeted it the simple way: Over a year on Omarchy now. No regrets. That was not meant as a grand claim about operating systems. I am not here to tell you macOS is bad, Windows is bad, or Linux has somehow won. I used macOS happily for a very long time. My first serious Mac was a 12” PowerBook, about a year before the Intel switch. After that I bought the first 16” Intel MacBook Pro and stayed in the Apple world for years. I converted plenty of friends and family along the way, partly because I liked the machines and partly because I did not want to keep fixing their Windows problems. I was not looking for a reason to leave. I was always Linux curious though. I had played with Linux From Scratch , Gentoo , Ubuntu , and Asahi on the Mac. My servers were Linux, so the operating system itself was never foreign to me. But desktop Linux was always the experimental machine. The one I poked at. The one I learned things on. Not the one I trusted when I had paid work to do. That distinction mattered. I could tolerate a half-working Linux system when I was tinkering. I could not tolerate it when I had client work, coding, screenshots, screencasts, email, Basecamp, Slack, and a normal day to get through. The Mac kept pulling me back for practical reasons. CleanShot was a big one. A lot of my work output involves showing what I built, recording quick demos, documenting bugs, or proving that code works. I also cared about the aesthetics. Fonts, keybindings, polish, the general feel of the machine. I was familiar with it and familiarity is valuable when you have work to do. Omarchy changed the equation because it was not another blank Linux canvas asking me to spend a month becoming my own desktop environment maintainer. It had opinionated defaults. You could touch nothing after the default install and have a good time. The omakase idea matters there. So does the manual . It gave me a supported path instead of another pile of choices. It also arrived at the right time. Linux itself has improved tremendously. A lot of the software I use is now web-based or Electron -based. The number of important apps that are only on Mac or Windows keeps shrinking, and the alternatives keep getting better. So I forced myself to use Omarchy as my daily driver for a week. I still had the Mac next to me. If I needed something, I could swivel over and use it. But as the week went on, I stopped swiveling. Eventually I closed the lid. I was productive. That is the whole thing. I could code. I could do client work. I could communicate. I could ship. And then the tiling window manager got me. Before this, I usually wanted multiple monitors connected to the Mac. With Omarchy, one monitor became enough. I can switch workspaces instantly, and that changed how the machine feels. My normal setup now is usually four workspaces, though it can stretch to eight. Workspace 1 is terminal, running Herdr and my coding sessions, with Pi and Claude Code sessions inside it. Workspace 2 is the browser. Workspace 3 is HEY and Slack . Workspace 4 is Basecamp . It sounds small until you live in it. The context switching is fast enough that extra monitors feel less necessary. The machine feels snappier. I get more computing for the buck. Less memory pressure, less CPU churn, fewer distractions. Some of that is my hardware, for sure. My main desktop is an Intel 14900 with 96GB of RAM, a 2TB drive, and a 16GB Nvidia card. It is a beast. But Omarchy makes that machine feel like mine in a way I had not felt for a while. That changed my relationship with hardware too. In the past, my MacBook was the computer. It sat on the desk connected to an external monitor, keyboard, and mouse. Everything orbited around it. Now Omarchy runs on my desktop and on my Framework 13 laptop. The laptop is nothing exotic; I mostly use it to SSH back into the desktop. My old 14” MacBook Pro with 64GB of RAM is still around, but it has been repurposed into an LLM experimentation machine because it can run some models that do not fit nicely on the desktop GPU. I still like Apple hardware. I just no longer need every serious machine I own to be Apple hardware. That is a bigger shift than it sounds like. I broke out of the bubble where I believed I needed an Apple computer to be productive. I can build an Intel or AMD machine, put Omarchy on it, and do my work. I can experiment with hardware without paying the Apple hardware tax every time I want a serious computer. The customization helps. I care that the machine looks good. Omarchy looks good by default, but I can also make it mine . The theme I happened to be using when I noticed the OS age was Retro 82. My favorite is my own version of Synthwave 84. Crisp font rendering matters. Theming matters. It sounds cosmetic, but it is part of whether I enjoy sitting in front of the thing all day. The other surprise is how well Omarchy pairs with AI agents. Linux has always been configurable, but much of that configuration lives in text files. That makes it unusually friendly to an agent that can read, explain, and carefully change the system. For someone technical who wants to understand more about their machine, that is extraordinary. A small example: VoxType , the speech-to-text tool that comes with Omarchy, stopped responding to its keybind one day. I opened Claude Code and asked it to figure out why VoxType was not working. It checked the system, found that the process had gotten stuck, stopped it, restarted it, and the tool came back. That is not a daily event, but when something does go astray, having an assistant that can inspect the system and explain what it is doing changes the experience. It makes Linux less mysterious without hiding how it works. That same feeling shows up when I fix Omarchy itself. I have had a handful of small PRs merged upstream: a 60-second inactivity timeout for the Walker launcher, AAC audio for screen recordings so Windows users could actually hear them, a silent screen recording option, update progress that does not look frozen, and audio normalization so screencasts are not absurdly quiet. None of these are grand architectural contributions. They are daily-driver paper cuts. Screen recording is important to my work, so when something was not quite right, I could figure it out and propose a fix. That is empowering. I can fix my own tools without asking anyone’s permission. If the fix seems useful to other people, I can send it upstream. You do not get to do that with core macOS or Windows behavior in the same way. There are still minor annoyances. Some software makers do not think about Linux first. Codex is not available there yet. Claude Code’s app eventually came to Linux, but it was not there on day one. These gaps are real, but they are less frequent than they used to be, and they bother me less than I expected. I would not tell everyone to switch. If you prefer using the mouse for everything and have no interest in learning keyboard shortcuts, Omarchy may not be for you. If you are not willing to pop the hood now and then, maybe stay where you are. But if you are technical, semi-technical, curious, a developer, a Mac power user, or just someone who likes computers and wants the machine to feel more like yours, I think it is worth trying. Especially if you tried desktop Linux five or ten years ago and bounced off. It is different now. Omarchy in particular gives you a system that works very well out of the box, with taste, performance, and a path through the rough edges. Omarchy is the first desktop Linux setup that crossed from interesting experiment to daily work machine for me. That is the post. Not that everyone should leave their current operating system. Not that I regret my years on the Mac. I do not. But I no longer feel tied to that ecosystem to get serious work done. A year passed with little fuss. The MacBook lid stayed closed. My work still got done. No regrets.

0 views
Farid Zakaria 2 months ago

Linux kernel will support $ORIGIN, sort of

For some reason, during TacoSprint 2026 I decided to see if we could tackle relocatable binaries in Nix. I enjoy these lofty goals to push Nix and the surrounding ecosystem forward. I am bold if not stupid . I left the last earlier post with one potential idea of how to get there: We could patch the Linux kernel so that $ORIGIN is supported in PT_INTERP and the shebang. I waded through the complexity of sending patches over email (turns out I actually enjoy this workflow!), and sent a proposal to the Linux kernel mailing list. My first attempt here proposed simply adding direct support for in the Virtual File System (VFS) subsystem. I waited nervously. I was expecting the result from what I had come to read about online; someone non-politely telling me to F$#CK OFF because there is something I missed, misunderstood or did not consider. 🤬 The result was completely different. 😲 Christian Brauner , the maintainer for VFS responded to me in good faith, asking for the rationale for the change and eventually proposing some ways in which such a support could make it into the subsystem. Note It definitely helped having someone like John Ericson chime in and advocate why having a non-fixed interpreter ( ) is useful to Nix and other use-cases (i.e. Buck & Bazel). He offered that potentially we could leverage eBPF as a programmable way to select an interpreter through binfmt_misc . I wanted to merely allow but a programmable selection could let us do anything! The idea must have really intrigued him because soon-after, on his vacation , Christian offered the first draft of such a solution. We went back and forth a little over the mailing list and the end result is a patch series that will make its way into branch in the near future. If you don’t know what eBPF is or , WTF did we just collaborate on? Let’s take a look! I won’t do eBPF justice, and there are plenty of articles online about it as it’s quite in-vogue at the moment. tl;dr; You can write programs in a C subset that gets compiled to an instruction set whose virtual machine is running within the kernel . Shouldn’t the kernel be super fast? Yes, the programs are jitted to their native CPU architecture and the programs have a fixed-time slice. Isn’t this some crazy vulnerability for the kernel? Before any code is loaded it is “verified” to be safe. Checkout this guide for more info. We can now support with a relatively simple eBPF program: Once the above program is loaded and registered into the kernel, we then ask the subsystem to trigger it. Checkout this thread if you want to see the complete example. What does that mean? It means that every binary now triggers the function above, in this case any file, but it could be executables with a new segment like , and the kernel will ask to determine the interpreter to use dynamically. Our special BPF program has support for 💥 What else could you do? Well we can now even completely replace the traditional QEMU registration script with a BPF program now like this one . What else can we do? Since we can now programmatically select our interpreter based on anything in the file, we can do quite a lot. I’m keen to hear your suggestions and ideas 💡. Some of the smaller items are that we can even support in the shebangs ( ) very easily as seen here : we simply look at the first 256 bytes of the file and look for to trigger. One downside or side-effect of the traditional hand-off was that the way in which the desired final binary was invoked was non-transparent . The registered interpreter becomes the process. It owns the entire process identity, and the binary you actually asked to run gets demoted to an argument. For or that’s acceptable as they are emulators but for a per-binary BPF loader that might pick a traditional it does not make much sense. This leaks in a few painful ways but the simplest are : Christian sent a large patch series for this as well. His latest patch series adds two new dispatch modes that close the gap from opposite ends and covers a few other gotchas that these modes can fix. The loader substitition is the one I’m most excited about for Nix. With the flag, the kernel executes the matched binary natively as the main image, and merely substitutes the registered interpreter for the loader named in the binary’s . stops being a hand-off and becomes a plain override. There’s no contract and no identity to reconstruct, so a stock dynamic loader works unchanged . Where does this leaves us? I’ll be tracking the Linux kernel releases and, once this lands in and ships in a tagged release, I plan to upstream a NixOS module that registers the support at boot. 🎉 The plan is to gate it on a new segment rather than matching every file. That keeps things backwards compatible : the BPF handler only kicks in for binaries that explicitly opt-in by carrying the new segment. This means Nix produced binaries continue to work without the BFP handler but those that have it may elevate themselves to relocatable status . A ship in harbor is safe, but that is not what ships are built for. — John A. Shedd and show the interpreter invocation, not what you executed. names the interpreter. Relocatable programs commonly locate themselves through , and instead they find the dynamic linker. 😩

0 views
Farid Zakaria 2 months ago

How to piss off your Nix friends

Warning If you are pissed off reading this blog post, I guess, mission accomplished ? Try not to take life too seriously. Unfortunately, there’s a lot worse things in life than my opinions on Nix. Seems like it’s all too easy to get people in Nix flustered, angry and out with their pitchforks. All it takes is someone proposing a markdown file for the community to lose its mind. Having been a member, exposed to and part of the Nix/NixOS community for many years, I thought I would share some personal opinions , some which are self-evident and others that are purely philosophical. Nix is brilliant and deeply flawed. Both things are true at the same time. The documentation is infamously terrible (although getting better!), the language is foreign to read for many and there are still growing pains from the governance changes. You should be free to say all of this and yet still believe Nix to be the best idea in the industry, at least this decade. The emperor has no clothes. “If we just fix the documentation and the onboarding, then there’s no stopping Nix & NixOS” - Most Nix users Nix is “having a moment”. Growth on any measurable metric is growing. There are endless posts about it. Part of human nature is the desire to win. As a result, there is a persistent fantasy that if we just fix the documentation, just smooth the onboarding, just ship a friendlier installer and so on, then everyone, even your grandmother , can be using NixOS. Nix is not meant for everyone. Nix is a power tool. Power tools have a learning curve and can occasionally take a finger. I continue to use a non-NixOS Linux machine in addition and guess what, it works well enough. It is surprisingly stable and despite what Nix leads us to believe, not everything is on fire. Our obsession with mass adoption has warped priorities and diluted the amazing possibilities Nix could allow by having to make it more palatable for broader appeal. Nix originated in Europe. It should be no surprise that it skews heavily European. We can easily affirm this from the 2025 community survey . Europeans are different from Americans. We hold different cultural values and priorities. Both have traits that I wish the other emulated. Unfortunately, where they clash however is often a point of contention. Americans are capitalist maximalists. The idea of the “American dream” is tied to it. We also have the largest military budget in the world. You’re rarely more than a degree or two from a through-line between a business and the military. This clashes with much of the European worldview. As a result, there’s a bit of an undercurrent where being an American or an American corporation is problematic in the community. Your position is suspect from the start, assumed to carry ulterior motives and it curdles into a purity test. I am clearly in the “AI is useful” camp. I have written before about how much LLMs have unlocked for me personally. The Nix ecosystem is probably the best poised for the AI-wave. I have found a newfound joy and love for my NixOS machine now with LLMs. All those weird quirks that bugged me I have been able to resolve, and declaratively reproduce for future generations. One-off AI written tools can be written and stored in my NixOS configuration with a sense of assurance that they will not collide or interfere with the rest of the system. Unfortunately there’s a loud contingent that treats AI output at best as technically unsound and at worst as some moral failing of the user. Despite nixpkgs offering AI tools, an AGENTS.md file was seen as heresy. I particularly enjoyed Linus Torvalds, on a kernel mailing list articulating better than me Linux’s position on AI: AI is a tool, just like other tools we use. And it’s clearly a useful one. […] Anybody who doubts that clearly hasn’t actually used it. These are tools we can use to push Nix & nixpkgs further. The democratic process is great for society but a software project originated from someone . Someone had the vision, birthed the idea, worked tirelessly on it and then attracted others to contribute to their ongoing vision. In the case of Nix, Eelco created Nix in 2003 as part of his PhD research. The NixOS foundation didn’t exist until 2015. That is over a decade of work towards a project driven by his own vision as the Benevolent Dictator for Life (BDFL). A non-democratic model works especially well in open-source because you are free to fork the software and try your hand at your own ideas if you disagree – the same cannot be said for our shared geography. A clear vision, whether you agree with it or not, is refreshing. Someone who can say yes or no and is not simply stonewalled by design-by-committee. DHH had said it poignantly well: “Using open source software does not entitle you to a vote on the direction of the project.” [ cite ]. Every hour spent making Nix pleasant on macOS is an hour not spent making Nix extraordinary on Linux. You would never catch an iOS developer working on Linux and yet it pains me to see those who target the Linux platform working on a Mac. For Nix, Darwin support is a bottomless tax. Closed toolchains, an SDK that shifts under you every release, a sandbox that fights you. All to chase an OS whose entire philosophy (opaque, proprietary, convention over purity) is the antithesis of Nix. When we have to target solutions that cover wildly different platforms, the end result is muddled and limited. Beauty, elegance and innovation emerge when you apply constraints and restrict a problem. Flakes are here to stay and yet their adoption is constantly brought up in order to validate its existence. I default to using it for my new projects, mostly because it’s easier at this point and it seems annoyingly tied to the new CLI format. Upon reflection though, I don’t feel like I have gained anything really over or . Subjectively my evaluations feel slower as now I’m fetching many more or jump through hoops to make every flake follow each other defeating the whole purpose of separate trees. Unless you are sharing a laptop with your family or are using a mainframe from 1980, you won’t have more than a single user on your machine. Despite this, the default installation we guide users towards is one designed for multiple users. The multiple-user install adds unnecessary complexity many don’t need or won’t understand: a build daemon, pool of users, systemd service, etc… In contrast, the single-user install is radically simpler to run, operate and triage. I don’t have to remember whether I am setting configuration for my “client” or the “daemon” and that there is a difference. Multi-user is the right default for a shared build farm. It is overkill for the single human it’s actually installed on the majority of the time. Nix is the closest thing we have to a solution where we can rebuild the entire world reproducibly. It is used by the Software Heritage Foundation as a way to reliably collect, preserve, and share all software that is publicly available in source code form [ cite ]. Some of the most amazing technology that exists in this world exists when one can make changes at multiple layers throughout the stack. This is the secret sauce to many of the hyperscalers of today. This is table-stakes for NixOS. You can implement a solution that requires new: application, compiler, library, runtime and kernel all within a single commit . Despite the ability to wildly diverge from traditional distributions, innovate and differentiate, we largely replicate the status-quo – albeit more reproducible. Whether it’s constraints imposed by needing to accommodate alternate platforms (e.g. macOS) or fearing alienating more novice-users we limit the potential of what Nix could do. Are you pissed off? Let us still be friends.

0 views
Kev Quirk 3 months ago

📝 2026-07-16 17:05: Anyone using Pop!OS with Cosmic? I tried it when it was first released, but I...

Anyone using Pop!_OS with Cosmic? I tried it when it was first released, but I looks like they've done a lot of dev work to it and it's improving all the time. Considering installing it again... Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views