-
Notifications
You must be signed in to change notification settings - Fork 141
Expand file tree
/
Copy pathnix.sh
More file actions
executable file
·105 lines (88 loc) · 4.02 KB
/
nix.sh
File metadata and controls
executable file
·105 lines (88 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env bash
# nix.sh - Run Nix commands via Docker without installing Nix locally.
#
# Usage: ./nix.sh <command>
#
# Run './nix.sh flake show' for available apps and packages, or see flake.nix.
# Examples: ./nix.sh run .#test, ./nix.sh build, ./nix.sh develop
#
# The first run downloads dependencies into /nix/store (cached in a Docker
# volume). Subsequent runs reuse the cache. To reset: docker volume rm crossplane-nix
set -e
# When NIX_SH_CONTAINER is set, we're running inside the Docker container.
# This script re-executes itself inside the container to avoid sh -c quoting.
if [ "${NIX_SH_CONTAINER:-}" = "1" ]; then
# Install tools this entrypoint script needs. It needs rsync to copy build
# the build result (cp doesn't work well on MacOS volumes). Installed
# packages persist across runs thanks to the crossplane-nix volume.
command -v rsync &>/dev/null || nix-env -iA nixpkgs.rsync
# The container runs as root, but the bind-mounted /crossplane-runtime is
# owned by the host user. Git refuses to operate in directories owned by
# other users.
git config --global --add safe.directory /crossplane-runtime
# Record the current time. After nix runs, we'll find files newer than this
# marker and chown them to the host user.
marker=$(mktemp)
# If result (i.e. the build output) is a directory, remove it so nix build can
# create its symlink. We only remove directories, not symlinks (which might be
# from a host Nix install).
if [ -d result ] && [ ! -L result ]; then
rm -rf result
fi
nix "${@}"
# Nix build makes result/ a symlink to a directory in the Nix store. That
# directory only exists inside the container, but it creates the symlink in
# /crossplane-runtime, which is shared with the host. We use this rsync trick
# to make result/ a directory of regular files.
if [ -L result ] && readlink result | grep -q '^/nix/store/' && [ -e result ]; then
rsync -rL --chmod=u+w result/ result.tmp
rm result
mv result.tmp result
fi
# Fix ownership of any files nix created or modified. The container runs as
# root, so without this, generated files would be root-owned on the host.
# Using -newer is surgical - we only chown files touched during this run.
find /crossplane-runtime -newer "${marker}" -exec chown "${HOST_UID}:${HOST_GID}" {} + 2>/dev/null || true
rm -f "${marker}"
exit 0
fi
# When running on the host, launch a Docker container and re-execute this
# script inside it.
# Nix configuration, equivalent to /etc/nix/nix.conf.
NIX_CONFIG="
# Flakes are Nix's modern project format - a flake.nix file plus a flake.lock
# that pins all dependencies. This is still marked 'experimental' but is stable
# and widely used.
experimental-features = nix-command flakes
# Build multiple derivations in parallel. A derivation is Nix's build unit,
# like a Makefile target. 'auto' uses one job per CPU core.
max-jobs = auto
# Sandbox builds to prevent access to undeclared dependencies. Requires --privileged.
sandbox = true
# Cachix is a binary cache service. Our GitHub Actions CI pushes there, so if CI
# has recently built the commit you're on Nix will download stuff instead of
# rebuilding it locally.
extra-substituters = https://crossplane.cachix.org
extra-trusted-public-keys = crossplane.cachix.org-1:NJluVUN9TX0rY/zAxHYaT19Y5ik4ELH4uFuxje+62d4=
"
# Only allocate a TTY if stdout is a terminal. TTY mode corrupts binary output
# (e.g., when piping stream-image to docker load). The -i flag keeps stdin open
# for interactive commands like 'nix develop'.
INTERACTIVE_FLAGS=""
if [ -t 1 ]; then
INTERACTIVE_FLAGS="-it"
fi
# Run with --privileged for sandboxed builds.
docker run --rm --privileged --cgroupns=host ${INTERACTIVE_FLAGS} \
-v "$(pwd):/crossplane-runtime" \
-v "crossplane-nix:/nix" \
-w /crossplane-runtime \
-e "NIX_SH_CONTAINER=1" \
-e "NIX_CONFIG=${NIX_CONFIG}" \
-e "GOMODCACHE=/nix/go-mod-cache" \
-e "GOCACHE=/nix/go-build-cache" \
-e "HOST_UID=$(id -u)" \
-e "HOST_GID=$(id -g)" \
-e "TERM=${TERM:-xterm}" \
nixos/nix \
/crossplane-runtime/nix.sh "${@}"