Compare commits

...

620 Commits

Author SHA1 Message Date
Nicolas Pierron
6468f63994 Fix typo. 2009-07-08 09:44:22 +00:00
Nicolas Pierron
9416202465 Add a way to cache result for future evaluations. 2009-07-08 09:27:35 +00:00
Nicolas Pierron
4941ba3413 Add a session independent cache. 2009-07-08 09:26:15 +00:00
Nicolas Pierron
7244b9b861 Create a cache of reduce operations which are session independent. 2009-07-08 09:18:26 +00:00
Eelco Dolstra
c6890d6b5c * Replace newlines in table output with spaces. 2009-07-02 08:52:12 +00:00
Eelco Dolstra
749dd97a54 * Support integers and lists of strings in meta fields. This is
useful for fields like meta.maintainers, meta.priority (which can be
  a proper integer now) and even meta.license (if there are multiple
  licenses).
2009-06-30 15:53:39 +00:00
Eelco Dolstra
f2c3fc5191 * Don't show trace information by default (`--show-trace' to enable).
NixOS evaluation errors in particular look intimidating and
  generally aren't very useful.  Ideally the builtins.throw messages
  should be self-contained.
2009-06-30 13:28:29 +00:00
Eelco Dolstra
a2fc3a53ba * Highlight URLs containing "=" properly. 2009-06-18 10:04:14 +00:00
Eelco Dolstra
d53603c928 * Attributes names in attrsets can contain dots now. 2009-06-18 09:56:50 +00:00
Eelco Dolstra
14bc3ce3d6 * Canonicalise timestamps in the Nix store to 1 (1970-01-01 00:00:01
UTC) rather than 0 (00:00:00).  1 is a better choice because some
  programs use 0 as a special value.  For instance, the Template
  Toolkit uses a timestamp of 0 to denote the non-existence of a file,
  so it barfs on files in the Nix store (see
  template-toolkit-nix-store.patch in Nixpkgs).  Similarly, Maya 2008
  fails to load script directories with a timestamp of 0 and can't be
  patched because it's closed source.

  This will also shut up those "implausibly old time stamp" GNU tar
  warnings.
2009-06-13 16:30:58 +00:00
Eelco Dolstra
f24cf5d303 * nix-build: if nix-instantiate or nix-store fails due to a signal
(e.g. out of memory or a segfault), print an error message.
  Otherwise the user doesn't see anything.
2009-06-10 11:30:34 +00:00
Eelco Dolstra
c6cb792d48 2009-05-26 16:32:02 +00:00
Eelco Dolstra
a64bbe049e * Change the scoping of "inherit (e) ..." in recs so that the
attributes of the rec are in scope of `e'.  This is useful in
  expressions such as

    rec {
      lib = import ./lib;
      inherit (lib) concatStrings;
    }

  It does change the semantics of expressions such as

    let x = {y = 1;}; in rec { x = {y = 2;}; inherit (x) y; }.y

  This now returns 2 instead of 1.  However, no code in Nixpkgs or
  NixOS seems to rely on the old behaviour.
2009-05-15 13:46:13 +00:00
Eelco Dolstra
d407d572fd * Some syntactic sugar for attribute sets: allow {x.y.z = ...;} as a
shorthand for {x = {y = {z = ...;};};}.  This is especially useful
  for NixOS configuration files, e.g.

    {
      services = {
        sshd = {
          enable = true;
          port = 2022;
        };
      };
    }

  can now be written as

    {
      services.sshd.enable = true;
      services.sshd.port = 2022;
    }

  However, it is currently not permitted to write
  
    {
      services.sshd = {enable = true;};
      services.sshd.port = 2022;
    }

  as this is considered a duplicate definition of `services.sshd'.
2009-05-15 12:35:23 +00:00
Eelco Dolstra
e42975490f * Check for duplicate attributes in fixAttrs, rather than doing a
separate traversal after parsing.  Likewise, check for duplicate
  pattern variables right away.
2009-05-14 14:29:45 +00:00
Eelco Dolstra
50d11b90ca * Allow unsafe (unspecified) comparisons between attrsets unless
NIX_NO_UNSAFE_EQ is set, for now.
2009-05-12 11:06:24 +00:00
Eelco Dolstra
c34e6d71bc * Disallow equality tests between attribute sets. This was always
broken, but now the evaluator checks for it to prevent Nix
  expressions from relying on undefined behaviour.  Equality tests are
  implemented using a shallow pointer equality test between ATerms.
  However, because attribute sets are lazy and contain position
  information, this can give false positives.  For instance,
  previously

    let y = {x = 1;}; in y == y

  evaluated to true, while the equivalent expression

    {x = 1;} == {x = 1;}

  evaluated to false.  So disallow these tests for now.  (Eventually
  we may want to implement deep equality tests for attribute sets,
  like lib.eqStrict.)
  
* Idem: disallow comparisons between functions.

* Implemented deep comparisons of lists.  This had the same problem as
  attribute sets - the elements in the list weren't evaluated.  For
  instance,

    ["xy"] == [("x" + "y")]

  evaluated to false.  Now it works properly.
2009-05-11 15:50:14 +00:00
Eelco Dolstra
9536ba19d4 2009-05-07 13:22:26 +00:00
Eelco Dolstra
83bd320b39 * Build a PDF version of the manual in the tarball job (it's not
included in the tarball though).
2009-05-07 13:12:46 +00:00
Eelco Dolstra
f751c2966b * Don't have a bugs section in the manual. Bugs should be kept in the
bug tracker.
2009-05-07 13:11:58 +00:00
Eelco Dolstra
404996ca1f * Produce the manual in the tarball job. 2009-05-07 12:57:04 +00:00
Eelco Dolstra
7660e2a068 * Remove a right recursion that causes the parser to barf on very long
lists.  The comment about ATreverse requiring unbounded stack space
  was unfounded anyway.
2009-05-07 11:35:52 +00:00
Eelco Dolstra
52a9ba96f5 * Include the version file. 2009-05-07 11:34:08 +00:00
Eelco Dolstra
6a5599fd01 * Typo. 2009-05-07 11:33:57 +00:00
Michael Raskin
098cb9d233 Add an ftruncate call paired with fallocate to play safe with some FSes (namely, BtrFS fallocate sets file size to allocated size, i.e. multiple of block size) 2009-05-04 08:10:24 +00:00
Eelco Dolstra
c710fe540e * Machines of type x86_64-linux can do i686-linux builds. 2009-04-21 12:42:47 +00:00
Eelco Dolstra
d5eab2fc82 * Use foreach in a lot of places. 2009-04-21 11:52:16 +00:00
Eelco Dolstra
8f1bf28505 * nix-store --verify: don't bail out if a referenced path is missing.
(It can't fix it though.)
2009-04-21 11:06:27 +00:00
Eelco Dolstra
4e646b0ddb * Fix a few "comparison is always false/true due to limited range of
data type" warnings on 64-bit platforms.  The one in parser.y is
  likely to be a real bug.
2009-04-16 12:03:17 +00:00
Eelco Dolstra
0460ea4c39 * Cleanup. 2009-04-16 09:27:33 +00:00
Eelco Dolstra
dfb863f333 * Don't cache transient build hook problems. 2009-04-15 06:25:02 +00:00
Eelco Dolstra
435a93b5d8 * Remove references to __XXX primops. 2009-04-14 13:03:27 +00:00
Eelco Dolstra
8b2a01a8c2 * Release notes. 2009-04-14 12:02:22 +00:00
Eelco Dolstra
50cb6f9782 * Debian packages: use /etc, not /usr/etc. 2009-04-02 08:16:15 +00:00
Eelco Dolstra
351bf658f9 * Do a substitution even if --max-jobs == 0. 2009-03-31 21:14:07 +00:00
Eelco Dolstra
cff2b2a13a * Doh! 2009-03-31 15:50:03 +00:00
Eelco Dolstra
160a60d663 2009-03-30 19:35:55 +00:00
Eelco Dolstra
805144b705 * Make the poll interval configurable. 2009-03-30 11:34:03 +00:00
Eelco Dolstra
096affb55b * Update the mtime on the lock file to make it easy to see when a slot
was last used.
2009-03-29 18:40:44 +00:00
Eelco Dolstra
cbc1f57b48 * Undocument the "system" option. No sane person would use it :-) 2009-03-29 18:08:32 +00:00
Eelco Dolstra
7377195297 * With `--max-jobs 0', print a nicer error message than "Assertion
`!awake.empty()' failed."
2009-03-29 18:06:00 +00:00
Eelco Dolstra
737423a89c * Use polling to wait for a remote build slot when using a build hook
(that is, call the build hook with a certain interval until it
  accepts the build).
* build-remote.pl was totally broken: for all system types other than
  the local system type, it would send all builds to the *first*
  machine of the appropriate type.
2009-03-29 18:00:45 +00:00
Eelco Dolstra
47706e3924 * nix-copy-closure: compute the closure in one call to nix-store,
which is much faster.
2009-03-28 21:10:29 +00:00
Eelco Dolstra
6e946c8e72 * Scan for references and compute the SHA-256 hash of the output in
one pass.  This halves the amount of I/O.
2009-03-28 20:51:33 +00:00
Eelco Dolstra
c7152c8f97 * Don't use the non-standard __gnu_cxx::stdio_filebuf class. 2009-03-28 19:41:53 +00:00
Eelco Dolstra
3a2bbe7f8a * Simplify communication with the hook a bit (don't use file
descriptors 3/4, just use stdin/stderr).
2009-03-28 19:29:55 +00:00
Eelco Dolstra
7fb548aa26 * Clean up the output a bit. 2009-03-28 16:12:46 +00:00
Eelco Dolstra
f54e800366 * The `fixedOutput' variable didn't get initialised when using a build
hook, causing negative caching to fail randomly.
2009-03-28 16:12:27 +00:00
Eelco Dolstra
38f98b3282 * Argh, stupid timing sensitive tests... 2009-03-27 22:40:22 +00:00
Eelco Dolstra
e23a7a8b7b * Debian 5.0, Ubuntu 8.10 builds. 2009-03-27 14:20:03 +00:00
Eelco Dolstra
cb85bc396e * Create /nix/store if it doesn't exist. 2009-03-27 14:19:04 +00:00
Eelco Dolstra
61686926d1 * A job for creating a fully statically linked binary tarball. 2009-03-26 14:12:42 +00:00
Eelco Dolstra
9856efc7b0 * Support doing a fully static build. Statically linked Nix binaries
will be useful as a fallback on platforms for which there are no
  RPMs/Debs available.
2009-03-26 12:22:08 +00:00
Eelco Dolstra
5dd8fb2069 * Don't use ULLONG_MAX in maxFreed - use 0 to mean "no limit".
18446744073709551615ULL breaks on GCC 3.3.6 (`integer constant is
  too large for "long" type').
2009-03-26 11:02:07 +00:00
Eelco Dolstra
92f525ecf4 * Negative caching, i.e. caching of build failures. Disabled by
default.  This is mostly useful for Hydra.
2009-03-25 21:05:42 +00:00
Eelco Dolstra
7024a1ef07 * Removed the locking.sh test; it's redundant because of the extended
parallel.sh test.  Also, don't call multiple nix-builds in parallel,
  since they can race creating .nix-build-tmp-derivation.
2009-03-25 16:43:38 +00:00
Eelco Dolstra
8146a0c731 * Use bash in the tests. 2009-03-25 16:11:04 +00:00
Eelco Dolstra
a046858a22 * Doh. 2009-03-24 23:40:24 +00:00
Eelco Dolstra
12c8c64efa 2009-03-24 14:07:37 +00:00
Eelco Dolstra
7aedcf9460 * Make this test a bit more robust. It's still timing dependent
though.
2009-03-23 15:16:36 +00:00
Eelco Dolstra
3a87163b24 * Shut up a GCC warning. 2009-03-23 13:52:52 +00:00
Eelco Dolstra
cacff1be88 * No longer block while waiting for a lock on a store path. Instead
poll for it (i.e. if we can't acquire the lock, then let the main
  select() loop wait for at most a few seconds and then try again).
  This improves parallelism: if two nix-store processes are both
  trying to build a path at the same time, the second one shouldn't
  block; it should first see if it can build other goals.  Also, it
  prevents the deadlocks that have been occuring in Hydra lately,
  where a process waits for a lock held by another process that's
  waiting for a lock held by the first.

  The downside is that polling isn't really elegant, but POSIX doesn't
  provide a way to wait for locks in a select() loop.  The only
  solution would be to spawn a thread for each lock to do a blocking
  fcntl() and then signal the main thread, but that would require
  pthreads.
2009-03-23 01:05:54 +00:00
Eelco Dolstra
58969fa2bf * Refactoring. 2009-03-22 23:53:05 +00:00
Eelco Dolstra
d7b2d11255 * Test case (currently fails): multiple Nix builds shouldn't block
waiting on the same lock when there are other builds that can be
  done.
2009-03-22 23:16:18 +00:00
Eelco Dolstra
7a57b2920b * Better error message when nix-store --import is applied to garbage
(previously it would likely say "implementation cannot deal with >
  32-bit integers").
2009-03-22 17:51:45 +00:00
Eelco Dolstra
77d272623f * NAR archives: handle files larger than 2^32 bytes. Previously it
would just silently store only (fileSize % 2^32) bytes.
* Use posix_fallocate if available when unpacking archives.
* Provide a better error message when trying to unpack something that
  isn't a NAR archive.
2009-03-22 17:36:43 +00:00
Eelco Dolstra
7e05b8b75e * Future proofing: assume we can read manifests up to version 10
(which should therefore be backwards compatible).
2009-03-19 10:02:02 +00:00
Eelco Dolstra
b88460bcbc * Disregard the Hash field in manifests. 2009-03-19 09:47:34 +00:00
Eelco Dolstra
2897286487 * Unify exportReferencesGraph and exportBuildReferencesGraph, and make
sure that it works as expected when you pass it a derivation.  That
  is, we have to make sure that all build-time dependencies are built,
  and that they are all in the input closure (otherwise remote builds
  might fail, for example).  This is ensured at instantiation time by
  adding all derivations and their sources to inputDrvs and inputSrcs.
2009-03-18 17:36:42 +00:00
Eelco Dolstra
e530e0a350 * Improve the test. 2009-03-18 16:36:13 +00:00
Eelco Dolstra
9485ec31ea * Better cleanup after tests. 2009-03-18 16:35:35 +00:00
Eelco Dolstra
13df3915ef * Missing file. 2009-03-18 16:23:29 +00:00
Eelco Dolstra
c183ee5c79 * Acquire the locks on the output paths before trying to run the build
hook.  This fixes a problem with log files being partially or
  completely filled with 0's because another nix-store process
  truncates the log file.  It should also be more efficient.
2009-03-18 14:48:42 +00:00
Eelco Dolstra
1dcf208f56 * Clean up some tests (use nix-build where appropriate). 2009-03-18 13:15:55 +00:00
Eelco Dolstra
93b6926054 * Regression test for exportBuildReferencesGraph. It currently fails. 2009-03-17 17:38:32 +00:00
Eelco Dolstra
51e7e32c3b * Refactoring: renamed *.nix.in to *.nix. 2009-03-17 17:11:55 +00:00
Eelco Dolstra
2d5114452d * Regression test for the `exportReferencesGraph'
derivation attribute.
2009-03-17 16:33:48 +00:00
Eelco Dolstra
33ecb42991 * Cleanup. 2009-03-17 11:42:55 +00:00
Eelco Dolstra
be88248add * Make the version available to release.nix. 2009-03-09 15:05:08 +00:00
Eelco Dolstra
a96cac0d18 2009-03-06 17:00:58 +00:00
Eelco Dolstra
d4753c944f 2009-03-06 11:01:45 +00:00
Eelco Dolstra
0e6f604178 * Install some headers in the right location. 2009-03-05 14:57:50 +00:00
Eelco Dolstra
7f254706b0 * Allow the channel to declare a name for itself. 2009-03-03 14:47:39 +00:00
Eelco Dolstra
1273d355ac * nix-install-package: don't pollute /nix/var/nix/manifests. 2009-02-27 14:06:38 +00:00
Eelco Dolstra
d4ca5c3952 * Use the regular progress bar; the hash bar isn't very useful when
the size of the download isn't known in advance.
2009-02-27 13:55:11 +00:00
Eelco Dolstra
fd2e14b3c8 * nix-build: support --option. 2009-02-27 12:09:30 +00:00
Eelco Dolstra
60cb7de336 * Allow options from the Nix config file to be overriden from the
command line (e.g. "--option build-use-chroot true").
2009-02-27 11:04:41 +00:00
Eelco Dolstra
8ab6bc5a49 * nix-channel: use nix-build. 2009-02-27 11:01:03 +00:00
Eelco Dolstra
f052c10eed * Check the manifest version. 2009-02-27 09:53:58 +00:00
Eelco Dolstra
a7cee528c5 * Handle base-16 hashes in manifests. 2009-02-26 21:12:35 +00:00
Eelco Dolstra
041717eda3 * download-using-manifests: don't check the cryptographic hash of
downloaded files; rather, check the hash of the unpacked store
  path.

  When the server produces bzipped NAR archives on demand (like Hydra
  does), the hash of the file is not known in advance; it's streamed
  from the server.  Thus the manifest doesn't contain a hash for the
  bzipped NAR archive.  However, the server does know the hash of the
  *uncompressed* NAR archive (the "NarHash" field), since it's stored
  in the Nix database (nix-store -q --hash /nix/store/bla).  So we use
  that instead for checking the integrity of the download.
2009-02-19 23:46:37 +00:00
Michael Raskin
621093cb1c Replace wrong (w.r.t. PATH) sed call with in-shell substitution 2009-02-19 20:46:45 +00:00
Eelco Dolstra
824b154ce8 * Release output locks as soon as possible, not when the destructor of
the DerivationGoal runs.  Otherwise, if a goal is a top-level goal,
  then the lock won't be released until nix-store finishes.  With
  --keep-going and lots of top-level goals, it's possible to run out
  of file descriptors (this happened sometimes in the build farm for
  Nixpkgs).  Also, for failed derivation, it won't be possible to
  build it again  until the lock is released.
  
* Idem for locks on build users: these weren't released in a timely
  manner for failed top-level derivation goals.  So if there were more
  than (say) 10 such failed builds, you would get an error about
  having run out of build users.
2009-02-16 09:24:20 +00:00
Marc Weber
2ef579d1aa documentation for previous commit 2009-02-05 19:35:44 +00:00
Marc Weber
1407a1ec99 added primop functions __isBool, __isString, __isInt 2009-02-05 19:35:40 +00:00
Eelco Dolstra
1bb0f1e84b * Build hook: compress the transferred data. 2009-02-03 10:34:15 +00:00
Eelco Dolstra
b682fae9d9 * Build hooks: use nix-store --import. This prevents a redundant
scan for runtime dependencies (i.e. the local machine shouldn't do a
  scan that the remote machine has already done).  Also pipe directly
  into `nix-store --import': don't use a temporary file.
2009-02-02 17:24:10 +00:00
Marc Weber
6f8c96d123 vim syntax: support for indented strings ('' .. '') 2009-01-28 12:14:53 +00:00
Nicolas Pierron
110606d470 Add the "addErrorContext" builtin to add more information in the stack trace. 2009-01-27 14:36:44 +00:00
Eelco Dolstra
061141e632 * Make it compile on Debian 4.0 (which doesn't define PER_LINUX32_3GB
in sys/personality.h).
2009-01-27 13:36:59 +00:00
Eelco Dolstra
019176137f * When using a build hook, distinguish between transient failures
(e.g. an SSH connection problem) and permanent failures (i.e. the
  builder failed).  This matters to Hydra (it wants to know whether it
  makes sense to retry a build).
2009-01-13 11:39:09 +00:00
Eelco Dolstra
4ce692df88 2009-01-13 10:42:13 +00:00
Eelco Dolstra
c504d90c11 * Support i686-linux builds directly on x86_64-linux Nix
installations.  This is implemented using the personality() syscall,
  which causes uname to return "i686" in child processes.
2009-01-12 16:30:32 +00:00
Eelco Dolstra
8e39d9bdb3 * Make Nix build with Bison 2.4. 2009-01-12 12:51:28 +00:00
Eelco Dolstra
28355dafcf * Removed reference to losser.st-lab.cs.uu.nl, which is RIP after 9
years of loyal service :-)
2009-01-05 12:14:43 +00:00
Eelco Dolstra
8fce03e0ad * nix-store --verify: repair bad hash fields in the metadata file. 2008-12-16 13:28:18 +00:00
Eelco Dolstra
60ec75048a * Pass --use-atime / --max-atime to the daemon. 2008-12-16 12:23:35 +00:00
Eelco Dolstra
6f6bb1fdea * Delete the chroot if it already exists (e.g. left over from an
interrupted build).
2008-12-15 23:55:11 +00:00
Eelco Dolstra
92cb7c4dfe * Put chroots in the Nix store. This ensures that we can create hard
links to the inputs.
2008-12-12 17:14:57 +00:00
Eelco Dolstra
0008b0006d * Simplify deleting .lock files in /nix/store: just don't delete them
if they belong a path that's currently being built.  This gets rid
  of some Cygwin-specific code.
2008-12-12 17:03:18 +00:00
Eelco Dolstra
ac36c6cd44 * Some hackery to make "make check" succeed on Cygwin. 2008-12-12 15:36:18 +00:00
Eelco Dolstra
2b70a8e7c9 * Detect whether unshare() is available. 2008-12-12 13:41:36 +00:00
Eelco Dolstra
9122dcecbb * We can't use string objects in signal handlers because they might
allocate memory, which is verboten in signal handlers.  This caused
  random failures in the test suite on Mac OS X (triggered by the spurious
  SIGPOLL signals on Mac OS X, which should also be fixed).
2008-12-12 12:59:27 +00:00
Eelco Dolstra
6776a52bb3 * Use a PathSet for the chroot directories so that we don't
accidentally bind-mount a directory twice.
2008-12-12 11:49:42 +00:00
Eelco Dolstra
d86bd22d24 * Define _GNU_SOURCE. Hopefully this fixes the build on Debian 4.0
(http://hydra.nixos.org/nixlog/384/1).
2008-12-12 10:20:19 +00:00
Eelco Dolstra
ac5478eb52 * Don't provide the whole Nix store in the chroot, but only the
closure of the inputs.  This really enforces that there can't be any
  undeclared dependencies on paths in the store.  This is done by
  creating a fake Nix store and creating bind-mounts or hard-links in
  the fake store for all paths in the closure.  After the build, the
  build output is moved from the fake store to the real store.  TODO:
  the chroot has to be on the same filesystem as the Nix store for
  this to work, but this isn't enforced yet.  (I.e. it only works
  currently if /tmp is on the same FS as /nix/store.)
2008-12-11 18:57:10 +00:00
Eelco Dolstra
652817046b * Revert r13150: now that we use private namespaces for the chroot, we
don't have to put the chroot in /nix/var/nix/chroots anymore.
  They're back in /tmp now.
2008-12-11 17:52:34 +00:00
Eelco Dolstra
5a569509b4 * Provide a minimal /etc/passwd in the chroot to keep some builders
happy.
2008-12-11 17:44:02 +00:00
Eelco Dolstra
7c54f1603f * Do chroot builds in a private namespace. This means that all the
bind-mounts we do are only visible to the builder process and its
  children.  So accidentally doing "rm -rf" on the chroot directory
  won't wipe out /nix/store and other bind-mounted directories
  anymore.  Also, the bind-mounts in the private namespace disappear
  automatically when the builder exits.
2008-12-11 17:00:12 +00:00
Eelco Dolstra
07cdfb09fb * Open the connection to the daemon lazily (on demand) so that
read-only operations (like nix-env -qa) work properly when the
  daemon isn't running.
2008-12-11 14:30:25 +00:00
Eelco Dolstra
a0766eca27 * Build on Debian 4.0 (GCC 4.1.1). 2008-12-04 21:07:29 +00:00
Eelco Dolstra
cd16d5dc3d * Doh. 2008-12-04 17:56:12 +00:00
Eelco Dolstra
5b949241a5 * Build some 64-bit RPMs/Debs. 2008-12-04 17:54:14 +00:00
Eelco Dolstra
67958f21df * Be sure to clean up the daemon if the test fails. 2008-12-04 16:55:22 +00:00
Eelco Dolstra
d91dc086bb 2008-12-04 16:51:36 +00:00
Eelco Dolstra
9ac3f5df9c * Propagate --max-silent-time to remote machines. 2008-12-04 16:51:16 +00:00
Eelco Dolstra
bcfe98acff * Prefer building on a remote machine over a local machine. This
makes more sense for the build farm, otherwise every nix-store
  invocation will lead to at least one local build.  Will come up with
  a better solution later...
2008-12-04 16:35:47 +00:00
Eelco Dolstra
9850262a72 * Build RPMs, Debs, coverage analysis. 2008-12-04 15:25:28 +00:00
Eelco Dolstra
909fbb9de1 * When using build hooks, for any nix-store -r build operation, it is
necessary that at least one build hook doesn't return "postpone",
  otherwise nix-store will barf ("waiting for a build slot, yet there
  are no running children").  So inform the build hook when this is
  the case, so that it can start a build even when that would exceed
  the maximum load on a machine.
2008-12-04 14:29:41 +00:00
Eelco Dolstra
5dfba0b4db * Force allocation of a pseudo-terminal to clean up the remote
nix-store process when the connection is interrupted.
2008-12-04 13:36:52 +00:00
Eelco Dolstra
9ccdb80de3 * Don't ignore errors from writing to stderr. That way, when
nix-store -r (or some other operation) is started via ssh, it will
  at least have a chance of terminating quickly when the connection is
  killed.  Right now it just runs to completion, because it never
  notices that stderr is no longer connected to anything.  Of course
  it would be better if sshd would just send a SIGHUP, but it doesn't
  (https://bugzilla.mindrot.org/show_bug.cgi?id=396).
2008-12-04 13:13:31 +00:00
Eelco Dolstra
9fd9c4c635 * Support multiple system types per remote machine, e.g. a machine
list like

    root@example.org x86_64-linux /root/.ssh/id_buildfarm 1
    root@example.org i686-darwin  /root/.ssh/id_buildfarm 1

  This is possible when the Nix installation on example.org itself has
  remote builds enabled.
2008-12-04 12:20:06 +00:00
Eelco Dolstra
63b8f09d8d 2008-12-04 10:45:47 +00:00
Eelco Dolstra
f8713e1287 * Dirty hack to make nix-push work properly on derivations: the
derivation should be a source rather than a derivation dependency of
  the call to the NAR derivation.  Otherwise the derivation (and all
  its dependencies) will be built as a side-effect, which may not even
  succeed.
2008-12-04 10:40:41 +00:00
Eelco Dolstra
82ae85de27 * addToStore() in nix-worker: don't write the NAR dump received from
the client to a temporary directory, as that is highly inefficient.
2008-12-03 18:05:14 +00:00
Eelco Dolstra
5eaf644c99 * A simple API for parsing NAR archives. 2008-12-03 17:30:32 +00:00
Eelco Dolstra
cdee317419 * Backwards compatibility. 2008-12-03 17:02:29 +00:00
Eelco Dolstra
d95b68fde3 2008-12-03 16:15:38 +00:00
Eelco Dolstra
ff762fb499 * Pass HashType values instead of strings. 2008-12-03 16:10:17 +00:00
Eelco Dolstra
1307b22223 * Made addToStore() a lot more efficient: it no longer reads the path
being copied 3 times in the worst case.  It doesn't run in constant space,
  but it didn't do that anyway.
2008-12-03 15:51:17 +00:00
Eelco Dolstra
64519cfd65 * Unify the treatment of sources copied to the store, and recursive
SHA-256 outputs of fixed-output derivations.  I.e. they now produce
  the same store path:

  $ nix-store --add x
  /nix/store/j2fq9qxvvxgqymvpszhs773ncci45xsj-x

  $ nix-store --add-fixed --recursive sha256 x
  /nix/store/j2fq9qxvvxgqymvpszhs773ncci45xsj-x

  the latter being the same as the path that a derivation

    derivation {
      name = "x";
      outputHashAlgo = "sha256";
      outputHashMode = "recursive";
      outputHash = "...";
      ...
    };

  produces.

  This does change the output path for such fixed-output derivations.
  Fortunately they are quite rare.  The most common use is fetchsvn
  calls with SHA-256 hashes.  (There are a handful of those is
  Nixpkgs, mostly unstable development packages.)
  
* Documented the computation of store paths (in store-api.cc).
2008-12-03 15:06:30 +00:00
Eelco Dolstra
09bc0c502c * Install the release notes. 2008-11-29 00:31:39 +00:00
Eelco Dolstra
5d4eb9dd07 * Moved the build farm job for building Nix to the Nix tree. 2008-11-26 01:13:29 +00:00
Eelco Dolstra
0c478d2f4d * Ignore carriage returns. 2008-11-25 02:30:35 +00:00
Eelco Dolstra
5024bde8f4 * Handle prematurely ended logfiles, i.e. make sure we emit enough
close tags.
2008-11-25 01:06:15 +00:00
Eelco Dolstra
2ab09a55cf * Bump the version number. 2008-11-20 21:51:58 +00:00
Eelco Dolstra
6bbff48079 2008-11-20 17:22:42 +00:00
Eelco Dolstra
b8eb32f4d2 * Urgh. 2008-11-20 16:42:52 +00:00
Eelco Dolstra
bba87589cc 2008-11-20 16:28:04 +00:00
Eelco Dolstra
f3e2e6076a 2008-11-20 16:10:55 +00:00
Eelco Dolstra
53cca4a445 2008-11-20 16:06:13 +00:00
Eelco Dolstra
4213b8d8ec * Urgh. 2008-11-20 15:44:59 +00:00
Eelco Dolstra
eb86b6f5a5 2008-11-20 15:08:39 +00:00
Eelco Dolstra
3d2035ea86 * Blindly doing a replacement of occurences of $bindir (when running
the tests) is a bad idea when $bindir = /usr and some programs (like
  perl) live there.  Fortunately it doesn't seem to be needed anymore.
2008-11-20 15:08:34 +00:00
Eelco Dolstra
285d26374a * Don't set the prefix to /nix by default, rather use the Autoconf
default of /usr/local.  However, localstatedir and storedir are set
  to /nix/var/nix and /nix/store respectively unless they're
  explicitly overriden.
2008-11-20 14:14:35 +00:00
Eelco Dolstra
a55113411f * Nix daemon: reload the configuration file after forking (NIX-100). 2008-11-20 12:25:11 +00:00
Eelco Dolstra
c202523e53 2008-11-20 12:01:05 +00:00
Eelco Dolstra
aab530e971 * Primop builtins.storePath for declaring a store path as a
dependency.  `storePath /nix/store/bla' gives exactly the same
  result as `toPath /nix/store/bla', except that the former includes
  /nix/store/bla in the dependency context of the string.

  Useful in some generated Nix expressions like nix-push, which now
  finally does the right thing wrt distributed builds.  (Previously
  the path to be packed wasn't an explicit dependency, so it wouldn't
  be copied to the remote machine.)
2008-11-19 23:26:19 +00:00
Eelco Dolstra
60564410ef * Patterns. 2008-11-19 17:50:25 +00:00
Eelco Dolstra
2668a43388 2008-11-19 17:27:52 +00:00
Eelco Dolstra
63ccd72496 * Updated the manual. 2008-11-19 17:00:32 +00:00
Eelco Dolstra
e13da525a7 * Files in the info directory starting with "." are temporary files
and don't indicate path validity.
2008-11-19 16:27:07 +00:00
Eelco Dolstra
5d250ad1ea * nix-store --dump-db: be more streamy. 2008-11-19 16:26:34 +00:00
Eelco Dolstra
7509d70f9d * Documented some of the sharing mechanisms. 2008-11-19 15:20:46 +00:00
Eelco Dolstra
2369b122d1 * Install documentation in $(docdir) (i.e. share/doc/nix). 2008-11-19 13:19:09 +00:00
Eelco Dolstra
6c2c771af7 * Removed obsolete option. 2008-11-19 13:18:46 +00:00
Eelco Dolstra
07d3a38726 * Remove references to Berkeley DB, including most of the
troubleshooting section.  W00t.
2008-11-19 11:58:33 +00:00
Eelco Dolstra
f5325d292d * Release notes. 2008-11-19 10:59:36 +00:00
Eelco Dolstra
fa791116a3 * Get rid of nix-pack-closure / nix-unpack-closure, they're redundant. 2008-11-18 14:43:40 +00:00
Eelco Dolstra
3f4ed681c2 * Prevent zombies. Previous the SIGCHLD handler only reaped one
zombie at a time, so if multiple children died before the handler
  got to run, some of them would not be cleaned up.
2008-11-14 16:50:01 +00:00
Eelco Dolstra
6fedb7aa0f * Restore SIGPIPE to SIG_DFL when running the builder. This prevents
subtle and often hard-to-reproduce bugs where programs in pipes
  either barf with a "Broken pipe" message or not, depending on the
  exact timing conditions.  This particularly happened in GNU M4 (and
  Bison, which uses M4).
2008-11-14 15:46:45 +00:00
Eelco Dolstra
a519bb0635 * Some somewhat ad hoc mechanism to allow the build farm to monitor
build progress.
2008-11-12 11:08:27 +00:00
Eelco Dolstra
96598e7b06 * Pass the --no-build-output flag to the daemon. 2008-11-11 15:11:10 +00:00
Eelco Dolstra
4166b11a53 * Add /dev/pts to the default nix.conf. 2008-11-11 14:59:20 +00:00
Eelco Dolstra
2b7c839b4e * Typo. 2008-11-11 14:58:37 +00:00
Eelco Dolstra
709b55ee02 * Put the chroots under /nix/var/nix/chroots to reduce the risk of
disasters involving `rm -rf' on bind mounts.  Will try the
  definitive fix (per-process mounts, apparently possible via the
  CLONE_NEWNS flag in clone()) some other time.
2008-10-29 15:34:48 +00:00
Ludovic Courtès
c98ea254dc libstore: Always mount `/dev/pts' individually.
This fixes problems such as Tcl's PTY handling:

  ERROR: The system has no more ptys.  Ask your system administrator to
  create more.
2008-10-16 21:04:32 +00:00
Eelco Dolstra
9d6d50269b * Bug fix for building on some old installations (contributed by Pjotr). 2008-10-16 14:16:03 +00:00
Eelco Dolstra
fa61ee70ee * Fix `--from-profile'. 2008-09-18 09:08:54 +00:00
Eelco Dolstra
f32fef1b07 * GC option `--max-atime' that specifies an upper limit to the last
accessed time of paths that may be deleted.  Anything more recently
  used won't be deleted.  The time is specified in time_t,
  e.g. seconds since 1970-01-01 00:00:00 UTC; use `date +%s' to
  convert to time_t from the command line. 

  Example: to delete everything that hasn't been used in the last two
  months:

  $ nix-store --gc -v --max-atime $(date +%s -d "2 months ago")
2008-09-17 14:52:35 +00:00
Eelco Dolstra
4af2fdba6d * Typo. 2008-09-17 13:00:55 +00:00
Eelco Dolstra
c987061aa4 * Some refactoring. Better output with `-v' for --use-atime. 2008-09-17 12:54:07 +00:00
Eelco Dolstra
77afd97a99 * nix-store --gc / --delete: show how many store paths were deleted. 2008-09-17 12:53:33 +00:00
Eelco Dolstra
7ab68961e4 * Garbage collector: added an option `--use-atime' to delete paths in
order of ascending last access time.  This is useful in conjunction
  with --max-freed or --max-links to prefer deleting non-recently used
  garbage, which is good (especially in the build farm) since garbage
  may become live again.

  The code could easily be modified to accept other criteria for
  ordering garbage by changing the comparison operator used by the
  priority queue in collectGarbage().
2008-09-17 10:02:55 +00:00
Eelco Dolstra
2b2aa8a820 * Doh. 2008-09-08 11:02:15 +00:00
Eelco Dolstra
7933cdc6dc * When writing the user environment manifest, filter out non-string
attributes from the meta attribute.  Not doing so caused nix-env to
  barf on the "psi" package, which has a meta.function attribute,
  the textual serialisation of which causes a gigantic string to be
  produced --- so big that it causes nix-env to run out of memory.

  Note however that "meta" really only should contain strings.  
  meta.function should be passthru.function.
2008-09-02 09:21:38 +00:00
Eelco Dolstra
0f0dbe8c0c * Extend the ATerm suppressions to 64-bit. 2008-08-29 14:38:04 +00:00
Eelco Dolstra
311c222f47 2008-08-29 13:59:03 +00:00
Michael Raskin
2a01d06da6 Added nix-http-export.cgi to extra distributed scripts; so it can be installed from releases, not only from SVN. 2008-08-29 08:34:38 +00:00
Eelco Dolstra
7718b19389 * Explicitly set PWD to prevent problems with chroot builds. In
particular, dietlibc cannot figure out the cwd because the inode of
  the current directory doesn't appear in .. (because getdents returns
  the inode of the mount point).
2008-08-27 17:20:25 +00:00
Eelco Dolstra
9cc0da8453 * Create a /tmp with 1777 permission in the chroot. Some builders
need a writable /tmp (they don't respect $TMPDIR).
2008-08-27 16:03:03 +00:00
Eelco Dolstra
99dc3e613a * Require that __overrides is defined as a non-recursive attribute
(which means it can only be defined via "inherit"), otherwise we get
  scoping bugs, since __overrides can't be recursive (or at least, it
  would be hard).
2008-08-26 14:05:59 +00:00
Eelco Dolstra
d06be428f6 * Disable chroot builds for fixed-output derivations so that we don't
need /etc in the chroot (in particular, /etc/resolv.conf for
  fetchurl).  Not having /etc/resolv.conf in the chroot is a good
  thing, since we don't want normal derivations to download files.
2008-08-25 15:49:22 +00:00
Eelco Dolstra
abec1c0004 * Evaluate attributes in sorted order for better determinism. 2008-08-25 14:31:29 +00:00
Eelco Dolstra
c4f1c2114b * Minor simplification. 2008-08-25 14:15:56 +00:00
Eelco Dolstra
49829da8b4 * Doh. 2008-08-25 13:32:27 +00:00
Eelco Dolstra
b428adc267 * Strip off the `.nix' suffix from the attribute name for files in
~/.nix-defexpr,  otherwise the attribute cannot be selected with the
  `-A' option.  Useful if you want to stick a Nix expression directly
  in ~/.nix-defexpr.
2008-08-25 13:31:57 +00:00
Eelco Dolstra
cc826dc03e * Simplify the Valgrind suppressions using wildcards. 2008-08-22 14:32:29 +00:00
Eelco Dolstra
51e2dda58c * Some more ATerm Valgrind suppressions. 2008-08-19 12:46:43 +00:00
Michael Raskin
b7ff182b6e Fixing an obvious typo in override code. I do not know whether it works correctly after the change, but at least it ca nbe compiled now. 2008-08-14 22:01:43 +00:00
Eelco Dolstra
ca07f3e370 * Another experimental feature: a way to truly override attributes in
a rec.  This will be very useful to allow end-user customisation of
  all-packages.nix, for instance globally overriding GCC or some other
  dependency.  The // operator doesn't cut it: you could replace the
  "gcc" attribute, but all other attributes would continue to
  reference the original value due to the substitution semantics of
  rec.

  The syntax is a bit hacky but this is to allow backwards
  compatibility.
2008-08-14 16:59:37 +00:00
Eelco Dolstra
9279174dde * Added an experimental feature suggested by Andres: ellipses ("...")
in attribute set pattern matches.  This allows defining a function
  that takes *at least* the listed attributes, while ignoring
  additional attributes.  For instance,

    {stdenv, fetchurl, fuse, ...}:
    
    stdenv.mkDerivation {
      ...
    };
    
  defines a function that requires an attribute set that contains the 
  specified attributes but ignores others.  The main advantage is that
  we can then write in all-packages.nix

    aefs = import ../bla/aefs pkgs;

  instead of

    aefs = import ../bla/aefs {
      inherit stdenv fetchurl fuse;
    };

  This saves a lot of typing (not to mention not having to update
  all-packages.nix with purely mechanical changes).  It saves as much
  typing as the "args: with args;" style, but has the advantage that
  the function arguments are properly declared (not implicit in what
  the body of the "with" uses).
2008-08-14 14:00:44 +00:00
Eelco Dolstra
db4f4a8425 * Backward compatibility check to prevent nixos-rebuild from barfing
when upgrading Nix.
2008-08-14 13:02:19 +00:00
Eelco Dolstra
1b962fc720 * @-patterns as in Haskell. For instance, in a function definition
f = args @ {x, y, z}: ...;

  `args' refers to the argument as a whole, which is further
  pattern-matched against the attribute set pattern {x, y, z}.
2008-08-14 12:53:29 +00:00
Eelco Dolstra
e818838412 * "pattern" non-terminal. 2008-08-14 10:14:34 +00:00
Eelco Dolstra
efe4b690ae * Refactoring: combine functions that take an attribute set and
functions that take a single argument (plain lambdas) into one AST
  node (Function) that contains a Pattern node describing the
  arguments.  Current patterns are single lazy arguments (VarPat) and
  matching against an attribute set (AttrsPat).

  This refactoring allows other kinds of patterns to be added easily,
  such as Haskell-style @-patterns, or list pattern matching.
2008-08-14 10:04:22 +00:00
Eelco Dolstra
c03b729319 * Increase the sleep periods a bit to make the test less likely to
fail on slow machines.  Of course it would be better if this test
  wasn't timing dependent...
2008-08-14 09:26:30 +00:00
Eelco Dolstra
5664b6d7ba * Removed the "valid values" feature. Nobody uses it anyway. 2008-08-11 13:36:40 +00:00
Michael Raskin
b455c4c45c Updates to nix-reduce-build
Common code in local build package sources refactored out in a function; before building the real set of derivations needed is found (slightly slower for only one build strategy, but less garbage on output and better performance for multiple build strategies).

Now you have full choice of best-effort build regardless of method (substituters or actual build), using substituters, building only fixed derivations (should get you all the downloads) and local build without even trying substituters. 

Some minor fix in the help text about behavior with no package sources.
2008-08-06 19:43:53 +00:00
Eelco Dolstra
72f3ea7358 * Moved some stuff to the Nixpkgs manual.
* Updated the release notes.
2008-08-05 11:03:05 +00:00
Eelco Dolstra
98b07466fb * Better error checking of the data from the substituters. 2008-08-05 10:57:53 +00:00
Eelco Dolstra
339c142009 * Use optimistic profile locking for nix-env operations like `-i' and
`-u'.  Instead of acquiring an exclusive lock on the profile for the
  entire duration of the operation, we just perform the operation
  optimistically (without an exclusive lock), and check at the end
  whether the profile changed while we were busy (i.e., the symlink
  target changed).  If so, the operation is restarted.  Restarting is
  generally cheap, since the build results are still in the Nix store.
  Most of the time, only the user environment has to be rebuilt.
2008-08-04 16:21:45 +00:00
Eelco Dolstra
a87b5256e2 * Fix the tests. 2008-08-04 16:16:49 +00:00
Eelco Dolstra
001b3f06ec * `nix-env --set': support --dry-run. 2008-08-04 14:58:50 +00:00
Eelco Dolstra
7592f48c83 * nix-build: `--dry-run' flag. 2008-08-04 13:46:01 +00:00
Eelco Dolstra
a1d310b6b5 * `nix-store --realise': print what paths will be built/downloaded,
just like nix-env.
* `nix-store --realise': --dry-run option.
2008-08-04 13:44:46 +00:00
Eelco Dolstra
42043953c3 * Doh. 2008-08-04 13:15:47 +00:00
Eelco Dolstra
5adbb0aabe * build.cc: only use a substituter if it returns info for a path. 2008-08-04 13:15:35 +00:00
Eelco Dolstra
5b1052663a * Always show what paths we're going to build/download (as in
--dry-run).  Maybe there should be an option to turn this on/off?
2008-08-04 13:11:09 +00:00
Eelco Dolstra
c4f98941ed * nix-env --dry-run: show the total size of the substituter
downloads.
2008-08-04 12:29:04 +00:00
Eelco Dolstra
03427e76f1 * querySubstitutablePathInfo: work properly when run via the daemon.
* --dry-run: print the paths that we don't know how to build/substitute.
2008-08-04 11:44:50 +00:00
Michael Raskin
b3c26180e3 Updates to nix-reduce-build: only realize fixed derivations if user asks so, or only use substituters. Oh, and add possibility to use : for things like /etc/nixos/nixpkgs:-A:gnused 2008-08-02 16:43:25 +00:00
Eelco Dolstra
3c92ea399d * Make nix-env --dry-run print the paths to be substituted correctly
again.  (After the previous substituter mechanism refactoring I
  didn't update the code that obtains the references of substitutable
  paths.)  This required some refactoring: the substituter programs
  are now kept running and receive/respond to info requests via
  stdin/stdout.
2008-08-02 12:54:35 +00:00
Eelco Dolstra
fc691e1cbd * Print a better error message when a non-derivation attribute set is
coerced to a string.
2008-07-24 14:52:25 +00:00
Eelco Dolstra
096198d11f * A quick hack to make nix-prefetch-url support mirror:// URLs. It
requires that $NIXPKGS_ALL points at a Nixpkgs tree.
2008-07-23 16:02:58 +00:00
Eelco Dolstra
660244f65f * Make sure that copy-from-other-stores.pl is built. 2008-07-23 09:38:38 +00:00
Eelco Dolstra
e139d7fc68 * Fix the tests. 2008-07-18 20:03:12 +00:00
Eelco Dolstra
989176c56e * Allow read-only access to the store (e.g., non-root users on NixOS
can do operations like "nix-store -qR <path>" even without the Nix
  daemon).
2008-07-18 15:34:46 +00:00
Eelco Dolstra
8bc591a6f0 * Use the copy-from-other-stores substituter by default. Of course,
it only does something if $NIX_OTHER_STORES (not really a good
  name...) is set.
* Do globbing on the elements of $NIX_OTHER_STORES.  E.g. you could
  set it to /mnts/*/nix or something.
* Install substituters in libexec/nix/substituters.
2008-07-18 13:05:10 +00:00
Eelco Dolstra
15f39aba8c * Quick prototype of a substituter that copies paths from other Nix
stores (typically remote Nix stores mounted via e.g. NFS, or the Nix
  store on the NixOS installation CD).  Example use:

  $ sshfs foo@example.org:/ /mnt
  $ NIX_OTHER_STORES=/mnt/nix \
    NIX_SUBSTITUTERS=.../copy-from-other-stores.pl \
    nix-env -i foo

  This will be especially useful for the installation CD since it
  doesn't require a manifest for the CD contents.
2008-07-12 18:58:24 +00:00
Eelco Dolstra
7cd88b1dec * Generalised the dependencyClosure primop to builtins.genericClosure,
which is hopefully more useful.
* New primops: length, mul, div.
2008-07-11 13:29:04 +00:00
Eelco Dolstra
d567baabbd * Export the nix-env derivation name parsing and version comparison
logic through the `parseDrvName' and `compareVersions' primops.
  This will allow expressions to easily check whether some dependency
  is a specific needed version or falls in some version range.  See
  tests/lang/eval-okay-versions.nix for examples.
2008-07-01 10:10:32 +00:00
Eelco Dolstra
b3b0b2a29e * `make ext-clean': remove the bzip2 build. 2008-06-23 13:52:28 +00:00
Eelco Dolstra
6c8641a542 2008-06-18 19:17:05 +00:00
Eelco Dolstra
5af84139a8 * --max-freed: support values >= 4 GB. 2008-06-18 15:20:33 +00:00
Eelco Dolstra
d3aa183beb * Garbage collector: option `--max-freed' to stop after at least N
bytes have been freed, `--max-links' to stop when the Nix store
  directory has fewer than N hard links (the latter being important
  for very large Nix stores on filesystems with a 32000 subdirectories
  limit).
2008-06-18 14:20:16 +00:00
Eelco Dolstra
a8f3b02092 * `nix-store --optimise': handle files with >= 32000 hard links.
(There can easily be more than 32000 occurrences of the empty file.)
2008-06-18 14:13:00 +00:00
Eelco Dolstra
a72709afd8 * Some refactoring: put the GC options / results in separate structs.
* The garbage collector now also prints the number of blocks freed.
2008-06-18 09:34:17 +00:00
Eelco Dolstra
934c58aa38 * Use bzip2 1.0.5. 2008-06-17 08:12:12 +00:00
Eelco Dolstra
ee8f15930d * Test instrumentation. 2008-06-15 15:10:03 +00:00
Eelco Dolstra
f351834f77 * nix-worker: clean up the temporary root for the worker processes
in /nix/var/nix/temproots.
2008-06-14 16:03:02 +00:00
Eelco Dolstra
94fd46fa1c * Note. 2008-06-14 16:02:31 +00:00
Michael Raskin
955b8841cd Also trying to build derivers in case we cannot get substituters 2008-06-14 08:48:40 +00:00
Michael Raskin
18e27629d3 Added local best-effort builds (i.e. one failure does not ruin all packages you would like to see built) 2008-06-14 08:30:35 +00:00
Eelco Dolstra
826b271d9a * Garbage collector: don't do a complete topological sort of the Nix
store under the reference relation, since that means that the
  garbage collector will need a long time to start deleting paths.
  Instead just delete the referrers of a path first.
2008-06-13 18:25:24 +00:00
Eelco Dolstra
30c9f909b2 * Print some progress info during the early GC stages. 2008-06-13 17:21:20 +00:00
Michael Raskin
194c66eeeb Stupid error in script 2008-06-13 14:34:19 +00:00
Michael Raskin
f903d86740 OK, I will believe that fix does no worse.. 2008-06-13 13:53:14 +00:00
Michael Raskin
ce85b55cf0 Updated help text 2008-06-12 17:45:38 +00:00
Michael Raskin
4532e4b90d Added verbosity for nix-reduce-build 2008-06-12 16:26:53 +00:00
Eelco Dolstra
2818b7cee6 * Updated some URLs. 2008-06-11 15:39:38 +00:00
Eelco Dolstra
997b95a4af * Fixed compatibility with old versions of "wc" that print whitespace
before the count.
2008-06-10 10:08:15 +00:00
Eelco Dolstra
b0e92f6d47 * Merged the no-bdb branch (-r10900:HEAD
https://svn.nixos.org/repos/nix/nix/branches/no-bdb).
2008-06-09 13:52:45 +00:00
Eelco Dolstra
4ed01ed791 * Updated some URLs (did this a long time ago but forgot to
commit...).
2008-06-09 13:42:13 +00:00
Sander van der Burg
c41a3ec3a9 First attempt to update Nix SDF grammar to match the actual bison grammar 2008-06-04 14:36:46 +00:00
Eelco Dolstra
bd955e15e1 * GCC 4.3.0 (Fedora 9) compatibility fixes. Reported by Gour and
Armijn Hemel.
2008-05-21 11:17:31 +00:00
Michael Raskin
9819bb20da Added support for file:// archive (.nar.gz) repositories to nix-reduce-build. /tmp/nix-export created by nix-http-export.cgi is OK. 2008-05-11 15:54:30 +00:00
Michael Raskin
b4bc8b7616 --proxy=proxy:3128 2008-05-07 14:18:28 +00:00
Michael Raskin
b1e321d6ce Added http alternative transport for nix-reduce-build 2008-04-29 04:03:54 +00:00
Eelco Dolstra
658816ddc9 * Make really sure that we use bash. The line
NEED_PROG(shell, bash)

  actually uses the content of $shell if set, which often points at
  /bin/sh.
2008-04-10 09:54:23 +00:00
Eelco Dolstra
72034ab35d * sockaddr_un doesn't allow path names of more than 108 characters.
This isn't usually a problem, except that it causes tests to fail
  when performed in a directory with a very long path name.  So chdir
  to the socket directory and use a relative path name.
2008-04-09 05:57:01 +00:00
Eelco Dolstra
f8985d195e * Fix for NIX-101 (should use an absolute path for call to nix-hash). 2008-03-28 17:52:33 +00:00
Eelco Dolstra
329025253d * Use /tmp/nix-build-<drvpath>-<counter> instead of
/tmp/nix-<pid>-<counter> for temporary build directories.  This
  increases purity a bit: many packages store the temporary build path
  in their output, causing (generally unimportant) binary differences.
2008-03-27 13:45:17 +00:00
Eelco Dolstra
5bb08db55b * Updated URL. 2008-03-21 14:57:16 +00:00
Eelco Dolstra
98968fbb63 * Disable the don't-run-as-root sanity check because it breaks RPM
builds (which are done as root...).
2008-03-20 18:15:20 +00:00
Eelco Dolstra
2f1e2cf632 * Note that the SDF grammar isn't used. 2008-03-20 14:59:33 +00:00
Eelco Dolstra
f106868110 * Cleanup. 2008-03-20 10:16:36 +00:00
Eelco Dolstra
f789ea1d09 * A transaction is unnecessary since the path cannot be
garbage-collected (it's a temporary root).
2008-03-01 21:05:33 +00:00
Eelco Dolstra
d7caac3e81 * Don't install nix-reduce-build by default yet please, I first want
to understand better what it does...
2008-02-28 21:27:47 +00:00
Michael Raskin
11d512e7a8 Added nix-reduce-build. You point it to some path you want to build and it fetches whatever it can from specified computers via nix-copy-closure. NOTE: You do want to set up RSA keys or ssh-agent or something... You really do want it. It will run separate ssh instances insane number of times. 2008-02-27 21:26:47 +00:00
Eelco Dolstra
0a84137c45 * checkVarDefs: don't check in closed terms, which don't have
undefined variables by definition.  This matters for the
  implementation of "with", which does a call to checkVarDefs to see
  if the body of the with has no undefined variables.  (It can't be
  checked at parse time because you don't know which variables are in
  the "with" attribute set.)  If we check closed terms, then we check
  not just the with body but also the substituted terms, which are
  typically very large.  This is the cause of the poor nix-env
  performance on Nixpkgs lately.  It didn't happen earlier because
  "with" wasn't used very often in the past.

  This fix improves nix-env performance roughly 60x on current Nixpkgs.
  nix-env -qa is down from 29.3s to 0.5s on my laptop, and nix-env -qa
  --out-path is down from 229s to 3.39s.  Not bad for a 1-line fix :-)
2008-02-21 12:01:24 +00:00
Eelco Dolstra
0ed89c569f * Fix the parsing of
''
      '${foo}'
    ''
    
  where the antiquote should work as expected, instead of giving the
  string "'${foo}'".
2008-02-05 13:38:07 +00:00
Eelco Dolstra
4066f450c2 * Doh. 2008-02-05 13:35:49 +00:00
Eelco Dolstra
e7bdde981f * Regression test. 2008-02-05 13:25:18 +00:00
Eelco Dolstra
66c51dc215 * nix-store --dump-db / --load-db to dump/load the Nix DB.
* nix-store --register-validity: option to supply the content hash of
  each path.
* Removed compatibility with Nix <= 0.7 stores.
2008-01-29 18:17:36 +00:00
Michael Raskin
5b5a3af983 Probably fixed __exprToString 2008-01-20 20:44:03 +00:00
Michael Raskin
5eb5c23447 Fixed exportBuildReferenceGraph 2008-01-15 04:32:08 +00:00
Eelco Dolstra
7d0f6aed59 * New primop `unsafeDiscardStringContext' to get rid of string
contexts.  Needed to prevent unnecessary dependencies when building
  the NixOS manual.
2008-01-04 14:22:49 +00:00
Eelco Dolstra
895c953817 * Bumped the version number to 0.12. 2007-12-31 17:53:59 +00:00
Eelco Dolstra
d4117859d6 2007-12-31 16:57:12 +00:00
Eelco Dolstra
e0ca671491 * More documentation. 2007-12-31 02:52:17 +00:00
Eelco Dolstra
6bdecfacbb * Documented a bunch of nix-store commands. 2007-12-31 01:52:57 +00:00
Eelco Dolstra
454f571f87 2007-12-31 01:22:09 +00:00
Eelco Dolstra
4c82983010 2007-12-31 01:17:25 +00:00
Eelco Dolstra
f60aa2aa21 2007-12-31 00:34:44 +00:00
Eelco Dolstra
dedd62dd0c * More release notes. 2007-12-31 00:08:09 +00:00
Eelco Dolstra
b5ddcf58ad * Fix the hashDerivationModulo test. I should really investigate
*why* the test failed...
2007-12-30 23:59:10 +00:00
Eelco Dolstra
59707975a3 * Documented indented string literals.
* Release notes.
2007-12-30 23:36:09 +00:00
Eelco Dolstra
de012e76e2 * Don't use "store expression", it's obsolete. 2007-12-30 23:35:45 +00:00
Michael Raskin
2196cb67c5 Added a way to include derivation with its outputs and dependencies - exportBuildReferenceGraph 2007-12-30 09:30:56 +00:00
Eelco Dolstra
df303666bc * Use strsignal if available to give better error messages for
builders that fail due to a signal.
2007-12-14 14:49:35 +00:00
Eelco Dolstra
1e90b4189d * Another insane Mac OS X 10.5 compatibility hack. 2007-12-14 14:15:30 +00:00
Eelco Dolstra
485d71c54a * Mac OS X 10.5 compatibility: echo -n foo' suddenly prints -n foo'
instead of `foo' without a newline (with /bin/sh, not /bin/bash,
  even though /bin/sh is also bash...).  So use printf instead.
2007-12-14 14:08:09 +00:00
Eelco Dolstra
30e4653783 * Mac OS X 10.5 compatibility. 2007-12-13 22:06:19 +00:00
Marc Weber
4ff1335b2e small udpate 2007-12-12 02:12:58 +00:00
Michael Raskin
3a2833daff corrected --help message for nix-store a bit 2007-12-10 22:16:47 +00:00
Marc Weber
764b0115d5 Very basic nix vim syntax highlighting 2007-12-10 21:17:29 +00:00
Eelco Dolstra
b42ef9c054 * Syntax to escape '', ${. 2007-12-06 10:20:58 +00:00
Eelco Dolstra
d4950f207f * component -> package. 2007-12-04 11:42:58 +00:00
Eelco Dolstra
6d6c68c0d2 * Added a new kind of multi-line string literal delimited by two
single quotes.  Example (from NixOS):

    job = ''
      start on network-interfaces

      start script

        rm -f /var/run/opengl-driver
        ${if videoDriver == "nvidia"        
          then "ln -sf ${nvidiaDrivers} /var/run/opengl-driver"
          else if cfg.driSupport
          then "ln -sf ${mesa} /var/run/opengl-driver"
          else ""
        }

        rm -f /var/log/slim.log

      end script
    '';

  This style has two big advantages:

  - \, ' and " aren't special, only '' and ${.  So you get a lot less
    escaping in shell scripts / configuration files in Nixpkgs/NixOS.
    The delimiter '' is rare in scripts (and can usually be written as
    "").  ${ is also fairly rare.

    Other delimiters such as <<...>>, {{...}} and <|...|> were also
    considered but this one appears to have the fewest drawbacks
    (thanks Martin).

  - Indentation is intelligently stripped so that multi-line strings
    can follow the nesting structure of the containing Nix
    expression.  E.g. in the example above 6 spaces are stripped from
    the start of each line.  This prevents unnecessary indentation in
    generated files (which sometimes even breaks things).

  See tests/lang/eval-okay-ind-string.nix for some examples.
2007-11-30 16:48:45 +00:00
Eelco Dolstra
633518628f * nix-env -e: support uninstalling by path, so that one can say
$ nix-env -e $(which firefox)

  or

    $ nix-env -e /nix/store/nywzlygrkfcgz7dfmhm5xixlx1l0m60v-pan-0.132

* nix-env -i: if an argument contains a slash anywhere, treat it as a
  path and follow it through symlinks into the Nix store.  This allows
  things like

    $ nix-build -A firefox
    $ nix-env -i ./result

* nix-env -q/-i/-e: don't complain when the `*' selector doesn't match
  anything.  In particular, `nix-env -q \*' doesn't fail anymore on an
  empty profile.
2007-11-29 16:18:24 +00:00
Eelco Dolstra
12d0a1eb75 * Troubleshooting entry about running out of locks. 2007-11-29 14:15:33 +00:00
Eelco Dolstra
06f95dd07c * New primop `readFile' to get the contents of a file as a string. 2007-11-21 13:49:59 +00:00
Eelco Dolstra
c370755583 * Flag `--no-build-hook' to disable distributed builds.
* queryDeriver in daemon mode: don't barf if the other side returns an
  empty string (which means there is no deriver).
2007-11-16 16:15:26 +00:00
Eelco Dolstra
c05783ad67 * nix-store --import: add a flag --require-signature. 2007-11-16 16:10:27 +00:00
Eelco Dolstra
6784b14241 * nix-build: pass --argstr to nix-instantiate. 2007-11-15 16:52:40 +00:00
Eelco Dolstra
ca210d2a58 * Doh! 2007-11-15 15:33:30 +00:00
Eelco Dolstra
149e273023 * Don't need gc.hh. 2007-11-15 15:07:27 +00:00
Eelco Dolstra
bfec245efa * Add build-remote.pl to the Nix distribution. 2007-11-15 14:28:08 +00:00
Michael Raskin
6fc60e2060 Added possibility to specify garbage collection levels for store paths; so packages can share intermediate results of compilation and GC will collect it automatically while never touching tarballs, for example. 2007-11-15 03:47:12 +00:00
Eelco Dolstra
5b74a59570 * nix-prefetch-url: don't fail if /tmp/nix-prefetch-url-<pid> exists,
instead use a counter just like we do for temporary build
  directories.
2007-11-05 18:12:29 +00:00
Eelco Dolstra
5f8a203b55 * A rule to make a PDF version of the manual. 2007-11-01 14:42:44 +00:00
Eelco Dolstra
1511aa11ce * Documented some of the more obscure derivation attributes (including
fixed-output derivations).
2007-11-01 13:28:33 +00:00
Eelco Dolstra
fa44e401a8 * Documented multi-user Nix. 2007-10-31 18:01:56 +00:00
Eelco Dolstra
e007b50eb7 2007-10-29 22:16:36 +00:00
Eelco Dolstra
bfea7b1f35 * Make the --prebuilt-only' / -b' option work not just for queries
but installations/upgrades as well.  So `nix-env -ub \*' will
  upgrade only those packages for which a substitute is available (or
  to be precise, it will upgrade each package to the highest version
  for which a substitute is available).
2007-10-29 14:31:45 +00:00
Eelco Dolstra
0b95603595 * Depend on bash instead of sh (since we use a few bashisms). 2007-10-29 10:46:45 +00:00
Eelco Dolstra
42d80d1170 * On FreeBSD, sys/mount.h needs sys/param.h. 2007-10-29 10:03:07 +00:00
Eelco Dolstra
d91cd30563 * Detect whether chroot / bind-mount support is available. 2007-10-27 16:51:55 +00:00
Eelco Dolstra
dc6f373842 * Delete the chroot directory automatically.
* Removed some debug messages.
2007-10-27 16:06:38 +00:00
Eelco Dolstra
9397cd30c8 * Support for doing builds in a chroot under Linux. The builder is
executed in a chroot that contains just the Nix store, the temporary
  build directory, and a configurable set of additional directories
  (/dev and /proc by default).  This allows a bit more purity
  enforcement: hidden build-time dependencies on directories such as
  /usr or /nix/var/nix/profiles are no longer possible.  As an added
  benefit, accidental network downloads (cf. NIXPKGS-52) are prevented
  as well (because files such as /etc/resolv.conf are not available in
  the chroot).

  However the usefulness of chroots is diminished by the fact that
  many builders depend on /bin/sh, so you need /bin in the list of
  additional directories.  (And then on non-NixOS you need /lib as
  well...)
2007-10-27 00:46:59 +00:00
Eelco Dolstra
0b4ed64d29 * "trace" primop: write the trace to standard error. 2007-10-26 18:25:50 +00:00
Eelco Dolstra
cd08fb3fde 2007-10-24 13:54:06 +00:00
Eelco Dolstra
d423968ba1 * Improved introduction (actually copied mostly from the homepage). 2007-10-23 16:34:04 +00:00
Eelco Dolstra
612b3e8fa3 * Document the new primops in Nix 0.11. 2007-10-22 15:28:32 +00:00
Eelco Dolstra
35ac16e75e * Move list of built-in functions to a separate file. 2007-10-22 12:58:28 +00:00
Eelco Dolstra
1db187ff69 2007-10-22 12:46:15 +00:00
Eelco Dolstra
f90d85107e 2007-10-22 12:05:30 +00:00
Eelco Dolstra
f8ed2e64a5 2007-10-22 12:05:18 +00:00
Marc Weber
f529a3be8a Added comment telling about setup-hook and propagatedBuildInputs 2007-10-22 01:10:19 +00:00
Eelco Dolstra
14e47e9c2c * Doh. 2007-10-10 14:58:00 +00:00
Eelco Dolstra
d04291cfab * Doh! Don't change the permissions on /nix/store. 2007-10-10 13:52:38 +00:00
Eelco Dolstra
315183f194 * nix-store --optimise: flag "--dry-run" to just query what the disk
savings would be.
2007-10-10 13:43:04 +00:00
Eelco Dolstra
a8629de827 * New command `nix-store --optimise' to reduce Nix store disk space
usage by finding identical files in the store and hard-linking them
  to each other.  It typically reduces the size of the store by
  something like 25-35%.  This is what the optimise-store.pl script
  did, but the new command is faster and more correct (it's safe wrt
  garbage collection and concurrent builds).
2007-10-09 22:14:27 +00:00
Eelco Dolstra
27a0662828 * listToAttrs: the list now should consist of {name, value} attribute
sets instead of {attr, value}.  "name" is better than "attr" because
  the *combination* of the two forms the attribute.
2007-10-09 12:51:25 +00:00
Eelco Dolstra
8a9fe6c11c * Manpage for nix-copy-closure. 2007-09-19 14:01:41 +00:00
Eelco Dolstra
27f57c9018 * Ignore dangling symlinks in ~/.nix-defexpr. 2007-09-18 14:01:14 +00:00
Eelco Dolstra
f3441e6122 * Pass various options to the worker so that flags like -K or -j work
in multi-user Nix (NIX-72).
* Client/worker: exchange a protocol version number for future
  compatibility.
2007-09-18 09:11:20 +00:00
Eelco Dolstra
26f981c2e5 * Remove garbage. 2007-09-18 08:26:55 +00:00
Eelco Dolstra
c8ea8a09b8 * nix-env -qa: make the "-A" flag do the expected thing, namely follow
the given attribute path (just as -A does with other option)
  (NIX-83).  So you can now say

  $ nix-env -qa -A nixpkgs_unstable.gnome \*
  atk-1.12.4
  esound-0.2.36
  ...

  to see the packages in the "gnome" attribute in Nixpkgs.

  To *print* the attribute path, you should now use "--attr-path" /
  "-P" (running out of letters...).
2007-09-17 19:24:07 +00:00
Eelco Dolstra
055608227f * nix-env: allow ~/.nix-defexpr to be a directory. If it is, then the
Nix expressions in that directory are combined into an attribute set
  {file1 = import file1; file2 = import file2; ...}, i.e. each Nix
  expression is an attribute with the file name as the attribute
  name.  Also recurses into directories.

* nix-env: removed the "--import" (-I) option which set the
  ~/.nix-defexpr symlink.

* nix-channel: don't use "nix-env --import", instead symlink
  ~/.nix-defexpr/channels.  So finally nix-channel --update doesn't
  override any default Nix expressions but combines with them.

  This means that you can have (say) a local Nixpkgs SVN tree and use
  it as a default for nix-env:

  $ ln -s .../path-to-nixpkgs-tree ~/.nix-defexpr/nixpkgs_svn

  and be subscribed to channels (including Nixpkgs) at the same time.
  (If there is any ambiguity, the -A flag can be used to
  disambiguate, e.g. "nix-env -i -A nixpkgs_svn.pan".)
2007-09-17 16:08:24 +00:00
Eelco Dolstra
3339f85447 * Test the impureEnvVars feature. 2007-09-11 13:32:04 +00:00
Eelco Dolstra
9441550acb * nix-push / generate-patches: bzip the manifest. 2007-09-04 15:38:09 +00:00
Marc Weber
7b20c0ed4b explanation what happens when passing true / false and null values to derivation builders added 2007-09-02 10:36:59 +00:00
Eelco Dolstra
0d65fc08e2 * Create the Nix daemon socket in a separate directory
(/nix/var/nix/daemon-socket).  This allows access to the Nix daemon
  to be restricted by setting the mode/ownership on that directory as
  desired, e.g.

    $ chmod 770 /nix/var/nix/daemon-socket
    $ chown root.wheel /nix/var/nix/daemon-socket

  to allow only users in the wheel group to use Nix.

  Setting the ownership on a socket is much trickier, since the socket
  must be deleted and recreated every time the daemon is started
  (which would require additional Nix configuration file directives to
  specify the mode/ownership, and wouldn't support arbitrary ACLs),
  some BSD variants appear to ignore permissions on sockets, and it's
  not clear whether the umask is respected on every platform when
  creating sockets.
2007-08-30 09:50:44 +00:00
Eelco Dolstra
cb1c1004cd * When there are multiple substituters, make sure to release the
lock on the output path after trying each.  Otherwise the
  pathIsLockedByMe() test gets confused.
2007-08-28 16:22:08 +00:00
Eelco Dolstra
c970b28ba0 * Fix a race condition with parallel builds where multiple
fixed-output derivations or substitutions try to build the same
  store path at the same time.  Locking generally catches this, but
  not between multiple goals in the same process.  This happened
  especially often (actually, only) in the build farm with fetchurl
  downloads of the same file being executed on multiple machines and
  then copied back to the main machine where they would clobber each
  other (NIXBF-13).

  Solution: if a goal notices that the output path is already locked,
  then go to sleep until another goal finishes (hopefully the one
  locking the path) and try again.
2007-08-28 11:36:17 +00:00
Eelco Dolstra
bc0429b1cd * Doh! Broken test. 2007-08-28 11:31:44 +00:00
Eelco Dolstra
e0d7e47862 * PathLocks::lockPaths: don't allow reacquiring a lock we already
hold.
2007-08-28 09:39:03 +00:00
Eelco Dolstra
455a7b9577 * Test case to show that parallel builds of different fixed-output
derivations that produce the same output path don't work properly
  wrt locking.  This happens a lot in the build farm when fetchurl
  derivations downloading the same file on different platforms are
  executed in parallel and then copied back to the main machine.
2007-08-28 09:21:47 +00:00
Eelco Dolstra
7d5836b34d * nix-channel: supports users who don't have write permission to the
manifests directory.  In that case, we don't do a nix-pull, so the
  user gets pure source deployment.

  The directory /nix/var/nix/gcroots/per-user/$USER should be
  writable.  (It's created automatically if
  /nix/var/nix/gcroots/per-user is writable, e.g. if it has 1777
  permission.)
2007-08-22 14:52:22 +00:00
Marc Weber
2629998e91 primop functions listToAttrs (+test), __isAttrs, __trace added
new configuration style proposal in lib/default-unstable.nix
2007-08-18 22:12:00 +00:00
Eelco Dolstra
dbc0170ed9 * Show errors in nix-prefetch-url. 2007-08-15 09:24:06 +00:00
Eelco Dolstra
5c793ad03e * Hopefully this fixes the test on FreeBSD. 2007-08-14 13:43:51 +00:00
Eelco Dolstra
ffa1c61cd5 * Fix the tests. 2007-08-14 13:15:59 +00:00
Eelco Dolstra
a7e1a51fdf * A test for the nix-worker. 2007-08-13 14:56:40 +00:00
Eelco Dolstra
550ba9ebb4 * Fix the tests. 2007-08-13 13:15:02 +00:00
Eelco Dolstra
3757ee589f * Bump the Nix database schema version number; delete the substitutes
table.
2007-08-13 11:37:39 +00:00
Eelco Dolstra
59afc1a15c * Backwards compatibility. 2007-08-13 11:15:13 +00:00
Eelco Dolstra
9e975458b4 * Get rid of the substitutes database table (NIX-47). Instead, if we
need any info on substitutable paths, we just call the substituters
  (such as download-using-manifests.pl) directly.  This means that
  it's no longer necessary for nix-pull to register substitutes or for
  nix-channel to clear them, which makes those operations much faster
  (NIX-95).  Also, we don't have to worry about keeping nix-pull
  manifests (in /nix/var/nix/manifests) and the database in sync with
  each other.

  The downside is that there is some overhead in calling an external
  program to get the substitutes info.  For instance, "nix-env -qas"
  takes a bit longer.

  Abolishing the substitutes table also makes the logic in
  local-store.cc simpler, as we don't need to store info for invalid
  paths.  On the downside, you cannot do things like "nix-store -qR"
  on a substitutable but invalid path (but nobody did that anyway).

* Never catch interrupts (the Interrupted exception).
2007-08-12 00:29:28 +00:00
Eelco Dolstra
4695f4edd6 * nix-pull: support bzipped manifests: when doing a nix-pull on $url,
try $url.bz2 first.
2007-08-10 01:42:00 +00:00
Eelco Dolstra
911bc01454 * Enable nix-prefetch-url caching in nix-channel. 2007-08-10 00:28:44 +00:00
Eelco Dolstra
5e52df18fe * Don't rely on /dev/stdin. 2007-08-10 00:22:21 +00:00
Eelco Dolstra
c5e934dcc9 * nix-pull: using nix-prefetch-url (so that we get caching for free),
and store the manifests in the Nix store.  (So now
  /nix/var/nix/manifests/ just contains symlinks to the store and is
  searched for GC roots.)
2007-08-09 23:52:53 +00:00
Eelco Dolstra
f881f7a017 * nix-prefetch-url: support caching. If the environment variable
NIX_DOWNLOAD_CACHE is set, then nix-prefetch-url will store the hash
  and timestamp of downloaded files in the directory
  $NIX_DOWNLOAD_CACHE.  This allows it to figure out if the file is
  still in the Nix store.
2007-08-09 23:16:44 +00:00
Eelco Dolstra
ef240bc0d5 * Use the new patched version of the aterm library. 2007-08-07 23:40:39 +00:00
Eelco Dolstra
d71cc503a6 * Don't allocate input files on the stack. 2007-08-07 15:00:13 +00:00
Eelco Dolstra
4cad125e08 * Optionally warn about packages that give an assertion failure. 2007-08-06 16:08:09 +00:00
Eelco Dolstra
6da6fbfbe9 * Properly keep packages during upgrades. 2007-07-05 20:33:04 +00:00
Eelco Dolstra
6d1a1191b0 * Support queryDeriver() in multi-user installations. 2007-06-12 16:53:44 +00:00
Eelco Dolstra
9d9e1c5c41 * Distribute bzip2 1.0.4. 2007-06-11 13:59:07 +00:00
Eelco Dolstra
9bff7ad728 * Check against creation of GC roots in the store. Those roots don't
work, because findRoots() stops when it encounters a symlink to the
  store.  And of course the store is supposed to be read-only.
2007-06-11 11:36:22 +00:00
Eelco Dolstra
f3ebd03bb1 * Remove debug statement. 2007-06-04 12:03:33 +00:00
Armijn Hemel
40b6f06f09 change default NIX_HASH_ALGO 2007-06-02 15:03:54 +00:00
Eelco Dolstra
b47da5ea21 2007-05-16 22:07:39 +00:00
Eelco Dolstra
bddc83a148 * New builtin function "isFunction". You're not supposed to use it
;-)
* Channels: fix channels that are plain lists of derivations (like
  strategoxt-unstable) instead  of functions (like nixpkgs-unstable).
  This fixes the error message "error: the left-hand side of the
  function call is neither a function nor a primop (built-in
  operation) but a list".
2007-05-16 16:17:04 +00:00
Eelco Dolstra
ca00aa1171 * Allow empty argument lists in function definitions (e.g., `{}:
bla').  Also allow trailing commas (`{x, y,}: ...') as a unintented
  consequence.  Hopefully the reduce/reduce conflict won't cause any
  problems.
2007-05-15 12:14:37 +00:00
Eelco Dolstra
7046c35843 * Typo (reported by Marc Weber). 2007-05-14 12:16:41 +00:00
Eelco Dolstra
e5da9c8803 * Create the database directory if it doesn't exist. 2007-05-07 16:59:19 +00:00
Eelco Dolstra
30beeb27a9 * Set the right priorities when recovering from a directory
collision.
2007-05-02 19:38:02 +00:00
Eelco Dolstra
34d4c9388b 2007-05-02 16:06:04 +00:00
Eelco Dolstra
93aefd9fc0 * Give unpacked channels more sensible names than 0, 1, ... They now
get the basename of the channel URL (e.g., nixpkgs-unstable).  The
  top-level Nix expression of the channel is now an attribute set, the
  attributes of which are the individual channels (e.g.,
  {nixpkgs_unstable = ...; strategoxt_unstable = ...}).  This makes
  attribute paths ("nix-env -qaA" and "nix-env -iA") more sensible,
  e.g., "nix-env -iA nixpkgs_unstable.subversion".
2007-05-01 23:16:38 +00:00
Eelco Dolstra
a9d15d4f43 * nix-env -i: instead of breaking package ties by version, break them
by priority and version install.  That is, if there are multiple
  packages with the same name, then pick the package with the highest
  priority, and only use the version if there are multiple packages
  with the same priority.

  This makes it possible to mark specific versions/variant in Nixpkgs
  more or less desirable than others.  A typical example would be a
  beta version of some package (e.g., "gcc-4.2.0rc1") which should not
  be installed even though it is the highest version, except when it
  is explicitly selected (e.g., "nix-env -i gcc-4.2.0rc1").

* Idem for nix-env -u, only the semantics are a bit trickier since we
  also need to take into account the priority of the currently
  installed package (we never upgrade to a lower priority, unless
  --always is given).
2007-05-01 20:33:18 +00:00
Eelco Dolstra
cbfac2fdcc * Set a terminate() handler to ensure that we leave the BDB
environment cleanly even when an exception is thrown from a
  destructor.  We still crash, but we don't take all other Nix
  processes with us.
2007-05-01 15:16:17 +00:00
Eelco Dolstra
644946feed * Make --verify more interruptable. 2007-05-01 13:21:05 +00:00
Eelco Dolstra
bd1f66453a * `nix-env -q --xml --meta' to show all meta attributes. 2007-05-01 11:30:52 +00:00
Eelco Dolstra
e20f0da22c * Doh. 2007-04-30 18:41:27 +00:00
Eelco Dolstra
89c1d2b202 * Package flag "keep" that prevents a package from being removed from
a user environment by an install or upgrade action.  This is
  particularly useful if you have a version installed that you don't
  want to upgrade (e.g., because the newer versions are broken).
  Example:

    $ nix-env -u zapping --dry-run
    (dry run; not doing anything)
    upgrading `zapping-0.9.6' to `zapping-0.10cvs6'

    $ nix-env --set-flag keep true zapping

    $ nix-env -u zapping --dry-run
    (dry run; not doing anything)

  However, "-e" will still uninstall the package.  (Maybe we should
  require the keep flag to be explicitly set to false before it can be
  uninstalled.)
2007-04-27 23:48:14 +00:00
Eelco Dolstra
a46db5d013 * Package conflict resolution through priority levels. If there is a
user environment collission between two packages due to overlapping
  file names, then a package with a higher priority will overwrite the
  symlinks of a package with a lower priority.  E.g.,

    $ nix-env --set-flag priority 5 gcc
    $ nix-env --set-flag priority 10 binutils

  gives gcc a higher priority than binutils (higher number = lower
  priority).
2007-04-27 23:28:44 +00:00
Eelco Dolstra
3d05166086 * Allow conflicting packages to be kept in a user environment, and
allow switching between them (NIX-80).

  Example: two versions of Pan:

    $ nix-env -q pan
    pan-0.128
    pan-0.14.2.91

    $ readlink $(which pan)
    /nix/store/l38jrbilw269drpjkx7kinhrxj6fjh59-pan-0.14.2.91/bin/pan

  At most one of them can be active any given time.  Assuming than
  0.14.2.91 is active, you can active 0.128 as follows:

    $ nix-env --set-flag active false pan-0.14.2.91
    $ nix-env --set-flag active true pan-0.128

    $ readlink $(which pan)
    /nix/store/nziqwnlzy7xl385kglxhg75pfl5i936n-pan-0.128/bin/pan

  More flags to follow.
2007-04-27 22:40:59 +00:00
Eelco Dolstra
b7f0f65c19 * nix-env -q now has a flag --prebuilt-only (-b<) that causes nix-env
to show only those derivations whose output is already in the Nix
  store or that can be substituted (i.e., downloaded from somewhere).
  In other words, it shows the packages that can be installed “quickly”,
  i.e., don’t need to be built from source.
2007-04-26 14:20:31 +00:00
Eelco Dolstra
5dc05b76ab * Updated dependency information. 2007-04-16 16:08:44 +00:00
Eelco Dolstra
5f2492eaec * New primop "throw <string>" to throw an error. This is like abort,
only thrown errors are caught by the top-level derivation evaluation
  in nix-env -qa / -i.
2007-04-16 15:03:19 +00:00
Eelco Dolstra
0a8eeea9d8 * Remove a warning. 2007-04-16 14:45:25 +00:00
Eelco Dolstra
2716f9bc5f * It seems that svnversion prints a carriage return on Cygwin, so we
get a invalid #define VERSION.  Use "svnversion -n" to leave out the
  newline.  Fix provided by Marc Weber.
2007-04-16 12:00:13 +00:00
Eelco Dolstra
ae7990cc88 * Work around a bug in Apple's GCC preprocessor. 2007-03-30 13:24:35 +00:00
Eelco Dolstra
4caca58ff7 * Make the maximum patch size configurable. 2007-03-30 09:01:05 +00:00
Eelco Dolstra
17b506c0c7 * Handle ECONNRESET from the client. Also, don't abort() if there are
unexpected conditions in the SIGPOLL handler, since that messes up
  the Berkeley DB environment (which a client must never be able to
  trigger).
2007-03-28 15:46:21 +00:00
Eelco Dolstra
efd31139df * Forgot a @bindir@. 2007-03-27 09:53:58 +00:00
Eelco Dolstra
d303b389a9 * `nix-copy-closure --from': copy from a remote machine instead of to
a remote machine.
2007-03-26 21:05:17 +00:00
Eelco Dolstra
7edd2e2cd2 * Refactoring. 2007-03-26 20:49:22 +00:00
Eelco Dolstra
f3584ff535 * Fix URL/description. 2007-03-21 12:39:55 +00:00
Eelco Dolstra
803cb6e3b9 * Override the setuid helper using NIX_SETUID_HELPER. 2007-03-20 22:04:25 +00:00
Eelco Dolstra
a8ea4cbcc8 * Scan /proc/sys/kernel/modprobe for roots to prevent the kernel
modules for the running kernel from being garbage-collected.  Idem
  for /proc/sys/kernel/fbsplash.
2007-03-20 11:13:15 +00:00
Eelco Dolstra
8ab229ddf2 * Terminate build hooks and substitutes with a TERM signal, not a KILL
signal.  This is necessary because those processes may have joined
  the BDB environment, so they have to be given a chance to clean up.
  (NIX-85)
2007-03-19 12:48:45 +00:00
Eelco Dolstra
b2b6cf3fc8 * Undocumented option `gc-check-reachability' to allow reachability
checking to be turned off on machines with way too many roots.
2007-03-19 09:16:47 +00:00
Eelco Dolstra
eb2dd4815c * Remove old generations in all directories under
/nix/var/nix/profiles, not just in that directory itself.  (NixOS
  puts profiles in /nix/var/nix/profiles/per-user.)
2007-03-13 11:30:57 +00:00
Eelco Dolstra
917e06bf63 * Delete the output paths before invoking the build hook. 2007-03-07 15:53:11 +00:00
Eelco Dolstra
df0283ae86 * Get rid of those stupid --login tricks, it's the responsibility of
the remote system to make sure that Nix is in the $PATH.
2007-03-01 13:55:47 +00:00
Eelco Dolstra
30394a4f3f * sh -> bash. 2007-03-01 13:49:20 +00:00
Eelco Dolstra
db1973d012 * Look for the openssl program at compile time. If not found, call
openssl through $PATH at runtime.
2007-03-01 13:30:46 +00:00
Eelco Dolstra
b4a040e52b * Don't check the signature unless we have to. 2007-03-01 12:30:24 +00:00
Eelco Dolstra
2ea3bebc23 * Doh! The deriver can be empty. 2007-02-27 23:18:57 +00:00
Eelco Dolstra
044b6482c1 * Greatly reduced the amount of stack space used by the Nix expression
evaluator.  This was important because the NixOS expressions started
  to hit 2 MB default stack size on Linux.

  GCC is really dumb about stack space: it just adds up all the local
  variables and temporaries of every scope into one huge stack frame.
  This is really bad for deeply recursive functions.  For instance,
  every `throw Error(format("error message"))' causes a format object
  of a few hundred bytes to be allocated on the stack.  As a result,
  every recursive call to evalExpr2() consumed 4680 bytes.  By
  splitting evalExpr2() and by moving the exception-throwing code out
  of the main functions, evalExpr2() now only consumes 40 bytes.
  Similar for evalExpr().
2007-02-27 19:10:45 +00:00
Eelco Dolstra
adce01a8d0 * When NIX_SHOW_STATS=1, show the amount of stack space consumed by
the Nix expression evaluator.
2007-02-27 17:28:51 +00:00
Eelco Dolstra
363e307fd3 * Error message to stdout. 2007-02-26 23:32:10 +00:00
Eelco Dolstra
ddde8e2f32 * Handle EINTR in select(). 2007-02-22 18:15:29 +00:00
Eelco Dolstra
27bb0ac7d2 * /man -> /share/man 2007-02-22 17:00:58 +00:00
Eelco Dolstra
fa2be32034 * nix-copy-closure: force a login shell on the remote machine to make
sure that nix-store is in the PATH.
* nix-copy-closure: option --gzip to compress data.
2007-02-22 16:42:01 +00:00
Eelco Dolstra
4c5e6d1a2f * nix-copy-closure: option --sign.
* nix-copy-closure: set SSH options through NIX_SSHOPTS..
2007-02-22 15:48:20 +00:00
Eelco Dolstra
024a8ed382 * New command `nix-copy-closure' to copy a closure to a Nix store on
another machine through ssh.  E.g.,

    $ nix-copy-closure xyzzy $(which svn)

  copies the closure of Subversion to machine `xyzzy'.  This is like
  `nix-pack-closure $(which svn) | ssh xyzzy', but it's much more
  efficient since it only copies those paths that are missing on the
  target machine.
2007-02-21 23:14:53 +00:00
Eelco Dolstra
7f6161ab3a * Flush cout to show progress. 2007-02-21 23:08:55 +00:00
Eelco Dolstra
0db450024d * Export/import many paths in one go. 2007-02-21 23:00:31 +00:00
Eelco Dolstra
9da367b7d5 * `nix-store -qR' and friends: print the paths sorted topologically
under the references relation.  This is useful for commands that
  want to copy paths to another Nix store in the right order.
2007-02-21 22:45:10 +00:00
Eelco Dolstra
881feb9698 * Flag --print-invalid' in nix-store --check-validity' to print out
which paths specified on the command line are invalid (i.e., don't
  barf when encountering an invalid path, just print it).  This is
  useful for build-remote.pl to figure out which paths need to be
  copied to a remote machine.  (Currently we use rsync, but that's
  rather inefficient.)
2007-02-21 17:57:59 +00:00
Eelco Dolstra
65f195f4c7 * Check that the file containing the secret key is secret. 2007-02-21 17:51:10 +00:00
Eelco Dolstra
bdadb98de8 * `nix-store --import' now also works in remote mode. The worker
always requires a signature on the archive.  This is to ensure that
  unprivileged users cannot add Trojan horses to the Nix store.
2007-02-21 17:34:02 +00:00
Eelco Dolstra
0f5da8a83c * Support exportPath() in remote mode. 2007-02-21 16:34:00 +00:00
Eelco Dolstra
dc7d594776 * importPath(): set the deriver.
* exportPath(): lock the path, use a transaction.
2007-02-21 16:23:25 +00:00
Eelco Dolstra
43c4d18c6a * nix-store --import': import an archive created by nix-store
--export' into the Nix store, and optionally check the cryptographic
  signatures against /nix/etc/nix/signing-key.pub.  (TODO: verify
  against a set of public keys.)
2007-02-21 15:45:32 +00:00
Eelco Dolstra
46e0919ced * `nix-store --export --sign': sign the Nix archive using the RSA key
in /nix/etc/nix/signing-key.sec
2007-02-21 14:31:42 +00:00
Eelco Dolstra
6c9fdb17fb * Don't use $SHELL. 2007-02-21 14:00:46 +00:00
Eelco Dolstra
b824a1daee * Start of `nix-store --export' operation for serialising a store
path.  This is like `nix-store --dump', only it also dumps the
  meta-information of the store path (references, deriver).  Will add
  a `--sign' flag later to add a cryptographic signature, which we
  will use for exchanging store paths between build farm machines in a
  secure manner.
2007-02-20 23:17:20 +00:00
Eelco Dolstra
3390c1be76 * Temporary notes on how we're going to use OpenSSL. 2007-02-20 22:57:46 +00:00
Eelco Dolstra
8181a1c3bb * Close the file - just in case. 2007-02-20 22:49:08 +00:00
Eelco Dolstra
46605fb4f5 * Fix 64-bit compiler warnings. 2007-02-06 20:03:53 +00:00
Eelco Dolstra
52d03276dd * Compatibility with docbook5-xsl. 2007-02-05 12:10:10 +00:00
Eelco Dolstra
451dbf687f * nix-env now maintains meta info (from the `meta' derivation
attribute) about installed packages in user environments.  Thus, an
  operation like `nix-env -q --description' shows useful information
  not only on available packages but also on installed packages.

* nix-env now passes the entire manifest as an argument to the Nix
  expression of the user environment builder (not just a list of
  paths), so that in particular the user environment builder has
  access to the meta attributes.
  
* New operation `--set-flag' in nix-env to change meta info of
  installed packages.  This will be useful to pass per-package
  policies to the user environment builder (e.g., how to resolve
  collision or whether to disable a package (NIX-80)) or upgrade
  policies in nix-env (e.g., that a package should be "masked", that
  is, left untouched by upgrade actions).  Example:

  $ nix-env --set-flag enabled false ghc-6.4
2007-02-02 01:52:42 +00:00
Eelco Dolstra
f52de527c7 * Doh! 2007-01-29 15:55:49 +00:00
Eelco Dolstra
b618fa6eb6 * computeStorePathForText: take the references into account when
computing the store path (NIX-77).  This is an important security
  property in multi-user Nix stores.

  Note that this changes the store paths of derivations (since the
  derivation aterms are added using addTextToStore), but not most
  outputs (unless they use builtins.toFile).
2007-01-29 15:51:37 +00:00
Eelco Dolstra
c558b1583c * Don't capitalise the primop functions. 2007-01-29 15:15:37 +00:00
Eelco Dolstra
18e6096105 * Organise primops.cc a bit better. 2007-01-29 15:11:32 +00:00
Eelco Dolstra
7349bd0176 New primitives:
* `sub' to subtract two numbers.
* `stringLength' to get the length of a string.
* `substring' to get a substring of a string.  These should be enough
  to allow most string operations to be expressed.
2007-01-29 14:23:09 +00:00
Eelco Dolstra
7dedbd896a * filterSource: pass strings to the predicate function instead of
paths.  Paths can have unexpected semantics.
2007-01-29 13:32:50 +00:00
Eelco Dolstra
84a84afb0e * Nasty: Glibc clears the TMPDIR environment variable in setuid
programs, so if a builder uses TMPDIR, then it will fail when
  executed through nix-setuid-helper.  In fact Glibc clears a whole
  bunch of variables (see sysdeps/generic/unsecvars.h in the Glibc
  sources), but only TMPDIR should matter in practice.  As a
  workaround, we reinitialise TMPDIR from NIX_BUILD_TOP.
2007-01-24 13:31:20 +00:00
Eelco Dolstra
fac63d6416 * exportReferencesGraph: work on paths within store paths as well. 2007-01-23 16:57:43 +00:00
Eelco Dolstra
bae75ca5a1 * New kind of manifest object: "localPath", which denotes that a store
path can be created by copying it from another location in the file
  system.  This is useful in the NixOS installation.
2007-01-23 16:50:19 +00:00
Eelco Dolstra
36d9258c0d * Successors have been gone for ages. 2007-01-23 16:05:59 +00:00
Eelco Dolstra
7bc30e1ca8 * nix-prefetch-url: change the default hash to SHA-256 (in base-32). 2007-01-22 09:53:36 +00:00
Eelco Dolstra
71ceb1c161 * Handle multiple indirect symlinks when loading a Nix expression. 2007-01-15 14:50:25 +00:00
Eelco Dolstra
e4b0666f8e * builtins.filterSource: pass the type of the file ("regular",
"directory", "symlink") as the second argument to the filter
  predicate.
2007-01-15 08:54:51 +00:00
Eelco Dolstra
63f3ce6d9a * `nix-store --verify': revive checking the referrers table. This is
important to get garbage collection to work if there is any
  inconsistency in the database (because the referrer table is used to
  determine whether it is safe to delete a path).
* `nix-store --verify': show some progress.
2007-01-14 17:28:30 +00:00
Eelco Dolstra
8f67b35886 * Make the garbage collector more resilient to certain consistency
errors: in-use paths now cause a warning, not a fatal error.
2007-01-14 16:24:49 +00:00
Eelco Dolstra
8659edc098 * Don't forget the .flags files. 2007-01-14 12:33:04 +00:00
Eelco Dolstra
e418976107 * Option --argstr for passing string arguments easily. (NIX-75) 2007-01-14 12:32:44 +00:00
Eelco Dolstra
4e329f173f * Doh. 2007-01-14 12:16:58 +00:00
Eelco Dolstra
afe23b5f38 * nix-pack-closure: store the top-level store paths in the closure.
* nix-unpack-closure: extract the top-level paths from the closure and
  print them on stdout.  This allows them to be installed, e.g.,
  "nix-env -i $(nix-unpack-closure)".  (NIX-64)
2007-01-13 19:50:42 +00:00
Eelco Dolstra
f25f900045 * Allow multiple --attr / -A arguments in nix-build / nix-instantiate
(NIX-74).
2007-01-13 18:25:30 +00:00
Eelco Dolstra
215505bb46 * Removed chroot support. 2007-01-13 17:54:01 +00:00
Eelco Dolstra
f23dcdd603 * Canonicalise ASTs in `nix-instantiate --eval': remove position
info, sort attribute sets.
2007-01-13 16:17:07 +00:00
Eelco Dolstra
05879db628 * Memoize strict evaluation. 2007-01-13 15:41:54 +00:00
Eelco Dolstra
5011588459 * printTermAsXML: treat derivations specially; emit an element
<derivation outPath=... drvPath=...> attrs </derivation>.  Only emit
  the attributes of any specific derivation only.  This prevents
  exponententially large XML output due to the absense of sharing.
2007-01-13 15:11:10 +00:00
Eelco Dolstra
792878af91 * Make printing an expression as XML interruptible. 2007-01-13 14:48:41 +00:00
Eelco Dolstra
11158028be * Cleanup. 2007-01-13 14:21:49 +00:00
Eelco Dolstra
1b7840b949 2007-01-11 19:28:28 +00:00
Eelco Dolstra
69c8b5b8a7 * Install generate-patches into libexec. 2007-01-11 16:19:45 +00:00
Eelco Dolstra
1f3722bd4a * Reject patches that are larger than a certain fraction of the full archive
(currently 60%).  Large patches aren't very economical.
2007-01-08 15:32:15 +00:00
Eelco Dolstra
50bdec410a * Huge speedup in patch propagation (20 minutes or so to 3 seconds). 2007-01-08 15:17:18 +00:00
Eelco Dolstra
4c63f9fe04 * Another great success. 2006-12-29 22:23:51 +00:00
Eelco Dolstra
57969b95b3 * Testing 1 2 3. 2006-12-29 20:37:55 +00:00
Eelco Dolstra
cafaceb707 * Handle weird cases when the server redirects us while setting a cookie. 2006-12-15 21:27:26 +00:00
Eelco Dolstra
1073b1780a * Remove debug message. 2006-12-13 14:29:05 +00:00
Eelco Dolstra
a3e6415ba8 * New primop builtins.filterSource, which can be used to filter files
from a source directory.  All files for which a predicate function
  returns true are copied to the store.  Typical example is to leave
  out the .svn directory:

    stdenv.mkDerivation {
      ...
      src = builtins.filterSource
        (path: baseNameOf (toString path) != ".svn")
        ./source-dir;
      # as opposed to
      #   src = ./source-dir;
    }

  This is important because the .svn directory influences the hash in
  a rather unpredictable and variable way.
2006-12-12 23:05:01 +00:00
Eelco Dolstra
b438d37558 * In dumpPath(): pass a function object that allows files to be
selectively in/excluded from the dump.
2006-12-12 21:51:02 +00:00
Eelco Dolstra
3130f1f0fa * Push. 2006-12-12 20:17:14 +00:00
Eelco Dolstra
7ace29dae7 * New operation `nix-env --set' which sets a user environment to a
single derivation specified by the argument.  This is useful when we
  want to have a profile for a single derivation, such as a server
  configuration.  Then we can just say (e.g.)

  $ nix-env -p /.../server-profile -f server.nix --set -A server

  We can't do queries or upgrades on such a profile, but we can do
  rollbacks.  The advantage over -i is that we don't have to worry
  about other packages having been installed in the profile
  previously; --set gets rid of them.
2006-12-12 19:06:02 +00:00
Eelco Dolstra
1a7e88bbd9 * New built-in function `builtins.attrNames' that returns the
names of the attributes in an attribute set.
2006-12-12 16:14:31 +00:00
Eelco Dolstra
5e6699188f 2006-12-09 23:14:55 +00:00
Eelco Dolstra
b17677462c * Use lchown() instead of chown() in canonicalisePathMetaData(). This
matters when running as root, since then we don't use the setuid
  helper (which already used lchown()).
  
* Also check for an obscure security problem on platforms that don't
  have lchown.  Then we can't change the ownership of symlinks, which
  doesn't matter *except* when the containing directory is writable by
  the owner (which is the case with the top-level Nix store directory).
2006-12-09 20:02:27 +00:00
Eelco Dolstra
5f681988f2 * Use deletePathWrapped() in more places. 2006-12-09 00:26:24 +00:00
Eelco Dolstra
fa33303146 * Goal cancellation inside the waitForInput() loop needs to be handled
very carefully, since it can invalidate iterators into the
  `children' map.
2006-12-08 18:41:48 +00:00
Eelco Dolstra
06c4929958 * Some refactoring.
* Throw more exceptions as BuildErrors instead of Errors.  This
  matters when --keep-going is turned on.  (A BuildError is caught
  and terminates the goal in question, an Error terminates the
  program.)
2006-12-08 17:26:21 +00:00
Eelco Dolstra
9dbfe242e3 * Kill a build if it has gone for more than a certain number of
seconds without producing output on stdout or stderr (NIX-65).  This
  timeout can be specified using the `--max-silent-time' option or the
  `build-max-silent-time' configuration setting.  The default is
  infinity (0).

* Fix a tricky race condition: if we kill the build user before the
  child has done its setuid() to the build user uid, then it won't be
  killed, and we'll potentially lock up in pid.wait().  So also send a
  conventional kill to the child.
2006-12-08 15:44:00 +00:00
Eelco Dolstra
d3fe6ab024 * Also for convenience, change the ownership of the build output even
in case of failure.
2006-12-08 00:19:50 +00:00
Eelco Dolstra
096194ab29 * Remove ancient terminology. 2006-12-07 23:58:36 +00:00
Eelco Dolstra
6833e8bbe8 * When keeping the temporary build directory (-K), change the owner
back to the Nix account.
2006-12-07 23:27:40 +00:00
Eelco Dolstra
e24d0201c2 * Doh! 2006-12-07 22:07:05 +00:00
Eelco Dolstra
2819eb36a4 * Be less verbose. 2006-12-07 21:43:35 +00:00
Eelco Dolstra
4ca01065c3 * Rename all those main.cc files. 2006-12-07 20:47:30 +00:00
Eelco Dolstra
d03f0d4117 * Check for lchown. 2006-12-07 18:51:11 +00:00
Eelco Dolstra
c3286ec020 * Don't count on the Pid deconstructor to kill the child process,
since if we're running a build user in non-root mode, we can't.  Let
  the setuid helper do it.
2006-12-07 17:52:58 +00:00
Eelco Dolstra
a82d80ddeb * Move setuidCleanup() to libutil. 2006-12-07 16:40:41 +00:00
Eelco Dolstra
f76fdb6d42 * If not running as root, let the setuid helper kill the build user's
processes before and after the build.
2006-12-07 16:33:31 +00:00
Eelco Dolstra
ec23ecc64d * In the garbage collector, if deleting a path fails, try to fix its
ownership, then try again.
2006-12-07 15:54:52 +00:00
Eelco Dolstra
a0a43c3206 * When not running as root, call the setuid helper to change the
ownership of the build result after the build.
2006-12-07 15:18:14 +00:00
Eelco Dolstra
6a07ff1ec0 * Change the ownership of store paths to the Nix account before
deleting them using the setuid helper.
2006-12-07 14:14:35 +00:00
Eelco Dolstra
7d8cf316ee * Pass the actual build user to the setuid helper. 2006-12-07 11:27:32 +00:00
Eelco Dolstra
a45c498e4e * If Nix is not running as root, call the setuid helper to start the
builder under the desired build user.
2006-12-07 00:42:30 +00:00
Eelco Dolstra
813a7c65c9 * Sanity check. 2006-12-07 00:19:27 +00:00
Eelco Dolstra
6a8e60913a * Move killUser() to libutil so that the setuid helper can use it. 2006-12-07 00:16:07 +00:00
Eelco Dolstra
79875c5e42 * Change the ownership of the current directory to the build user. 2006-12-06 23:52:25 +00:00
Eelco Dolstra
62ab131412 * Verify that the desired target user is in the build users group (as
specified in the setuid config file).
2006-12-06 23:15:26 +00:00
Eelco Dolstra
f07ac41656 * Check that the caller is allowed to call the setuid helper. The
allowed uid is specified in a configuration file in
  /etc/nix-setuid.conf.
2006-12-06 22:45:41 +00:00
Eelco Dolstra
173d328351 * Urgh. 2006-12-06 20:19:25 +00:00
Eelco Dolstra
ef281b93c2 * Fix the safety check. 2006-12-06 20:18:29 +00:00
Eelco Dolstra
a14d491f09 * Oops. 2006-12-06 20:16:28 +00:00
Eelco Dolstra
6e5ec1029a * Get rid of `build-users'. We'll just take all the members of
`build-users-group'.  This makes configuration easier: you can just
  add users in /etc/group.
2006-12-06 20:00:15 +00:00
Eelco Dolstra
751f6d2157 * nix-setuid-helper: allow running programs under a different uid. 2006-12-06 17:29:10 +00:00
Eelco Dolstra
9f0efa6611 * Start of the setuid helper (the program that performs the operations
that have to be done as root: running builders under different uids,
  changing ownership of build results, and deleting paths in the store
  with the wrong ownership).
2006-12-06 01:24:02 +00:00
Eelco Dolstra
2b558843a2 * Be less chatty. 2006-12-05 19:01:19 +00:00
Eelco Dolstra
44cad9630f * Urgh. Do setgid() before setuid(), because the semantics of setgid()
changes completely depending on whether you're root...
2006-12-05 18:28:15 +00:00
Eelco Dolstra
6f0d050324 * Tricky: child processes should not send data to the client since
that might mess up the protocol.  And besides, the socket file
  descriptor is probably closed.
2006-12-05 18:21:16 +00:00
Eelco Dolstra
4c1c37d0b6 * FreeBSD returns ESRCH when there are no processes to kill. 2006-12-05 18:07:46 +00:00
Eelco Dolstra
8d1854c3f1 * Oops! In daemon mode, we can't run as root either if build-users is empty. 2006-12-05 17:44:19 +00:00
Eelco Dolstra
99655245ae * Use an explicit handler for SIGCHLD, since SIG_IGN doesn't do the
right thing on FreeBSD 4 (it leaves zombies).
2006-12-05 17:21:42 +00:00
Eelco Dolstra
62b0497c0f * Better message. 2006-12-05 16:17:01 +00:00
Eelco Dolstra
c808e6252f * Ugly hack to handle spurious SIGPOLLs. 2006-12-05 15:36:31 +00:00
Eelco Dolstra
fd4a9db91f * Some renaming. 2006-12-05 14:15:51 +00:00
Eelco Dolstra
fc1c20d11b * Redundant. 2006-12-05 13:57:35 +00:00
Eelco Dolstra
a9c4f66cfb * Allow unprivileged users to run the garbage collector and to do
`nix-store --delete'.  But unprivileged users are not allowed to
  ignore liveness.
* `nix-store --delete --ignore-liveness': ignore the runtime roots as
  well.
2006-12-05 02:18:46 +00:00
Eelco Dolstra
29cf434a35 * The determination of the root set should be made by the privileged
process, so forward the operation.
* Spam the user about GC misconfigurations (NIX-71).
* findRoots: skip all roots that are unreadable - the warnings with
  which we spam the user should be enough.
2006-12-05 01:31:45 +00:00
Eelco Dolstra
8623256f48 * findRoots: return a map from the symlink (outside of the store) to
the store path (inside the store).
2006-12-05 00:48:36 +00:00
Eelco Dolstra
d27a73b1a9 * In addPermRoot, check that the root that we just registered can be
found by the garbage collector.  This addresses NIX-71 and is a
  particular concern in multi-user stores.
2006-12-05 00:34:42 +00:00
Eelco Dolstra
74033a844f * Add indirect root registration to the protocol so that unprivileged
processes can register indirect roots.  Of course, there is still
  the problem that the garbage collector can only read the targets of
  the indirect roots when it's running as root...
2006-12-04 23:29:16 +00:00
Eelco Dolstra
0d40f6d7bb * Not every OS knows about SIGPOLL. 2006-12-04 22:58:44 +00:00
Eelco Dolstra
7751160e9f * Don't redirect stderr. 2006-12-04 19:10:23 +00:00
Eelco Dolstra
40c3529909 * Handle exceptions and stderr for all protocol functions.
* SIGIO -> SIGPOLL (POSIX calls it that).
* Use sigaction instead of signal to register the SIGPOLL handler.
  Sigaction is better defined, and a handler registered with signal
  appears not to interrupt fcntl(..., F_SETLKW, ...), which is bad.
2006-12-04 17:55:14 +00:00
Eelco Dolstra
0130ef88ea * Daemon mode (`nix-worker --daemon'). Clients connect to the server
via the Unix domain socket in /nix/var/nix/daemon.socket.  The
  server forks a worker process per connection.
* readString(): use the heap, not the stack.
* Some protocol fixes.
2006-12-04 17:17:13 +00:00
Eelco Dolstra
4740baf3a6 * When NIX_REMOTE=daemon, connect to /nix/var/nix/daemon.socket
instead of forking a worker.
2006-12-04 14:21:39 +00:00
Eelco Dolstra
f5f0cf423f * Refactoring. 2006-12-04 13:28:14 +00:00
Eelco Dolstra
052b6fb149 * Pass the verbosity level to the worker. 2006-12-04 13:15:29 +00:00
Eelco Dolstra
1e16d20655 * Install the worker in bindir, not libexecdir.
* Allow the worker path to be overriden through the NIX_WORKER
  environment variable.
2006-12-04 13:09:16 +00:00
Eelco Dolstra
9322b399f3 * Doh. 2006-12-03 20:41:22 +00:00
Eelco Dolstra
f4279bcde0 * Don't run setuid root when build-users is empty.
* Send startup errors to the client.
2006-12-03 16:25:19 +00:00
Eelco Dolstra
35247c4c9f * Removed `build-allow-root'.
* Added `build-users-group', the group under which builds are to be
  performed.
* Check that /nix/store has 1775 permission and is owner by the
  build-users-group.
2006-12-03 15:32:38 +00:00
Eelco Dolstra
84d6459bd5 * Use setreuid if setresuid is not available. 2006-12-03 14:32:22 +00:00
Eelco Dolstra
a9f9241054 * Handle a subtle race condition: the client closing the socket
between the last worker read/write and the enabling of the signal
  handler.
2006-12-03 03:16:27 +00:00
Eelco Dolstra
3ed9e4ad9b * Some hardcore magic to handle asynchronous client disconnects.
The problem is that when we kill the client while the worker is
  building, and the builder is not writing anything to stderr, then
  the worker never notice that the socket is closed on the other side,
  so it just continues indefinitely.  The solution is to catch SIGIO,
  which is sent when the far side of the socket closes, and simulate
  an normal interruption.  Of course, SIGIO is also sent every time
  the client sends data over the socket, so we only enable the signal
  handler when we're not expecting any data...
2006-12-03 03:03:36 +00:00
Eelco Dolstra
4251f94b32 * Use a Unix domain socket instead of pipes. 2006-12-03 02:36:44 +00:00
Eelco Dolstra
8c76df93e6 * Better error message if the worker doesn't start. 2006-12-03 02:22:04 +00:00
Eelco Dolstra
363f40022f * Pid::kill() should be interruptable. 2006-12-03 02:12:26 +00:00
Eelco Dolstra
7951c3c546 * Some hackery to propagate the worker's stderr and exceptions to the
client.
2006-12-03 02:08:13 +00:00
Eelco Dolstra
714fa24cfb * Run the worker in a separate session to prevent terminal signals
from interfering.
2006-12-03 00:52:27 +00:00
Eelco Dolstra
e25fad691a * Move addTempRoot() to the store API, and add another function
syncWithGC() to allow clients to register GC roots without needing
  write access to the global roots directory or the GC lock.
2006-12-02 16:41:36 +00:00
Eelco Dolstra
30bf547f4f * Doh. 2006-12-02 15:46:17 +00:00
Eelco Dolstra
536595b072 * Remove most of the old setuid code.
* Much simpler setuid code for the worker in slave mode.
2006-12-02 15:45:51 +00:00
Eelco Dolstra
9c9cdb06d0 * Remove SwitchToOriginalUser, we're not going to need it anymore. 2006-12-02 14:34:14 +00:00
Eelco Dolstra
626f8ee42f * Clear NIX_REMOTE in the tests. 2006-12-02 14:33:39 +00:00
Eelco Dolstra
8ba5d32769 * Remove queryPathHash().
* Help for nix-worker.
2006-12-02 14:27:24 +00:00
Eelco Dolstra
fcd9900d74 * Replace read-only calls to addTextToStore. 2006-12-01 21:00:39 +00:00
Eelco Dolstra
a824d58b56 * Merge addToStore and addToStoreFixed.
* addToStore now adds unconditionally, it doesn't use readOnlyMode.
  Read-only operation is up to the caller (who can call
  computeStorePathForPath).
2006-12-01 20:51:18 +00:00
Eelco Dolstra
ceb982a1be * Right name. 2006-12-01 18:02:05 +00:00
Eelco Dolstra
b0d8e05be1 * More operations.
* addToStore() and friends: don't do a round-trip to the worker if
  we're only interested in the path (i.e., in read-only mode).
2006-12-01 18:00:01 +00:00
Eelco Dolstra
0565b5f2b3 * More remote operations.
* Added new operation hasSubstitutes(), which is more efficient than
  querySubstitutes().size() > 0.
2006-11-30 22:43:55 +00:00
Eelco Dolstra
aac547a8b3 * Doh. 2006-11-30 21:32:46 +00:00
Eelco Dolstra
0263279071 * More operations. 2006-11-30 20:45:20 +00:00
Eelco Dolstra
a711689368 * First remote operation: isValidPath(). 2006-11-30 20:13:59 +00:00
Eelco Dolstra
765bdfe542 * When NIX_REMOTE is set to "slave", fork off nix-worker in slave
mode.  Presumably nix-worker would be setuid to the Nix store user.
  The worker performs all operations on the Nix store and database, so
  the caller can be completely unprivileged.

  This is already much more secure than the old setuid scheme, since
  the worker doesn't need to do Nix expression evaluation and so on.
  Most importantly, this means that it doesn't need to access any user
  files, with all resulting security risks; it only performs pure
  store operations.

  Once this works, it is easy to move to a daemon model that forks off
  a worker for connections established through a Unix domain socket.
  That would be even more secure.
2006-11-30 19:54:43 +00:00
Eelco Dolstra
40b3f64b55 * Skeleton of the privileged worker program.
* Some refactoring: put the NAR archive integer/string serialisation
  code in a separate file so it can be reused by the worker protocol
  implementation.
2006-11-30 19:19:59 +00:00
Eelco Dolstra
9adc074dc3 * Oops. 2006-11-30 18:35:50 +00:00
Eelco Dolstra
9cf1948993 * Skeleton of remote store implementation. 2006-11-30 18:35:36 +00:00
Eelco Dolstra
6ecb840fd1 * Put building in the store API. 2006-11-30 18:02:04 +00:00
Eelco Dolstra
e2ef5e07fd * Refactoring. There is now an abstract interface class StoreAPI
containing functions that operate on the Nix store.  One
  implementation is LocalStore, which operates on the Nix store
  directly.  The next step, to enable secure multi-user Nix, is to
  create a different implementation RemoteStore that talks to a
  privileged daemon process that uses LocalStore to perform the actual
  operations.
2006-11-30 17:43:04 +00:00
Eelco Dolstra
5f0b9de6d8 * Benchmarking Unix domain sockets. 2006-11-30 15:06:46 +00:00
Eelco Dolstra
fe15f991e3 * Troubleshooting information on fixing a b0rked Berkeley DB database. 2006-11-30 11:24:10 +00:00
Eelco Dolstra
80b742dd52 * Don't spam. 2006-11-29 22:07:49 +00:00
Roy van den Broek
92417600a1 * Example script to set permissions for setuid operation. 2006-11-29 21:58:09 +00:00
Eelco Dolstra
71e867c5f5 * Remove --enable-setuid, --with-nix-user and --with-nix-group.
Rather, setuid support is now always compiled in (at least on
  platforms that have the setresuid system call, e.g., Linux and
  FreeBSD), but it must enabled by chowning/chmodding the Nix
  binaries.
2006-11-29 21:06:58 +00:00
Eelco Dolstra
c6a97e3b74 * Doh! Path sizes need to be computed recursively of course.
(NIX-70)
2006-11-24 20:24:14 +00:00
Eelco Dolstra
a76efaeb3f * Dead files. 2006-11-24 20:07:30 +00:00
Eelco Dolstra
d941186289 * Show more progress. 2006-11-18 19:03:45 +00:00
Eelco Dolstra
0541ddc7e3 * Turn off synchronisation between C and C++ I/O functions. This
gives a huge speedup in operations that read or write from standard
  input/output.  (So libstdc++'s I/O isn't that bad, you just have to
  call std::ios::sync_with_stdio(false).)  For instance, `nix-store
  --register-substitutes' went from 1.4 seconds to 0.1 seconds on a
  certain input.  Another victory for Valgrind.
2006-11-18 18:56:30 +00:00
Eelco Dolstra
471749ca7e * Grrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr... 2006-11-14 19:18:52 +00:00
Eelco Dolstra
17d18b1a9c * Doh! 2006-11-14 19:11:36 +00:00
Eelco Dolstra
0ddaee756e * Doh. 2006-11-14 19:08:46 +00:00
Eelco Dolstra
bce9ff7ece * Use the patched ATerm library. 2006-11-14 15:36:27 +00:00
Eelco Dolstra
745e354b19 * Push. 2006-11-14 10:23:21 +00:00
Eelco Dolstra
f459a5bb3a * Remove the undocumented `noscan' feature. It's no longer necessary
now that reference scanning is sufficiently streamy.
2006-11-13 18:19:05 +00:00
Eelco Dolstra
e2a70b7ec0 * Magic attribute `exportReferencesGraph' that allows the references
graph to be passed to a builder.  This attribute should be a list of
  pairs [name1 path1 name2 path2 ...].  The references graph of each
  `pathN' will be stored in a text file `nameN' in the temporary build
  directory.  The text files have the format used by `nix-store
  --register-validity'.  However, the deriver fields are left empty.

  `exportReferencesGraph' is useful for builders that want to do
  something with the closure of a store path.  Examples: the builders
  that make initrds and ISO images for NixOS.

  `exportReferencesGraph' is entirely pure.  It's necessary because
  otherwise the only way for a builder to get this information would
  be to call `nix-store' directly, which is not allowed (though
  unfortunately possible).
2006-11-13 18:18:13 +00:00
Eelco Dolstra
e40d4a5604 * Option --reregister' in nix-store --register-validity'. We need
this in the NixOS installer (or in the buildfarm) to ensure that the
  cryptographic hash of the path contents still matches the actual
  contents.
2006-11-13 16:48:27 +00:00
Eelco Dolstra
e790404318 * Don't use the result of `uname -p' on x86_64 as it gives wacky
results on some machines. (NIX-69)
2006-11-13 14:54:18 +00:00
Eelco Dolstra
983c5e3fce * Fix the locking patch for Berkeley DB 4.5. 2006-11-07 14:51:28 +00:00
Eelco Dolstra
7e85a2af5f * Fix importing of derivation outputs. 2006-11-03 16:17:39 +00:00
Eelco Dolstra
b3f916995a * Oops, `nix-build --no-out-link' was broken. 2006-10-31 18:45:17 +00:00
Eelco Dolstra
005eecfc4d * Release notes. 2006-10-30 16:29:05 +00:00
Eelco Dolstra
8478cd260f * readFile: don't overflow the stack on large files. 2006-10-30 11:56:09 +00:00
Eelco Dolstra
8d17265ac4 * Don't use EPSV. 2006-10-28 22:07:09 +00:00
Eelco Dolstra
ae6fb27f18 * `nix-store --read-log / -l PATH' shows the build log of PATH, if
available.  For instance,

    $ nix-store -l $(which svn) | less

  lets you read the build log of the Subversion instance in your
  profile.

* `nix-store -qb': if applied to a non-derivation, take the deriver.
2006-10-28 16:33:54 +00:00
Eelco Dolstra
99b0ea7c67 * Typo reported by Arie Middelkoop.
* Left out close-quote in example.
2006-10-26 23:06:47 +00:00
Eelco Dolstra
dd300fb48d * Some better error messages. 2006-10-23 16:45:19 +00:00
Eelco Dolstra
1d694eef4c * Require Perl 5.8.0 or newer. I mean, it *is* more than four years
old...
2006-10-19 19:20:18 +00:00
Eelco Dolstra
7a4497d98c * Checks for allowedReferences and some other features.
* Use nix-build in a test.
2006-10-19 17:44:51 +00:00
Eelco Dolstra
17f4883bfe * Better message. 2006-10-19 17:43:58 +00:00
Eelco Dolstra
9bd93f7606 * toFile: maintain the references. 2006-10-19 17:39:02 +00:00
Eelco Dolstra
b3d3700e11 * nix-build: check the exit status of `nix-store -r'. 2006-10-19 17:30:09 +00:00
Eelco Dolstra
6a67556f71 * Special derivation attribute `allowedReferences' that causes Nix to
check that the references of the output of a derivation are in the
  specified set.  For instance,

    allowedReferences = [];

  specifies that the output cannot have any references.  (This is
  useful, for instance, for the generation of bootstrap binaries for
  stdenv-linux, which must not have any references for purity).  It
  could also be used to guard against undesired runtime dependencies,
  e.g.,

    {gcc, dynlib}: derivation {
      ...
      allowedReferences = [dynlib];
    }

  says that the output can refer to the path of `dynlib' but not
  `gcc'.  A `forbiddedReferences' attribute would be more useful for
  this, though.
2006-10-19 16:09:24 +00:00
Eelco Dolstra
daa8f85fcd * Backwards compatibility hack for user environments made by Nix <= 0.10. 2006-10-17 14:13:15 +00:00
Eelco Dolstra
24737f279e * Backwards compatibility with old user environment manifests. 2006-10-17 14:01:45 +00:00
Eelco Dolstra
4bd5cdb90b * Print out the offending path. 2006-10-17 14:01:28 +00:00
Eelco Dolstra
58ff6939f4 * An awful backwards compatibility hack. 2006-10-17 12:58:42 +00:00
Eelco Dolstra
3059df0f1e * baseNameOf: paths don't have to be absolute. 2006-10-17 12:34:13 +00:00
Eelco Dolstra
822dba2210 * Maintain the references for the user environment properly. 2006-10-17 12:15:15 +00:00
Eelco Dolstra
dfc042a0c1 * Another test. 2006-10-17 11:16:02 +00:00
Eelco Dolstra
9e30694f98 * Fix the tests wrt the AST changes, i.e., Str(s) -> Str(s, []), and
the semantic changes.
2006-10-17 11:08:59 +00:00
Eelco Dolstra
be1961c9f8 * toPath: should be the identity on paths. 2006-10-17 11:07:11 +00:00
Eelco Dolstra
cba913c521 * dirOf: return a path if the argument is a path. 2006-10-17 11:05:34 +00:00
Eelco Dolstra
cf705eaf78 * toString: don't copy paths. So toString can be used to pass
non-store paths to a builder.
2006-10-17 10:58:12 +00:00
Eelco Dolstra
7de5fe2fc2 * Do the path check on the normal form. 2006-10-17 10:57:25 +00:00
Eelco Dolstra
46b631b6c4 * Don't generate an empty drvPath attribute in the manifest. 2006-10-17 10:15:42 +00:00
Eelco Dolstra
d7efd76394 * Big cleanup of the semantics of paths, strings, contexts, string
concatenation and string coercion.  This was a big mess (see
  e.g. NIX-67).  Contexts are now folded into strings, so that they
  don't cause evaluation errors when they're not expected.  The
  semantics of paths has been clarified (see nixexpr-ast.def).
  toString() and coerceToString() have been merged.

  Semantic change: paths are now copied to the store when they're in a
  concatenation (and in most other situations - that's the
  formalisation of the meaning of a path).  So

    "foo " + ./bla

  evaluates to "foo /nix/store/hash...-bla", not "foo
  /path/to/current-dir/bla".  This prevents accidental impurities, and
  is more consistent with the treatment of derivation outputs, e.g.,
  `"foo " + bla' where `bla' is a derivation.  (Here `bla' would be
  replaced by the output path of `bla'.)
2006-10-16 15:55:34 +00:00
Eelco Dolstra
4c9aa821b9 * Fix version. 2006-10-13 14:08:14 +00:00
Eelco Dolstra
142863a89d * Use Berkeley DB 4.5. 2006-10-13 12:11:30 +00:00
Eelco Dolstra
37c8a664f3 * A helpful message. 2006-10-13 11:49:55 +00:00
Eelco Dolstra
e4af398681 * Don't crash when upgrading the Berkeley DB environment. 2006-10-13 11:15:53 +00:00
Eelco Dolstra
2a535689fe * Reduce the maximum archive size for patch generation to 100 MB to
prevent trashing on nix.cs.uu.nl.
2006-10-12 20:13:29 +00:00
Eelco Dolstra
7d4567f2cc * Removed URIs from the evaluator (NIX-66). They are now just another
kind of notation for strings.
2006-10-11 21:59:33 +00:00
Eelco Dolstra
b4e012ab4d * Merge 0.10.1 release notes. 2006-10-11 13:39:00 +00:00
Eelco Dolstra
0c4c5c2020 * Quick hack to fix NIX-67: evaluation result differing if the Nix
expression resides in the store.
2006-10-10 21:23:35 +00:00
Eelco Dolstra
bd0c40e1e9 * import': unwrap the context. Necessary to make import (x + y)'
work, where x is a store path.
2006-10-10 15:07:23 +00:00
Eelco Dolstra
7bada48b36 * Bumped the version number to 0.11. 2006-10-06 13:45:29 +00:00
288 changed files with 17222 additions and 8096 deletions

View File

@@ -1,29 +1,26 @@
SUBDIRS = externals src scripts corepkgs doc misc tests
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
svn-revision nix.conf.example NEWS
nix.conf.example NEWS version
include ./substitute.mk
nix.spec: nix.spec.in
rpm: nix.spec dist
rpm $(EXTRA_RPM_FLAGS) -ta $(distdir).tar.gz
relname:
echo -n $(distdir) > relname
install-data-local: init-state
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix
$(INSTALL_DATA) $(srcdir)/nix.conf.example $(DESTDIR)$(sysconfdir)/nix
if ! test -e $(DESTDIR)$(sysconfdir)/nix/nix.conf; then \
$(INSTALL_DATA) $(srcdir)/nix.conf.example $(DESTDIR)$(sysconfdir)/nix/nix.conf; \
fi
$(INSTALL) -d $(DESTDIR)$(docdir)
$(INSTALL_DATA) README $(DESTDIR)$(docdir)/
if INIT_STATE
if SETUID_HACK
INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@
GROUP_WRITABLE = -m 775
endif
# For setuid operation, you can enable the following:
# INIT_FLAGS = -g @NIX_GROUP@ -o @NIX_USER@
# GROUP_WRITABLE = -m 775
init-state:
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/db
@@ -34,20 +31,18 @@ init-state:
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/temproots
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/gcroots/tmp
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/gcroots/channels
rm -f $(DESTDIR)$(localstatedir)/nix/gcroots/profiles
ln -s $(localstatedir)/nix/profiles $(DESTDIR)$(localstatedir)/nix/gcroots/profiles
ln -sfn $(localstatedir)/nix/profiles $(DESTDIR)$(localstatedir)/nix/gcroots/profiles
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/userpool
$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(prefix)/store
$(INSTALL) $(INIT_FLAGS) -m 1777 -d $(DESTDIR)$(storedir)
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests
# $(bindir)/nix-store --init
ln -sfn $(localstatedir)/nix/manifests $(DESTDIR)$(localstatedir)/nix/gcroots/manifests
else
init-state:
endif
svn-revision:
svnversion . > svn-revision
all-local: NEWS
NEWS: doc/manual/NEWS.txt
NEWS:
$(MAKE) -C doc/manual NEWS.txt
cp $(srcdir)/doc/manual/NEWS.txt NEWS

9
README
View File

@@ -1,9 +1,10 @@
For installation and usage instructions, please read the manual, which
can be found in `docs/manual/manual.html', and additionally at the Nix
website at <http://www.cs.uu.nl/groups/ST/Trace/Nix>.
Nix is a purely functional package manager. For installation and
usage instructions, please read the manual, which can be found in
`docs/manual/manual.html', and additionally at the Nix website at
<http://nixos.org/>.
Acknowledgments
This product includes software developed by the OpenSSL Project for
use in the OpenSSL Toolkit (http://www.OpenSSL.org/)
use in the OpenSSL Toolkit (http://www.OpenSSL.org/).

View File

@@ -1,184 +1,117 @@
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:mark_memory_young
fun:mark_phase_young
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_isValidSymbol
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_isValidSymbol
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_isInsideValidTerm
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_isInsideValidTerm
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_markTerm_young
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_markTerm_young
fun:mark_memory_young
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_isValidSymbol
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_isValidSymbol
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_isInsideValidTerm
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_isInsideValidTerm
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_markTerm
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_markTerm
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_markTerm
fun:mark_memory
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:mark_phase_young
fun:*
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:mark_phase_young
fun:*
fun:AT_collect_minor
}
{
<insert a suppression name here>
Memcheck:Cond
fun:AT_isValidSymbol
fun:mark_phase_young
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:AT_collect_minor
}
{
<insert a suppression name here>
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:AT_isValidSymbol
fun:mark_phase_young
fun:*
fun:*
fun:AT_collect_minor
}
{
<insert a suppression name here>
Memcheck:Value4
fun:AT_isInsideValidTerm
fun:mark_phase_young
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:*
fun:AT_collect_minor
}
{
<insert a suppression name here>
ATerm library conservatively scans for GC roots
Memcheck:Addr4
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Addr8
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:AT_isInsideValidTerm
fun:mark_phase_young
fun:AT_collect_minor
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Addr4
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Addr8
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:*
fun:AT_collect
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:*
fun:*
fun:AT_collect
}

View File

@@ -1,24 +1,9 @@
AC_INIT(nix, 0.10)
AC_INIT(nix, m4_esyscmd([echo -n $(cat ./version)$VERSION_SUFFIX]))
AC_CONFIG_SRCDIR(README)
AC_CONFIG_AUX_DIR(config)
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
# Change to `1' to produce a `stable' release (i.e., the `preREVISION'
# suffix is not added).
STABLE=0
# Put the revision number in the version.
if test "$STABLE" != "1"; then
if REVISION=`test -d $srcdir/.svn && svnversion $srcdir 2> /dev/null`; then
VERSION=${VERSION}pre${REVISION}
elif REVISION=`cat $srcdir/svn-revision 2> /dev/null`; then
VERSION=${VERSION}pre${REVISION}
fi
fi
AC_DEFINE_UNQUOTED(NIX_VERSION, ["$(echo $VERSION)"], [version])
AC_PREFIX_DEFAULT(/nix)
AC_DEFINE_UNQUOTED(NIX_VERSION, ["$VERSION"], [Nix version.])
AC_CANONICAL_HOST
@@ -32,6 +17,9 @@ case $machine_name in
i*86)
machine_name=i686
;;
x86_64)
machine_name=x86_64
;;
ppc)
machine_name=powerpc
;;
@@ -51,21 +39,41 @@ case $sys_name in
esac
AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
[platform identifier (e.g., `i686-linux')]),
[Platform identifier (e.g., `i686-linux').]),
system=$withval, system="${machine_name}-${sys_name}")
AC_MSG_RESULT($system)
AC_SUBST(system)
AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier (`cpu-os')])
# State should be stored in /nix/var, unless the user overrides it explicitly.
test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
# Whether to produce a statically linked binary. On Cygwin, this is
# the default: dynamically linking against the ATerm DLL does work,
# except that it requires the ATerm "lib" directory to be in $PATH, as
# Windows doesn't have anything like an RPATH embedded in executable.
# Since this is kind of annoying, we use static libraries for now.
AC_ARG_ENABLE(static-nix, AC_HELP_STRING([--enable-static-nix],
[produce statically linked binaries]),
static_nix=$enableval, static_nix=no)
if test "$sys_name" = cygwin; then
static_nix=yes
fi
if test "$static_nix" = yes; then
AC_DISABLE_SHARED
AC_ENABLE_STATIC
fi
# Windows-specific stuff.
if test "$sys_name" = "cygwin"; then
# We cannot delete open files.
AC_DEFINE(CANNOT_DELETE_OPEN_FILES, 1, [Whether it is impossible to delete open files.])
# Shared libraries don't work, currently.
AC_DISABLE_SHARED
AC_ENABLE_STATIC
fi
@@ -91,17 +99,34 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iostream>
using namespace std;
static char buf[1024];]],
[[cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));]])],
[AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PUBSETBUF, 1, [whether pubsetbuf is available])],
[AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PUBSETBUF, 1, [Whether pubsetbuf is available.])],
AC_MSG_RESULT(no))
AC_LANG_POP(C++)
# Check for <locale>
# Check for chroot support (requires chroot() and bind mounts).
AC_CHECK_FUNCS([chroot])
AC_CHECK_FUNCS([unshare])
AC_CHECK_HEADERS([sched.h], [], [], [])
AC_CHECK_HEADERS([sys/param.h], [], [], [])
AC_CHECK_HEADERS([sys/mount.h], [], [],
[#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# endif
])
# Check for <locale>.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([locale])
AC_CHECK_HEADERS([locale], [], [], [])
AC_LANG_POP(C++)
# Check whether we have the personality() syscall, which allows us to
# do i686-linux builds on x86_64-linux machines.
AC_CHECK_HEADERS([sys/personality.h])
AC_DEFUN([NEED_PROG],
[
AC_PATH_PROG($1, $2)
@@ -111,7 +136,7 @@ fi
])
NEED_PROG(curl, curl)
NEED_PROG(shell, sh)
NEED_PROG(bash, bash)
NEED_PROG(patch, patch)
AC_PATH_PROG(xmllint, xmllint, false)
AC_PATH_PROG(xsltproc, xsltproc, false)
@@ -122,8 +147,23 @@ AC_PATH_PROG(bison, bison, false)
NEED_PROG(perl, perl)
NEED_PROG(tar, tar)
AC_PATH_PROG(dot, dot)
AC_PATH_PROG(dblatex, dblatex)
AC_PATH_PROG(gzip, gzip)
AC_PATH_PROG(openssl_prog, openssl, openssl) # if not found, call openssl in $PATH
AC_SUBST(openssl_prog)
AC_DEFINE_UNQUOTED(OPENSSL_PATH, ["$openssl_prog"], [Path of the OpenSSL binary])
# Test that Perl has the open/fork feature (Perl 5.8.0 and beyond).
AC_MSG_CHECKING([whether Perl is recent enough])
if ! $perl -e 'open(FOO, "-|", "true"); while (<FOO>) { print; }; close FOO or die;'; then
AC_MSG_RESULT(no)
AC_MSG_ERROR([Your Perl version is too old. Nix requires Perl 5.8.0 or newer.])
fi
AC_MSG_RESULT(yes)
NEED_PROG(cat, cat)
NEED_PROG(tr, tr)
AC_ARG_WITH(coreutils-bin, AC_HELP_STRING([--with-coreutils-bin=PATH],
[path of cat, mkdir, etc.]),
coreutils=$withval, coreutils=$(dirname $cat))
@@ -146,11 +186,16 @@ AC_SUBST(xmlflags)
AC_ARG_WITH(store-dir, AC_HELP_STRING([--with-store-dir=PATH],
[path of the Nix store]),
storedir=$withval, storedir='${prefix}/store')
storedir=$withval, storedir='/nix/store')
AC_SUBST(storedir)
AC_ARG_ENABLE(old-db-compat, AC_HELP_STRING([--disable-old-db-compat],
[disable support for converting from old Berkeley DB-based Nix stores]),
old_db_compat=$enableval, old_db_compat=yes)
AM_CONDITIONAL(OLD_DB_COMPAT, test "$old_db_compat" = "yes")
AC_ARG_WITH(bdb, AC_HELP_STRING([--with-bdb=PATH],
[prefix of Berkeley DB]),
[prefix of Berkeley DB (for Nix <= 0.11 compatibility)]),
bdb=$withval, bdb=)
AM_CONDITIONAL(HAVE_BDB, test -n "$bdb")
if test -z "$bdb"; then
@@ -160,6 +205,12 @@ else
bdb_lib="-L$bdb/lib -ldb_cxx"
bdb_include="-I$bdb/include"
fi
if test "$old_db_compat" = "no"; then
bdb_lib=
bdb_include=
else
AC_DEFINE(OLD_DB_COMPAT, 1, [Whether to support converting from old Berkeley DB-based Nix stores.])
fi
AC_SUBST(bdb_lib)
AC_SUBST(bdb_include)
@@ -188,7 +239,7 @@ if test -n "$openssl"; then
LDFLAGS="-L$openssl/lib -lcrypto $LDFLAGS"
CFLAGS="-I$openssl/include $CFLAGS"
CXXFLAGS="-I$openssl/include $CXXFLAGS"
AC_DEFINE(HAVE_OPENSSL, 1, [whether to use OpenSSL])
AC_DEFINE(HAVE_OPENSSL, 1, [Whether to use OpenSSL.])
fi
AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2=PATH],
@@ -201,7 +252,7 @@ if test -z "$bzip2"; then
bzip2_lib='-L${top_builddir}/externals/inst-bzip2/lib -lbz2'
bzip2_include='-I${top_builddir}/externals/inst-bzip2/include'
# The binary will be copied to $libexecdir.
bzip2_bin='${libexecdir}'
bzip2_bin='${libexecdir}/nix'
# But for testing, we have to use the temporary copy :-(
bzip2_bin_test='${top_builddir}/externals/inst-bzip2/bin'
else
@@ -226,33 +277,14 @@ AM_CONDITIONAL(INIT_STATE, test "$init_state" = "yes")
# Setuid installations.
AC_ARG_ENABLE(setuid, AC_HELP_STRING([--enable-setuid],
[install Nix setuid]),
setuid_hack=$enableval, setuid_hack=no)
AM_CONDITIONAL(SETUID_HACK, test "$setuid_hack" = "yes")
if test "$setuid_hack" = "yes"; then
AC_DEFINE(SETUID_HACK, 1, [whether to install Nix setuid])
fi
AC_CHECK_FUNCS([setresuid setreuid lchown])
AC_CHECK_FUNC(setresuid, [HAVE_SETRESUID=1], [HAVE_SETRESUID=])
AM_CONDITIONAL(HAVE_SETRESUID, test "$HAVE_SETRESUID" = "1")
if test "$HAVE_SETRESUID" = "1"; then
AC_DEFINE(HAVE_SETRESUID, 1, [whether we have setresuid()])
fi
AC_ARG_WITH(nix-user, AC_HELP_STRING([--with-nix-user=USER],
[user for Nix setuid binaries]),
NIX_USER=$withval, NIX_USER=nix)
AC_SUBST(NIX_USER)
AC_DEFINE_UNQUOTED(NIX_USER, ["$NIX_USER"], [Nix user])
AC_ARG_WITH(nix-group, AC_HELP_STRING([--with-nix-group=USER],
[group for Nix setuid binaries]),
NIX_GROUP=$withval, NIX_GROUP=nix)
AC_SUBST(NIX_GROUP)
AC_DEFINE_UNQUOTED(NIX_GROUP, ["$NIX_GROUP"], [Nix group])
# Nice to have, but not essential.
AC_CHECK_FUNCS([strsignal])
AC_CHECK_FUNCS([posix_fallocate])
# This is needed if ATerm, Berkeley DB or bzip2 are static libraries,
# and the Nix libraries are dynamic.
if test "$(uname)" = "Darwin"; then
@@ -260,6 +292,14 @@ if test "$(uname)" = "Darwin"; then
fi
if test "$static_nix" = yes; then
# `-all-static' has to be added at the end of configure, because
# the C compiler doesn't know about -all-static (it's filtered out
# by libtool, but configure doesn't use libtool).
LDFLAGS="-all-static $LDFLAGS"
fi
AM_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile
externals/Makefile
@@ -275,6 +315,8 @@ AC_CONFIG_FILES([Makefile
src/libexpr/Makefile
src/nix-instantiate/Makefile
src/nix-env/Makefile
src/nix-worker/Makefile
src/nix-setuid-helper/Makefile
src/nix-log2xml/Makefile
src/bsdiff-4.3/Makefile
scripts/Makefile

View File

@@ -12,13 +12,15 @@ mkdir "$out", 0755 || die "error creating $out";
my $symlinks = 0;
my %priorities;
# For each activated package, create symlinks.
sub createLinks {
my $srcDir = shift;
my $dstDir = shift;
my $ignoreCollisions = shift;
my $priority = shift;
my @srcFiles = glob("$srcDir/*");
@@ -42,7 +44,7 @@ sub createLinks {
lstat $dstFile;
if (-d _) {
createLinks($srcFile, $dstFile, $ignoreCollisions);
createLinks($srcFile, $dstFile, $priority);
}
elsif (-l _) {
@@ -53,27 +55,35 @@ sub createLinks {
unlink $dstFile or die "error unlinking `$dstFile': $!";
mkdir $dstFile, 0755 ||
die "error creating directory `$dstFile': $!";
createLinks($target, $dstFile, $ignoreCollisions);
createLinks($srcFile, $dstFile, $ignoreCollisions);
createLinks($target, $dstFile, $priorities{$dstFile});
createLinks($srcFile, $dstFile, $priority);
}
else {
symlink($srcFile, $dstFile) ||
die "error creating link `$dstFile': $!";
$priorities{$dstFile} = $priority;
$symlinks++;
}
}
elsif (-l $dstFile) {
if (!$ignoreCollisions) {
my $target = readlink $dstFile;
die "collission between `$srcFile' and `$target'";
}
}
else {
if (-l $dstFile) {
my $target = readlink $dstFile;
my $prevPriority = $priorities{$dstFile};
die ( "Collission between `$srcFile' and `$target'. "
. "Suggested solution: use `nix-env --set-flag "
. "priority NUMBER PKGNAME' to change the priority of "
. "one of the conflicting packages.\n" )
if $prevPriority == $priority;
next if $prevPriority < $priority;
unlink $dstFile or die;
}
symlink($srcFile, $dstFile) ||
die "error creating link `$dstFile': $!";
$priorities{$dstFile} = $priority;
$symlinks++;
}
}
@@ -86,13 +96,13 @@ my %postponed;
sub addPkg;
sub addPkg {
my $pkgDir = shift;
my $ignoreCollisions = shift;
my $priority = shift;
return if (defined $done{$pkgDir});
$done{$pkgDir} = 1;
# print "symlinking $pkgDir\n";
createLinks("$pkgDir", "$out", $ignoreCollisions);
createLinks("$pkgDir", "$out", $priority);
my $propagatedFN = "$pkgDir/nix-support/propagated-user-env-packages";
if (-e $propagatedFN) {
@@ -107,11 +117,29 @@ sub addPkg {
}
# Symlink to the packages that have been installed explicitly by the user.
my @args = split ' ', $ENV{"derivations"};
# Convert the stuff we get from the environment back into a coherent
# data type.
my @paths = split ' ', $ENV{"paths"};
my @active = split ' ', $ENV{"active"};
my @priority = split ' ', $ENV{"priority"};
foreach my $pkgDir (sort @args) {
addPkg($pkgDir, 0);
die if scalar @paths != scalar @active;
die if scalar @paths != scalar @priority;
my %pkgs;
for (my $n = 0; $n < scalar @paths; $n++) {
$pkgs{$paths[$n]} =
{ active => $active[$n]
, priority => $priority[$n] };
}
# Symlink to the packages that have been installed explicitly by the
# user.
foreach my $pkg (sort (keys %pkgs)) {
#print $pkg, " ", $pkgs{$pkg}->{priority}, "\n";
addPkg($pkg, $pkgs{$pkg}->{priority}) if $pkgs{$pkg}->{active} ne "false";
}
@@ -119,11 +147,12 @@ foreach my $pkgDir (sort @args) {
# installed by the user (i.e., package X declares that it want Y
# installed as well). We do these later because they have a lower
# priority in case of collisions.
my $priorityCounter = 1000; # don't care about collisions
while (scalar(keys %postponed) > 0) {
my @pkgDirs = keys %postponed;
%postponed = ();
foreach my $pkgDir (sort @pkgDirs) {
addPkg($pkgDir, 1);
addPkg($pkgDir, $priorityCounter++);
}
}

View File

@@ -4,6 +4,11 @@ derivation {
name = "user-environment";
system = system;
builder = ./builder.pl;
derivations = derivations;
manifest = manifest;
# !!! grmbl, need structured data for passing this in a clean way.
paths = derivations;
active = map (x: if x ? meta && x.meta ? active then x.meta.active else "true") derivations;
priority = map (x: if x ? meta && x.meta ? priority then x.meta.priority else "5") derivations;
}

View File

@@ -4,19 +4,29 @@
@coreutils@/mkdir $out/tmp
cd $out/tmp
expr=$out/default.nix
echo '[' > $expr
inputs=($inputs)
for ((n = 0; n < ${#inputs[*]}; n += 2)); do
channelName=${inputs[n]}
channelTarball=${inputs[n+1]}
echo "unpacking channel $channelName"
@bunzip2@ < $channelTarball | @tar@ xf -
nr=0
for i in $inputs; do
echo "unpacking $i"
@bunzip2@ < $i | @tar@ xf -
@coreutils@/mv * ../$nr # !!! hacky
echo "(import ./$nr)" >> $expr
nr=$(($nr + 1))
if test -e */channel-name; then
channelName="$(@coreutils@/cat */channel-name)"
fi
nr=1
attrName=$(echo $channelName | @tr@ -- '- ' '__')
dirName=$attrName
while test -e ../$dirName; do
nr=$((nr+1))
dirName=$attrName-$nr
done
@coreutils@/mv * ../$dirName # !!! hacky
done
echo ']' >> $expr
cd ..
@coreutils@/rmdir tmp

View File

@@ -1,5 +1,8 @@
To produce a `stable' release from the trunk:
-1. Update the release notes; make sure that the release date is
correct.
0. Make sure that the trunk builds in the release supervisor.
1. Branch the trunk, e.g., `svn cp .../trunk
@@ -22,8 +25,8 @@ To produce a `stable' release from the trunk:
branch (e.g., `.../branches/0.5') should be created from the
original revision of the trunk (since maintenance releases should
also be tested first; hence, we cannot have `STABLE=1'). The same
procedure can then be followed to produce maintenance release; just
substitute `.../branches/VERSION' for the trunk.
procedure can then be followed to produce maintenance releases;
just substitute `.../branches/VERSION' for the trunk.
7. Switch back to the trunk.

View File

@@ -14,15 +14,16 @@ XSLTPROC = $(xsltproc) $(xmlflags) \
man1_MANS = nix-env.1 nix-build.1 nix-store.1 nix-instantiate.1 \
nix-collect-garbage.1 nix-push.1 nix-pull.1 \
nix-prefetch-url.1 nix-channel.1 \
nix-pack-closure.1 nix-unpack-closure.1 \
nix-install-package.1 nix-hash.1
nix-install-package.1 nix-hash.1 nix-copy-closure.1
man8_MANS = nix-worker.8
FIGURES = figures/user-environments.png
MANUAL_SRCS = manual.xml introduction.xml installation.xml \
package-management.xml writing-nix-expressions.xml \
package-management.xml writing-nix-expressions.xml builtins.xml \
build-farm.xml \
$(man1_MANS:.1=.xml) \
$(man1_MANS:.1=.xml) $(man8_MANS:.8=.xml) \
troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \
env-common.xml quick-start.xml nix-lang-ref.xml glossary.xml \
conf-file.xml release-notes.xml \
@@ -31,7 +32,7 @@ MANUAL_SRCS = manual.xml introduction.xml installation.xml \
manual.is-valid: $(MANUAL_SRCS) version.txt
# $(XMLLINT) --xinclude $< | $(XMLLINT) --noout --nonet --relaxng $(docbookrng)/docbook.rng -
if test "$(jing)" != "false"; then \
$(XMLLINT) --xinclude $< | $(jing) $(docbookrng)/docbook.rng /dev/stdin; \
$(XMLLINT) --xinclude $< | $(jing) $(docbookrng)/docbook.rng /dev/fd/0; \
else \
echo "Not validating."; \
fi
@@ -47,6 +48,14 @@ manual.html: $(MANUAL_SRCS) manual.is-valid images
$(XSLTPROC) --nonet --xinclude --output manual.html \
$(docbookxsl)/html/docbook.xsl manual.xml
manual.pdf: $(MANUAL_SRCS) manual.is-valid images
if test "$(dblatex)" != ""; then \
$(dblatex) manual.xml; \
else \
echo "Please install dblatex and rerun configure."; \
exit 1; \
fi
NEWS_OPTS = \
--stringparam generate.toc "article nop" \
@@ -68,12 +77,16 @@ NEWS.txt: release-notes.xml
all-local: manual.html NEWS.html NEWS.txt
install-data-local: manual.html
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/manual
$(INSTALL_DATA) manual.html $(DESTDIR)$(datadir)/nix/manual
$(INSTALL_DATA) style.css $(DESTDIR)$(datadir)/nix/manual
cp -r images $(DESTDIR)$(datadir)/nix/manual/images
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/manual/figures
$(INSTALL_DATA) $(FIGURES) $(DESTDIR)$(datadir)/nix/manual/figures
$(INSTALL) -d $(DESTDIR)$(docdir)/manual
$(INSTALL_DATA) manual.html $(DESTDIR)$(docdir)/manual
ln -sf manual.html $(DESTDIR)$(docdir)/manual/index.html
$(INSTALL_DATA) style.css $(DESTDIR)$(docdir)/manual
cp -r images $(DESTDIR)$(docdir)/manual/images
$(INSTALL) -d $(DESTDIR)$(docdir)/manual/figures
$(INSTALL_DATA) $(FIGURES) $(DESTDIR)$(docdir)/manual/figures
$(INSTALL) -d $(DESTDIR)$(docdir)/release-notes
$(INSTALL_DATA) NEWS.html $(DESTDIR)$(docdir)/release-notes/index.html
$(INSTALL_DATA) style.css $(DESTDIR)$(docdir)/release-notes/
images:
mkdir images

View File

@@ -15,18 +15,6 @@ generation 43 is created which is a descendant of 39, not 42. So a
rollback from 43 ought to go back to 39. This is not currently
implemented; generations form a linear sequence.</para></listitem>
<listitem><para><emphasis>Build management.</emphasis> In principle it
is already possible to do build management using Nix (by writing
builders that perform appropriate build steps), but the Nix expression
language is not yet powerful enough to make this pleasant (?). The
language should be extended with features from the <link
xlink:href='http://www.cs.uu.nl/~eelco/maak/'>Maak build
manager</link>. Another interesting idea is to write a
<command>make</command> implementation that uses Nix as a back-end to
support <link
xlink:href='http://www.research.att.com/~bs/bs_faq.html#legacy'>legacy</link>
build files.</para></listitem>
<listitem><para>For security, <command>nix-push</command> manifests
should be digitally signed, and <command>nix-pull</command> should
verify the signatures. The actual NAR archives in the cache do not

View File

@@ -36,10 +36,10 @@ build farm, since:
builds, and Nix expressions are self-contained.</para></listitem>
<listitem><para>Nix will only rebuild things that have actually
changed. For instance, if the sources of a component haven't
changed between runs of the build farm, the component won't be
rebuild (unless it was garbage-collected). Also, dependencies
typically don't change very often, so they only need to be built
changed. For instance, if the sources of a package haven't changed
between runs of the build farm, the package won't be rebuilt (unless
it was garbage-collected). Also, dependencies typically don't
change very often, so they only need to be built
once.</para></listitem>
<listitem><para>The results of a Nix build farm can be made
@@ -56,7 +56,7 @@ build farm, since:
<para>TODO</para>
<para>The sources of the Nix build farm are at <link
xlink:href='https://svn.cs.uu.nl:12443/repos/trace/release/trunk'/>.</para>
xlink:href='https://svn.nixos.org/repos/nix/release/trunk'/>.</para>
</section>
@@ -85,7 +85,7 @@ nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto
<para>An example build hook can be found in the Nix build farm
sources: <link
xlink:href='https://svn.cs.uu.nl:12443/repos/trace/release/trunk/common/distributed/build-remote.pl'
xlink:href='https://svn.nixos.org/repos/nix/release/trunk/common/distributed/build-remote.pl'
/>. It should be suitable for most purposes, with maybe some minor
adjustments. It uses <command>ssh</command> and
<command>rsync</command> to copy the build inputs and outputs and

841
doc/manual/builtins.xml Normal file
View File

@@ -0,0 +1,841 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id='ssec-builtins'>
<title>Built-in functions</title>
<para>This section lists the functions and constants built into the
Nix expression evaluator. (The built-in function
<function>derivation</function> is discussed above.) Some built-ins,
such as <function>derivation</function>, are always in scope of every
Nix expression; you can just access them right away. But to prevent
polluting the namespace too much, most built-ins are not in scope.
Instead, you can access them through the <varname>builtins</varname>
built-in value, which is an attribute set that contains all built-in
functions and values. For instance, <function>derivation</function>
is also available as <function>builtins.derivation</function>.</para>
<variablelist>
<varlistentry><term><function>abort</function> <replaceable>s</replaceable></term>
<listitem><para>Abort Nix expression evaluation, print error
message <replaceable>s</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.add</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return the sum of the integers
<replaceable>e1</replaceable> and
<replaceable>e2</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.attrNames</function>
<replaceable>attrs</replaceable></term>
<listitem><para>Return the names of the attributes in the
attribute set <replaceable>attrs</replaceable> in a sorted list.
For instance, <literal>builtins.attrNames {y = 1; x =
"foo";}</literal> evaluates to <literal>["x" "y"]</literal>.
There is no built-in function <function>attrValues</function>, but
you can easily define it yourself:
<programlisting>
attrValues = attrs: map (name: builtins.getAttr name attrs) (builtins.attrNames attrs);</programlisting>
</para></listitem>
</varlistentry>
<varlistentry><term><function>baseNameOf</function> <replaceable>s</replaceable></term>
<listitem><para>Return the <emphasis>base name</emphasis> of the
string <replaceable>s</replaceable>, that is, everything following
the final slash in the string. This is similar to the GNU
<command>basename</command> command.</para></listitem>
</varlistentry>
<varlistentry><term><varname>builtins</varname></term>
<listitem><para>The attribute set <varname>builtins</varname>
contains all the built-in functions and values. You can use
<varname>builtins</varname> to test for the availability of
features in the Nix installation, e.g.,
<programlisting>
if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
This allows a Nix expression to fall back gracefully on older Nix
installations that dont have the desired built-in
function.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.compareVersions</function>
<replaceable>s1</replaceable> <replaceable>s2</replaceable></term>
<listitem><para>Compare two strings representing versions and
return <literal>-1</literal> if version
<replaceable>s1</replaceable> is older than version
<replaceable>s2</replaceable>, <literal>0</literal> if they are
the same, and <literal>1</literal> if
<replaceable>s1</replaceable> is newer than
<replaceable>s2</replaceable>. The version comparison algorithm
is the same as the one used by <link
linkend="ssec-version-comparisons"><command>nix-env
-u</command></link>.</para></listitem>
</varlistentry>
<varlistentry
xml:id='builtin-currentSystem'><term><varname>builtins.currentSystem</varname></term>
<listitem><para>The built-in value <varname>currentSystem</varname>
evaluates to the Nix platform identifier for the Nix installation
on which the expression is being evaluated, such as
<literal>"i686-linux"</literal> or
<literal>"powerpc-darwin"</literal>.</para></listitem>
</varlistentry>
<!--
<varlistentry><term><function>currentTime</function></term>
<listitem><para>The built-in value <varname>currentTime</varname>
returns the current system time in seconds since 00:00:00 1/1/1970
UTC. Due to the evaluation model of Nix expressions
(<emphasis>maximal laziness</emphasis>), it always yields the same
value within an execution of Nix.</para></listitem>
</varlistentry>
-->
<!--
<varlistentry><term><function>dependencyClosure</function></term>
<listitem><para>TODO</para></listitem>
</varlistentry>
-->
<varlistentry><term><function>derivation</function>
<replaceable>attrs</replaceable></term>
<listitem><para><function>derivation</function> is described in
<xref linkend='ssec-derivation' />.</para></listitem>
</varlistentry>
<varlistentry><term><function>dirOf</function> <replaceable>s</replaceable></term>
<listitem><para>Return the directory part of the string
<replaceable>s</replaceable>, that is, everything before the final
slash in the string. This is similar to the GNU
<command>dirname</command> command.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.div</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return the quotient of the integers
<replaceable>e1</replaceable> and
<replaceable>e2</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.filterSource</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem>
<para>This function allows you to copy sources into the Nix
store while filtering certain files. For instance, suppose that
you want to use the directory <filename>source-dir</filename> as
an input to a Nix expression, e.g.
<programlisting>
stdenv.mkDerivation {
...
src = ./source-dir;
}
</programlisting>
However, if <filename>source-dir</filename> is a Subversion
working copy, then all those annoying <filename>.svn</filename>
subdirectories will also be copied to the store. Worse, the
contents of those directories may change a lot, causing lots of
spurious rebuilds. With <function>filterSource</function> you
can filter out the <filename>.svn</filename> directories:
<programlisting>
src = builtins.filterSource
(path: type: type != "directory" || baseNameOf path != ".svn")
./source-dir;
</programlisting>
</para>
<para>Thus, the first argument <replaceable>e1</replaceable>
must be a predicate function that is called for each regular
file, directory or symlink in the source tree
<replaceable>e2</replaceable>. If the function returns
<literal>true</literal>, the file is copied to the Nix store,
otherwise it is omitted. The function is called with two
arguments. The first is the full path of the file. The second
is a string that identifies the type of the file, which is
either <literal>"regular"</literal>,
<literal>"directory"</literal>, <literal>"symlink"</literal> or
<literal>"unknown"</literal> (for other kinds of files such as
device nodes or fifos — but note that those cannot be copied to
the Nix store, so if the predicate returns
<literal>true</literal> for them, the copy will fail).</para>
</listitem>
</varlistentry>
<varlistentry><term><function>builtins.getAttr</function>
<replaceable>s</replaceable> <replaceable>attrs</replaceable></term>
<listitem><para><function>getAttr</function> returns the attribute
named <replaceable>s</replaceable> from the attribute set
<replaceable>attrs</replaceable>. Evaluation aborts if the
attribute doesnt exist. This is a dynamic version of the
<literal>.</literal> operator, since <replaceable>s</replaceable>
is an expression rather than an identifier.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.getEnv</function>
<replaceable>s</replaceable></term>
<listitem><para><function>getEnv</function> returns the value of
the environment variable <replaceable>s</replaceable>, or an empty
string if the variable doesnt exist. This function should be
used with care, as it can introduce all sorts of nasty environment
dependencies in your Nix expression.</para>
<para><function>getEnv</function> is used in Nix Packages to
locate the file <filename>~/.nixpkgs/config.nix</filename>, which
contains user-local settings for Nix Packages. (That is, it does
a <literal>getEnv "HOME"</literal> to locate the users home
directory.)</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.hasAttr</function>
<replaceable>s</replaceable> <replaceable>attrs</replaceable></term>
<listitem><para><function>hasAttr</function> returns
<literal>true</literal> if the attribute set
<replaceable>attrs</replaceable> has an attribute named
<replaceable>s</replaceable>, and <literal>false</literal>
otherwise. This is a dynamic version of the <literal>?</literal>
operator, since <replaceable>s</replaceable> is an expression
rather than an identifier.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.head</function>
<replaceable>list</replaceable></term>
<listitem><para>Return the first element of a list; abort
evaluation if the argument isnt a list or is an empty list. You
can test whether a list is empty by comparing it with
<literal>[]</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><function>import</function>
<replaceable>path</replaceable></term>
<listitem><para>Load, parse and return the Nix expression in the
file <replaceable>path</replaceable>. Evaluation aborts if the
file doesnt exist or contains an incorrect Nix
expression. <function>import</function> implements Nixs module
system: you can put any Nix expression (such as an attribute set
or a function) in a separate file, and use it from Nix expressions
in other files.</para>
<para>A Nix expression loaded by <function>import</function> must
not contain any <emphasis>free variables</emphasis> (identifiers
that are not defined in the Nix expression itself and are not
built-in). Therefore, it cannot refer to variables that are in
scope at the call site. For instance, if you have a calling
expression
<programlisting>
rec {
x = 123;
y = import ./foo.nix;
}</programlisting>
then the following <filename>foo.nix</filename> will give an
error:
<programlisting>
x + 456</programlisting>
since <varname>x</varname> is not in scope in
<filename>foo.nix</filename>. If you want <varname>x</varname>
to be available in <filename>foo.nix</filename>, you should pass
it as a function argument:
<programlisting>
rec {
x = 123;
y = import ./foo.nix x;
}</programlisting>
and
<programlisting>
x: x + 456</programlisting>
(The function argument doesnt have to be called
<varname>x</varname> in <filename>foo.nix</filename>; any name
would work.)</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isAttrs</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to an attribute set, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isList</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a list, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isFunction</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a function, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isString</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a string, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isInt</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a int, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.isBool</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a bool, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry><term><function>isNull</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to <literal>null</literal>,
and <literal>false</literal> otherwise.</para>
<warning><para>This function is <emphasis>deprecated</emphasis>;
just write <literal>e == null</literal> instead.</para></warning>
</listitem>
</varlistentry>
<varlistentry><term><function>builtins.length</function>
<replaceable>e</replaceable></term>
<listitem><para>Return the length of the list
<replaceable>e</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.lessThan</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return <literal>true</literal> if the integer
<replaceable>e1</replaceable> is less than the integer
<replaceable>e2</replaceable>, and <literal>false</literal>
otherwise. Evaluation aborts if either
<replaceable>e1</replaceable> or <replaceable>e2</replaceable>
does not evaluate to an integer.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.listToAttrs</function>
<replaceable>e</replaceable></term>
<listitem><para>Construct an attribute set from a list specifying
the names and values of each attribute. Each element of the list
should be an attribute set consisting of a string-valued attribute
<varname>name</varname> specifying the name of the attribute, and
an attribute <varname>value</varname> specifying its value.
Example:
<programlisting>
builtins.listToAttrs [
{name = "foo"; value = 123;}
{name = "bar"; value = 456;}
]
</programlisting>
evaluates to
<programlisting>
{ foo = 123; bar = 456; }
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry><term><function>map</function>
<replaceable>f</replaceable> <replaceable>list</replaceable></term>
<listitem><para>Apply the function <replaceable>f</replaceable> to
each element in the list <replaceable>list</replaceable>. For
example,
<programlisting>
map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
evaluates to <literal>["foobar" "foobla"
"fooabc"]</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.mul</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return the product of the integers
<replaceable>e1</replaceable> and
<replaceable>e2</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.parseDrvName</function>
<replaceable>s</replaceable></term>
<listitem><para>Split the string <replaceable>s</replaceable> into
a package name and version. The package name is everything up to
but not including the first dash followed by a digit, and the
version is everything following that dash. The result is returned
in an attribute set <literal>{name, version}</literal>. Thus,
<literal>builtins.parseDrvName "nix-0.12pre12876"</literal>
returns <literal>{name = "nix"; version =
"0.12pre12876";}</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.pathExists</function>
<replaceable>path</replaceable></term>
<listitem><para>Return <literal>true</literal> if the path
<replaceable>path</replaceable> exists, and
<literal>false</literal> otherwise. One application of this
function is to conditionally include a Nix expression containing
user configuration:
<programlisting>
let
fileName = builtins.getEnv "CONFIG_FILE";
config =
if fileName != "" &amp;&amp; builtins.pathExists (builtins.toPath fileName)
then import (builtins.toPath fileName)
else { someSetting = false; }; <lineannotation># default configuration</lineannotation>
in config.someSetting</programlisting>
(Note that <envar>CONFIG_FILE</envar> must be an absolute path for
this to work.)</para></listitem>
</varlistentry>
<!--
<varlistentry><term><function>relativise</function></term>
<listitem><para>TODO</para></listitem>
</varlistentry>
-->
<varlistentry><term><function>builtins.readFile</function>
<replaceable>path</replaceable></term>
<listitem><para>Return the contents of the file
<replaceable>path</replaceable> as a string.</para></listitem>
</varlistentry>
<varlistentry><term><function>removeAttrs</function>
<replaceable>attrs</replaceable> <replaceable>list</replaceable></term>
<listitem><para>Remove the attributes listed in
<replaceable>list</replaceable> from the attribute set
<replaceable>attrs</replaceable>. The attributes dont have to
exist in <replaceable>attrs</replaceable>. For instance,
<screen>
removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
evaluates to <literal>{y = 2;}</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.stringLength</function>
<replaceable>e</replaceable></term>
<listitem><para>Return the length of the string
<replaceable>e</replaceable>. If <replaceable>e</replaceable> is
not a string, evaluation is aborted.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.sub</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Return the difference between the integers
<replaceable>e1</replaceable> and
<replaceable>e2</replaceable>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.substring</function>
<replaceable>start</replaceable> <replaceable>len</replaceable>
<replaceable>s</replaceable></term>
<listitem><para>Return the substring of
<replaceable>s</replaceable> from character position
<replaceable>start</replaceable> (zero-based) up to but not
including <replaceable>start + len</replaceable>. If
<replaceable>start</replaceable> is greater than the length of the
string, an empty string is returned, and if <replaceable>start +
len</replaceable> lies beyond the end of the string, only the
substring up to the end of the string is returned.
<replaceable>start</replaceable> must be
non-negative.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.tail</function>
<replaceable>list</replaceable></term>
<listitem><para>Return the second to last elements of a list;
abort evaluation if the argument isnt a list or is an empty
list.</para></listitem>
</varlistentry>
<varlistentry><term><function>throw</function>
<replaceable>s</replaceable></term>
<listitem><para>Throw an error message
<replaceable>s</replaceable>. This usually aborts Nix expression
evaluation, but in <command>nix-env -qa</command> and other
commands that try to evaluate a set of derivations to get
information about those derivations, a derivation that throws an
error is silently skipped (which is not the case for
<function>abort</function>).</para></listitem>
</varlistentry>
<varlistentry
xml:id='builtin-toFile'><term><function>builtins.toFile</function>
<replaceable>name</replaceable> <replaceable>s</replaceable></term>
<listitem><para>Store the string <replaceable>s</replaceable> in a
file in the Nix store and return its path. The file has suffix
<replaceable>name</replaceable>. This file can be used as an
input to derivations. One application is to write builders
“inline”. For instance, the following Nix expression combines
<xref linkend='ex-hello-nix' /> and <xref
linkend='ex-hello-builder' /> into one file:
<programlisting>
{stdenv, fetchurl, perl}:
stdenv.mkDerivation {
name = "hello-2.1.1";
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
PATH=$perl/bin:$PATH
tar xvfz $src
cd hello-*
./configure --prefix=$out
make
make install
";
src = fetchurl {
url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
md5 = "70c9ccf9fac07f762c24f2df2290784d";
};
inherit perl;
}</programlisting>
</para>
<para>It is even possible for one file to refer to another, e.g.,
<programlisting>
builder = let
configFile = builtins.toFile "foo.conf" "
# This is some dummy configuration file.
<replaceable>...</replaceable>
";
in builtins.toFile "builder.sh" "
source $stdenv/setup
<replaceable>...</replaceable>
cp ${configFile} $out/etc/foo.conf
";</programlisting>
Note that <literal>${configFile}</literal> is an antiquotation
(see <xref linkend='ssec-values' />), so the result of the
expression <literal>configFile</literal> (i.e., a path like
<filename>/nix/store/m7p7jfny445k...-foo.conf</filename>) will be
spliced into the resulting string.</para>
<para>It is however <emphasis>not</emphasis> allowed to have files
mutually referring to each other, like so:
<programlisting>
let
foo = builtins.toFile "foo" "...${bar}...";
bar = builtins.toFile "bar" "...${foo}...";
in foo</programlisting>
This is not allowed because it would cause a cyclic dependency in
the computation of the cryptographic hashes for
<varname>foo</varname> and <varname>bar</varname>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.toPath</function> <replaceable>s</replaceable></term>
<listitem><para>Convert the string value
<replaceable>s</replaceable> into a path value. The string
<replaceable>s</replaceable> must represent an absolute path
(i.e., must start with <literal>/</literal>). The path need not
exist. The resulting path is canonicalised, e.g.,
<literal>builtins.toPath "//foo/xyzzy/../bar/"</literal> returns
<literal>/foo/bar</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><function>toString</function> <replaceable>e</replaceable></term>
<listitem><para>Convert the expression
<replaceable>e</replaceable> to a string.
<replaceable>e</replaceable> can be a string (in which case
<function>toString</function> is a no-op) or a path (e.g.,
<literal>toString /foo/bar</literal> yields
<literal>"/foo/bar"</literal>.</para></listitem>
</varlistentry>
<varlistentry xml:id='builtin-toXML'><term><function>builtins.toXML</function> <replaceable>e</replaceable></term>
<listitem><para>Return a string containing an XML representation
of <replaceable>e</replaceable>. The main application for
<function>toXML</function> is to communicate information with the
builder in a more structured format than plain environment
variables.</para>
<!-- TODO: more formally describe the schema of the XML
representation -->
<para><xref linkend='ex-toxml' /> shows an example where this is
the case. The builder is supposed to generate the configuration
file for a <link xlink:href='http://jetty.mortbay.org/'>Jetty
servlet container</link>. A servlet container contains a number
of servlets (<filename>*.war</filename> files) each exported under
a specific URI prefix. So the servlet configuration is a list of
attribute sets containing the <varname>path</varname> and
<varname>war</varname> of the servlet (<xref
linkend='ex-toxml-co-servlets' />). This kind of information is
difficult to communicate with the normal method of passing
information through an environment variable, which just
concatenates everything together into a string (which might just
work in this case, but wouldnt work if fields are optional or
contain lists themselves). Instead the Nix expression is
converted to an XML representation with
<function>toXML</function>, which is unambiguous and can easily be
processed with the appropriate tools. For instance, in the
example an XSLT stylesheet (<xref linkend='ex-toxml-co-stylesheet'
/>) is applied to it (<xref linkend='ex-toxml-co-apply' />) to
generate the XML configuration file for the Jetty server. The XML
representation produced from <xref linkend='ex-toxml-co-servlets'
/> by <function>toXML</function> is shown in <xref
linkend='ex-toxml-result' />.</para>
<para>Note that <xref linkend='ex-toxml' /> uses the <function
linkend='builtin-toFile'>toFile</function> built-in to write the
builder and the stylesheet “inline” in the Nix expression. The
path of the stylesheet is spliced into the builder at
<literal>xsltproc ${stylesheet}
<replaceable>...</replaceable></literal>.</para>
<example xml:id='ex-toxml'><title>Passing information to a builder
using <function>toXML</function></title>
<programlisting><![CDATA[
{stdenv, fetchurl, libxslt, jira, uberwiki}:
stdenv.mkDerivation (rec {
name = "web-server";
buildInputs = [libxslt];
builder = builtins.toFile "builder.sh" "
source $stdenv/setup
mkdir $out
echo $servlets | xsltproc ${stylesheet} - > $out/server-conf.xml]]> <co xml:id='ex-toxml-co-apply' /> <![CDATA[
";
stylesheet = builtins.toFile "stylesheet.xsl"]]> <co xml:id='ex-toxml-co-stylesheet' /> <![CDATA[
"<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:template match='/'>
<Configure>
<xsl:for-each select='/expr/list/attrs'>
<Call name='addWebApplication'>
<Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
<Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
</Call>
</xsl:for-each>
</Configure>
</xsl:template>
</xsl:stylesheet>
";
servlets = builtins.toXML []]> <co xml:id='ex-toxml-co-servlets' /> <![CDATA[
{ path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
{ path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
];
})]]></programlisting>
</example>
<example xml:id='ex-toxml-result'><title>XML representation produced by
<function>toXML</function></title>
<programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
<expr>
<list>
<attrs>
<attr name="path">
<string value="/bugtracker" />
</attr>
<attr name="war">
<path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
</attr>
</attrs>
<attrs>
<attr name="path">
<string value="/wiki" />
</attr>
<attr name="war">
<path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
</attr>
</attrs>
</list>
</expr>]]></programlisting>
</example>
</listitem>
</varlistentry>
<varlistentry><term><function>builtins.trace</function>
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
<listitem><para>Evaluate <replaceable>e1</replaceable> and print its
abstract syntax representation on standard error. Then return
<replaceable>e2</replaceable>. This function is useful for
debugging.</para></listitem>
</varlistentry>
</variablelist>
</section>

View File

@@ -60,27 +60,6 @@ env-keep-derivations = false
</varlistentry>
<varlistentry xml:id="conf-gc-reserved-space"><term><literal>gc-reserved-space</literal></term>
<listitem><para>This option specifies how much space should be
reserved in normal use so that the garbage collector can run
succesfully. Since the garbage collector must perform Berkeley DB
transactions, it needs some disk space for itself. However, when
the disk is full, this space is not available, so the collector
would not be able to run precisely when it is most needed.</para>
<para>For this reason, when Nix is run, it allocates a file
<filename>/nix/var/nix/db/reserved</filename> of the size
specified by this option. When the garbage collector is run, this
file is deleted before the Berkeley DB environment is opened.
This should give it enough room to proceed.</para>
<para>The default is <literal>1048576</literal> (1
MiB).</para></listitem>
</varlistentry>
<varlistentry><term><literal>env-keep-derivations</literal></term>
<listitem><para>If <literal>false</literal> (default), derivations
@@ -118,6 +97,123 @@ env-keep-derivations = false
</varlistentry>
<varlistentry xml:id="conf-build-max-silent-time"><term><literal>build-max-silent-time</literal></term>
<listitem>
<para>This option defines the maximum number of seconds that a
builder can go without producing any data on standard output or
standard error. This is useful (for instance in a automated
build system) to catch builds that are stuck in an infinite
loop, or to catch remote builds that are hanging due to network
problems. It can be overriden using the <option
linkend="opt-max-silent-time">--max-silent-time</option> command
line switch.</para>
<para>The value <literal>0</literal> means that there is no
timeout. This is also the default.</para>
</listitem>
</varlistentry>
<varlistentry xml:id="conf-build-users-group"><term><literal>build-users-group</literal></term>
<listitem><para>This options specifies the Unix group containing
the Nix build user accounts. In multi-user Nix installations,
builds should not be performed by the Nix account since that would
allow users to arbitrarily modify the Nix store and database by
supplying specially crafted builders; and they cannot be performed
by the calling user since that would allow him/her to influence
the build result.</para>
<para>Therefore, if this option is non-empty and specifies a valid
group, builds will be performed under the user accounts that are a
member of the group specified here (as listed in
<filename>/etc/group</filename>). Those user accounts should not
be used for any other purpose!</para>
<para>Nix will never run two builds under the same user account at
the same time. This is to prevent an obvious security hole: a
malicious user writing a Nix expression that modifies the build
result of a legitimate Nix expression being built by another user.
Therefore it is good to have as many Nix build user accounts as
you can spare. (Remember: uids are cheap.)</para>
<para>The build users should have permission to create files in
the Nix store, but not delete them. Therefore,
<filename>/nix/store</filename> should be owned by the Nix
account, its group should be the group specified here, and its
mode should be <literal>1775</literal>.</para>
<para>If the build users group is empty, builds will be performed
under the uid of the Nix process (that is, the uid of the caller
if <envar>NIX_REMOTE</envar> is empty, the uid under which the Nix
daemon runs if <envar>NIX_REMOTE</envar> is
<literal>daemon</literal>, or the uid that owns the setuid
<command>nix-worker</command> program if <envar>NIX_REMOTE</envar>
is <literal>slave</literal>). Obviously, this should not be used
in multi-user settings with untrusted users.</para>
</listitem>
</varlistentry>
<varlistentry><term><literal>build-use-chroot</literal></term>
<listitem><para>If set to <literal>true</literal>, builds will be
performed in a <emphasis>chroot environment</emphasis>, i.e., the
build will be isolated from the normal file system hierarchy and
will only see the Nix store, the temporary build directory, and
the directories configured with the <link
linkend='conf-build-chroot-dirs'><literal>build-chroot-dirs</literal>
option</link> (such as <filename>/proc</filename> and
<filename>/dev</filename>). This is useful to prevent undeclared
dependencies on files in directories such as
<filename>/usr/bin</filename>.</para>
<para>The use of a chroot requires that Nix is run as root (but
you can still use the <link
linkend='conf-build-users-group'>“build users” feature</link> to
perform builds under different users than root). Currently,
chroot builds only work on Linux because Nix uses “bind mounts” to
make the Nix store and other directories available inside the
chroot.</para>
</listitem>
</varlistentry>
<varlistentry xml:id="conf-build-chroot-dirs"><term><literal>build-chroot-dirs</literal></term>
<listitem><para>When builds are performed in a chroot environment,
Nix will mount (using <command>mount --bind</command> on Linux)
some directories from the normal file system hierarchy inside the
chroot. These are the Nix store, the temporary build directory
(usually
<filename>/tmp/nix-<replaceable>pid</replaceable>-<replaceable>number</replaceable></filename>)
and the directories listed here. The default is <literal>dev
/proc</literal>. Files in <filename>/dev</filename> (such as
<filename>/dev/null</filename>) are needed by many builds, and
some files in <filename>/proc</filename> may also be needed
occasionally.</para>
<para>The value used on NixOS is
<programlisting>
build-use-chroot = /dev /proc /bin</programlisting>
to make the <filename>/bin/sh</filename> symlink available (which
is still needed by many builders).</para>
</listitem>
</varlistentry>
<varlistentry><term><literal>system</literal></term>
<listitem><para>This option specifies the canonical Nix system

View File

@@ -10,17 +10,6 @@
<variablelist>
<varlistentry><term><envar>NIX_ROOT</envar></term>
<listitem><para>If <envar>NIX_ROOT</envar> is set, the Nix command
will on startup perform a <function>chroot()</function> to the
specified directory. This is useful in certain bootstrapping
situations (e.g., when installing a Nix installation onto a hard
disk from CD-ROM).</para></listitem>
</varlistentry>
<varlistentry><term><envar>NIX_IGNORE_SYMLINK_STORE</envar></term>
<listitem>
@@ -162,12 +151,12 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<para>On the basis of this information, and whatever persistent
state the build hook keeps about other machines and their current
load, it has to decide what to do with the build. It should print
out on file descriptor 3 one of the following responses (terminated
by a newline, <literal>"\n"</literal>):
out on standard error one of the following responses (terminated by
a newline, <literal>"\n"</literal>):
<variablelist>
<varlistentry><term><literal>decline</literal></term>
<varlistentry><term><literal># decline</literal></term>
<listitem><para>The build hook is not willing or able to perform
the build; the calling Nix process should do the build itself,
@@ -175,7 +164,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
<varlistentry><term><literal>postpone</literal></term>
<varlistentry><term><literal># postpone</literal></term>
<listitem><para>The build hook cannot perform the build now, but
can do so in the future (e.g., because all available build slots
@@ -185,7 +174,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
<varlistentry><term><literal>accept</literal></term>
<varlistentry><term><literal># accept</literal></term>
<listitem><para>The build hook has accepted the
build.</para></listitem>
@@ -196,37 +185,12 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</para>
<para>If the build hook accepts the build, it is possible that it is
no longer necessary to do the build because some other process has
performed the build in the meantime. To prevent races, the hook
must read from file descriptor 4 a single line that tells it whether
to continue:
<variablelist>
<varlistentry><term><literal>cancel</literal></term>
<listitem><para>The build has already been done, so the hook
should exit.</para></listitem>
</varlistentry>
<varlistentry><term><literal>okay</literal></term>
<listitem><para>The hook should proceed with the build. At this
point, the calling Nix process has acquired locks on the output
path, so no other Nix process will perform the
build.</para></listitem>
</varlistentry>
</variablelist>
</para>
<para>If the hook has been told to proceed, Nix will store in the
hooks current directory a number of text files that contain
information about the derivation:
<para>After sending <literal># accept</literal>, the hook should
read one line from standard input, which will be the string
<literal>okay</literal>. It can then proceed with the build.
Before sending <literal>okay</literal>, Nix will store in the hooks
current directory a number of text files that contain information
about the derivation:
<variablelist>
@@ -266,7 +230,9 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<para>The hook should copy the inputs to the remote machine,
register the validity of the inputs, perform the remote build, and
copy the outputs back to the local machine. An exit code other than
<literal>0</literal> indicates that the hook has failed.</para>
<literal>0</literal> indicates that the hook has failed. An exit
code equal to 100 means that the remote build failed (as opposed to,
e.g., a network error).</para>
</listitem>
@@ -274,6 +240,38 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
<varlistentry xml:id="envar-remote"><term><envar>NIX_REMOTE</envar></term>
<listitem><para>This variable should be set to
<literal>daemon</literal> if you want to use the Nix daemon to
executed Nix operations, which is necessary in <link
linkend="ssec-multi-user">multi-user Nix installations</link>.
Otherwise, it should be left unset.</para></listitem>
</varlistentry>
<varlistentry xml:id="envar-other-stores"><term><envar>NIX_OTHER_STORES</envar></term>
<listitem><para>This variable contains the paths of remote Nix
installations from whichs paths can be copied, separated by colons.
See <xref linkend="sec-sharing-packages" /> for details. Each path
should be the <filename>/nix</filename> directory of a remote Nix
installation (i.e., not the <filename>/nix/store</filename>
directory). The paths are subject to globbing, so you can set it so
something like <literal>/var/run/nix/remote-stores/*/nix</literal>
and mount multiple remote filesystems in
<literal>/var/run/nix/remote-stores</literal>.</para>
<para>Note that if youre building through the <link
linkend="sec-nix-worker">Nix daemon</link>, the only setting for
this variable that matters is the one that the
<command>nix-worker</command> process uses. So if you want to
change it, you have to restart the daemon.</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -74,9 +74,9 @@
<glossentry><glossterm>Nix expression</glossterm>
<glossdef><para>A high-level description of software components and
<glossdef><para>A high-level description of software packages and
compositions thereof. Deploying software using Nix entails writing
Nix expressions for your components. Nix expressions are translated
Nix expressions for your packages. Nix expressions are translated
to derivations that are stored in the Nix store. These derivations
can then be built.</para></glossdef>

View File

@@ -6,29 +6,58 @@
<title>Installation</title>
<section><title>Supported platforms</title>
<para>Nix is currently supported on the following platforms:
<itemizedlist>
<listitem><para>Linux (particularly on x86, x86_64, and
PowerPC).</para></listitem>
<listitem><para>Mac OS X, both on Intel and
PowerPC.</para></listitem>
<listitem><para>FreeBSD (only tested on Intel).</para></listitem>
<listitem><para>Windows through <link
xlink:href="http://www.cygwin.com/">Cygwin</link>.</para>
<warning><para>On Cygwin, Nix <emphasis>must</emphasis> be installed
on an NTFS partition. It will not work correctly on a FAT
partition.</para></warning>
</listitem>
</itemizedlist>
</para>
<para>Nix is pretty portable, so it should work on most other Unix
platforms as well.</para>
</section>
<section><title>Obtaining Nix</title>
<para>The easiest way to obtain Nix is to download a <link
xlink:href="http://www.cs.uu.nl/groups/ST/Trace/Nix">source
distribution</link>. RPMs for Red Hat, SuSE, and Fedora Core are also
available.</para>
xlink:href="http://nixos.org/">source distribution</link>. RPMs
for Red Hat, SuSE, and Fedora Core are also available.</para>
<para>Alternatively, the most recent sources of Nix can be obtained
from its <link
xlink:href="https://svn.cs.uu.nl:12443/repos/trace/nix/trunk">Subversion
xlink:href="https://svn.nixos.org/repos/nix/nix/trunk">Subversion
repository</link>. For example, the following command will check out
the latest revision into a directory called
<filename>nix</filename>:</para>
<screen>
$ svn checkout https://svn.cs.uu.nl:12443/repos/trace/nix/trunk nix</screen>
$ svn checkout https://svn.nixos.org/repos/nix/nix/trunk nix</screen>
<para>Likewise, specific releases can be obtained from the <link
xlink:href="https://svn.cs.uu.nl:12443/repos/trace/nix/tags">tags
directory</link> of the repository. If you don't have Subversion, you
can also download an automatically generated <link
xlink:href="https://svn.cs.uu.nl:12443/dist/trace/">compressed
tar-file</link> of the head revision of the trunk.</para>
xlink:href="https://svn.nixos.org/repos/nix/nix/tags">tags
directory</link> of the repository.</para>
</section>
@@ -57,25 +86,33 @@ repository.</para>
<para>To build the parser, very <emphasis>recent</emphasis> versions
of Bison and Flex are required. (This is because Nix needs GLR
support in Bison and reentrancy support in Flex.) For Bison, you need
version 1.875c or higher (1.875 does <emphasis>not</emphasis> work),
which can be obtained from the <link
xlink:href="ftp://alpha.gnu.org/pub/gnu/bison">GNU FTP server</link>.
For Flex, you need version 2.5.31, which is available on <link
xlink:href="http://lex.sourceforge.net/">SourceForge</link>. Slightly
older versions may also work, but ancient versions like the ubiquitous
2.5.4a won't. Note that these are only required if you modify the
parser or when you are building from the Subversion repository.</para>
version 2.3 or higher (1.875 does <emphasis>not</emphasis> work),
which can be obtained from
the <link xlink:href="ftp://alpha.gnu.org/pub/gnu/bison">GNU FTP
server</link>. For Flex, you need version 2.5.33, which is available
on <link xlink:href="http://lex.sourceforge.net/">SourceForge</link>.
Slightly older versions may also work, but ancient versions like the
ubiquitous 2.5.4a won't. Note that these are only required if you
modify the parser or when you are building from the Subversion
repository.</para>
<para>Nix uses Sleepycat's Berkeley DB and CWI's ATerm library. These
are included in the Nix source distribution. If you build from the
Subversion repository, you must download them yourself and place them
in the <filename>externals/</filename> directory. See
<para>Nix uses CWI's ATerm library and the bzip2 compressor (including
the bzip2 library). These are included in the Nix source
distribution. If you build from the Subversion repository, you must
download them yourself and place them in the
<filename>externals/</filename> directory. See
<filename>externals/Makefile.am</filename> for the precise URLs of
these packages. Alternatively, if you already have them installed,
you can use <command>configure</command>'s <option>--with-bdb</option>
and <option>--with-aterm</option> options to point to their respective
locations. Note that Berkeley DB <emphasis>must</emphasis> be version
4.4; other versions may not have compatible database formats.</para>
you can use <command>configure</command>'s
<option>--with-aterm</option> and <option>--with-bzip2</option>
options to point to their respective locations.</para>
<para>If you want to be able to upgrade Nix stores from before version
0.12pre12020, you need Sleepycat's Berkeley DB version version 4.5.
(Other versions may not have compatible database formats.). Berkeley
DB 4.5 is included in the Nix source distribution. If you do not need
this ability, you can build Nix with the
<option>--disable-old-db-compat</option> configure option.</para>
</section>
@@ -84,19 +121,21 @@ locations. Note that Berkeley DB <emphasis>must</emphasis> be version
<para>After unpacking or checking out the Nix sources, issue the
following commands:
</para>
<screen>
$ ./configure <replaceable>options...</replaceable>
$ make
$ make install</screen>
</para>
<para>When building from the Subversion repository, these should be
preceded by the command:
</para>
<screen>
$ autoreconf -i</screen>
$ ./bootstrap</screen>
</para>
<para>The installation path can be specified by passing the
<option>--prefix=<replaceable>prefix</replaceable></option> to
@@ -123,28 +162,32 @@ options.</para>
<section><title>Installing from RPMs</title>
<para>RPM packages of Nix can be downloaded from <uri
xlink:href="http://www.cs.uu.nl/groups/ST/Trace/Nix">http://www.cs.uu.nl/groups/ST/Trace/Nix</uri>.
These RPMs should work for most fairly recent releases of SuSE and Red
Hat Linux. They have been known to work work on SuSE Linux 8.1 and
9.0, and Red Hat 9.0. In fact, it should work on any RPM-based Linux
distribution based on <literal>glibc</literal> 2.3 or later.</para>
<para>RPM packages of Nix can be downloaded from <link
xlink:href="http://nixos.org/" />. These RPMs should work for most
fairly recent releases of SuSE and Red Hat Linux. They have been
known to work work on SuSE Linux 8.1 and 9.0, and Red Hat 9.0. In
fact, it should work on any RPM-based Linux distribution based on
<literal>glibc</literal> 2.3 or later.</para>
<para>Once downloaded, the RPMs can be installed or upgraded using
<command>rpm -U</command>. For example,</para>
<command>rpm -U</command>. For example,
<screen>
$ rpm -U nix-0.5pre664-1.i386.rpm</screen>
</para>
<para>The RPMs install into the directory <filename>/nix</filename>.
Nix can be uninstalled using <command>rpm -e nix</command>. After
this it will be necessary to manually remove the Nix store and other
auxiliary data:</para>
auxiliary data:
<screen>
$ rm -rf /nix/store
$ rm -rf /nix/var</screen>
</para>
</section>
@@ -152,64 +195,262 @@ $ rm -rf /nix/var</screen>
<para>You can install the latest stable version of Nix through Nix
itself by subscribing to the channel <link
xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-stable" /> ,
or the latest unstable version by subscribing to the channel<link
xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-unstable" />.
xlink:href="http://nixos.org/releases/nix/channels/nix-stable" />,
or the latest unstable version by subscribing to the channel <link
xlink:href="http://nixos.org/releases/nix/channels/nix-unstable" />.
You can also do a <link linkend="sec-one-click">one-click
installation</link> by clicking on the package links at <link
xlink:href="http://nix.cs.uu.nl/dist/nix/" />.</para>
xlink:href="http://nixos.org/releases/full-index-nix.html" />.</para>
</section>
<section><title>Permissions</title>
<section><title>Security</title>
<para>All Nix operations must be performed under the user ID that owns
the Nix store and database
(<filename><replaceable>prefix</replaceable>/store</filename> and
<filename><replaceable>prefix</replaceable>/var/nix/db</filename>,
respectively). When installed from the RPM packages, these
directories are owned by <systemitem class="username">root</systemitem>.</para>
<para>Nix has two basic security models. First, it can be used in
“single-user mode”, which is similar to what most other package
management tools do: there is a single user (typically <systemitem
class="username">root</systemitem>) who performs all package
management operations. All other users can then use the installed
packages, but they cannot perform package management operations
themselves.</para>
<section><title>Setuid installation</title>
<para>Alternatively, you can configure Nix in “multi-user mode”. In
this model, all users can perform package management operations — for
instance, every user can install software without requiring root
privileges. Nix ensures that this is secure. For instance, its not
possible for one user to overwrite a package used by another user with
a Trojan horse.</para>
<para>As a somewhat <emphasis>ad hoc</emphasis> hack, you can also
install the Nix binaries <quote>setuid</quote> so that a Nix store can
be shared among several users. To do this, configure Nix with the
<emphasis>--enable-setuid</emphasis> option. Nix will be installed as
owned by a user and group specified by the
<option>--with-nix-user=</option><parameter>user</parameter> and
<option>--with-nix-group=</option><parameter>group</parameter>
options. E.g.,
<screen>
$ ./configure --enable-setuid --with-nix-user=my_nix_user --with-nix-group=my_nix_group</screen>
<section><title>Single-user mode</title>
<para>In single-user mode, all Nix operations that access the database
in <filename><replaceable>prefix</replaceable>/var/nix/db</filename>
or modify the Nix store in
<filename><replaceable>prefix</replaceable>/store</filename> must be
performed under the user ID that owns those directories. This is
typically <systemitem class="username">root</systemitem>. (If you
install from RPM packages, thats in fact the default ownership.)
However, on single-user machines, it is often convenient to
<command>chown</command> those directories to your normal user account
so that you dont have to <command>su</command> to <systemitem
class="username">root</systemitem> all the time.</para>
The user and group default to <literal>nix</literal>. You should make
sure that both the user and the group exist. Any <quote>real</quote>
users that you want to allow access should be added to the Nix
</section>
<section xml:id="ssec-multi-user"><title>Multi-user mode</title>
<para>To allow a Nix store to be shared safely among multiple users,
it is important that users are not able to run builders that modify
the Nix store or database in arbitrary ways, or that interfere with
builds started by other users. If they could do so, they could
install a Trojan horse in some package and compromise the accounts of
other users.</para>
<para>To prevent this, the Nix store and database are owned by some
privileged user (usually <literal>root</literal>) and builders are
executed under special user accounts (usually named
<literal>nixbld1</literal>, <literal>nixbld2</literal>, etc.). When a
unprivileged user runs a Nix command, actions that operate on the Nix
store (such as builds) are forwarded to a <emphasis>Nix
daemon</emphasis> running under the owner of the Nix store/database
that performs the operation.</para>
<note><para>Multi-user mode has one important limitation: only
<systemitem class="username">root</systemitem> can run <command
linkend="sec-nix-pull">nix-pull</command> to register the availability
of pre-built binaries. However, those registrations are shared by all
users, so they still get the benefit from <command>nix-pull</command>s
done by <systemitem class="username">root</systemitem>.</para></note>
<section><title>Setting up the build users</title>
<para>The <emphasis>build users</emphasis> are the special UIDs under
which builds are performed. They should all be members of the
<emphasis>build users group</emphasis> (usually called
<literal>nixbld</literal>). This group should have no other members.
The build users should not be members of any other group.</para>
<para>Here is a typical <filename>/etc/group</filename> definition of
the build users group with 10 build users:
<programlisting>
nixbld:!:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10
</programlisting>
In this example the <literal>nixbld</literal> group has UID 30000, but
of course it can be anything that doesnt collide with an existing
group.</para>
<warning><para>A setuid installation should only by used if the users
in the Nix group are mutually trusted, since any user in that group
has the ability to change anything in the Nix store or database. For
instance, they could install a trojan horse in executables used by
other users.</para></warning>
<para>Here is the corresponding part of
<filename>/etc/passwd</filename>:
<warning><para>On some platforms, the Nix binaries will be installed
as setuid <literal>root</literal>. They drop root privileges
immediately after startup and switch to the Nix user. The reason for
this is that both the real and effective user must be set to the Nix
user, and POSIX has no system call to do this. This is not the case
on systems that have the <function>setresuid()</function> system call
(such as Linux and FreeBSD), so on those systems the binaries are
simply owned by the Nix user.</para></warning>
<programlisting>
nixbld1:x:30001:65534:Nix build user 1:/var/empty:/noshell
nixbld2:x:30002:65534:Nix build user 2:/var/empty:/noshell
nixbld3:x:30003:65534:Nix build user 3:/var/empty:/noshell
...
nixbld10:x:30010:65534:Nix build user 10:/var/empty:/noshell
</programlisting>
The home directory of the build users should not exist or should be an
empty directory to which they do not have write access.</para>
<para>The build users should have write access to the Nix store, but
they should not have the right to delete files. Thus the Nix stores
group should be the build users group, and it should have the sticky
bit turned on (like <filename>/tmp</filename>):
<screen>
$ chgrp nixbld /nix/store
$ chmod 1777 /nix/store
</screen>
</para>
<para>Finally, you should tell Nix to use the build users by
specifying the build users group in the <link
linkend="conf-build-users-group"><literal>build-users-group</literal>
option</link> in the <link linkend="sec-conf-file">Nix configuration
file</link> (<literal>/nix/etc/nix/nix.conf</literal>):
<programlisting>
build-users-group = nixbld
</programlisting>
</para>
</section>
<section><title>Nix store/database owned by root</title>
<para>The simplest setup is to let <literal>root</literal> own the Nix
store and database. I.e.,
<screen>
$ chown -R root /nix/store /nix/var/nix</screen>
</para>
<para>The <link linkend="sec-nix-worker">Nix daemon</link> should be
started as follows (as <literal>root</literal>):
<screen>
$ nix-worker --daemon</screen>
Youll want to put that line somewhere in your systems boot
scripts.</para>
<para>To let unprivileged users use the daemon, they should set the
<link linkend="envar-remote"><envar>NIX_REMOTE</envar> environment
variable</link> to <literal>daemon</literal>. So you should put a
line like
<programlisting>
export NIX_REMOTE=daemon</programlisting>
into the users login scripts.</para>
</section>
<section><title>Nix store/database not owned by root</title>
<para>It is also possible to let the Nix store and database be owned
by a non-root user, which should be more secure<footnote><para>Note
however that even when the Nix daemon runs as root, not
<emphasis>that</emphasis> much code is executed as root: Nix
expression evaluation is performed by the calling (unprivileged) user,
and builds are performed under the special build user accounts. So
only the code that accesses the database and starts builds is executed
as <literal>root</literal>.</para></footnote>. Typically, this user
is a special account called <literal>nix</literal>, but it can be
named anything. It should own the Nix store and database:
<screen>
$ chown -R root /nix/store /nix/var/nix</screen>
and of course <command>nix-worker --daemon</command> should be started
under that user, e.g.,
<screen>
$ su - nix -c "exec /nix/bin/nix-worker --daemon"</screen>
</para>
<para>There is a catch, though: non-<literal>root</literal> users
cannot start builds under the build user accounts, since the
<function>setuid</function> system call is obviously privileged. To
allow a non-<literal>root</literal> Nix daemon to use the build user
feature, it calls a setuid-root helper program,
<command>nix-setuid-helper</command>. This program is installed in
<filename><replaceable>prefix</replaceable>/libexec/nix-setuid-helper</filename>.
To set the permissions properly (Nixs <command>make install</command>
doesnt do this, since we dont want to ship setuid-root programs
out-of-the-box):
<screen>
$ chown root.root /nix/libexec/nix-setuid-helper
$ chmod 4755 /nix/libexec/nix-setuid-helper
</screen>
(This example assumes that the Nix binaries are installed in
<filename>/nix</filename>.)</para>
<para>Of course, the <command>nix-setuid-helper</command> command
should not be usable by just anybody, since then anybody could run
commands under the Nix build user accounts. For that reason there is
a configuration file <filename>/etc/nix-setuid.conf</filename> that
restricts the use of the helper. This file should be a text file
containing precisely two lines, the first being the Nix daemon user
and the second being the build users group, e.g.,
<programlisting>
nix
nixbld
</programlisting>
The setuid-helper barfs if it is called by a user other than the one
specified on the first line, or if it is asked to execute a build
under a user who is not a member of the group specified on the second
line. The file <filename>/etc/nix-setuid.conf</filename> must be
owned by root, and must not be group- or world-writable. The
setuid-helper barfs if this is not the case.</para>
</section>
<section><title>Restricting access</title>
<para>To limit which users can perform Nix operations, you can use the
permissions on the directory
<filename>/nix/var/nix/daemon-socket</filename>. For instance, if you
want to restrict the use of Nix to the members of a group called
<literal>nix-users</literal>, do
<screen>
$ chgrp nix-users /nix/var/nix/daemon-socket
$ chmod ug=rwx,o= /nix/var/nix/daemon-socket
</screen>
This way, users who are not in the <literal>nix-users</literal> group
cannot connect to the Unix domain socket
<filename>/nix/var/nix/daemon-socket/socket</filename>, so they cannot
perform Nix operations.</para>
</section>
</section> <!-- end of multi-user -->
</section> <!-- end of security -->
<section><title>Using Nix</title>
<para>To use Nix, some environment variables should be set. In

View File

@@ -1,150 +1,337 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-introduction">
<title>Introduction</title>
<para>Nix is a system for the deployment of software. Software
deployment is concerned with the creation, distribution, and
management of software components (<quote>packages</quote>). Its main
features are:
<itemizedlist>
<section><title>About Nix</title>
<listitem><para>It helps you make sure that dependency specifications
are complete. In general in a deployment system you have to specify
for each component what its dependencies are, but there are no
guarantees that this specification is complete. If you forget a
dependency, then the component will build and work correctly on
<emphasis>your</emphasis> machine if you have the dependency
installed, but not on the end user's machine if it's not
there.</para></listitem>
<para>Nix is a <emphasis>purely functional package manager</emphasis>.
This means that it treats packages like values in purely functional
programming languages such as Haskell — they are built by functions
that dont have side-effects, and they never change after they have
been built. Nix stores packages in the <emphasis>Nix
store</emphasis>, usually the directory
<filename>/nix/store</filename>, where each package has its own unique
subdirectory such as
<listitem><para>It is possible to have <emphasis>multiple versions or
variants</emphasis> of a component installed at the same time. In
contrast, in systems such as RPM different versions of the same
package tend to install to the same location in the file system, so
installing one version will remove the other. This is especially
important if you want to use applications that have conflicting
requirements on different versions of a component (e.g., application A
requires version 1.0 of library X, while application B requires a
non-backwards compatible version 1.1).</para></listitem>
<programlisting>
/nix/store/r8vvq9kq18pz08v249h8my6r9vs7s0n3-firefox-2.0.0.1/
</programlisting>
<listitem><para>Users can have different <quote>views</quote>
(<quote>profiles</quote> in Nix parlance) on the set of installed
applications in a system. For instance, one user can have version 1.0
of some package visible, while another is using version 1.1, and a
third doesn't use it at all.</para></listitem>
where <literal>r8vvq9kq…</literal> is a unique identifier for the
package that captures all its dependencies (its a cryptographic hash
of the packages build dependency graph). This enables many powerful
features.</para>
<listitem><para>It is possible to atomically
<emphasis>upgrade</emphasis> software. I.e., there is no time window
during an upgrade in which part of the old version and part of the new
version are simultaneously visible (which might well cause the
component to fail).</para></listitem>
<listitem><para>Likewise, it is possible to atomically roll back after
an install, upgrade, or uninstall action. That is, in a fast (O(1))
operation the previous configuration of the system can be restored.
This is because upgrade or uninstall actions don't actually remove
components from the system.</para></listitem>
<simplesect><title>Multiple versions</title>
<listitem><para>Unused components can be
<emphasis>garbage-collected</emphasis> automatically and safely: when
you remove an application from a profile, its dependencies will be
deleted by the garbage collector only if there are no other active
applications using them.</para></listitem>
<para>You can have multiple versions or variants of a package
installed at the same time. This is especially important when
different applications have dependencies on different versions of the
same package — it prevents the “DLL hell”. Because of the hashing
scheme, different versions of a package end up in different paths in
the Nix store, so they dont interfere with each other.</para>
<listitem><para>Nix supports both source-based deployment models
(where you distribute <emphasis>Nix expressions</emphasis> that tell
Nix how to build software from source) and binary-based deployment
models. The latter is more-or-less transparent: installation of
components is always based on Nix expressions, but if the expressions
have been built before and Nix knows that the resulting binaries are
available somewhere, it will use those instead.</para></listitem>
<para>An important consequence is that operations like upgrading or
uninstalling an application cannot break other applications, since
these operations never “destructively” update or delete files that are
used by other packages.</para>
<listitem><para>Nix is flexible in the deployment policies that it
supports. There is a clear separation between the tools that
implement basic Nix <emphasis>mechanisms</emphasis> (e.g., building
Nix expressions), and the tools that implement various deployment
<emphasis>policies</emphasis>. For instance, there is a concept of
<quote>Nix channels</quote> that can be used to keep software
installations up-to-date automatically from a network source. This is
a policy that is implemented by a fairly short Perl script, which can
be adapted easily to achieve similar policies.</para></listitem>
</simplesect>
<listitem><para>Nix component builds aim to be <quote>pure</quote>;
that is, unaffected by anything other than the declared dependencies.
This means that if a component was built successfully once, it can be
rebuilt again on another machine and the result will be the same. We
cannot <emphasis>guarantee</emphasis> this (e.g., if the build depends
on the time-of-day), but Nix (and the tools in the Nix Packages
collection) takes special care to help achieve this.</para></listitem>
<listitem><para>Nix expressions (the things that tell Nix how to build
components) are self-contained: they describe not just components but
complete compositions. In other words, Nix expressions also describe
how to build all the dependencies. This is in contrast to component
specification languages like RPM spec files, which might say that a
component X depends on some other component Y, but since it does not
describe <emphasis>exactly</emphasis> what Y is, the result of
building or running X might be different on different machines.
Combined with purity, self-containedness ensures that a component that
<quote>works</quote> on one machine also works on another, when
deployed using Nix.</para></listitem>
<simplesect><title>Complete dependencies</title>
<listitem><para>The Nix expression language makes it easy to describe
variability in components (e.g., optional features or
dependencies).</para></listitem>
<para>Nix helps you make sure that package dependency specifications
are complete. In general, when youre making a package for a package
management system like RPM, you have to specify for each package what
its dependencies are, but there are no guarantees that this
specification is complete. If you forget a dependency, then the
package will build and work correctly on <emphasis>your</emphasis>
machine if you have the dependency installed, but not on the end
user's machine if it's not there.</para>
<listitem><para>Nix is ideal for building build farms that do
continuous builds of software from a version management system, since
it can take care of building all the dependencies as well. Also, Nix
only rebuilds components that have changed, so there are no
unnecessary builds. In addition, Nix can transparently distribute
build jobs over different machines, including different
platforms.</para></listitem>
<para>Since Nix on the other hand doesnt install packages in “global”
locations like <filename>/usr/bin</filename> but in package-specific
directories, the risk of incomplete dependencies is greatly reduced.
This is because tools such as compilers dont search in per-packages
directories such as
<filename>/nix/store/5lbfaxb722zp…-openssl-0.9.8d/include</filename>,
so if a package builds correctly on your system, this is because you
specified the dependency explicitly.</para>
<listitem><para>Nix can be used not only for software deployment, but
also for <emphasis>service deployment</emphasis>, such as the
deployment of a complete web server with all its configuration files,
static pages, software dependencies, and so on. Nix's advantages for
software deployment also apply here: for instance, the ability
trivially to have multiple configurations at the same time, or the
ability to do rollbacks.</para></listitem>
<para>Runtime dependencies are found by scanning binaries for the hash
parts of Nix store paths (such as <literal>r8vvq9kq…</literal>). This
sounds risky, but it works extremely well.</para>
<listitem><para>Nix can efficiently upgrade between different versions
of a component through <emphasis>binary patching</emphasis>. If
patches are available on a server, and you try to install a new
version of some component, Nix will automatically apply a patch (or
sequence of patches), if available, to transform the installed
component into the new version.</para></listitem>
</simplesect>
</itemizedlist>
</para>
<simplesect><title>Multi-user support</title>
<para>Starting at version 0.11, Nix has multi-user support. This
means that non-privileged users can securely install software. Each
user can have a different <emphasis>profile</emphasis>, a set of
packages in the Nix store that appear in the users
<envar>PATH</envar>. If a user installs a package that another user
has already installed previously, the package wont be built or
downloaded a second time. At the same time, it is not possible for
one user to inject a Trojan horse into a package that might be used by
another user.</para>
<!--
<para>More details can be found in Section 3 of our <a
href="docs/papers.html#securesharing">ASE 2005 paper</a>.</para>
-->
</simplesect>
<simplesect><title>Atomic upgrades and rollbacks</title>
<para>Since package management operations never overwrite packages in
the Nix store but just add new versions in different paths, they are
<emphasis>atomic</emphasis>. So during a package upgrade, there is no
time window in which the package has some files from the old version
and some files from the new version — which would be bad because a
program might well crash if its started during that period.</para>
<para>And since package arent overwritten, the old versions are still
there after an upgrade. This means that you can <emphasis>roll
back</emphasis> to the old version:</para>
<screen>
$ nix-env --upgrade <replaceable>some-packages</replaceable>
$ nix-env --rollback
</screen>
</simplesect>
<simplesect><title>Garbage collection</title>
<para>When you install a package like this…
<screen>
$ nix-env --uninstall firefox
</screen>
the package isnt deleted from the system right away (after all, you
might want to do a rollback, or it might be in the profiles of other
users). Instead, unused packages can be deleted safely by running the
<emphasis>garbage collector</emphasis>:
<screen>
$ nix-collect-garbage
</screen>
This deletes all packages that arent in use by any user profile or by
a currently running program.</para>
</simplesect>
<simplesect><title>Functional package language</title>
<para>Packages are built from <emphasis>Nix expressions</emphasis>,
which is a simple functional language. A Nix expression describes
everything that goes into a package build action (a “derivation”):
other packages, sources, the build script, environment variables for
the build script, etc. Nix tries very hard to ensure that Nix
expressions are <emphasis>deterministic</emphasis>: building a Nix
expression twice should yield the same result.</para>
<para>Because its a functional language, its easy to support
building variants of a package: turn the Nix expression into a
function and call it any number of times with the appropriate
arguments. Due to the hashing scheme, variants dont conflict with
each other in the Nix store.</para>
</simplesect>
<simplesect><title>Transparent source/binary deployment</title>
<para>Nix expressions generally describe how to build a package from
source, so an installation action like
<screen>
$ nix-env --install firefox
</screen>
<emphasis>could</emphasis> cause quite a bit of build activity, as not
only Firefox but also all its dependencies (all the way up to the C
library and the compiler) would have to built, at least if they are
not already in the Nix store. This is a <emphasis>source deployment
model</emphasis>. For most users, building from source is not very
pleasant as it takes far too long. However, Nix can automatically
skip building from source and download a pre-built binary instead if
it knows about it. <emphasis>Nix channels</emphasis> provide Nix
expressions along with pre-built binaries.</para>
<!--
<para>source deployment model (like <a
href="http://www.gentoo.org/">Gentoo</a>) and a binary model (like
RPM)</para>
-->
</simplesect>
<simplesect><title>Binary patching</title>
<para>In addition to downloading binaries automatically if theyre
available, Nix can download binary deltas that patch an existing
package in the Nix store into a new version. This speeds up
upgrades.</para>
</simplesect>
<simplesect><title>Nix Packages collection</title>
<para>We provide a large set of Nix expressions containing hundreds of
existing Unix packages, the <emphasis>Nix Packages
collection</emphasis> (Nixpkgs).</para>
</simplesect>
<simplesect><title>Service deployment</title>
<para>Nix can be used not only for rolling out packages, but also
complete <emphasis>configurations</emphasis> of services. This is
done by treating all the static bits of a service (such as software
packages, configuration files, control scripts, static web pages,
etc.) as “packages” that can be built by Nix expressions. As a
result, all the features above apply to services as well: for
instance, you can roll back a web server configuration if a
configuration change turns out to be undesirable, you can easily have
multiple instances of a service (e.g., a test and production server),
and because the whole service is built in a purely functional way from
a Nix expression, it is repeatable so you can easily reproduce the
service on another machine.</para>
<!--
<para>You can read more about this in our <a
href="docs/papers.html#servicecm">SCM-12 paper</a>.</para>
-->
</simplesect>
<simplesect><title>Portability</title>
<para>Nix should run on most Unix systems, including Linux, FreeBSD and
Mac OS X. It is also supported on Windows using Cygwin.</para>
</simplesect>
<simplesect><title>NixOS</title>
<para>NixOS is a Linux distribution based on Nix. It uses Nix not
just for package management but also to manage the system
configuration (e.g., to build configuration files in
<filename>/etc</filename>). This means, among other things, that its
possible to easily roll back the entire configuration of the system to
an earlier state. Also, users can install software without root
privileges. For more information and downloads, see the <link
xlink:href="http://nixos.org/">NixOS homepage</link>.</para>
</simplesect>
<!-- other features:
- build farms
- reproducibility (Nix expressions allows whole configuration to be rebuilt)
-->
</section>
<section><title>About us</title>
<para>Nix was originally developed at the <link
xlink:href="http://www.cs.uu.nl/">Department of Information and
Computing Sciences</link>, Utrecht University by the <link
xlink:href="http://www.cs.uu.nl/wiki/Trace/WebHome">TraCE
project</link> (2003-2008). The project was funded by the Software
Engineering Research Program <link
xlink:href="http://www.jacquard.nl/">Jacquard</link> to improve the
support for variability in software systems. Further funding is now
provided by the NIRICT LaQuSo Build Farm project.</para>
</section>
<section><title>About this manual</title>
<para>This manual tells you how to install and use Nix and how to
write Nix expressions for software not already in the Nix Packages
collection. It also discusses some advanced topics, such as setting
up a Nix-based build farm, and doing service deployment using
Nix.</para>
up a Nix-based build farm.</para>
<note><para>Some background information on Nix can be found in a
number of papers. The ICSE 2004 paper <citetitle
xlink:href='http://www.cs.uu.nl/~eelco/pubs/immdsd-icse2004-final.pdf'>Imposing
</section>
<section><title>License</title>
<para>Nix is free software; you can redistribute it and/or modify it
under the terms of the <link
xlink:href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser General
Public License</link> as published by the <link
xlink:href="http://www.fsf.org/">Free Software Foundation</link>;
either version 2.1 of the License, or (at your option) any later
version. Nix is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.</para>
</section>
<section><title>More information</title>
<para>Some background information on Nix can be found in a number of
papers. The ICSE 2004 paper <citetitle
xlink:href='http://www.st.ewi.tudelft.nl/~dolstra/pubs/immdsd-icse2004-final.pdf'>Imposing
a Memory Management Discipline on Software Deployment</citetitle>
discusses the hashing mechanism used to ensure reliable dependency
identification and non-interference between different versions and
variants of packages. The LISA 2004 paper <citetitle
xlink:href='http://www.cs.uu.nl/~eelco/pubs/nspfssd-lisa2004-final.pdf'>Nix:
xlink:href='http://www.st.ewi.tudelft.nl/~dolstra/pubs/nspfssd-lisa2004-final.pdf'>Nix:
A Safe and Policy-Free System for Software Deployment</citetitle>
gives a more general discussion of Nix from a system-administration
perspective. The CBSE 2005 paper <citetitle
xlink:href='http://www.cs.uu.nl/~eelco/pubs/eupfcdm-cbse2005-final.pdf'>Efficient
xlink:href='http://www.st.ewi.tudelft.nl/~dolstra/pubs/eupfcdm-cbse2005-final.pdf'>Efficient
Upgrading in a Purely Functional Component Deployment Model
</citetitle> is about transparent patch deployment in Nix. Finally,
the SCM-12 paper <citetitle
xlink:href='http://www.cs.uu.nl/~eelco/pubs/servicecm-scm12-final.pdf'>
</citetitle> is about transparent patch deployment in Nix. The SCM-12
paper <citetitle
xlink:href='http://www.st.ewi.tudelft.nl/~dolstra/pubs/servicecm-scm12-final.pdf'>
Service Configuration Management</citetitle> shows how services (e.g.,
web servers) can be deployed and managed through Nix.</para></note>
web servers) can be deployed and managed through Nix. A short
overview of NixOS is given in the HotOS XI paper <citetitle
xlink:href="http://www.st.ewi.tudelft.nl/~dolstra/pubs/hotos-final.pdf">Purely
Functional System Configuration Management</citetitle>. The Nix
homepage has <link
xlink:href="http://nix.cs.uu.nl/docs/papers.html">an up-to-date list
of Nix-related papers</link>.</para>
<para>Nix is the subject of Eelco Dolstras PhD thesis <citetitle
xlink:href="http://igitur-archive.library.uu.nl/dissertations/2006-0118-200031/index.htm">The
Purely Functional Software Deployment Model</citetitle>, which
contains most of the papers listed above.</para>
<para>Nix has a homepage at <link
xlink:href="http://nixos.org/"/>.</para>
</section>
</chapter>

View File

@@ -13,14 +13,22 @@
<firstname>Eelco</firstname>
<surname>Dolstra</surname>
</personname>
<affiliation>
<orgname>Delft University of Technology</orgname>
<orgdiv>Department of Software Technology</orgdiv>
</affiliation>
</author>
<copyright>
<year>2004</year>
<year>2005</year>
<year>2006</year>
<year>2007</year>
<year>2008</year>
<holder>Eelco Dolstra</holder>
</copyright>
<date>November 2008</date>
</info>
@@ -49,7 +57,7 @@
<title>nix-instantiate</title>
<xi:include href="nix-instantiate.xml" />
</section>
<section>
<section xml:id="sec-nix-store">
<title>nix-store</title>
<xi:include href="nix-store.xml" />
</section>
@@ -65,10 +73,14 @@
<title>nix-channel</title>
<xi:include href="nix-channel.xml" />
</section>
<section>
<section xml:id="sec-nix-collect-garbage">
<title>nix-collect-garbage</title>
<xi:include href="nix-collect-garbage.xml" />
</section>
<section xml:id="sec-nix-copy-closure">
<title>nix-copy-closure</title>
<xi:include href="nix-copy-closure.xml" />
</section>
<section xml:id="sec-nix-hash">
<title>nix-hash</title>
<xi:include href="nix-hash.xml" />
@@ -77,15 +89,11 @@
<title>nix-install-package</title>
<xi:include href="nix-install-package.xml" />
</section>
<section>
<title>nix-pack-closure</title>
<xi:include href="nix-pack-closure.xml" />
</section>
<section>
<section xml:id="sec-nix-prefetch-url">
<title>nix-prefetch-url</title>
<xi:include href="nix-prefetch-url.xml" />
</section>
<section>
<section xml:id="sec-nix-pull">
<title>nix-pull</title>
<xi:include href="nix-pull.xml" />
</section>
@@ -93,16 +101,16 @@
<title>nix-push</title>
<xi:include href="nix-push.xml" />
</section>
<section>
<title>nix-unpack-closure</title>
<xi:include href="nix-unpack-closure.xml" />
<section xml:id="sec-nix-worker">
<title>nix-worker</title>
<xi:include href="nix-worker.xml" />
</section>
</section>
</appendix>
<xi:include href="troubleshooting.xml" />
<xi:include href="bugs.xml" />
<!-- <xi:include href="bugs.xml" /> -->
<xi:include href="glossary.xml" />
<appendix>

View File

@@ -1,5 +1,13 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-build</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-build</refname>
@@ -9,8 +17,9 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-build</command>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xpointer(/nop/*)" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<arg><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg><option>--argstr</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--attr</option></arg>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-channel</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-channel</refname>
<refpurpose>manage Nix channels</refpurpose>
@@ -54,11 +62,11 @@ also <xref linkend="sec-channels" />.</para>
<varlistentry><term><option>--update</option></term>
<listitem><para>Downloads the Nix expressions of all subscribed
channels, makes the conjunction of these the default for
<command>nix-env</command> operations (by calling <command>nix-env
-I</command>), and performs a <command>nix-pull</command> on the
manifests of all channels to make pre-built binaries
available.</para></listitem>
channels, makes them the default for <command>nix-env</command>
operations (by symlinking them in the directory
<filename>~/.nix-defexpr</filename>), and performs a
<command>nix-pull</command> on the manifests of all channels to
make pre-built binaries available.</para></listitem>
</varlistentry>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-collect-garbage</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-collect-garbage</refname>
<refpurpose>delete unreachable store paths</refpurpose>

View File

@@ -0,0 +1,151 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-copy-closure</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-copy-closure</refname>
<refpurpose>copy a closure to or from a remote machine via SSH</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-copy-closure</command>
<group>
<arg choice='plain'><option>--to</option></arg>
<arg choice='plain'><option>--from</option></arg>
</group>
<arg><option>--sign</option></arg>
<arg><option>--gzip</option></arg>
<arg choice='plain'>
<arg><replaceable>user@</replaceable></arg><replaceable>machine</replaceable>
</arg>
<arg choice='plain'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para><command>nix-copy-closure</command> gives you an easy and
efficient way to exchange software between machines. Given one or
more Nix store paths <replaceable>paths</replaceable> on the local
machine, <command>nix-copy-closure</command> computes the closure of
those paths (i.e. all their dependencies in the Nix store), and copies
all paths in the closure to the remote machine via the
<command>ssh</command> (Secure Shell) command. With the
<option>--from</option>, the direction is reversed:
the closure of <replaceable>paths</replaceable> on a remote machine is
copied to the Nix store on the local machine.</para>
<para>This command is efficient because it only sends the store paths
that are missing on the target machine.</para>
<para>Since <command>nix-copy-closure</command> calls
<command>ssh</command>, you may be asked to type in the appropriate
password or passphrase. In fact, you may be asked
<emphasis>twice</emphasis> because <command>nix-copy-closure</command>
currently connects twice to the remote machine, first to get the set
of paths missing on the target machine, and second to send the dump of
those paths. If this bothers you, use
<command>ssh-agent</command>.</para>
<refsection><title>Options</title>
<variablelist>
<varlistentry><term><option>--to</option></term>
<listitem><para>Copy the closure of
<replaceable>paths</replaceable> from the local Nix store to the
Nix store on <replaceable>machine</replaceable>. This is the
default.</para></listitem>
</varlistentry>
<varlistentry><term><option>--from</option></term>
<listitem><para>Copy the closure of
<replaceable>paths</replaceable> from the Nix store on
<replaceable>machine</replaceable> to the local Nix
store.</para></listitem>
</varlistentry>
<varlistentry><term><option>--sign</option></term>
<listitem><para>Let the sending machine cryptographically sign the
dump of each path with the key in
<filename>/nix/etc/nix/signing-key.sec</filename>. If the user on
the target machine does not have direct access to the Nix store
(i.e., if the target machine has a multi-user Nix installation),
then the target machine will check the dump against
<filename>/nix/etc/nix/signing-key.pub</filename> before unpacking
it in its Nix store. This allows secure sharing of store paths
between untrusted users on two machines, provided that there is a
trust relation between the Nix installations on both machines
(namely, they have matching public/secret keys).</para></listitem>
</varlistentry>
<varlistentry><term><option>--gzip</option></term>
<listitem><para>Compress the dump of each path with
<command>gzip</command> before sending it.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Environment variables</title>
<variablelist>
<varlistentry><term><envar>NIX_SSHOPTS</envar></term>
<listitem><para>Additional options to be passed to
<command>ssh</command> on the command line.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<para>Copy Firefox with all its dependencies to a remote machine:
<screen>
$ nix-copy-closure --to alice@itchy.labs $(type -tP firefox)</screen>
</para>
<para>Copy Subversion from a remote machine and then install it into a
user environment:
<screen>
$ nix-copy-closure --from alice@itchy.labs \
/nix/store/0dj0503hjxy5mbwlafv1rsbdiyx1gkdy-subversion-1.4.4
$ nix-env -i /nix/store/0dj0503hjxy5mbwlafv1rsbdiyx1gkdy-subversion-1.4.4
</screen>
</para>
</refsection>
</refsection>
</refentry>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-env</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-env</refname>
<refpurpose>manipulate or query Nix user environments</refpurpose>
@@ -9,15 +17,9 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-env</command>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xpointer(/nop/*)" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<arg><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--attr</option></arg>
<arg choice='plain'><option>-A</option></arg>
</group>
<replaceable>attrPath</replaceable>
</arg>
<arg><option>--argstr</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--file</option></arg>
@@ -37,9 +39,6 @@
<replaceable>system</replaceable>
</arg>
<arg><option>--dry-run</option></arg>
<arg><option>--from-expression</option></arg>
<arg><option>-E</option></arg>
<arg><option>--from-profile</option> <replaceable>path</replaceable></arg>
<arg choice='plain'><replaceable>operation</replaceable></arg>
<arg rep='repeat'><replaceable>options</replaceable></arg>
<arg rep='repeat'><replaceable>arguments</replaceable></arg>
@@ -50,7 +49,7 @@
<refsection><title>Description</title>
<para>The command <command>nix-env</command> is used to manipulate Nix
user environments. User environments are sets of software components
user environments. User environments are sets of software packages
available to a user at some point in time. In other words, they are a
synthesised view of the programs available in the Nix store. There
may be many user environments: different users can have different
@@ -142,14 +141,34 @@ linkend="sec-common-options" />.</para>
<variablelist>
<varlistentry><term><filename>~/.nix-defexpr</filename></term>
<listitem><para>The default Nix expression used by the
<option>--install</option>, <option>--upgrade</option>, and
<option>--query --available</option> operations to obtain
derivations. It is generally a symbolic link to some other
location set using the <option>--import</option> operation. The
<listitem><para>A directory that contains the default Nix
expressions used by the <option>--install</option>,
<option>--upgrade</option>, and <option>--query
--available</option> operations to obtain derivations. The
<option>--file</option> option may be used to override this
default.</para></listitem>
default.</para>
<para>The Nix expressions in this directory are combined into a
single attribute set, with each file as an attribute that has the
name of the file. Thus, if <filename>~/.nix-defexpr</filename>
contains two files, <filename>foo</filename> and
<filename>bar</filename>, then the default Nix expression will
essentially be
<programlisting>
{
foo = import ~/.nix-defexpr/foo;
bar = import ~/.nix-defexpr/bar;
}</programlisting>
</para>
<para>The command <command>nix-channel</command> places symlinks
to the downloaded Nix expressions from each subscribed channel in
this directory.</para>
</listitem>
</varlistentry>
@@ -182,6 +201,7 @@ linkend="sec-common-options" />.</para>
<arg choice='plain'><option>--install</option></arg>
<arg choice='plain'><option>-i</option></arg>
</group>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<group choice='opt'>
<arg choice='plain'><option>--preserve-installed</option></arg>
<arg choice='plain'><option>-P</option></arg>
@@ -213,11 +233,21 @@ number of possible ways:
<para>If there are multiple derivations matching a name in
<replaceable>args</replaceable> that have the same name (e.g.,
<literal>gcc-3.3.6</literal> and <literal>gcc-4.1.1</literal>), then
only the highest version will be installed. You can force the
installation of multiple derivations with the same name by being
specific about the versions. For instance, <literal>nix-env -i
gcc-3.3.6 gcc-4.1.1</literal> will install both version of GCC (and
will probably cause a user environment conflict!).</para></listitem>
the derivation with the highest <emphasis>priority</emphasis> is
used. A derivation can define a priority by declaring the
<varname>meta.priority</varname> attribute. This attribute should
be a number, with a higher value denoting a lower priority. The
default priority is <literal>0</literal>.</para>
<para>If there are multiple matching derivations with the same
priority, then the derivation with the highest version will be
installed.</para>
<para>You can force the installation of multiple derivations with
the same name by being specific about the versions. For instance,
<literal>nix-env -i gcc-3.3.6 gcc-4.1.1</literal> will install both
version of GCC (and will probably cause a user environment
conflict!).</para></listitem>
<listitem><para>If <link
linkend='opt-attr'><option>--attr</option></link>
@@ -264,6 +294,15 @@ number of possible ways:
<variablelist>
<varlistentry><term><option>--prebuild-only</option> / <option>-b</option></term>
<listitem><para>Use only derivations for which a substitute is
registered, i.e., there is a pre-built binary available that can
be downloaded in lieu of building the derivation. Thus, no
packages will be built from source.</para></listitem>
</varlistentry>
<varlistentry><term><option>--preserve-installed</option></term>
<term><option>-P</option></term>
@@ -379,7 +418,7 @@ the following paths will be substituted:
<!--######################################################################-->
<refsection><title>Operation <option>--upgrade</option></title>
<refsection xml:id="rsec-nix-env-upgrade"><title>Operation <option>--upgrade</option></title>
<refsection><title>Synopsis</title>
@@ -389,6 +428,7 @@ the following paths will be substituted:
<arg choice='plain'><option>--upgrade</option></arg>
<arg choice='plain'><option>-u</option></arg>
</group>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<group choice='opt'>
<arg choice='plain'><option>--lt</option></arg>
<arg choice='plain'><option>--leq</option></arg>
@@ -463,6 +503,9 @@ installed.</para>
</variablelist>
<para>For the other flags, see <option
linkend="rsec-nix-env-install">--install</option>.</para>
</refsection>
<refsection><title>Examples</title>
@@ -483,7 +526,7 @@ upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
</refsection>
<refsection><title>Versions</title>
<refsection xml:id="ssec-version-comparisons"><title>Versions</title>
<para>The upgrade operation determines whether a derivation
<varname>y</varname> is an upgrade of a derivation
@@ -572,6 +615,111 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
<!--######################################################################-->
<refsection xml:id="rsec-nix-env-set-flag"><title>Operation <option>--set-flag</option></title>
<refsection><title>Synopsis</title>
<cmdsynopsis>
<command>nix-env</command>
<arg choice='plain'><option>--set-flag</option></arg>
<arg choice='plain'><replaceable>name</replaceable></arg>
<arg choice='plain'><replaceable>value</replaceable></arg>
<arg choice='plain' rep='repeat'><replaceable>drvnames</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The <option>--set-flag</option> operation allows meta attributes
of installed packages to be modified. There are several attributes
that can be usefully modified, because they affect the behaviour of
<command>nix-env</command> or the user environment build
script:
<itemizedlist>
<listitem><para><varname>priority</varname> can be changed to
resolve filename clashes. The user environment build script uses
the <varname>meta.priority</varname> attribute of derivations to
resolve filename collisions between packages. Lower priority values
denote a higher priority. For instance, the GCC wrapper package and
the Binutils package in Nixpkgs both have a file
<filename>bin/ld</filename>, so previously if you tried to install
both you would get a collision. Now, on the other hand, the GCC
wrapper declares a higher priority than Binutils, so the formers
<filename>bin/ld</filename> is symlinked in the user
environment.</para></listitem>
<listitem><para><varname>keep</varname> can be set to
<literal>true</literal> to prevent the package from being upgraded
or replaced. This is useful if you want to hang on to an older
version of a package.</para></listitem>
<listitem><para><varname>active</varname> can be set to
<literal>false</literal> to “disable” the package. That is, no
symlinks will be generated to the files of the package, but it
remains part of the profile (so it wont be garbage-collected). It
can be set back to <literal>true</literal> to re-enable the
package.</para></listitem>
</itemizedlist>
</para>
</refsection>
<refsection><title>Examples</title>
<para>To prevent the currently installed Firefox from being upgraded:
<screen>
$ nix-env --set-flag keep true firefox</screen>
After this, <command>nix-env -u</command> will ignore Firefox.</para>
<para>To disable the currently installed Firefox, then install a new
Firefox while the old remains part of the profile:
<screen>
$ nix-env -q \*
firefox-2.0.0.9 <lineannotation>(the current one)</lineannotation>
$ nix-env --preserve-installed -i firefox-2.0.0.11
installing `firefox-2.0.0.11'
building path(s) `/nix/store/myy0y59q3ig70dgq37jqwg1j0rsapzsl-user-environment'
Collission between `/nix/store/<replaceable>...</replaceable>-firefox-2.0.0.11/bin/firefox'
and `/nix/store/<replaceable>...</replaceable>-firefox-2.0.0.9/bin/firefox'.
<lineannotation>(i.e., cant have two active at the same time)</lineannotation>
$ nix-env --set-flag active false firefox
setting flag on `firefox-2.0.0.9'
$ nix-env --preserve-installed -i firefox-2.0.0.11
installing `firefox-2.0.0.11'
$ nix-env -q \*
firefox-2.0.0.11 <lineannotation>(the enabled one)</lineannotation>
firefox-2.0.0.9 <lineannotation>(the disabled one)</lineannotation></screen>
</para>
<para>To make files from <literal>binutils</literal> take precedence
over files from <literal>gcc</literal>:
<screen>
$ nix-env --set-flag priority 5 binutils
$ nix-env --set-flag priority 10 gcc</screen>
</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--query</option></title>
@@ -584,13 +732,14 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
<arg choice='plain'><option>--query</option></arg>
<arg choice='plain'><option>-q</option></arg>
</group>
<arg><option>--xml</option></arg>
<group choice='opt'>
<arg choice='plain'><option>--installed</option></arg>
<arg choice='plain'><option>--available</option></arg>
<arg choice='plain'><option>-a</option></arg>
</group>
<sbr />
<arg>
<group choice='req'>
<arg choice='plain'><option>--status</option></arg>
@@ -599,8 +748,8 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
</arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--attr</option></arg>
<arg choice='plain'><option>-A</option></arg>
<arg choice='plain'><option>--attr-path</option></arg>
<arg choice='plain'><option>-P</option></arg>
</group>
</arg>
<arg><option>--no-name</option></arg>
@@ -614,6 +763,28 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
<arg><option>--drv-path</option></arg>
<arg><option>--out-path</option></arg>
<arg><option>--description</option></arg>
<arg><option>--meta</option></arg>
<sbr />
<arg><option>--xml</option></arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--prebuilt-only</option></arg>
<arg choice='plain'><option>-b</option></arg>
</group>
</arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--attr</option></arg>
<arg choice='plain'><option>-A</option></arg>
</group>
<replaceable>attribute-path</replaceable>
</arg>
<sbr />
<arg choice='plain' rep='repeat'><replaceable>names</replaceable></arg>
</cmdsynopsis>
@@ -690,6 +861,16 @@ user environment elements, etc. -->
</varlistentry>
<varlistentry><term><option>--prebuild-only</option> / <option>-b</option></term>
<listitem><para>Show only derivations for which a substitute is
registered, i.e., there is a pre-built binary available that can
be downloaded in lieu of building the derivation. Thus, this
shows all packages that probably can be installed
quickly.</para></listitem>
</varlistentry>
<varlistentry><term><option>--status</option></term>
<term><option>-s</option></term>
@@ -709,8 +890,8 @@ user environment elements, etc. -->
</varlistentry>
<varlistentry><term><option>--attr</option></term>
<term><option>-a</option></term>
<varlistentry><term><option>--attr-path</option></term>
<term><option>-P</option></term>
<listitem><para>Print the <emphasis>attribute path</emphasis> of
the derivation, which can be used to unambiguously select it using
@@ -733,35 +914,35 @@ user environment elements, etc. -->
<listitem><para>Compare installed versions to available versions,
or vice versa (if <option>--available</option> is given). This is
useful for quickly seeing whether upgrades for installed
components are available in a Nix expression. A column is added
packages are available in a Nix expression. A column is added
with the following meaning:
<variablelist>
<varlistentry><term><literal>&lt;</literal> <replaceable>version</replaceable></term>
<listitem><para>A newer version of the component is available
<listitem><para>A newer version of the package is available
or installed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>=</literal> <replaceable>version</replaceable></term>
<listitem><para>At most the same version of the component is
<listitem><para>At most the same version of the package is
available or installed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>></literal> <replaceable>version</replaceable></term>
<listitem><para>Only older versions of the component are
<listitem><para>Only older versions of the package are
available or installed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>- ?</literal></term>
<listitem><para>No version of the component is available or
<listitem><para>No version of the package is available or
installed.</para></listitem>
</varlistentry>
@@ -802,6 +983,14 @@ user environment elements, etc. -->
</varlistentry>
<varlistentry><term><option>--meta</option></term>
<listitem><para>Print all of the meta-attributes of the
derivation. This option is only available with
<option>--xml</option>.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
@@ -1061,43 +1250,4 @@ error: no generation older than the current (91) exists</screen>
<!--######################################################################-->
<refsection><title>Operation <option>--import</option></title>
<refsection><title>Synopsis</title>
<cmdsynopsis>
<command>nix-env</command>
<group choice='req'>
<arg choice='plain'><option>--import</option></arg>
<arg choice='plain'><option>-I</option></arg>
</group>
<arg choice='req'><replaceable>path</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>This operation makes <replaceable>path</replaceable> the default
active Nix expression for the user. That is, the symlink
<filename>~/.nix-userenv</filename> is made to point to
<replaceable>path</replaceable>.</para>
</refsection>
<refsection><title>Examples</title>
<screen>
$ nix-env -I ~/nixpkgs-0.5/</screen>
</refsection>
</refsection>
</refentry>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-hash</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-hash</refname>
<refpurpose>compute the cryptographic hash of a path</refpurpose>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-install-package</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-install-package</refname>
<refpurpose>install a Nix Package file</refpurpose>

View File

@@ -1,6 +1,14 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-instantiate</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-instantiate</refname>
<refpurpose>instantiate store derivations from Nix expressions</refpurpose>
@@ -9,7 +17,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-instantiate</command>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xpointer(/nop/*)" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<arg><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg>
<arg>
<group choice='req'>

View File

@@ -1,64 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>nix-pack-closure</refname>
<refpurpose>pack the closure of a store path into a single file that
can be unpacked with
<command>nix-unpack-closure</command></refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-pack-closure</command>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>The command <command>nix-pack-closure</command> packs the
contents of the store paths <replaceable>paths</replaceable> and
<emphasis>all their dependencies</emphasis> into a single file, which
is written to standard output. (That is, it
<emphasis>serialises</emphasis> <replaceable>paths</replaceable>.)
The output can then be unpacked into the Nix store of another machine
using <command>nix-unpack-closure</command>.</para>
<para>Together, <command>nix-pack-closure</command> and
<command>nix-unpack-closure</command> provide a quick and easy way to
deploy a package to a different machine. However, as the output of
<command>nix-pack-closure</command> tends to be rather large (since it
contains all dependencies), its not very efficient.
<command>nix-push</command> and <command>nix-pull</command> are more
efficient, but are also a bit more cumbersome to use.</para>
</refsection>
<refsection><title>Examples</title>
<para>To copy some instance of Subversion with all its dependencies to
another machine:
<screen>
$ nix-pack-closure /nix/store/hj232g1r...-subversion-1.3.0 > svn.closure
<lineannotation>Copy <!-- !!! <filename> -->svn.closure to the remote machine, then on the remote machine do:</lineannotation>
$ nix-unpack-closure &lt; svn.closure</screen>
</para>
<para>Copy the program <command>azureus</command> with all its
dependencies to the machine <literal>scratchy</literal>:
<screen>
$ nix-pack-closure $(which azureus) | ssh scratchy nix-unpack-closure</screen>
</para>
</refsection>
</refentry>

View File

@@ -1,5 +1,14 @@
<refentry>
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-prefetch-url</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-prefetch-url</refname>
<refpurpose>copy a file from a URL into the store and print its MD5 hash</refpurpose>
@@ -38,7 +47,7 @@ avoided.</para>
<para>The environment variable <envar>NIX_HASH_ALGO</envar> specifies
which hash algorithm to use. It can be either <literal>md5</literal>,
<literal>sha1</literal>, or <literal>sha256</literal>. The default is
<literal>md5</literal>.</para>
<literal>sha256</literal>.</para>
<para>If <replaceable>hash</replaceable> is specified, then a download
is not performed if the Nix store already contains a file with the

View File

@@ -1,5 +1,13 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-pull</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-pull</refname>

View File

@@ -1,5 +1,13 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-push</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-push</refname>

View File

@@ -1,5 +1,13 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-store</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-store</refname>
@@ -9,7 +17,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-store</command>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xpointer(/nop/*)" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-common-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" />
<arg><option>--add-root</option> <replaceable>path</replaceable></arg>
<arg><option>--indirect</option></arg>
<arg choice='plain'><replaceable>operation</replaceable></arg>
@@ -120,6 +128,7 @@ lrwxrwxrwx 1 ... 2005-03-13 21:10 /home/eelco/bla/result -> /nix/store/1r1134
<arg choice='plain'><option>-r</option></arg>
</group>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
<arg><option>--dry-run</option></arg>
</cmdsynopsis>
</refsection>
@@ -158,6 +167,11 @@ the specified store paths. Realisation is a somewhat overloaded term:
output. (For non-derivations argument, the argument itself is
printed.)</para>
<para>If the <option>--dry-run</option> option is used, then
<command>nix-store</command> will print on standard error a
description of what packages would be built or downloaded, and then
quit.</para>
</refsection>
@@ -196,6 +210,10 @@ linkend="sec-nix-build"><command>nix-build</command></link> does.</para>
<arg choice='plain'><option>--print-dead</option></arg>
<arg choice='plain'><option>--delete</option></arg>
</group>
<arg><option>--max-freed</option> <replaceable>bytes</replaceable></arg>
<arg><option>--max-links</option> <replaceable>nrlinks</replaceable></arg>
<arg><option>--max-atime</option> <replaceable>atime</replaceable></arg>
<arg><option>--use-atime</option></arg>
</cmdsynopsis>
</refsection>
@@ -250,7 +268,70 @@ the Nix store not reachable via file system references from a set of
</variablelist>
<para>The behaviour of the collector is influenced by the <link
<para>By default, all unreachable paths are deleted. The following
options control what gets deleted and in what order:
<variablelist>
<varlistentry><term><option>--max-freed</option> <replaceable>bytes</replaceable></term>
<listitem><para>Keep deleting paths until at least
<replaceable>bytes</replaceable> bytes have been
deleted, then stop.</para></listitem>
</varlistentry>
<varlistentry><term><option>--max-links</option> <replaceable>nrlinks</replaceable></term>
<listitem><para>Keep deleting paths until the hard link count on
<filename>/nix/store</filename> is less than
<replaceable>nrlinks</replaceable>, then stop. This is useful for
very large Nix stores on filesystems with a 32000 subdirectories
limit (like <literal>ext3</literal>).</para></listitem>
</varlistentry>
<varlistentry><term><option>--max-atime</option> <replaceable>atime</replaceable></term>
<listitem><para>Only delete a store path if its last-accessed time
is less than <replaceable>atime</replaceable>. This allows you to
garbage-collect only packages that havent been used recently.
The time is expressed as the number of seconds in the Unix epoch,
i.e., since 1970-01-01 00:00:00 UTC. An easy way to convert to
this format is <literal>date +%s -d "<replaceable>date
specification</replaceable>"</literal>.</para>
<para>For directories, the last-accessed time is the highest
last-accessed time of any regular file in the directory (or in any
of its subdirectories). That is, the <literal>atime</literal>
field maintained by the filesystem is ignored for directories.
This is because operations such as rebuilding the
<command>locate</command> database tend to update the
<literal>atime</literal> values of all directories, so theyre not
a useful indicator of whether a package was recently used.</para>
<para>Note that <command>nix-store --optimise</command> reads all
regular files in the Nix store, and so causes all last-accessed
times to be set to the present time. This makes
<option>--max-atime</option> ineffective (for a while at
least).</para></listitem>
</varlistentry>
<varlistentry><term><option>--use-atime</option></term>
<listitem><para>Delete store paths in order of ascending
last-accessed time. This is useful in conjunction with the other
options to delete only the least recently used
packages.</para></listitem>
</varlistentry>
</variablelist>
</para>
<para>The behaviour of the collector is also influenced by the <link
linkend="conf-gc-keep-outputs"><literal>gc-keep-outputs</literal></link>
and <link
linkend="conf-gc-keep-derivations"><literal>gc-keep-derivations</literal></link>
@@ -276,6 +357,20 @@ deleting `/nix/store/kq82idx6g0nyzsp2s14gfsc38npai7lf-cairo-1.0.4.tar.gz.drv'
</para>
<para>To delete unreachable paths not accessed in the last two months:
<screen>
$ nix-store --gc -v --max-atime $(date +%s -d "2 months ago")</screen>
</para>
<para>To delete at least 100 MiBs of unreachable paths:
<screen>
$ nix-store --gc --max-freed $((100 * 1024 * 1024))</screen>
</para>
</refsection>
@@ -651,37 +746,7 @@ $ gv graph.ps</screen>
<!--######################################################################-->
<!--
<refsection><title>Operation <option>-XXX-substitute</option></title>
<refsection><title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>-XXX-substitute</option></arg>
<arg choice='plain'
rep='repeat'><replaceable>srcpath</replaceable> <replaceable>subpath</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>-XXX-substitute</option> registers that the
store path <replaceable>srcpath</replaceable> can be built by
realising the derivation expression in
<replaceable>subpath</replaceable>. This is used to implement binary
deployment.</para>
</refsection>
</refsection>
-->
<!--######################################################################-->
<refsection><title>Operation <option>--verify</option></title>
<refsection xml:id='refsec-nix-store-verify'><title>Operation <option>--verify</option></title>
<refsection>
<title>Synopsis</title>
@@ -801,4 +866,222 @@ archive is read from standard input.</para>
</refsection>
<!--######################################################################-->
<refsection xml:id='refsec-nix-store-export'><title>Operation <option>--export</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--export</option></arg>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--export</option> writes a serialisation
of the specified store paths to standard output in a format that can
be imported into another Nix store with <command
linkend="refsec-nix-store-import">nix-store --import</command>. This
is like <command linkend="refsec-nix-store-dump">nix-store
--dump</command>, except that the NAR archive produced by that command
doesnt contain the necessary meta-information to allow it to be
imported into another Nix store (namely, the set of references of the
path).</para>
<para>This command does not produce a <emphasis>closure</emphasis> of
the specified paths, so if a store path references other store paths
that are missing in the target Nix store, the import will fail. To
copy a whole closure, do something like
<screen>
$ nix-store --export $(nix-store -qR <replaceable>paths</replaceable>) > out</screen>
</para>
<para>For an example of how <option>--export</option> and
<option>--import</option> can be used, see the source of the <command
linkend="sec-nix-copy-closure">nix-copy-closure</command>
command.</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection xml:id='refsec-nix-store-import'><title>Operation <option>--import</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--import</option></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--export</option> reads a serialisation of
a set of store paths produced by <command
linkend="refsec-nix-store-export">nix-store --import</command> from
standard input and adds those store paths to the Nix store. Paths
that already exist in the Nix store are ignored. If a path refers to
another path that doesnt exist in the Nix store, the import
fails.</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--optimise</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--optimise</option></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--optimise</option> reduces Nix store disk
space usage by finding identical files in the store and hard-linking
them to each other. It typically reduces the size of the store by
something like 25-35%. Only regular files and symlinks are
hard-linked in this manner. Files are considered identical when they
have the same NAR archive serialisation: that is, regular files must
have the same contents and permission (executable or non-executable),
and symlinks must have the same contents.</para>
<para>After completion, or when the command is interrupted, a report
on the achieved savings is printed on standard error.</para>
<para>Use <option>-vv</option> or <option>-vvv</option> to get some
progress indication.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store --optimise
hashing files in `/nix/store/qhqx7l2f1kmwihc9bnxs7rc159hsxnf3-gcc-4.1.1'
<replaceable>...</replaceable>
541838819 bytes (516.74 MiB) freed by hard-linking 54143 files;
there are 114486 files with equal contents out of 215894 files in total
</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--read-log</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<group choice='req'>
<arg choice='plain'><option>--read-log</option></arg>
<arg choice='plain'><option>-l</option></arg>
</group>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--read-log</option> prints the build log
of the specified store paths on standard output. The build log is
whatever the builder of a derivation wrote to standard output and
standard error. If a store path is not a derivation, the deriver of
the store path is used.</para>
<para>Build logs are kept in
<filename>/nix/var/log/nix/drvs</filename>. However, there is no
guarantee that a build log is available for any particular store
path. For instance, if the path was downloaded as a pre-built binary
through a substitute, then the log is unavailable.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store -l $(which ktorrent)
building /nix/store/dhc73pvzpnzxhdgpimsd9sw39di66ph1-ktorrent-2.2.1
unpacking sources
unpacking source archive /nix/store/p8n1jpqs27mgkjw07pb5269717nzf5f8-ktorrent-2.2.1.tar.gz
ktorrent-2.2.1/
ktorrent-2.2.1/NEWS
<replaceable>...</replaceable>
</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--dump-db</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--dump-db</option></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--dump-db</option> writes a dump of the
Nix database to standard output. It can be loaded into an empty Nix
store using <option>--load-db</option>. This is useful for making
backups and when migrating to different database schemas.</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--dump-db</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--load-db</option></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--load-db</option> reads a dump of the Nix
database created by <option>--dump-db</option> from standard input and
loads it into the Nix database.</para>
</refsection>
</refsection>
</refentry>

View File

@@ -1,28 +0,0 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>nix-unpack-closure</refname>
<refpurpose>unpack the closure of a store path created by <command>nix-pack-closure</command> into the Nix store</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-unpack-closure</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>The command <command>nix-unpack-closure</command> unpacks the
closure of a set of store paths created by
<command>nix-pack-closure</command> into the local Nix store. The
closure is a single file read from standard input. See the
description of <command>nix-pack-closure</command> for details and
examples.</para>
</refsection>
</refentry>

34
doc/manual/nix-worker.xml Normal file
View File

@@ -0,0 +1,34 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle>nix-worker</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix-worker</refname>
<refpurpose>Nix multi-user support daemon</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-worker</command>
<arg choice="plain"><option>--daemon</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>The Nix daemon is necessary in multi-user Nix installations. It
performs build actions and other operations on the Nix store on behalf
of unprivileged users.</para>
</refsection>
</refentry>

View File

@@ -1,4 +1,4 @@
<nop>
<nop xmlns="http://docbook.org/ns/docbook">
<arg><option>--help</option></arg>
<arg><option>--version</option></arg>
@@ -13,6 +13,10 @@
</group>
<replaceable>number</replaceable>
</arg>
<arg>
<arg><option>--max-silent-time</option></arg>
<replaceable>number</replaceable>
</arg>
<arg><option>--keep-going</option></arg>
<arg><option>-k</option></arg>
<arg><option>--keep-failed</option></arg>
@@ -20,6 +24,7 @@
<arg><option>--fallback</option></arg>
<arg><option>--readonly-mode</option></arg>
<arg><option>--log-type</option> <replaceable>type</replaceable></arg>
<arg><option>--show-trace</option></arg>
<sbr />
</nop>

View File

@@ -103,6 +103,17 @@
</varlistentry>
<varlistentry xml:id="opt-max-silent-time"><term><option>--max-silent-time</option></term>
<listitem><para>Sets the maximum number of seconds that a builder
can go without producing any data on standard output or standard
error. The default is specified by the <link
linkend='conf-build-max-silent-time'><literal>build-max-silent-time</literal></link>
configuration setting. <literal>0</literal> means no
time-out.</para></listitem>
</varlistentry>
<varlistentry><term><option>--keep-going</option></term>
<term><option>-k</option></term>
@@ -240,14 +251,14 @@
<programlisting>
{ # The system (e.g., `i686-linux') for which to build the packages.
system ? __currentSystem
system ? builtins.currentSystem
<replaceable>...</replaceable>
}: <replaceable>...</replaceable></programlisting>
So if you call this Nix expression (e.g., when you do
<literal>nix-env -i <replaceable>pkgname</replaceable></literal>),
the function will be called automatically using the value <link
linkend='builtin-currentSystem'><literal>__currentSystem</literal></link>
linkend='builtin-currentSystem'><literal>builtins.currentSystem</literal></link>
for the <literal>system</literal> argument. You can override this
using <option>--arg</option>, e.g., <literal>nix-env -i
<replaceable>pkgname</replaceable> --arg system
@@ -257,6 +268,17 @@
</varlistentry>
<varlistentry><term><option>--argstr</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
<listitem><para>This option is like <option>--arg</option>, only the
value is not a Nix expression but a string. So instead of
<literal>--arg system \"i686-linux\"</literal> (the outer quotes are
to keep the shell happy) you can say <literal>--argstr system
i686-linux</literal>.</para></listitem>
</varlistentry>
<varlistentry xml:id="opt-attr"><term><option>--attr</option> / <option>-A</option>
<replaceable>attrPath</replaceable></term>
@@ -283,6 +305,14 @@
</varlistentry>
<varlistentry><term><option>--show-trace</option></term>
<listitem><para>Causes Nix to print out a stack trace in case of Nix
expression evaluation errors.</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -0,0 +1,22 @@
<nop xmlns="http://docbook.org/ns/docbook">
<arg>
<group choice='req'>
<arg choice='plain'><option>--prebuilt-only</option></arg>
<arg choice='plain'><option>-b</option></arg>
</group>
</arg>
<arg>
<group choice='req'>
<arg choice='plain'><option>--attr</option></arg>
<arg choice='plain'><option>-A</option></arg>
</group>
</arg>
<arg><option>--from-expression</option></arg>
<arg><option>-E</option></arg>
<arg><option>--from-profile</option> <replaceable>path</replaceable></arg>
</nop>

View File

@@ -6,9 +6,9 @@
<para>This chapter discusses how to do package management with Nix,
i.e., how to obtain, install, upgrade, and erase components. This is
i.e., how to obtain, install, upgrade, and erase packages. This is
the “users” perspective of the Nix system — people
who want to <emphasis>create</emphasis> components should consult
who want to <emphasis>create</emphasis> packages should consult
<xref linkend='chap-writing-nix-expressions' />.</para>
@@ -16,8 +16,8 @@ who want to <emphasis>create</emphasis> components should consult
<para>The main command for package management is <link
linkend="sec-nix-env"><command>nix-env</command></link>. You can use
it to install, upgrade, and erase components, and to query what
components are installed or are available for installation.</para>
it to install, upgrade, and erase packages, and to query what
packages are installed or are available for installation.</para>
<para>In Nix, different users can have different “views”
on the set of installed applications. That is, there might be lots of
@@ -30,18 +30,18 @@ environment</emphasis>, which is just a directory tree consisting of
symlinks to the files of the active applications. </para>
<para>Components are installed from a set of <emphasis>Nix
expressions</emphasis> that tell Nix how to build those components,
expressions</emphasis> that tell Nix how to build those packages,
including, if necessary, their dependencies. There is a collection of
Nix expressions called the Nix Package collection that contains
components ranging from basic development stuff such as GCC and Glibc,
packages ranging from basic development stuff such as GCC and Glibc,
to end-user applications like Mozilla Firefox. (Nix is however not
tied to the Nix Package collection; you could write your own Nix
expressions based on it, or completely new ones.) You can download
the latest version from <link
xlink:href='http://nix.cs.uu.nl/dist/nix' />.</para>
xlink:href='http://nixos.org/releases/full-index-nixpkgs.html' />.</para>
<para>Assuming that you have downloaded and unpacked a release of Nix
Packages, you can view the set of available components in the release:
Packages, you can view the set of available packages in the release:
<screen>
$ nix-env -qaf nixpkgs-<replaceable>version</replaceable> '*'
@@ -74,7 +74,7 @@ gcc-4.1.1</screen>
</para>
<para>It is also possible to see the <emphasis>status</emphasis> of
available components, i.e., whether they are installed into the user
available packages, i.e., whether they are installed into the user
environment and/or present in the system:
<screen>
@@ -86,24 +86,24 @@ IPS bison-1.875d
...</screen>
The first character (<literal>I</literal>) indicates whether the
component is installed in your current user environment. The second
package is installed in your current user environment. The second
(<literal>P</literal>) indicates whether it is present on your system
(in which case installing it into your user environment would be a
very quick operation). The last one (<literal>S</literal>) indicates
whether there is a so-called <emphasis>substitute</emphasis> for the
component, which is Nixs mechanism for doing binary deployment. It
just means that Nix know that it can fetch a pre-built component from
package, which is Nixs mechanism for doing binary deployment. It
just means that Nix knows that it can fetch a pre-built package from
somewhere (typically a network server) instead of building it
locally.</para>
<para>So now that we have a set of Nix expressions we can build the
components contained in them. This is done using <literal>nix-env
packages contained in them. This is done using <literal>nix-env
-i</literal>. For instance,
<screen>
$ nix-env -f nixpkgs-<replaceable>version</replaceable> -i subversion</screen>
will install the component called <literal>subversion</literal> (which
will install the package called <literal>subversion</literal> (which
is, of course, the <link
xlink:href='http://subversion.tigris.org/'>Subversion version
management system</link>).</para>
@@ -112,21 +112,21 @@ management system</link>).</para>
Subversion and all its dependencies. This will take quite a while —
typically an hour or two on modern machines. Fortunately, there is a
faster way (so do a Ctrl-C on that install operation!): you just need
to tell Nix that pre-built binaries of all those components are
to tell Nix that pre-built binaries of all those packages are
available somewhere. This is done using the
<command>nix-pull</command> command, which must be supplied with a URL
containing a <emphasis>manifest</emphasis> describing what binaries
are available. This URL should correspond to the Nix Packages release
that youre using. For instance, if you obtained a release from <link
xlink:href='http://nix.cs.uu.nl/dist/nix/nixpkgs-0.6pre1554/' />, then
you should do:
xlink:href='http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x'
/>, then you should do:
<screen>
$ nix-pull http://nix.cs.uu.nl/dist/nix/nixpkgs-0.6pre1554/MANIFEST</screen>
$ nix-pull http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x/MANIFEST</screen>
If you then issue the installation command, it should start
downloading binaries from <systemitem
class='fqdomainname'>nix.cs.uu.nl</systemitem>, instead of building
class='fqdomainname'>nixos.org</systemitem>, instead of building
them from source. This might still take a while since all
dependencies must be downloaded, but on a reasonably fast connection
such as an DSL line its on the order of a few minutes.</para>
@@ -153,7 +153,7 @@ expressions, use <parameter>-i</parameter> instead of
<parameter>-u</parameter>; <parameter>-i</parameter> will remove
whatever version is already installed.</para>
<para>You can also upgrade all components for which there are newer
<para>You can also upgrade all packages for which there are newer
versions:
<screen>
@@ -199,19 +199,19 @@ set.</para></footnote></para>
implementing the ability to allow different users to have different
configurations, and to do atomic upgrades and rollbacks. To
understand how they work, its useful to know a bit about how Nix
works. In Nix, components are stored in unique locations in the
works. In Nix, packages are stored in unique locations in the
<emphasis>Nix store</emphasis> (typically,
<filename>/nix/store</filename>). For instance, a particular version
of the Subversion component might be stored in a directory
of the Subversion package might be stored in a directory
<filename>/nix/store/dpmvp969yhdqs7lm2r1a3gng7pyq6vy4-subversion-1.1.3/</filename>,
while another version might be stored in
<filename>/nix/store/5mq2jcn36ldlmh93yj1n8s9c95pj7c5s-subversion-1.1.2</filename>.
The long strings prefixed to the directory names are cryptographic
hashes<footnote><para>160-bit truncations of SHA-256 hashes encoded in
a base-32 notation, to be precise.</para></footnote> of
<emphasis>all</emphasis> inputs involved in building the component
<emphasis>all</emphasis> inputs involved in building the package
sources, dependencies, compiler flags, and so on. So if two
components differ in any way, they end up in different locations in
packages differ in any way, they end up in different locations in
the file system, so they dont interfere with each other. <xref
linkend='fig-user-environments' /> shows a part of a typical Nix
store.</para>
@@ -231,12 +231,12 @@ $ /nix/store/dpmvp969yhdq...-subversion-1.1.3/bin/svn</screen>
every time you want to run Subversion. Of course we could set up the
<envar>PATH</envar> environment variable to include the
<filename>bin</filename> directory of every component we want to use,
<filename>bin</filename> directory of every package we want to use,
but this is not very convenient since changing <envar>PATH</envar>
doesnt take effect for already existing processes. The solution Nix
uses is to create directory trees of symlinks to
<emphasis>activated</emphasis> components. These are called
<emphasis>user environments</emphasis> and they are components
<emphasis>activated</emphasis> packages. These are called
<emphasis>user environments</emphasis> and they are packages
themselves (though automatically generated by
<command>nix-env</command>), so they too reside in the Nix store. For
instance, in <xref linkend='fig-user-environments' /> the user
@@ -285,8 +285,8 @@ operation, a new user environment and generation link are created
based on the current one, and finally the <filename>default</filename>
symlink is made to point at the new generation. This last step is
atomic on Unix, which explains how we can do atomic upgrades. (Note
that the building/installing of new components doesnt interfere in
any way with old components, since they are stored in different
that the building/installing of new packages doesnt interfere in
any way with old packages, since they are stored in different
locations in the Nix store.)</para>
<para>If you find that you want to undo a <command>nix-env</command>
@@ -352,18 +352,18 @@ This will <emphasis>not</emphasis> change the
<para><command>nix-env</command> operations such as upgrades
(<option>-u</option>) and uninstall (<option>-e</option>) never
actually delete components from the system. All they do (as shown
actually delete packages from the system. All they do (as shown
above) is to create a new user environment that no longer contains
symlinks to the “deleted” components.</para>
symlinks to the “deleted” packages.</para>
<para>Of course, since disk space is not infinite, unused components
<para>Of course, since disk space is not infinite, unused packages
should be removed at some point. You can do this by running the Nix
garbage collector. It will remove from the Nix store any component
garbage collector. It will remove from the Nix store any package
not used (directly or indirectly) by any generation of any
profile.</para>
<para>Note however that as long as old generations reference a
component, it will not be deleted. After all, we wouldnt be able to
package, it will not be deleted. After all, we wouldnt be able to
do a rollback otherwise. So in order for garbage collection to be
effective, you should also delete (some) old generations. Of course,
this should only be done if you are certain that you will not need to
@@ -458,7 +458,7 @@ URL.</para>
<command>nix-channel --add</command>, e.g.,
<screen>
$ nix-channel --add http://nix.cs.uu.nl/dist/nix/channels-v3/nixpkgs-unstable</screen>
$ nix-channel --add http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable</screen>
subscribes you to a channel that always contains that latest version
of the Nix Packages collection. (Instead of
@@ -486,7 +486,7 @@ makes the union of each channels Nix expressions the default for
<screen>
$ nix-env -u '*'</screen>
to upgrade all components in your profile to the latest versions
to upgrade all packages in your profile to the latest versions
available in the subscribed channels.</para>
</section>
@@ -496,20 +496,19 @@ available in the subscribed channels.</para>
<para>Often, when you want to install a specific package (e.g., from
the <link
xlink:href="http://nix.cs.uu.nl/dist/nix/nixpkgs-unstable-latest/">Nix
Packages collection</link> or from our <link
xlink:href='http://nix.cs.uu.nl/dist/'>release server</link>),
subscribing to a channel is a bit cumbersome. And channels dont help
you at all if you want to install an older version of a package than
the one provided by the current contents of the channel, or a package
that has been removed from the channel. Thats when
<emphasis>one-click installs</emphasis> come in handy: you can just go
to the web page that contains the package, click on it, and it will be
installed with all the necessary dependencies.</para>
xlink:href="http://nixos.org/releases/nixpkgs/nixpkgs-unstable/">Nix
Packages collection</link>), subscribing to a channel is a bit
cumbersome. And channels dont help you at all if you want to install
an older version of a package than the one provided by the current
contents of the channel, or a package that has been removed from the
channel. Thats when <emphasis>one-click installs</emphasis> come in
handy: you can just go to the web page that contains the package,
click on it, and it will be installed with all the necessary
dependencies.</para>
<para>For instance, you can go to <link
xlink:href="http://nix.cs.uu.nl/dist/nix/nixpkgs-unstable-latest/" />
or to any older release of Nix Packages — and click on any link for
xlink:href="http://nixos.org/releases/nixpkgs/nixpkgs-unstable/" />
or to any older release of Nix Packages — and click on any link for
the individual packages for your platform (say, <link
xlink:href='http://nix.cs.uu.nl/dist/nix/nixpkgs-0.10pre6622/pkgs/subversion-1.4.0-i686-linux.nixpkg'><literal>subversion-1.4.0</literal>
for <literal>i686-linux</literal></link>). The first time you do
@@ -529,4 +528,82 @@ linkend='sec-nix-install-package' /> for details.</para>
</section>
<section xml:id="sec-sharing-packages"><title>Sharing packages between machines</title>
<para>Sometimes you want to copy a package from one machine to
another. Or, you want to install some packages and you know that
another machine already has some or all of those packages or their
dependencies. In that case there are mechanisms to quickly copy
packages between machines.</para>
<para>The command <command
linkend="sec-nix-copy-closure">nix-copy-closure</command> copies a Nix
store path along with all its dependencies to or from another machine
via the SSH protocol. It doesnt copy store paths that are already
present on the target machine. For example, the following command
copies Firefox with all its dependencies:
<screen>
$ nix-copy-closure --to alice@itchy.example.org $(type -p firefox)</screen>
See <xref linkend='sec-nix-copy-closure' /> for details.</para>
<para>With <command linkend='refsec-nix-store-export'>nix-store
--export</command> and <command
linkend='refsec-nix-store-import'>nix-store --import</command> you can
write the closure of a store path (that is, the path and all its
dependencies) to a file, and then unpack that file into another Nix
store. For example,
<screen>
$ nix-store --export $(type -p firefox) > firefox.closure</screen>
writes the closure of Firefox to a file. You can then copy this file
to another machine and install the closure:
<screen>
$ nix-store --import &lt; firefox.closure</screen>
Any store paths in the closure that are already present in the target
store are ignored. It is also possible to pipe the export into
another command, e.g. to copy and install a closure directly to/on
another machine:
<screen>
$ nix-store --export $(type -p firefox) | bzip2 | \
ssh alice@itchy.example.org "bunzip2 | nix-store --import"</screen>
But note that <command>nix-copy-closure</command> is generally more
efficient in this example because it only copies paths that are not
already present in the target Nix store.</para>
<para>Finally, if you can mount the Nix store of a remote machine in
your local filesystem, Nix can copy paths from the remote Nix store to
the local Nix store <emphasis>on demand</emphasis>. For instance,
suppose that you mount a remote machine containing a Nix store via
<command
xlink:href="http://fuse.sourceforge.net/sshfs.html">sshfs</command>:
<screen>
$ sshfs alice@itchy.example.org:/ /mnt</screen>
You should then set the <envar>NIX_OTHER_STORES</envar> environment
variable to tell Nix about this remote Nix store:
<screen>
$ export NIX_OTHER_STORES=/mnt/nix</screen>
Then if you do any Nix operation, e.g.
<screen>
$ nix-env -i firefox</screen>
and Nix has to build a path that it sees is already present in
<filename>/mnt/nix</filename>, then it will just copy from there
instead of building it from source.</para>
</section>
</chapter>

View File

@@ -11,7 +11,7 @@ to the following chapters.</para>
<orderedlist>
<listitem><para>Download a source tarball or RPM from <link
xlink:href='http://www.cs.uu.nl/groups/ST/Trace/Nix'/>. Build source
xlink:href='http://nixos.org/'/>. Build source
distributions using the regular sequence:
<screen>
@@ -22,8 +22,9 @@ $ make install <lineannotation>(as root)</lineannotation></screen>
This will install Nix in <filename>/nix</filename>. You shouldn't
change the prefix if at all possible since that will make it
impossible to use our pre-built components. Alternatively, you could
grab an RPM if you're on an RPM-based system. You should also add
impossible to use pre-built binaries from the Nixpkgs channel and
other channels. Alternatively, you could grab an RPM if you're on an
RPM-based system. You should also add
<filename>/nix/etc/profile.d/nix.sh</filename> to your
<filename>~/.bashrc</filename> (or some other login
file).</para></listitem>
@@ -32,7 +33,7 @@ file).</para></listitem>
<screen>
$ nix-channel --add \
http://nix.cs.uu.nl/dist/nix/channels-v3/nixpkgs-unstable</screen>
http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable</screen>
</para></listitem>
@@ -40,14 +41,14 @@ $ nix-channel --add \
<screen>
$ nix-channel --update</screen>
Note that this in itself doesn't download any components, it just
Note that this in itself doesn't download any packages, it just
downloads the Nix expressions that build them and stores them
somewhere (under <filename>~/.nix-defexpr</filename>, in case you're
curious). Also, it registers the fact that pre-built binaries are
available remotely.</para></listitem>
<listitem><para>See what installable components are currently
available in the channel:
<listitem><para>See what installable packages are currently available
in the channel:
<screen>
$ nix-env -qa * <lineannotation>(mind the quotes!)</lineannotation>
@@ -59,13 +60,13 @@ libxslt-1.1.0
</para></listitem>
<listitem><para>Install some components from the channel:
<listitem><para>Install some packages from the channel:
<screen>
$ nix-env -i hello firefox <replaceable>...</replaceable> </screen>
This should download the pre-built components; it should not build
them locally (if it does, something went wrong).</para></listitem>
This should download pre-built packages; it should not build them
locally (if it does, something went wrong).</para></listitem>
<listitem><para>Test that they work:
@@ -92,8 +93,8 @@ $ nix-env -e hello</screen>
$ nix-channel --update
$ nix-env -u '*'</screen>
The latter command will upgrade each installed component for which
there is a “newer” version (as determined by comparing the version
The latter command will upgrade each installed package for which there
is a “newer” version (as determined by comparing the version
numbers).</para></listitem>
<listitem><para>You can also install specific packages directly from
@@ -107,7 +108,7 @@ appear asking you whether its okay to install the package. Say
installed.</para></listitem>
<listitem><para>If you're unhappy with the result of a
<command>nix-env</command> action (e.g., an upgraded component turned
<command>nix-env</command> action (e.g., an upgraded package turned
out not to work properly), you can go back:
<screen>
@@ -124,7 +125,7 @@ $ nix-collect-garbage -d</screen>
<!--
The first command deletes old “generations” of your profile (making
rollbacks impossible, but also making the components in those old
rollbacks impossible, but also making the packages in those old
generations available for garbage collection), while the second
command actually deletes them.-->

View File

@@ -1,10 +1,545 @@
<article xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-relnotes">
<title>Nix Release Notes</title>
<!--==================================================================-->
<section xml:id="ssec-relnotes-0.13"><title>Release 0.13 (April NN,
2009)</title>
<para>This is primarily a bug fix release. It has some new
features:</para>
<itemizedlist>
<listitem>
<para>Syntactic sugar for writing nested attribute sets. Instead of
<programlisting>
{
foo = {
bar = 123;
xyzzy = true;
};
a = { b = { c = "d"; }; };
}
</programlisting>
you can write
<programlisting>
{
foo.bar = 123;
foo.xyzzy = true;
a.b.c = "d";
}
</programlisting>
This is useful, for instance, in NixOS configuration files.</para>
</listitem>
<listitem>
<para>Support for Nix channels generated by Hydra, the Nix-based
continuous build system. (Hydra generates NAR archives on the
fly, so the size and hash of these archives isnt known in
advance.)</para>
</listitem>
<listitem>
<para>Support <literal>i686-linux</literal> builds directly on
<literal>x86_64-linux</literal> Nix installations. This is
implemented using the <function>personality()</function> syscall,
which causes <command>uname</command> to return
<literal>i686</literal> in child processes.</para>
</listitem>
<listitem>
<para>Various improvements to the <literal>chroot</literal>
support. Building in a <literal>chroot</literal> works quite well
now.</para>
</listitem>
<listitem>
<para>Nix no longer blocks if it tries to build a path and another
process is already building the same path. Instead it tries to
build another buildable path first. This improves
parallelism.</para>
</listitem>
<listitem>
<para>Support for large (> 4 GiB) files in NAR archives.</para>
</listitem>
<listitem>
<para>Various (performance) improvements to the remote build
mechanism.</para>
</listitem>
<listitem>
<para>New primops: <varname>builtins.addErrorContext</varname> (to
add a string to stack traces — useful for debugging),
<varname>builtins.isBool</varname>,
<varname>builtins.isString</varname>,
<varname>builtins.isInt</varname>.</para>
</listitem>
</itemizedlist>
</section>
<!--==================================================================-->
<section xml:id="ssec-relnotes-0.12"><title>Release 0.12 (November 20,
2008)</title>
<itemizedlist>
<listitem>
<para>Nix no longer uses Berkeley DB to store Nix store metadata.
The principal advantages of the new storage scheme are: it works
properly over decent implementations of NFS (allowing Nix stores
to be shared between multiple machines); no recovery is needed
when a Nix process crashes; no write access is needed for
read-only operations; no more running out of Berkeley DB locks on
certain operations.</para>
<para>You still need to compile Nix with Berkeley DB support if
you want Nix to automatically convert your old Nix store to the
new schema. If you dont need this, you can build Nix with the
<filename>configure</filename> option
<option>--disable-old-db-compat</option>.</para>
<para>After the automatic conversion to the new schema, you can
delete the old Berkeley DB files:
<screen>
$ cd /nix/var/nix/db
$ rm __db* log.* derivers references referrers reserved validpaths DB_CONFIG</screen>
The new metadata is stored in the directories
<filename>/nix/var/nix/db/info</filename> and
<filename>/nix/var/nix/db/referrer</filename>. Though the
metadata is stored in human-readable plain-text files, they are
not intended to be human-editable, as Nix is rather strict about
the format.</para>
<para>The new storage schema may or may not require less disk
space than the Berkeley DB environment, mostly depending on the
cluster size of your file system. With 1 KiB clusters (which
seems to be the <literal>ext3</literal> default nowadays) it
usually takes up much less space.</para>
</listitem>
<listitem><para>There is a new substituter that copies paths
directly from other (remote) Nix stores mounted somewhere in the
filesystem. For instance, you can speed up an installation by
mounting some remote Nix store that already has the packages in
question via NFS or <literal>sshfs</literal>. The environment
variable <envar>NIX_OTHER_STORES</envar> specifies the locations of
the remote Nix directories,
e.g. <literal>/mnt/remote-fs/nix</literal>.</para></listitem>
<listitem><para>New <command>nix-store</command> operations
<option>--dump-db</option> and <option>--load-db</option> to dump
and reload the Nix database.</para></listitem>
<listitem><para>The garbage collector has a number of new options to
allow only some of the garbage to be deleted. The option
<option>--max-freed <replaceable>N</replaceable></option> tells the
collector to stop after at least <replaceable>N</replaceable> bytes
have been deleted. The option <option>--max-links
<replaceable>N</replaceable></option> tells it to stop after the
link count on <filename>/nix/store</filename> has dropped below
<replaceable>N</replaceable>. This is useful for very large Nix
stores on filesystems with a 32000 subdirectories limit (like
<literal>ext3</literal>). The option <option>--use-atime</option>
causes store paths to be deleted in order of ascending last access
time. This allows non-recently used stuff to be deleted. The
option <option>--max-atime <replaceable>time</replaceable></option>
specifies an upper limit to the last accessed time of paths that may
be deleted. For instance,
<screen>
$ nix-store --gc -v --max-atime $(date +%s -d "2 months ago")</screen>
deletes everything that hasnt been accessed in two months.</para></listitem>
<listitem><para><command>nix-env</command> now uses optimistic
profile locking when performing an operation like installing or
upgrading, instead of setting an exclusive lock on the profile.
This allows multiple <command>nix-env -i / -u / -e</command>
operations on the same profile in parallel. If a
<command>nix-env</command> operation sees at the end that the profile
was changed in the meantime by another process, it will just
restart. This is generally cheap because the build results are
still in the Nix store.</para></listitem>
<listitem><para>The option <option>--dry-run</option> is now
supported by <command>nix-store -r</command> and
<command>nix-build</command>.</para></listitem>
<listitem><para>The information previously shown by
<option>--dry-run</option> (i.e., which derivations will be built
and which paths will be substituted) is now always shown by
<command>nix-env</command>, <command>nix-store -r</command> and
<command>nix-build</command>. The total download size of
substitutable paths is now also shown. For instance, a build will
show something like
<screen>
the following derivations will be built:
/nix/store/129sbxnk5n466zg6r1qmq1xjv9zymyy7-activate-configuration.sh.drv
/nix/store/7mzy971rdm8l566ch8hgxaf89x7lr7ik-upstart-jobs.drv
...
the following paths will be downloaded/copied (30.02 MiB):
/nix/store/4m8pvgy2dcjgppf5b4cj5l6wyshjhalj-samba-3.2.4
/nix/store/7h1kwcj29ip8vk26rhmx6bfjraxp0g4l-libunwind-0.98.6
...</screen>
</para></listitem>
<listitem><para>Language features:
<itemizedlist>
<listitem><para>@-patterns as in Haskell. For instance, in a
function definition
<programlisting>f = args @ {x, y, z}: <replaceable>...</replaceable>;</programlisting>
<varname>args</varname> refers to the argument as a whole, which
is further pattern-matched against the attribute set pattern
<literal>{x, y, z}</literal>.</para></listitem>
<listitem><para><literal>...</literal>” (ellipsis) patterns.
An attribute set pattern can now say <literal>...</literal> at
the end of the attribute name list to specify that the function
takes <emphasis>at least</emphasis> the listed attributes, while
ignoring additional attributes. For instance,
<programlisting>{stdenv, fetchurl, fuse, ...}: <replaceable>...</replaceable></programlisting>
defines a function that accepts any attribute set that includes
at least the three listed attributes.</para></listitem>
<listitem><para>New primops:
<varname>builtins.parseDrvName</varname> (split a package name
string like <literal>"nix-0.12pre12876"</literal> into its name
and version components, e.g. <literal>"nix"</literal> and
<literal>"0.12pre12876"</literal>),
<varname>builtins.compareVersions</varname> (compare two version
strings using the same algorithm that <command>nix-env</command>
uses), <varname>builtins.length</varname> (efficiently compute
the length of a list), <varname>builtins.mul</varname> (integer
multiplication), <varname>builtins.div</varname> (integer
division).
<!-- <varname>builtins.genericClosure</varname> -->
</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para><command>nix-prefetch-url</command> now supports
<literal>mirror://</literal> URLs, provided that the environment
variable <envar>NIXPKGS_ALL</envar> points at a Nixpkgs
tree.</para></listitem>
<listitem><para>Removed the commands
<command>nix-pack-closure</command> and
<command>nix-unpack-closure</command>. You can do almost the same
thing but much more efficiently by doing <literal>nix-store --export
$(nix-store -qR <replaceable>paths</replaceable>) > closure</literal> and
<literal>nix-store --import &lt;
closure</literal>.</para></listitem>
<listitem><para>Lots of bug fixes, including a big performance bug in
the handling of <literal>with</literal>-expressions.</para></listitem>
</itemizedlist>
</section>
<!--==================================================================-->
<section xml:id="ssec-relnotes-0.11"><title>Release 0.11 (December 31,
2007)</title>
<para>Nix 0.11 has many improvements over the previous stable release.
The most important improvement is secure multi-user support. It also
features many usability enhancements and language extensions, many of
them prompted by NixOS, the purely functional Linux distribution based
on Nix. Here is an (incomplete) list:</para>
<itemizedlist>
<listitem><para>Secure multi-user support. A single Nix store can
now be shared between multiple (possible untrusted) users. This is
an important feature for NixOS, where it allows non-root users to
install software. The old setuid method for sharing a store between
multiple users has been removed. Details for setting up a
multi-user store can be found in the manual.</para></listitem>
<listitem><para>The new command <command>nix-copy-closure</command>
gives you an easy and efficient way to exchange software between
machines. It copies the missing parts of the closure of a set of
store path to or from a remote machine via
<command>ssh</command>.</para></listitem>
<listitem><para>A new kind of string literal: strings between double
single-quotes (<literal>''</literal>) have indentation
“intelligently” removed. This allows large strings (such as shell
scripts or configuration file fragments in NixOS) to cleanly follow
the indentation of the surrounding expression. It also requires
much less escaping, since <literal>''</literal> is less common in
most languages than <literal>"</literal>.</para></listitem>
<listitem><para><command>nix-env</command> <option>--set</option>
modifies the current generation of a profile so that it contains
exactly the specified derivation, and nothing else. For example,
<literal>nix-env -p /nix/var/nix/profiles/browser --set
firefox</literal> lets the profile named
<filename>browser</filename> contain just Firefox.</para></listitem>
<listitem><para><command>nix-env</command> now maintains
meta-information about installed packages in profiles. The
meta-information is the contents of the <varname>meta</varname>
attribute of derivations, such as <varname>description</varname> or
<varname>homepage</varname>. The command <literal>nix-env -q --xml
--meta</literal> shows all meta-information.</para></listitem>
<listitem><para><command>nix-env</command> now uses the
<varname>meta.priority</varname> attribute of derivations to resolve
filename collisions between packages. Lower priority values denote
a higher priority. For instance, the GCC wrapper package and the
Binutils package in Nixpkgs both have a file
<filename>bin/ld</filename>, so previously if you tried to install
both you would get a collision. Now, on the other hand, the GCC
wrapper declares a higher priority than Binutils, so the formers
<filename>bin/ld</filename> is symlinked in the user
environment.</para></listitem>
<listitem><para><command>nix-env -i / -u</command>: instead of
breaking package ties by version, break them by priority and version
number. That is, if there are multiple packages with the same name,
then pick the package with the highest priority, and only use the
version if there are multiple packages with the same
priority.</para>
<para>This makes it possible to mark specific versions/variant in
Nixpkgs more or less desirable than others. A typical example would
be a beta version of some package (e.g.,
<literal>gcc-4.2.0rc1</literal>) which should not be installed even
though it is the highest version, except when it is explicitly
selected (e.g., <literal>nix-env -i
gcc-4.2.0rc1</literal>).</para></listitem>
<listitem><para><command>nix-env --set-flag</command> allows meta
attributes of installed packages to be modified. There are several
attributes that can be usefully modified, because they affect the
behaviour of <command>nix-env</command> or the user environment
build script:
<itemizedlist>
<listitem><para><varname>meta.priority</varname> can be changed
to resolve filename clashes (see above).</para></listitem>
<listitem><para><varname>meta.keep</varname> can be set to
<literal>true</literal> to prevent the package from being
upgraded or replaced. Useful if you want to hang on to an older
version of a package.</para></listitem>
<listitem><para><varname>meta.active</varname> can be set to
<literal>false</literal> to “disable” the package. That is, no
symlinks will be generated to the files of the package, but it
remains part of the profile (so it wont be garbage-collected).
Set it back to <literal>true</literal> to re-enable the
package.</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para><command>nix-env -q</command> now has a flag
<option>--prebuilt-only</option> (<option>-b</option>) that causes
<command>nix-env</command> to show only those derivations whose
output is already in the Nix store or that can be substituted (i.e.,
downloaded from somewhere). In other words, it shows the packages
that can be installed “quickly”, i.e., dont need to be built from
source. The <option>-b</option> flag is also available in
<command>nix-env -i</command> and <command>nix-env -u</command> to
filter out derivations for which no pre-built binary is
available.</para></listitem>
<listitem><para>The new option <option>--argstr</option> (in
<command>nix-env</command>, <command>nix-instantiate</command> and
<command>nix-build</command>) is like <option>--arg</option>, except
that the value is a string. For example, <literal>--argstr system
i686-linux</literal> is equivalent to <literal>--arg system
\"i686-linux\"</literal> (note that <option>--argstr</option>
prevents annoying quoting around shell arguments).</para></listitem>
<listitem><para><command>nix-store</command> has a new operation
<option>--read-log</option> (<option>-l</option>)
<parameter>paths</parameter> that shows the build log of the given
paths.</para></listitem>
<!--
<listitem><para>TODO: semantic cleanups of string concatenation
etc. (mostly in r6740).</para></listitem>
-->
<listitem><para>Nix now uses Berkeley DB 4.5. The database is
upgraded automatically, but you should be careful not to use old
versions of Nix that still use Berkeley DB 4.4.</para></listitem>
<!-- foo
<listitem><para>TODO: option <option>- -reregister</option> in
<command>nix-store - -register-validity</command>.</para></listitem>
-->
<listitem><para>The option <option>--max-silent-time</option>
(corresponding to the configuration setting
<literal>build-max-silent-time</literal>) allows you to set a
timeout on builds — if a build produces no output on
<literal>stdout</literal> or <literal>stderr</literal> for the given
number of seconds, it is terminated. This is useful for recovering
automatically from builds that are stuck in an infinite
loop.</para></listitem>
<listitem><para><command>nix-channel</command>: each subscribed
channel is its own attribute in the top-level expression generated
for the channel. This allows disambiguation (e.g. <literal>nix-env
-i -A nixpkgs_unstable.firefox</literal>).</para></listitem>
<listitem><para>The substitutes table has been removed from the
database. This makes operations such as <command>nix-pull</command>
and <command>nix-channel --update</command> much, much
faster.</para></listitem>
<listitem><para><command>nix-pull</command> now supports
bzip2-compressed manifests. This speeds up
channels.</para></listitem>
<listitem><para><command>nix-prefetch-url</command> now has a
limited form of caching. This is used by
<command>nix-channel</command> to prevent unnecessary downloads when
the channel hasnt changed.</para></listitem>
<listitem><para><command>nix-prefetch-url</command> now by default
computes the SHA-256 hash of the file instead of the MD5 hash. In
calls to <function>fetchurl</function> you should pass the
<literal>sha256</literal> attribute instead of
<literal>md5</literal>. You can pass either a hexadecimal or a
base-32 encoding of the hash.</para></listitem>
<listitem><para>Nix can now perform builds in an automatically
generated “chroot”. This prevents a builder from accessing stuff
outside of the Nix store, and thus helps ensure purity. This is an
experimental feature.</para></listitem>
<listitem><para>The new command <command>nix-store
--optimise</command> reduces Nix store disk space usage by finding
identical files in the store and hard-linking them to each other.
It typically reduces the size of the store by something like
25-35%.</para></listitem>
<listitem><para><filename>~/.nix-defexpr</filename> can now be a
directory, in which case the Nix expressions in that directory are
combined into an attribute set, with the file names used as the
names of the attributes. The command <command>nix-env
--import</command> (which set the
<filename>~/.nix-defexpr</filename> symlink) is
removed.</para></listitem>
<listitem><para>Derivations can specify the new special attribute
<varname>allowedReferences</varname> to enforce that the references
in the output of a derivation are a subset of a declared set of
paths. For example, if <varname>allowedReferences</varname> is an
empty list, then the output must not have any references. This is
used in NixOS to check that generated files such as initial ramdisks
for booting Linux dont have any dependencies.</para></listitem>
<listitem><para>The new attribute
<varname>exportReferencesGraph</varname> allows builders access to
the references graph of their inputs. This is used in NixOS for
tasks such as generating ISO-9660 images that contain a Nix store
populated with the closure of certain paths.</para></listitem>
<listitem><para>Fixed-output derivations (like
<function>fetchurl</function>) can define the attribute
<varname>impureEnvVars</varname> to allow external environment
variables to be passed to builders. This is used in Nixpkgs to
support proxy configuration, among other things.</para></listitem>
<listitem><para>Several new built-in functions:
<function>builtins.attrNames</function>,
<function>builtins.filterSource</function>,
<function>builtins.isAttrs</function>,
<function>builtins.isFunction</function>,
<function>builtins.listToAttrs</function>,
<function>builtins.stringLength</function>,
<function>builtins.sub</function>,
<function>builtins.substring</function>,
<function>throw</function>,
<function>builtins.trace</function>,
<function>builtins.readFile</function>.</para></listitem>
</itemizedlist>
</section>
<!--==================================================================-->
<section><title>Release 0.10.1 (October 11, 2006)</title>
<para>This release fixes two somewhat obscure bugs that occur when
evaluating Nix expressions that are stored inside the Nix store
(<literal>NIX-67</literal>). These do not affect most users.</para>
</section>
<!--==================================================================-->
<section><title>Release 0.10 (October 6, 2006)</title>

View File

@@ -46,6 +46,11 @@ h3 /* subsections */
font-size: 125%;
}
div.simplesect h2
{
font-size: 110%;
}
div.appendix h3
{
font-size: 150%;

View File

@@ -4,33 +4,9 @@
<title>Troubleshooting</title>
<para>This section provides solutions for some common problems.</para>
<section><title>Berkeley DB: <quote>Cannot allocate memory</quote></title>
<para>Symptom: Nix operations (in particular the
<command>nix-store</command> operations <option>--gc</option>,
<option>--verify</option>, and <option>--clear-substitutes</option>
the latter being called by <command>nix-channel --update</command>)
failing:
<screen>
$ nix-store --verify
error: Db::del: Cannot allocate memory</screen>
</para>
<para>Possible solution: make sure that no Nix processes are running,
then do:
<screen>
$ cd /nix/var/nix/db
$ rm __db.00*</screen>
</para>
</section>
<para>This section provides solutions for some common problems. See
the <link xlink:href="http://bugs.strategoxt.org/browse/NIX">Nix
bug tracker</link> for a list of currently known issues.</para>
<section><title>Collisions in <command>nix-env</command></title>
@@ -100,7 +76,8 @@ Furthermore, the <literal>st_nlink</literal> field of the
<para>This only happens on very large Nix installations (such as build
machines).</para>
<para>Quick solution: run the garbage collector.</para>
<para>Quick solution: run the garbage collector. You may want to use
the <option>--max-links</option> option.</para>
<para>Real solution: put the Nix store on a file system that supports
more than 32,000 subdirectories per directory, such as ReiserFS.

File diff suppressed because it is too large Load Diff

24
doc/signing.txt Normal file
View File

@@ -0,0 +1,24 @@
Generate a private key:
$ (umask 277 && openssl genrsa -out /nix/etc/nix/signing-key.sec 2048)
The private key should be kept secret (only readable to the Nix daemon
user).
Generate the corresponding public key:
$ openssl rsa -in /nix/etc/nix/signing-key.sec -pubout > /nix/etc/nix/signing-key.pub
The public key should be copied to all machines to which you want to
export store paths.
Signing:
$ nix-hash --type sha256 --flat svn.nar | openssl rsautl -sign -inkey mykey.sec > svn.nar.sign
Verifying a signature:
$ test "$(nix-hash --type sha256 --flat svn.nar)" = "$(openssl rsautl -verify -inkey mykey.pub -pubin -in svn.nar.sign)"

40
externals/Makefile.am vendored
View File

@@ -1,11 +1,13 @@
# Berkeley DB
DB = db-4.4.20.NC
DB = db-4.5.20
if OLD_DB_COMPAT
$(DB).tar.gz:
@echo "Nix requires Berkeley DB to build."
@echo "Please download version 4.4.20 from"
@echo " http://downloads.sleepycat.com/db-4.4.20.NC.tar.gz"
@echo "Please download version 4.5.20 from"
@echo " http://download-east.oracle.com/berkeley-db/db-4.5.20.tar.gz"
@echo "and place it in the externals/ directory."
false
@@ -32,22 +34,26 @@ build-db: have-db
touch build-db
endif
else
build-db:
endif
# CWI ATerm
ATERM = aterm-2.4.2
ATERM = aterm-2.4.2-fixes-r2
$(ATERM).tar.gz:
$(ATERM).tar.bz2:
@echo "Nix requires the CWI ATerm library to build."
@echo "Please download version 2.4.2 from"
@echo " http://www.cwi.nl/projects/MetaEnv/aterm/aterm-2.4.2.tar.gz"
@echo "Please download version 2.4.2-fixes-r2 from"
@echo " http://nixos.org/tarballs/aterm-2.4.2-fixes-r2.tar.bz2"
@echo "and place it in the externals/ directory."
false
$(ATERM): $(ATERM).tar.gz
gunzip < $(srcdir)/$(ATERM).tar.gz | tar xvf -
(cd $(ATERM) && $(patch) -p1) < $(srcdir)/aterm-aliasing.patch
# (cd $(ATERM) && $(patch) -p1) < $(srcdir)/aterm-64-bit.patch
$(ATERM): $(ATERM).tar.bz2
bunzip2 < $(srcdir)/$(ATERM).tar.bz2 | tar xvf -
have-aterm:
$(MAKE) $(ATERM)
@@ -69,12 +75,12 @@ endif
# bzip2
BZIP2 = bzip2-1.0.3
BZIP2 = bzip2-1.0.5
$(BZIP2).tar.gz:
@echo "Nix requires bzip2 to build."
@echo "Please download version 1.0.3 from"
@echo " http://www.bzip.org/1.0.3/bzip2-1.0.3.tar.gz"
@echo "Please download version 1.0.5 from"
@echo " http://www.bzip.org/1.0.5/bzip2-1.0.5.tar.gz"
@echo "and place it in the externals/ directory."
false
@@ -103,9 +109,9 @@ endif
all: build-db build-aterm build-bzip2
EXTRA_DIST = $(DB).tar.gz $(ATERM).tar.gz $(BZIP2).tar.gz \
bdb-cygwin.patch aterm-aliasing.patch aterm-64-bit.patch
EXTRA_DIST = $(DB).tar.gz $(ATERM).tar.bz2 $(BZIP2).tar.gz \
bdb-cygwin.patch
ext-clean:
$(RM) -f have-db build-db have-aterm build-aterm
$(RM) -f have-db build-db have-aterm build-aterm have-bzip2 build-bzip2
$(RM) -rf $(DB) $(ATERM) $(BZIP2)

View File

@@ -1,661 +0,0 @@
diff -rc aterm-2.4.2-orig/aterm/bafio.c aterm-2.4.2/aterm/bafio.c
*** aterm-2.4.2-orig/aterm/bafio.c 2004-02-02 12:24:34.000000000 +0100
--- aterm-2.4.2/aterm/bafio.c 2006-09-22 13:39:07.000000000 +0200
***************
*** 222,227 ****
--- 222,229 ----
}
}
+ if (val) return -1;
+
/* Ok */
return 0;
}
***************
*** 544,551 ****
* terms have been sorted by symbol.
*/
! void gather_top_symbols(sym_entry *cur_entry, int cur_arg,
! int total_top_symbols)
{
int index;
unsigned int hnr;
--- 546,553 ----
* terms have been sorted by symbol.
*/
! static void gather_top_symbols(sym_entry *cur_entry, int cur_arg,
! int total_top_symbols)
{
int index;
unsigned int hnr;
***************
*** 899,905 ****
} else {
switch(ATgetType(t)) {
case AT_INT:
! if(writeBits(ATgetInt((ATermInt)t), HEADER_BITS, writer) < 0) {
return ATfalse;
}
#if 0
--- 901,908 ----
} else {
switch(ATgetType(t)) {
case AT_INT:
! /* If ATerm integers are > 32 bits, then this can fail. */
! if(writeBits(ATgetInt((ATermInt)t), INT_SIZE_IN_BAF, writer) < 0) {
return ATfalse;
}
#if 0
***************
*** 1033,1039 ****
/*}}} */
/*{{{ ATbool write_baf(ATerm t, byte_writer *writer) */
! ATbool
write_baf(ATerm t, byte_writer *writer)
{
int nr_unique_terms = 0;
--- 1036,1042 ----
/*}}} */
/*{{{ ATbool write_baf(ATerm t, byte_writer *writer) */
! static ATbool
write_baf(ATerm t, byte_writer *writer)
{
int nr_unique_terms = 0;
***************
*** 1233,1239 ****
* Read a single symbol from file.
*/
! Symbol read_symbol(byte_reader *reader)
{
unsigned int arity, quoted;
int len;
--- 1236,1242 ----
* Read a single symbol from file.
*/
! static Symbol read_symbol(byte_reader *reader)
{
unsigned int arity, quoted;
int len;
***************
*** 1260,1266 ****
* Read all symbols from file.
*/
! ATbool read_all_symbols(byte_reader *reader)
{
unsigned int val;
int i, j, k, arity;
--- 1263,1269 ----
* Read all symbols from file.
*/
! static ATbool read_all_symbols(byte_reader *reader)
{
unsigned int val;
int i, j, k, arity;
***************
*** 1280,1293 ****
/*}}} */
/*{{{ Read term count and allocate space */
! if(readInt(&val, reader) < 0)
return ATfalse;
read_symbols[i].nr_terms = val;
read_symbols[i].term_width = bit_width(val);
! if(val == 0)
! read_symbols[i].terms = NULL;
! else
! read_symbols[i].terms = (ATerm *)calloc(val, sizeof(ATerm));
if(!read_symbols[i].terms)
ATerror("read_symbols: could not allocate space for %d terms.\n", val);
ATprotectArray(read_symbols[i].terms, val);
--- 1283,1293 ----
/*}}} */
/*{{{ Read term count and allocate space */
! if(readInt(&val, reader) < 0 || val == 0)
return ATfalse;
read_symbols[i].nr_terms = val;
read_symbols[i].term_width = bit_width(val);
! read_symbols[i].terms = (ATerm *)calloc(val, sizeof(ATerm));
if(!read_symbols[i].terms)
ATerror("read_symbols: could not allocate space for %d terms.\n", val);
ATprotectArray(read_symbols[i].terms, val);
***************
*** 1351,1357 ****
/*}}} */
/*{{{ ATerm read_term(sym_read_entry *sym, byte_reader *reader) */
! ATerm read_term(sym_read_entry *sym, byte_reader *reader)
{
unsigned int val;
int i, arity = sym->arity;
--- 1351,1357 ----
/*}}} */
/*{{{ ATerm read_term(sym_read_entry *sym, byte_reader *reader) */
! static ATerm read_term(sym_read_entry *sym, byte_reader *reader)
{
unsigned int val;
int i, arity = sym->arity;
***************
*** 1365,1370 ****
--- 1365,1371 ----
ATprotectArray(args, arity);
if(!args)
ATerror("could not allocate space for %d arguments.\n", arity);
+ /* !!! leaks memory on the "return NULL" paths */
}
/*ATfprintf(stderr, "reading term over symbol %y\n", sym->sym);*/
***************
*** 1372,1377 ****
--- 1373,1380 ----
/*ATfprintf(stderr, " reading argument %d (%d)", i, sym->sym_width[i]);*/
if(readBits(&val, sym->sym_width[i], reader) < 0)
return NULL;
+ if(val >= sym->nr_topsyms[i])
+ return NULL;
arg_sym = &read_symbols[sym->topsyms[i][val]];
/* ATfprintf(stderr, "argument %d, symbol index = %d, symbol = %y\n",
i, val, arg_sym->sym);*/
***************
*** 1381,1386 ****
--- 1384,1391 ----
if(readBits(&val, arg_sym->term_width, reader) < 0)
return NULL;
/* ATfprintf(stderr, "arg term index = %d\n", val);*/
+ if(val >= arg_sym->nr_terms)
+ return NULL;
if(!arg_sym->terms[val]) {
arg_sym->terms[val] = read_term(arg_sym, reader);
if(!arg_sym->terms[val])
***************
*** 1396,1402 ****
case AS_INT:
/*{{{ Read an integer */
! if(readBits(&val, HEADER_BITS, reader) < 0)
return NULL;
result = (ATerm)ATmakeInt((int)val);
--- 1401,1407 ----
case AS_INT:
/*{{{ Read an integer */
! if(readBits(&val, INT_SIZE_IN_BAF, reader) < 0)
return NULL;
result = (ATerm)ATmakeInt((int)val);
***************
*** 1494,1502 ****
for(i=0; i<nr_unique_symbols; i++) {
sym_read_entry *entry = &read_symbols[i];
! ATunprotectArray(entry->terms);
! if(entry->terms)
free(entry->terms);
if(entry->nr_topsyms)
free(entry->nr_topsyms);
if(entry->sym_width)
--- 1499,1508 ----
for(i=0; i<nr_unique_symbols; i++) {
sym_read_entry *entry = &read_symbols[i];
! if(entry->terms) {
! ATunprotectArray(entry->terms);
free(entry->terms);
+ }
if(entry->nr_topsyms)
free(entry->nr_topsyms);
if(entry->sym_width)
Only in aterm-2.4.2/aterm: config.h.in
diff -rc aterm-2.4.2-orig/aterm/encoding.h aterm-2.4.2/aterm/encoding.h
*** aterm-2.4.2-orig/aterm/encoding.h 2004-06-01 10:29:02.000000000 +0200
--- aterm-2.4.2/aterm/encoding.h 2006-09-22 13:39:07.000000000 +0200
***************
*** 10,15 ****
--- 10,17 ----
{
#endif/* __cplusplus */
+ #include "config.h"
+
/*
|--------------------------------|
|info|type |arity|quoted|mark|age|
***************
*** 31,37 ****
#define SHIFT_REMOVE_MARK_AGE 3
#define MASK_AGE_MARK (MASK_AGE|MASK_MARK)
! #if AT_64BIT
#define SHIFT_LENGTH 34
#define HEADER_BITS 64
typedef unsigned long header_type;
--- 33,39 ----
#define SHIFT_REMOVE_MARK_AGE 3
#define MASK_AGE_MARK (MASK_AGE|MASK_MARK)
! #ifdef AT_64BIT
#define SHIFT_LENGTH 34
#define HEADER_BITS 64
typedef unsigned long header_type;
***************
*** 137,142 ****
--- 139,150 ----
#define AT_TABLE_SIZE(table_class) (1<<(table_class))
#define AT_TABLE_MASK(table_class) (AT_TABLE_SIZE(table_class)-1)
+
+ /* Integers in BAF are always exactly 32 bits. The size must be fixed so that
+ * BAF terms can be exchanged between platforms. */
+ #define INT_SIZE_IN_BAF 32
+
+
#ifdef __cplusplus
}
#endif/* __cplusplus */
diff -rc aterm-2.4.2-orig/aterm/gc.c aterm-2.4.2/aterm/gc.c
*** aterm-2.4.2-orig/aterm/gc.c 2004-06-01 10:29:02.000000000 +0200
--- aterm-2.4.2/aterm/gc.c 2006-09-22 13:39:07.000000000 +0200
***************
*** 154,166 ****
}
#ifdef AT_64BIT
! odd_term = *((ATerm *)((MachineWord)cur)+4);
real_term = AT_isInsideValidTerm(odd_term);
if (real_term != NULL) {
AT_markTerm(odd_term);
}
! odd_sym = *((AFun *)((MachineWord)cur)+4);
if (AT_isValidSymbol(odd_sym)) {
/*fprintf(stderr,"mark_memory: AT_markSymbol(%d)\n",odd_sym);*/
AT_markSymbol(odd_sym);
--- 154,166 ----
}
#ifdef AT_64BIT
! odd_term = *((ATerm *)(((MachineWord)cur)+4));
real_term = AT_isInsideValidTerm(odd_term);
if (real_term != NULL) {
AT_markTerm(odd_term);
}
! odd_sym = *((AFun *)(((MachineWord)cur)+4));
if (AT_isValidSymbol(odd_sym)) {
/*fprintf(stderr,"mark_memory: AT_markSymbol(%d)\n",odd_sym);*/
AT_markSymbol(odd_sym);
***************
*** 198,210 ****
}
#ifdef AT_64BIT
! odd_term = *((ATerm *)((MachineWord)cur)+4);
real_term = AT_isInsideValidTerm(odd_term);
if (real_term != NULL) {
AT_markTerm_young(odd_term);
}
! odd_sym = *((AFun *)((MachineWord)cur)+4);
if (AT_isValidSymbol(odd_sym)) {
/*fprintf(stderr,"mark_memory_young: AT_markSymbol_young(%d)\n",odd_sym);*/
AT_markSymbol_young(odd_sym);
--- 198,210 ----
}
#ifdef AT_64BIT
! odd_term = *((ATerm *)(((MachineWord)cur)+4));
real_term = AT_isInsideValidTerm(odd_term);
if (real_term != NULL) {
AT_markTerm_young(odd_term);
}
! odd_sym = *((AFun *)(((MachineWord)cur)+4));
if (AT_isValidSymbol(odd_sym)) {
/*fprintf(stderr,"mark_memory_young: AT_markSymbol_young(%d)\n",odd_sym);*/
AT_markSymbol_young(odd_sym);
***************
*** 225,235 ****
ATerm *start, *stop;
ProtEntry *prot;
- #ifdef AT_64BIT
- ATerm oddTerm;
- AFun oddSym;
- #endif
-
#ifdef WIN32
unsigned int r_eax, r_ebx, r_ecx, r_edx, \
--- 225,230 ----
***************
*** 287,293 ****
/* Traverse possible register variables */
sigsetjmp(env,0);
! start = (ATerm *)env;
stop = ((ATerm *)(((char *)env) + sizeof(sigjmp_buf)));
mark_memory(start, stop);
#endif
--- 282,288 ----
/* Traverse possible register variables */
sigsetjmp(env,0);
! start = (ATerm *)env; /* !!! illegal aliasing */
stop = ((ATerm *)(((char *)env) + sizeof(sigjmp_buf)));
mark_memory(start, stop);
#endif
***************
*** 338,348 ****
ATerm *start, *stop;
ProtEntry *prot;
- #ifdef AT_64BIT
- ATerm oddTerm;
- AFun oddSym;
- #endif
-
#ifdef WIN32
unsigned int r_eax, r_ebx, r_ecx, r_edx, \
--- 333,338 ----
***************
*** 400,406 ****
/* Traverse possible register variables */
sigsetjmp(env,0);
! start = (ATerm *)env;
stop = ((ATerm *)(((char *)env) + sizeof(sigjmp_buf)));
mark_memory_young(start, stop);
#endif
--- 390,396 ----
/* Traverse possible register variables */
sigsetjmp(env,0);
! start = (ATerm *)env; /* !!! illegal aliasing */
stop = ((ATerm *)(((char *)env) + sizeof(sigjmp_buf)));
mark_memory_young(start, stop);
#endif
***************
*** 1047,1053 ****
/*fprintf(stderr,"minor_sweep_phase_young: ensure empty freelist[%d]\n",size);*/
for(data = at_freelist[size] ; data ; data=data->next) {
if(!EQUAL_HEADER(data->header,FREE_HEADER)) {
! fprintf(stderr,"data = %x header = %x\n",(unsigned int)data,data->header);
}
assert(EQUAL_HEADER(data->header,FREE_HEADER));
assert(ATgetType(data) == AT_FREE);
--- 1037,1043 ----
/*fprintf(stderr,"minor_sweep_phase_young: ensure empty freelist[%d]\n",size);*/
for(data = at_freelist[size] ; data ; data=data->next) {
if(!EQUAL_HEADER(data->header,FREE_HEADER)) {
! fprintf(stderr,"data = %p header = %x\n",data,(unsigned int) data->header);
}
assert(EQUAL_HEADER(data->header,FREE_HEADER));
assert(ATgetType(data) == AT_FREE);
diff -rc aterm-2.4.2-orig/aterm/Makefile.am aterm-2.4.2/aterm/Makefile.am
*** aterm-2.4.2-orig/aterm/Makefile.am 2005-08-03 11:45:19.000000000 +0200
--- aterm-2.4.2/aterm/Makefile.am 2006-09-22 13:39:07.000000000 +0200
***************
*** 37,43 ****
aterm2.h \
atypes.h \
deprecated.h \
! encoding.h
PRIVATE_INCL = \
_afun.h \
--- 37,44 ----
aterm2.h \
atypes.h \
deprecated.h \
! encoding.h \
! config.h
PRIVATE_INCL = \
_afun.h \
diff -rc aterm-2.4.2-orig/aterm/md5.h aterm-2.4.2/aterm/md5.h
*** aterm-2.4.2-orig/aterm/md5.h 2003-09-02 15:32:46.000000000 +0200
--- aterm-2.4.2/aterm/md5.h 2006-09-22 13:39:07.000000000 +0200
***************
*** 24,29 ****
--- 24,31 ----
documentation and/or software.
*/
+ #include <stdint.h>
+
/* GLOBAL.H - RSAREF types and constants
*/
***************
*** 46,55 ****
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
! typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
! typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
--- 48,57 ----
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
! typedef uint16_t UINT2;
/* UINT4 defines a four byte word */
! typedef uint32_t UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
diff -rc aterm-2.4.2-orig/aterm/memory.c aterm-2.4.2/aterm/memory.c
*** aterm-2.4.2-orig/aterm/memory.c 2005-10-11 13:19:25.000000000 +0200
--- aterm-2.4.2/aterm/memory.c 2006-09-22 13:39:16.000000000 +0200
***************
*** 96,102 ****
#define HASHNUMBER4(t) hash_number(t,4)
#define HASHINT(val) (tmp[0]=(MachineWord)(AT_INT<<SHIFT_TYPE),\
tmp[1]=(MachineWord)0,\
! tmp[2]=(MachineWord)val,\
hash_number(tmp,3))
#else
--- 96,102 ----
#define HASHNUMBER4(t) hash_number(t,4)
#define HASHINT(val) (tmp[0]=(MachineWord)(AT_INT<<SHIFT_TYPE),\
tmp[1]=(MachineWord)0,\
! tmp[2]=(MachineWord)((unsigned int) val),\
hash_number(tmp,3))
#else
***************
*** 127,133 ****
((MachineWord*)t)[2]),((MachineWord*)t)[3]))
#define HASHINT(val) \
! FINISH(COMBINE(START( (AT_INT<<SHIFT_TYPE) ), val))
#endif /* HASHPEM */
--- 127,133 ----
((MachineWord*)t)[2]),((MachineWord*)t)[3]))
#define HASHINT(val) \
! FINISH(COMBINE(START( (AT_INT<<SHIFT_TYPE) ), (unsigned int) val))
#endif /* HASHPEM */
***************
*** 708,714 ****
at_blocks[size] = newblock;
top_at_blocks[size] = newblock->data;
assert(at_blocks[size] != NULL);
! assert(((int)top_at_blocks[size] % MAX(sizeof(double), sizeof(void *))) == 0);
/* [pem: Feb 14 02] TODO: fast allocation */
assert(at_freelist[size] == NULL);
--- 708,714 ----
at_blocks[size] = newblock;
top_at_blocks[size] = newblock->data;
assert(at_blocks[size] != NULL);
! assert(((long)top_at_blocks[size] % MAX(sizeof(double), sizeof(void *))) == 0);
/* [pem: Feb 14 02] TODO: fast allocation */
assert(at_freelist[size] == NULL);
***************
*** 1009,1018 ****
do {
if(!cur) {
/*printf("freeterm = %d\n",t);*/
! fprintf(stderr,"### cannot find term %x in hashtable at pos %d header = %x\n", (unsigned int)t, hnr, t->header);
!
! ATabort("### cannot find term %n at %p in hashtable at pos %d"
! ", header = %d\n", t, t, hnr, t->header);
}
if (cur == t) {
if(prev)
--- 1009,1016 ----
do {
if(!cur) {
/*printf("freeterm = %d\n",t);*/
! ATabort("### cannot find term %p in hashtable at pos %d"
! ", header = %x\n", t, hnr, t->header);
}
if (cur == t) {
if(prev)
***************
*** 1728,1733 ****
--- 1726,1733 ----
hashtable[hnr] = cur;
}
+ assert((hnr & table_mask) == (hash_number(cur, TERM_SIZE_INT) & table_mask));
+
return (ATermInt)cur;
}
diff -rc aterm-2.4.2-orig/aterm.m4 aterm-2.4.2/aterm.m4
*** aterm-2.4.2-orig/aterm.m4 2005-08-03 11:45:19.000000000 +0200
--- aterm-2.4.2/aterm.m4 2006-09-22 13:39:07.000000000 +0200
***************
*** 8,15 ****
[AS_HELP_STRING([--with-sharing],[create libraries that do term sharing @<:@yes@:>@])],
[if test "$withval" = "no"; then
AC_MSG_RESULT([no])
! AC_DEFINE([NO_SHARING])
! AC_DEFINE([WITH_STATS])
else
if test "$withval" != "yes"; then
AC_MSG_RESULT([unknown value specified for --with-sharing.])
--- 8,15 ----
[AS_HELP_STRING([--with-sharing],[create libraries that do term sharing @<:@yes@:>@])],
[if test "$withval" = "no"; then
AC_MSG_RESULT([no])
! AC_DEFINE([NO_SHARING], [], [Whether terms are shared.])
! AC_DEFINE([WITH_STATS], [], [Whether to keep statistics.])
else
if test "$withval" != "yes"; then
AC_MSG_RESULT([unknown value specified for --with-sharing.])
***************
*** 73,78 ****
--- 73,102 ----
AC_SUBST([OPTIMIZECFLAGS])
])
+ # ATERM_64_BIT
+ # ------------
+ # Enable 64-bit mode if pointers are 8 bytes large.
+ AC_DEFUN([ATERM_64_BIT], [
+ AC_CHECK_SIZEOF(void *)
+ AC_CHECK_SIZEOF(int)
+ AC_CHECK_SIZEOF(long)
+
+ AC_MSG_CHECKING([what kind of platform this is])
+
+ AC_SUBST([AT_64BIT], [0])
+ if test "$ac_cv_sizeof_void_p" = "8" -a "$ac_cv_sizeof_int" = "4" -a "$ac_cv_sizeof_long" = "8"; then
+ AC_MSG_RESULT([LP64])
+ AC_SUBST([AT_64BIT], [1])
+ elif test "$ac_cv_sizeof_void_p" = "8" -a "$ac_cv_sizeof_int" = "8" -a "$ac_cv_sizeof_long" = "8"; then
+ AC_MSG_RESULT([ILP64 - warning, untested])
+ AC_SUBST([AT_64BIT], [1])
+ elif test "$ac_cv_sizeof_void_p" = "4" -a "$ac_cv_sizeof_int" = "4" -a "$ac_cv_sizeof_long" = "4"; then
+ AC_MSG_RESULT([32 bits])
+ else
+ AC_MSG_RESULT([something weird - warning, untested])
+ fi
+ ])
+
# XT_SVN_REVISION
# ---------------
AC_DEFUN([XT_SVN_REVISION],
diff -rc aterm-2.4.2-orig/configure.ac aterm-2.4.2/configure.ac
*** aterm-2.4.2-orig/configure.ac 2005-08-03 11:45:19.000000000 +0200
--- aterm-2.4.2/configure.ac 2006-09-22 13:39:07.000000000 +0200
***************
*** 30,35 ****
--- 30,38 ----
# Add a configuration option to allow users to control sharing.
ATERM_WITH_SHARING
+ # Enable 64-bit mode if pointers are 8 bytes large.
+ ATERM_64_BIT
+
CURDATE=`date`
AC_SUBST([CURDATE])
***************
*** 45,49 ****
--- 48,53 ----
doc/spec/Makefile
aterm.spec
aterm.pc
+ aterm/config.h
])
AC_OUTPUT
diff -rc aterm-2.4.2-orig/utils/dicttoc.c aterm-2.4.2/utils/dicttoc.c
*** aterm-2.4.2-orig/utils/dicttoc.c 2003-10-07 13:57:40.000000000 +0200
--- aterm-2.4.2/utils/dicttoc.c 2006-09-22 13:39:07.000000000 +0200
***************
*** 69,74 ****
--- 69,75 ----
fprintf(file, "#ifndef __%s_H\n", code_prefix);
fprintf(file, "#define __%s_H\n\n", code_prefix);
fprintf(file, "#include <aterm2.h>\n\n");
+ fprintf(file, "#include <assert.h>\n\n");
while (!ATisEmpty(afuns)) {
ATerm afun, alias, pair = ATgetFirst(afuns);
***************
*** 244,251 ****
ATfprintf(file, "{\n");
ATfprintf(file, " ATermList afuns, terms;\n\n");
! ATfprintf(file, " _%s = ATreadFromBinaryString(_%s_baf, _%s_LEN);\n\n",
code_prefix, code_prefix, code_prefix);
ATfprintf(file, " ATprotect(&_%s);\n\n", code_prefix);
ATfprintf(file, " afuns = (ATermList)ATelementAt((ATermList)_%s, 0);\n\n", code_prefix);
--- 245,253 ----
ATfprintf(file, "{\n");
ATfprintf(file, " ATermList afuns, terms;\n\n");
! ATfprintf(file, " _%s = ATreadFromBinaryString(_%s_baf, _%s_LEN);\n",
code_prefix, code_prefix, code_prefix);
+ ATfprintf(file, " assert(_%s);\n\n", code_prefix);
ATfprintf(file, " ATprotect(&_%s);\n\n", code_prefix);
ATfprintf(file, " afuns = (ATermList)ATelementAt((ATermList)_%s, 0);\n\n", code_prefix);

View File

@@ -1,224 +0,0 @@
diff -rc aterm-1142707243.10633/aterm/aterm.c aterm/aterm/aterm.c
*** aterm-1142707243.10633/aterm/aterm.c 2006-02-08 11:35:28.000000000 +0100
--- aterm/aterm/aterm.c 2006-04-25 17:10:52.000000000 +0200
***************
*** 193,198 ****
--- 193,199 ----
/* that have char == 2 bytes, and sizeof(header_type) == 2 */
assert(sizeof(header_type) == sizeof(ATerm *));
assert(sizeof(header_type) >= 4);
+ assert(sizeof(ATerm) == sizeof(MachineWord));
/*}}} */
/*{{{ Initialize buffer */
diff -rc aterm-1142707243.10633/aterm/memory.c aterm/aterm/memory.c
*** aterm-1142707243.10633/aterm/memory.c 2006-03-09 15:02:56.000000000 +0100
--- aterm/aterm/memory.c 2006-04-25 18:22:00.000000000 +0200
***************
*** 119,130 ****
hash_number(tmp,3))
*/
#define HASHNUMBER3(t)\
! FINISH(COMBINE(START(((MachineWord*)t)[0]), ((MachineWord*)t)[2]))
#define HASHNUMBER4(t)\
! FINISH(COMBINE(COMBINE(START(((MachineWord*)t)[0]), \
! ((MachineWord*)t)[2]),((MachineWord*)t)[3]))
#define HASHINT(val) \
FINISH(COMBINE(START( (AT_INT<<SHIFT_TYPE) ), val))
--- 119,171 ----
hash_number(tmp,3))
*/
+ /* The ATerm library use some heavy aliasing. For instance, the
+ various ATermXXX structures are referenced through MachineWord
+ arrays. This is not generally allowed by the C standard --- see
+ C99, section 6.5, clause 7. In particular, this means that you
+ cannot assign something through an ATermXXX pointer, e.g.,
+
+ protoAppl->header = header;
+
+ and then read it through a MachineWord*, e.g.,
+
+ hnr = hash_number((ATerm) protoAppl, 2);
+
+ (hash_number walks over the term by casting it to a MachineWord*).
+
+ However, the same clause of the C standard also specifies that you
+ *can* read the memory location through a union type that contains
+ both the original type (e.g. ATermAppl) and the type used to read
+ the memory location (e.g. MachineWord). That's what we do
+ below: we have a union of all the types that occur in the various
+ ATerm types. We then read the "w" element of the union. The
+ compiler is not allowed to assume absence of aliasing with the
+ other types in the union.
+
+ A better solution would be to hash the term through a character
+ pointer (since *any* memory location can be legally read as a
+ character), but I'm too lazy right now. Performance might also
+ suffer if we do that. */
+
+ typedef union
+ {
+ MachineWord w;
+ header_type header;
+ ATerm term;
+ ATermList list;
+ int i;
+ double d;
+ void* p;
+ } Aliaser;
+
+ #define GET_WORD(t, n) (((Aliaser*) (((MachineWord*) t) + n))->w)
+
#define HASHNUMBER3(t)\
! FINISH(COMBINE(START(GET_WORD(t, 0)), GET_WORD(t, 2)))
#define HASHNUMBER4(t)\
! FINISH(COMBINE(COMBINE(START(GET_WORD(t, 0)), \
! GET_WORD(t, 2)), GET_WORD(t, 3)))
#define HASHINT(val) \
FINISH(COMBINE(START( (AT_INT<<SHIFT_TYPE) ), val))
***************
*** 132,144 ****
#endif /* HASHPEM */
! #define PROTO_APPL_ARGS ((ATerm *) (protoTerm + ARG_OFFSET))
#define SET_PROTO_APPL_ARG(i, a) \
! (PROTO_APPL_ARGS[(i)] = (a))
#define GET_PROTO_APPL_ARG(i) \
! (PROTO_APPL_ARGS[(i)])
#define CHECK_TERM(t) \
assert((t) != NULL \
--- 173,185 ----
#endif /* HASHPEM */
! #define PROTO_APPL_ARGS (protoTerm + ARG_OFFSET)
#define SET_PROTO_APPL_ARG(i, a) \
! (PROTO_APPL_ARGS[(i)] = (MachineWord) (a))
#define GET_PROTO_APPL_ARG(i) \
! ((ATerm) PROTO_APPL_ARGS[(i)])
#define CHECK_TERM(t) \
assert((t) != NULL \
***************
*** 323,336 ****
#else
static HashNumber hash_number(ATerm t, int size)
{
- MachineWord *words = (MachineWord *) t;
int i;
HashNumber hnr;
! hnr = START(HIDE_AGE_MARK(words[0]));
for (i=2; i<size; i++) {
! hnr = COMBINE(hnr, words[i]);
}
return FINISH(hnr);
--- 364,376 ----
#else
static HashNumber hash_number(ATerm t, int size)
{
int i;
HashNumber hnr;
! hnr = START(HIDE_AGE_MARK(GET_WORD(t, 0)));
for (i=2; i<size; i++) {
! hnr = COMBINE(hnr, GET_WORD(t, i));
}
return FINISH(hnr);
***************
*** 338,351 ****
static HashNumber hash_number_anno(ATerm t, int size, ATerm anno)
{
- MachineWord *words = (MachineWord *) t;
int i;
HashNumber hnr;
! hnr = START(HIDE_AGE_MARK(words[0]));
for (i=2; i<size; i++) {
! hnr = COMBINE(hnr, words[i]);
}
hnr = COMBINE(hnr, (MachineWord)anno);
--- 378,390 ----
static HashNumber hash_number_anno(ATerm t, int size, ATerm anno)
{
int i;
HashNumber hnr;
! hnr = START(HIDE_AGE_MARK(GET_WORD(t, 0)));
for (i=2; i<size; i++) {
! hnr = COMBINE(hnr, GET_WORD(t, i));
}
hnr = COMBINE(hnr, (MachineWord)anno);
***************
*** 1639,1645 ****
protoAppl->header = header;
CHECK_HEADER(protoAppl->header);
! if (args != PROTO_APPL_ARGS) {
for (i=0; i<arity; i++) {
CHECK_TERM(args[i]);
SET_PROTO_APPL_ARG(i, args[i]);
--- 1678,1684 ----
protoAppl->header = header;
CHECK_HEADER(protoAppl->header);
! if (args != (ATerm *) PROTO_APPL_ARGS) {
for (i=0; i<arity; i++) {
CHECK_TERM(args[i]);
SET_PROTO_APPL_ARG(i, args[i]);
***************
*** 1680,1686 ****
hashtable[hnr] = cur;
}
! if (args != PROTO_APPL_ARGS) {
for (i=0; i<arity; i++) {
protected_buffer[i] = NULL;
}
--- 1719,1725 ----
hashtable[hnr] = cur;
}
! if (args != (ATerm *) PROTO_APPL_ARGS) {
for (i=0; i<arity; i++) {
protected_buffer[i] = NULL;
}
***************
*** 2144,2150 ****
}
SET_PROTO_APPL_ARG(n, arg);
! result = ATmakeApplArray(sym, PROTO_APPL_ARGS);
annos = AT_getAnnotations((ATerm)appl);
if (annos != NULL) {
result = (ATermAppl)AT_setAnnotations((ATerm)result, annos);
--- 2183,2189 ----
}
SET_PROTO_APPL_ARG(n, arg);
! result = ATmakeApplArray(sym, (ATerm *) PROTO_APPL_ARGS);
annos = AT_getAnnotations((ATerm)appl);
if (annos != NULL) {
result = (ATermAppl)AT_setAnnotations((ATerm)result, annos);

View File

@@ -1,21 +1,22 @@
diff -rc db-4.4.20.NC-old/os/os_flock.c db-4.4.20.NC/os/os_flock.c
*** db-4.4.20.NC-old/os/os_flock.c Mon Jun 20 16:59:01 2005
--- db-4.4.20.NC/os/os_flock.c Wed Jun 7 17:01:49 2006
diff -rc db-4.5.20-orig/os/os_flock.c db-4.5.20/os/os_flock.c
*** db-4.5.20-orig/os/os_flock.c 2006-10-13 12:36:12.000000000 +0200
--- db-4.5.20/os/os_flock.c 2006-10-13 12:40:11.000000000 +0200
***************
*** 36,41 ****
--- 36,50 ----
*** 30,35 ****
--- 30,44 ----
DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
DB_ASSERT(dbenv, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+ #ifdef __CYGWIN__
+ /*
+ * Windows file locking interferes with read/write operations, so we
+ * map the ranges to an area past the end of the file.
+ */
+ DB_ASSERT(offset < (off_t) 1 << 62);
+ DB_ASSERT(dbenv, offset < (off_t) 1 << 62);
+ offset += (off_t) 1 << 62;
+ #endif
+
#ifdef HAVE_FCNTL
fl.l_start = offset;
fl.l_len = 1;
fl.l_type = acquire ? F_WRLCK : F_UNLCK;
Only in db-4.5.20/os: os_flock.c~

View File

@@ -76,10 +76,10 @@ The hook `nix-mode-hook' is run when Nix mode is started.
("\\<baseNameOf\\>" . font-lock-builtin-face)
("\\<toString\\>" . font-lock-builtin-face)
("\\<isNull\\>" . font-lock-builtin-face)
("\\<\\([a-zA-Z_][a-zA-Z0-9_']*\\)[ \t]*="
(1 font-lock-variable-name-face nil nil))
("[a-zA-Z][a-zA-Z0-9\\+-\\.]*:[a-zA-Z0-9%/\\?:@&=\\+\\$,_\\.!~\\*'-]+"
. font-lock-constant-face)
("\\<\\([a-zA-Z_][a-zA-Z0-9_'\.]*\\)[ \t]*="
(1 font-lock-variable-name-face nil nil))
("[a-zA-Z0-9._\\+-]*\\(/[a-zA-Z0-9._\\+-]+\\)+"
. font-lock-constant-face)
))

37
misc/vim/syntax/nix.vim Normal file
View File

@@ -0,0 +1,37 @@
" Vim syntax file
" Language: nix
" Maintainer: Marc Weber <marco-oweber@gmx.de>
" Modify and commit if you feel that way
" Last Change: 2007 Dec
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
finish
endif
syn keyword nixKeyword let throw inherit import true false null with
syn keyword nixConditional if else then
syn keyword nixBrace ( ) { } =
syn keyword nixBuiltin __currentSystem __currentTime __isFunction __getEnv __trace __toPath __pathExists
\ __readFile __toXML __toFile __filterSource __attrNames __getAttr __hasAttr __isAttrs __listToAttrs __isList
\ __head __tail __add __sub __lessThan __substring __stringLength
syn match nixAttr "\w\+\ze\s*="
syn match nixFuncArg "\zs\w\+\ze\s*:"
syn region nixStringParam start=+\${+ end=+}+
syn region nixMultiLineComment start=+/\*+ skip=+\\"+ end=+\*/+
syn match nixEndOfLineComment "#.*$"
syn region nixStringIndented start=+''+ skip=+'''\|''${\|"+ end=+''+ contains=nixStringParam
syn region nixString start=+"+ skip=+\\"+ end=+"+ contains=nixStringParam
hi def link nixKeyword Keyword
hi def link nixConditional Conditional
hi def link nixBrace Special
hi def link nixString String
hi def link nixStringIndented String
hi def link nixBuiltin Special
hi def link nixStringParam Macro
hi def link nixMultiLineComment Comment
hi def link nixEndOfLineComment Comment
hi def link nixAttr Identifier
hi def link nixFuncArg Identifier

View File

@@ -29,25 +29,6 @@
#gc-keep-derivations = true
### Option `gc-reserved-space'
#
# This option specifies how much space should be reserved in normal
# use so that the garbage collector can run succesfully. Since the
# garbage collector must perform Berkeley DB transactions, it needs
# some disk space for itself. However, when the disk is full, this
# space is not available, so the collector would not be able to run
# precisely when it is most needed.
#
# For this reason, when Nix is run, it allocates a file
# /nix/var/nix/db/reserved of the size specified by this option. When
# the garbage collector is run, this file is deleted before the
# Berkeley DB environment is opened. This should give it enough room
# to proceed.
#
# The default is "1048576" (1 MiB).
#gc-reserved-space = 1048576
### Option `env-keep-derivations'
#
# If `false' (default), derivations are not stored in Nix user
@@ -78,52 +59,112 @@
#build-max-jobs = 1
### Option `build-allow-root'
### Option `build-max-silent-time'
#
# This option controls Nix's behaviour when it is invoked under the
# `root' user (or setuid-root). If `true' (default), builds are
# performed under the `root' user. If `false', builds are performed
# under one of the users listed in the `build-users' option (see
# below).
#build-allow-root = true
### Option `build-users'
# This option defines the maximum number of seconds that a builder can
# go without producing any data on standard output or standard error.
# This is useful (for instance in a automated build system) to catch
# builds that are stuck in an infinite loop, or to catch remote builds
# that are hanging due to network problems. It can be overriden using
# the `--max-silent-time' command line switch.
#
# This option is only applicable if `build-allow-root' is `false' and
# Nix is invoked under the `root' user (or setuid-root). It contains
# a list of user names under which Nix can execute builds. Builds
# cannot be performed by root since that would allow users to take
# over the system by supplying specially crafted builders; and they
# cannot be performed by the calling user since that would allow
# him/her to influence the build result.
#
# Thus this list should contain a number of `special' user accounts
# created specifically for Nix, e.g., `nix-builder-1',
# `nix-builder-2', and so on. The more users the better, since at
# most a number of builds equal to the number of build users can be
# started.
# The value 0 means that there is no timeout. This is also the
# default.
#
# Example:
# build-users = nix-builder-1 nix-builder-2 nix-builder-3
#build-users =
# build-max-silent-time = 600 # = 10 minutes
#build-max-silent-time = 0
### Option `system'
### Option `build-users-group'
#
# This option specifies the canonical Nix system name of the current
# installation, such as `i686-linux' or `powerpc-darwin'. Nix can
# only build derivations whose `system' attribute equals the value
# specified here. In general, it never makes sense to modify this
# value from its default, since you can use it to `lie' about the
# platform you are building on (e.g., perform a Mac OS build on a
# Linux machine; the result would obviously be wrong). It only makes
# sense if the Nix binaries can run on multiple platforms, e.g.,
# `universal binaries' that run on `powerpc-darwin' and `i686-darwin'.
# This options specifies the Unix group containing the Nix build user
# accounts. In multi-user Nix installations, builds should not
# be performed by the Nix account since that would allow users to
# arbitrarily modify the Nix store and database by supplying specially
# crafted builders; and they cannot be performed by the calling user
# since that would allow him/her to influence the build result.
#
# It defaults to the canonical Nix system name detected by `configure'
# at build time.
# Therefore, if this option is non-empty and specifies a valid group,
# builds will be performed under the user accounts that are a member
# of the group specified here (as listed in /etc/group). Those user
# accounts should not be used for any other purpose!
#
# Nix will never run two builds under the same user account at the
# same time. This is to prevent an obvious security hole: a malicious
# user writing a Nix expression that modifies the build result of a
# legitimate Nix expression being built by another user. Therefore it
# is good to have as many Nix build user accounts as you can spare.
# (Remember: uids are cheap.)
#
# The build users should have permission to create files in the Nix
# store, but not delete them. Therefore, /nix/store should be owned
# by the Nix account, its group should be the group specified here,
# and its mode should be 1775.
#
# If the build users group is empty, builds will be performed under
# the uid of the Nix process (that is, the uid of the caller if
# $NIX_REMOTE is empty, the uid under which the Nix daemon runs if
# $NIX_REMOTE is `daemon', or the uid that owns the setuid nix-worker
# program if $NIX_REMOTE is `slave'). Obviously, this should not be
# used in multi-user settings with untrusted users.
#
# The default is empty.
#
# Example:
# system = i686-darwin
#system =
# build-users-group = nix-builders
#build-users-group =
### Option `build-use-chroot'
#
# If set to `true', builds will be performed in a chroot environment,
# i.e., the build will be isolated from the normal file system
# hierarchy and will only see the Nix store, the temporary build
# directory, and the directories configured with the
# `build-chroot-dirs' option (such as /proc and /dev). This is useful
# to prevent undeclared dependencies on files in directories such as
# /usr/bin.
#
# The use of a chroot requires that Nix is run as root (but you can
# still use the "build users" feature to perform builds under
# different users than root). Currently, chroot builds only work on
# Linux because Nix uses "bind mounts" to make the Nix store and other
# directories available inside the chroot.
#
# The default is `false'.
#
# Example:
# build-use-chroot = true
#build-use-chroot = false
### Option `build-chroot-dirs'
#
# When builds are performed in a chroot environment, Nix will mount
# (using `mount --bind' on Linux) some directories from the normal
# file system hierarchy inside the chroot. These are the Nix store,
# the temporary build directory (usually /tmp/nix-<pid>-<number>) and
# the directories listed here. The default is "/dev /dev/pts /proc".
# Files in /dev (such as /dev/null) are needed by many builds, and
# some files in /proc may also be needed occasionally.
#
# Example:
# build-use-chroot = /dev /proc /bin
#build-chroot-dirs = /dev /dev/pts /proc
### Option `build-cache-failure'
#
# If this option is enabled, Nix will do negative caching; that is, it
# will remember failed builds, and won't attempt to try to build them
# again if you ask for it. Negative caching is disabled by default
# because Nix cannot distinguish between permanent build errors (e.g.,
# a syntax error in a source file) and transient build errors (e.g., a
# full disk), as they both cause the builder to return a non-zero exit
# code. You can clear the cache by doing `rm -f
# /nix/var/nix/db/failed/*'.
#
# Example:
# build-cache-failure = true
#build-cache-failure = false

View File

@@ -13,11 +13,10 @@ Version: @version@
Release: 1
License: GPL
Group: Software Deployment
URL: http://www.cs.uu.nl/groups/ST/Trace/Nix
URL: http://nixos.org/
Source0: %{name}-@version@.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
%define _prefix /nix
Prefix: %{_prefix}
Prefix: /usr
Requires: /usr/bin/perl
Requires: curl
@@ -26,7 +25,12 @@ Provides: perl(readmanifest)
%description
Nix is a system for software deployment.
Nix is a purely functional package manager. It allows multiple
versions of a package to be installed side-by-side, ensures that
dependency specifications are complete, supports atomic upgrades and
rollbacks, allows non-root users to install software, and has many
other features. It is the basis of the NixOS Linux distribution, but
it can be used equally well under other Unix systems.
%prep
%setup -q
@@ -42,14 +46,14 @@ if test -n "%{enable_setuid}"; then
extraFlags="$extraFlags --with-nix-group=%{nix_group}"
fi
fi
./configure --prefix=%{_prefix} $extraFlags
./configure --prefix=%{_prefix} --sysconfdir=/etc $extraFlags
make
make check
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT install
rm $RPM_BUILD_ROOT/%{_prefix}/etc/nix/nix.conf
rm $RPM_BUILD_ROOT/etc/nix/nix.conf
strip $RPM_BUILD_ROOT/%{_prefix}/bin/* || true
%clean
@@ -71,11 +75,9 @@ fi
%{_prefix}/lib
%{_prefix}/libexec
%{_prefix}/include
%{_prefix}/var
%{_prefix}/share
%{_prefix}/man
%{_prefix}/store
/etc/profile.d/nix.sh
/nix/var
/nix/store
%config
%{_prefix}/etc
#%doc
#%{_prefix}/share/nix/manual
/etc/nix

196
release.nix Normal file
View File

@@ -0,0 +1,196 @@
{ nixpkgs ? ../nixpkgs }:
let
jobs = rec {
tarball =
{ nix ? {outPath = ./.; rev = 1234;}
, officialRelease ? false
}:
with import nixpkgs {};
releaseTools.sourceTarball {
name = "nix-tarball";
version = builtins.readFile ./version;
src = nix;
inherit officialRelease;
buildInputs = [curl bison flex2533 perl libxml2 libxslt w3m bzip2 jing_tools tetex dblatex];
configureFlags = ''
--with-docbook-rng=${docbook5}/xml/rng/docbook
--with-docbook-xsl=${docbook5_xsl}/xml/xsl/docbook
--with-xml-flags=--nonet
'';
# Include the BDB, ATerm and Bzip2 tarballs in the distribution.
preConfigure = ''
stripHash ${db45.src}
# Remove unnecessary stuff from the Berkeley DB tarball.
( mkdir bdb-temp
cd bdb-temp
tar xfz ${db45.src}
cd *
rm -rf docs test tcl perl libdb_java java rpc_server build_vxworks \
examples_java examples_c examples_cxx dist/tags
mkdir test
touch test/include.tcl
cd ..
tar cvfz ../externals/$strippedName *
)
stripHash ${aterm242fixes.src}
cp -pv ${aterm242fixes.src} externals/$strippedName
stripHash ${bzip2.src}
cp -pv ${bzip2.src} externals/$strippedName
'';
preDist = ''
make -C doc/manual install prefix=$out
make -C doc/manual manual.pdf prefix=$out
cp doc/manual/manual.pdf $out/manual.pdf
echo "doc manual $out/share/doc/nix/manual" >> $out/nix-support/hydra-build-products
echo "doc-pdf manual $out/manual.pdf" >> $out/nix-support/hydra-build-products
echo "doc release-notes $out/share/doc/nix/release-notes" >> $out/nix-support/hydra-build-products
'';
};
build =
{ tarball ? jobs.tarball {}
, system ? "i686-linux"
}:
with import nixpkgs {inherit system;};
releaseTools.nixBuild {
name = "nix";
src = tarball;
buildInputs = [curl perl bzip2 openssl];
configureFlags = ''
--disable-init-state
--with-bdb=${db45} --with-aterm=${aterm242fixes} --with-bzip2=${bzip2}
'';
};
static =
{ tarball ? jobs.tarball {}
, system ? "i686-linux"
}:
with import nixpkgs {inherit system;};
releaseTools.binaryTarball {
name = "nix-static-tarball";
src = tarball;
buildInputs = [curl perl bzip2];
configureFlags = ''
--disable-init-state
--disable-old-db-compat --with-aterm=${aterm242fixes} --with-bzip2=${bzip2}
--enable-static-nix
'';
};
coverage =
{ tarball ? jobs.tarball {}
}:
with import nixpkgs {};
releaseTools.coverageAnalysis {
name = "nix-build";
src = tarball;
buildInputs = [
curl perl bzip2 openssl
# These are for "make check" only:
graphviz libxml2 libxslt
];
configureFlags = ''
--disable-init-state --disable-shared
--with-bdb=${db45} --with-aterm=${aterm242fixes} --with-bzip2=${bzip2}
'';
lcovFilter = ["*/boost/*" "*-tab.*"];
# We call `dot', and even though we just use it to
# syntax-check generated dot files, it still requires some
# fonts. So provide those.
FONTCONFIG_FILE = texFunctions.fontsConf;
};
rpm_fedora5i386 = makeRPM_i686 (diskImages: diskImages.fedora5i386) 20;
rpm_fedora9i386 = makeRPM_i686 (diskImages: diskImages.fedora9i386) 50;
rpm_fedora9x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora9x86_64) 50;
rpm_fedora10i386 = makeRPM_i686 (diskImages: diskImages.fedora10i386) 40;
rpm_fedora10x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora10x86_64) 40;
rpm_opensuse103i386 = makeRPM_i686 (diskImages: diskImages.opensuse103i386) 40;
deb_debian40i386 = makeDeb_i686 (diskImages: diskImages.debian40i386) 40;
deb_debian40x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian40x86_64) 40;
deb_debian50i386 = makeDeb_i686 (diskImages: diskImages.debian50i386) 30;
deb_debian50x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian50x86_64) 30;
deb_ubuntu804i386 = makeDeb_i686 (diskImages: diskImages.ubuntu804i386) 50;
deb_ubuntu804x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu804x86_64) 50;
deb_ubuntu810i386 = makeDeb_i686 (diskImages: diskImages.ubuntu810i386) 40;
deb_ubuntu810x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu810x86_64) 40;
};
makeRPM_i686 = makeRPM "i686-linux";
makeRPM_x86_64 = makeRPM "x86_64-linux";
makeRPM =
system: diskImageFun: prio:
{ tarball ? jobs.tarball {}
}:
with import nixpkgs {inherit system;};
releaseTools.rpmBuild rec {
name = "nix-rpm-${diskImage.name}";
src = tarball;
diskImage = diskImageFun vmTools.diskImages;
memSize = 1024;
meta = { schedulingPriority = toString prio; };
};
makeDeb_i686 = makeDeb "i686-linux";
makeDeb_x86_64 = makeDeb "x86_64-linux";
makeDeb =
system: diskImageFun: prio:
{ tarball ? jobs.tarball {}
}:
with import nixpkgs {inherit system;};
releaseTools.debBuild {
name = "nix-deb";
src = tarball;
diskImage = diskImageFun vmTools.diskImages;
memSize = 1024;
meta = { schedulingPriority = toString prio; };
configureFlags = "--sysconfdir=/etc";
};
in jobs

View File

@@ -1,20 +1,26 @@
bin_SCRIPTS = nix-collect-garbage \
nix-pull nix-push nix-prefetch-url \
nix-install-package nix-channel nix-build \
nix-pack-closure nix-unpack-closure
nix-copy-closure
noinst_SCRIPTS = nix-profile.sh generate-patches.pl find-runtime-roots.pl
noinst_SCRIPTS = nix-profile.sh generate-patches.pl \
find-runtime-roots.pl build-remote.pl nix-reduce-build \
copy-from-other-stores.pl nix-http-export.cgi
nix-pull nix-push: readmanifest.pm readconfig.pm download-using-manifests.pl
install-exec-local: readmanifest.pm download-using-manifests.pl find-runtime-roots.pl
install-exec-local: readmanifest.pm download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d
$(INSTALL_PROGRAM) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh
$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix
$(INSTALL_DATA) readmanifest.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_DATA) readconfig.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) download-using-manifests.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) generate-patches.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix/substituters
$(INSTALL_PROGRAM) download-using-manifests.pl $(DESTDIR)$(libexecdir)/nix/substituters
$(INSTALL_PROGRAM) copy-from-other-stores.pl $(DESTDIR)$(libexecdir)/nix/substituters
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix
include ../substitute.mk
@@ -27,6 +33,10 @@ EXTRA_DIST = nix-collect-garbage.in \
readconfig.pm.in \
nix-build.in \
download-using-manifests.pl.in \
copy-from-other-stores.pl.in \
generate-patches.pl.in \
nix-pack-closure.in nix-unpack-closure.in \
find-runtime-roots.pl.in
nix-copy-closure.in \
find-runtime-roots.pl.in \
build-remote.pl.in \
nix-reduce-build.in \
nix-http-export.cgi.in

212
scripts/build-remote.pl.in Executable file
View File

@@ -0,0 +1,212 @@
#! @perl@ -w
use strict;
use Fcntl ':flock';
use English '-no_match_vars';
use IO::Handle;
# General operation:
#
# Try to find a free machine of type $neededSystem. We do this as
# follows:
# - We acquire an exclusive lock on $currentLoad/main-lock.
# - For each machine $machine of type $neededSystem and for each $slot
# less than the maximum load for that machine, we try to get an
# exclusive lock on $currentLoad/$machine-$slot (without blocking).
# If we get such a lock, we send "accept" to the caller. Otherwise,
# we send "postpone" and exit.
# - We release the exclusive lock on $currentLoad/main-lock.
# - We perform the build on $neededSystem.
# - We release the exclusive lock on $currentLoad/$machine-$slot.
#
# The nice thing about this scheme is that if we die prematurely, the
# locks are released automatically.
my $loadIncreased = 0;
my ($amWilling, $localSystem, $neededSystem, $drvPath, $maxSilentTime) = @ARGV;
$maxSilentTime = 0 unless defined $maxSilentTime;
sub sendReply {
my $reply = shift;
print STDERR "# $reply\n";
}
sub decline {
sendReply "decline";
exit 0;
}
my $currentLoad = $ENV{"NIX_CURRENT_LOAD"};
decline unless defined $currentLoad;
mkdir $currentLoad, 0777 or die unless -d $currentLoad;
my $conf = $ENV{"NIX_REMOTE_SYSTEMS"};
decline if !defined $conf || ! -e $conf;
my $canBuildLocally = $amWilling && ($localSystem eq $neededSystem);
# Otherwise find a willing remote machine.
my @machines;
my %curJobs;
# Read the list of machines.
open CONF, "< $conf" or die;
while (<CONF>) {
chomp;
s/\#.*$//g;
next if /^\s*$/;
/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s*$/ or die;
push @machines,
{ hostName => $1
, systemType => $2
, sshKeys => $3
, maxJobs => $4
};
}
close CONF;
# Acquire the exclusive lock on $currentLoad/main-lock.
my $mainLock = "$currentLoad/main-lock";
open MAINLOCK, ">>$mainLock" or die;
flock(MAINLOCK, LOCK_EX) or die;
# Find a suitable system.
my $rightType = 0;
my $machine;
my $slotLock;
LOOP: foreach my $cur (@machines) {
if ($neededSystem eq $cur->{systemType}
|| ($neededSystem eq "i686-linux" && $cur->{systemType} eq "x86_64-linux"))
{
$rightType = 1;
# We have a machine of the right type. Try to get a lock on
# one of the machine's lock files.
my $slot = 0;
while ($slot < $cur->{maxJobs}) {
my $slotLockFn = "$currentLoad/" . $cur->{systemType} . "-" . $cur->{hostName} . "-$slot";
$slotLock = new IO::Handle;
open $slotLock, ">>$slotLockFn" or die;
if (flock($slotLock, LOCK_EX | LOCK_NB)) {
utime undef, undef, $slotLock;
$machine = $cur;
last LOOP;
}
close $slotLock;
$slot++;
}
}
}
close MAINLOCK;
# Didn't find one? Then decline or postpone.
if (!defined $machine) {
# Postpone if we have a machine of the right type, except if the
# local system can and wants to do the build.
if ($rightType && !$canBuildLocally) {
sendReply "postpone";
exit 0;
} else {
decline;
}
}
# Yes we did, accept.
sendReply "accept";
my $x = <STDIN>;
chomp $x;
if ($x ne "okay") {
exit 0;
}
# Do the actual job.
my $hostName = $machine->{hostName};
print STDERR "building `$drvPath' on `$hostName'\n";
# Make sure that we don't get any SSH passphrase or host key popups -
# if there is any problem it should fail, not do something
# interactive.
$ENV{"DISPLAY"} = "";
$ENV{"SSH_PASSWORD_FILE="} = "";
$ENV{"SSH_ASKPASS="} = "";
my $sshOpts = "-i " . $machine->{sshKeys} . " -x";
# Hack to support Cygwin: if we login without a password, we don't
# have exactly the same rights as when we do. This causes the
# Microsoft C compiler to fail with certain flags:
#
# http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99676
#
# So as a workaround, we pass a verbatim password. ssh tries to makes
# this very hard; the trick is to make it call SSH_ASKPASS to get the
# password. (It only calls this command when there is no controlling
# terminal, but Nix ensures that is is the case. When doing this
# manually, use setsid(1).)
if ($machine->{sshKeys} =~ /^password:/) {
my $passwordFile = $machine->{sshKeys};
$passwordFile =~ s/^password://;
$sshOpts = "ssh -x";
$ENV{"SSH_PASSWORD_FILE"} = $passwordFile;
$ENV{"SSH_ASKPASS"} = "/tmp/writepass";
open WRITEPASS, ">/tmp/writepass" or die;
print WRITEPASS "#! /bin/sh\ncat \"\$SSH_PASSWORD_FILE\"";
close WRITEPASS;
chmod 0755, "/tmp/writepass" or die;
}
my $inputs = `cat inputs`; die if ($? != 0);
$inputs =~ s/\n/ /g;
my $outputs = `cat outputs`; die if ($? != 0);
$outputs =~ s/\n/ /g;
print "copying inputs...\n";
my $maybeSign = "";
$maybeSign = "--sign" if -e "/nix/etc/nix/signing-key.sec";
system("NIX_SSHOPTS=\"$sshOpts\" @bindir@/nix-copy-closure --gzip $hostName $maybeSign $drvPath $inputs") == 0
or die "cannot copy inputs to $hostName: $?";
print "building...\n";
my $buildFlags = "--max-silent-time $maxSilentTime";
# `-tt' forces allocation of a pseudo-terminal. This is required to
# make the remote nix-store process receive a signal when the
# connection dies. Without it, the remote process might continue to
# run indefinitely (that is, until it next tries to write to
# stdout/stderr).
if (system("ssh -tt $sshOpts $hostName 'nix-store --realise -K $buildFlags $drvPath > /dev/null'") != 0) {
# If we couldn't run ssh or there was an ssh problem (indicated by
# exit code 255), then we return exit code 1; otherwise we assume
# that the builder failed, which we indicated to Nix using exit
# code 100. It's important to distinguish between the two because
# the first is a transient failure and the latter is permanent.
my $res = $? == -1 || ($? >> 8) == 255 ? 1 : 100;
print STDERR "build of `$drvPath' on `$hostName' failed with exit code $?\n";
exit $res;
}
print "build of `$drvPath' on `$hostName' succeeded\n";
foreach my $output (split '\n', $outputs) {
my $maybeSignRemote = "";
$maybeSignRemote = "--sign" if $UID != 0;
system("ssh $sshOpts $hostName 'nix-store --export $maybeSignRemote $output | gzip' | gunzip | @bindir@/nix-store --import > /dev/null") == 0
or die "cannot copy $output from $hostName: $?";
}

View File

@@ -0,0 +1,98 @@
#! @perl@ -w
use strict;
use File::Basename;
use IO::Handle;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
STDOUT->autoflush(1);
my @remoteStoresAll = split ':', ($ENV{"NIX_OTHER_STORES"} or "");
my @remoteStores;
foreach my $dir (@remoteStoresAll) {
push @remoteStores, glob($dir);
}
sub findStorePath {
my $storePath = shift;
my $storePathName = basename $storePath;
foreach my $store (@remoteStores) {
# Determine whether $storePath exists by looking for the
# existence of the info file, and if so, get store path info
# from that file. This rather breaks abstraction: we should
# be using `nix-store' for that. But right now there is no
# good way to tell nix-store to access a store mounted under a
# different location (there's $NIX_STORE, but that only works
# if the remote store is mounted under its "real" location).
my $infoFile = "$store/var/nix/db/info/$storePathName";
my $storePath2 = "$store/store/$storePathName";
if (-f $infoFile && -e $storePath2) {
return ($infoFile, $storePath2);
}
}
}
if ($ARGV[0] eq "--query") {
while (<STDIN>) {
my $cmd = $_; chomp $cmd;
if ($cmd eq "have") {
my $storePath = <STDIN>; chomp $storePath;
(my $infoFile) = findStorePath $storePath;
print STDOUT ($infoFile ? "1\n" : "0\n");
}
elsif ($cmd eq "info") {
my $storePath = <STDIN>; chomp $storePath;
(my $infoFile) = findStorePath $storePath;
if (!$infoFile) {
print "0\n";
next; # not an error
}
print "1\n";
my $deriver = "";
my @references = ();
open INFO, "<$infoFile" or die "cannot read info file $infoFile\n";
while (<INFO>) {
chomp;
/^([\w-]+): (.*)$/ or die "bad info file";
my $key = $1;
my $value = $2;
if ($key eq "Deriver") { $deriver = $value; }
elsif ($key eq "References") { @references = split ' ', $value; }
}
close INFO;
print "$deriver\n";
print scalar @references, "\n";
print "$_\n" foreach @references;
print "0\n"; # !!! showing size not supported (yet)
}
else { die "unknown command `$cmd'"; }
}
}
elsif ($ARGV[0] eq "--substitute") {
die unless scalar @ARGV == 2;
my $storePath = $ARGV[1];
(my $infoFile, my $sourcePath) = findStorePath $storePath;
die unless $infoFile;
print "\n*** Copying `$storePath' from `$sourcePath'\n\n";
system("$binDir/nix-store --dump $sourcePath | $binDir/nix-store --restore $storePath") == 0
or die "cannot copy `$sourcePath' to `$storePath'";
}
else { die; }

View File

@@ -5,12 +5,81 @@ use readmanifest;
use POSIX qw(strftime);
use File::Temp qw(tempdir);
my $manifestDir = "@localstatedir@/nix/manifests";
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
STDOUT->autoflush(1);
my $manifestDir = ($ENV{"NIX_MANIFESTS_DIR"} or "@localstatedir@/nix/manifests");
my $logFile = "@localstatedir@/log/nix/downloads";
open LOGFILE, ">>$logFile" or die "cannot open log file $logFile";
delete $ENV{"NIX_ROOT"};
# Load all manifests.
my %narFiles;
my %localPaths;
my %patches;
for my $manifest (glob "$manifestDir/*.nixmanifest") {
my $version = readManifest($manifest, \%narFiles, \%localPaths, \%patches);
if ($version < 3) {
print STDERR "you have an old-style manifest `$manifest'; please delete it\n";
exit 1;
}
if ($version >= 10) {
print STDERR "manifest `$manifest' is too new; please delete it or upgrade Nix\n";
exit 1;
}
}
# Parse the arguments.
if ($ARGV[0] eq "--query") {
while (<STDIN>) {
my $cmd = $_; chomp $cmd;
if ($cmd eq "have") {
my $storePath = <STDIN>; chomp $storePath;
print STDOUT ((defined $narFiles{$storePath} or defined $localPaths{$storePath})
? "1\n" : "0\n");
}
elsif ($cmd eq "info") {
my $storePath = <STDIN>; chomp $storePath;
my $info;
if (defined $narFiles{$storePath}) {
$info = @{$narFiles{$storePath}}[0];
}
elsif (defined $localPaths{$storePath}) {
$info = @{$localPaths{$storePath}}[0];
}
else {
print "0\n";
next; # not an error
}
print "1\n";
print "$info->{deriver}\n";
my @references = split " ", $info->{references};
print scalar @references, "\n";
print "$_\n" foreach @references;
my $size = $info->{size} || 0;
print "$size\n";
}
else { die "unknown command `$cmd'"; }
}
exit 0;
}
elsif ($ARGV[0] ne "--substitute") {
die "syntax: $0 [--query-paths | --query-info PATHS... | --substitute PATH]\n";
}
die unless scalar @ARGV == 2;
my $targetPath = $ARGV[1];
# Create a temporary directory.
my $tmpDir = tempdir("nix-download.XXXXXX", CLEANUP => 1, TMPDIR => 1)
@@ -21,12 +90,8 @@ chdir $tmpDir or die "cannot change to `$tmpDir': $!";
my $tmpNar = "$tmpDir/nar";
my $tmpNar2 = "$tmpDir/nar2";
END { unlink $tmpNar; unlink $tmpNar2; rmdir $tmpDir; }
# Check the arguments.
die unless scalar @ARGV == 1;
my $targetPath = $ARGV[0];
open LOGFILE, ">>$logFile" or die "cannot open log file $logFile";
my $date = strftime ("%F %H:%M:%S UTC", gmtime (time));
print LOGFILE "$$ get $targetPath $date\n";
@@ -34,16 +99,15 @@ print LOGFILE "$$ get $targetPath $date\n";
print "\n*** Trying to download/patch `$targetPath'\n";
# Load all manifests.
my %narFiles;
my %patches;
my %successors;
for my $manifest (glob "$manifestDir/*.nixmanifest") {
# print STDERR "reading $manifest\n";
if (readManifest($manifest, \%narFiles, \%patches, \%successors) < 3) {
print STDERR "you have an old-style manifest `$manifest'; please delete it\n";
exit 1;
# If we can copy from a local path, do that.
my $localPathList = $localPaths{$targetPath};
foreach my $localPath (@{$localPathList}) {
my $sourcePath = $localPath->{copyFrom};
if (-e $sourcePath) {
print "\n*** Step 1/1: copying from $sourcePath\n";
system("$binDir/nix-store --dump $sourcePath | $binDir/nix-store --restore $targetPath") == 0
or die "cannot copy `$sourcePath' to `$targetPath'";
exit 0;
}
}
@@ -90,7 +154,7 @@ addToQueue $targetPath;
sub isValidPath {
my $p = shift;
return system("@bindir@/nix-store --check-validity '$p' 2> /dev/null") == 0;
return system("$binDir/nix-store --check-validity '$p' 2> /dev/null") == 0;
}
sub parseHash {
@@ -124,15 +188,13 @@ while ($queueFront < scalar @queue) {
my ($baseHashAlgo, $baseHash) = parseHash $patch->{baseHash};
my $format = "--base32";
$format = "" if $baseHashAlgo eq "md5";
my $hash = `@bindir@/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
my $hash = `$binDir/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
chomp $hash;
# print " MY HASH is $hash\n";
if ($hash ne $baseHash) {
print LOGFILE "$$ rejecting $patch->{basePath}\n";
next;
}
}
# print " PATCH from $patch->{basePath}\n";
addToQueue $patch->{basePath};
addEdge $patch->{basePath}, $u, $patch->{size}, "patch", $patch;
}
@@ -140,10 +202,12 @@ while ($queueFront < scalar @queue) {
# Add NAR file edges to the start node.
my $narFileList = $narFiles{$u};
foreach my $narFile (@{$narFileList}) {
# print " NAR from $narFile->{url}\n";
addEdge "start", $u, $narFile->{size}, "narfile", $narFile;
# !!! how to handle files whose size is not known in advance?
# For now, assume some arbitrary size (1 MB).
addEdge "start", $u, ($narFile->{size} || 1000000), "narfile", $narFile;
if ($u eq $targetPath) {
print LOGFILE "$$ full-download-would-be $narFile->{size}\n";
my $size = $narFile->{size} || -1;
print LOGFILE "$$ full-download-would-be $size\n";
}
}
@@ -169,8 +233,6 @@ while (scalar @todo > 0) {
my $u_ = $graph{$u};
# print "IN $u $u_->{d}\n";
foreach my $edge (@{$u_->{edges}}) {
my $v_ = $graph{$edge->{end}};
if ($v_->{d} > $u_->{d} + $edge->{weight}) {
@@ -178,7 +240,6 @@ while (scalar @todo > 0) {
# Store the edge; to edge->start is actually the
# predecessor.
$v_->{pred} = $edge;
# print " RELAX $edge->{end} $v_->{d}\n";
}
}
}
@@ -200,20 +261,18 @@ while ($cur ne "start") {
my $curStep = 1;
my $maxStep = scalar @path;
sub downloadFile {
my $url = shift;
my ($hashAlgo, $hash) = parseHash(shift);
sub downloadFile {
my $url = shift;
$ENV{"PRINT_PATH"} = 1;
$ENV{"QUIET"} = 1;
$ENV{"NIX_HASH_ALGO"} = $hashAlgo;
my ($hash2, $path) = `@bindir@/nix-prefetch-url '$url' '$hash'`;
my ($hash, $path) = `$binDir/nix-prefetch-url '$url'`;
die "download of `$url' failed" unless $? == 0;
chomp $hash2;
chomp $path;
die "hash mismatch, expected $hash, got $hash2" if $hash ne $hash2;
return $path;
}
my $finalNarHash;
while (scalar @path > 0) {
my $edge = pop @path;
my $u = $edge->{start};
@@ -230,7 +289,7 @@ while (scalar @path > 0) {
# as a base to one or more patches. So turn the base path
# into a NAR archive, to which we can apply the patch.
print " packing base path...\n";
system("@bindir@/nix-store --dump $v > $tmpNar") == 0
system("$binDir/nix-store --dump $v > $tmpNar") == 0
or die "cannot dump `$v'";
}
}
@@ -243,7 +302,7 @@ while (scalar @path > 0) {
# Download the patch.
print " downloading patch...\n";
my $patchPath = downloadFile "$patch->{url}", "$patch->{hash}";
my $patchPath = downloadFile "$patch->{url}";
# Apply the patch to the NAR archive produced in step 1 (for
# the already present path) or a later step (for patch sequences).
@@ -258,20 +317,23 @@ while (scalar @path > 0) {
# This was the last patch. Unpack the final NAR archive
# into the target path.
print " unpacking patched archive...\n";
system("@bindir@/nix-store --restore $v < $tmpNar2") == 0
system("$binDir/nix-store --restore $v < $tmpNar2") == 0
or die "cannot unpack $tmpNar2 into `$v'";
}
$finalNarHash = $patch->{narHash};
}
elsif ($edge->{type} eq "narfile") {
my $narFile = $edge->{info};
print "downloading `$narFile->{url}' into `$v'\n";
print LOGFILE "$$ narfile $narFile->{url} $narFile->{size} $v\n";
my $size = $narFile->{size} || -1;
print LOGFILE "$$ narfile $narFile->{url} $size $v\n";
# Download the archive.
print " downloading archive...\n";
my $narFilePath = downloadFile "$narFile->{url}", "$narFile->{hash}";
my $narFilePath = downloadFile "$narFile->{url}";
if ($curStep < $maxStep) {
# The archive will be used a base to a patch.
@@ -280,14 +342,39 @@ while (scalar @path > 0) {
} else {
# Unpack the archive into the target path.
print " unpacking archive...\n";
system("@bunzip2@ < '$narFilePath' | @bindir@/nix-store --restore '$v'") == 0
system("@bunzip2@ < '$narFilePath' | $binDir/nix-store --restore '$v'") == 0
or die "cannot unpack `$narFilePath' into `$v'";
}
$finalNarHash = $narFile->{narHash};
}
$curStep++;
}
# Make sure that the hash declared in the manifest matches what we
# downloaded and unpacked.
if (defined $finalNarHash) {
my ($hashAlgo, $hash) = parseHash $finalNarHash;
# The hash in the manifest can be either in base-16 or base-32.
# Handle both.
my $extraFlag =
($hashAlgo eq "sha256" && length($hash) != 64)
? "--base32" : "";
my $hash2 = `@bindir@/nix-hash --type $hashAlgo $extraFlag $targetPath`
or die "cannot compute hash of path `$targetPath'";
chomp $hash2;
die "hash mismatch in downloaded path $targetPath; expected $hash, got $hash2"
if $hash ne $hash2;
} else {
die "cannot check integrity of the downloaded path since its hash is not known";
}
print LOGFILE "$$ success\n";
close LOGFILE;

View File

@@ -56,3 +56,20 @@ sub lsof {
readProc;
lsof;
sub readFile {
my $path = shift;
if (-e $path) {
if (open FILE, "$path") {
while (<FILE>) {
print;
}
close FILE;
}
}
}
# This is rather NixOS-specific, so it probably shouldn't be here.
readFile "/proc/sys/kernel/modprobe";
readFile "/proc/sys/kernel/fbsplash";

View File

@@ -4,6 +4,18 @@ use strict;
use File::Temp qw(tempdir);
use readmanifest;
# Some patch generations options.
# Max size of NAR archives to generate patches for.
my $maxNarSize = $ENV{"NIX_MAX_NAR_SIZE"};
$maxNarSize = 100 * 1024 * 1024 if !defined $maxNarSize;
# If patch is bigger than this fraction of full archive, reject.
my $maxPatchFraction = $ENV{"NIX_PATCH_FRACTION"};
$maxPatchFraction = 0.60 if !defined $maxPatchFraction;
die unless scalar @ARGV == 5;
my $hashAlgo = "sha256";
@@ -22,23 +34,22 @@ print "TEMP = $tmpDir\n";
#END { rmdir $tmpDir; }
my %srcNarFiles;
my %srcLocalPaths;
my %srcPatches;
my %srcSuccessors;
my %dstNarFiles;
my %dstLocalPaths;
my %dstPatches;
my %dstSuccessors;
readManifest "$srcDir/MANIFEST",
\%srcNarFiles, \%srcPatches, \%srcSuccessors;
\%srcNarFiles, \%srcLocalPaths, \%srcPatches;
readManifest "$dstDir/MANIFEST",
\%dstNarFiles, \%dstPatches, \%dstSuccessors;
\%dstNarFiles, \%dstLocalPaths, \%dstPatches;
sub findOutputPaths {
my $narFiles = shift;
my $successors = shift;
my %outPaths;
@@ -63,10 +74,10 @@ sub findOutputPaths {
}
print "finding src output paths...\n";
my %srcOutPaths = findOutputPaths \%srcNarFiles, \%srcSuccessors;
my %srcOutPaths = findOutputPaths \%srcNarFiles;
print "finding dst output paths...\n";
my %dstOutPaths = findOutputPaths \%dstNarFiles, \%dstSuccessors;
my %dstOutPaths = findOutputPaths \%dstNarFiles;
sub getNameVersion {
@@ -277,8 +288,6 @@ foreach my $p (keys %dstOutPaths) {
my $srcNarBz2 = getNarBz2 \%srcNarFiles, $closest;
my $dstNarBz2 = getNarBz2 \%dstNarFiles, $p;
my $maxNarSize = 150 * 1024 * 1024;
system("@bunzip2@ < $srcNarBz2 > $tmpDir/A") == 0
or die "cannot unpack $srcNarBz2";
@@ -310,16 +319,21 @@ foreach my $p (keys %dstOutPaths) {
my $narDiffSize = (stat "$tmpDir/DIFF")[7];
my $dstNarBz2Size = (stat $dstNarBz2)[7];
print " size $narDiffSize; full size $dstNarBz2Size\n";
if ($narDiffSize >= $dstNarBz2Size) {
print " rejecting; patch bigger than full archive\n";
next;
}
if ($narDiffSize / $dstNarBz2Size >= $maxPatchFraction) {
print " rejecting; patch too large relative to full archive\n";
next;
}
my $finalName =
"$narDiffHash.nar-bsdiff";
print " size $narDiffSize; full size $dstNarBz2Size\n";
if (-e "$patchesDir/$finalName") {
print " not copying, already exists\n";
}
@@ -348,11 +362,22 @@ foreach my $p (keys %dstOutPaths) {
# patches that produce either paths in the destination or paths that
# can be used as the base for other useful patches).
print "propagating patches...\n";
my $changed;
do {
# !!! we repeat this to reach the transitive closure; inefficient
$changed = 0;
print "loop\n";
my %dstBasePaths;
foreach my $q (keys %dstPatches) {
foreach my $patch (@{$dstPatches{$q}}) {
$dstBasePaths{$patch->{basePath}} = 1;
}
}
foreach my $p (keys %srcPatches) {
my $patchList = $srcPatches{$p};
@@ -360,22 +385,18 @@ do {
# Is path $p included in the destination? If so, include
# patches that produce it.
$include = 1 if (defined $dstNarFiles{$p});
$include = 1 if defined $dstNarFiles{$p};
# Is path $p a path that serves as a base for paths in the
# destination? If so, include patches that produce it.
foreach my $q (keys %dstPatches) {
foreach my $patch (@{$dstPatches{$q}}) {
# !!! check baseHash
$include = 1 if ($p eq $patch->{basePath});
}
}
# !!! check baseHash
$include = 1 if defined $dstBasePaths{$p};
if ($include) {
foreach my $patch (@{$patchList}) {
$changed = 1 if addPatch \%dstPatches, $p, $patch;
}
}
}
}
@@ -384,4 +405,4 @@ do {
# Rewrite the manifest of the destination (with the new patches).
writeManifest "$dstDir/MANIFEST",
\%dstNarFiles, \%dstPatches, \%dstSuccessors;
\%dstNarFiles, \%dstPatches;

View File

@@ -7,12 +7,12 @@ use readcache;
# Read the manifests.
my %narFiles;
my %localPaths;
my %patches;
my %successors;
foreach my $manifest (@ARGV) {
print STDERR "loading $manifest\n";
if (readManifest($manifest, \%narFiles, \%patches, \%successors, 1) < 3) {
if (readManifest($manifest, \%narFiles, \%localPaths, \%patches, 1) < 3) {
# die "manifest `$manifest' is too old (i.e., for Nix <= 0.7)\n";
}
}

View File

@@ -15,7 +15,7 @@ sub readDir {
}
readDir "/data/webserver/dist/nix-cache";
readDir "/data/webserver/dist/test";
readDir "/data/webserver/dist/test-cache";
readDir "/data/webserver/dist/patches";
print STDERR scalar (keys %archives), "\n";

View File

@@ -6,12 +6,12 @@ use readcache;
my %allNarFiles;
my %allLocalPaths;
my %allPatches;
my %allSuccessors;
foreach my $manifest (glob "/data/webserver/dist/*/*/MANIFEST") {
print STDERR "loading $manifest\n";
readManifest($manifest, \%allNarFiles, \%allPatches, \%allSuccessors, 1);
readManifest($manifest, \%allNarFiles, \%allLocalPaths, \%allPatches, 1);
}
@@ -22,9 +22,8 @@ foreach my $manifest (@ARGV) {
my %narFiles;
my %patches;
my %successors;
if (readManifest($manifest, \%narFiles, \%patches, \%successors, 1) < 3) {
if (readManifest($manifest, \%narFiles, \%patches, 1) < 3) {
print STDERR "manifest `$manifest' is too old (i.e., for Nix <= 0.7)\n";
next;
}

View File

@@ -2,6 +2,8 @@
use strict;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
my $addDrvLink = 0;
my $addOutLink = 1;
@@ -9,6 +11,8 @@ my $addOutLink = 1;
my $outLink;
my $drvLink;
my $dryRun = 0;
my @instArgs = ();
my @buildArgs = ();
my @exprs = ();
@@ -56,7 +60,7 @@ EOF
}
elsif ($arg eq "--no-out-link" or $arg eq "--no-link") {
$addOutLink = 1;
$addOutLink = 0;
}
elsif ($arg eq "--drv-link") {
@@ -73,16 +77,41 @@ EOF
elsif ($arg eq "--attr" or $arg eq "-A") {
$n++;
die "$0: `--attr' requires an argument\n" unless $n < scalar @ARGV;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
push @instArgs, ("--attr", $ARGV[$n]);
}
elsif ($arg eq "--arg") {
die "$0: `--arg' requires two arguments\n" unless $n + 2 < scalar @ARGV;
push @instArgs, ("--arg", $ARGV[$n + 1], $ARGV[$n + 2]);
elsif ($arg eq "--arg" || $arg eq "--argstr") {
die "$0: `$arg' requires two arguments\n" unless $n + 2 < scalar @ARGV;
push @instArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
$n += 2;
}
elsif ($arg eq "--log-type") {
$n++;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
push @instArgs, ($arg, $ARGV[$n]);
push @buildArgs, ($arg, $ARGV[$n]);
}
elsif ($arg eq "--option") {
die "$0: `$arg' requires two arguments\n" unless $n + 2 < scalar @ARGV;
push @instArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
push @buildArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
$n += 2;
}
elsif ($arg eq "--max-jobs" or $arg eq "-j" or $arg eq "--max-silent-time" or $arg eq "--log-type") {
$n++;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
push @buildArgs, ($arg, $ARGV[$n]);
}
elsif ($arg eq "--dry-run") {
push @buildArgs, "--dry-run";
$dryRun = 1;
}
elsif (substr($arg, 0, 1) eq "-") {
push @buildArgs, $arg;
}
@@ -111,22 +140,32 @@ foreach my $expr (@exprs) {
# Instantiate.
my @drvPaths;
# !!! would prefer the perl 5.8.0 pipe open feature here.
my $pid = open(DRVPATHS, "-|") || exec "@bindir@/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
my $pid = open(DRVPATHS, "-|") || exec "$binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
while (<DRVPATHS>) {chomp; push @drvPaths, $_;}
close DRVPATHS or exit 1;
if (!close DRVPATHS) {
die "nix-instantiate killed by signal " . ($? & 127) . "\n" if ($? & 127);
exit 1;
}
foreach my $drvPath (@drvPaths) {
my $target = readlink $drvPath;
my $target = readlink $drvPath or die "cannot read symlink `$drvPath'";
print STDERR "store derivation is $target\n";
}
# Build.
my $outPaths = `@bindir@/nix-store --add-root "$outLink" --indirect -rv @buildArgs @drvPaths`;
my @outPaths = split ' ', $outPaths;
foreach my $outPath (@outPaths) {
my $target = readlink $outPath;
print "$target\n";
my @outPaths;
$pid = open(OUTPATHS, "-|") || exec "$binDir/nix-store", "--add-root", $outLink, "--indirect", "-rv",
@buildArgs, @drvPaths;
while (<OUTPATHS>) {chomp; push @outPaths, $_;}
if (!close OUTPATHS) {
die "nix-store killed by signal " . ($? & 127) . "\n" if ($? & 127);
exit 1;
}
next if $dryRun;
foreach my $outPath (@outPaths) {
my $target = readlink $outPath or die "cannot read symlink `$outPath'";
print "$target\n";
}
}

View File

@@ -2,16 +2,24 @@
use strict;
my $rootsDir = "@localstatedir@/nix/gcroots/channels";
my $rootsDir = "@localstatedir@/nix/gcroots";
my $stateDir = $ENV{"NIX_STATE_DIR"};
$stateDir = "@localstatedir@/nix" unless defined $stateDir;
# Turn on caching in nix-prefetch-url.
my $channelCache = "$stateDir/channel-cache";
mkdir $channelCache, 0755 unless -e $channelCache;
$ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache;
# Figure out the name of the `.nix-channels' file to use.
my $home = $ENV{"HOME"};
die '$HOME not set' unless defined $home;
my $channelsList = "$home/.nix-channels";
my $nixDefExpr = "$home/.nix-defexpr";
my @channels;
@@ -70,61 +78,70 @@ sub removeChannel {
sub update {
readChannels;
# Get rid of all the old substitutes.
system("@bindir@/nix-store", "--clear-substitutes") == 0
or die "cannot clear substitutes";
# Do we have write permission to the manifests directory? If not,
# then just skip pulling the manifest and just download the Nix
# expressions. If the user is a non-privileged user in a
# multi-user Nix installation, he at least gets installation from
# source.
if (-W "$stateDir/manifests") {
# Remove all the old manifests.
for my $manifest (glob "$stateDir/manifests/*.nixmanifest") {
unlink $manifest or die "cannot remove `$manifest': $!";
}
# Remove all the old manifests.
for my $manifest (glob "$stateDir/manifests/*.nixmanifest") {
unlink $manifest or die "cannot remove `$manifest': $!";
}
# Pull cache manifests.
foreach my $url (@channels) {
#print "pulling cache manifest from `$url'\n";
system("@bindir@/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
or die "cannot pull cache manifest from `$url'";
}
# Pull cache manifests.
foreach my $url (@channels) {
print "pulling cache manifest from `$url'\n";
system("@bindir@/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
or die "cannot pull cache manifest from `$url'";
}
# Create a Nix expression that fetches and unpacks the channel Nix
# expressions.
my $nixExpr = "[";
my $inputs = "[";
foreach my $url (@channels) {
$url =~ /\/([^\/]+)\/?$/;
my $channelName = $1;
$channelName = "unnamed" unless defined $channelName;
my $fullURL = "$url/nixexprs.tar.bz2";
print "downloading Nix expressions from `$fullURL'...\n";
$ENV{"PRINT_PATH"} = 1;
my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL' 2> /dev/null`;
$ENV{"QUIET"} = 1;
my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL'`;
die "cannot fetch `$fullURL'" if $? != 0;
chomp $path;
$nixExpr .= $path . " ";
$inputs .= '"' . $channelName . '"' . " " . $path . " ";
}
$nixExpr .= "]";
$nixExpr =
"(import @datadir@/nix/corepkgs/channels/unpack.nix) " .
"{inputs = $nixExpr; system = \"@system@\";}";
$inputs .= "]";
# Figure out a name for the GC root.
my $userName = getpwuid($<);
die "who ARE you? go away" unless defined $userName;
my $rootFile = "$rootsDir/$userName";
my $rootFile = "$rootsDir/per-user/$userName/channels";
# Instantiate the Nix expression.
my $storeExpr = `echo '$nixExpr' | @bindir@/nix-instantiate --add-root '$rootFile'.tmp -`
or die "cannot instantiate Nix expression";
chomp $storeExpr;
# Build the resulting derivation.
my $outPath = `@bindir@/nix-store --add-root '$rootFile' -r '$storeExpr'`
or die "cannot realise store expression";
# Build the Nix expression.
print "unpacking channel Nix expressions...\n";
my $outPath = `\\
@bindir@/nix-build --out-link '$rootFile' --drv-link '$rootFile'.tmp \\
@datadir@/nix/corepkgs/channels/unpack.nix \\
--argstr system @system@ --arg inputs '$inputs'`
or die "cannot unpack the channels";
chomp $outPath;
unlink "$rootFile.tmp";
# Make it the default Nix expression for `nix-env'.
system("@bindir@/nix-env", "--import", "$outPath") == 0
or die "cannot pull set default Nix expression to `$outPath'";
# Make the channels appear in nix-env.
unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr
mkdir $nixDefExpr or die "cannot create directory `$nixDefExpr'" if !-e $nixDefExpr;
my $channelLink = "$nixDefExpr/channels";
unlink $channelLink; # !!! not atomic
symlink($outPath, $channelLink) or die "cannot symlink `$channelLink' to `$outPath'";
}

View File

@@ -4,6 +4,8 @@ use strict;
my $profilesDir = "@localstatedir@/nix/profiles";
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
# Process the command line arguments.
my @args = ();
@@ -21,22 +23,31 @@ for my $arg (@ARGV) {
# If `-d' was specified, remove all old generations of all profiles.
# Of course, this makes rollbacks to before this point in time
# impossible.
if ($removeOld) {
opendir DIR, $profilesDir or die;
sub removeOldGenerations;
sub removeOldGenerations {
my $dir = shift;
foreach my $name (sort (readdir DIR)) {
$name = $profilesDir . "/" . $name;
my $dh;
opendir $dh, $dir or die;
foreach my $name (sort (readdir $dh)) {
next if $name eq "." || $name eq "..";
$name = $dir . "/" . $name;
if (-l $name && (readlink($name) =~ /link/)) {
print STDERR "removing old generations of profile $name\n";
system("@bindir@/nix-env", "-p", $name, "--delete-generations", "old");
system("$binDir/nix-env", "-p", $name, "--delete-generations", "old");
}
elsif (! -l $name && -d $name) {
removeOldGenerations $name;
}
}
closedir DIR or die;
closedir $dh or die;
}
removeOldGenerations $profilesDir if $removeOld;
# Run the actual garbage collector.
exec "@bindir@/nix-store", "--gc", @args;
exec "$binDir/nix-store", "--gc", @args;

131
scripts/nix-copy-closure.in Normal file
View File

@@ -0,0 +1,131 @@
#! @perl@ -w
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
if (scalar @ARGV < 1) {
print STDERR <<EOF
Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] PATHS...
EOF
;
exit 1;
}
# Get the target host.
my $sshHost;
my @sshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or "");
my $sign = 0;
my $compressor = "cat";
my $decompressor = "cat";
my $toMode = 1;
# !!! Copied from nix-pack-closure, should put this in a module.
my @storePaths = ();
while (@ARGV) {
my $arg = shift @ARGV;
if ($arg eq "--sign") {
$sign = 1;
}
elsif ($arg eq "--gzip") {
$compressor = "gzip";
$decompressor = "gunzip";
}
elsif ($arg eq "--from") {
$toMode = 0;
}
elsif ($arg eq "--to") {
$toMode = 1;
}
elsif (!defined $sshHost) {
$sshHost = $arg;
}
else {
push @storePaths, $arg;
}
}
if ($toMode) { # Copy TO the remote machine.
my @allStorePaths;
# Get the closure of this path.
my $pid = open(READ, "$binDir/nix-store --query --requisites @storePaths|") or die;
while (<READ>) {
chomp;
die "bad: $_" unless /^\//;
push @allStorePaths, $_;
}
close READ or die "nix-store failed: $?";
# Ask the remote host which paths are invalid.
open(READ, "ssh @sshOpts $sshHost nix-store --check-validity --print-invalid @allStorePaths|");
my @missing = ();
while (<READ>) {
chomp;
print STDERR "target machine needs $_\n";
push @missing, $_;
}
close READ or die;
# Export the store paths and import them on the remote machine.
if (scalar @missing > 0) {
my $extraOpts = "";
$extraOpts .= "--sign" if $sign == 1;
system("nix-store --export $extraOpts @missing | $compressor | ssh @sshOpts $sshHost '$decompressor | nix-store --import'") == 0
or die "copying store paths to remote machine `$sshHost' failed: $?";
}
}
else { # Copy FROM the remote machine.
# Query the closure of the given store paths on the remote
# machine. Paths are assumed to be store paths; there is no
# resolution (following of symlinks).
my $pid = open(READ,
"ssh @sshOpts $sshHost nix-store --query --requisites @storePaths|") or die;
my @allStorePaths;
while (<READ>) {
chomp;
die "bad: $_" unless /^\//;
push @allStorePaths, $_;
}
close READ or die "nix-store on remote machine `$sshHost' failed: $?";
# What paths are already valid locally?
open(READ, "@bindir@/nix-store --check-validity --print-invalid @allStorePaths|");
my @missing = ();
while (<READ>) {
chomp;
print STDERR "local machine needs $_\n";
push @missing, $_;
}
close READ or die;
# Export the store paths on the remote machine and import them on locally.
if (scalar @missing > 0) {
my $extraOpts = "";
$extraOpts .= "--sign" if $sign == 1;
system("ssh @sshOpts $sshHost 'nix-store --export $extraOpts @missing | $compressor' | $decompressor | @bindir@/nix-store --import") == 0
or die "copying store paths to remote machine `$sshHost' failed: $?";
}
}

51
scripts/nix-http-export.cgi.in Executable file
View File

@@ -0,0 +1,51 @@
#! /bin/sh
export HOME=/tmp
export NIX_REMOTE=daemon
TMP_DIR="${TMP_DIR:-/tmp/nix-export}"
@coreutils@/mkdir -p "$TMP_DIR" || true
@coreutils@/chmod a+r "$TMP_DIR"
needed_path="?$QUERY_STRING"
needed_path="${needed_path#*[?&]needed_path=}"
needed_path="${needed_path%%&*}"
#needed_path="$(echo $needed_path | ./unhttp)"
needed_path="${needed_path//%2B/+}"
needed_path="${needed_path//%3D/=}"
echo needed_path: "$needed_path" >&2
NIX_STORE="${NIX_STORE_DIR:-/nix/store}"
echo NIX_STORE: "${NIX_STORE}" >&2
full_path="${NIX_STORE}"/"$needed_path"
if [ "$needed_path" != "${needed_path%.drv}" ]; then
echo "Status: 403 You should create the derivation file yourself"
echo "Content-Type: text/plain"
echo
echo "Refusing to disclose derivation contents"
exit
fi
if @bindir@/nix-store --check-validity "$full_path"; then
if ! [ -e nix-export/"$needed_path".nar.gz ]; then
@bindir@/nix-store --export "$full_path" | @gzip@ > "$TMP_DIR"/"$needed_path".nar.gz
@coreutils@/ln -fs "$TMP_DIR"/"$needed_path".nar.gz nix-export/"$needed_path".nar.gz
fi;
echo "Status: 301 Moved"
echo "Location: nix-export/"$needed_path".nar.gz"
echo
else
echo "Status: 404 No such path found"
echo "Content-Type: text/plain"
echo
echo "Path not found:"
echo "$needed_path"
echo "checked:"
echo "$full_path"
fi

View File

@@ -3,6 +3,8 @@
use strict;
use File::Temp qw(tempdir);
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
sub usageError {
print STDERR <<EOF;
@@ -13,7 +15,7 @@ downloading it from URL.
Flags:
--profile / -p LINK: install into the specified profile
--non-interactive: don't run inside a new terminal XXX
--non-interactive: don't run inside a new terminal
EOF
; # '
exit 1;
@@ -59,7 +61,7 @@ if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) {
$ENV{"NIX_HAVE_TERMINAL"} = "1";
$ENV{"LD_LIBRARY_PATH"} = "";
foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") {
exec($term, "-e", "@bindir@/nix-install-package", @ARGV);
exec($term, "-e", "$binDir/nix-install-package", @ARGV);
}
die "cannot execute `xterm'";
}
@@ -121,13 +123,18 @@ if ($interactive) {
}
# Store the manifest in the temporary directory so that we don't
# pollute /nix/var/nix/manifests.
$ENV{NIX_MANIFESTS_DIR} = $tmpDir;
print "\nPulling manifests...\n";
system("@bindir@/nix-pull", $manifestURL) == 0
system("$binDir/nix-pull", $manifestURL) == 0
or barf "nix-pull failed: $?";
print "\nInstalling package...\n";
system("@bindir@/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
system("$binDir/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
or barf "nix-env failed: $?";

View File

@@ -1,65 +0,0 @@
#! @perl@ -w
# This tool computes the closure of a path (using "nix-store --query
# --requisites") and puts the contents of each path in the closure in
# a big NAR archive that can be installed on another Nix installation
# using "nix-unpack-closure".
# TODO: make this program "streamy", i.e., don't use a temporary
# directory.
use strict;
use File::Temp qw(tempdir);
my $binDir = $ENV{"NIX_BIN_DIR"};
$binDir = "@bindir@" unless defined $binDir;
my $tmpDir = tempdir("nix-pack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
mkdir "$tmpDir/contents", 0777 or die;
mkdir "$tmpDir/references", 0777 or die;
mkdir "$tmpDir/derivers", 0777 or die;
my %storePaths;
while (@ARGV) {
my $storePath = shift @ARGV;
# Get the closure of this path.
my $pid = open(READ,
"$binDir/nix-store --query --requisites '$storePath'|") or die;
while (<READ>) {
chomp;
die "bad: $_" unless /^\//;
$storePaths{$_} = "";
}
close READ or die "nix-store failed: $?";
}
foreach my $storePath (sort(keys %storePaths)) {
print STDERR "packing `$storePath'...\n";
$storePath =~ /\/([^\/]+)$/;
my $name = $1;
system("$binDir/nix-store --dump '$storePath' > $tmpDir/contents/$name") == 0
or die "nix-store --dump failed on `$storePath': $?";
system("$binDir/nix-store --query --references '$storePath' > $tmpDir/references/$name") == 0
or die "nix-store --query --references failed on `$storePath': $?";
system("$binDir/nix-store --query --deriver '$storePath' > $tmpDir/derivers/$name") == 0
or die "nix-store --query --deriver failed on `$storePath': $?";
}
# Write a NAR archive of everything to standard output.
system("nix-store --dump '$tmpDir'") == 0
or die "nix-store --dump failed";

View File

@@ -3,15 +3,12 @@
url=$1
expHash=$2
# to prevent doing more than 1 chroot
unset NIX_ROOT
# needed to make it work on NixOS
export PATH=$PATH:@coreutils@
hashType=$NIX_HASH_ALGO
if test -z "$hashType"; then
hashType=md5
hashType=sha256
fi
hashFormat=
@@ -39,29 +36,116 @@ if test -n "$expHash"; then
fi
mkTempDir() {
if test -n "$tmpPath"; then return; fi
local i=0
while true; do
if test -z "$TMPDIR"; then TMPDIR=/tmp; fi
tmpPath=$TMPDIR/nix-prefetch-url-$$-$i
if mkdir "$tmpPath"; then break; fi
# !!! to bad we can't check for ENOENT in mkdir, so this check
# is slightly racy (it bombs out if somebody just removed
# $tmpPath...).
if ! test -e "$tmpPath"; then exit 1; fi
i=$((i + 1))
done
trap removeTempDir EXIT SIGINT SIGQUIT
}
removeTempDir() {
if test -n "$tmpPath"; then
rm -rf "$tmpPath" || true
fi
}
doDownload() {
@curl@ $cacheFlags --fail --location --max-redirs 20 --disable-epsv \
--cookie-jar $tmpPath/cookies "$url" -o $tmpFile
}
# Hack to support the mirror:// scheme from Nixpkgs.
if test "${url:0:9}" = "mirror://"; then
if test -z "$NIXPKGS_ALL"; then
echo "Resolving mirror:// URLs requires Nixpkgs. Please point \$NIXPKGS_ALL at a Nixpkgs tree." >&2
exit 1
fi
mkTempDir
nix-build "$NIXPKGS_ALL" -A resolveMirrorURLs --argstr url "$url" -o $tmpPath/urls > /dev/null
expanded=($(cat $tmpPath/urls))
if test "${#expanded[*]}" = 0; then
echo "$0: cannot resolve $url." >&2
exit 1
fi
echo "$url expands to ${expanded[*]} (using ${expanded[0]})" >&2
url="${expanded[0]}"
fi
# If we don't know the hash or a file with that hash doesn't exist,
# download the file and add it to the store.
if test -z "$finalPath"; then
tmpPath=/tmp/nix-prefetch-url-$$ # !!! security?
mkTempDir
tmpFile=$tmpPath/$name
mkdir $tmpPath
# Optionally do timestamp-based caching of the download.
# Actually, the only thing that we cache in $NIX_DOWNLOAD_CACHE is
# the hash and the timestamp of the file at $url. The caching of
# the file *contents* is done in Nix store, where it can be
# garbage-collected independently.
if test -n "$NIX_DOWNLOAD_CACHE"; then
echo -n "$url" > $tmpPath/url
urlHash=$(@bindir@/nix-hash --type sha256 --base32 --flat $tmpPath/url)
echo "$url" > "$NIX_DOWNLOAD_CACHE/$urlHash.url"
cachedHashFN="$NIX_DOWNLOAD_CACHE/$urlHash.$hashType"
cachedTimestampFN="$NIX_DOWNLOAD_CACHE/$urlHash.stamp"
cacheFlags="--remote-time"
if test -e "$cachedTimestampFN" -a -e "$cachedHashFN"; then
# Only download the file if it is newer than the cached version.
cacheFlags="$cacheFlags --time-cond $cachedTimestampFN"
fi
fi
# Perform the download.
@curl@ --fail --location --max-redirs 20 "$url" > $tmpFile
doDownload
# Compute the hash.
hash=$(@bindir@/nix-hash --type "$hashType" $hashFormat --flat $tmpFile)
if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi
if test -n "$NIX_DOWNLOAD_CACHE" -a ! -e $tmpFile; then
# Curl didn't create $tmpFile, so apparently there's no newer
# file on the server.
hash=$(cat $cachedHashFN)
finalPath=$(@bindir@/nix-store --print-fixed-path "$hashType" "$hash" "$name")
if ! @bindir@/nix-store --check-validity "$finalPath" 2> /dev/null; then
echo "cached contents of \`$url' disappeared, redownloading..." >&2
finalPath=
cacheFlags="--remote-time"
doDownload
fi
fi
# Add the downloaded file to the Nix store.
finalPath=$(@bindir@/nix-store --add-fixed "$hashType" $tmpFile)
if test -z "$finalPath"; then
if test -n "$tmpPath"; then rm -rf $tmpPath || true; fi
# Compute the hash.
hash=$(@bindir@/nix-hash --type "$hashType" $hashFormat --flat $tmpFile)
if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi
if test -n "$expHash" -a "$expHash" != "$hash"; then
echo "hash mismatch for URL \`$url'"
exit 1
if test -n "$NIX_DOWNLOAD_CACHE"; then
echo $hash > $cachedHashFN
touch -r $tmpFile $cachedTimestampFN
fi
# Add the downloaded file to the Nix store.
finalPath=$(@bindir@/nix-store --add-fixed "$hashType" $tmpFile)
if test -n "$expHash" -a "$expHash" != "$hash"; then
echo "hash mismatch for URL \`$url'" >&2
exit 1
fi
fi
fi

View File

@@ -7,5 +7,12 @@ if test -n "$HOME"; then
@coreutils@/ln -s "$_NIX_DEF_LINK" "$NIX_LINK"
fi
export PATH=$NIX_LINK/bin:@prefix@/bin:$PATH
export PATH=$NIX_LINK/bin:$PATH
fi
# This is a quick hack to make fontconfig-based packages in Nixpkgs
# work out of the box on non-NixOS systems. Of course, we should
# really fix fontconfig...
if test -z "$FONTCONFIG_FILE" -a -e /etc/fonts/fonts.conf; then
export FONTCONFIG_FILE=/etc/fonts/fonts.conf
fi

View File

@@ -7,19 +7,11 @@ use readmanifest;
my $tmpDir = tempdir("nix-pull.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
my $manifest = "$tmpDir/manifest";
my $binDir = $ENV{"NIX_BIN_DIR"};
$binDir = "@bindir@" unless defined $binDir;
my $libexecDir = $ENV{"NIX_LIBEXEC_DIR"};
$libexecDir = "@libexecdir@" unless defined $libexecDir;
my $stateDir = $ENV{"NIX_STATE_DIR"};
$stateDir = "@localstatedir@/nix" unless defined $stateDir;
my $storeDir = $ENV{"NIX_STORE_DIR"};
$storeDir = "@storedir@" unless defined $storeDir;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
my $libexecDir = ($ENV{"NIX_LIBEXEC_DIR"} or "@libexecdir@");
my $storeDir = ($ENV{"NIX_STORE_DIR"} or "@storedir@");
my $stateDir = ($ENV{"NIX_STATE_DIR"} or "@localstatedir@/nix");
my $manifestDir = ($ENV{"NIX_MANIFESTS_DIR"} or "$stateDir/manifests");
# Prevent access problems in shared-stored installations.
@@ -28,25 +20,55 @@ umask 0022;
# Process the URLs specified on the command line.
my %narFiles;
my %localPaths;
my %patches;
my %successors;
my $skipWrongStore = 0;
sub downloadFile {
my $url = shift;
$ENV{"PRINT_PATH"} = 1;
$ENV{"QUIET"} = 1;
my ($dummy, $path) = `$binDir/nix-prefetch-url '$url'`;
die "cannot fetch `$url'" if $? != 0;
die "nix-prefetch-url did not return a path" unless defined $path;
chomp $path;
return $path;
}
sub processURL {
my $url = shift;
$url =~ s/\/$//;
print "obtaining list of Nix archives at $url...\n";
system("@curl@ --fail --silent --show-error --location --max-redirs 20 " .
"'$url' > '$manifest'") == 0
or die "curl failed: $?";
my $manifest;
if (readManifest($manifest, \%narFiles, \%patches, \%successors) < 3) {
die "manifest `$url' is too old (i.e., for Nix <= 0.7)\n";
# First see if a bzipped manifest is available.
if (system("@curl@ --fail --silent --head '$url'.bz2 > /dev/null") == 0) {
print "obtaining list of Nix archives at `$url.bz2'...\n";
my $bzipped = downloadFile "$url.bz2";
$manifest = "$tmpDir/MANIFEST";
system("@bunzip2@ < $bzipped > $manifest") == 0
or die "cannot decompress manifest";
$manifest = (`$binDir/nix-store --add $manifest`
or die "cannot copy $manifest to the store");
chomp $manifest;
}
# Otherwise, just get the uncompressed manifest.
else {
print "obtaining list of Nix archives at `$url'...\n";
$manifest = downloadFile $url;
}
my $version = readManifest($manifest, \%narFiles, \%localPaths, \%patches);
die "`$url' is not a manifest or it is too old (i.e., for Nix <= 0.7)\n" if $version < 3;
die "manifest `$url' is too new\n" if $version >= 5;
if ($skipWrongStore) {
foreach my $path (keys %narFiles) {
if (substr($path, 0, length($storeDir) + 1) ne "$storeDir/") {
@@ -65,10 +87,10 @@ sub processURL {
or die "cannot hash `$manifest'";
chomp $hash;
my $finalPath = "$stateDir/manifests/$baseName-$hash.nixmanifest";
my $finalPath = "$manifestDir/$baseName-$hash.nixmanifest";
system ("@coreutils@/mv", "-f", "$manifest", "$finalPath") == 0
or die "cannot move `$manifest' to `$finalPath";
system("@coreutils@/ln", "-sfn", "$manifest", "$finalPath") == 0
or die "cannot link `$finalPath to `$manifest'";
}
while (@ARGV) {
@@ -81,30 +103,5 @@ while (@ARGV) {
}
my $size = scalar (keys %narFiles);
my $size = scalar (keys %narFiles) + scalar (keys %localPaths);
print "$size store paths in manifest\n";
# Register all substitutes.
print STDERR "registering substitutes...\n";
my $pid = open(WRITE, "|$binDir/nix-store --register-substitutes")
or die "cannot run nix-store";
foreach my $storePath (keys %narFiles) {
my $narFileList = $narFiles{$storePath};
foreach my $narFile (@{$narFileList}) {
print WRITE "$storePath\n";
print WRITE "$narFile->{deriver}\n";
print WRITE "$libexecDir/nix/download-using-manifests.pl\n";
print WRITE "0\n";
my @references = split " ", $narFile->{references};
my $count = scalar @references;
print WRITE "$count\n";
foreach my $reference (@references) {
print WRITE "$reference\n";
}
}
}
close WRITE or die "nix-store failed: $?";

View File

@@ -16,8 +16,7 @@ my $curl = "@curl@ --fail --silent";
my $extraCurlFlags = ${ENV{'CURL_FLAGS'}};
$curl = "$curl $extraCurlFlags" if defined $extraCurlFlags;
my $binDir = $ENV{"NIX_BIN_DIR"};
$binDir = "@bindir@" unless defined $binDir;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
my $dataDir = $ENV{"NIX_DATA_DIR"};
$dataDir = "@datadir@" unless defined $dataDir;
@@ -107,7 +106,7 @@ foreach my $storePath (@storePaths) {
# Construct a Nix expression that creates a Nix archive.
my $nixexpr =
"((import $dataDir/nix/corepkgs/nar/nar.nix) " .
"{storePath = builtins.toPath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\";}) ";
"{storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\";}) ";
print NIX $nixexpr;
}
@@ -116,9 +115,9 @@ print NIX "]";
close NIX;
# Instantiate store expressions from the Nix expression.
# Instantiate store derivations from the Nix expression.
my @storeExprs;
print STDERR "instantiating store expressions...\n";
print STDERR "instantiating store derivations...\n";
my $pid = open(READ, "$binDir/nix-instantiate $nixExpr|")
or die "cannot run nix-instantiate";
while (<READ>) {
@@ -129,7 +128,7 @@ while (<READ>) {
close READ or die "nix-instantiate failed: $?";
# Realise the store expressions.
# Build the derivations.
print STDERR "creating archives...\n";
my @narPaths;
@@ -141,11 +140,6 @@ while (scalar @tmp > 0) {
my @tmp2 = @tmp[0..$n - 1];
@tmp = @tmp[$n..scalar @tmp - 1];
# Note: we disable build hooks because of the impure path
# reference (see above). Even if that is fixed, using a hook
# probably wouldn't make that much sense; pumping lots of data
# around just to compress them won't gain that much.
$ENV{"NIX_BUILD_HOOK"} = "";
my $pid = open(READ, "$binDir/nix-store --realise @tmp2|")
or die "cannot run nix-store";
while (<READ>) {
@@ -224,13 +218,14 @@ writeManifest $manifest, \%narFiles, \%patches;
sub copyFile {
my $src = shift;
my $dst = shift;
system("@coreutils@/cp", $src, "$dst.tmp") == 0 or die "cannot copy file";
rename("$dst.tmp", "$dst") or die "cannot rename file";
my $tmp = "$dst.tmp.$$";
system("@coreutils@/cp", $src, $tmp) == 0 or die "cannot copy file";
rename($tmp, $dst) or die "cannot rename file: $!";
}
# Upload the archives.
print STDERR "uploading archives...\n";
# Upload/copy the archives.
print STDERR "uploading/copying archives...\n";
sub archiveExists {
my $name = shift;
@@ -244,9 +239,12 @@ foreach my $narArchive (@narArchives) {
my $basename = $1;
if ($localCopy) {
# Since nix-push creates $dst atomically, if it exists we
# don't have to copy again.
my $dst = "$localArchivesDir/$basename";
if (! -f "$localArchivesDir/$basename") {
print STDERR " $narArchive\n";
copyFile $narArchive, "$localArchivesDir/$basename";
copyFile $narArchive, $dst;
}
}
else {
@@ -264,8 +262,12 @@ foreach my $narArchive (@narArchives) {
print STDERR "uploading manifest...\n";
if ($localCopy) {
copyFile $manifest, $localManifestFile;
copyFile "$manifest.bz2", "$localManifestFile.bz2";
} else {
system("$curl --show-error --upload-file " .
system("$curl --show-error --upload-file " .
"'$manifest' '$manifestPutURL' > /dev/null") == 0 or
die "curl failed on $manifest: $?";
system("$curl --show-error --upload-file " .
"'$manifest'.bz2 '$manifestPutURL'.bz2 > /dev/null") == 0 or
die "curl failed on $manifest: $?";
}

171
scripts/nix-reduce-build.in Normal file
View File

@@ -0,0 +1,171 @@
#! @shell@
WORKING_DIRECTORY=$(mktemp -d "${TMPDIR:-/tmp}"/nix-reduce-build-XXXXXX);
cd "$WORKING_DIRECTORY";
if test -z "$1" || test "a--help" = "a$1" ; then
echo 'nix-reduce-build (paths or Nix expressions) -- (package sources)' >&2
echo As in: >&2
echo nix-reduce-build /etc/nixos/nixos -- ssh://user@somewhere.nowhere.example.org >&2
echo nix-reduce-build /etc/nixos/nixos -- \\
echo " " \''http://somewhere.nowhere.example.org/nix/nix-http-export.cgi?needed_path='\' >&2
echo " store path name will be added into the end of the URL" >&2
echo nix-reduce-build /etc/nixos/nixos -- file://home/user/nar/ >&2
echo " that should be a directory where gzipped 'nix-store --export' ">&2
echo " files are located (they should have .nar.gz extension)" >&2
echo " Or all together: " >&2
echo -e nix-reduce-build /expr.nix /e2.nix -- \\\\\\\n\
" ssh://a@b.example.com http://n.example.com/get-nar?q= file://nar/" >&2
echo " Also supports best-effort local builds of failing expression set:" >&2
echo "nix-reduce-build /e.nix -- nix-daemon:// nix-self://" >&2
echo " nix-daemon:// builds using daemon"
echo " nix-self:// builds directly using nix-store from current installation" >&2
echo " nix-daemon-fixed:// and nix-self-fixed:// do the same, but only for" >&2;
echo "derivations with specified output hash (sha256, sha1 or md5)." >&2
echo " nix-daemon-substitute:// and nix-self-substitute:// try to substitute" >&2;
echo "maximum amount of paths" >&2;
echo " nix-daemon-build:// and nix-self-build:// try to build (not substitute)" >&2;
echo "maximum amount of paths" >&2;
echo " If no package sources are specified, required paths are listed." >&2;
exit;
fi;
while ! test "$1" = "--" || test "$1" = "" ; do
echo "$1" >> initial; >&2
shift;
done
shift;
echo Will work on $(cat initial | wc -l) targets. >&2
while read ; do
case "$REPLY" in
${NIX_STORE_DIR:-/nix/store}/*)
echo "$REPLY" >> paths; >&2
;;
*)
(
IFS=: ;
nix-instantiate $REPLY >> paths;
);
;;
esac;
done < initial;
echo Proceeding $(cat paths | wc -l) paths. >&2
while read; do
case "$REPLY" in
*.drv)
echo "$REPLY" >> derivers; >&2
;;
*)
nix-store --query --deriver "$REPLY" >>derivers;
;;
esac;
done < paths;
echo Found $(cat derivers | wc -l) derivers. >&2
cat derivers | xargs nix-store --query -R > derivers-closure;
echo Proceeding at most $(cat derivers-closure | wc -l) derivers. >&2
cat derivers-closure | egrep '[.]drv$' | xargs nix-store --query --outputs > wanted-paths;
cat derivers-closure | egrep -v '[.]drv$' >> wanted-paths;
echo Prepared $(cat wanted-paths | wc -l) paths to get. >&2
cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
echo We need $(cat needed-paths | wc -l) paths. >&2
egrep '[.]drv$' derivers-closure > critical-derivers;
if test -z "$1" ; then
cat needed-paths;
fi;
refresh_critical_derivers() {
echo "Finding needed derivers..." >&2;
cat critical-derivers | while read; do
if ! (nix-store --query --outputs "$REPLY" | xargs nix-store --check-validity &> /dev/null;); then
echo "$REPLY";
fi;
done > new-critical-derivers;
mv new-critical-derivers critical-derivers;
echo The needed paths are realized by $(cat critical-derivers | wc -l) derivers. >&2
}
build_here() {
cat critical-derivers | while read; do
echo "Realising $REPLY using nix-daemon" >&2
@bindir@/nix-store -r "${REPLY}"
done;
}
try_to_substitute(){
cat needed-paths | while read ; do
echo "Building $REPLY using nix-daemon" >&2
@bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}"
done;
}
for i in "$@"; do
sshHost="${i#ssh://}";
httpHost="${i#http://}";
httpsHost="${i#https://}";
filePath="${i#file:/}";
if [ "$i" != "$sshHost" ]; then
cat needed-paths | while read; do
echo "Getting $REPLY and its closure over ssh" >&2
nix-copy-closure --from "$sshHost" --gzip "$REPLY" </dev/null || true;
done;
elif [ "$i" != "$httpHost" ] || [ "$i" != "$httpsHost" ]; then
cat needed-paths | while read; do
echo "Getting $REPLY over http/https" >&2
curl ${BAD_CERTIFICATE:+-k} -L "$i${REPLY##*/}" | gunzip | nix-store --import;
done;
elif [ "$i" != "$filePath" ] ; then
cat needed-paths | while read; do
echo "Installing $REPLY from file" >&2
gunzip < "$filePath/${REPLY##*/}".nar.gz | nix-store --import;
done;
elif [ "$i" = "nix-daemon://" ] ; then
NIX_REMOTE=daemon try_to_substitute;
refresh_critical_derivers;
NIX_REMOTE=daemon build_here;
elif [ "$i" = "nix-self://" ] ; then
NIX_REMOTE= try_to_substitute;
refresh_critical_derivers;
NIX_REMOTE= build_here;
elif [ "$i" = "nix-daemon-fixed://" ] ; then
refresh_critical_derivers;
cat critical-derivers | while read; do
if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
echo "Realising $REPLY using nix-daemon" >&2
NIX_REMOTE=daemon @bindir@/nix-store -r "${REPLY}"
fi;
done;
elif [ "$i" = "nix-self-fixed://" ] ; then
refresh_critical_derivers;
cat critical-derivers | while read; do
if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
echo "Realising $REPLY using direct Nix build" >&2
NIX_REMOTE= @bindir@/nix-store -r "${REPLY}"
fi;
done;
elif [ "$i" = "nix-daemon-substitute://" ] ; then
NIX_REMOTE=daemon try_to_substitute;
elif [ "$i" = "nix-self-substitute://" ] ; then
NIX_REMOTE= try_to_substitute;
elif [ "$i" = "nix-daemon-build://" ] ; then
refresh_critical_derivers;
NIX_REMOTE=daemon build_here;
elif [ "$i" = "nix-self-build://" ] ; then
refresh_critical_derivers;
NIX_REMOTE= build_here;
fi;
mv needed-paths wanted-paths;
cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
echo We still need $(cat needed-paths | wc -l) paths. >&2
done;
cd /
rm -r "$WORKING_DIRECTORY"

View File

@@ -1,79 +0,0 @@
#! @perl@ -w
# This tool unpacks the closures created by "nix-pack-closure" and
# adds them to the Nix store.
# TODO: make this program "streamy", i.e., don't use a temporary
# directory.
use strict;
use File::Temp qw(tempdir);
my $binDir = $ENV{"NIX_BIN_DIR"};
$binDir = "@bindir@" unless defined $binDir;
my $tmpDir = tempdir("nix-unpack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
# Unpack the NAR archive on standard input.
system("nix-store --restore '$tmpDir/unpacked'") == 0
or die "nix-store --restore failed";
open VALID, ">$tmpDir/validity" or die;
# For each path in the closure that is not yet valid, add it to the
# store. TODO: use proper locking. Or even better, let nix-store do
# this.
opendir(DIR, "$tmpDir/unpacked/contents") or die "cannot open directory: $!";
foreach my $name (sort(readdir DIR)) {
next if $name eq "." or $name eq "..";
my $storePath = "@storedir@/$name"; # !!!
# !!! this really isn't a good validity check!
system "$binDir/nix-store --check-validity '$storePath' 2> /dev/null";
if ($? != 0) {
print STDERR "unpacking `$storePath'...\n";
# !!! race
system("@coreutils@/rm -rf '$storePath'") == 0
or die "cannot remove `$storePath': $?";
system("$binDir/nix-store --restore '$storePath' < '$tmpDir/unpacked/contents/$name'") == 0
or die "nix-store --dump failed on `$storePath': $?";
print VALID "$storePath\n";
open DRV, "<$tmpDir/unpacked/derivers/$name" or die;
my $deriver = <DRV>;
chomp $deriver;
$deriver = "" if $deriver eq "unknown-deriver";
close DRV;
my @refs;
open REFS, "<$tmpDir/unpacked/references/$name" or die;
while (<REFS>) {
chomp;
push @refs, $_;
}
close REFS;
print VALID "$deriver\n";
print VALID (scalar @refs), "\n";
foreach my $ref (@refs) {
print VALID "$ref\n";
}
}
}
closedir(DIR) or die;
# Register the invalid paths as valid.
system("nix-store --register-validity <'$tmpDir/validity'") == 0
or die "nix-store --register-validity failed";

View File

@@ -1,91 +0,0 @@
#! /usr/bin/perl -w
use strict;
use File::Basename;
my @paths = ("/nix/store");
print "hashing...\n";
my $hashList = "/tmp/nix-optimise-hash-list";
system("find @paths -type f -print0 | xargs -0 md5sum -- > $hashList") == 0
or die "cannot hash store files";
print "sorting by hash...\n";
system("sort $hashList > $hashList.sorted") == 0
or die "cannot sort list";
sub atomicLink {
my $target = shift;
my $new = shift;
my $tmpNew = "${new}_optimise.$$";
# Make the directory writable temporarily.
my $dir = dirname $new;
my @st = stat $dir or die;
chmod ($st[2] | 0200, $dir) or die "cannot make `$dir' writable: $!";
link $target, $tmpNew or die "cannot create hard link `$tmpNew': $!";
rename $tmpNew, $new or die "cannot rename `$tmpNew' to `$new': $!";
chmod ($st[2], $dir) or die "cannot restore permission on `$dir': $!";
utime ($st[8], $st[9], $dir) or die "cannot restore timestamp on `$dir': $!";
}
print "hard-linking...\n";
open LIST, "<$hashList.sorted" or die;
my $prevFile;
my $prevHash;
my $prevInode;
my $prevExec;
my $totalSpace = 0;
my $savedSpace = 0;
while (<LIST>) {
/^([0-9a-f]*)\s+(.*)$/ or die;
my $curFile = $2;
my $curHash = $1;
my @st = stat $curFile or die;
next if ($st[2] & 0222) != 0; # skip writable files
my $fileSize = $st[7];
$totalSpace += $fileSize;
my $isExec = ($st[2] & 0111) == 0111;
if (defined $prevHash && $curHash eq $prevHash
&& $prevExec == $isExec)
{
if ($st[1] != $prevInode) {
print "$curFile = $prevFile\n";
atomicLink $prevFile, $curFile;
$savedSpace += $fileSize;
}
} else {
$prevFile = $curFile;
$prevHash = $curHash;
$prevInode = $st[1];
$prevExec = ($st[2] & 0111) == 0111;
}
}
print "total space = $totalSpace\n";
print "saved space = $savedSpace\n";
my $savings = ($savedSpace / $totalSpace) * 100.0;
print "savings = $savings %\n";
close LIST;

View File

@@ -2,10 +2,7 @@ use strict;
sub addPatch {
my $patches = shift;
my $storePath = shift;
my $patch = shift;
my $allowConflicts = shift;
my ($patches, $storePath, $patch) = @_;
$$patches{$storePath} = []
unless defined $$patches{$storePath};
@@ -14,15 +11,9 @@ sub addPatch {
my $found = 0;
foreach my $patch2 (@{$patchList}) {
if ($patch2->{url} eq $patch->{url}) {
if ($patch2->{hash} eq $patch->{hash}) {
$found = 1 if ($patch2->{basePath} eq $patch->{basePath});
} else {
die "conflicting hashes for URL $patch->{url}, " .
"namely $patch2->{hash} and $patch->{hash}"
unless $allowConflicts;
}
}
$found = 1 if
$patch2->{url} eq $patch->{url} &&
$patch2->{basePath} eq $patch->{basePath};
}
push @{$patchList}, $patch if !$found;
@@ -32,12 +23,7 @@ sub addPatch {
sub readManifest {
my $manifest = shift;
my $narFiles = shift;
my $patches = shift;
my $successors = shift;
my $allowConflicts = shift;
$allowConflicts = 0 unless defined $allowConflicts;
my ($manifest, $narFiles, $localPaths, $patches) = @_;
open MANIFEST, "<$manifest"
or die "cannot open `$manifest': $!";
@@ -51,7 +37,6 @@ sub readManifest {
my $url;
my $hash;
my $size;
my @preds;
my $basePath;
my $baseHash;
my $patchType;
@@ -59,6 +44,7 @@ sub readManifest {
my $references;
my $deriver;
my $hashAlgo;
my $copyFrom;
while (<MANIFEST>) {
chomp;
@@ -75,7 +61,6 @@ sub readManifest {
undef $url;
undef $hash;
undef $size;
@preds = ();
undef $narHash;
undef $basePath;
undef $baseHash;
@@ -99,15 +84,7 @@ sub readManifest {
my $found = 0;
foreach my $narFile (@{$narFileList}) {
if ($narFile->{url} eq $url) {
if ($narFile->{hash} eq $hash) {
$found = 1;
} else {
die "conflicting hashes for URL $url, " .
"namely $narFile->{hash} and $hash"
unless $allowConflicts;
}
}
$found = 1 if $narFile->{url} eq $url;
}
if (!$found) {
push @{$narFileList},
@@ -117,10 +94,6 @@ sub readManifest {
};
}
foreach my $p (@preds) {
$$successors{$p} = $storePath;
}
}
elsif ($type eq "patch") {
@@ -129,16 +102,32 @@ sub readManifest {
, basePath => $basePath, baseHash => $baseHash
, narHash => $narHash, patchType => $patchType
, hashAlgo => $hashAlgo
}, $allowConflicts;
};
}
elsif ($type eq "localPath") {
$$localPaths{$storePath} = []
unless defined $$localPaths{$storePath};
my $localPathsList = $$localPaths{$storePath};
# !!! remove duplicates
push @{$localPathsList},
{ copyFrom => $copyFrom, references => $references
, deriver => ""
};
}
}
elsif (/^\s*StorePath:\s*(\/\S+)\s*$/) { $storePath = $1; }
elsif (/^\s*CopyFrom:\s*(\/\S+)\s*$/) { $copyFrom = $1; }
elsif (/^\s*Hash:\s*(\S+)\s*$/) { $hash = $1; }
elsif (/^\s*URL:\s*(\S+)\s*$/) { $url = $1; }
elsif (/^\s*Size:\s*(\d+)\s*$/) { $size = $1; }
elsif (/^\s*SuccOf:\s*(\/\S+)\s*$/) { push @preds, $1; }
elsif (/^\s*SuccOf:\s*(\/\S+)\s*$/) { } # obsolete
elsif (/^\s*BasePath:\s*(\/\S+)\s*$/) { $basePath = $1; }
elsif (/^\s*BaseHash:\s*(\S+)\s*$/) { $baseHash = $1; }
elsif (/^\s*Type:\s*(\S+)\s*$/) { $patchType = $1; }
@@ -160,11 +149,8 @@ sub readManifest {
}
sub writeManifest
{
my $manifest = shift;
my $narFiles = shift;
my $patches = shift;
sub writeManifest {
my ($manifest, $narFiles, $patches) = @_;
open MANIFEST, ">$manifest.tmp"; # !!! check exclusive
@@ -178,9 +164,9 @@ sub writeManifest
print MANIFEST "{\n";
print MANIFEST " StorePath: $storePath\n";
print MANIFEST " NarURL: $narFile->{url}\n";
print MANIFEST " Hash: $narFile->{hash}\n";
print MANIFEST " Hash: $narFile->{hash}\n" if defined $narFile->{hash};
print MANIFEST " NarHash: $narFile->{narHash}\n";
print MANIFEST " Size: $narFile->{size}\n";
print MANIFEST " Size: $narFile->{size}\n" if defined $narFile->{size};
print MANIFEST " References: $narFile->{references}\n"
if defined $narFile->{references} && $narFile->{references} ne "";
print MANIFEST " Deriver: $narFile->{deriver}\n"
@@ -210,6 +196,14 @@ sub writeManifest
rename("$manifest.tmp", $manifest)
or die "cannot rename $manifest.tmp: $!";
# Create a bzipped manifest.
system("@bzip2@ < $manifest > $manifest.bz2.tmp") == 0
or die "cannot compress manifest";
rename("$manifest.bz2.tmp", "$manifest.bz2")
or die "cannot rename $manifest.bz2.tmp: $!";
}

View File

@@ -6,14 +6,12 @@ use readmanifest;
for my $p (@ARGV) {
my %narFiles;
my %localPaths;
my %patches;
my %successors;
readManifest $p,
\%narFiles, \%patches, \%successors;
readManifest $p, \%narFiles, \%localPaths, \%patches;
%patches = ();
writeManifest $p,
\%narFiles, \%patches, \%successors;
writeManifest $p, \%narFiles, \%patches;
}

View File

@@ -8,10 +8,10 @@ die unless scalar @ARGV == 2;
my $cache = $ARGV[0];
my $manifest = $ARGV[1];
my %narFiles;
my %localPaths;
my %patches;
my %successors;
readManifest $manifest, \%narFiles, \%patches, \%successors;
readManifest $manifest, \%narFiles, \%localPaths, \%patches;
foreach my $storePath (keys %narFiles) {
my $narFileList = $narFiles{$storePath};
@@ -50,4 +50,4 @@ if (! -e "$manifest.backup") {
system "mv --reply=no '$manifest' '$manifest.backup'";
}
writeManifest $manifest, \%narFiles, \%patches, \%successors;
writeManifest $manifest, \%narFiles, \%patches;

View File

@@ -1,15 +1,5 @@
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
libexpr nix-instantiate nix-env nix-log2xml bsdiff-4.3
libexpr nix-instantiate nix-env nix-worker nix-setuid-helper \
nix-log2xml bsdiff-4.3
EXTRA_DIST = aterm-helper.pl
SETUID_PROGS = nix-store nix-instantiate nix-env
install-exec-hook:
if SETUID_HACK
if HAVE_SETRESUID
cd $(DESTDIR)$(bindir) && chown @NIX_USER@ $(SETUID_PROGS) \
&& chgrp @NIX_GROUP@ $(SETUID_PROGS) && chmod ug+s $(SETUID_PROGS)
else
cd $(DESTDIR)$(bindir) && chown root $(SETUID_PROGS) && chmod u+s $(SETUID_PROGS)
endif
endif

View File

@@ -47,6 +47,7 @@ print HEADER "#endif\n\n\n";
print IMPL "namespace nix {\n";
while (<STDIN>) {
s/\#.*//;
next if (/^\s*$/);
if (/^\s*(\w*)\s*\|([^\|]*)\|\s*(\w+)\s*\|\s*(\w+)?/) {

View File

@@ -1,6 +1,6 @@
SUBDIRS = format
pkginclude_HEADERS = assert.hpp checked_delete.hpp format.hpp \
nobase_pkginclude_HEADERS = assert.hpp checked_delete.hpp format.hpp \
shared_ptr.hpp weak_ptr.hpp throw_exception.hpp \
enable_shared_from_this.hpp \
detail/shared_count.hpp detail/workaround.hpp

View File

@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
static off_t offtin(u_char *buf)
{

View File

@@ -2,11 +2,13 @@ pkglib_LTLIBRARIES = libexpr.la
libexpr_la_SOURCES = \
nixexpr.cc eval.cc primops.cc lexer-tab.cc parser-tab.cc \
get-drvs.cc attr-path.cc expr-to-xml.cc
get-drvs.cc attr-path.cc expr-to-xml.cc common-opts.cc \
names.cc normal-forms.cc
pkginclude_HEADERS = \
nixexpr.hh eval.hh parser.hh lexer-tab.hh parser-tab.hh \
get-drvs.hh attr-path.hh expr-to-xml.hh
get-drvs.hh attr-path.hh expr-to-xml.hh common-opts.hh \
names.hh nixexpr-ast.hh
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
../boost/format/libformat.la

View File

@@ -46,7 +46,7 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath,
if (apType == apAttr) {
ATermMap attrs(128);
ATermMap attrs;
if (!isAttrs(state, e, attrs))
throw TypeError(

View File

@@ -0,0 +1,32 @@
#include "common-opts.hh"
#include "../libmain/shared.hh"
#include "util.hh"
#include "parser.hh"
namespace nix {
bool parseOptionArg(const string & arg, Strings::iterator & i,
const Strings::iterator & argsEnd, EvalState & state,
ATermMap & autoArgs)
{
if (arg != "--arg" && arg != "--argstr") return false;
UsageError error(format("`%1%' requires two arguments") % arg);
if (i == argsEnd) throw error;
string name = *i++;
if (i == argsEnd) throw error;
string value = *i++;
Expr e = arg == "--arg"
? parseExprFromString(state, value, absPath("."))
: makeStr(value);
autoArgs.set(toATerm(name), e);
return true;
}
}

View File

@@ -0,0 +1,17 @@
#ifndef __COMMON_OPTS_H
#define __COMMON_OPTS_H
#include "eval.hh"
namespace nix {
/* Some common option parsing between nix-env and nix-instantiate. */
bool parseOptionArg(const string & arg, Strings::iterator & i,
const Strings::iterator & argsEnd, EvalState & state,
ATermMap & autoArgs);
}
#endif /* !__COMMON_OPTS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,7 @@ typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
struct EvalState
{
ATermMap normalForms;
ATermMap sessionNormalForms;
ATermMap primOps;
DrvRoots drvRoots;
DrvHashes drvHashes; /* normalised derivation hashes */
@@ -37,12 +38,19 @@ struct EvalState
unsigned int nrEvaluated;
unsigned int nrCached;
unsigned int nrDepthAfterReset;
bool allowUnsafeEquality;
bool safeCache;
EvalState();
~EvalState();
void addPrimOps();
void addPrimOp(const string & name,
unsigned int arity, PrimOp primOp);
void loadNormalForms();
void saveNormalForms();
};
@@ -56,21 +64,29 @@ Expr evalFile(EvalState & state, const Path & path);
attributes. If `canonicalise' is true, we remove things like
position information and make sure that attribute sets are in
sorded order. */
Expr strictEvalExpr(EvalState & state, Expr e,
bool canonicalise = false);
Expr strictEvalExpr(EvalState & state, Expr e);
/* Specific results. */
string evalString(EvalState & state, Expr e);
Path evalPath(EvalState & state, Expr e);
string evalString(EvalState & state, Expr e, PathSet & context);
string evalStringNoCtx(EvalState & state, Expr e);
int evalInt(EvalState & state, Expr e);
bool evalBool(EvalState & state, Expr e);
ATermList evalList(EvalState & state, Expr e);
ATerm coerceToString(Expr e);
/* Contexts. */
string coerceToStringWithContext(EvalState & state,
ATermList & context, Expr e, bool & isPath);
Expr wrapInContext(ATermList context, Expr e);
/* Flatten nested lists into a single list (or expand a singleton into
a list). */
ATermList flattenList(EvalState & state, Expr e);
/* String coercion. Converts strings, paths and derivations to a
string. If `coerceMore' is set, also converts nulls, integers,
booleans and lists to a string. */
string coerceToString(EvalState & state, Expr e, PathSet & context,
bool coerceMore = false, bool copyToStore = true);
/* Path coercion. Converts strings, paths and derivations to a path.
The result is guaranteed to be an canonicalised, absolute path.
Nothing is copied to the store. */
Path coerceToPath(EvalState & state, Expr e, PathSet & context);
/* Automatically call a function for which each argument has a default
value or has a binding in the `args' map. Note: result is a call,

View File

@@ -2,6 +2,9 @@
#include "xml-writer.hh"
#include "nixexpr-ast.hh"
#include "aterm.hh"
#include "util.hh"
#include <cstdlib>
namespace nix {
@@ -15,29 +18,70 @@ static XMLAttrs singletonAttrs(const string & name, const string & value)
}
static void printTermAsXML(Expr e, XMLWriter & doc, ATermList & context)
/* set<Expr> is safe because all the expressions are also reachable
from the stack, therefore can't be garbage-collected. */
typedef set<Expr> ExprSet;
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
ExprSet & drvsSeen);
static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
PathSet & context, ExprSet & drvsSeen)
{
StringSet names;
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
names.insert(aterm2String(i->key));
for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen);
}
}
static void printPatternAsXML(Pattern pat, XMLWriter & doc)
{
ATerm name;
ATermList formals;
Pattern pat1, pat2;
ATermBool ellipsis;
if (matchVarPat(pat, name))
doc.writeEmptyElement("varpat", singletonAttrs("name", aterm2String(name)));
else if (matchAttrsPat(pat, formals, ellipsis)) {
XMLOpenElement _(doc, "attrspat");
for (ATermIterator i(formals); i; ++i) {
Expr name; ATerm dummy;
if (!matchFormal(*i, name, dummy)) abort();
doc.writeEmptyElement("attr", singletonAttrs("name", aterm2String(name)));
}
if (ellipsis == eTrue) doc.writeEmptyElement("ellipsis");
}
else if (matchAtPat(pat, pat1, pat2)) {
XMLOpenElement _(doc, "at");
printPatternAsXML(pat1, doc);
printPatternAsXML(pat2, doc);
}
}
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
ExprSet & drvsSeen)
{
XMLAttrs attrs;
ATerm s;
string s;
ATerm s2;
int i;
Expr e2;
ATermList as, es, formals;
ATerm body, pos;
ATermList as, es;
ATerm pat, body, pos;
while (matchContext(e, es, e2)) {
e = e2;
for (ATermIterator i(es); i; ++i)
context = ATinsert(context, *i);
}
checkInterrupt();
if (matchStr(e, s))
doc.writeEmptyElement("string", singletonAttrs("value", aterm2String(s)));
if (matchStr(e, s, context)) /* !!! show the context? */
doc.writeEmptyElement("string", singletonAttrs("value", s));
else if (matchPath(e, s))
doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s)));
else if (matchUri(e, s))
doc.writeEmptyElement("uri", singletonAttrs("value", aterm2String(s)));
else if (matchPath(e, s2))
doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2)));
else if (matchNull(e))
doc.writeEmptyElement("null");
@@ -52,40 +96,47 @@ static void printTermAsXML(Expr e, XMLWriter & doc, ATermList & context)
doc.writeEmptyElement("bool", singletonAttrs("value", "false"));
else if (matchAttrs(e, as)) {
XMLOpenElement _(doc, "attrs");
ATermMap attrs(128);
ATermMap attrs;
queryAllAttrs(e, attrs);
StringSet names;
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
names.insert(aterm2String(i->key));
for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
printTermAsXML(attrs.get(toATerm(*i)), doc, context);
Expr a = attrs.get(toATerm("type"));
if (a && matchStr(a, s, context) && s == "derivation") {
XMLAttrs xmlAttrs;
Path outPath, drvPath;
a = attrs.get(toATerm("drvPath"));
if (matchStr(a, drvPath, context))
xmlAttrs["drvPath"] = drvPath;
a = attrs.get(toATerm("outPath"));
if (matchStr(a, outPath, context))
xmlAttrs["outPath"] = outPath;
XMLOpenElement _(doc, "derivation", xmlAttrs);
if (drvsSeen.find(e) == drvsSeen.end()) {
drvsSeen.insert(e);
showAttrs(attrs, doc, context, drvsSeen);
} else
doc.writeEmptyElement("repeated");
}
else {
XMLOpenElement _(doc, "attrs");
showAttrs(attrs, doc, context, drvsSeen);
}
}
else if (matchList(e, es)) {
XMLOpenElement _(doc, "list");
for (ATermIterator i(es); i; ++i)
printTermAsXML(*i, doc, context);
printTermAsXML(*i, doc, context, drvsSeen);
}
else if (matchFunction(e, formals, body, pos)) {
else if (matchFunction(e, pat, body, pos)) {
XMLOpenElement _(doc, "function");
for (ATermIterator i(formals); i; ++i) {
Expr name; ValidValues valids; ATerm dummy;
if (!matchFormal(*i, name, valids, dummy)) abort();
XMLOpenElement _(doc, "arg", singletonAttrs("name", aterm2String(name)));
ATermList valids2;
if (matchValidValues(valids, valids2)) {
for (ATermIterator j(valids2); j; ++j) {
XMLOpenElement _(doc, "value");
printTermAsXML(*j, doc, context);
}
}
}
printPatternAsXML(pat, doc);
}
else
@@ -93,11 +144,12 @@ static void printTermAsXML(Expr e, XMLWriter & doc, ATermList & context)
}
void printTermAsXML(Expr e, std::ostream & out, ATermList & context)
void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
{
XMLWriter doc(true, out);
XMLOpenElement root(doc, "expr");
printTermAsXML(e, doc, context);
ExprSet drvsSeen;
printTermAsXML(e, doc, context, drvsSeen);
}

View File

@@ -9,7 +9,7 @@
namespace nix {
void printTermAsXML(Expr e, std::ostream & out, ATermList & context);
void printTermAsXML(Expr e, std::ostream & out, PathSet & context);
}

View File

@@ -10,7 +10,15 @@ string DrvInfo::queryDrvPath(EvalState & state) const
{
if (drvPath == "") {
Expr a = attrs->get(toATerm("drvPath"));
(string &) drvPath = a ? evalPath(state, a) : "";
/* Backwards compatibility hack with user environments made by
Nix <= 0.10: these contain illegal Path("") expressions. */
ATerm t;
if (a && matchPath(evalExpr(state, a), t))
return aterm2String(t);
PathSet context;
(string &) drvPath = a ? coerceToPath(state, a, context) : "";
}
return drvPath;
}
@@ -21,7 +29,8 @@ string DrvInfo::queryOutPath(EvalState & state) const
if (outPath == "") {
Expr a = attrs->get(toATerm("outPath"));
if (!a) throw TypeError("output path missing");
(string &) outPath = evalPath(state, a);
PathSet context;
(string &) outPath = coerceToPath(state, a, context);
}
return outPath;
}
@@ -34,21 +43,66 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
Expr a = attrs->get(toATerm("meta"));
if (!a) return meta; /* fine, empty meta information */
ATermMap attrs2(16); /* !!! */
ATermMap attrs2;
queryAllAttrs(evalExpr(state, a), attrs2);
for (ATermMap::const_iterator i = attrs2.begin(); i != attrs2.end(); ++i) {
ATerm s = coerceToString(evalExpr(state, i->value));
if (s)
meta[aterm2String(i->key)] = aterm2String(s);
/* For future compatibility, ignore attribute values that are
not strings. */
Expr e = evalExpr(state, i->value);
string s;
PathSet context;
MetaValue value;
int n;
ATermList es;
if (matchStr(e, s, context)) {
value.type = MetaValue::tpString;
value.stringValue = s;
meta[aterm2String(i->key)] = value;
} else if (matchInt(e, n)) {
value.type = MetaValue::tpInt;
value.intValue = n;
meta[aterm2String(i->key)] = value;
} else if (matchList(e, es)) {
value.type = MetaValue::tpStrings;
for (ATermIterator j(es); j; ++j)
value.stringValues.push_back(evalStringNoCtx(state, *j));
meta[aterm2String(i->key)] = value;
}
}
return meta;
}
MetaValue DrvInfo::queryMetaInfo(EvalState & state, const string & name) const
{
/* !!! evaluates all meta attributes => inefficient */
return queryMetaInfo(state)[name];
}
void DrvInfo::setMetaInfo(const MetaInfo & meta)
{
ATermMap metaAttrs;
foreach (MetaInfo::const_iterator, i, meta) {
Expr e;
switch (i->second.type) {
case MetaValue::tpInt: e = makeInt(i->second.intValue); break;
case MetaValue::tpString: e = makeStr(i->second.stringValue); break;
case MetaValue::tpStrings: {
ATermList es = ATempty;
foreach (Strings::const_iterator, j, i->second.stringValues)
es = ATinsert(es, makeStr(*j));
e = makeList(ATreverse(es));
break;
}
default: abort();
}
metaAttrs.set(toATerm(i->first), makeAttrRHS(e, makeNoPos()));
}
attrs->set(toATerm("meta"), makeAttrs(metaAttrs));
}
/* Cache for already evaluated derivations. Usually putting ATerms in
a STL container is unsafe (they're not scanning for GC roots), but
here it doesn't matter; everything in this set is reachable from
@@ -70,11 +124,11 @@ static bool getDerivation(EvalState & state, Expr e,
e = evalExpr(state, e);
if (!matchAttrs(e, es)) return true;
boost::shared_ptr<ATermMap> attrs(new ATermMap(32)); /* !!! */
boost::shared_ptr<ATermMap> attrs(new ATermMap());
queryAllAttrs(e, *attrs, false);
Expr a = attrs->get(toATerm("type"));
if (!a || evalString(state, a) != "derivation") return true;
if (!a || evalStringNoCtx(state, a) != "derivation") return true;
/* Remove spurious duplicates (e.g., an attribute set like
`rec { x = derivation {...}; y = x;}'. */
@@ -86,13 +140,13 @@ static bool getDerivation(EvalState & state, Expr e,
a = attrs->get(toATerm("name"));
/* !!! We really would like to have a decent back trace here. */
if (!a) throw TypeError("derivation name missing");
drv.name = evalString(state, a);
drv.name = evalStringNoCtx(state, a);
a = attrs->get(toATerm("system"));
if (!a)
drv.system = "unknown";
else
drv.system = evalString(state, a);
drv.system = evalStringNoCtx(state, a);
drv.attrs = attrs;
@@ -140,23 +194,38 @@ static void getDerivations(EvalState & state, Expr e,
if (matchAttrs(e, es)) {
ATermMap drvMap(ATgetLength(es));
queryAllAttrs(e, drvMap);
for (ATermMap::const_iterator i = drvMap.begin(); i != drvMap.end(); ++i) {
startNest(nest, lvlDebug,
format("evaluating attribute `%1%'") % aterm2String(i->key));
string pathPrefix2 = addToPath(pathPrefix, aterm2String(i->key));
if (getDerivation(state, i->value, pathPrefix2, drvs, doneExprs)) {
/* !!! undocumented hackery to support combining channels in
nix-env.cc. */
bool combineChannels = drvMap.get(toATerm("_combineChannels"));
/* Consider the attributes in sorted order to get more
deterministic behaviour in nix-env operations (e.g. when
there are names clashes between derivations, the derivation
bound to the attribute with the "lower" name should take
precedence). */
typedef std::map<string, Expr> AttrsSorted;
AttrsSorted attrsSorted;
foreach (ATermMap::const_iterator, i, drvMap)
attrsSorted[aterm2String(i->key)] = i->value;
foreach (AttrsSorted::iterator, i, attrsSorted) {
startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first);
string pathPrefix2 = addToPath(pathPrefix, i->first);
if (combineChannels)
getDerivations(state, i->second, pathPrefix2, autoArgs, drvs, doneExprs);
else if (getDerivation(state, i->second, pathPrefix2, drvs, doneExprs)) {
/* If the value of this attribute is itself an
attribute set, should we recurse into it? => Only
if it has a `recurseForDerivations = true'
attribute. */
ATermList es;
Expr e = evalExpr(state, i->value);
Expr e = evalExpr(state, i->second), e2;
if (matchAttrs(e, es)) {
ATermMap attrs(ATgetLength(es));
queryAllAttrs(e, attrs, false);
Expr e2 = attrs.get(toATerm("recurseForDerivations"));
if (e2 && evalBool(state, e2))
if (((e2 = attrs.get(toATerm("recurseForDerivations")))
&& evalBool(state, e2)))
getDerivations(state, e, pathPrefix2, autoArgs, drvs, doneExprs);
}
}

View File

@@ -12,7 +12,16 @@
namespace nix {
typedef std::map<string, string> MetaInfo;
struct MetaValue
{
enum { tpNone, tpString, tpStrings, tpInt } type;
string stringValue;
Strings stringValues;
int intValue;
};
typedef std::map<string, MetaValue> MetaInfo;
struct DrvInfo
@@ -26,11 +35,15 @@ public:
string attrPath; /* path towards the derivation */
string system;
/* !!! these should really be hidden, and setMetaInfo() should
make a copy since the ATermMap can be shared between multiple
DrvInfos. */
boost::shared_ptr<ATermMap> attrs;
string queryDrvPath(EvalState & state) const;
string queryOutPath(EvalState & state) const;
MetaInfo queryMetaInfo(EvalState & state) const;
MetaValue queryMetaInfo(EvalState & state, const string & name) const;
void setDrvPath(const string & s)
{
@@ -41,6 +54,8 @@ public:
{
outPath = s;
}
void setMetaInfo(const MetaInfo & meta);
};

View File

@@ -4,6 +4,7 @@
%x STRING
%x IND_STRING
%{
@@ -64,7 +65,7 @@ static Expr unescapeStr(const char * s)
}
else t += c;
}
return makeStr(toATerm(t));
return makeStr(toATerm(t), ATempty);
}
@@ -94,6 +95,7 @@ let { return LET; }
in { return IN; }
rec { return REC; }
inherit { return INHERIT; }
\.\.\. { return ELLIPSIS; }
\=\= { return EQ; }
\!\= { return NEQ; }
@@ -122,6 +124,30 @@ inherit { return INHERIT; }
<STRING>\" { BEGIN(INITIAL); return '"'; }
<STRING>. return yytext[0]; /* just in case: shouldn't be reached */
\'\'(\ *\n)? { BEGIN(IND_STRING); return IND_STRING_OPEN; }
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
yylval->t = makeIndStr(toATerm(yytext));
return IND_STR;
}
<IND_STRING>\'\'\$ {
yylval->t = makeIndStr(toATerm("$"));
return IND_STR;
}
<IND_STRING>\'\'\' {
yylval->t = makeIndStr(toATerm("''"));
return IND_STR;
}
<IND_STRING>\'\'\\. {
yylval->t = unescapeStr(yytext + 2);
return IND_STR;
}
<IND_STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
<IND_STRING>\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; }
<IND_STRING>\' {
yylval->t = makeIndStr(toATerm("'"));
return IND_STR;
}
<IND_STRING>. return yytext[0]; /* just in case: shouldn't be reached */
{PATH} { yylval->t = toATerm(yytext); return PATH; /* !!! alloc */ }
{URI} { yylval->t = toATerm(yytext); return URI; /* !!! alloc */ }
@@ -148,4 +174,10 @@ void backToString(yyscan_t scanner)
BEGIN(STRING);
}
void backToIndString(yyscan_t scanner)
{
struct yyguts_t * yyg = (struct yyguts_t *) scanner;
BEGIN(IND_STRING);
}
}

View File

@@ -92,25 +92,6 @@ int compareVersions(const string & v1, const string & v2)
}
static void testCompareVersions()
{
#define TEST(v1, v2, n) assert( \
compareVersions(v1, v2) == n && compareVersions(v2, v1) == -n)
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
}
DrvNames drvNamesFromArgs(const Strings & opArgs)
{
DrvNames result;

View File

@@ -1,10 +1,13 @@
%% Note: this SDF grammar is no longer used in the Nix expression
%% parser and may not be up to date.
definition
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top level syntax.
module Nix
module Main
imports Nix-Exprs Nix-Layout
@@ -38,6 +41,7 @@ exports
"with" Expr ";" Expr -> Expr {cons("With")}
"rec" "{" Bind* "}" -> Expr {cons("Rec")}
"let" Bind* "in" Expr -> Expr {cons("Let")}
"let" "{" Bind* "}" -> Expr {cons("LetRec")}
"{" Bind* "}" -> Expr {cons("Attrs")}
@@ -102,7 +106,8 @@ exports
[0-9]+ -> Int
"\"" ~[\n\"]* "\"" -> Str
"\"" (~[\"\\] | ("\\" ~[]) )* "\"" -> Str
"''" (~[\"\\] | ("\\" ~[]) )* "''" -> Str
[a-zA-Z0-9\.\_\-\+]* ("/"[a-zA-Z0-9\.\_\-\+]+)+ -> Path

View File

@@ -3,8 +3,7 @@ init initNixExprHelpers
Pos | string int int | Pos |
NoPos | | Pos |
Function | ATermList Expr Pos | Expr |
Function1 | string Expr Pos | Expr |
Function | Pattern Expr Pos | Expr |
Assert | Expr Expr Pos | Expr |
With | Expr Expr Pos | Expr |
If | Expr Expr Expr | Expr |
@@ -24,9 +23,41 @@ Call | Expr Expr | Expr |
Select | Expr string | Expr |
Var | string | Expr |
Int | int | Expr |
Str | string | Expr |
# Strings in the evaluator carry a so-called `context' (the ATermList)
# which is a list of strings representing store paths. This is to
# allow users to write things like
#
# "--with-freetype2-library=" + freetype + "/lib"
#
# where `freetype' is a derivation (or a source to be copied to the
# store). If we just concatenated the strings without keeping track
# of the referenced store paths, then if the string is used as a
# derivation attribute, the derivation will not have the correct
# dependencies in its inputDrvs and inputSrcs.
#
# The semantics of the context is as follows: when a string with
# context C is used as a derivation attribute, then the derivations in
# C will be added to the inputDrvs of the derivation, and the other
# store paths in C will be added to the inputSrcs of the derivations.
#
# For canonicity, the store paths should be in sorted order.
Str | string ATermList | Expr |
Str | string | Expr | ObsoleteStr
# Internal to the parser, doesn't occur in ASTs.
IndStr | string | Expr |
# A path is a reference to a file system object that is to be copied
# to the Nix store when used as a derivation attribute. When it is
# concatenated to a string (i.e., `str + path'), it is also copied and
# the resulting store path is concatenated to the string (with the
# store path in the context). If a string or path is concatenated to
# a path (i.e., `path + str' or `path + path'), the result is a new
# path (if the right-hand side is a string, the context must be
# empty).
Path | string | Expr |
Uri | string | Expr |
List | ATermList | Expr |
BlackHole | | Expr |
Undefined | | Expr |
@@ -35,26 +66,27 @@ PrimOp | int ATermBlob ATermList | Expr |
Attrs | ATermList | Expr |
Closed | Expr | Expr |
Rec | ATermList ATermList | Expr |
Bool | ATerm | Expr |
Bool | ATermBool | Expr |
Null | | Expr |
Context | ATermList Expr | Expr |
Bind | string Expr Pos | ATerm |
Bind | string Expr | ATerm | Bind2
BindAttrPath | ATermList Expr Pos | ATerm | # desugared during parsing
Bind | string Expr | ATerm | ObsoleteBind
Inherit | Expr ATermList Pos | ATerm |
Scope | | Expr |
Formal | string ValidValues DefaultValue | ATerm |
VarPat | string | Pattern |
AttrsPat | ATermList ATermBool | Pattern | # bool = `...'
AtPat | Pattern Pattern | Pattern |
ValidValues | ATermList | ValidValues |
UnrestrictedValues | | ValidValues |
Formal | string DefaultValue | ATerm |
DefaultValue | Expr | DefaultValue |
NoDefaultValue | | DefaultValue |
True | | ATerm |
False | | ATerm |
True | | ATermBool |
False | | ATermBool |
PrimOpDef | int ATermBlob | ATerm |
@@ -62,3 +94,4 @@ AttrRHS | Expr Pos | ATerm |
eTrue = makeBool(makeTrue())
eFalse = makeBool(makeFalse())
sOverrides = toATerm("__overrides")

View File

@@ -6,6 +6,8 @@
#include "nixexpr-ast.hh"
#include "nixexpr-ast.cc"
#include <cstdlib>
namespace nix {
@@ -17,7 +19,7 @@ string showPos(ATerm pos)
if (matchNoPos(pos)) return "undefined position";
if (!matchPos(pos, path, line, column))
throw badTerm("position expected", pos);
return (format("`%1%', line %2%") % aterm2String(path) % line).str();
return (format("`%1%:%2%:%3%'") % aterm2String(path) % line % column).str();
}
@@ -54,7 +56,7 @@ void queryAllAttrs(Expr e, ATermMap & attrs, bool withPos)
{
ATermList bnds;
if (!matchAttrs(e, bnds))
throw TypeError("attribute set expected");
throw TypeError(format("value is %1% while an attribute set was expected") % showType(e));
for (ATermIterator i(bnds); i; ++i) {
ATerm name;
@@ -77,7 +79,7 @@ Expr queryAttr(Expr e, const string & name, ATerm & pos)
{
ATermList bnds;
if (!matchAttrs(e, bnds))
throw TypeError("attribute set expected");
throw TypeError(format("value is %1% while an attribute set was expected") % showType(e));
for (ATermIterator i(bnds); i; ++i) {
ATerm name2, pos2;
@@ -108,6 +110,31 @@ Expr makeAttrs(const ATermMap & attrs)
}
static void varsBoundByPattern(ATermMap & map, Pattern pat)
{
ATerm name;
ATermList formals;
Pattern pat1, pat2;
ATermBool ellipsis;
/* Use makeRemoved() so that it can be used directly in
substitute(). */
if (matchVarPat(pat, name))
map.set(name, makeRemoved());
else if (matchAttrsPat(pat, formals, ellipsis)) {
for (ATermIterator i(formals); i; ++i) {
ATerm d1;
if (!matchFormal(*i, name, d1)) abort();
map.set(name, makeRemoved());
}
}
else if (matchAtPat(pat, pat1, pat2)) {
varsBoundByPattern(map, pat1);
varsBoundByPattern(map, pat2);
}
else abort();
}
Expr substitute(const Substitution & subs, Expr e)
{
checkInterrupt();
@@ -133,27 +160,17 @@ Expr substitute(const Substitution & subs, Expr e)
/* In case of a function, filter out all variables bound by this
function. */
ATermList formals;
Pattern pat;
ATerm body;
if (matchFunction(e, formals, body, pos)) {
ATermMap map(ATgetLength(formals));
for (ATermIterator i(formals); i; ++i) {
ATerm d1, d2;
if (!matchFormal(*i, name, d1, d2)) abort();
map.set(name, makeRemoved());
}
if (matchFunction(e, pat, body, pos)) {
ATermMap map(16);
varsBoundByPattern(map, pat);
Substitution subs2(&subs, &map);
return makeFunction(
(ATermList) substitute(subs2, (ATerm) formals),
(Pattern) substitute(subs2, (Expr) pat),
substitute(subs2, body), pos);
}
if (matchFunction1(e, name, body, pos)) {
ATermMap map(1);
map.set(name, makeRemoved());
return makeFunction1(name, substitute(Substitution(&subs, &map), body), pos);
}
/* Idem for a mutually recursive attribute set. */
ATermList rbnds, nrbnds;
if (matchRec(e, rbnds, nrbnds)) {
@@ -211,38 +228,25 @@ static void checkVarDefs2(set<Expr> & done, const ATermMap & defs, Expr e)
done.insert(e);
ATerm name, pos, value;
ATermList formals;
ATerm with, body;
ATermList rbnds, nrbnds;
Pattern pat;
if (matchVar(e, name)) {
/* Closed terms don't have free variables, so we don't have to
check by definition. */
if (matchClosed(e, value)) return;
else if (matchVar(e, name)) {
if (!defs.get(name))
throw EvalError(format("undefined variable `%1%'")
% aterm2String(name));
}
else if (matchFunction(e, formals, body, pos)) {
else if (matchFunction(e, pat, body, pos)) {
ATermMap defs2(defs);
for (ATermIterator i(formals); i; ++i) {
ATerm d1, d2;
if (!matchFormal(*i, name, d1, d2)) abort();
defs2.set(name, (ATerm) ATempty);
}
for (ATermIterator i(formals); i; ++i) {
ATerm valids, deflt;
set<Expr> done2;
if (!matchFormal(*i, name, valids, deflt)) abort();
checkVarDefs2(done, defs, valids);
checkVarDefs2(done2, defs2, deflt);
}
set<Expr> done2;
checkVarDefs2(done2, defs2, body);
}
else if (matchFunction1(e, name, body, pos)) {
ATermMap defs2(defs);
defs2.set(name, (ATerm) ATempty);
varsBoundByPattern(defs2, pat);
set<Expr> done2;
checkVarDefs2(done2, defs2, pat);
checkVarDefs2(done2, defs2, body);
}
@@ -287,41 +291,102 @@ void checkVarDefs(const ATermMap & defs, Expr e)
}
struct Canonicalise : TermFun
{
ATerm operator () (ATerm e)
{
/* Remove position info. */
ATerm path;
int line, column;
if (matchPos(e, path, line, column))
return makeNoPos();
/* Sort attribute sets. */
ATermList _;
if (matchAttrs(e, _)) {
ATermMap attrs;
queryAllAttrs(e, attrs);
StringSet names;
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
names.insert(aterm2String(i->key));
ATermList attrs2 = ATempty;
for (StringSet::reverse_iterator i = names.rbegin(); i != names.rend(); ++i)
attrs2 = ATinsert(attrs2,
makeBind(toATerm(*i), attrs.get(toATerm(*i)), makeNoPos()));
return makeAttrs(attrs2);
}
return e;
}
};
Expr canonicaliseExpr(Expr e)
{
Canonicalise canonicalise;
return bottomupRewrite(canonicalise, e);
}
Expr makeBool(bool b)
{
return b ? eTrue : eFalse;
}
bool matchStr(Expr e, string & s, PathSet & context)
{
ATermList l;
ATerm s_;
if (!matchStr(e, s_, l)) return false;
s = aterm2String(s_);
for (ATermIterator i(l); i; ++i)
context.insert(aterm2String(*i));
return true;
}
Expr makeStr(const string & s, const PathSet & context)
{
return makeStr(toATerm(s), toATermList(context));
}
string showType(Expr e)
{
ATerm t1, t2, t3;
ATerm t1, t2;
ATermList l1;
ATermBlob b1;
int i1;
if (matchStr(e, t1)) return "a string";
Pattern p1;
if (matchStr(e, t1, l1)) return "a string";
if (matchPath(e, t1)) return "a path";
if (matchUri(e, t1)) return "a path";
if (matchNull(e)) return "null";
if (matchInt(e, i1)) return "an integer";
if (matchBool(e, t1)) return "a boolean";
if (matchFunction(e, l1, t1, t2)) return "a function";
if (matchFunction1(e, t1, t2, t3)) return "a function";
if (matchFunction(e, p1, t1, t2)) return "a function";
if (matchAttrs(e, l1)) return "an attribute set";
if (matchList(e, l1)) return "a list";
if (matchPrimOp(e, i1, b1, l1)) return "a partially applied built-in function";
if (matchContext(e, l1, t1)) return "a context containing " + showType(t1);
return "an unknown type";
}
string showValue(Expr e)
{
ATerm s;
PathSet context;
string s;
ATerm s2;
int i;
if (matchStr(e, s)) {
string t = aterm2String(s), u;
for (string::iterator i = t.begin(); i != t.end(); ++i)
if (matchStr(e, s, context)) {
string u;
for (string::iterator i = s.begin(); i != s.end(); ++i)
if (*i == '\"' || *i == '\\') u += "\\" + *i;
else if (*i == '\n') u += "\\n";
else if (*i == '\r') u += "\\r";
@@ -329,8 +394,7 @@ string showValue(Expr e)
else u += *i;
return "\"" + u + "\"";
}
if (matchPath(e, s)) return aterm2String(s);
if (matchUri(e, s)) return aterm2String(s);
if (matchPath(e, s2)) return aterm2String(s2);
if (matchNull(e)) return "null";
if (matchInt(e, i)) return (format("%1%") % i).str();
if (e == eTrue) return "true";

View File

@@ -11,7 +11,9 @@ namespace nix {
MakeError(EvalError, Error)
MakeError(ParseError, Error)
MakeError(AssertionError, EvalError)
MakeError(ThrownError, AssertionError)
MakeError(Abort, EvalError)
MakeError(TypeError, EvalError)
@@ -20,11 +22,10 @@ MakeError(TypeError, EvalError)
property of the ATerm library allows us to implement caching of
normals forms efficiently. */
typedef ATerm Expr;
typedef ATerm DefaultValue;
typedef ATerm ValidValues;
typedef ATerm Pos;
typedef ATerm Pattern;
typedef ATerm ATermBool;
/* A STL vector of ATerms. Should be used with great care since it's
@@ -71,6 +72,7 @@ struct TermFun
};
ATerm bottomupRewrite(TermFun & f, ATerm e);
/* Query all attributes in an attribute set expression. The
expression must be in normal form. */
void queryAllAttrs(Expr e, ATermMap & attrs, bool withPos = false);
@@ -83,16 +85,33 @@ Expr queryAttr(Expr e, const string & name, ATerm & pos);
/* Create an attribute set expression from an Attrs value. */
Expr makeAttrs(const ATermMap & attrs);
/* Perform a set of substitutions on an expression. */
Expr substitute(const Substitution & subs, Expr e);
/* Check whether all variables are defined in the given expression.
Throw an exception if this isn't the case. */
void checkVarDefs(const ATermMap & def, Expr e);
/* Canonicalise a Nix expression by sorting attributes and removing
location information. */
Expr canonicaliseExpr(Expr e);
/* Create an expression representing a boolean. */
Expr makeBool(bool b);
/* Manipulation of Str() nodes. Note: matchStr() does not clear
context! */
bool matchStr(Expr e, string & s, PathSet & context);
Expr makeStr(const string & s, const PathSet & context = PathSet());
/* Showing types, values. */
string showType(Expr e);
string showValue(Expr e);

View File

@@ -0,0 +1,64 @@
#include "eval.hh"
#include "util.hh"
#include "globals.hh"
#include "serialise.hh"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
namespace nix {
void EvalState::loadNormalForms()
{
// nixCacheFile = getEnv("NIX_CACHE_FILE", nixStateDir + "/reduce-cache");
nixCacheFile = getEnv("NIX_CACHE_FILE");
string loadFlag = getEnv("NIX_CACHE_FILE_LOAD", "1");
if(nixCacheFile == "" || loadFlag == "")
return;
if(!pathExists(nixCacheFile))
return;
printMsg(lvlInfo, format("Load cache: ..."));
try {
int fd = open(nixCacheFile.c_str(), O_RDONLY);
if (fd == -1)
throw SysError(format("opening file `%1%'") % nixCacheFile);
AutoCloseFD auto_fd = fd;
FdSource source = fd;
normalForms = readATermMap(source);
} catch (Error & e) {
e.addPrefix(format("Cannot load cached reduce operations from %1%:\n") % nixCacheFile);
throw;
}
printMsg(lvlInfo, format("Load cache: end"));
}
void EvalState::saveNormalForms()
{
string saveFlag = getEnv("NIX_CACHE_FILE_SAVE", "");
if(nixCacheFile == "" || saveFlag == "")
return;
printMsg(lvlInfo, format("Save cache: ..."));
try {
int fd = open(nixCacheFile.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (fd == -1)
throw SysError(format("opening file `%1%'") % nixCacheFile);
AutoCloseFD auto_fd = fd;
FdSink sink = fd;
writeATermMap(normalForms, sink);
} catch (Error & e) {
e.addPrefix(format("Cannot save cached reduce operations to %1%:\n") % nixCacheFile);
throw;
}
printMsg(lvlInfo, format("Save cache: end"));
}
}

Some files were not shown because too many files have changed in this diff Show More