nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 runtimeShell,
4 srcOnly,
5 stdenvNoCC,
6 writeTextFile,
7 writeShellScript,
8 path,
9 bubblewrap,
10 coreutils,
11 curl,
12 jq,
13 mitm-cache,
14 nix,
15 openssl,
16 procps,
17 python3,
18}:
19
20lib.makeOverridable (
21 {
22 pkg,
23 pname,
24 attrPath,
25 bwrapFlags,
26 data,
27 silent,
28 useBwrap,
29 }:
30 let
31 keep = [
32 "MITM_CACHE_HOST"
33 "MITM_CACHE_PORT"
34 "MITM_CACHE_ADDRESS"
35 "MITM_CACHE_CA"
36 "MITM_CACHE_CERT_DIR"
37 ];
38 gradleScript = writeShellScript "gradle-commands.sh" ''
39 set -eo pipefail
40 export http_proxy="$MITM_CACHE_ADDRESS"
41 export https_proxy="$MITM_CACHE_ADDRESS"
42 export SSL_CERT_FILE="$MITM_CACHE_CA"
43 export NIX_SSL_CERT_FILE="$MITM_CACHE_CA"
44 export GRADLE_USER_HOME="$(${coreutils}/bin/mktemp -d)"
45 export IN_GRADLE_UPDATE_DEPS=1
46 trap "${coreutils}/bin/rm -rf '$GRADLE_USER_HOME'" SIGINT SIGTERM ERR EXIT
47 cd "$(${coreutils}/bin/mktemp -d)"
48 ${coreutils}/bin/mkdir out
49 export out="$PWD/out"
50 trap "${coreutils}/bin/rm -rf '$PWD'" SIGINT SIGTERM ERR EXIT
51 source "$stdenv/setup"
52 phases="''${prePhases[*]:-} unpackPhase patchPhase ''${preConfigurePhases[*]:-} configurePhase gradleUpdateScript" genericBuild
53 '';
54 source = srcOnly (
55 pkg.overrideAttrs (old: {
56 mitmCache = "";
57 gradleInitScript = ./init-deps.gradle;
58
59 stdenv = old.stdenv or stdenvNoCC;
60 })
61 );
62 sourceDrvPath = builtins.unsafeDiscardOutputDependency source.drvPath;
63 nixShellKeep = lib.concatMapStringsSep " " (x: "--keep ${x}") keep;
64 in
65 writeTextFile {
66 name = "fetch-deps.sh";
67 executable = true;
68 # see pkgs/common-updater/combinators.nix
69 derivationArgs.passthru = {
70 supportedFeatures = lib.optional silent "silent";
71 }
72 // lib.optionalAttrs (attrPath != null) { inherit attrPath; };
73 text = ''
74 #!${runtimeShell}
75 set -eo pipefail
76 export PATH="${
77 lib.makeBinPath (
78 [
79 coreutils
80 curl
81 jq
82 mitm-cache
83 openssl
84 procps
85 python3.pkgs.ephemeral-port-reserve
86 ]
87 ++ lib.optional useBwrap bubblewrap
88 )
89 }:$PATH"
90 outPath="${
91 # if this is an absolute path in nix store, use path relative to the store path
92 if lib.hasPrefix "${builtins.storeDir}/" (toString data) then
93 builtins.concatStringsSep "/" (
94 lib.drop 1 (lib.splitString "/" (lib.removePrefix "${builtins.storeDir}/" (toString data)))
95 )
96 # if this is an absolute path anywhere else, just use that path
97 else if lib.hasPrefix "/" (toString data) then
98 toString data
99 # otherwise, use a path relative to the package
100 else
101 "${dirOf pkg.meta.position}/${data}"
102 }"
103
104 pushd "$(mktemp -d)" >/dev/null
105 MITM_CACHE_DIR="$PWD"
106 trap "rm -rf '$MITM_CACHE_DIR'" SIGINT SIGTERM ERR EXIT
107 openssl genrsa -out ca.key 2048
108 openssl req -x509 -new -nodes -key ca.key -sha256 -days 1 -out ca.cer -subj "/C=AL/ST=a/L=a/O=a/OU=a/CN=example.org"
109 export MITM_CACHE_HOST=127.0.0.1
110 export MITM_CACHE_PORT="''${mitmCachePort:-$(ephemeral-port-reserve "$MITM_CACHE_HOST")}"
111 export MITM_CACHE_ADDRESS="$MITM_CACHE_HOST:$MITM_CACHE_PORT"
112 # forget all redirects - this makes the lockfiles predictable
113 # not only does this strip CDN URLs, but it also improves security - since the redirects aren't
114 # stored in the lockfile, a malicious actor can't change the redirect URL stored in the lockfile
115 mitm-cache \
116 -l"$MITM_CACHE_ADDRESS" \
117 record \
118 --reject '\.(md5|sha(1|256|512:?):?)$' \
119 --forget-redirects-from '.*' \
120 --record-text '/maven-metadata\.xml$' >/dev/null 2>/dev/null &
121 MITM_CACHE_PID="$!"
122 # wait for mitm-cache to fully start
123 for i in {0..20}; do
124 kill -0 "$MITM_CACHE_PID" 2>/dev/null || (echo "Failed to start mitm-cache" && exit 1)
125 curl -so/dev/null "$MITM_CACHE_ADDRESS" && break
126 [[ "$i" -eq 20 ]] && (echo "Failed to start mitm-cache" && exit 1)
127 sleep 0.5
128 done
129 trap "kill '$MITM_CACHE_PID'" SIGINT SIGTERM ERR EXIT
130 export MITM_CACHE_CERT_DIR="$PWD"
131 export MITM_CACHE_CA="$MITM_CACHE_CERT_DIR/ca.cer"
132 popd >/dev/null
133 useBwrap="''${USE_BWRAP:-${toString useBwrap}}"
134 if [ -n "$useBwrap" ]; then
135 # bwrap isn't necessary, it's only used to prevent messy build scripts from touching ~
136 bwrap \
137 --unshare-all --share-net --clearenv --chdir / --setenv HOME /homeless-shelter \
138 --tmpfs /home --bind /tmp /tmp --ro-bind /nix /nix --ro-bind /run /run --proc /proc --dev /dev \
139 --ro-bind ${toString path} ${toString path} --bind "$MITM_CACHE_CERT_DIR" "$MITM_CACHE_CERT_DIR" \
140 ${builtins.concatStringsSep " " (map (x: "--setenv ${x} \"\$${x}\"") keep)} \
141 --setenv NIX_BUILD_SHELL ${runtimeShell} ${bwrapFlags} ''${BWRAP_FLAGS:-} \
142 -- ${nix}/bin/nix-shell --pure --run ${gradleScript} ${nixShellKeep} ${sourceDrvPath}
143 else
144 NIX_BUILD_SHELL=${runtimeShell} nix-shell --pure --run ${gradleScript} ${nixShellKeep} ${sourceDrvPath}
145 fi${lib.optionalString silent " >&2"}
146 kill -s SIGINT "$MITM_CACHE_PID"
147 for i in {0..20}; do
148 # check for valid json
149 if jq -e 1 "$MITM_CACHE_DIR/out.json" >/dev/null 2>/dev/null; then
150 exec ${python3.interpreter} ${./compress-deps-json.py} "$MITM_CACHE_DIR/out.json" "$outPath"
151 fi
152 sleep 1
153 done
154 exit 1
155 '';
156 }
157)