daemon: Use deterministic $TMPDIR in chroot.
Rather than using $<host-TMPDIR>/nix-build-<drvname>-<number>, the temporary directory is now always /tmp/nix-build-<drvname>-0. This improves bitwise-exact reproducibility for builds that store $TMPDIR in their build output. (Of course, those should still be fixed...) * nix/libstore/build.cc (DerivationGoal)[tmpDirInSandbox]: New field. (DerivationGoal::startBuilder): Initialize 'useChroot' earlier. Compute 'tmpDirInSandbox', and use it when populating 'dirsInChroot'. * doc/guix.texi (Build Environment Setup): Document it. Co-authored-by: Ludovic Courtès <ludo@gnu.org>master
parent
a8d65643fb
commit
cb9601029e
|
@ -600,6 +600,14 @@ user @file{nobody};
|
||||||
a writable @file{/tmp} directory.
|
a writable @file{/tmp} directory.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
You can influence the directory where the daemon stores build trees
|
||||||
|
@i{via} the @code{TMPDIR} environment variable. However, the build tree
|
||||||
|
within the chroot is always @file{/tmp/nix-build-@var{name}.drv-0},
|
||||||
|
where @var{name} is the derivation name---e.g., @code{coreutils-8.24}.
|
||||||
|
This way, the value of @code{TMPDIR} does not leak inside build
|
||||||
|
environments, which avoids discrepancies in cases where build processes
|
||||||
|
capture the name of their build tree.
|
||||||
|
|
||||||
If you are installing Guix as an unprivileged user, it is still possible
|
If you are installing Guix as an unprivileged user, it is still possible
|
||||||
to run @command{guix-daemon} provided you pass @code{--disable-chroot}.
|
to run @command{guix-daemon} provided you pass @code{--disable-chroot}.
|
||||||
However, build processes will not be isolated from one another, and not
|
However, build processes will not be isolated from one another, and not
|
||||||
|
|
|
@ -736,6 +736,9 @@ private:
|
||||||
/* The temporary directory. */
|
/* The temporary directory. */
|
||||||
Path tmpDir;
|
Path tmpDir;
|
||||||
|
|
||||||
|
/* The path of the temporary directory in the sandbox. */
|
||||||
|
Path tmpDirInSandbox;
|
||||||
|
|
||||||
/* File descriptor for the log file. */
|
/* File descriptor for the log file. */
|
||||||
FILE * fLogFile;
|
FILE * fLogFile;
|
||||||
BZFILE * bzLogFile;
|
BZFILE * bzLogFile;
|
||||||
|
@ -1662,6 +1665,8 @@ void DerivationGoal::startBuilder()
|
||||||
% drv.platform % settings.thisSystem % drvPath);
|
% drv.platform % settings.thisSystem % drvPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useChroot = settings.useChroot;
|
||||||
|
|
||||||
/* Construct the environment passed to the builder. */
|
/* Construct the environment passed to the builder. */
|
||||||
env.clear();
|
env.clear();
|
||||||
|
|
||||||
|
@ -1694,20 +1699,25 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
/* Create a temporary directory where the build will take
|
/* Create a temporary directory where the build will take
|
||||||
place. */
|
place. */
|
||||||
tmpDir = createTempDir("", "nix-build-" + storePathToName(drvPath), false, false, 0700);
|
auto drvName = storePathToName(drvPath);
|
||||||
|
tmpDir = createTempDir("", "nix-build-" + drvName, false, false, 0700);
|
||||||
|
|
||||||
|
/* In a sandbox, for determinism, always use the same temporary
|
||||||
|
directory. */
|
||||||
|
tmpDirInSandbox = useChroot ? "/tmp/nix-build-" + drvName + "-0" : tmpDir;
|
||||||
|
|
||||||
/* For convenience, set an environment pointing to the top build
|
/* For convenience, set an environment pointing to the top build
|
||||||
directory. */
|
directory. */
|
||||||
env["NIX_BUILD_TOP"] = tmpDir;
|
env["NIX_BUILD_TOP"] = tmpDirInSandbox;
|
||||||
|
|
||||||
/* Also set TMPDIR and variants to point to this directory. */
|
/* Also set TMPDIR and variants to point to this directory. */
|
||||||
env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDir;
|
env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDirInSandbox;
|
||||||
|
|
||||||
/* Explicitly set PWD to prevent problems with chroot builds. In
|
/* Explicitly set PWD to prevent problems with chroot builds. In
|
||||||
particular, dietlibc cannot figure out the cwd because the
|
particular, dietlibc cannot figure out the cwd because the
|
||||||
inode of the current directory doesn't appear in .. (because
|
inode of the current directory doesn't appear in .. (because
|
||||||
getdents returns the inode of the mount point). */
|
getdents returns the inode of the mount point). */
|
||||||
env["PWD"] = tmpDir;
|
env["PWD"] = tmpDirInSandbox;
|
||||||
|
|
||||||
/* Compatibility hack with Nix <= 0.7: if this is a fixed-output
|
/* Compatibility hack with Nix <= 0.7: if this is a fixed-output
|
||||||
derivation, tell the builder, so that for instance `fetchurl'
|
derivation, tell the builder, so that for instance `fetchurl'
|
||||||
|
@ -1792,8 +1802,6 @@ void DerivationGoal::startBuilder()
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % tmpDir);
|
throw SysError(format("cannot change ownership of '%1%'") % tmpDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
useChroot = settings.useChroot;
|
|
||||||
|
|
||||||
if (useChroot) {
|
if (useChroot) {
|
||||||
#if CHROOT_ENABLED
|
#if CHROOT_ENABLED
|
||||||
/* Create a temporary directory in which we set up the chroot
|
/* Create a temporary directory in which we set up the chroot
|
||||||
|
@ -1855,7 +1863,7 @@ void DerivationGoal::startBuilder()
|
||||||
else
|
else
|
||||||
dirsInChroot[string(i, 0, p)] = string(i, p + 1);
|
dirsInChroot[string(i, 0, p)] = string(i, p + 1);
|
||||||
}
|
}
|
||||||
dirsInChroot[tmpDir] = tmpDir;
|
dirsInChroot[tmpDirInSandbox] = tmpDir;
|
||||||
|
|
||||||
/* Make the closure of the inputs available in the chroot,
|
/* Make the closure of the inputs available in the chroot,
|
||||||
rather than the whole Nix store. This prevents any access
|
rather than the whole Nix store. This prevents any access
|
||||||
|
@ -2173,7 +2181,7 @@ void DerivationGoal::runChild()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chdir(tmpDir.c_str()) == -1)
|
if (chdir(tmpDirInSandbox.c_str()) == -1)
|
||||||
throw SysError(format("changing into `%1%'") % tmpDir);
|
throw SysError(format("changing into `%1%'") % tmpDir);
|
||||||
|
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
|
|
Reference in New Issue