aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-07-10 13:41:28 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-07-10 13:41:28 +0000
commitd072485d2895d01dbbab1d899418726e3349343f (patch)
tree237c23cdb613d363e9205f89d51cac8433cf3b85
parent5d4b90b689b09965be39c69aceddaf0b165598d0 (diff)
* Get `nix-push' working again. It now uses Nix/Fix to create Nix
archives (using the package in corepkgs/nar). * queryPathByHash -> expandHash, and it takes an argument specifying the target path (which may be empty). * Install the core Fix packages in $prefix/share/fix. TODO: bootstrap Nix and install Nix as a Fix package.
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac3
-rw-r--r--corepkgs/Makefile.am8
-rw-r--r--corepkgs/nar/nar.fix8
-rw-r--r--corepkgs/nar/nar.sh3
-rw-r--r--scripts/Makefile.am2
-rw-r--r--scripts/nix-pull2
-rw-r--r--scripts/nix-push60
-rw-r--r--src/fix.cc8
-rw-r--r--src/fstate.cc22
-rw-r--r--src/globals.cc4
-rw-r--r--src/globals.hh2
-rw-r--r--src/nix.cc24
-rw-r--r--src/shared.cc1
-rw-r--r--src/store.cc51
-rw-r--r--src/store.hh8
16 files changed, 154 insertions, 54 deletions
diff --git a/Makefile.am b/Makefile.am
index 83a04399a..2bed3f3bb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1 @@
-SUBDIRS = src scripts
+SUBDIRS = src scripts corepkgs
diff --git a/configure.ac b/configure.ac
index e3b0f0c6e..110d8f0e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,9 +13,10 @@ AC_PROG_RANLIB
# Unix shell scripting should die a slow and painful death.
AC_DEFINE_UNQUOTED(NIX_STORE_DIR, "$(eval echo $prefix/store)", Nix store directory.)
+AC_DEFINE_UNQUOTED(NIX_DATA_DIR, "$(eval echo $datadir)", Nix data directory.)
AC_DEFINE_UNQUOTED(NIX_STATE_DIR, "$(eval echo $localstatedir/nix)", Nix state directory.)
AC_DEFINE_UNQUOTED(NIX_LOG_DIR, "$(eval echo $localstatedir/log/nix)", Nix log file directory.)
AM_CONFIG_HEADER([config.h])
-AC_CONFIG_FILES([Makefile src/Makefile scripts/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile scripts/Makefile corepkgs/Makefile])
AC_OUTPUT
diff --git a/corepkgs/Makefile.am b/corepkgs/Makefile.am
new file mode 100644
index 000000000..9ce9c8c79
--- /dev/null
+++ b/corepkgs/Makefile.am
@@ -0,0 +1,8 @@
+install-data-local:
+ $(INSTALL) -d $(datadir)/fix
+ $(INSTALL) -d $(datadir)/fix/fetchurl
+ $(INSTALL_DATA) fetchurl/fetchurl.fix $(datadir)/fix/fetchurl
+ $(INSTALL_DATA) fetchurl/fetchurl.sh $(datadir)/fix/fetchurl
+ $(INSTALL) -d $(datadir)/fix/nar
+ $(INSTALL_DATA) nar/nar.fix $(datadir)/fix/nar
+ $(INSTALL_DATA) nar/nar.sh $(datadir)/fix/nar
diff --git a/corepkgs/nar/nar.fix b/corepkgs/nar/nar.fix
new file mode 100644
index 000000000..3db6a48a0
--- /dev/null
+++ b/corepkgs/nar/nar.fix
@@ -0,0 +1,8 @@
+Function(["path", "name"],
+ Package(
+ [ ("name", Var("name"))
+ , ("build", Relative("nar/nar.sh"))
+ , ("path", Var("path"))
+ ]
+ )
+) \ No newline at end of file
diff --git a/corepkgs/nar/nar.sh b/corepkgs/nar/nar.sh
new file mode 100644
index 000000000..6ffcf6322
--- /dev/null
+++ b/corepkgs/nar/nar.sh
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+/tmp/nix/bin/nix --dump --file "$path" > $out || exit 1
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index cf70f1574..e4602f2a1 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -1,5 +1,5 @@
bin_SCRIPTS = nix-switch nix-collect-garbage \
- nix-pull-prebuilts nix-push-prebuilts
+ nix-pull nix-push
install-exec-local:
$(INSTALL) -d $(sysconfdir)/profile.d
diff --git a/scripts/nix-pull b/scripts/nix-pull
new file mode 100644
index 000000000..0b09c8e00
--- /dev/null
+++ b/scripts/nix-pull
@@ -0,0 +1,2 @@
+#! /usr/bin/perl -w
+
diff --git a/scripts/nix-push b/scripts/nix-push
new file mode 100644
index 000000000..14b7e2834
--- /dev/null
+++ b/scripts/nix-push
@@ -0,0 +1,60 @@
+#! /usr/bin/perl -w
+
+my @pushlist;
+
+foreach my $hash (@ARGV) {
+
+ die unless $hash =~ /^([0-9a-z]{32})$/;
+
+ # Get all paths referenced by the normalisation of the given
+ # fstate expression.
+ my @paths;
+ open PATHS, "nix -qrh $hash 2> /dev/null |" or die "nix -qrh";
+ while (<PATHS>) {
+ chomp;
+ next unless /^\//;
+ push @paths, $_;
+ }
+ close PATHS;
+
+ # For each path, create a Fix expression that turns the path into
+ # a Nix archive.
+ foreach my $path (@paths) {
+
+ # Hash the path.
+ my $phash = `nix-hash $path`;
+ $? and die "nix-hash";
+ chomp $phash;
+ die unless $phash =~ /^([0-9a-z]{32})$/;
+
+ # Construct a Fix expression that creates a Nar archive.
+ my $fixexpr =
+ "App(IncludeFix(\"nar/nar.fix\"), " .
+ "[ (\"path\", Path(\"$path\", Hash(\"$phash\"), [Include(\"$hash\")]))" .
+ ", (\"name\", \"$phash.nar\")" .
+ "])";
+
+ my $fixfile = "/tmp/nix-push-tmp.fix";
+ open FIX, ">$fixfile";
+ print FIX $fixexpr;
+ close FIX;
+
+ # Instantiate a Nix expression from the Fix expression.
+ my $nhash = `fix $fixfile`;
+ $? and die "instantiating Nix archive expression";
+ chomp $nhash;
+ die unless $nhash =~ /^([0-9a-z]{32})$/;
+
+ # Realise the Nix expression.
+ my $npath = `nix -qph $nhash 2> /dev/null`;
+ $? and die "creating Nix archive";
+ chomp $npath;
+
+ push @pushlist, $npath;
+
+ print "$path -> $npath\n";
+ }
+}
+
+# Push the prebuilts to the server. !!! FIXME
+system "rsync -av -e ssh @pushlist eelco\@losser.st-lab.cs.uu.nl:/home/eelco/public_html/nix-dist/";
diff --git a/src/fix.cc b/src/fix.cc
index 9e5b8b5d4..5c4297bfb 100644
--- a/src/fix.cc
+++ b/src/fix.cc
@@ -15,6 +15,8 @@ static Strings searchDirs;
static string searchPath(string relPath)
{
+ if (string(relPath, 0, 1) == "/") return relPath;
+
for (Strings::iterator i = searchDirs.begin();
i != searchDirs.end(); i++)
{
@@ -218,7 +220,10 @@ static Expr evalExpr(Expr e)
static Expr evalFile(string relPath)
{
- Expr e = ATreadFromNamedFile(searchPath(relPath).c_str());
+ string path = searchPath(relPath);
+ Expr e = ATreadFromNamedFile(path.c_str());
+ if (!e)
+ throw Error(format("unable to read a term from `%1%'") % path);
return evalExpr(e);
}
@@ -228,6 +233,7 @@ void run(Strings args)
Strings files;
searchDirs.push_back(".");
+ searchDirs.push_back(nixDataDir + "/fix");
for (Strings::iterator it = args.begin();
it != args.end(); )
diff --git a/src/fstate.cc b/src/fstate.cc
index e289ca7b1..fdd43d1b1 100644
--- a/src/fstate.cc
+++ b/src/fstate.cc
@@ -149,7 +149,7 @@ Hash hashTerm(ATerm t)
ATerm termFromHash(const Hash & hash, string * p)
{
- string path = queryPathByHash(hash);
+ string path = expandHash(hash);
if (p) *p = path;
ATerm t = ATreadFromNamedFile(path.c_str());
if (!t) throw Error(format("cannot read aterm %1%") % path);
@@ -253,26 +253,6 @@ static FState realise(FState fs, StringSet & paths)
/* Expand the hash into the target path. */
expandHash(hash, path);
-#if 0
- /* Perhaps the path already exists and has the right hash? */
- if (pathExists(path)) {
-
- if (hash != hashPath(path))
- throw Error(format("path %1% exists, but does not have hash %2%")
- % path % (string) hash);
-
- debug(format("path %1% already has hash %2%")
- % path % (string) hash);
-
- } else {
-
- /* Do we know a path with that hash? If so, copy it. */
- string path2 = queryPathByHash(hash);
- copyPath(path2, path);
-
- }
-#endif
-
return nf;
}
diff --git a/src/globals.cc b/src/globals.cc
index 40a5a981b..9893d7ad2 100644
--- a/src/globals.cc
+++ b/src/globals.cc
@@ -4,8 +4,11 @@
string dbHash2Paths = "hash2paths";
string dbSuccessors = "successors";
+string dbSubstitutes = "substitutes";
+
string nixStore = "/UNINIT";
+string nixDataDir = "/UNINIT";
string nixLogDir = "/UNINIT";
string nixDB = "/UNINIT";
@@ -14,4 +17,5 @@ void initDB()
{
createDB(nixDB, dbHash2Paths);
createDB(nixDB, dbSuccessors);
+ createDB(nixDB, dbSubstitutes);
}
diff --git a/src/globals.hh b/src/globals.hh
index 8d8c63bd7..0668ac40e 100644
--- a/src/globals.hh
+++ b/src/globals.hh
@@ -52,6 +52,8 @@ extern string dbSubstitutes;
derived files. */
extern string nixStore;
+extern string nixDataDir; /* !!! fix */
+
/* nixLogDir is the directory where we log various operations. */
extern string nixLogDir;
diff --git a/src/nix.cc b/src/nix.cc
index d6f2db4fe..4721563fd 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -37,7 +37,7 @@ static ArgType argType = atpUnknown;
Source selection for --install, --dump:
- --file / -f: by file name
+ --file / -f: by file name !!! -> path
--hash / -h: by hash
Query flags:
@@ -87,6 +87,12 @@ static Hash argToHash(const string & arg)
}
+static FState hash2fstate(Hash hash)
+{
+ return ATmake("Include(<str>)", ((string) hash).c_str());
+}
+
+
/* Realise (or install) paths from the given Nix fstate
expressions. */
static void opInstall(Strings opFlags, Strings opArgs)
@@ -98,7 +104,7 @@ static void opInstall(Strings opFlags, Strings opArgs)
it != opArgs.end(); it++)
{
StringSet paths;
- realiseFState(termFromHash(argToHash(*it)), paths);
+ realiseFState(hash2fstate(argToHash(*it)), paths);
}
}
@@ -157,14 +163,16 @@ static void opQuery(Strings opFlags, Strings opArgs)
switch (query) {
- case qPath:
+ case qPath: {
+ StringSet refs;
cout << format("%s\n") %
- (string) fstatePath(termFromHash(hash));
+ (string) fstatePath(realiseFState(termFromHash(hash), refs));
break;
+ }
case qRefs: {
StringSet refs;
- FState fs = ATmake("Include(<str>)", ((string) hash).c_str());
+ FState fs = hash2fstate(hash);
fstateRefs(realiseFState(fs, refs), refs);
for (StringSet::iterator j = refs.begin();
j != refs.end(); j++)
@@ -203,10 +211,8 @@ static void opDump(Strings opFlags, Strings opArgs)
string arg = *opArgs.begin();
string path;
- if (argType == atpHash)
- path = queryPathByHash(parseHash(arg));
- else if (argType == atpPath)
- path = arg;
+ if (argType == atpHash) path = expandHash(parseHash(arg));
+ else if (argType == atpPath) path = arg;
dumpPath(path, sink);
}
diff --git a/src/shared.cc b/src/shared.cc
index bd165ce97..bfd7498de 100644
--- a/src/shared.cc
+++ b/src/shared.cc
@@ -16,6 +16,7 @@ static void initAndRun(int argc, char * * argv)
{
/* Setup Nix paths. */
nixStore = NIX_STORE_DIR;
+ nixDataDir = NIX_DATA_DIR;
nixLogDir = NIX_LOG_DIR;
nixDB = (string) NIX_STATE_DIR + "/nixstate.db";
diff --git a/src/store.cc b/src/store.cc
index 38e059a29..5a3a4e067 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -131,25 +131,53 @@ bool isInPrefix(const string & path, const string & _prefix)
}
-static string queryPathByHashPrefix(Hash hash, const string & prefix)
+string expandHash(const Hash & hash, const string & target,
+ const string & prefix)
{
Strings paths;
+ if (!target.empty() && !isInPrefix(target, prefix))
+ abort();
+
if (!queryListDB(nixDB, dbHash2Paths, hash, paths))
throw Error(format("no paths known with hash `%1%'") % (string) hash);
- /* Arbitrarily pick the first one that exists and still hash the
- right hash. */
+ /* !!! we shouldn't check for staleness by default --- too slow */
+
+ /* Pick one equal to `target'. */
+ if (!target.empty()) {
+
+ for (Strings::iterator i = paths.begin();
+ i != paths.end(); i++)
+ {
+ string path = *i;
+ try {
+ if (path == target && hashPath(path) == hash)
+ return path;
+ } catch (Error & e) {
+ debug(format("stale path: %1%") % e.msg());
+ /* try next one */
+ }
+ }
+
+ }
+ /* Arbitrarily pick the first one that exists and isn't stale. */
for (Strings::iterator it = paths.begin();
it != paths.end(); it++)
{
string path = *it;
try {
- if (isInPrefix(path, prefix) && hashPath(path) == hash)
- return path;
+ if (isInPrefix(path, prefix) && hashPath(path) == hash) {
+ if (target.empty())
+ return path;
+ else {
+ copyPath(path, target);
+ return target;
+ }
+ }
} catch (Error & e) {
- debug(format("checking hash: %1%") % e.msg());
+ debug(format("stale path: %1%") % e.msg());
/* try next one */
}
}
@@ -157,16 +185,7 @@ static string queryPathByHashPrefix(Hash hash, const string & prefix)
throw Error(format("all paths with hash `%1%' are stale") % (string) hash);
}
-
-string expandHash(const Hash & hash, const string & outPath = "")
-{
-string queryPathByHash(Hash hash)
-{
- return queryPathByHashPrefix(hash, "/");
-}
-
-
void addToStore(string srcPath, string & dstPath, Hash & hash)
{
srcPath = absPath(srcPath);
@@ -174,7 +193,7 @@ void addToStore(string srcPath, string & dstPath, Hash & hash)
hash = hashPath(srcPath);
try {
- dstPath = queryPathByHashPrefix(hash, nixStore);
+ dstPath = expandHash(hash, "", nixStore);
return;
} catch (...) {
}
diff --git a/src/store.hh b/src/store.hh
index f747b7ee3..8b02cba99 100644
--- a/src/store.hh
+++ b/src/store.hh
@@ -13,15 +13,15 @@ void copyPath(string src, string dst);
/* Register a path keyed on its hash. */
Hash registerPath(const string & path, Hash hash = Hash());
-/* Return a path whose contents have the given hash. If outPath is
- not empty, ensure that such a path is realised in outPath (if
+/* Return a path whose contents have the given hash. If target is
+ not empty, ensure that such a path is realised in target (if
necessary by copying from another location). If prefix is not
empty, only return a path that is an descendent of prefix.
If no path with the given hash is known to exist in the file
- system, ...
+ system,
*/
-string expandHash(const Hash & hash, const string & outPath = "",
+string expandHash(const Hash & hash, const string & target = "",
const string & prefix = "/");
/* Copy a file to the nixStore directory and register it in dbRefs.