Using NixOS in an isolated environment

I haven’t been on discourse a while and I come back to this status report, thats pretty cool!! :smiley:

I used to work in an air-gapped environment, and being able to easily mirror would have been necessary to adopt nixpkgs. Thanks for exploring this domain :slight_smile: @ejpcmac

3 Likes

@deliciouslytyped, @jonringer You’re welcome :slight_smile: Your comments acted as a reminder to post here the last investigations I’ve done while preparing my over-the-sea upgrade in July.

Building an “enhanced” binary cache

With the idea of getting a more complete binary cache, but still using only upstream cache.nixos.org, I’ve imagined a process I’ve called “cache enhancement”.

First, I’ve split my script in two parts:

  1. nix-mirror-channel, that just fetches files from the channel:

    #!/bin/sh
    
    set -e
    
    if [ $# -ne 3 ]; then
        echo "usage: $0 <channel> <local_path> <local_binary_cache>"
        exit 1
    fi
    
    channel=https://nixos.org/channels/$1
    mirror=$2
    mirror_cache=$3
    
    printf "\n\e[32m=> Create a local channel in $mirror...\e[0m\n\n"
    
    # Build the local channel.
    mkdir -p "$mirror"
    curl -L $channel/git-revision > "$mirror/git-revision"
    curl -L $channel/nixexprs.tar.xz > "$mirror/nixexprs.tar.xz"
    curl -L $channel/store-paths.xz > "$mirror/store-paths.xz"
    printf "file://$mirror_cache" > "$mirror/binary-cache-url"
    
    printf "\n\e[32m\e[1mThe mirror is up to date!\e[0m\n\n"
    
  2. nix-build-cache, that builds a local binary cache given a store-paths.xz and an upstream binary cache:

    #!/bin/sh
    
    set -e
    
    if [ $# -ne 3 ]; then
        echo "usage: $0 <store-paths.xz> <upstream_binary_cache> <local_binary_cache>"
        exit 1
    fi
    
    paths=$1
    upstream=$2
    mirror=$3
    
    printf "\n\e[32m=> Copy the binary cache to $mirror...\e[0m\n\n"
    
    # Build the local binary cache.
    mkdir -p "$mirror"
    xzcat "$paths" | xargs nix copy --store $upstream --to "file://$mirror"
    
    printf "\n\e[32m\e[1mThe mirror is up to date!\e[0m\n\n"
    

This, obviously, gives me the same incomplete binary cache. Now, let’s enhance the store-paths.xz by adding to it paths from my configuration that are also present in cache.nixos.org. I’ve written nix-add-store-paths for this:

#!/bin/sh

if [ $# -ne 4 ]; then
    echo "usage: $0 <store-paths.xz> <paths_to_add> <binary_cache> <updated-store-paths.xz>"
    exit 1
fi

store_paths=$1
paths_to_add=$2
binary_cache=$3
updated_paths=$4
tmp_dir=/tmp/nix-add-store-paths


printf "\n\e[32m=> Querying $binary_cache for new paths...\e[0m\n\n"

mkdir -p "$tmp_dir"
rm $tmp_dir/*
xzcat "$store_paths" > "$tmp_dir/store-paths"

while read path; do
    if [ $(grep $path "$tmp_dir/store-paths" | wc -l) -eq 0 ]; then
        nix path-info $path --store $binary_cache

        if [ $? -eq 0 ]; then
            echo $path >> "$tmp_dir/to_add"
        else
            # TODO: Remove when debugging is done.
            echo $path >> "$tmp_dir/missing"
        fi
    fi
done < "$paths_to_add"

sort "$tmp_dir/store-paths" "$tmp_dir/to_add" | xz > "$updated_paths"

# TODO: Remove when debugging is done.
# rm -r "$tmp_dir"

printf "\n\e[32m\e[1mPaths have been merged!\e[0m\n\n"

I was then able to run a second time nix-build-cache with this enhanced store-paths.xz.

Missing paths

I’ve purposely kept lists of added and missing paths during the “enhancement” process to investigate a bit more. Interestingly, there where far less missing paths (332) than added ones (4668).

Paths present in my store but not in cache.nixos.org

The absence of these paths is generally not a surprise, as they belong to the following categories:

  • local system and user configurations,
  • local packages,
  • proprietary software present in nixpkgs but not cached (like the Nvidia driver and unrar),
  • nmd, needed by home-manager.

Paths present in my store and in cache.nixos.org but not in the channel

These paths are however kind of a surprise: they contain a large part of TeXLive, but also lots of libraries. I think their absence is what currently prevents a completely-offline graphical installation of NixOS.

For reference, here’s a gist containing the full list: Nix paths present in both my config and cache.nixos.org but not in the channel · GitHub. There are two files: the second one is exactly the same as the first one, with TeXLive paths removed for readability.

This is strange these paths are not included in the channel. Maybe this is to help channel updates to be available more quickly, but in this case: what builds these paths on Hydra? Is there a complete path list somewhere so I can provide it to my nix-build-cache script without using the “enhancement” hack?

Next steps

The Marion Dufresne is on its way to Kerguelen and the OP will start here on Friday, bringing with it new people and the postal mail containing my SSD with the new channel and binary cache. I will then be able to try things next week.

For sure, I will not be able to upgrade my laptop with the new cache only, since it lacks the first category of paths. For them, I have an archive built by nix-store --export. However, I will try to setup a new machine from a configuration with a desktop environment and nixpkgs-only dependencies, using only my “enhanced” binary cache. I will then let you know if it works as expected.

8 Likes

The main TV channel here showed a bunch of documentaries about the marion Dufresnes and the Kerguelen islands. It’s a bit of a random comment but you are a lucky one ! Have fun over there (with nixos and the rest) !

2 Likes