This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / .github / lazy-store.sh
3.9 kB 91 lines
1#!/usr/bin/env bash 2# Mounts a lazy /nix/store for building INSTALLABLE... (the machine jobs of 3# ci.yml): every store path the build would substitute from cache.nixos.org 4# or cache.lassul.us is registered as valid from its narinfo and served by 5# lazy-store (tools/lazy-store), which downloads a path's NAR only when a 6# file in it is opened first. What nix builds, and what neither cache has, 7# is built or substituted (also from hestia) as usual; writes go to the 8# real store dir below the mount. 9# 10# Needs sudo, /dev/fuse and LAZY_STORE, the lazy-store package's out path 11# (substitutable). If anything fails before the paths are registered, the 12# mount is undone and the build substitutes eagerly: this script always 13# exits 0. The FUSE log ends up in $RUNNER_TEMP/lazy-store/fuse.log. 14# Usage: lazy-store.sh INSTALLABLE... 15set -euo pipefail 16L=$RUNNER_TEMP/lazy-store 17mkdir -p "$L" 18 19fallback() { 20 set +e 21 echo "::error::lazy store: $1; the build substitutes eagerly instead" 22 if [ -s "$L/fuse.log" ]; then 23 tail -n 50 "$L/fuse.log" 24 fi 25 if mountpoint -q /nix/store; then 26 sudo umount /nix/store || sudo umount -l /nix/store 27 fi 28 if mountpoint -q /lazy/nix; then 29 sudo umount -l /lazy/nix 30 fi 31 exit 0 32} 33trap 'fallback "line $LINENO failed"' ERR 34 35nix-store --realise "$LAZY_STORE" >/dev/null || fallback "cannot get $LAZY_STORE" 36lazy=$LAZY_STORE/bin/lazy-store 37nixbin=$(dirname "$(readlink -f "$(command -v nix-store)")") 38 39nix build --dry-run "$@" 2>"$L/plan" || fallback "nix build --dry-run failed: $(cat "$L/plan")" 40# the path lines below the "will be fetched" header, up to the next header 41awk '/^[^ ]/ { f = /will be fetched/; next } f && $1 ~ /^\/nix\/store\// { print $1 }' \ 42 "$L/plan" >"$L/fetch" 43if [ ! -s "$L/fetch" ]; then 44 echo "lazy store: nothing to substitute" 45 exit 0 46fi 47 48"$lazy" closure "$L" <"$L/fetch" >/dev/null || fallback "closure failed" 49jq -r '"lazy store: \(.paths) of the \(.roots) paths to substitute and their closure (\(.file_size / 1048576 | floor) MiB to download eagerly); \(.missing | length) not in the caches, \(.incomplete) referring to those"' \ 50 "$L/closure.json" 51n=$(jq length "$L/paths.json") 52if [ "$n" = 0 ]; then 53 exit 0 54fi 55 56sudo modprobe fuse || true 57# The upper layer is the real store dir, reached through a private bind 58# mount of /nix, so that the mount on /nix/store doesn't show up there. 59sudo mkdir -p /lazy/nix 60sudo mount --bind /nix /lazy/nix || fallback "bind mount of /nix failed" 61sudo mount --make-private /lazy/nix || fallback "making /lazy/nix private failed" 62# shellcheck disable=SC2024 # the log is ours, only the mount needs root 63sudo "$lazy" mount "$L" /lazy/nix/store /nix/store >"$L/fuse.log" 2>&1 & 64fuse=$! 65# sudo runs as root (no kill -0) and stays a zombie until waited for 66fuse_alive() { 67 local s 68 s=$(ps -o stat= -p "$fuse") && [[ $s != Z* ]] 69} 70# it fetches all .ls listings before mounting 71until mountpoint -q /nix/store; do 72 fuse_alive || fallback "lazy-store exited before mounting /nix/store" 73 sleep 1 74done 75grep -m1 '^init: ' "$L/fuse.log" || true 76 77some=$(jq -r 'keys[0]' "$L/paths.json") 78[ -e "/nix/store/$some" ] || fallback "/nix/store/$some is not served" 79# shellcheck disable=SC2024 # db.dump is ours, only nix-store needs root 80sudo "$nixbin/nix-store" --load-db <"$L/db.dump" || fallback "registering the paths failed" 81# registered: the mount has to stay 82trap - ERR 83set +e 84echo "lazy store: mounted on /nix/store, $n paths registered" 85# niks3 and hestia leave out what cache.nixos.org signed by the signatures 86# in nix's database; without them they would upload (and so download) 87# those paths 88jq -r 'keys[] | "/nix/store/" + .' "$L/paths.json" | 89 sudo "$nixbin/nix" --extra-experimental-features nix-command \ 90 store copy-sigs -s "file://$L/narinfo" --stdin || 91 echo "::warning::lazy store: copying the signatures failed, uploads may download paths of cache.nixos.org"