diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-07-10 15:11:48 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-07-10 15:11:48 +0000 |
commit | 1d1c3691d2fdf5aad0baceadd8596f23c1e0e1fa (patch) | |
tree | c89123e33796e3408b613e1a824bcc66ad30395e /src/store.cc | |
parent | d072485d2895d01dbbab1d899418726e3349343f (diff) |
* The policy-free derivate sharing now *almost* works. :-) For any
hash for which no local expansion is available, Nix can execute a
`substitute' which should produce a path with such a hash.
This is policy-free since Nix does not in any way specify how the
substitute should work, i.e., it's an arbitrary (unnormalised)
fstate expression. For example, `nix-pull' registers substitutes
that fetch Nix archives from the network (through `wget') and unpack
them, but any other method is possible as well. This is an
improvement over the old Nix sharing scheme, which had a policy
(fetching through `wget') built in.
The sharing scheme doesn't work completely yet because successors
from fstate rewriting have to be registered on the receiving side.
Probably the whole successor stuff can be folded up into the
substitute mechanism; this would be a nice simplification.
Diffstat (limited to 'src/store.cc')
-rw-r--r-- | src/store.cc | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/src/store.cc b/src/store.cc index 5a3a4e067..435ac5cc6 100644 --- a/src/store.cc +++ b/src/store.cc @@ -7,6 +7,7 @@ #include "globals.hh" #include "db.hh" #include "archive.hh" +#include "fstate.hh" struct CopySink : DumpSink @@ -83,6 +84,20 @@ void copyPath(string src, string dst) } +void registerSubstitute(const Hash & srcHash, const Hash & subHash) +{ + Strings subs; + queryListDB(nixDB, dbSubstitutes, srcHash, subs); /* non-existence = ok */ + + for (Strings::iterator it = subs.begin(); it != subs.end(); it++) + if (parseHash(*it) == subHash) return; + + subs.push_back(subHash); + + setListDB(nixDB, dbSubstitutes, srcHash, subs); +} + + Hash registerPath(const string & _path, Hash hash) { string path(canonPath(_path)); @@ -139,8 +154,7 @@ string expandHash(const Hash & hash, const string & target, if (!target.empty() && !isInPrefix(target, prefix)) abort(); - if (!queryListDB(nixDB, dbHash2Paths, hash, paths)) - throw Error(format("no paths known with hash `%1%'") % (string) hash); + queryListDB(nixDB, dbHash2Paths, hash, paths); /* !!! we shouldn't check for staleness by default --- too slow */ @@ -181,8 +195,32 @@ string expandHash(const Hash & hash, const string & target, /* try next one */ } } + + /* Try to realise the substitutes. */ + + Strings subs; + queryListDB(nixDB, dbSubstitutes, hash, subs); /* non-existence = ok */ + + for (Strings::iterator it = subs.begin(); it != subs.end(); it++) { + StringSet dummy; + FState nf = realiseFState(hash2fstate(parseHash(*it)), dummy); + string path = fstatePath(nf); + + if (hashPath(path) != hash) + throw Error(format("bad substitute in `%1%'") % (string) path); + + if (target.empty()) + return path; /* !!! prefix */ + else { + if (path != target) { + copyPath(path, target); + registerPath(target, hash); + } + return target; + } + } - throw Error(format("all paths with hash `%1%' are stale") % (string) hash); + throw Error(format("cannot expand hash `%1%'") % (string) hash); } @@ -193,6 +231,7 @@ void addToStore(string srcPath, string & dstPath, Hash & hash) hash = hashPath(srcPath); try { + /* !!! should not use the substitutes! */ dstPath = expandHash(hash, "", nixStore); return; } catch (...) { |