diff options
-rw-r--r-- | doc/manual/installation/prerequisites-source.xml | 4 | ||||
-rw-r--r-- | scripts/local.mk | 1 | ||||
-rw-r--r-- | scripts/nix-profile-daemon.sh.in | 54 | ||||
-rw-r--r-- | src/libexpr/primops/fetchgit.cc | 10 | ||||
-rw-r--r-- | src/libstore/binary-cache-store.cc | 72 | ||||
-rw-r--r-- | src/libstore/binary-cache-store.hh | 1 | ||||
-rw-r--r-- | src/libstore/remote-fs-accessor.cc | 34 | ||||
-rw-r--r-- | src/libstore/remote-fs-accessor.hh | 12 | ||||
-rw-r--r-- | src/libstore/store-api.cc | 2 | ||||
-rwxr-xr-x | src/nix-build/nix-build.cc | 2 |
10 files changed, 112 insertions, 80 deletions
diff --git a/doc/manual/installation/prerequisites-source.xml b/doc/manual/installation/prerequisites-source.xml index 7311e4885e74..49660c36e397 100644 --- a/doc/manual/installation/prerequisites-source.xml +++ b/doc/manual/installation/prerequisites-source.xml @@ -10,14 +10,14 @@ <listitem><para>GNU Make.</para></listitem> - <listitem><para>A version of GCC or Clang that supports C++11.</para></listitem> + <listitem><para>A version of GCC or Clang that supports C++14.</para></listitem> <listitem><para><command>pkg-config</command> to locate dependencies. If your distribution does not provide it, you can get it from <link xlink:href="http://www.freedesktop.org/wiki/Software/pkg-config" />.</para></listitem> - + <listitem><para>The OpenSSL library to calculate cryptographic hashes. If your distribution does not provide it, you can get it from <link xlink:href="https://www.openssl.org"/>.</para></listitem> diff --git a/scripts/local.mk b/scripts/local.mk index 9524baf81b03..2a00558521b2 100644 --- a/scripts/local.mk +++ b/scripts/local.mk @@ -8,5 +8,6 @@ noinst-scripts += $(nix_noinst_scripts) profiledir = $(sysconfdir)/profile.d $(eval $(call install-file-as, $(d)/nix-profile.sh, $(profiledir)/nix.sh, 0644)) +$(eval $(call install-file-as, $(d)/nix-profile-daemon.sh, $(profiledir)/nix-daemon.sh, 0644)) clean-files += $(nix_noinst_scripts) diff --git a/scripts/nix-profile-daemon.sh.in b/scripts/nix-profile-daemon.sh.in new file mode 100644 index 000000000000..43c7156062de --- /dev/null +++ b/scripts/nix-profile-daemon.sh.in @@ -0,0 +1,54 @@ +# Only execute this file once per shell. +if [ -n "$__ETC_PROFILE_NIX_SOURCED" ]; then return; fi +__ETC_PROFILE_NIX_SOURCED=1 + +# Set up secure multi-user builds: non-root users build through the +# Nix daemon. +if [ "$USER" != root -o ! -w @localstatedir@/nix/db ]; then + export NIX_REMOTE=daemon +fi + +export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER" +export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile" + +# Set up the per-user profile. +mkdir -m 0755 -p $NIX_USER_PROFILE_DIR +if ! test -O "$NIX_USER_PROFILE_DIR"; then + echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2 +fi + +if test -w $HOME; then + if ! test -L $HOME/.nix-profile; then + if test "$USER" != root; then + ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile + else + # Root installs in the system-wide profile by default. + ln -s @localstatedir@/nix/profiles/default $HOME/.nix-profile + fi + fi + + # Subscribe the root user to the NixOS channel by default. + if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then + echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels + fi + + # Create the per-user garbage collector roots directory. + NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER + mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR + if ! test -O "$NIX_USER_GCROOTS_DIR"; then + echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2 + fi + + # Set up a default Nix expression from which to install stuff. + if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then + rm -f $HOME/.nix-defexpr + mkdir -p $HOME/.nix-defexpr + if [ "$USER" != root ]; then + ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root + fi + fi +fi + +export NIX_SSL_CERT_FILE="@localstatedir@/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" +export NIX_PATH="@localstatedir@/nix/profiles/per-user/root/channels" +export PATH="$HOME/.nix-profile/bin:$HOME/.nix-profile/lib/kde4/libexec:@localstatedir@/nix/profiles/default/bin:@localstatedir@/nix/profiles/default:@localstatedir@/nix/profiles/default/lib/kde4/libexec:$PATH" diff --git a/src/libexpr/primops/fetchgit.cc b/src/libexpr/primops/fetchgit.cc index e16c8235378d..9db4adbc9da2 100644 --- a/src/libexpr/primops/fetchgit.cc +++ b/src/libexpr/primops/fetchgit.cc @@ -13,20 +13,12 @@ namespace nix { Path exportGit(ref<Store> store, const std::string & uri, const std::string & ref, const std::string & rev) { - if (!isUri(uri)) - throw EvalError(format("'%s' is not a valid URI") % uri); - if (rev != "") { std::regex revRegex("^[0-9a-fA-F]{40}$"); if (!std::regex_match(rev, revRegex)) throw Error("invalid Git revision '%s'", rev); } - // FIXME: too restrictive, but better safe than sorry. - std::regex refRegex("^[0-9a-zA-Z][0-9a-zA-Z.-]+$"); - if (!std::regex_match(ref, refRegex)) - throw Error("invalid Git ref '%s'", ref); - Path cacheDir = getCacheDir() + "/nix/git"; if (!pathExists(cacheDir)) { @@ -47,7 +39,7 @@ Path exportGit(ref<Store> store, const std::string & uri, if (stat(localRefFile.c_str(), &st) != 0 || st.st_mtime < now - settings.tarballTtl) { - runProgram("git", true, { "-C", cacheDir, "fetch", "--force", uri, ref + ":" + localRef }); + runProgram("git", true, { "-C", cacheDir, "fetch", "--force", "--", uri, ref + ":" + localRef }); struct timeval times[2]; times[0].tv_sec = now; diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 556fa3d59355..67607ab3d43a 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -17,66 +17,6 @@ namespace nix { -/* Given requests for a path /nix/store/<x>/<y>, this accessor will - first download the NAR for /nix/store/<x> from the binary cache, - build a NAR accessor for that NAR, and use that to access <y>. */ -struct BinaryCacheStoreAccessor : public FSAccessor -{ - ref<BinaryCacheStore> store; - - std::map<Path, ref<FSAccessor>> nars; - - BinaryCacheStoreAccessor(ref<BinaryCacheStore> store) - : store(store) - { - } - - std::pair<ref<FSAccessor>, Path> fetch(const Path & path_) - { - auto path = canonPath(path_); - - auto storePath = store->toStorePath(path); - std::string restPath = std::string(path, storePath.size()); - - if (!store->isValidPath(storePath)) - throw InvalidPath(format("path '%1%' is not a valid store path") % storePath); - - auto i = nars.find(storePath); - if (i != nars.end()) return {i->second, restPath}; - - StringSink sink; - store->narFromPath(storePath, sink); - - auto accessor = makeNarAccessor(sink.s); - nars.emplace(storePath, accessor); - return {accessor, restPath}; - } - - Stat stat(const Path & path) override - { - auto res = fetch(path); - return res.first->stat(res.second); - } - - StringSet readDirectory(const Path & path) override - { - auto res = fetch(path); - return res.first->readDirectory(res.second); - } - - std::string readFile(const Path & path) override - { - auto res = fetch(path); - return res.first->readFile(res.second); - } - - std::string readLink(const Path & path) override - { - auto res = fetch(path); - return res.first->readLink(res.second); - } -}; - BinaryCacheStore::BinaryCacheStore(const Params & params) : Store(params) { @@ -161,7 +101,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str if (info.narHash && info.narHash != narInfo->narHash) throw Error(format("refusing to copy corrupted path '%1%' to binary cache") % info.path); - auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor); + auto accessor_ = std::dynamic_pointer_cast<RemoteFSAccessor>(accessor); /* Optionally write a JSON file containing a listing of the contents of the NAR. */ @@ -174,8 +114,10 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str auto narAccessor = makeNarAccessor(nar); - if (accessor_) + if (accessor_) { accessor_->nars.emplace(info.path, narAccessor); + accessor_->addToCache(info.path, *nar); + } std::function<void(const Path &, JSONPlaceholder &)> recurse; @@ -220,8 +162,10 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str } else { - if (accessor_) + if (accessor_) { accessor_->nars.emplace(info.path, makeNarAccessor(nar)); + accessor_->addToCache(info.path, *nar); + } } /* Compress the NAR. */ @@ -379,7 +323,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s, ref<FSAccessor> BinaryCacheStore::getFSAccessor() { - return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this())); + return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()), localNarCache); } std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const Path & path) diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index f9c1c2cbe8a8..d3b0e0bd9332 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -18,6 +18,7 @@ public: const Setting<std::string> compression{this, "xz", "compression", "NAR compression method ('xz', 'bzip2', or 'none')"}; const Setting<bool> writeNARListing{this, false, "write-nar-listing", "whether to write a JSON file listing the files in each NAR"}; const Setting<Path> secretKeyFile{this, "", "secret-key", "path to secret key used to sign the binary cache"}; + const Setting<Path> localNarCache{this, "", "local-nar-cache", "path to a local cache of NARs"}; private: diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc index 098151f8c0f6..ba9620a175bb 100644 --- a/src/libstore/remote-fs-accessor.cc +++ b/src/libstore/remote-fs-accessor.cc @@ -3,10 +3,29 @@ namespace nix { - -RemoteFSAccessor::RemoteFSAccessor(ref<Store> store) +RemoteFSAccessor::RemoteFSAccessor(ref<Store> store, const Path & cacheDir) : store(store) + , cacheDir(cacheDir) { + if (cacheDir != "") + createDirs(cacheDir); +} + +Path RemoteFSAccessor::makeCacheFile(const Path & storePath) +{ + assert(cacheDir != ""); + return fmt("%s/%s.nar", cacheDir, storePathToHash(storePath)); +} + +void RemoteFSAccessor::addToCache(const Path & storePath, const std::string & nar) +{ + try { + if (cacheDir == "") return; + /* FIXME: do this asynchronously. */ + writeFile(makeCacheFile(storePath), nar); + } catch (...) { + ignoreException(); + } } std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_) @@ -23,7 +42,16 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_) if (i != nars.end()) return {i->second, restPath}; StringSink sink; - store->narFromPath(storePath, sink); + + try { + if (cacheDir != "") + *sink.s = nix::readFile(makeCacheFile(storePath)); + } catch (SysError &) { } + + if (sink.s->empty()) { + store->narFromPath(storePath, sink); + addToCache(storePath, *sink.s); + } auto accessor = makeNarAccessor(sink.s); nars.emplace(storePath, accessor); diff --git a/src/libstore/remote-fs-accessor.hh b/src/libstore/remote-fs-accessor.hh index 28f36c8296e1..2a3fc01eff58 100644 --- a/src/libstore/remote-fs-accessor.hh +++ b/src/libstore/remote-fs-accessor.hh @@ -12,10 +12,20 @@ class RemoteFSAccessor : public FSAccessor std::map<Path, ref<FSAccessor>> nars; + Path cacheDir; + std::pair<ref<FSAccessor>, Path> fetch(const Path & path_); + + friend class BinaryCacheStore; + + Path makeCacheFile(const Path & storePath); + + void addToCache(const Path & storePath, const std::string & nar); + public: - RemoteFSAccessor(ref<Store> store); + RemoteFSAccessor(ref<Store> store, + const /* FIXME: use std::optional */ Path & cacheDir = ""); Stat stat(const Path & path) override; diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index fa6ade75002a..3bc5e4c57c95 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -619,6 +619,8 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePa for (auto & path : storePaths) if (!valid.count(path)) missing.insert(path); + if (missing.empty()) return; + Activity act(*logger, lvlInfo, actCopyPaths, fmt("copying %d paths", missing.size())); std::atomic<size_t> nrDone{0}; diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index a3d3c8007be6..4541c89a700c 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -278,7 +278,7 @@ void mainWrapped(int argc, char * * argv) /* If we're in a #! script, interpret filenames relative to the script. */ exprs.push_back(state.parseExprFromFile(resolveExprPath(lookupFileArg(state, - inShebang && !packages ? absPath(i, dirOf(script)) : i)))); + inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))); } /* Evaluate them into derivations. */ |