diff options
-rw-r--r-- | Makefile.config.in | 5 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | flake.nix | 17 | ||||
-rw-r--r-- | mk/libraries.mk | 2 | ||||
-rw-r--r-- | src/libexpr/eval-cache.cc | 2 | ||||
-rw-r--r-- | src/libstore/build/hook-instance.cc | 25 | ||||
-rw-r--r-- | src/libstore/build/local-derivation-goal.cc | 14 | ||||
-rw-r--r-- | src/libstore/build/substitution-goal.cc | 2 | ||||
-rw-r--r-- | src/libstore/globals.cc | 6 | ||||
-rw-r--r-- | src/libstore/globals.hh | 5 | ||||
-rw-r--r-- | src/libstore/local.mk | 11 | ||||
-rw-r--r-- | src/libstore/nar-info.cc | 5 | ||||
-rw-r--r-- | src/libstore/nar-info.hh | 1 | ||||
-rw-r--r-- | src/libutil/util.cc | 24 | ||||
-rw-r--r-- | src/libutil/util.hh | 6 | ||||
-rw-r--r-- | src/nix/main.cc | 5 | ||||
-rw-r--r-- | src/nix/run.cc | 2 | ||||
-rw-r--r-- | src/nix/search.cc | 4 | ||||
-rw-r--r-- | tests/ca/content-addressed.nix | 2 | ||||
-rw-r--r-- | tests/common.sh.in | 2 | ||||
-rw-r--r-- | tests/fmt.sh | 7 | ||||
-rw-r--r-- | tests/local.mk | 6 | ||||
-rw-r--r-- | tests/plugins.sh | 5 | ||||
-rw-r--r-- | tests/search.sh | 1 |
24 files changed, 129 insertions, 38 deletions
diff --git a/Makefile.config.in b/Makefile.config.in index d724853fa..1c5405c6d 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -1,4 +1,3 @@ -HOST_OS = @host_os@ AR = @AR@ BDW_GC_LIBS = @BDW_GC_LIBS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ @@ -13,13 +12,14 @@ ENABLE_S3 = @ENABLE_S3@ GTEST_LIBS = @GTEST_LIBS@ HAVE_LIBCPUID = @HAVE_LIBCPUID@ HAVE_SECCOMP = @HAVE_SECCOMP@ +HOST_OS = @host_os@ LDFLAGS = @LDFLAGS@ LIBARCHIVE_LIBS = @LIBARCHIVE_LIBS@ LIBBROTLI_LIBS = @LIBBROTLI_LIBS@ LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@ LOWDOWN_LIBS = @LOWDOWN_LIBS@ OPENSSL_LIBS = @OPENSSL_LIBS@ -LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ SHELL = @bash@ @@ -31,6 +31,7 @@ datadir = @datadir@ datarootdir = @datarootdir@ doc_generate = @doc_generate@ docdir = @docdir@ +embedded_sandbox_shell = @embedded_sandbox_shell@ exec_prefix = @exec_prefix@ includedir = @includedir@ libdir = @libdir@ diff --git a/configure.ac b/configure.ac index 15d5606c9..f0210ab78 100644 --- a/configure.ac +++ b/configure.ac @@ -320,6 +320,14 @@ if test ${cross_compiling:-no} = no && ! test -z ${sandbox_shell+x}; then fi fi +AC_ARG_ENABLE(embedded-sandbox-shell, AS_HELP_STRING([--enable-embedded-sandbox-shell],[include the sandbox shell in the Nix binary [default=no]]), + embedded_sandbox_shell=$enableval, embedded_sandbox_shell=no) +AC_SUBST(embedded_sandbox_shell) +if test "$embedded_sandbox_shell" = yes; then + AC_DEFINE(HAVE_EMBEDDED_SANDBOX_SHELL, 1, [Include the sandbox shell in the Nix binary.]) +fi + + # Expand all variables in config.status. test "$prefix" = NONE && prefix=$ac_default_prefix test "$exec_prefix" = NONE && exec_prefix='${prefix}' @@ -571,14 +571,23 @@ nativeBuildInputs = nativeBuildDeps; buildInputs = buildDeps ++ propagatedDeps; - configureFlags = [ "--sysconfdir=/etc" ]; + # Work around pkgsStatic disabling all tests. + preHook = + '' + doCheck=1 + doInstallCheck=1 + ''; + + configureFlags = + configureFlags ++ + [ "--sysconfdir=/etc" + "--enable-embedded-sandbox-shell" + ]; enableParallelBuilding = true; makeFlags = "profiledir=$(out)/etc/profile.d"; - doCheck = true; - installFlags = "sysconfdir=$(out)/etc"; postInstall = '' @@ -588,7 +597,6 @@ echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products ''; - doInstallCheck = true; installCheckFlags = "sysconfdir=$(out)/etc"; stripAllList = ["bin"]; @@ -597,6 +605,7 @@ hardeningDisable = [ "pie" ]; }; + dockerImage = let pkgs = nixpkgsFor.${system}; diff --git a/mk/libraries.mk b/mk/libraries.mk index 876148a55..6541775f3 100644 --- a/mk/libraries.mk +++ b/mk/libraries.mk @@ -125,7 +125,7 @@ define build-library $(1)_PATH := $$(_d)/$$($(1)_NAME).a $$($(1)_PATH): $$($(1)_OBJS) | $$(_d)/ - +$$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$? + +$$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$^ $$(trace-ar) $(AR) crs $$@ $$(_d)/$$($(1)_NAME).o $(1)_LDFLAGS_USE += $$($(1)_PATH) $$($(1)_LDFLAGS) diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index d77b25898..dbfd8e70b 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -282,7 +282,7 @@ struct AttrDb auto queryAttribute(state->queryAttribute.use()(key.first)(symbols[key.second])); if (!queryAttribute.next()) return {}; - auto rowId = (AttrType) queryAttribute.getInt(0); + auto rowId = (AttrId) queryAttribute.getInt(0); auto type = (AttrType) queryAttribute.getInt(1); switch (type) { diff --git a/src/libstore/build/hook-instance.cc b/src/libstore/build/hook-instance.cc index 0f6f580be..1f19ddccc 100644 --- a/src/libstore/build/hook-instance.cc +++ b/src/libstore/build/hook-instance.cc @@ -7,6 +7,22 @@ HookInstance::HookInstance() { debug("starting build hook '%s'", settings.buildHook); + auto buildHookArgs = tokenizeString<std::list<std::string>>(settings.buildHook.get()); + + if (buildHookArgs.empty()) + throw Error("'build-hook' setting is empty"); + + auto buildHook = buildHookArgs.front(); + buildHookArgs.pop_front(); + + Strings args; + + for (auto & arg : buildHookArgs) + args.push_back(arg); + + args.push_back(std::string(baseNameOf(settings.buildHook.get()))); + args.push_back(std::to_string(verbosity)); + /* Create a pipe to get the output of the child. */ fromHook.create(); @@ -36,14 +52,9 @@ HookInstance::HookInstance() if (dup2(builderOut.readSide.get(), 5) == -1) throw SysError("dupping builder's stdout/stderr"); - Strings args = { - std::string(baseNameOf(settings.buildHook.get())), - std::to_string(verbosity), - }; - - execv(settings.buildHook.get().c_str(), stringsToCharPtrs(args).data()); + execv(buildHook.c_str(), stringsToCharPtrs(args).data()); - throw SysError("executing '%s'", settings.buildHook); + throw SysError("executing '%s'", buildHook); }); pid.setSeparatePG(true); diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 3ac9c20f9..d1ec91ed5 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -1717,7 +1717,19 @@ void LocalDerivationGoal::runChild() for (auto & i : dirsInChroot) { if (i.second.source == "/proc") continue; // backwards compatibility - doBind(i.second.source, chrootRootDir + i.first, i.second.optional); + + #if HAVE_EMBEDDED_SANDBOX_SHELL + if (i.second.source == "__embedded_sandbox_shell__") { + static unsigned char sh[] = { + #include "embedded-sandbox-shell.gen.hh" + }; + auto dst = chrootRootDir + i.first; + createDirs(dirOf(dst)); + writeFile(dst, std::string_view((const char *) sh, sizeof(sh))); + chmod_(dst, 0555); + } else + #endif + doBind(i.second.source, chrootRootDir + i.first, i.second.optional); } /* Bind a new instance of procfs on /proc. */ diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc index ca5218627..2af105b4d 100644 --- a/src/libstore/build/substitution-goal.cc +++ b/src/libstore/build/substitution-goal.cc @@ -154,7 +154,7 @@ void PathSubstitutionGoal::tryNext() only after we've downloaded the path. */ if (!sub->isTrusted && worker.store.pathInfoIsUntrusted(*info)) { - warn("the substitute for '%s' from '%s' is not signed by any of the keys in 'trusted-public-keys'", + warn("ignoring substitute for '%s' from '%s', as it's not signed by any of the keys in 'trusted-public-keys'", worker.store.printStorePath(storePath), sub->getUri()); tryNext(); return; diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index cc009a026..0f2ca4b15 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -36,7 +36,6 @@ Settings::Settings() , nixStateDir(canonPath(getEnv("NIX_STATE_DIR").value_or(NIX_STATE_DIR))) , nixConfDir(canonPath(getEnv("NIX_CONF_DIR").value_or(NIX_CONF_DIR))) , nixUserConfFiles(getUserConfigFiles()) - , nixLibexecDir(canonPath(getEnv("NIX_LIBEXEC_DIR").value_or(NIX_LIBEXEC_DIR))) , nixBinDir(canonPath(getEnv("NIX_BIN_DIR").value_or(NIX_BIN_DIR))) , nixManDir(canonPath(NIX_MAN_DIR)) , nixDaemonSocketFile(canonPath(getEnv("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH))) @@ -67,12 +66,13 @@ Settings::Settings() sandboxPaths = tokenizeString<StringSet>("/bin/sh=" SANDBOX_SHELL); #endif - -/* chroot-like behavior from Apple's sandbox */ + /* chroot-like behavior from Apple's sandbox */ #if __APPLE__ sandboxPaths = tokenizeString<StringSet>("/System/Library/Frameworks /System/Library/PrivateFrameworks /bin/sh /bin/bash /private/tmp /private/var/tmp /usr/lib"); allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh"); #endif + + buildHook = getSelfExe().value_or("nix") + " __build-remote"; } void loadConfFile() diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 0ee27ecb6..d7f351166 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -79,9 +79,6 @@ public: /* A list of user configuration files to load. */ std::vector<Path> nixUserConfFiles; - /* The directory where internal helper programs are stored. */ - Path nixLibexecDir; - /* The directory where the main programs are stored. */ Path nixBinDir; @@ -195,7 +192,7 @@ public: )", {"build-timeout"}}; - PathSetting buildHook{this, true, nixLibexecDir + "/nix/build-remote", "build-hook", + PathSetting buildHook{this, true, "", "build-hook", "The path of the helper program that executes builds to remote machines."}; Setting<std::string> builders{ diff --git a/src/libstore/local.mk b/src/libstore/local.mk index b992bcbc0..1d26ac918 100644 --- a/src/libstore/local.mk +++ b/src/libstore/local.mk @@ -39,14 +39,23 @@ libstore_CXXFLAGS += \ -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ - -DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \ -DNIX_BIN_DIR=\"$(bindir)\" \ -DNIX_MAN_DIR=\"$(mandir)\" \ -DLSOF=\"$(lsof)\" +ifeq ($(embedded_sandbox_shell),yes) +libstore_CXXFLAGS += -DSANDBOX_SHELL=\"__embedded_sandbox_shell__\" + +$(d)/build/local-derivation-goal.cc: $(d)/embedded-sandbox-shell.gen.hh + +$(d)/embedded-sandbox-shell.gen.hh: $(sandbox_shell) + $(trace-gen) hexdump -v -e '1/1 "0x%x," "\n"' < $< > $@.tmp + @mv $@.tmp $@ +else ifneq ($(sandbox_shell),) libstore_CXXFLAGS += -DSANDBOX_SHELL="\"$(sandbox_shell)\"" endif +endif $(d)/local-store.cc: $(d)/schema.sql.gen.hh $(d)/ca-specific-schema.sql.gen.hh diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 2d75e7a82..071d8355e 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -69,8 +69,6 @@ NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & if (value != "unknown-deriver") deriver = StorePath(value); } - else if (name == "System") - system = value; else if (name == "Sig") sigs.insert(value); else if (name == "CA") { @@ -106,9 +104,6 @@ std::string NarInfo::to_string(const Store & store) const if (deriver) res += "Deriver: " + std::string(deriver->to_string()) + "\n"; - if (!system.empty()) - res += "System: " + system + "\n"; - for (auto sig : sigs) res += "Sig: " + sig + "\n"; diff --git a/src/libstore/nar-info.hh b/src/libstore/nar-info.hh index 39ced76e5..01683ec73 100644 --- a/src/libstore/nar-info.hh +++ b/src/libstore/nar-info.hh @@ -14,7 +14,6 @@ struct NarInfo : ValidPathInfo std::string compression; std::optional<Hash> fileHash; uint64_t fileSize = 0; - std::string system; NarInfo() = delete; NarInfo(StorePath && path, Hash narHash) : ValidPathInfo(std::move(path), narHash) { } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index a368ac844..28df30fef 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -29,6 +29,7 @@ #ifdef __APPLE__ #include <sys/syscall.h> +#include <mach-o/dyld.h> #endif #ifdef __linux__ @@ -580,7 +581,7 @@ Path getHome() int result = stat(homeDir->c_str(), &st); if (result != 0) { if (errno != ENOENT) { - warn("Couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno); + warn("couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno); homeDir.reset(); } } else if (st.st_uid != geteuid()) { @@ -633,6 +634,27 @@ Path getDataDir() } +std::optional<Path> getSelfExe() +{ + static auto cached = []() -> std::optional<Path> + { + #if __linux__ + return readLink("/proc/self/exe"); + #elif __APPLE__ + char buf[1024]; + uint32_t size = sizeof(buf); + if (_NSGetExecutablePath(buf, &size) == 0) + return buf; + else + return std::nullopt; + #else + return std::nullopt; + #endif + }(); + return cached; +} + + Paths createDirs(const Path & path) { Paths created; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 90418b04d..d3ed15b0b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -149,10 +149,14 @@ std::vector<Path> getConfigDirs(); /* Return $XDG_DATA_HOME or $HOME/.local/share. */ Path getDataDir(); +/* Return the path of the current executable. */ +std::optional<Path> getSelfExe(); + /* Create a directory and all its parents, if necessary. Returns the list of created directories, in order of creation. */ Paths createDirs(const Path & path); -inline Paths createDirs(PathView path) { +inline Paths createDirs(PathView path) +{ return createDirs(Path(path)); } diff --git a/src/nix/main.cc b/src/nix/main.cc index f398e3118..17c92ebc6 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -266,6 +266,11 @@ void mainWrapped(int argc, char * * argv) programPath = argv[0]; auto programName = std::string(baseNameOf(programPath)); + if (argc > 0 && std::string_view(argv[0]) == "__build-remote") { + programName = "build-remote"; + argv++; argc--; + } + { auto legacy = (*RegisterLegacyCommand::commands)[programName]; if (legacy) return legacy(argc, argv); diff --git a/src/nix/run.cc b/src/nix/run.cc index 25a8fa8d3..45d2dfd0d 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -47,7 +47,7 @@ void runProgramInStore(ref<Store> store, Strings helperArgs = { chrootHelperName, store->storeDir, store2->getRealStoreDir(), program }; for (auto & arg : args) helperArgs.push_back(arg); - execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data()); + execv(getSelfExe().value_or("nix").c_str(), stringsToCharPtrs(helperArgs).data()); throw SysError("could not execute chroot helper"); } diff --git a/src/nix/search.cc b/src/nix/search.cc index f1f5f9641..bdd45cbed 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -34,7 +34,9 @@ struct CmdSearch : InstallableCommand, MixJSON .shortName = 'e', .description = "Hide packages whose attribute path, name or description contain *regex*.", .labels = {"regex"}, - .handler = Handler(&excludeRes), + .handler = {[this](std::string s) { + excludeRes.push_back(s); + }}, }); } diff --git a/tests/ca/content-addressed.nix b/tests/ca/content-addressed.nix index 31c144ae0..81bc4bf5c 100644 --- a/tests/ca/content-addressed.nix +++ b/tests/ca/content-addressed.nix @@ -75,7 +75,7 @@ rec { buildCommand = '' mkdir -p $out/bin echo ${rootCA} # Just to make it depend on it - echo "" > $out/bin/${name} + echo "#! ${shell}" > $out/bin/${name} chmod +x $out/bin/${name} ''; }; diff --git a/tests/common.sh.in b/tests/common.sh.in index 6cb579e0d..5efd025ee 100644 --- a/tests/common.sh.in +++ b/tests/common.sh.in @@ -50,6 +50,8 @@ export busybox="@sandbox_shell@" export version=@PACKAGE_VERSION@ export system=@system@ +export BUILD_SHARED_LIBS=@BUILD_SHARED_LIBS@ + export IMPURE_VAR1=foo export IMPURE_VAR2=bar diff --git a/tests/fmt.sh b/tests/fmt.sh index bc05118ff..254681ca2 100644 --- a/tests/fmt.sh +++ b/tests/fmt.sh @@ -18,7 +18,12 @@ cat << EOF > flake.nix with import ./config.nix; mkDerivation { name = "formatter"; - buildCommand = "mkdir -p \$out/bin; cp \${./fmt.simple.sh} \$out/bin/formatter"; + buildCommand = '' + mkdir -p \$out/bin + echo "#! ${shell}" > \$out/bin/formatter + cat \${./fmt.simple.sh} >> \$out/bin/formatter + chmod +x \$out/bin/formatter + ''; }; }; } diff --git a/tests/local.mk b/tests/local.mk index 2932d2b13..ae15c70f9 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -114,4 +114,8 @@ tests-environment = NIX_REMOTE= $(bash) -e clean-files += $(d)/common.sh $(d)/config.nix $(d)/ca/config.nix -test-deps += tests/common.sh tests/config.nix tests/ca/config.nix tests/plugins/libplugintest.$(SO_EXT) +test-deps += tests/common.sh tests/config.nix tests/ca/config.nix + +ifeq ($(BUILD_SHARED_LIBS), 1) + test-deps += tests/plugins/libplugintest.$(SO_EXT) +endif diff --git a/tests/plugins.sh b/tests/plugins.sh index e22bf4408..6e278ad9d 100644 --- a/tests/plugins.sh +++ b/tests/plugins.sh @@ -2,6 +2,11 @@ source common.sh set -o pipefail +if [[ $BUILD_SHARED_LIBS != 1 ]]; then + echo "plugins are not supported" + exit 99 +fi + res=$(nix --option setting-set true --option plugin-files $PWD/plugins/libplugintest* eval --expr builtins.anotherNull) [ "$res"x = "nullx" ] diff --git a/tests/search.sh b/tests/search.sh index 41b706ac6..1a98f5b49 100644 --- a/tests/search.sh +++ b/tests/search.sh @@ -43,3 +43,4 @@ e=$'\x1b' # grep doesn't support \e, \033 or even \x1b (( $(nix search -f search.nix foo --exclude 'foo|bar' | grep -Ec 'foo|bar') == 0 )) (( $(nix search -f search.nix foo -e foo --exclude bar | grep -Ec 'foo|bar') == 0 )) +[[ $(nix search -f search.nix -e bar --json | jq -c 'keys') == '["foo","hello"]' ]] |