Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8480508

Browse files
committed
fix(flake.nix): limit the amount of maximum layers to 32 on dogfood nix image
Change-Id: I7d34f5d50509bfa1b5e8f6ed9e150462151fbbe0 Signed-off-by: Thomas Kosiewski <[email protected]>
1 parent 2808816 commit 8480508

File tree

2 files changed

+259
-2
lines changed

2 files changed

+259
-2
lines changed

flake.nix

+13-2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@
136136
zstd
137137
];
138138

139+
docker = pkgs.callPackage ./nix/docker.nix { };
140+
139141
# buildSite packages the site directory.
140142
buildSite = pnpm2nix.packages.${system}.mkPnpmPackage {
141143
inherit nodejs pnpm;
@@ -237,12 +239,21 @@
237239
aarch64-windows = buildFat "windows_arm64.exe";
238240
}
239241
// (pkgs.lib.optionalAttrs pkgs.stdenv.isLinux {
240-
dev_image = pkgs.dockerTools.buildNixShellImage {
242+
dev_image = docker.buildNixShellImage {
241243
name = "codercom/oss-dogfood-nix";
242244
tag = "latest-${system}";
243245

246+
maxLayers = 32;
247+
244248
drv = devShells.default.overrideAttrs (oldAttrs: {
245-
buildInputs = oldAttrs.buildInputs ++ [ pkgs.nix ];
249+
# (ThomasK33): Workaround for images with too many layers (>64 layers) causing sysbox
250+
# to have issues on dogfood envs.
251+
buildInputs =
252+
oldAttrs.buildInputs
253+
++ (with pkgs; [
254+
nix
255+
coreutils
256+
]);
246257
});
247258
};
248259
});

nix/docker.nix

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# (ThomasK33): Inlined the relevant dockerTools functions, so that we can
2+
# set the maxLayers attribute on the attribute set passed
3+
# to the buildNixShellImage function.
4+
#
5+
# I'll create an upstream PR to nixpkgs with those changes, making this
6+
# eventually unnecessary and ripe for removal.
7+
{
8+
lib,
9+
dockerTools,
10+
devShellTools,
11+
bashInteractive,
12+
fakeNss,
13+
runCommand,
14+
writeShellScriptBin,
15+
writeText,
16+
cacert,
17+
storeDir ? builtins.storeDir,
18+
pigz,
19+
zstd,
20+
}:
21+
let
22+
inherit (lib)
23+
optionalString
24+
;
25+
26+
inherit (devShellTools)
27+
valueToString
28+
;
29+
30+
inherit (dockerTools)
31+
streamLayeredImage
32+
binSh
33+
usrBinEnv
34+
;
35+
36+
compressors = {
37+
none = {
38+
ext = "";
39+
nativeInputs = [ ];
40+
compress = "cat";
41+
decompress = "cat";
42+
};
43+
gz = {
44+
ext = ".gz";
45+
nativeInputs = [ pigz ];
46+
compress = "pigz -p$NIX_BUILD_CORES -nTR";
47+
decompress = "pigz -d -p$NIX_BUILD_CORES";
48+
};
49+
zstd = {
50+
ext = ".zst";
51+
nativeInputs = [ zstd ];
52+
compress = "zstd -T$NIX_BUILD_CORES";
53+
decompress = "zstd -d -T$NIX_BUILD_CORES";
54+
};
55+
};
56+
compressorForImage =
57+
compressor: imageName:
58+
compressors.${compressor}
59+
or (throw "in docker image ${imageName}: compressor must be one of: [${toString builtins.attrNames compressors}]");
60+
61+
streamNixShellImage =
62+
{
63+
drv,
64+
name ? drv.name + "-env",
65+
tag ? null,
66+
uid ? 1000,
67+
gid ? 1000,
68+
homeDirectory ? "/build",
69+
shell ? bashInteractive + "/bin/bash",
70+
command ? null,
71+
run ? null,
72+
maxLayers ? 100,
73+
}:
74+
assert lib.assertMsg (!(drv.drvAttrs.__structuredAttrs or false))
75+
"streamNixShellImage: Does not work with the derivation ${drv.name} because it uses __structuredAttrs";
76+
assert lib.assertMsg (
77+
command == null || run == null
78+
) "streamNixShellImage: Can't specify both command and run";
79+
let
80+
81+
# A binary that calls the command to build the derivation
82+
builder = writeShellScriptBin "buildDerivation" ''
83+
exec ${lib.escapeShellArg (valueToString drv.drvAttrs.builder)} ${lib.escapeShellArgs (map valueToString drv.drvAttrs.args)}
84+
'';
85+
86+
staticPath = "${dirOf shell}:${lib.makeBinPath [ builder ]}";
87+
88+
# https://github.com/NixOS/nix/blob/2.8.0/src/nix-build/nix-build.cc#L493-L526
89+
rcfile = writeText "nix-shell-rc" ''
90+
unset PATH
91+
dontAddDisableDepTrack=1
92+
# TODO: https://github.com/NixOS/nix/blob/2.8.0/src/nix-build/nix-build.cc#L506
93+
[ -e $stdenv/setup ] && source $stdenv/setup
94+
PATH=${staticPath}:"$PATH"
95+
SHELL=${lib.escapeShellArg shell}
96+
BASH=${lib.escapeShellArg shell}
97+
set +e
98+
[ -n "$PS1" -a -z "$NIX_SHELL_PRESERVE_PROMPT" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '
99+
if [ "$(type -t runHook)" = function ]; then
100+
runHook shellHook
101+
fi
102+
unset NIX_ENFORCE_PURITY
103+
shopt -u nullglob
104+
shopt -s execfail
105+
${optionalString (command != null || run != null) ''
106+
${optionalString (command != null) command}
107+
${optionalString (run != null) run}
108+
exit
109+
''}
110+
'';
111+
112+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/globals.hh#L464-L465
113+
sandboxBuildDir = "/build";
114+
115+
drvEnv =
116+
devShellTools.unstructuredDerivationInputEnv { inherit (drv) drvAttrs; }
117+
// devShellTools.derivationOutputEnv {
118+
outputList = drv.outputs;
119+
outputMap = drv;
120+
};
121+
122+
# Environment variables set in the image
123+
envVars =
124+
{
125+
126+
# Root certificates for internet access
127+
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
128+
NIX_SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
129+
130+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1027-L1030
131+
# PATH = "/path-not-set";
132+
# Allows calling bash and `buildDerivation` as the Cmd
133+
PATH = staticPath;
134+
135+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1032-L1038
136+
HOME = homeDirectory;
137+
138+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1040-L1044
139+
NIX_STORE = storeDir;
140+
141+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1046-L1047
142+
# TODO: Make configurable?
143+
NIX_BUILD_CORES = "1";
144+
145+
}
146+
// drvEnv
147+
// {
148+
149+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1008-L1010
150+
NIX_BUILD_TOP = sandboxBuildDir;
151+
152+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1012-L1013
153+
TMPDIR = sandboxBuildDir;
154+
TEMPDIR = sandboxBuildDir;
155+
TMP = sandboxBuildDir;
156+
TEMP = sandboxBuildDir;
157+
158+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1015-L1019
159+
PWD = sandboxBuildDir;
160+
161+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1071-L1074
162+
# We don't set it here because the output here isn't handled in any special way
163+
# NIX_LOG_FD = "2";
164+
165+
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L1076-L1077
166+
TERM = "xterm-256color";
167+
};
168+
169+
in
170+
streamLayeredImage {
171+
inherit name tag maxLayers;
172+
contents = [
173+
binSh
174+
usrBinEnv
175+
(fakeNss.override {
176+
# Allows programs to look up the build user's home directory
177+
# https://github.com/NixOS/nix/blob/ffe155abd36366a870482625543f9bf924a58281/src/libstore/build/local-derivation-goal.cc#L906-L910
178+
# Slightly differs however: We use the passed-in homeDirectory instead of sandboxBuildDir.
179+
# We're doing this because it's arguably a bug in Nix that sandboxBuildDir is used here: https://github.com/NixOS/nix/issues/6379
180+
extraPasswdLines = [
181+
"nixbld:x:${toString uid}:${toString gid}:Build user:${homeDirectory}:/noshell"
182+
];
183+
extraGroupLines = [
184+
"nixbld:!:${toString gid}:"
185+
];
186+
})
187+
];
188+
189+
fakeRootCommands = ''
190+
# Effectively a single-user installation of Nix, giving the user full
191+
# control over the Nix store. Needed for building the derivation this
192+
# shell is for, but also in case one wants to use Nix inside the
193+
# image
194+
mkdir -p ./nix/{store,var/nix} ./etc/nix
195+
chown -R ${toString uid}:${toString gid} ./nix ./etc/nix
196+
197+
# Gives the user control over the build directory
198+
mkdir -p .${sandboxBuildDir}
199+
chown -R ${toString uid}:${toString gid} .${sandboxBuildDir}
200+
'';
201+
202+
# Run this image as the given uid/gid
203+
config.User = "${toString uid}:${toString gid}";
204+
config.Cmd =
205+
# https://github.com/NixOS/nix/blob/2.8.0/src/nix-build/nix-build.cc#L185-L186
206+
# https://github.com/NixOS/nix/blob/2.8.0/src/nix-build/nix-build.cc#L534-L536
207+
if run == null then
208+
[
209+
shell
210+
"--rcfile"
211+
rcfile
212+
]
213+
else
214+
[
215+
shell
216+
rcfile
217+
];
218+
config.WorkingDir = sandboxBuildDir;
219+
config.Env = lib.mapAttrsToList (name: value: "${name}=${value}") envVars;
220+
};
221+
in
222+
{
223+
224+
# This function streams a docker image that behaves like a nix-shell for a derivation
225+
# Docs: doc/build-helpers/images/dockertools.section.md
226+
# Tests: nixos/tests/docker-tools-nix-shell.nix
227+
228+
# Wrapper around streamNixShellImage to build an image from the result
229+
# Docs: doc/build-helpers/images/dockertools.section.md
230+
# Tests: nixos/tests/docker-tools-nix-shell.nix
231+
buildNixShellImage =
232+
{
233+
drv,
234+
compressor ? "gz",
235+
...
236+
}@args:
237+
let
238+
stream = streamNixShellImage (builtins.removeAttrs args [ "compressor" ]);
239+
compress = compressorForImage compressor drv.name;
240+
in
241+
runCommand "${drv.name}-env.tar${compress.ext}" {
242+
inherit (stream) imageName;
243+
passthru = { inherit (stream) imageTag; };
244+
nativeBuildInputs = compress.nativeInputs;
245+
} "${stream} | ${compress.compress} > $out";
246+
}

0 commit comments

Comments
 (0)