aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Ballou <kballou@devnulllabs.io>2019-08-15 06:57:53 -0600
committerKenny Ballou <kballou@devnulllabs.io>2019-09-29 12:55:11 -0600
commit60851fa3b72c4a89852982e5f9890af4b5726920 (patch)
tree6d2e87644a29e973b99b327655ae689d13664cc7
parente6a997d8a7cb1bfaacb2d3cfd958bda23b83c7e1 (diff)
downloadblog.kennyballou.com-60851fa3b72c4a89852982e5f9890af4b5726920.tar.gz
blog.kennyballou.com-60851fa3b72c4a89852982e5f9890af4b5726920.tar.xz
nixos: the what and why
Signed-off-by: Kenny Ballou <kballou@devnulllabs.io>
-rw-r--r--posts/nixos.org461
1 files changed, 461 insertions, 0 deletions
diff --git a/posts/nixos.org b/posts/nixos.org
new file mode 100644
index 0000000..d99cff4
--- /dev/null
+++ b/posts/nixos.org
@@ -0,0 +1,461 @@
+#+TITLE: NixOS
+#+DESCRIPTION: NixOS
+#+TAGS: GNU/Linux
+#+TAGS: nixos
+#+TAGS: nix
+#+DATE: 2019-07-19
+#+SLUG: nixos
+#+LINK: ansible https://www.ansible.com/
+#+LINK: configuration-management-wiki https://en.wikipedia.org/wiki/Software_configuration_management
+#+LINK: fhs https://refspecs.linuxfoundation.org/fhs.shtml
+#+LINK: glibc https://www.gnu.org/software/libc/
+#+LINK: gnu https://www.gnu.org
+#+LINK: guile-scheme https://www.gnu.org/software/guile/
+#+LINK: guix https://guix.gnu.org/
+#+LINK: linux https://www.kernel.org/
+#+LINK: man-symlink-2 http://man7.org/linux/man-pages/man2/symlink.2.html
+#+LINK: mozilla-firefox https://www.mozilla.org/en-US/firefox/
+#+LINK: nftables https://wiki.nftables.org/wiki-nftables/index.php/Main_Page
+#+LINK: nix https://nixos.org/nix/
+#+LINK: nix-expression https://nixos.wiki/wiki/Nix_Expression_Language
+#+LINK: nix-expressions https://nixos.wiki/wiki/Nix_Expression_Language
+#+LINK: nix-paper https://www.usenix.org/legacy/events/lisa04/tech/full_papers/dolstra/dolstra.pdf
+#+LINK: nixos https://nixos.org/
+#+LINK: nixos-manual https://nixos.org/nixos/manual/index.html
+#+LINK: nixos-paper https://nixos.org/~eelco/pubs/nixos-icfp2008-final.pdf
+#+LINK: puppet https://puppet.com/
+#+LINK: python https://python.org
+#+LINK: salt-stack https://www.saltstack.com/
+#+LINK: wiki-dsl https://en.wikipedia.org/wiki/Domain-specific_language
+#+LINK: wiki-dsl https://en.wikipedia.org/wiki/Domain-specific_language
+#+LINK: wiki-luks https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup
+#+LINK: wiki-raid https://en.wikipedia.org/wiki/RAID
+#+LINK: wiki-unix-epoch https://en.wikipedia.org/wiki/Unix_time
+
+
+#+BEGIN_PREVIEW
+[[nixos][NixOS]] is a new kind of [[gnu][GNU]]/[[linux][Linux]] distribution,
+borrowing the ideas of functional programming languages to bring about a
+revolution of how we think about operating systems and software development.
+#+END_PREVIEW
+
+** NixOS
+
+[[nixos][NixOS]] is a "functional" [[gnu][GNU]]/[[linux][Linux]] distribution
+extending the ideas of functional programming languages to operating systems.
+
+To illustrate, most operating systems are more analogous to imperative
+languages where the programmer instructs, via the various incantations of the
+language, the computer to perform some operation. Many of these instructions
+modify state-- variables, files, network packets. Functional programming
+languages can be instructive, but many of them feel more declarative in nature.
+That is, instead of telling what the computer to do, the programmer defines the
+result of the computation. Side-effects, as they are known, are either
+disallowed completely or require a certain amount of "ceremony" to be
+performed.
+
+Following this imperfect analogy, [[gnu][GNU]]/[[linux][Linux]] distributions
+typically follow the imperative paradigm: the operator issues instructions that
+modify the state of the system. Installing and configuring some software
+package, for example, requires the operator to run a series of commands that
+first install the package, another series of commands to configure the software
+to the desired state, and finally, the system and the resulting software is
+ready for use.
+
+In contrast, [[nixos][NixOS]] follows the functional paradigm. The entire
+system, from the boot loader to the available software and its configuration
+can all be traced to a single file: ~/etc/nixos/configuration.nix~.
+
+In the system configuration file for [[nixos][NixOS]], we declare the various
+end states of the system:
+
+- system packages
+
+- system services
+
+- users and groups
+
+- kernel modules loaded during boot
+
+- boot loader configuration
+
+- mount points
+
+The vast majority of the system can be codified into this configuration file.
+Currently missing is disk partitioning and allocation and user data.
+
+To understand better the concepts behind [[nixos][NixOS]], we will take a brief
+detour through [[nix][Nix]], the package manager.
+
+*** Nix (the package manager)
+
+Beyond the comparisons of language paradigms, there are some other _really_
+neat ideas that come from the [[nix][Nix]] family. Specifically, I want to
+discuss the dependency management of [[nix][Nix]] and, therefore,
+[[nixos][NixOS]].
+
+Recall the description of the "imperative" operating systems above: many
+software packages have dependencies on various other components and packages.
+Typically the distribution managers resolve the dependencies into a coherent
+tree such that all packages resolve to the correct (read available) version of
+[[glibc][~glibc~]]. However, maintainers are human and maintainership is
+non-trivial. Packages slip through, and core breakages happen. Worse, the
+possible matrix of configurations and various packages is mind-numbingly
+large.
+
+Concretely, what this may look like can be demonstrated by a simple example.
+Let's say an operator installs package ~A~ which depends on package ~C~.
+Later, our example operator installs another package ~B~, which also depends on
+package ~C~. For now, we will say that package ~C~ is the same version. So
+far, all is good. Nothing is broken, and the system is stable. However, some
+time later, package ~B~ needs to be updated and causes a resulting update to
+package ~C~. Now package ~A~ may not work. Its version of package ~C~ is now
+replaced by the version pulled in by package ~B~. This may be fine, but by a
+similar token, it may also be plainly broken. Worse, it may be only _subtly_
+broken, the breakage is not noticed by cursory testing.
+
+Using [[nix][Nix]], this situation is impossible. Package ~A~ has its own
+complete dependency graph, including package ~C~'s dependency graph. The same
+holds for package ~B~, [[nix][Nix]] stores the entire dependency graph of each
+package separate from each other package.
+
+Therefore, given our above example of package management mishaps, when package
+~B~ updates and pulls in a new version of package ~C~. The version of ~C~ used
+by ~A~ is left untouched and package ~A~ works just the same as before.
+
+*** Nix Store
+
+After examining the above example, how does [[nix][Nix]] accomplish this?
+
+If we think about the [[fhs][Filesystem Hierarchy Standard]], an executable
+package is installed into some ~bin~ directory, its dynamically linked objects
+are in a ~lib~ directory, its configuration may be in a ~etc~ directory.
+
+With a [[nix][Nix]] package, the package has all same directories, however,
+they are isolated in the "store". The [[nix][Nix]] store is typically a
+directory ~/nix/store/~ that contains each package in its ~hash-name-version~
+folder. For example, let's look at [[mozilla-firefox][Firefox]]:
+
+#+begin_example
+% ls -al $(which firefox)
+lrwxrwxrwx 1 root root 68 Dec 31 1969 /run/current-system/sw/bin/firefox -> /nix/store/78gl44fjjira5jsgyj8vdwsnw8wdwngs-firefox-68.0/bin/firefox
+% ls -l /nix/store/78gl44fjjira5jsgyj8vdwsnw8wdwngs-firefox-68.0/
+total 0
+dr-xr-xr-x 2 root root 21 Dec 31 1969 bin
+dr-xr-xr-x 3 root root 21 Dec 31 1969 lib
+dr-xr-xr-x 2 root root 42 Dec 31 1969 nix-support
+dr-xr-xr-x 4 root root 39 Dec 31 1969 share
+#+end_example
+
+There's a few things to notice here. One, the directories are all read-only;
+two, the modified time is set to [[wiki-unix-epoch][UNIX Epoch]]; third, the
+entire folder structure necessary for [[mozilla-firefox][Firefox]] to run is in
+this store.
+
+Let's examine a package that requires dynamic linking to correctly execute, the
+[[python][Python]] interpreter:
+
+#+begin_example
+% ls -l $(which python)
+lrwxrwxrwx 1 root root 68 Dec 31 1969 /run/current-system/sw/bin/python -> /nix/store/dmh36s38dcpc91grfsh6wqrm65rz5hfh-pythonOverlay/bin/python
+% ls -l /nix/store/dmh36s38dcpc91grfsh6wqrm65rz5hfh-pythonOverlay
+total 4
+dr-xr-xr-x 2 root root 4096 Dec 31 1969 bin
+lrwxrwxrwx 1 root root 65 Dec 31 1969 include -> /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/include
+dr-xr-xr-x 3 root root 113 Dec 31 1969 lib
+dr-xr-xr-x 3 root root 17 Dec 31 1969 share
+#+end_example
+
+Now, let's examine the linked objects:
+
+#+begin_example
+% ldd $(which python)
+linux-vdso.so.1 (0x00007ffd3c3d9000)
+libpython3.7m.so.1.0 => /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/lib/libpython3.7m.so.1.0 (0x00007f6ccf964000)
+libpthread.so.0 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libpthread.so.0 (0x00007f6ccf943000)
+libdl.so.2 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libdl.so.2 (0x00007f6ccf93e000)
+libcrypt.so.1 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libcrypt.so.1 (0x00007f6ccf904000)
+libncursesw.so.6 => /nix/store/adc71v5apk4dzcxg7cjqgszjg1a6pd0z-ncurses-6.1-20190112/lib/libncursesw.so.6 (0x00007f6ccf892000)
+libutil.so.1 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libutil.so.1 (0x00007f6ccf88b000)
+libm.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libm.so.6 (0x00007f6ccf6f5000)
+libgcc_s.so.1 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libgcc_s.so.1 (0x00007f6ccf4df000)
+libc.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc.so.6 (0x00007f6ccf329000)
+/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib64/ld-linux-x86-64.so.2 (0x00007f6ccfccf000)
+#+end_example
+
+Each of the linked objects, sans the kernel object, are found in the
+[[nix][Nix]] store.
+
+Furthermore, if we examine the [[python][Python]] ~lib~ folder:
+
+#+begin_example
+% ls -l /nix/store/dmh36s38dcpc91grfsh6wqrm65rz5hfh-pythonOverlay/lib
+total 12
+lrwxrwxrwx 1 root root 78 Dec 31 1969 libpython3.7m.so -> /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/lib/libpython3.7m.so
+lrwxrwxrwx 1 root root 82 Dec 31 1969 libpython3.7m.so.1.0 -> /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/lib/libpython3.7m.so.1.0
+lrwxrwxrwx 1 root root 75 Dec 31 1969 libpython3.so -> /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/lib/libpython3.so
+lrwxrwxrwx 1 root root 71 Dec 31 1969 pkgconfig -> /nix/store/10rqw9cx8x2knwdaxhlyb4drla8v8zzk-python3-3.7.4/lib/pkgconfig
+dr-xr-xr-x 3 root root 8192 Dec 31 1969 python3.7
+#+end_example
+
+The shared objects and folders are also symbolic links to other packages and
+folders in the [[nix][Nix]] store.
+
+This leads us to the following observation: packages in the [[nix][Nix]] store
+are comprised of the outputs of the package and associated symbolic links to
+the package's inputs.
+
+*** Nix Profiles
+
+Packages in [[nix][Nix]] are directory trees found in the [[nix][Nix]] store,
+what are profiles? Perhaps, more appropriately, what are user environments?
+
+When setting up [[nix][Nix]] as a package manager either in [[nixos][NixOS]] or
+a different [[gnu][GNU]]/[[linux][Linux]] distribution, there's typically a
+symbolic link in the user's home directory:
+
+#+begin_example
+% ls -l ~/.nix-profile
+lrwxrwxrwx 1 kb users 41 May 15 2017 /home/kb/.nix-profile -> /nix/var/nix/profiles/per-user/kb/profile
+#+end_example
+
+However, this link is to another link. Let's follow the rabbit:
+
+#+begin_example
+% ls -l /nix/var/nix/profiles/per-user/kb/profile
+lrwxrwxrwx 1 kb users 14 Jul 30 15:15 /nix/var/nix/profiles/per-user/kb/profile -> profile-3-link
+#+end_example
+
+This indirect symbolic link points to a symbolic link in the same directory.
+Let's keep following:
+
+#+begin_example
+% ls -l /nix/var/nix/profiles/per-user/kb/profile-3-link
+lrwxrwxrwx 1 kb users 60 Jul 30 15:15 /nix/var/nix/profiles/per-user/kb/profile-3-link -> /nix/store/d7d6hcv8v2crb98nhh00nrr2bkh034kc-user-environment
+% ls -l /nix/store/d7d6hcv8v2crb98nhh00nrr2bkh034kc-user-environment
+dr-xr-xr-x 2 root root 156 Dec 31 1969 bin
+lrwxrwxrwx 1 root root 63 Dec 31 1969 etc -> /nix/store/k0hyks88khah4hvb19i0d6swsawyzz5a-awscli-1.16.170/etc
+dr-xr-xr-x 2 root root 35 Dec 31 1969 lib
+lrwxrwxrwx 1 root root 60 Dec 31 1969 manifest.nix -> /nix/store/lqc7v4cb77fzgnrqn0miz1fpkzb3dxc2-env-manifest.nix
+lrwxrwxrwx 1 root root 65 Dec 31 1969 share -> /nix/store/k0hyks88khah4hvb19i0d6swsawyzz5a-awscli-1.16.170/share
+#+end_example
+
+After following three links, we are referred to a directory tree in the
+[[nix][Nix]] store.
+
+Let's examine the ~bin~ directory quickly:
+
+#+begin_example
+% ls -l /nix/store/d7d6hcv8v2crb98nhh00nrr2bkh034kc-user-environment/bin
+total 0
+lrwxrwxrwx 1 root root 67 Dec 31 1969 aws -> /nix/store/k0hyks88khah4hvb19i0d6swsawyzz5a-awscli-1.16.170/bin/aws
+lrwxrwxrwx 1 root root 82 Dec 31 1969 aws_bash_completer -> /nix/store/k0hyks88khah4hvb19i0d6swsawyzz5a-awscli-1.16.170/bin/aws_bash_completer
+lrwxrwxrwx 1 root root 77 Dec 31 1969 aws_completer -> /nix/store/k0hyks88khah4hvb19i0d6swsawyzz5a-awscli-1.16.170/bin/aws_completer
+lrwxrwxrwx 1 root root 89 Dec 31 1969 cargo-generate-nixfile -> /nix/store/s11zqp9r8h4r65iqv272b477igb9a9mw-rust_carnix-0.10.0/bin/cargo-generate-nixfile
+lrwxrwxrwx 1 root root 91 Dec 31 1969 cargo_generate_nixfile.d -> /nix/store/s11zqp9r8h4r65iqv272b477igb9a9mw-rust_carnix-0.10.0/bin/cargo_generate_nixfile.d
+lrwxrwxrwx 1 root root 73 Dec 31 1969 carnix -> /nix/store/s11zqp9r8h4r65iqv272b477igb9a9mw-rust_carnix-0.10.0/bin/carnix
+lrwxrwxrwx 1 root root 75 Dec 31 1969 carnix.d -> /nix/store/s11zqp9r8h4r65iqv272b477igb9a9mw-rust_carnix-0.10.0/bin/carnix.d
+#+end_example
+
+Currently, this example profile only has two packages installed:
+
+#+begin_example
+% nix-env -q
+awscli-1.16.170
+rust_carnix-0.10.0
+#+end_example
+
+But from this example so far, we see that user environments are comprised of
+symbolic link "forests" of the packages that make up the current profile.
+
+Let's follow this example again, however, we going to modify the user
+environment by adding a package:
+
+#+begin_example
+% nix-env -i autogen
+#+end_example
+
+Starting with second link:
+
+#+begin_example
+% ls -l /nix/var/nix/profiles/per-user/kb/profile
+lrwxrwxrwx 1 kb users 14 Aug 13 05:52 /nix/var/nix/profiles/per-user/kb/profile -> profile-4-link
+#+end_example
+
+The profile link now points to a different link. Let's keep going:
+
+#+begin_example
+% ls -l /nix/var/nix/profiles/per-user/kb/profile-4-link
+lrwxrwxrwx 1 kb users 60 Aug 13 05:52 /nix/var/nix/profiles/per-user/kb/profile-4-link -> /nix/store/xslnn9gs5gkgdvzgb0w3b0iggbsszag5-user-environment
+#+end_example
+
+The user-profile now points to a completely different symlink forest in the
+[[nix][Nix]] store.
+
+The old profile still exists. Let's switch (rollback) to it:
+
+#+begin_example
+% nix-env --rollback (1)
+switching from generation 4 to 3
+% ls -l /nix/var/nix/profiles/per-user/kb/profile
+lrwxrwxrwx 1 kb users 14 Aug 13 05:56 /nix/var/nix/profiles/per-user/kb/profile -> profile-3-link
+% ls -l /nix/var/nix/profiles/per-user/kb/profile-3-link
+lrwxrwxrwx 1 kb users 60 Jul 30 15:15 /nix/var/nix/profiles/per-user/kb/profile-3-link -> /nix/store/d7d6hcv8v2crb98nhh00nrr2bkh034kc-user-environment
+#+end_example
+
+Rolling back to a previous profile was effortless and we went back to _exactly_
+the same store path that we had previously.
+
+Since the [[man-symlink-2][~symlink(2)~]] operation is atomic, changing profile
+generations is atomic. Adding a package to the profile is atomic: that is,
+once the package is downloaded, built, added to the store, and the set of links
+are compiled into a new profile, the switch to this new profile is entirely
+atomic. If the any of the previous steps fail, the user profile is not
+adversely affected.
+
+*** System Profiles
+
+After user profiles, we are left with system profiles. What exactly is
+[[nixos][NixOS]]? If any of the above provides any foreshadowing, the answer
+may seem obvious: a system profile is a forest of symbolic links to the
+packages, services, and other system configuration that comprise a
+[[gnu][GNU]]/[[linux][Linux]] system.
+
+However, that may not be obvious.
+
+Let's start by first reiterating that [[nixos][NixOS]] is different than
+traditional [[gnu][GNU]]/[[linux][Linux]] distributions, very different. One
+of the most notable differences that is important to this discussion is the
+lack of adherence to the [[fhs][Filesystem Hierarchy Standard]]. Chiefly, in
+the root of the filesystem of a [[nixos][NixOS]] system, there is almost no
+need for ~/bin~, ~/usr~, and ~/lib~.
+
+#+begin_example
+% ls -l /
+total 57
+drwxr-xr-x 2 root root 4096 Aug 2 09:04 bin
+drwxr-xr-x 5 root root 1024 Jun 5 17:01 boot
+drwxr-xr-x 21 root root 4140 Aug 13 05:37 dev
+drwxr-xr-x 26 root root 4096 Aug 2 09:04 etc
+drwxr-xr-x 3 root root 19 May 16 10:54 gnu
+drwxr-xr-x 3 root root 29 May 8 07:24 home
+drwx------ 2 root root 16384 Jun 5 16:02 lost+found
+drwxr-xr-x 4 root root 30 May 16 09:49 nix
+drwxr-xr-x 5 root root 4096 Jun 5 20:01 opt
+dr-xr-xr-x 257 root root 0 Aug 2 09:03 proc
+drwx------ 6 root root 4096 Aug 12 23:04 root
+drwxr-xr-x 20 root root 640 Aug 14 20:56 run
+dr-xr-xr-x 13 root root 0 Aug 2 09:03 sys
+drwxrwxrwt 55 root root 16384 Aug 14 21:00 tmp
+drwxr-xr-x 3 root root 4096 Jun 5 17:01 usr
+drwxr-xr-x 9 root root 4096 Aug 2 09:04 var
+#+end_example
+
+In the above output, there /is/ both ~/bin~ and ~/usr~, but no ~/lib~. What is
+in ~/bin~ and ~/usr~? Two things: one, ~/bin/sh~ and two, ~/usr/bin/env~.
+These are kept around as ways to resolve issues with porting packages into the
+[[nix][Nix]] environment.
+
+#+begin_example
+% ls -l /bin/
+total 4
+lrwxrwxrwx 1 root root 75 Aug 2 09:04 sh -> /nix/store/93h01q6yg13xdrabvqbddzbk11w6a928-bash-interactive-4.4-p23/bin/sh
+% ls -lR /usr
+/usr:
+total 4
+drwxr-xr-x 2 root root 4096 Aug 2 09:04 bin
+/usr/bin:
+total 4
+lrwxrwxrwx 1 root root 66 Aug 2 09:04 env -> /nix/store/d9s1kq1bnwqgxwcvv4zrc36ysnxg8gv7-coreutils-8.30/bin/env
+#+end_example
+
+Notice, however, that these files are in fact symbolic links into the
+[[nix][Nix]] store.
+
+If there is nothing in ~/bin~ and nothing in ~/usr~, where does the system find
+all of the install programs?
+
+The answer: ~/run/current-system~:
+
+#+begin_example
+% ls -l /run/current-system
+lrwxrwxrwx 1 root root 88 Aug 2 09:04 /run/current-system -> /nix/store/9c3k3ky5lg3x937984902v1d7148m7c5-nixos-system-phenex-19.03.173147.77295b0bd26
+% ls -l /nix/store/9c3k3ky5lg3x937984902v1d7148m7c5-nixos-system-phenex-19.03.173147.77295b0bd26
+total 48
+-r-xr-xr-x 1 root root 16455 Dec 31 1969 activate
+lrwxrwxrwx 1 root root 91 Dec 31 1969 append-initrd-secrets -> /nix/store/vynm9pvxlzd8rracmmkhpj2a3g79whbw-append-initrd-secrets/bin/append-initrd-secrets
+dr-xr-xr-x 2 root root 37 Dec 31 1969 bin
+-r--r--r-- 1 root root 0 Dec 31 1969 configuration-name
+lrwxrwxrwx 1 root root 51 Dec 31 1969 etc -> /nix/store/a04f5cdfinc8p4n6x0hw9a0jn5l2mi9i-etc/etc
+-r--r--r-- 1 root root 57 Dec 31 1969 extra-dependencies
+dr-xr-xr-x 2 root root 6 Dec 31 1969 fine-tune
+lrwxrwxrwx 1 root root 65 Dec 31 1969 firmware -> /nix/store/ak22608y0db7m4bzwmps23gi4f0s13dc-firmware/lib/firmware
+-r-xr-xr-x 1 root root 5568 Dec 31 1969 init
+-r--r--r-- 1 root root 9 Dec 31 1969 init-interface-version
+lrwxrwxrwx 1 root root 57 Dec 31 1969 initrd -> /nix/store/n7x32hhg41mflx9xvmmw61piwjdr81m1-initrd/initrd
+lrwxrwxrwx 1 root root 65 Dec 31 1969 kernel -> /nix/store/sgkk7pqh7jqvy6rvgnkk367amrpknw91-linux-4.19.59/bzImage
+lrwxrwxrwx 1 root root 58 Dec 31 1969 kernel-modules -> /nix/store/nrmlrwxyqmp4dbcldrlvibv0h61356bf-kernel-modules
+-r--r--r-- 1 root root 10 Dec 31 1969 kernel-params
+-r--r--r-- 1 root root 24 Dec 31 1969 nixos-version
+lrwxrwxrwx 1 root root 55 Dec 31 1969 sw -> /nix/store/11pfbzzamqvnbfxis4pbnzhrvarn3pj1-system-path
+-r--r--r-- 1 root root 12 Dec 31 1969 system
+lrwxrwxrwx 1 root root 64 Dec 31 1969 systemd -> /nix/store/9zkhhvix7rlqlj8pf8s2kbw8b88rky75-systemd-239.20190219
+#+end_example
+
+The various files and directories in this derivation are what is necessary for
+the current generation of the system. Similar to user environments, upgrades
+and rollbacks are atomic. Installing a package into the system packages, for
+example, will happen in isolation. Only after the build process is complete
+and successful does the forest of links get changed.
+
+However, because there is some necessary artifacts of state when running a
+system, this isolation is certainly not perfect. Particularly so with the
+interaction of services and their underlying configuration.
+
+** Alternatives
+
+Aside from [[nixos][NixOS]], there is also [[guix][Guix]], a [[gnu][GNU]]
+alternative to [[nix][Nix]] and [[nixos][NixOS]]. Many of the ideas of
+[[guix][Guix]] are derived from [[nix][Nix]]. In fact, early on in the life of
+the [[guix][Guix]] project, [[guix][Guix]] interacted with the [[nix][Nix]]
+daemon directly. This is no longer the case as [[guix][Guix]] has its own
+daemon now, however, the design is very similar.
+
+The configuration language of [[guix][Guix]] is, in proper [[gnu][GNU]] style,
+[[guile-scheme][Guile Scheme]] instead of a [[wiki-dsl][DSL]]--
+[[nix-expressions][nix]].
+
+[[guix][Guix]], as a [[gnu][GNU]] project, also takes a hard-line stance on
+software freedom and therefore does not and will not include any non-free code
+in the package repositories. Furthermore, this also means that [[guix][Guix]]
+the package manager will not be supported on other operating systems such as
+Apple MacOS and Microsoft Windows.
+
+Another alternative is using any number of
+[[configuraiton-management-wiki][Configuration Management]] solutions on a
+typical [[gnu][GNU]]/[[linux][Linux]] distribution. However, solutions such as
+[[ansible][Ansible]], [[puppet][Puppet]], and [[salt-stack][Salt]] fail in a
+very similar way that tradition distrubtions fail: they are dependent on
+ordering and distrubtion managers and software maintainers to create
+appropriate software dependency graphs. Failure in dependency management
+yields failures in the system. Furthermore, once a package is no longer
+available in the official repositories, it is no longer trivially available to
+be installed via the software configuraiton tools.
+
+** Impressions and Thoughts
+
+[[nix][Nix]] and by extension [[nixos][NixOS]] (hopefully) solve some really
+annoying problems I tend to keep running into when developing software and
+immutable, reproducible infrastructure. I'm really excited about the
+possibilities [[nix][Nix]] can bring. However, until I can really sit down and
+_use_ [[nix][Nix]] for development, I can't say anything with certainty.
+
+In time, I will provide more detail on my impressions and review [[nix][Nix]]
+and [[nixos][NixOS]] in more depth. However, if nothing else, being able to
+codify systems and environments in a reproducible manner is already a huge win.
+
+I highly recommend reading [[nixos-paper][NixOS: A Purely Functional Linux
+Distribution]] and [[nix-paper][Nix: A Safe and Policy-Free System for Software
+Development]] by Dolstra /et al./. Both papers are very good explanations and
+breakdowns of the motivation and ideas behind [[nix][Nix]] and
+[[nixos][NixOS]].