summaryrefslogtreecommitdiff
path: root/src/blog/linking.kuht
diff options
context:
space:
mode:
Diffstat (limited to 'src/blog/linking.kuht')
-rw-r--r--src/blog/linking.kuht245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/blog/linking.kuht b/src/blog/linking.kuht
new file mode 100644
index 0000000..f994765
--- /dev/null
+++ b/src/blog/linking.kuht
@@ -0,0 +1,245 @@
+<import "base.kuht" as "base" />
+
+<head>
+ <title>What Other Distros Can Learn from NixOS</title>
+ <meta name="description" content="Traditional distros will either have delayed updates or unstable updates. NixOS allows us to have both." />
+</head>
+
+<body>
+<article>
+<h1>What Other Distros Can Learn from NixOS</h1>
+
+<p>
+ As a warning, this blog post contains the ramblings of an Arch user who
+ barely knows what a flatpak is and has like, three of them on their system.
+ Their background is in web deployment pipelines and they're trying to apply
+ their personal beliefs to Linux distributions, like an idiot, without even
+ making a proof-of-concept. Reader discretion is advised.
+</p>
+
+<p>
+ One debate that often comes up is static versus dynamic linking. Most Linux
+ distributions try to manage dependencies by dynamically linking them. This can
+ be good, because if a previous version of a library contains a bug, then it's
+ easy to distribute the bug fix and have it apply to all applications
+ simultaneously. The downside is that if a newer version of a library contains
+ a bug, or a backwards-incompatible change, then that will apply to all
+ installed applications. Dynamic linking is a double-edged sword that makes it
+ both easier to fix bugs and easier to create new ones.
+</p>
+
+<p>
+ But NixOS offers strict control over both the release and use of libraries,
+ which allows applications to get both the ease of rollout that comes with
+ dynamic linking, and the control that comes from static linking.
+</p>
+
+<h2>Background</h2>
+
+<p>
+ When an application is installed on NixOS, it is not put in the
+ <code>/bin</code> folder. In fact, this folder is almost entirely empty.
+ Instead, it goes to <code>/nix/store</code>, in a directory with an
+ unreadable hash. Then, when you boot the system, the files for your system
+ applications are symlinked into <code>/run/current-system/sw</code>, which is
+ in the <code>PATH</code>, so these applications can run in your terminal.
+</p>
+
+<p>
+ But that's only system applications. For libraries, the application sets its
+ own <code>LD_LIBRARY_PATH</code> variable. This tells the dynamic linker
+ where to fetch the required libraries from. This isn't exactly what the file
+ looks like, but you can imagine it looking something like this:
+</p>
+
+<pre>
+#!/path/to/bash
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/nix/store/naioghuraopjfi4738-libgit2-2.23"
+export LD_LIBRARY_PATH
+exec -a git "$@"
+</pre>
+
+<p>
+ The benefit of this system is that you can multiple versions of the same
+ library installed on your system, and different applications can depend on
+ different versions, depending on what they need.
+</p>
+
+<p>
+ I want to note that there's nothing special about NixOS that would make this
+ impossible on other systems. Flatpak already allows applications to bundle
+ their own versions of libraries, and Snap has a similar system. So I think
+ other distros can still benefit from this system.
+</p>
+
+<h2>Testing</h2>
+
+<p>
+ Before I go into the benefits of the system described above, I'll touch on
+ something that distros can do already, but that specifying dependency
+ versions might make easier.
+</p>
+
+<p>
+ Before you can even update the repository, you'll have to test the library.
+ Hopefully, the maintainer of the library has already done this for you, by
+ creating a suite of unit tests that they ran before creating the release. I
+ suppose it wouldn't hurt to double check.
+</p>
+
+<p>
+ The more interesting test you'll need to run is similar to what
+ <a href="https://github.com/rust-lang/crater">crater</a> does for the Rust
+ ecosystem. Whenever a change is made to the language, Rust runs crater to
+ determine if the change would cause a breaking change for any packages on
+ crates.io. It's a very brute-force way to test for new bugs.
+</p>
+
+<p>
+ In order for this to work, not only does the library need a unit test suite,
+ but so does every application that depends on that library. You'll build
+ every single dependent against the newer version of the library, and then
+ test all of them to see if anything breaks.
+</p>
+
+<p>
+ Inevitably, some applications will fail under a new version of a library.
+ This doesn't necessarily need to be because of a problem in the library
+ itself, but it could be due to a transient failure in the application. In
+ such a scenario, the application's dependency would be updated to say
+ <code>3.13</code> instead of <code>3</code>, so it doesn't block other
+ applications from using the newer version.
+</p>
+
+<p>
+ It would also be beneficial to store somewhere in the package which version
+ of each dependency an application was last tested with. Then, if you want to
+ be extra safe, you can delay upgrading the dependency until you know that a
+ test has been run on the latest dependencies.
+</p>
+
+<h2>Beta Channel</h2>
+
+<p>
+ The delayed release of packages is what separates Arch Linux from Manajaro.
+ Some users are more interested in being on the bleeding edge than others. I
+ don't see any reason why two separate package repositories are needed for
+ this. We can allow users to opt-in to the bleeding edge for specific packages
+ faster. These people can submit bug reports before the new features make
+ their way to regular users.
+</p>
+
+<p>
+ NixOS has this in the form of the <code>unstable</code> channel. Users can
+ opt-in to using the unstable channel to get an experience more similar to a
+ rolling release distro. And judging from some Reddit threads, there are
+ people using the unstable channel regularly. This makes sense to me, since
+ not everyone who uses Nix is there for stability. Some people just like
+ having a central config file. NixOS also lets people go one step further and
+ use <code>unstable</code> for specific packages, but leave the rest of their
+ entire system stable.
+</p>
+
+<p>
+ Other distros do have this. Most commonly this comes in the form of an LTS
+ variant of the distro, which most users are expected to stay on. The non-LTS
+ variant is often treated as a beta.
+</p>
+
+<h2>Rollout</h2>
+
+<p>
+ The rest of the ideas presented in this post are ideas that can be done as
+ long as you have a way to pin dependency versions, but they're not done by
+ NixOS. How important these are is debatable, since NixOS already tests their
+ stable channels before releasing them.
+</p>
+
+<p>
+ Not every package is of equal importance. A change to a library affecting
+ pacman is far more critical to a library that only affects GIMP. But thanks
+ to the system we have here, it doesn't need to affect every package at the
+ same time. We can rollout a library change to less important packages first
+ before we apply it to every library.
+</p>
+
+<p>
+ To give an example of how this would work, let's say a new library version
+ releases, and it affects both pacman and GIMP. For this to work, we'd need to
+ assign a priority level to every package. Pacman would probably be a level 2
+ package, meaning it's very important. There should only be a few level 1
+ packages. GIMP would be level 4, so not very important. As a level 4 package,
+ GIMP would be one of the first packages to use the new version of the
+ library. After a couple days, pacman would also start using the new library.
+</p>
+
+<h2>Rollback</h2>
+
+<p>
+ So with all that in mind, what happens when a library actually is bad? Well,
+ marking the library version as bad is luckily pretty simple. We just update
+ the version resolver to say that if a package asks for version
+ <code>3</code>, don't use <code>3.14</code>. Prefer <code>3.13</code>
+ instead. Pacman already caches older versions of packages, so you might not
+ even need to re-install <code>3.13</code>.
+</p>
+
+<p>
+ Of course, rolling backwards isn't always safe. Some newer packaages might
+ already be using features of <code>3.14</code> that don't exist in
+ <code>3.13</code>. To partially resolve this, we can run the test suite
+ against each package before downgrading to <code>3.13</code>. Hopefully
+ everything will pass, but if a particular package does not, then we can set
+ that package specifically to require a minimum of <code>3.14</code>. We can
+ also mark this downstream package as bad, and prevent new installations of it
+ until a patch is made.
+</p>
+
+<h2>Distribution</h2>
+
+<p>
+ There's one thing here that we can't control: the distribution. Meaning, we
+ don't know when the user is going to run an upgrade. Unlike in Windows land
+ or web land, we don't run the upgrade automatically. Some systems will at
+ least automatically check for updates and notify the user when there is one,
+ but there's usually no distinction between critical bug fixes and feature
+ updates.
+</p>
+
+<p>
+ I would recommend having a daemon that at least automatically downgrades in
+ the case of bad library versions. Since we can cache older versions of the
+ library, this wouldn't require too much network activity. And we can always
+ give the user an option to disable it.
+</p>
+
+<p>
+ NixOS actually does support full automatic upgrades in the background. Some
+ NixOS users report that because NixOS is so stable, they feel comfortable to
+ just letting everything update in the background without intervention. The
+ NixOS wiki provides this example on how to do so.
+</p>
+
+<pre>
+system.autoUpgrade = {
+ enable = true;
+ flags = [
+ "--print-build-logs"
+ ];
+ dates = "02:00";
+ randomizedDelaySec = "45min";
+ allowReboot = false; # Set to true if you want automatic reboots
+};
+</pre>
+
+<h2>Conclusion</h2>
+
+<p>
+ I don't want to say none of these solutions come with caveats. NixOS has
+ trouble running arbitrary executables because of how it goes about
+ accomplishing its goals. The way things are set up on NixOS can sometimes be
+ confusing to newcomers, and I understand why a Linux distro wouldn't want to
+ copy everything from NixOS. But I think even a best-effort attempt at some of
+ the ideas that NixOS provides could provide major benefits for stability.
+ It's just about choosing the right compromises.
+</p>