Compare commits

..

319 Commits
sqlite ... 1.0

Author SHA1 Message Date
Eelco Dolstra
dfc6a43b72 Fix the install check 2012-05-11 23:30:47 -04:00
Eelco Dolstra
587b408210 Set release date 2012-05-11 17:40:58 -04:00
Eelco Dolstra
8a08813d6c Manual updates 2012-05-11 17:39:06 -04:00
Eelco Dolstra
2b00e6990c CSS tweaks 2012-05-11 16:21:21 -04:00
Eelco Dolstra
58d1de08d9 Use perl.libPrefix to (hopefully) fix the Cygwin build
http://hydra.nixos.org/build/2602599
2012-05-11 09:41:39 -04:00
Eelco Dolstra
37fa47908b Build Ubuntu 12.04 packages 2012-05-10 22:12:20 -04:00
Eelco Dolstra
4d383f57f4 Document "nix-build --run-env" 2012-05-10 19:29:36 -04:00
Eelco Dolstra
4f7bab7db1 Support building with the Perl XS bindings disabled
Since the Perl bindings require shared libraries, this is required on
platforms such as Cygwin where we do a static build.
2012-05-10 19:03:23 -04:00
Eelco Dolstra
6a7b24a3f2 Document "nix-store --add" 2012-05-10 18:09:45 -04:00
Eelco Dolstra
cda1fd8ec8 Remove an obsolete hack 2012-05-10 16:56:36 -04:00
Eelco Dolstra
663c06e8cd Disable building in chroot for Nix's corepkgs
The dependencies of the corepkgs are not necessarily in the chroot (or
in the Nix store), so don't build them in a chroot.
2012-05-09 22:14:36 -04:00
Eelco Dolstra
cb1248d208 Document some nix-store subcommands 2012-05-09 19:06:39 -04:00
Eelco Dolstra
7a213ffc69 Document $NIX_PATH / -I 2012-05-09 19:06:13 -04:00
Eelco Dolstra
a58efdb69b Update the release notes 2012-05-09 19:05:30 -04:00
Eelco Dolstra
0c4c8f7a9d Remove obsolete files (moved to release tree) 2012-05-08 15:43:54 -04:00
Eelco Dolstra
afa7b8a479 nix-channel --update: allow updating only the specified channels 2012-05-07 17:55:56 -04:00
Eelco Dolstra
147f10157f Now *really* prevent accumulation of old manifests 2012-05-07 17:23:26 -04:00
Eelco Dolstra
464089365e Fix some 32-bit builds
Perl on some 32-bit systems needs -D_FILE_OFFSET_BITS=64.  See also commit
02f1363e19.
2012-05-04 21:40:56 -04:00
Eelco Dolstra
c6acb219f9 Drop the Perl-specific CFLAGS
This fixes the Darwin build (http://hydra.nixos.org/build/2517380).
Hopefully it doesn't break other builds.
2012-05-04 18:50:34 -04:00
Eelco Dolstra
56c82f3d9d Don't build for old Debian/Ubuntu releases that don't have a sufficiently new SQLite 2012-05-04 17:45:21 -04:00
Eelco Dolstra
373e875ac2 Don't build for old Fedora releases that don't have a sufficiently new SQLite 2012-05-04 17:25:25 -04:00
Eelco Dolstra
d03a295192 Require SQLite >= 3.6.19
Nix needs SQLite's foreign key constraint feature, which was
introduced in 3.6.19.  Without it, the database won't be cleaned up
correctly when paths are deleted.  See
e.g. http://hydra.nixos.org/build/2494142.
2012-05-04 17:21:43 -04:00
Eelco Dolstra
e060c99447 Use mkpath instead of make_path
Perl <= 5.10 doesn't have make_path.  See
e.g. http://hydra.nixos.org/build/2493981.
2012-05-01 16:35:18 -04:00
Eelco Dolstra
e19fb7ebed Do "make installcheck" for RPM builds 2012-05-01 16:31:56 -04:00
Eelco Dolstra
e145ac30e3 Do "make installcheck" for Debian builds 2012-05-01 15:48:17 -04:00
Eelco Dolstra
db5b86ef13 * Add an option ‘build-use-substitutes’, which can be set to ‘false’
to disable use of substitutes; i.e., force building from source.
  Fixes Nix/221.
2012-04-30 19:15:34 -04:00
Eelco Dolstra
59a26360c7 Support mandatory system features in the build hook
Mandatory features are features that MUST be present in a derivation's
requiredSystemFeatures attribute.  One application is performance
testing, where we have a dedicated machine to run performance tests
(and nothing else).  Then we would add the label "perf" to the
machine's mandatory features and to the performance testing
derivations.
2012-04-30 17:22:45 -04:00
Eelco Dolstra
82ae0e688c Update the documentation of build-remote.pl 2012-04-30 16:49:00 -04:00
Eelco Dolstra
46cdc6ad51 Handle EPERM when creating a hard link for the chroot
There is a race condition when doing parallel builds with chroots and
the immutable bit enabled.  One process may call makeImmutable()
before the other has called link(), in which case link() will fail
with EPERM.  We could retry or wrap the operation in a lock, but since
this condition is rare and I'm lazy, we just use the existing copy
fallback.

Fixes #9.
2012-04-30 10:58:04 -04:00
Eelco Dolstra
c722193a91 Don't use the build hook for unpacking channels 2012-04-26 16:52:08 +02:00
Eelco Dolstra
6de5d53416 Fix a warning in the build hook about $progressViewer 2012-04-24 12:56:30 +02:00
Eelco Dolstra
6387830c3b Merge pull request #2 from viric/master
Again, adding the sync option
2012-04-23 03:29:03 -07:00
Eelco Dolstra
259c6d3fbb Fix URL set by nix-channel 2012-04-18 13:40:18 +02:00
Eelco Dolstra
9cd3ff1059 nix-instantiate: default to "default.nix" if no arguments are given 2012-04-17 17:19:43 +02:00
Eelco Dolstra
8745fade03 Added utility command ‘nix-instantiate --find-file’ to look up a file in Nix's search path 2012-04-17 17:14:14 +02:00
Eelco Dolstra
8cf1719e3e Hack to prevent accumulation of old manifests 2012-04-16 19:52:31 +02:00
Eelco Dolstra
1132dd27ea Fix obscure race condition in GC root creation
This should fix rare Hydra errors of the form:

error: symlinking `/nix/var/nix/gcroots/per-user/hydra/hydra-roots/7sfhs5fdmjxm8sqgcpd0pgcsmz1kq0l0-nixos-iso-0.1pre33785-33795' to `/nix/store/7sfhs5fdmjxm8sqgcpd0pgcsmz1kq0l0-nixos-iso-0.1pre33785-33795': File exists
2012-04-16 18:47:01 +02:00
Eelco Dolstra
154aa7f71a Set a few more close-on-exec flags 2012-04-15 00:42:16 +02:00
Eelco Dolstra
31e34fcf93 Close almost all file descriptors in the builder
This regression was accidentally introduced in
35355fc1fc.
2012-04-15 00:20:32 +02:00
Eelco Dolstra
0b5107c016 If the (redirected) channel URL contains a version number, use it 2012-04-14 21:05:28 +02:00
Eelco Dolstra
1d0bafb74d Follow redirects early to ensure consistency between the manifest and the tarball
Without this change, if the URL is a redirect that changes in between,
we can get a manifest that doesn't match the tarball.
2012-04-14 21:04:22 +02:00
Eelco Dolstra
ca3d9f8b31 Urgh, modified the wrong file... 2012-04-14 19:52:58 +02:00
Eelco Dolstra
ef902274fd Remove unnecessary "system" argument 2012-04-14 18:48:11 +02:00
Eelco Dolstra
e855c7e2c9 nix-channel improvements
"nix-channel --add" now accepts a second argument: the channel name.
This allows channels to have a nicer name than (say) nixpkgs_unstable.
If no name is given, it defaults to the last component of the URL
(with "-unstable" or "-stable" removed).

Also, channels are now stored in a profile
(/nix/var/nix/profiles/per-user/$USER/channels).  One advantage of
this is that it allows rollbacks (e.g. if "nix-channel --update" gives
an undesirable update).
2012-04-14 18:38:52 +02:00
Eelco Dolstra
969a14599d If "pv" is available at compile time, hard-code its path 2012-04-13 14:41:33 +02:00
Shea Levy
34a85c5405 nix-copy-closure: Move the progressViewer directly adjacent to the ssh call so that network progress is what's measured 2012-04-13 14:29:12 +02:00
Shea Levy
055e803851 Add the '--show-progress' flag to nix-copy-closure 2012-04-13 14:29:12 +02:00
Eelco Dolstra
00c98a6bef Use Bison 2.5 2012-04-13 14:28:26 +02:00
Eelco Dolstra
209927bb27 Unconfuse Rob 2012-04-10 16:40:51 +02:00
Eelco Dolstra
1fb30e6d50 Handle the case where $SHELL is not set 2012-04-10 13:52:37 +02:00
Rob Vermaas
8f6146a7bc Merge pull request #5 from shlevy/doc-fix
Nix is on github now
2012-04-09 00:24:08 -07:00
Shea Levy
242a99c95a Nix is on github now 2012-04-08 23:59:02 -04:00
Eelco Dolstra
533250a4a3 Fix building from the tarball 2012-04-06 22:54:15 +02:00
Eelco Dolstra
831c7aa410 Documentation fix 2012-04-06 22:03:19 +02:00
Eelco Dolstra
5863987bba Include environment variables in the manpages 2012-04-06 21:56:20 +02:00
Eelco Dolstra
998b977ede Include common options in the manpages using some XInclude hackery 2012-04-06 21:45:00 +02:00
Eelco Dolstra
d49ef039dd Update affiliation 2012-04-06 21:43:56 +02:00
Eelco Dolstra
5a6d50998d Add a missing DocBook source file to the tarball
Reported on IRC by Adrian Siekierka.
2012-04-06 20:26:30 +02:00
Eelco Dolstra
f2467eb6a0 On Linux, pretend we're building on Linux 2.6
Setting the UNAME26 personality causes "uname" to return "2.6.x",
regardless of the kernel version.  This improves determinism in
a few misbehaved packages.
2012-04-05 13:03:19 +02:00
Hydra mirror
3b859ead37 nix-generate-patches: Optionally write new patches to $NIX_ALL_PATCHES 2012-04-04 20:46:18 +00:00
Eelco Dolstra
34ea91b259 Include --keep-going in --help 2012-04-04 16:22:32 +02:00
Eelco Dolstra
0837348049 Follow redirects when checking for the existence of MANIFEST.bz2
If we don't follow redirects, we might think that MANIFEST.bz2 exists
just because the HEAD request succeeds on the redirector URI.
2012-04-04 15:41:35 +02:00
Eelco Dolstra
b8fb0ce563 Update "nix-build --help" 2012-03-27 11:59:36 +02:00
Eelco Dolstra
5144abe5b6 Add an option "--exclude" to filter dependencies in "nix-build --run-env"
Sometimes when doing "nix-build --run-env" you don't want all
dependencies to be built.  For instance, if we want to do "--run-env"
on the "build" attribute in Hydra's release.nix (to get Hydra's build
environment), we don't want its "tarball" dependency to be built.  So
we can do:

  $ nix-build --run-env release.nix -A build --exclude 'hydra-tarball'

This will skip the dependency whose name matches the "hydra-tarball"
regular expression.  The "--exclude" option can be repeated any number
of times.
2012-03-27 11:40:47 +02:00
Eelco Dolstra
3e94ffffd6 Allow the command executed by "nix-build --run-env" to be overriden with --command 2012-03-27 11:16:43 +02:00
Eelco Dolstra
446b827bae Mac OS X fix 2012-03-26 23:18:36 +02:00
Eelco Dolstra
480dda0e42 Delete non-directory valid paths right away
It's unlikely that rename() is faster than unlink() on a regular file
or symlink, so don't bother.
2012-03-26 20:56:30 +02:00
Eelco Dolstra
117670be57 Make the garbage collector more concurrent
Make the garbage collector more concurrent by deleting valid paths
outside the region where we're holding the global GC lock.  This
should greatly reduce the time during which new builds are blocked,
since the deletion accounts for the vast majority of the time spent in
the GC.

To ensure that this is safe, the valid paths are invalidated and
renamed to some arbitrary path while we're holding the lock.  This
ensures that we when we finally delete the path, it's not a (newly)
valid or locked path.
2012-03-26 20:43:33 +02:00
Eelco Dolstra
8be1979f1a Remove the --max-links GC option
We don't need this anymore now that current filesystems support more
than 32,000 files in a directory.
2012-03-26 20:00:02 +02:00
Lluís Batlle i Rossell
85799bf89e Fixing the default of sync-before-registering
Setting 'false' as default, as suggested by Eelco.

I also added a comment about the setting in the code.
2012-03-22 20:05:54 +01:00
Lluís Batlle i Rossell
25de80e2b6 Adding a nix option to sync before registering a path, for non-ext*
filesystems.
2012-03-22 19:57:42 +01:00
Eelco Dolstra
19d9762ad5 nix-store --clear-failed-paths: Clear derivation outputs
If the argument to ‘nix-store --clear-failed-paths’ is a derivation,
then clear the failed state of its outputs.
2012-03-20 18:23:26 +01:00
Eelco Dolstra
cb79e91ec3 Fix the coverage build 2012-03-19 17:05:42 +01:00
Eelco Dolstra
457dd55962 Fix the Deb builds 2012-03-19 15:11:22 +01:00
Eelco Dolstra
4b83483142 Fix the RPM 2012-03-19 14:30:59 +01:00
Eelco Dolstra
7f38087f35 Add a command "nix-build --run-env" to reproduce the environment of a derivation
This command builds or fetches all dependencies of the given
derivation, then starts a shell with the environment variables from
the derivation.  This shell also sources $stdenv/setup to initialise
the environment further.

The current directory is not changed.  Thus this is a convenient way
to reproduce a build environment in an existing working tree.

Existing environment variables are left untouched (unless the
derivation overrides them).  As a special hack, the original value of
$PATH is appended to the $PATH produced by $stdenv/setup.

Example session:

$ nix-build --run-env '<nixpkgs>' -A xterm
(the dependencies of xterm are built/fetched...)
$ tar xf $src
$ ./configure
$ make
$ emacs
(... hack source ...)
$ make
$ ./xterm
2012-03-19 04:14:21 +01:00
Eelco Dolstra
ea402a255f Replace "make check" with "make installcheck"
Ensuring that the tests work from the build tree requires a growing
number of nasty hacks.  The tests also don't verify that the installed
Nix actually works.  Thus, the tests now require "make install" to
have been run.
2012-03-19 01:20:02 +01:00
Eelco Dolstra
4b23900ff1 Fix the optional dependency on OpenSSL
http://hydra.nixos.org/build/2306540
2012-03-19 01:06:13 +01:00
Eelco Dolstra
b006a31d52 Drop the externals directory
Nix now requires SQLite and bzip2 to be pre-installed.  SQLite is
detected using pkg-config.  We required DBD::SQLite anyway, so
depending on SQLite is not a big problem.

The --with-bzip2, --with-openssl and --with-sqlite flags are gone.
2012-03-18 23:54:57 +01:00
Eelco Dolstra
2e0322efd1 Clean up when building from a working tree 2012-03-18 22:10:59 +01:00
Eelco Dolstra
bd50c01972 Ensure that Perl processes delete their entry in the temproots directory
By moving the destructor object to libstore.so, it's also run when
download-using-manifests and nix-prefetch-url exit.  This prevents
them from cluttering /nix/var/nix/temproots with stale files.
2012-03-13 17:07:49 +01:00
Eelco Dolstra
b461721f17 Fix tests 2012-03-12 21:41:45 +01:00
Eelco Dolstra
005d1e4ccb Update bzip2 dependency 2012-03-06 20:03:20 +01:00
Eelco Dolstra
605b16cd7b Fix compilation on FreeBSD
http://hydra.nixos.org/build/2213576

Not sure why compilation doesn't fail on other platforms...
2012-03-05 22:04:40 +01:00
Eelco Dolstra
d645633643 nix-copy-closure: don't print copied path on stdout
We're already printing progress on stderr, so printing them on stdout
afterwards is kind of useless.
2012-03-05 20:52:24 +01:00
Eelco Dolstra
35355fc1fc Set the close-on-exec flag on file descriptors 2012-03-05 20:29:00 +01:00
Eelco Dolstra
7b22bec252 Don't leak a file descriptor in commonChildInit() 2012-03-05 20:28:09 +01:00
Eelco Dolstra
1d487dc6a6 nix-worker: put the pid of the caller in argv[1]
This is useful for debugging.
2012-03-05 19:19:29 +01:00
Eelco Dolstra
2b4964f319 Restore progress indication during nix-copy-closure 2012-03-05 18:13:44 +01:00
Eelco Dolstra
56042a120a build-remote.pl: don't wait forever for the upload lock
In the build hook, don't wait forever to get the upload lock.  This
ensures progress if another process gets stuck while holding the
upload lock.
2012-03-05 17:58:09 +01:00
Eelco Dolstra
8afd28a922 Remove dependency on sqlite3_table_column_metadata
Not all SQLite builds have the function sqlite3_table_column_metadata.
We were only using it in a schema upgrade check for compatibility with
databases that were probably never seen in the wild.  So remove it.
2012-03-01 16:06:49 +01:00
Eelco Dolstra
1c94524458 Fix an uninitialised variable
The variable ‘useChroot’ was not initialised properly.  This caused
random failures if using the build hook.  Seen on Mac OS X 10.7 with Clang.
Thanks to KolibriFX for finding this :-)
2012-03-01 16:06:49 +01:00
Eelco Dolstra
6fe13e6aba Fix chroots builds
Chroots are initialised by hard-linking inputs from the Nix store to
the chroot.  This doesn't work if the input has its immutable bit set,
because it's forbidden to create hard links to immutable files.  So
temporarily clear the immutable bit when creating and destroying the
chroot.

Note that making regular files in the Nix store immutable isn't very
reliable, since the bit can easily become cleared: for instance, if we
run the garbage collector after running ‘nix-store --optimise’.  So
maybe we should only make directories immutable.
2012-02-18 01:23:52 +01:00
Eelco Dolstra
bd013b6f98 On Linux, make the Nix store really read-only by using the immutable bit
I was bitten one time too many by Python modifying the Nix store by
creating *.pyc files when run as root.  On Linux, we can prevent this
by setting the immutable bit on files and directories (as in ‘chattr
+i’).  This isn't supported by all filesystems, so it's not an error
if setting the bit fails.  The immutable bit is cleared by the garbage
collector before deleting a path.  The only tricky aspect is in
optimiseStore(), since it's forbidden to create hard links to an
immutable file.  Thus optimiseStore() temporarily clears the immutable
bit before creating the link.
2012-02-15 01:31:56 +01:00
Eelco Dolstra
5e57047d87 Fix a broken guard around utime()
Because of an outdated check for a timestamp of 0, we were calling
utime() even when it wasn't necessary.
2012-02-15 01:00:30 +01:00
Eelco Dolstra
58ac7a17a4 Don't use deletePath() to delete a single file 2012-02-15 00:28:01 +01:00
Eelco Dolstra
e9fc91df45 Fix error message
This fixes the error message

  error: file `' was not found in the Nix search path (add it using $NIX_PATH or -I)
2012-02-09 18:56:48 +01:00
Eelco Dolstra
d5a5a83ad4 Use data() instead of c_str() where appropriate 2012-02-09 18:27:45 +01:00
Eelco Dolstra
ec2827f5fc Update .gitignore 2012-02-08 19:25:43 +01:00
Eelco Dolstra
4055a3b19c Remove empty ChangeLog file 2012-02-08 13:22:08 +01:00
Eelco Dolstra
fb95455c02 Set the versionSuffix to include the Git shortrev 2012-02-08 12:31:14 +01:00
Eelco Dolstra
67444f5e54 * Build Nix for the latest Fedora and Ubuntu releases (and drop some
old ones).
2012-02-07 13:18:20 +00:00
Eelco Dolstra
f491ae97d4 * Inline some functions and get rid of the indirection through
EvalState::eval().  This gives a 12% speedup on ‘nix-instantiate
  /etc/nixos/nixos/ -A system --readonly-mode’ (from 1.01s to 0.89s).
2012-02-04 13:50:25 +00:00
Eelco Dolstra
2bda12ef3b * Print elapsed evaluation time. 2012-02-04 13:27:11 +00:00
Eelco Dolstra
ce86a9a0ae * nix-channel: fail if we don't have write permission to the manifests
directory.  Previously in this situation we did add the Nix
  expressions from the channel to allow installation from source, but
  this doesn't work for binary-only channels and leads to confusing
  error messages.
2012-02-02 12:25:56 +00:00
Eelco Dolstra
baa0501cc1 * Fix importing a derivation. This gave a segfault. 2012-01-26 13:13:00 +00:00
Eelco Dolstra
4c9fdd2cd6 * Add a test for importing derivations. 2012-01-26 13:04:50 +00:00
Eelco Dolstra
330df4b4db * Allow comparisons between derivations by comparing the outPath
attributes.
2012-01-19 23:08:47 +00:00
Eelco Dolstra
18047d4625 * Add some debug output to print the derivation name once it's known.
This makes it easier to pinpoint the source of a crash.
2012-01-19 23:07:42 +00:00
Eelco Dolstra
126c7317bc * Add a test case for comparing derivations. 2012-01-19 22:10:24 +00:00
Eelco Dolstra
ddd0ce534a * Don't distribute Store.cc, it's generated automatically by xsubpp. 2012-01-18 16:43:48 +00:00
Eelco Dolstra
02f1363e19 * Pass the appropriate flags to GCC when building the Perl bindings.
Without these, Nix fails on 32-bit Linux with Perl 5.14, with a
  rather unhelpful error message:

    Not a CODE reference at /nix/store/n6kpbacn6nn7i3i735v8j3di8aqyl07v-perl-5.14.2/lib/perl5/5.14.2/i686-linux-thread-multi/DynaLoader.pm

  This is likely because the lack of -D_FILE_OFFSET_BITS=64 causes
  various Perl structures to not match what the Perl interpreter
  expects.
2012-01-18 16:39:54 +00:00
Eelco Dolstra
4e624849b6 * Added a command ‘nix-store --print-env $drvpath’ that prints out the
environment of the given derivation in a format that can be sourced
  by the shell, e.g.

  $ eval "$(nix-store --print-env $(nix-instantiate /etc/nixos/nixpkgs -A pkg))"
  $ NIX_BUILD_TOP=/tmp
  $ source $stdenv/setup

  This is especially useful to reproduce the environment used to build
  a package outside of its builder for development purposes.

  TODO: add a nix-build option to do the above and fetch the
  dependencies of the derivation as well.
2012-01-17 23:07:22 +00:00
Eelco Dolstra
2a3f4110c5 * nix-build: put the temporary derivation symlink in a temporary
directory rather than the current directory.
* nix-build: --drv-link now implies --add-drv-link.
2012-01-13 23:35:07 +00:00
Eelco Dolstra
7ae763e16b * ‘-module’ causes the generated library to have an .so extension on
Mac OS X instead of .dylib, so don't do that.
2012-01-12 14:16:25 +00:00
Ludovic Courtès
6245f0d529 tests: Run `download-using-manifests' via libtool so that dlopening works. 2012-01-11 16:58:49 +00:00
Ludovic Courtès
c5d9ccd810 perl: Build libNixStore.la with `-module'. 2012-01-11 16:44:42 +00:00
Eelco Dolstra
f86fca9b70 * Figure out the extension of dynamic libraries; don't hard-code .so. 2012-01-11 15:41:42 +00:00
Eelco Dolstra
9fe24c5a0d * Don't create thunks for simple constants (integers, strings, paths)
and allocate them only once.
* Move Value and related functions into value.hh.
2012-01-07 17:26:33 +00:00
Eelco Dolstra
d4e6b9f2d6 * Doh! 2012-01-05 21:07:12 +00:00
Eelco Dolstra
a7366a764a * Add a -I flag to the Perl bindings to nix-build and some other
scripts.
* Include the version and architecture in the -I flag so that there is
  at least a chance that a Nix binary built for one Perl version will
  run on another version.
2012-01-05 20:33:46 +00:00
Eelco Dolstra
b52966e821 * Remove dead code. 2012-01-04 21:47:48 +00:00
Eelco Dolstra
35f2a6ba82 * Don't use dynamic_cast, it's very slow. "nix-instantiate
/etc/nixos/nixos -A system" spent about 10% of its time in
  dynamic_cast.
2012-01-04 21:24:11 +00:00
Eelco Dolstra
adaf64a99b * Merge the multiple-outputs-sandbox branch (svn merge --reintegrate
^/nix/branches/multiple-outputs-sandbox).  Multiple output support
  still isn't complete, but it wasn't complete in the trunk either, so
  it doesn't hurt.
2012-01-04 16:22:25 +00:00
Eelco Dolstra
9936da6b54 * Check whether the outputName attribute works. 2012-01-04 12:45:53 +00:00
Eelco Dolstra
9d43a02382 * Let --disable-gc work. 2012-01-04 12:45:40 +00:00
Eelco Dolstra
a0477a458f * currentOutput -> outputName. "current" implies some temporal
aspect.
2012-01-04 12:00:39 +00:00
Eelco Dolstra
b79b85ad76 * Export the original input attributes of the derivation in
‘drvAttrs’.  This will simplify the implementation of functions such
  as ‘overrideDerivation’ in Nixpkgs, which need to filter out any
  added attributes such as outPath.
2012-01-04 11:56:15 +00:00
Eelco Dolstra
83647f4ef1 * Simplify the implementation of "derivation" a bit: lift out the
common attribution so that they're evaluated only once, etc.  Note
  that the default output is now the first element of the "outputs"
  attribute, rather than the first element of the sorted list of
  outputs.  This seems more user-friendly.
2012-01-04 11:04:19 +00:00
Eelco Dolstra
71f3c46cf6 * Drop the inefficient "Path" suffix in output attribute names. 2012-01-03 15:27:18 +00:00
Eelco Dolstra
921111d197 * Move the implementation of the ‘derivation’ primop into a separate
file.
2012-01-03 14:01:47 +00:00
Eelco Dolstra
6c31232e14 * Sync with the trunk. 2012-01-03 12:59:31 +00:00
Eelco Dolstra
502d94048a * Ignore missing manifest symlinks. 2012-01-03 12:59:00 +00:00
Eelco Dolstra
63227d434c * FreeBSD tar defaults to the tape device instead of stdout. 2012-01-03 12:18:41 +00:00
Eelco Dolstra
9b7df1ef00 * Forgot to add. 2012-01-03 09:19:40 +00:00
Eelco Dolstra
39d45a6b09 * Add a test for nix-channel.
* Refactor the nix-channel unpacker a bit.
2012-01-03 01:51:38 +00:00
Eelco Dolstra
dadbb51d96 * Use Nix::Config. 2012-01-03 00:47:27 +00:00
Eelco Dolstra
48cea0d01e * Refactoring: Get rid of a few subdirectories in corepkgs/, and some
other simplifications.
* Use <nix/...> to locate the corepkgs.  This allows them to be
  overriden through $NIX_PATH.
* Use bash's pipefail option in the NAR builder so that we don't need
  to create a temporary file.
2012-01-03 00:16:29 +00:00
Eelco Dolstra
93e71e6ab6 * Follow our own coding conventions. 2011-12-30 17:39:03 +00:00
Eelco Dolstra
f2d65c9c80 * Remove a redundant dot (Nicolas Pierron). 2011-12-30 17:31:58 +00:00
Eelco Dolstra
93b56acb2d * Support multiple outputs in nix-store (specifically the ‘--query’
and ‘--realise’ actions).
2011-12-30 17:25:19 +00:00
Eelco Dolstra
a71d02440b * Oops. 2011-12-30 17:13:25 +00:00
Eelco Dolstra
6f5e3326ce * Move topoSortPaths() out of gc.cc. 2011-12-30 15:02:50 +00:00
Eelco Dolstra
b1004f40f7 * Reject a build if there is a cycle among the outputs. This is
necessary because existing code assumes that the references graph is
  acyclic.
2011-12-30 14:47:14 +00:00
Eelco Dolstra
ed11b17b2e * Fix doc error. 2011-12-30 13:43:29 +00:00
Eelco Dolstra
254b3399ba * Sync with the trunk. 2011-12-30 13:08:14 +00:00
Eelco Dolstra
8c42a8c8ff * Make sure that lock files are cleaned up properly when building
through the build hook.
2011-12-25 16:38:37 +00:00
Eelco Dolstra
524fa8a4f1 * Oops. 2011-12-22 16:27:03 +00:00
Eelco Dolstra
b33da599c5 * In the garbage collector, delete invalid paths before deleting
unreachable paths.  This matters when using --max-freed etc.:
  unreachable paths could become reachable again, so it's nicer to
  keep them if there is "real" garbage to be deleted.  Also, don't use
  readDirectory() but read the Nix store and delete invalid paths in
  parallel.  This reduces GC latency on very large Nix stores.
2011-12-22 15:55:53 +00:00
Eelco Dolstra
58d974336c * Drop unnecessary call to canonPath() (nixStore is already canonical). 2011-12-22 14:33:34 +00:00
Eelco Dolstra
66c99b0cf5 * ‘--disable-shared’ is no longer supported. Fortunately it's not
needed for the coverage analysis.
2011-12-22 10:58:27 +00:00
Eelco Dolstra
2aac7cd021 * Another case of lock file permissions being too liberal. 2011-12-21 19:17:45 +00:00
Eelco Dolstra
4d728bc3e6 * Security: make sure the lock files used by build-remote.pl are not
readable to other users.  Otherwise, any user can open the lock file
  for reading and lock it, thus DoSing the remote build mechanism.
2011-12-21 19:11:58 +00:00
Eelco Dolstra
69d6f0936a * Use a lock to ensure that only one build-remote instance can copy a
closure to a given machine at the same time.  This prevents the case
  where multiple instances try to copy the same missing store path to
  the target machine, which is very wasteful.
2011-12-21 18:59:25 +00:00
Eelco Dolstra
5679041132 * The ‘foo.drvPath’ feature was already broken in read-only mode.
Since it's rarely used and fixing it is too much work right now,
  just document it.
2011-12-21 18:19:05 +00:00
Shea Levy
f8e54b7874 Make the reference cycle in the cyclic outputs test indirect 2011-12-21 17:34:44 +00:00
Shea Levy
b4cee3f816 Revert previous commit
It doesn't detect indirect references
2011-12-21 17:31:34 +00:00
Shea Levy
f3c88f297d Detect and reject mutually-referential outputs
There is probably a more efficient way to do this.
2011-12-21 17:14:28 +00:00
Eelco Dolstra
b19a0f63db * Simplify the context handling logic. 2011-12-21 15:33:30 +00:00
Eelco Dolstra
4be5a2c096 * Add a test for unsafeDiscardOutputDependency. Not really related to
multiple outputs, but good to have anyway.
2011-12-21 14:42:06 +00:00
Eelco Dolstra
179409b911 * Add a test for referring to another derivation's ‘drvPath’. This
currently fails in read-only mode.
2011-12-21 13:47:21 +00:00
Eelco Dolstra
3877619888 * Add some accidentally committed files. 2011-12-21 11:47:52 +00:00
Eelco Dolstra
edd9359beb * Doing a GC after building a derivation with cyclic outputs currently
segfaults.
2011-12-20 17:10:39 +00:00
Eelco Dolstra
1f3b0ede7d * Add a (currently failing) test that checks whether mutually
recursive outputs are properly rejected.
* Add a (also failing) test for "nix-build -A <output-name>".
2011-12-20 17:08:43 +00:00
Eelco Dolstra
46e42c92c1 * Refactor a bit so that more tests can be added. 2011-12-20 17:01:02 +00:00
Eelco Dolstra
b5363810bb * Fix the build. 2011-12-20 16:37:01 +00:00
Eelco Dolstra
194d21f9f6 * Sync with the trunk. 2011-12-16 23:33:01 +00:00
Eelco Dolstra
273b288a7e * importPath() -> importPaths(). Because of buffering of the input
stream it's now necessary for the daemon to process the entire
  sequence of exported paths, rather than letting the client do it.
2011-12-16 22:31:25 +00:00
Eelco Dolstra
8d3dfa2c17 * Avoid expensive conversions from char arrays to STL strings. 2011-12-16 21:29:46 +00:00
Eelco Dolstra
e0bd307802 * Make the import operation through the daemon much more efficient
(way fewer roundtrips) by allowing the client to send data in bigger
  chunks.
* Some refactoring.
2011-12-16 19:44:13 +00:00
Eelco Dolstra
78598d06f0 * Clean up exception handling. 2011-12-16 15:45:42 +00:00
Eelco Dolstra
5a1b9ed0aa * Refactoring: move sink/source buffering into separate classes.
* Buffer the HashSink.  This speeds up hashing a bit because it
  prevents lots of calls to the hash update functions (e.g. nix-hash
  went from 9.3s to 8.7s of user time on the closure of my
  /var/run/current-system).
2011-12-15 16:19:53 +00:00
Eelco Dolstra
a67b8ae224 * Typo. 2011-12-15 14:04:35 +00:00
Eelco Dolstra
a3e0656cbb * Buffer reads in FdSource. Together with write buffering, this
significantly cuts down the number of syscalls (e.g., for "nix-store
  -qR /var/run/current-system" via the daemon, it reduced the number
  of syscalls in the client from 29134 to 4766 and in the daemon from
  44266 to 20666).
2011-12-15 12:32:08 +00:00
Eelco Dolstra
3a48282b06 * Buffer writes in FdSink. This significantly reduces the number of
system calls / context switches when dumping a NAR and in the worker
  protocol.
2011-12-14 23:30:06 +00:00
Eelco Dolstra
893cac1402 * Remove the terminate handler, which was only really needed because
of Berkeley DB (see r8632).
2011-12-14 22:41:10 +00:00
Eelco Dolstra
23bf700196 * Oops, the daemon test wasn't actually using the daemon. 2011-12-14 22:31:31 +00:00
Eelco Dolstra
c8c0380744 * Remove unnecessary quotes. showPaths() already adds quotes. 2011-12-05 21:04:20 +00:00
Eelco Dolstra
000160f5b9 * In ‘nix-store --verify --check-contents’, repair missing hashes
rather than complain about them.
2011-12-02 17:52:18 +00:00
Eelco Dolstra
3964d95abf * nix-prefetch-url: rewritten in Perl. 2011-12-02 12:09:50 +00:00
Eelco Dolstra
92d6a5ed73 * Add some more functions to the Perl bindings. 2011-12-02 12:09:24 +00:00
Eelco Dolstra
49f59dceca * Move parseHash16or32 into libutil, and use in nix-hash. 2011-12-02 11:47:06 +00:00
Eelco Dolstra
b12b21825c * Allow '<nixexpr>' syntax to be used in nix-instantiate, nix-build
and nix-env, e.g.,

  $ nix-env -f '<nixpkgs>' -i patchelf

  or

  $ nix-build '<nixos/tests>' -A login.test
2011-12-01 16:41:43 +00:00
Eelco Dolstra
23c38a04cc * Slight improvement. 2011-12-01 13:51:05 +00:00
Eelco Dolstra
24f863d86b * When doing "nix-store --add-fixed" without "--recursive" via the Nix
daemon (which is an error), print a nicer error message than
  "Connection reset by peer" or "broken pipe".
* In the daemon, log errors that occur during request parameter
  processing.
2011-12-01 13:48:48 +00:00
Peter Simons
be9be4c147 doc/manual/nix-env.xml: fixed "nix-env -qaA" typo 2011-12-01 08:03:30 +00:00
Peter Simons
3c7ec8fc1b doc/manual/nix-env.xml: stripped trailing whitespace 2011-12-01 08:02:37 +00:00
Eelco Dolstra
f35c4351e5 * Don't require a specific Perl version. 2011-11-29 22:15:07 +00:00
Eelco Dolstra
4d0407ba08 * Fix make check. 2011-11-29 13:38:52 +00:00
Eelco Dolstra
1749a7b0ae * download-using-manifests: use the Perl bindings. 2011-11-29 13:01:24 +00:00
Eelco Dolstra
b1eb8f4249 * Get rid of some superfluous error messages if a substituter fails.
* Say "fetch" instead of "substitute".
2011-11-29 13:00:41 +00:00
Eelco Dolstra
216440b3ff * For consistency with "nix-store -q --hash", produce hashes in
base-32.  (This affects Hydra manifests.)
2011-11-29 12:32:55 +00:00
Eelco Dolstra
1df120cb05 * Get rid of the shell in ssh calls. 2011-11-29 10:51:22 +00:00
Eelco Dolstra
784083176a * Fix race. 2011-11-25 17:04:26 +00:00
Eelco Dolstra
f3bc98b001 2011-11-23 15:39:54 +00:00
Eelco Dolstra
10e2b2b79e * Document the --include-outputs option. 2011-11-23 15:39:02 +00:00
Eelco Dolstra
d5ac78e0d6 * Add bzip2 and xz support to nix-copy-closure. 2011-11-23 15:29:58 +00:00
Eelco Dolstra
5bbd693cae * Add an API function exportPaths() that provides the functionality of
‘nix-store --export’.
* Add a Perl module that provides the functionality of
  ‘nix-copy-closure --to’.  This is used by build-remote.pl so it no
  longer needs to start a separate nix-copy-closure process.  Also, it
  uses the Perl API to do the export, so it doesn't need to start a
  separate nix-store process either.  As a result, nix-copy-closure
  and build-remote.pl should no longer fail on very large closures due
  to an "Argument list too long" error.  (Note that having very many
  dependencies in a single derivation can still fail because the
  environment can become too large.  Can't be helped though.)
2011-11-23 15:13:37 +00:00
Eelco Dolstra
ab20af3e6f * build-remote.pl: drop a hard-coded reference to /nix/etc/nix. 2011-11-23 12:21:35 +00:00
Eelco Dolstra
993fa94fb4 * Move initialisation of variables like nixConfDir from libmain to
libstore so that the Perl bindings can use it as well.  It's vital
  that the Perl bindings use the configuration file, because otherwise
  nix-copy-closure will fail with a ‘database locked’ message if the
  value of ‘use-sqlite-wal’ is changed from the default.
2011-11-22 17:28:41 +00:00
Rob Vermaas
4e1ea17052 nix: add /etc/hosts with localhost entry to chroot builds. 2011-11-21 15:19:51 +00:00
Eelco Dolstra
4de3e2a0db * Doh. 2011-11-21 13:22:34 +00:00
Eelco Dolstra
23e933b3b3 * Put back the "sys_name" variable which got removed somewhere. This
broke building on Cygwin and Solaris.
2011-11-21 12:23:48 +00:00
Eelco Dolstra
a6abade8e8 * Escape the [ and ] characters in the sed call, otherwise autoconf
will eat them.
2011-11-21 12:18:26 +00:00
Eelco Dolstra
964399c079 * "sed" on FreeBSD doesn't know the "+" operator. 2011-11-20 19:23:50 +00:00
Eelco Dolstra
b92f76374f * In the platform, canonicalise "amd64" to "x86_64". FreeBSD 8.2's
uname reports amd64.
* Drop the FreeBSD version number, e.g. "i686-freebsd" instead of
  "i686-freebsd8.2".
2011-11-18 17:25:40 +00:00
Ludovic Courtès
42164d6de4 configure: Change i*86 to i686 as has always been done. 2011-11-16 20:58:21 +00:00
Ludovic Courtès
45ec69cbdf configure: Rely on `AC_CANONICAL_HOST' to determine the Nix system name.
This should be more robust and also plays better with
cross-compilation---it uses the host name, instead of using the build
name.
2011-11-16 20:39:59 +00:00
Eelco Dolstra
f8e609c341 * nix-pull: update the Nix manifest cache if necessary. Also, don't
read the manifest just to check the version and print the number of
  paths.  This makes nix-pull very fast for the cached cache (speeding
  up nixos-rebuild without the ‘--no-pull’ or ‘--fast’ options).
2011-11-16 16:41:48 +00:00
Eelco Dolstra
d7d7910ba4 * Don't decompress the manifests in /nix/var/nix/manifest. This saves
disk space, and, since they're typically only decompressed once (to
  fill the manifest cache), doesn't make things slower.
2011-11-16 16:25:38 +00:00
Eelco Dolstra
63ee5e4d2a * Remove obsolete line. 2011-11-16 11:56:19 +00:00
Eelco Dolstra
a5952405d2 * Re-use prepared statements across insertions into the manifest cache
DB.  This speeds up creating the cache from 16.1s to 7.9s on my
  system.
2011-11-16 11:37:40 +00:00
Eelco Dolstra
c0b706213d * Boldly make SQLite WAL mode the default again. Hopefully the
intermittent problems are gone by now.  WAL mode is preferrable
  because it does way fewer fsyncs.
2011-11-07 21:11:59 +00:00
Shea Levy
3c3107da86 There's no need to mess with drvPath at all 2011-11-06 07:18:19 +00:00
Shea Levy
2ab29be70c Fix faulty reversion of my changes to unsafeDiscardOutputDependency 2011-11-06 07:03:14 +00:00
Shea Levy
ca0d47a70c Respect all outputs passed to the derivation, not just the last one 2011-11-06 06:54:05 +00:00
Shea Levy
24b65937e1 Remove the unused sCurrentOutput symbol 2011-11-06 06:28:34 +00:00
Shea Levy
3522730316 Embed output name into the context of the *OutPath attributes and extract it for input derivations
Multiple outputs test passes!
2011-11-06 06:28:30 +00:00
Shea Levy
46876ff203 Fix stupid typo in multiple outputs test 2011-11-06 06:28:25 +00:00
Shea Levy
af2e53fd48 Include all outputs of derivations in the closure of explicitly-passed derivation paths
This required adding a queryOutputDerivationNames function in the store API
2011-11-06 06:28:20 +00:00
Shea Levy
981edeab7b The 'insert output between = signs' approach was not helpful 2011-11-06 06:28:14 +00:00
Shea Levy
f883afa1a1 The nixinstantiate and nixstore env vars are no longer set in common.sh 2011-11-06 06:28:08 +00:00
Shea Levy
2721e9f56f Merge from trunk 2011-11-06 00:13:09 +00:00
Eelco Dolstra
a6a3f3a8c2 * Fix race condition in the test. 2011-11-05 21:23:01 +00:00
Eelco Dolstra
fa69ff5726 * Fix the broken reference to bunzip2 in the channel unpack script. 2011-11-05 21:06:24 +00:00
Eelco Dolstra
daed9aeac5 2011-11-03 19:22:24 +00:00
Eelco Dolstra
d7b87bebe3 * The Nix configuration file is usually /etc/nix/nix.conf. 2011-11-03 18:47:10 +00:00
Eelco Dolstra
325b5a8aee * Fix permission on /nix/store in the manual for multi-user installs
(reported by Silvio Frischknecht).
2011-11-02 19:14:54 +00:00
Eelco Dolstra
a12095d3be * In printValueAsXML, handle the case where a "type" attribute is not
a string.  This happens in the NixOS option system.
* Remove a bogus comparison of a unsigned integer with -1.
2011-10-27 19:06:23 +00:00
Eelco Dolstra
00b41e46ed * Print a consistent message. 2011-10-19 21:34:13 +00:00
Eelco Dolstra
f186a9141e * nix-copy-closure: support ‘--dry-run’ and ‘--include-outputs’. 2011-10-18 21:21:22 +00:00
Eelco Dolstra
6761757428 * Use the Store API bindings in nix-copy-closure. 2011-10-11 15:41:13 +00:00
Eelco Dolstra
d43a148204 * Add a test for nix-copy-closure. 2011-10-11 13:58:47 +00:00
Eelco Dolstra
2492914fbc * Move the remote building test from the NixOS tree to the Nix tree. 2011-10-11 13:06:59 +00:00
Eelco Dolstra
c362e4d718 * Move SSH.pm. 2011-10-11 11:45:36 +00:00
Eelco Dolstra
7d314b8c95 * Work around a race condition starting the Nix daemon. 2011-10-11 11:14:30 +00:00
Eelco Dolstra
5193db048e * Set svn:ignore. 2011-10-11 09:32:34 +00:00
Eelco Dolstra
a2a317eb0b * Distribute GeneratePatches.pm. 2011-10-11 09:31:55 +00:00
Eelco Dolstra
5090c34ee1 * Set the executable bit on scripts. 2011-10-10 22:40:17 +00:00
Eelco Dolstra
8af7d766f0 * Refactoring: remove unnecessary variables from the tests. 2011-10-10 21:32:34 +00:00
Eelco Dolstra
cd6d02c366 2011-10-10 21:30:59 +00:00
Eelco Dolstra
6fcdbcac20 * Install NixManifest.pm, NixConfig.pm and GeneratePatches.pm under
the Nix:: namespace.
2011-10-10 21:11:08 +00:00
Eelco Dolstra
659c427caa * Hopefully perl-devel contains the required headers (untested). 2011-10-10 18:58:49 +00:00
Eelco Dolstra
73fe6871c4 * Include the Nix Perl bindings in Nix itself. This will allow the
bindings to be used in Nix's own Perl scripts.

  The only downside is that Perl XS and Automake/libtool don't really
  like each other, so building is a bit tricky.
2011-10-10 18:12:40 +00:00
Shea Levy
bffe35aced Update gitignore 2011-09-19 04:36:49 +00:00
Shea Levy
6c38cc9025 Ignore everything created during build 2011-09-19 04:15:26 +00:00
Eelco Dolstra
55481c44d4 * Don't assume that we want a shared Nix store. 2011-09-17 09:53:31 +00:00
Shea Levy
e81c09edbf Remove the current output metadata from the string for unsaveDiscardOutputDependency 2011-09-16 11:31:00 +00:00
Shea Levy
bf50d6ad32 Add information about which output is active to drvPath's context
This will break things that depend on being able to just strip away an equals sign, so those have to be updated next
2011-09-16 11:30:52 +00:00
Shea Levy
ffa038f66d Add an sCurrentOutput member to EvalState 2011-09-16 11:30:44 +00:00
Shea Levy
f3e410d4bf Add a currentOutput attribute to derivations keep track of which output is active 2011-09-16 11:30:03 +00:00
Shea Levy
8f28a3ba25 Add a test for multiple outputs
This currently fails. Yay test-driven development!
2011-09-14 05:59:29 +00:00
Shea Levy
c172d16b00 First attempt at the output-as-derivation semantics
For each output, this adds a corresponding attribute to the derivation that is
the same as the derivation except for outPath, which is set to the path specific
to that output. Additionally, an "all" attribute is added that is a list of all
of the output derivations. This has to be done outside of derivationStrict as
each output is itself a derivation that contains itself (and all other outputs)
as an attribute. The derivation itself is equivalent to the first output in the
outputs list (or "out" if that list isn't set).
2011-09-14 05:59:17 +00:00
Shea Levy
0b34e57eb8 Create a branch for me to play around with finishing off the multiple outputs implementation 2011-09-14 00:41:02 +00:00
Eelco Dolstra
13114daa3e * Ouch. A store upgrade could cause a substituter to be triggered,
causing a deadlock.
2011-09-12 09:07:43 +00:00
Ludovic Courtès
281e3ed059 bootstrap: Simplify & make more robust. 2011-09-06 12:11:05 +00:00
Eelco Dolstra
e6cb3d0a0d * Added a command ‘nix-store --verify-paths PATHS’ to check whether
the contents of any of the given store paths have been modified.
  E.g.

    $ nix-store --verify-path $(nix-store -qR /var/run/current-system)
    path `/nix/store/m2smyiwbxidlprfxfz4rjlvz2c3mg58y-etc' was modified! expected hash `fc87e271c5fdf179b47939b08ad13440493805584b35e3014109d04d8436e7b8', got `20f1a47281b3c0cbe299ce47ad5ca7340b20ab34246426915fce0ee9116483aa'

  All paths are checked; the exit code is 1 if any path has been
  modified, 0 otherwise.
2011-09-06 12:06:30 +00:00
Eelco Dolstra
82710f96f7 * Add some -f flags, never hurts. 2011-09-06 12:00:11 +00:00
Eelco Dolstra
93227ff65c * Eliminate all uses of the global variable ‘store’ from libstore.
This should also fix:

    nix-instantiate: ./../boost/shared_ptr.hpp:254: T* boost::shared_ptr<T>::operator->() const [with T = nix::StoreAPI]: Assertion `px != 0' failed.

  which was caused by hashDerivationModulo() calling the ‘store’
  object (during store upgrades) before openStore() assigned it.
2011-08-31 21:11:50 +00:00
Eelco Dolstra
5bcdc7e351 * Update the cleanup script. 2011-08-27 16:59:32 +00:00
Eelco Dolstra
a95ba4cdd9 * Use last_insert_id instead of sqlite_last_insert_rowid, which you're
not really supposed to use according to the DBD::SQLite docs, and
  fails on some systems (e.g. http://hydra.nixos.org/build/1246662).
2011-08-17 14:17:19 +00:00
Eelco Dolstra
da18b11b05 * On FreeBSD, ‘touch’ is not in the test $PATH, so don't use it. 2011-08-08 14:08:38 +00:00
Eelco Dolstra
76e0029f7a * Add perl-DBD-SQLite as a dependency of the RPM builds. 2011-08-08 14:06:10 +00:00
Eelco Dolstra
d374be551d * Add DBD-SQLite as a dependency to the Debian/Ubuntu builds.
* Drop some old Fedora/Debian/Ubuntu releases.
2011-08-08 13:19:00 +00:00
Eelco Dolstra
2d663b502d * Cache the result of file evaluation (i.e, memoize evalFile()). This
prevents files from being evaluated and stored as values multiple
  times.  For instance, evaluation of the ‘system’ attribute in NixOS
  causes ‘nixpkgs/pkgs/lib/lists.nix’ to be evaluated 2019 times.

  Caching gives a modest speedup and a decent memory footprint
  reduction (e.g., from 1.44s to 1.28s, and from 81 MiB to 59 MiB with
  GC_INITIAL_HEAP_SIZE=100000 on my system).
2011-08-06 19:45:43 +00:00
Eelco Dolstra
510033e783 * Handle <path> syntax. 2011-08-06 18:54:29 +00:00
Eelco Dolstra
9d091ee99a * Handle the case where the search path element is a regular file. 2011-08-06 18:45:28 +00:00
Eelco Dolstra
00a724ebc6 * Remove a debug statement. 2011-08-06 18:24:43 +00:00
Eelco Dolstra
07340b8be7 * Add the Nix corepkgs to the end of the search path. This makes it
possible for other Nix expressions to use corepkgs (mostly useful
  for the buildenv function).
2011-08-06 18:23:38 +00:00
Eelco Dolstra
c7101dac0b * Allow redirections in search path entries. E.g. if you have a
directory

    /home/eelco/src/stdenv-updates

  that you want to use as the directory for import such as

    with (import <nixpkgs> { });

  then you can say

    $ nix-build -I nixpkgs=/home/eelco/src/stdenv-updates
2011-08-06 17:48:57 +00:00
Eelco Dolstra
1578b2261d * Add lang/dir* to the distribution. 2011-08-06 16:18:54 +00:00
Eelco Dolstra
1ecc97b6bd * Add a Nix expression search path feature. Paths between angle
brackets, e.g.

    import <nixpkgs/pkgs/lib>

  are resolved by looking them up relative to the elements listed in
  the search path.  This allows us to get rid of hacks like

    import "${builtins.getEnv "NIXPKGS_ALL"}/pkgs/lib"

  The search path can be specified through the ‘-I’ command-line flag
  and through the colon-separated ‘NIX_PATH’ environment variable,
  e.g.,

    $ nix-build -I /etc/nixos ...

  If a file is not found in the search path, an error message is
  lazily thrown.
2011-08-06 16:05:24 +00:00
Eelco Dolstra
54945a2950 * Refactoring: move parseExprFromFile() and parseExprFromString() into
the EvalState class.
2011-08-06 13:02:55 +00:00
Eelco Dolstra
c8606664ab * Don't allow derivations with fixed and non-fixed outputs. 2011-07-20 18:26:00 +00:00
Eelco Dolstra
b2027f70d9 * Fix a huuuuge security hole in the Nix daemon. It didn't check that
derivations added to the store by clients have "correct" output
  paths (meaning that the output paths are computed by hashing the
  derivation according to a certain algorithm).  This means that a
  malicious user could craft a special .drv file to build *any*
  desired path in the store with any desired contents (so long as the
  path doesn't already exist).  Then the attacker just needs to wait
  for a victim to come along and install the compromised path.

  For instance, if Alice (the attacker) knows that the latest Firefox
  derivation in Nixpkgs produces the path

    /nix/store/1a5nyfd4ajxbyy97r1fslhgrv70gj8a7-firefox-5.0.1

  then (provided this path doesn't already exist) she can craft a .drv
  file that creates that path (i.e., has it as one of its outputs),
  add it to the store using "nix-store --add", and build it with
  "nix-store -r".  So the fake .drv could write a Trojan to the
  Firefox path.  Then, if user Bob (the victim) comes along and does

    $ nix-env -i firefox
    $ firefox

  he executes the Trojan injected by Alice.

  The fix is to have the Nix daemon verify that derivation outputs are
  correct (in addValidPath()).  This required some refactoring to move
  the hash computation code to libstore.
2011-07-20 18:10:47 +00:00
Eelco Dolstra
d2bfe1b071 * Added a test that make sure that users cannot register
specially-crafted derivations that produce output paths belonging to
  other derivations.  This could be used to inject malware into the
  store.
2011-07-20 12:15:40 +00:00
Eelco Dolstra
4bdb51e621 * Refactoring. 2011-07-20 11:50:13 +00:00
Eelco Dolstra
0243eea4b9 * Create a symlink to /nix/var/nix/manifests in /nix/var/nix/gcroots
if it doesn't exist.
2011-07-20 11:47:00 +00:00
Eelco Dolstra
d329c3ea9d * Support multiple outputs. A derivation can declare multiple outputs
by setting the ‘outputs’ attribute.  For example:

    stdenv.mkDerivation {
      name = "aterm-2.5";

      src = ...;

      outputs = [ "out" "tools" "dev" ];

      configureFlags = "--bindir=$(tools)/bin --includedir=$(dev)/include";
    }

  This derivation creates three outputs, named like this:

    /nix/store/gcnqgllbh01p3d448q8q6pzn2nc2gpyl-aterm-2.5
    /nix/store/gjf1sgirwfnrlr0bdxyrwzpw2r304j02-aterm-2.5-tools
    /nix/store/hp6108bqfgxvza25nnxfs7kj88xi2vdx-aterm-2.5-dev

  That is, the symbolic name of the output is suffixed to the store
  path (except for the ‘out’ output).  Each path is passed to the
  builder through the corresponding environment variable, e.g.,
  ${tools}.

  The main reason for multiple outputs is to allow parts of a package
  to be distributed and garbage-collected separately.  For instance,
  most packages depend on Glibc for its libraries, but don't need its
  header files.  If these are separated into different store paths,
  then a package that depends on the Glibc libraries only causes the
  libraries and not the headers to be downloaded.

  The main problem with multiple outputs is that if one output exists
  while the others have been garbage-collected (or never downloaded in
  the first place), and we want to rebuild the other outputs, then
  this isn't possible because we can't clobber a valid output (it
  might be in active use).  This currently gives an error message
  like:

    error: derivation `/nix/store/1s9zw4c8qydpjyrayxamx2z7zzp5pcgh-aterm-2.5.drv' is blocked by its output paths

  There are two solutions: 1) Do the build in a chroot.  Then we don't
  need to overwrite the existing path.  2) Use hash rewriting (see the
  ASE-2005 paper).  Scary but it should work.

  This is not finished yet.  There is not yet an easy way to refer to
  non-default outputs in Nix expressions.  Also, mutually recursive
  outputs aren't detected yet and cause the garbage collector to
  crash.
2011-07-18 23:31:03 +00:00
Eelco Dolstra
d9a5959139 * Show the default for --with-store-dir (Nix/211). 2011-07-13 15:57:44 +00:00
Eelco Dolstra
d5d4dcd4c9 * Allow attribute names to be strings. Based on the
allow-arbitrary-strinsg-in-names patch by Marc Weber.
2011-07-13 15:53:24 +00:00
Eelco Dolstra
e649f3168b * Fix concurrency issues in download-using-manifests' handling of the
SQLite manifest cache.  The DBI AutoCommit feature caused every
  process to have an active transaction at all times, which could
  indefinitely block processes wanting to update the manifest cache.

* Disable fsync() in the manifest cache because we don't need
  integrity (the cache can always be recreated if it gets corrupted).
2011-07-13 14:05:54 +00:00
Eelco Dolstra
0a623a10c7 * Allow a default value in attribute selection by writing
x.y.z or default

  (as originally proposed in
  https://mail.cs.uu.nl/pipermail/nix-dev/2009-September/002989.html).

  For instance, an expression like

    stdenv.lib.attrByPath ["features" "ckSched"] false args

  can now be written as

    args.features.ckSched or false
2011-07-13 12:19:57 +00:00
Eelco Dolstra
2b9e29b1c8 * Change the right-hand side of the ‘.’ operator from an attribute to
an attribute path.  This is a refactoring to support default values.
2011-07-06 12:28:57 +00:00
Eelco Dolstra
5580f3817c * Test case. 2011-07-06 10:58:53 +00:00
Eelco Dolstra
5637037802 * In the ‘?’ operator, allow attribute paths. For instance, you can
write ‘attrs ? a.b’ to test whether ‘attrs’ has an attribute ‘a’
  containing an attribute ‘b’.  This is more convenient than ‘attrs ?
  a && attrs.a ? b’.

  Slight change in the semantics: it's no longer an error if the
  left-hand side of ‘?’ is not an attribute set.  In that case it just
  returns false.  So, ‘null ? foo’ no longer throws an error.
2011-07-06 10:58:17 +00:00
Eelco Dolstra
34f4b91820 2011-07-04 14:44:53 +00:00
Ludovic Courtès
1ea6e06445 doc: Fix typo. 2011-06-30 15:48:40 +00:00
Ludovic Courtès
5c9e9f732d Add support for the build-timeout' and --timeout' options. 2011-06-30 15:19:13 +00:00
Eelco Dolstra
9c99aa2620 2011-06-27 09:01:09 +00:00
Eelco Dolstra
e4d8148585 2011-06-27 08:04:54 +00:00
Eelco Dolstra
4891b21f34 * Use SQLite 3.7.6.2. 2011-05-03 16:17:24 +00:00
Eelco Dolstra
d94cb02bfe * nix-install-package: unset NIX_REMOTE because $NIX_MANIFESTS_DIR
doesn't work when building through the Nix daemon.  This also
  ensures an error message when the user doesn't have sufficient
  privileges to do nix-pull.
2011-04-19 10:52:35 +00:00
Eelco Dolstra
8c69dac8a1 * Handle error messages from the Nix worker containing the `%'
character.  (Nix/216)
2011-04-19 10:44:44 +00:00
Eelco Dolstra
4ba6afaf48 * nix-env -ub' (--prebuilt-only') didn't really work because it
checked too soon whether substitutes are available.  That is, it did
  so for every available package, rather than those matching installed
  packages.  This was very slow and subject to assertion failures.  So
  do the check much later.  Idem for `nix-env -qab' and `nix-env -ib'.
2011-04-11 16:27:05 +00:00
Eelco Dolstra
412914d004 * Read manifests directly into the database, rather than first reading
them into memory.  This brings memory use down to (more or less)
  O(1).  For instance, on my test case, the maximum resident size of
  download-using-manifests while filling the DB went from 142 MiB to
  11 MiB.
2011-04-11 13:16:54 +00:00
Eelco Dolstra
08c8971498 * Lock the database during updates. 2011-04-11 12:40:13 +00:00
Eelco Dolstra
b2c11b9ed0 2011-04-11 10:23:15 +00:00
Eelco Dolstra
3cbf680f5d * configure: detect whether DBD::SQLite is present. If necessary the
location to DBI and DBD::SQLite can be passed with --with-dbi and
  --with-dbd-sqlite.
2011-04-11 10:13:53 +00:00
Eelco Dolstra
83252b4ca9 * Subtle bug: if you import File::stat in one module, it affects other
modules as well.  So use symbolic field names everywhere (which is
  nicer anyway).
2011-04-11 08:21:30 +00:00
Eelco Dolstra
b1882c3ef7 * Create $manifestDir if it doesn't exist. 2011-04-11 08:06:14 +00:00
Eelco Dolstra
5591fcc529 * Cache the manifests in /nix/var/nix/manifests in a SQLite database.
This significantly speeds up the download-using-manifests
  substituter, especially if manifests are very large.  For instance,
  one "nix-build -A geeqie" operation that updated four packages using
  binary patches went from 18.5s to 1.6s.  It also significantly
  reduces memory use.

  The cache is kept in /nix/var/nix/manifests/cache.sqlite.  It's
  updated automatically when manifests are added to or removed from
  /nix/var/nix/manifests.  It might be interesting to have nix-pull
  store manifests directly in the DB, rather than storing them as
  separate flat files, but then we would need a command line interface
  to delete manifests from the DB.
2011-04-10 23:22:46 +00:00
Eelco Dolstra
1e7e4f21ba * Remove the localPaths feature in manifests since it's no longer used
and redundant anyway.
2011-04-06 09:16:22 +00:00
Eelco Dolstra
0423d0692a * Print a better error message. 2011-03-16 15:55:57 +00:00
Eelco Dolstra
48bdbbf070 * Fix a bug in the documentation (reported by Olexiy Buyanskyy,
Nix/215).
2011-03-15 13:12:59 +00:00
Eelco Dolstra
802c2651c8 2011-02-17 15:08:33 +00:00
Eelco Dolstra
e945b52a31 * nix-push: handle the case where the hash is not set in the DB. 2011-02-17 13:26:33 +00:00
Eelco Dolstra
c3cee5395b * Build for Ubuntu 10.04. 2011-02-14 14:56:02 +00:00
Florian Friesdorf
8fcaf3e9c6 make nix-mode provide 'nix-mode
this enables (require 'nix-mode)
2011-02-14 03:11:56 +00:00
Eelco Dolstra
538b7caab0 * Don't allocate a big initial GC address space on machines with
little RAM.  Even if the memory isn't actually used, it can cause
  problems with the overcommit heuristics in the kernel.  So use a VM
  space of 25% of RAM, up to 384 MB.
2011-02-10 14:31:04 +00:00
Eelco Dolstra
5a6b039802 * Don't call GC_expand_hp unless we're actually using the garbage
collector.
2011-02-09 22:59:50 +00:00
Ludovic Courtès
f1462c208b Use $BDW_GC_LIBS instead of a custom variable. 2011-02-09 21:23:13 +00:00
Eelco Dolstra
1876ab764f * A better fix. $boehmgc isn't set anywhere, we should use the flags
returned by pkg-config.
2011-02-09 14:13:09 +00:00
Eelco Dolstra
dfc4117e90 * The GC library can't be found on Solaris
(http://hydra.nixos.org/build/890714), so don't build with GC
  support for now.
2011-02-09 14:08:32 +00:00
Eelco Dolstra
d159ea1b7e * Urgh, FreeBSD doesn't have a "seq" command. 2011-02-09 14:03:16 +00:00
Eelco Dolstra
3087b3f751 * Obsolete. 2011-02-09 12:48:54 +00:00
Eelco Dolstra
eb94581d39 * Remove obsolete directory. 2011-02-09 12:43:44 +00:00
Eelco Dolstra
7bba67c401 * Remove obsolete file. 2011-02-09 12:42:15 +00:00
Eelco Dolstra
d0eda1f3e9 * Merged the SQLite branch. 2011-02-09 12:41:54 +00:00
226 changed files with 5723 additions and 4190 deletions

147
.gitignore vendored
View File

@@ -1,8 +1,7 @@
# START "git svn show-ignore"
Makefile
Makefile.in
# /
/Makefile
/Makefile.in
/aclocal.m4
/autom4te.cache
/config.*
@@ -22,33 +21,19 @@
/config/mkinstalldirs
/config/ltmain.sh
# /corepkgs/
/corepkgs/Makefile
/corepkgs/Makefile.in
/corepkgs/config.nix
# /corepkgs/buildenv/
/corepkgs/buildenv/Makefile.in
/corepkgs/buildenv/Makefile
/corepkgs/buildenv/builder.pl
# /corepkgs/channels/
/corepkgs/channels/Makefile.in
/corepkgs/channels/Makefile
/corepkgs/channels/unpack.sh
# /corepkgs/nar/
/corepkgs/nar/Makefile
/corepkgs/nar/Makefile.in
/corepkgs/nar/nar.sh
/corepkgs/nar/unnar.sh
# /doc/
/doc/Makefile
/doc/Makefile.in
# /doc/manual/
/doc/manual/Makefile
/doc/manual/Makefile.in
/doc/manual/manual.html
/doc/manual/manual.is-valid
/doc/manual/*.1
@@ -58,38 +43,7 @@
/doc/manual/NEWS.html
/doc/manual/NEWS.txt
# /externals/
/externals/Makefile
/externals/Makefile.in
/externals/aterm-*
/externals/have-aterm
/externals/build-aterm
/externals/inst-aterm
/externals/bzip2-*
/externals/have-bzip2
/externals/build-bzip2
/externals/inst-bzip2
# /make/examples/aterm/
/make/examples/aterm/result*
# /make/examples/aterm/aterm/
/make/examples/aterm/aterm/*
# /make/examples/aterm/test/
/make/examples/aterm/test/*
# /misc/
/misc/Makefile.in
/misc/Makefile
# /misc/emacs/
/misc/emacs/Makefile.in
/misc/emacs/Makefile
# /scripts/
/scripts/Makefile
/scripts/Makefile.in
/scripts/nix-profile.sh
/scripts/nix-pull
/scripts/nix-push
@@ -100,49 +54,25 @@
/scripts/nix-channel
/scripts/nix-build
/scripts/nix-copy-closure
/scripts/readmanifest.pm
/scripts/readconfig.pm
/scripts/nix-generate-patches
/scripts/NixConfig.pm
/scripts/NixManifest.pm
/scripts/GeneratePatches.pm
/scripts/download-using-manifests.pl
/scripts/copy-from-other-stores.pl
/scripts/generate-patches.pl
/scripts/find-runtime-roots.pl
/scripts/build-remote.pl
# /src/
/src/Makefile
/src/Makefile.in
/scripts/nix-reduce-build
/scripts/nix-http-export.cgi
# /src/bin2c/
/src/bin2c/Makefile.in
/src/bin2c/Makefile
/src/bin2c/bin2c
/src/bin2c/.deps
/src/bin2c/.libs
# /src/boost/
/src/boost/Makefile
/src/boost/Makefile.in
# /src/boost/format/
/src/boost/format/Makefile
/src/boost/format/Makefile.in
/src/boost/format/.deps
/src/boost/format/libformat.a
/src/boost/format/.libs
# /src/bsdiff-4.3/
/src/bsdiff-4.3/Makefile
/src/bsdiff-4.3/Makefile.in
/src/bsdiff-4.3/bsdiff
/src/bsdiff-4.3/bspatch
/src/bsdiff-4.3/.deps
/src/bsdiff-4.3/.libs
# /src/libexpr/
/src/libexpr/Makefile
/src/libexpr/Makefile.in
/src/libexpr/.deps
/src/libexpr/libexpr.a
/src/libexpr/lexer-tab.cc
/src/libexpr/lexer-tab.hh
/src/libexpr/parser-tab.cc
@@ -150,109 +80,66 @@
/src/libexpr/parser-tab.output
/src/libexpr/nixexpr-ast.hh
/src/libexpr/nixexpr-ast.cc
/src/libexpr/.libs
/src/libexpr/nix.tbl
# /src/libmain/
/src/libmain/Makefile
/src/libmain/Makefile.in
/src/libmain/.deps
/src/libmain/libmain.a
/src/libmain/.libs
# /src/libstore/
/src/libstore/Makefile
/src/libstore/Makefile.in
/src/libstore/.deps
/src/libstore/libstore.a
/src/libstore/derivations-ast.cc
/src/libstore/derivations-ast.hh
/src/libstore/.libs
# /src/libutil/
/src/libutil/Makefile
/src/libutil/Makefile.in
/src/libutil/.deps
/src/libutil/libutil.a
/src/libutil/.libs
/src/libstore/schema.sql.hh
# /src/nix-env/
/src/nix-env/Makefile.in
/src/nix-env/Makefile
/src/nix-env/.deps
/src/nix-env/nix-env
/src/nix-env/help.txt.hh
/src/nix-env/.libs
# /src/nix-hash/
/src/nix-hash/Makefile
/src/nix-hash/Makefile.in
/src/nix-hash/.deps
/src/nix-hash/.libs
/src/nix-hash/nix-hash
/src/nix-hash/help.txt.hh
# /src/nix-instantiate/
/src/nix-instantiate/Makefile.in
/src/nix-instantiate/Makefile
/src/nix-instantiate/.deps
/src/nix-instantiate/nix-instantiate
/src/nix-instantiate/help.txt.hh
/src/nix-instantiate/.libs
# /src/nix-log2xml/
/src/nix-log2xml/Makefile.in
/src/nix-log2xml/Makefile
/src/nix-log2xml/.deps
/src/nix-log2xml/nix-log2xml
/src/nix-log2xml/test*.*
/src/nix-log2xml/.libs
/src/nix-log2xml/*.log
/src/nix-log2xml/*.xml
/src/nix-log2xml/*.html
# /src/nix-setuid-helper/
/src/nix-setuid-helper/Makefile.in
/src/nix-setuid-helper/Makefile
/src/nix-setuid-helper/.deps
/src/nix-setuid-helper/nix-setuid-helper
/src/nix-setuid-helper/help.txt.hh
/src/nix-setuid-helper/.libs
# /src/nix-store/
/src/nix-store/Makefile
/src/nix-store/Makefile.in
/src/nix-store/.deps
/src/nix-store/help.txt.hh
/src/nix-store/nix-store
/src/nix-store/.libs
# /src/nix-worker/
/src/nix-worker/Makefile.in
/src/nix-worker/Makefile
/src/nix-worker/.deps
/src/nix-worker/nix-worker
/src/nix-worker/help.txt.hh
/src/nix-worker/.libs
# /tests/
/tests/Makefile
/tests/Makefile.in
/tests/test-tmp
/tests/config.nix
/tests/common.sh
/tests/dummy
/tests/result*
# /tests/lang/
/tests/lang/*.out
/tests/lang/*.out.xml
/tests/lang/*.ast
# END "git svn show-ignore"
/perl/lib/Nix/Config.pm
/perl/lib/Nix/Store.cc
.deps
.libs
*.a
*.lo
*.la
*.o
*.so
*~
# GNU Global

View File

View File

@@ -1,4 +1,4 @@
SUBDIRS = externals src scripts corepkgs doc misc tests
SUBDIRS = src perl scripts corepkgs doc misc tests
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
nix.conf.example NEWS version
@@ -33,7 +33,7 @@ init-state:
$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(localstatedir)/nix/temproots
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)$(storedir)
-$(INSTALL) $(INIT_FLAGS) -d $(DESTDIR)$(storedir)
$(INSTALL) $(INIT_FLAGS) $(GROUP_WRITABLE) -d $(DESTDIR)$(localstatedir)/nix/manifests
ln -sfn $(localstatedir)/nix/manifests $(DESTDIR)$(localstatedir)/nix/gcroots/manifests

View File

@@ -1,149 +0,0 @@
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:*
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:*
fun:AT_collect_minor
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value8
fun:*
fun:*
fun:AT_collect_minor
}
{
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:*
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
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:*
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:*
fun:*
fun:mark_phase
}
{
ATerm library conservatively scans for GC roots
Memcheck:Value4
fun:*
fun:*
fun:mark_phase_young
}
{
ATerm library conservatively scans for GC roots
Memcheck:Cond
fun:*
fun:*
fun:mark_phase_young
}

View File

@@ -1,252 +0,0 @@
#! /usr/bin/perl -w -I /home/eelco/.nix-profile/lib/site_perl
use strict;
use XML::LibXML;
#use XML::Simple;
my $blacklistFN = shift @ARGV;
die unless defined $blacklistFN;
my $userEnv = shift @ARGV;
die unless defined $userEnv;
# Read the blacklist.
my $parser = XML::LibXML->new();
my $blacklist = $parser->parse_file($blacklistFN)->getDocumentElement;
#print $blacklist->toString() , "\n";
# Get all the elements of the user environment.
my $userEnvElems = `nix-store --query --references '$userEnv'`;
die "cannot query user environment elements" if $? != 0;
my @userEnvElems = split ' ', $userEnvElems;
my %storePathHashes;
sub getElemNodes {
my $node = shift;
my @elems = ();
foreach my $node ($node->getChildNodes) {
push @elems, $node if $node->nodeType == XML_ELEMENT_NODE;
}
return @elems;
}
my %referencesCache;
sub getReferences {
my $path = shift;
return $referencesCache{$path} if defined $referencesCache{$path};
my $references = `nix-store --query --references '$path'`;
die "cannot query references" if $? != 0;
$referencesCache{$path} = [split ' ', $references];
return $referencesCache{$path};
}
my %attrsCache;
sub getAttr {
my $path = shift;
my $name = shift;
my $key = "$path/$name";
return $referencesCache{$key} if defined $referencesCache{$key};
my $value = `nix-store --query --binding '$name' '$path' 2> /dev/null`;
$value = "" if $? != 0; # !!!
chomp $value;
$referencesCache{$key} = $value;
return $value;
}
sub evalCondition;
sub traverse {
my $done = shift;
my $set = shift;
my $path = shift;
my $stopCondition = shift;
return if defined $done->{$path};
$done->{$path} = 1;
$set->{$path} = 1;
# print " in $path\n";
if (!evalCondition({$path => 1}, $stopCondition)) {
# print " STOPPING in $path\n";
return;
}
# Get the requisites of the deriver.
foreach my $reference (@{getReferences $path}) {
traverse($done, $set, $reference, $stopCondition);
}
}
sub evalSet {
my $inSet = shift;
my $expr = shift;
my $name = $expr->getName;
if ($name eq "traverse") {
my $stopCondition = (getElemNodes $expr)[0];
my $done = { };
my $set = { };
foreach my $path (keys %{$inSet}) {
traverse($done, $set, $path, $stopCondition);
}
return $set;
}
else {
die "unknown element `$name'";
}
}
# Function for evaluating conditions.
sub evalCondition {
my $storePaths = shift;
my $condition = shift;
my $elemName = $condition->getName;
if ($elemName eq "containsSource") {
my $hash = $condition->attributes->getNamedItem("hash")->getValue;
foreach my $path (keys %{$storePathHashes{$hash}}) {
return 1 if defined $storePaths->{$path};
}
return 0;
}
elsif ($elemName eq "hasName") {
my $nameRE = $condition->attributes->getNamedItem("name")->getValue;
foreach my $path (keys %{$storePaths}) {
return 1 if $path =~ /$nameRE/;
}
return 0;
}
elsif ($elemName eq "hasAttr") {
my $name = $condition->attributes->getNamedItem("name")->getValue;
my $valueRE = $condition->attributes->getNamedItem("value")->getValue;
foreach my $path (keys %{$storePaths}) {
if ($path =~ /\.drv$/) {
my $value = getAttr($path, $name);
# print " $path $name $value\n";
return 1 if $value =~ /$valueRE/;
}
}
return 0;
}
elsif ($elemName eq "and") {
my $result = 1;
foreach my $node (getElemNodes $condition) {
$result &= evalCondition($storePaths, $node);
}
return $result;
}
elsif ($elemName eq "not") {
return !evalCondition($storePaths, (getElemNodes $condition)[0]);
}
elsif ($elemName eq "within") {
my @elems = getElemNodes $condition;
my $set = evalSet($storePaths, $elems[0]);
return evalCondition($set, $elems[1]);
}
elsif ($elemName eq "true") {
return 1;
}
elsif ($elemName eq "false") {
return 0;
}
else {
die "unknown element `$elemName'";
}
}
sub evalOr {
my $storePaths = shift;
my $nodes = shift;
my $result = 0;
foreach my $node (@{$nodes}) {
$result |= evalCondition($storePaths, $node);
}
return $result;
}
# Iterate over all elements, check them.
foreach my $userEnvElem (@userEnvElems) {
# Get the deriver of this path.
my $deriver = `nix-store --query --deriver '$userEnvElem'`;
die "cannot query deriver" if $? != 0;
chomp $deriver;
if ($deriver eq "unknown-deriver") {
# print " deriver unknown, cannot check sources\n";
next;
}
print "CHECKING $userEnvElem\n";
# Get the requisites of the deriver.
# my $requisites = `nix-store --query --requisites --include-outputs '$deriver'`;
# die "cannot query requisites" if $? != 0;
# my @requisites = split ' ', $requisites;
# Get the hashes of the requisites.
# my $hashes = `nix-store --query --hash @requisites`;
# die "cannot query hashes" if $? != 0;
# my @hashes = split ' ', $hashes;
# for (my $i = 0; $i < scalar @requisites; $i++) {
# die unless $i < scalar @hashes;
# my $hash = $hashes[$i];
# $storePathHashes{$hash} = {} unless defined $storePathHashes{$hash};
# my $r = $storePathHashes{$hash}; # !!! fix
# $$r{$requisites[$i]} = 1;
# }
# Evaluate each blacklist item.
foreach my $item ($blacklist->getChildrenByTagName("item")) {
my $itemId = $item->getAttributeNode("id")->getValue;
# print " CHECKING FOR $itemId\n";
my $condition = ($item->getChildrenByTagName("condition"))[0];
die unless $condition;
# Evaluate the condition.
my @elems = getElemNodes $condition;
if (evalOr({$deriver => 1}, \@elems)) {
# Oops, condition triggered.
my $reason = ($item->getChildrenByTagName("reason"))[0]->getChildNodes->to_literal;
$reason =~ s/\s+/ /g;
$reason =~ s/^\s+//g;
print " VULNERABLE TO `$itemId': $reason\n";
}
}
}

View File

@@ -1,8 +1,4 @@
#! /bin/sh -e
rm -f aclocal.m4
mkdir -p config
libtoolize --copy
aclocal
autoheader
automake --add-missing --copy
autoconf
exec autoreconf -vfi

View File

@@ -5,42 +5,42 @@ AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AC_DEFINE_UNQUOTED(NIX_VERSION, ["$VERSION"], [Nix version.])
AC_CANONICAL_HOST
AC_PROG_SED
# Construct a Nix system name (like "i686-linux").
AC_CANONICAL_HOST
AC_MSG_CHECKING([for the canonical Nix system name])
cpu_name=$(uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' 'abcdefghijklmnopqrstuvwxyz_')
machine_name=$(uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' 'abcdefghijklmnopqrstuvwxyz_')
case $machine_name in
i*86)
machine_name=i686
;;
x86_64)
machine_name=x86_64
;;
ppc)
machine_name=powerpc
;;
*)
if test "$cpu_name" != "unknown"; then
machine_name=$cpu_name
fi
;;
esac
AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
[Platform identifier (e.g., `i686-linux').]),
[system=$withval],
[case "$host_cpu" in
i*86)
machine_name="i686";;
amd64)
machine_name="x86_64";;
*)
machine_name="$host_cpu";;
esac
sys_name=$(uname -s | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' 'abcdefghijklmnopqrstuvwxyz_')
case "$host_os" in
linux-gnu*)
# For backward compatibility, strip the `-gnu' part.
system="$machine_name-linux";;
*)
# Strip the version number from names such as `gnu0.3',
# `darwin10.2.0', etc.
system="$machine_name-`echo $host_os | "$SED" -e's/@<:@0-9.@:>@*$//g'`";;
esac])
sys_name=$(uname -s | tr 'A-Z ' 'a-z_')
case $sys_name in
cygwin*)
sys_name=cygwin
;;
esac
AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
[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')])
@@ -62,7 +62,7 @@ fi
# Solaris-specific stuff.
if test "$sys_name" = "sunos"; then
if test "$sys_name" = sunos; then
# Solaris requires -lsocket -lnsl for network functions
LIBS="-lsocket -lnsl $LIBS"
fi
@@ -71,7 +71,7 @@ fi
AC_PROG_CC
AC_PROG_CXX
# To build programs to be run in the build machine
# To build programs to be run in the build machine.
if test "$CC_FOR_BUILD" = ""; then
if test "$cross_compiling" = "yes"; then
AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc)
@@ -86,13 +86,6 @@ AC_DISABLE_STATIC
AC_ENABLE_SHARED
AC_PROG_LIBTOOL
if test "$enable_shared" = yes; then
SUB_CONFIGURE_FLAGS="--enable-shared --disable-static"
else
SUB_CONFIGURE_FLAGS="--enable-static --disable-shared"
fi
AC_SUBST(SUB_CONFIGURE_FLAGS)
# Use 64-bit file system calls so that we can support files > 2 GiB.
AC_SYS_LARGEFILE
@@ -113,8 +106,8 @@ AC_LANG_POP(C++)
# 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([sched.h])
AC_CHECK_HEADERS([sys/param.h])
AC_CHECK_HEADERS([sys/mount.h], [], [],
[#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
@@ -124,7 +117,7 @@ AC_CHECK_HEADERS([sys/mount.h], [], [],
# Check for <locale>.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([locale], [], [], [])
AC_CHECK_HEADERS([locale])
AC_LANG_POP(C++)
@@ -138,9 +131,13 @@ AC_SUBST([bsddiff_compat_include])
AC_CHECK_HEADERS([sys/personality.h])
# Check for <linux/fs.h> (for immutable file support).
AC_CHECK_HEADERS([linux/fs.h])
# Check for tr1/unordered_set.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([tr1/unordered_set], [], [], [])
AC_CHECK_HEADERS([tr1/unordered_set])
AC_LANG_POP(C++)
@@ -163,13 +160,12 @@ AC_PATH_PROG(bison, bison, false)
NEED_PROG(perl, perl)
NEED_PROG(sed, sed)
NEED_PROG(tar, tar)
NEED_PROG(bzip2, bzip2)
AC_PATH_PROG(dot, dot)
AC_PATH_PROG(dblatex, dblatex)
AC_PATH_PROG(gzip, gzip)
AC_PATH_PROG(pv, pv, pv)
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])
@@ -179,6 +175,15 @@ if ! $perl -e 'open(FOO, "-|", "true"); while (<FOO>) { print; }; close FOO or d
fi
AC_MSG_RESULT(yes)
# Figure out where to install Perl modules.
AC_MSG_CHECKING([for the Perl installation prefix])
perlversion=$($perl -e 'use Config; print $Config{version};')
perlarchname=$($perl -e 'use Config; print $Config{archname};')
AC_SUBST(perllibdir, [$\(libdir\)/perl5/site_perl/$perlversion/$perlarchname])
AC_MSG_RESULT($perllibdir)
NEED_PROG(cat, cat)
NEED_PROG(tr, tr)
AC_ARG_WITH(coreutils-bin, AC_HELP_STRING([--with-coreutils-bin=PATH],
@@ -186,6 +191,7 @@ AC_ARG_WITH(coreutils-bin, AC_HELP_STRING([--with-coreutils-bin=PATH],
coreutils=$withval, coreutils=$(dirname $cat))
AC_SUBST(coreutils)
AC_ARG_WITH(docbook-rng, AC_HELP_STRING([--with-docbook-rng=PATH],
[path of the DocBook RelaxNG schema]),
docbookrng=$withval, docbookrng=/docbook-rng-missing)
@@ -196,83 +202,86 @@ AC_ARG_WITH(docbook-xsl, AC_HELP_STRING([--with-docbook-xsl=PATH],
docbookxsl=$withval, docbookxsl=/docbook-xsl-missing)
AC_SUBST(docbookxsl)
AC_ARG_WITH(xml-flags, AC_HELP_STRING([--with-xml-flags=FLAGS],
[extra flags to be passed to xmllint and xsltproc]),
xmlflags=$withval, xmlflags=)
AC_SUBST(xmlflags)
AC_ARG_WITH(store-dir, AC_HELP_STRING([--with-store-dir=PATH],
[path of the Nix store]),
[path of the Nix store (defaults to /nix/store)]),
storedir=$withval, storedir='/nix/store')
AC_SUBST(storedir)
AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl=PATH],
[prefix of the OpenSSL library]),
openssl=$withval, openssl=)
AM_CONDITIONAL(HAVE_OPENSSL, test -n "$openssl")
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.])
fi
AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2=PATH],
[prefix of bzip2]),
bzip2=$withval, bzip2=)
AM_CONDITIONAL(HAVE_BZIP2, test -n "$bzip2")
ATERM_VERSION=2.5
AC_SUBST(ATERM_VERSION)
if test -z "$bzip2"; then
# Headers and libraries will be used from the temporary installation
# in externals/inst-bzip2.
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}/nix'
# But for testing, we have to use the temporary copy :-(
bzip2_bin_test='${top_builddir}/externals/inst-bzip2/bin'
else
bzip2_lib="-L$bzip2/lib -lbz2"
bzip2_include="-I$bzip2/include"
bzip2_bin="$bzip2/bin"
bzip2_bin_test="$bzip2/bin"
fi
AC_SUBST(bzip2_lib)
AC_SUBST(bzip2_include)
AC_SUBST(bzip2_bin)
AC_SUBST(bzip2_bin_test)
# Look for OpenSSL, an optional dependency.
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])
PKG_CHECK_MODULES([OPENSSL], [libcrypto],
[AC_DEFINE([HAVE_OPENSSL], [1], [Whether to use OpenSSL.])
CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"
have_openssl=1], [true])
AM_CONDITIONAL(HAVE_OPENSSL, test "$have_openssl" = 1)
# Look for libbz2, a required dependency.
AC_CHECK_LIB([bz2], [BZ2_bzWriteOpen], [true],
[AC_MSG_ERROR([Nix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])])
AC_CHECK_HEADERS([bzlib.h], [true],
[AC_MSG_ERROR([Nix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])])
# Look for SQLite, a required dependency.
PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CXXFLAGS"])
AC_ARG_WITH(sqlite, AC_HELP_STRING([--with-sqlite=PATH],
[prefix of SQLite]),
sqlite=$withval, sqlite=)
AM_CONDITIONAL(HAVE_SQLITE, test -n "$sqlite")
SQLITE_VERSION=3070500
AC_SUBST(SQLITE_VERSION)
if test -z "$sqlite"; then
sqlite_lib='${top_builddir}/externals/sqlite-autoconf-$(SQLITE_VERSION)/libsqlite3.la'
sqlite_include='-I${top_builddir}/externals/sqlite-autoconf-$(SQLITE_VERSION)'
sqlite_bin='${top_builddir}/externals/sqlite-autoconf-$(SQLITE_VERSION)'
else
sqlite_lib="-L$sqlite/lib -lsqlite3"
sqlite_include="-I$sqlite/include"
sqlite_bin="$sqlite/bin"
fi
AC_SUBST(sqlite_lib)
AC_SUBST(sqlite_include)
AC_SUBST(sqlite_bin)
# Whether to use the Boehm garbage collector.
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
[enable garbage collection in the Nix expression evaluator (requires Boehm GC)]),
gc=$enableval, gc=)
if test -n "$gc"; then
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]),
gc=$enableval, gc=no)
if test "$gc" = yes; then
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
boehmgc_lib="-L$boehmgc/lib -lgc"
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
fi
AC_SUBST(boehmgc_lib)
# Check for the required Perl dependencies (DBI and DBD::SQLite).
perlFlags="-I$perllibdir"
AC_ARG_WITH(dbi, AC_HELP_STRING([--with-dbi=PATH],
[prefix of the Perl DBI library]),
perlFlags="$perlFlags -I$withval")
AC_ARG_WITH(dbd-sqlite, AC_HELP_STRING([--with-dbd-sqlite=PATH],
[prefix of the Perl DBD::SQLite library]),
perlFlags="$perlFlags -I$withval")
AC_MSG_CHECKING([whether DBD::SQLite works])
if ! $perl $perlFlags -e 'use DBI; use DBD::SQLite;' 2>&5; then
AC_MSG_RESULT(no)
AC_MSG_FAILURE([The Perl modules DBI and/or DBD::SQLite are missing.])
fi
AC_MSG_RESULT(yes)
AC_SUBST(perlFlags)
# Whether to build the Perl bindings
AC_MSG_CHECKING([whether to build the Perl bindings])
AC_ARG_ENABLE(perl-bindings, AC_HELP_STRING([--enable-perl-bindings],
[whether to build the Perl bindings (recommended) [default=yes]]),
perlbindings=$enableval, perlbindings=yes)
if test "$enable_shared" = no; then
# Perl bindings require shared libraries.
perlbindings=no
fi
AM_CONDITIONAL(PERL_BINDINGS, test "$perlbindings" = "yes")
AC_SUBST(perlbindings)
AC_MSG_RESULT($perlbindings)
AC_ARG_ENABLE(init-state, AC_HELP_STRING([--disable-init-state],
@@ -286,19 +295,23 @@ AC_CHECK_FUNCS([setresuid setreuid lchown])
# Nice to have, but not essential.
AC_CHECK_FUNCS([strsignal posix_fallocate nanosleep])
AC_CHECK_FUNCS([strsignal posix_fallocate nanosleep sysconf])
# This is needed if ATerm or bzip2 are static libraries,
# and the Nix libraries are dynamic.
# This is needed if bzip2 is a static library, and the Nix libraries
# are dynamic.
if test "$(uname)" = "Darwin"; then
LDFLAGS="-all_load $LDFLAGS"
fi
# Figure out the extension of dynamic libraries.
eval dynlib_suffix=$shrext_cmds
AC_SUBST(dynlib_suffix)
AM_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile
externals/Makefile
src/Makefile
src/bin2c/Makefile
src/boost/Makefile
@@ -315,11 +328,9 @@ AC_CONFIG_FILES([Makefile
src/nix-setuid-helper/Makefile
src/nix-log2xml/Makefile
src/bsdiff-4.3/Makefile
perl/Makefile
scripts/Makefile
corepkgs/Makefile
corepkgs/nar/Makefile
corepkgs/buildenv/Makefile
corepkgs/channels/Makefile
doc/Makefile
doc/manual/Makefile
misc/Makefile

View File

@@ -1 +1,11 @@
SUBDIRS = nar buildenv channels
all-local: config.nix
files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh derivation.nix
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
$(INSTALL_DATA) config.nix $(files) $(DESTDIR)$(datadir)/nix/corepkgs
include ../substitute.mk
EXTRA_DIST = config.nix.in $(files)

View File

@@ -1,9 +1,12 @@
{system, derivations, manifest}:
with import <nix/config.nix>;
{ derivations, manifest }:
derivation {
name = "user-environment";
system = system;
builder = ./builder.pl;
system = builtins.currentSystem;
builder = perl;
args = [ "-w" ./buildenv.pl ];
manifest = manifest;
@@ -15,4 +18,7 @@ derivation {
# Building user environments remotely just causes huge amounts of
# network traffic, so don't do that.
preferLocalBuild = true;
# Don't build in a chroot because Nix's dependencies may not be there.
__noChroot = true;
}

View File

@@ -1,5 +1,3 @@
#! @perl@ -w
use strict;
use Cwd;
use IO::Handle;

View File

@@ -1,11 +0,0 @@
all-local: builder.pl
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
$(INSTALL_DATA) $(srcdir)/default.nix $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
$(INSTALL_PROGRAM) builder.pl $(DESTDIR)$(datadir)/nix/corepkgs/buildenv
include ../../substitute.mk
EXTRA_DIST = default.nix builder.pl.in

View File

@@ -1,11 +0,0 @@
all-local: unpack.sh
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/channels
$(INSTALL_DATA) $(srcdir)/unpack.nix $(DESTDIR)$(datadir)/nix/corepkgs/channels
$(INSTALL_PROGRAM) unpack.sh $(DESTDIR)$(datadir)/nix/corepkgs/channels
include ../../substitute.mk
EXTRA_DIST = unpack.nix unpack.sh.in

View File

@@ -1,7 +0,0 @@
{system, inputs}:
derivation {
name = "channels";
builder = ./unpack.sh;
inherit system inputs;
}

View File

@@ -1,35 +0,0 @@
#! @shell@ -e
# Cygwin compatibility hack: bunzip2 expects cygwin.dll in $PATH.
export PATH=@coreutils@
@coreutils@/mkdir $out
@coreutils@/mkdir $out/tmp
cd $out/tmp
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 -
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
cd ..
@coreutils@/rmdir tmp

13
corepkgs/config.nix.in Normal file
View File

@@ -0,0 +1,13 @@
let
fromEnv = var: def:
let val = builtins.getEnv var; in
if val != "" then val else def;
in {
perl = "@perl@";
shell = "@shell@";
coreutils = "@coreutils@";
bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
tar = "@tar@";
tr = "@tr@";
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
}

27
corepkgs/derivation.nix Normal file
View File

@@ -0,0 +1,27 @@
/* This is the implementation of the derivation builtin function.
It's actually a wrapper around the derivationStrict primop. */
drvAttrs @ { outputs ? [ "out" ], ... }:
let
strict = derivationStrict drvAttrs;
commonAttrs = drvAttrs // (builtins.listToAttrs outputsList) //
{ all = map (x: x.value) outputsList;
inherit drvAttrs;
};
outputToAttrListElement = outputName:
{ name = outputName;
value = commonAttrs // {
outPath = builtins.getAttr outputName strict;
drvPath = strict.drvPath;
type = "derivation";
inherit outputName;
};
};
outputsList = map outputToAttrListElement outputs;
in (builtins.head outputsList).value

34
corepkgs/nar.nix Normal file
View File

@@ -0,0 +1,34 @@
with import <nix/config.nix>;
let
builder = builtins.toFile "nar.sh"
''
export PATH=${nixBinDir}:${coreutils}
echo "packing $storePath..."
mkdir $out
dst=$out/tmp.nar.bz2
set -o pipefail
nix-store --dump "$storePath" | ${bzip2} > $dst
nix-hash --flat --type $hashAlgo --base32 $dst > $out/narbz2-hash
mv $out/tmp.nar.bz2 $out/$(cat $out/narbz2-hash).nar.bz2
'';
in
{ storePath, hashAlgo }:
derivation {
name = "nar";
system = builtins.currentSystem;
builder = shell;
args = [ "-e" builder ];
inherit storePath hashAlgo;
# Don't build in a chroot because Nix's dependencies may not be there.
__noChroot = true;
}

View File

@@ -1,11 +0,0 @@
all-local: nar.sh
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/nar
$(INSTALL_DATA) $(srcdir)/nar.nix $(DESTDIR)$(datadir)/nix/corepkgs/nar
$(INSTALL_PROGRAM) nar.sh $(DESTDIR)$(datadir)/nix/corepkgs/nar
include ../../substitute.mk
EXTRA_DIST = nar.nix nar.sh.in

View File

@@ -1,7 +0,0 @@
{system, storePath, hashAlgo}:
derivation {
name = "nar";
builder = ./nar.sh;
inherit system storePath hashAlgo;
}

View File

@@ -1,12 +0,0 @@
#! @shell@ -e
echo "packing $storePath into $out..."
@coreutils@/mkdir $out
dst=$out/tmp.nar.bz2
@bindir@/nix-store --dump "$storePath" > tmp
@bzip2@ < tmp > $dst
@bindir@/nix-hash --flat --type $hashAlgo --base32 $dst > $out/narbz2-hash
@coreutils@/mv $out/tmp.nar.bz2 $out/$(@coreutils@/cat $out/narbz2-hash).nar.bz2

View File

@@ -0,0 +1,17 @@
with import <nix/config.nix>;
{ name, channelName, src }:
derivation {
system = builtins.currentSystem;
builder = shell;
args = [ "-e" ./unpack-channel.sh ];
inherit name channelName src bzip2 tar tr;
PATH = "${nixBinDir}:${coreutils}";
# No point in doing this remotely.
preferLocalBuild = true;
# Don't build in a chroot because Nix's dependencies may not be there.
__noChroot = true;
}

View File

@@ -0,0 +1,4 @@
mkdir $out
cd $out
$bzip2 -d < $src | $tar xf -
mv * $out/$channelName

View File

@@ -1,5 +1,5 @@
XMLLINT = $(xmllint) $(xmlflags)
XSLTPROC = $(xsltproc) $(xmlflags) \
XMLLINT = $(xmllint) --nonet $(xmlflags)
XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
--param section.autolabel 1 \
--param section.label.includes.component.label 1 \
--param html.stylesheet \'style.css\' \
@@ -29,29 +29,41 @@ MANUAL_SRCS = manual.xml introduction.xml installation.xml \
package-management.xml writing-nix-expressions.xml builtins.xml \
build-farm.xml \
$(man1_MANS:.1=.xml) $(man8_MANS:.8=.xml) \
troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \
troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml opt-inst-syn.xml \
env-common.xml quick-start.xml nix-lang-ref.xml glossary.xml \
conf-file.xml release-notes.xml \
style.css images
# Do XInclude processing.
manual.xmli: $(MANUAL_SRCS) version.txt
$(XMLLINT) --xinclude $< -o $@.tmp
mv $@.tmp $@
# Note: RelaxNG validation requires xmllint >= 2.7.4.
manual.is-valid: $(MANUAL_SRCS) version.txt
$(XMLLINT) --noout --nonet --xinclude --noxincludenode --relaxng $(docbookrng)/docbook.rng $<
manual.is-valid: manual.xmli
$(XSLTPROC) --novalid --stringparam profile.condition manual \
$(docbookxsl)/profiling/profile.xsl $< 2> /dev/null | \
$(XMLLINT) --noout --relaxng $(docbookrng)/docbook.rng -
touch $@
version.txt:
echo -n $(VERSION) > version.txt
man $(MANS): $(MANUAL_SRCS) manual.is-valid
$(XSLTPROC) --nonet --xinclude $(docbookxsl)/manpages/docbook.xsl manual.xml
man $(MANS): manual.is-valid
$(XSLTPROC) --stringparam profile.condition manpage \
$(docbookxsl)/profiling/profile.xsl manual.xmli 2> /dev/null | \
$(XSLTPROC) $(docbookxsl)/manpages/docbook.xsl -
manual.html: $(MANUAL_SRCS) manual.is-valid images
$(XSLTPROC) --nonet --xinclude --output manual.html \
$(docbookxsl)/html/docbook.xsl manual.xml
$(XSLTPROC) --xinclude --stringparam profile.condition manual \
$(docbookxsl)/profiling/profile.xsl manual.xml | \
$(XSLTPROC) --output manual.html $(docbookxsl)/html/docbook.xsl -
manual.pdf: $(MANUAL_SRCS) manual.is-valid images
if test "$(dblatex)" != ""; then \
$(dblatex) $(dblatex_opts) manual.xml; \
$(XSLTPROC) --xinclude --stringparam profile.condition manual \
$(docbookxsl)/profiling/profile.xsl manual.xml | \
$(dblatex) -o manual.pdf $(dblatex_opts) -; \
else \
echo "Please install dblatex and rerun configure."; \
exit 1; \
@@ -64,12 +76,12 @@ NEWS_OPTS = \
--stringparam header.rule 0
NEWS.html: release-notes.xml
$(XSLTPROC) --nonet --xinclude --output $@ $(NEWS_OPTS) \
$(XSLTPROC) --xinclude --output $@ $(NEWS_OPTS) \
$(docbookxsl)/html/docbook.xsl release-notes.xml
NEWS.txt: release-notes.xml
$(XSLTPROC) --nonet --xinclude quote-literals.xsl release-notes.xml | \
$(XSLTPROC) --nonet --output $@.tmp.html $(NEWS_OPTS) \
$(XSLTPROC) --xinclude quote-literals.xsl release-notes.xml | \
$(XSLTPROC) --output $@.tmp.html $(NEWS_OPTS) \
$(docbookxsl)/html/docbook.xsl -
LANG=en_US $(w3m) -dump $@.tmp.html > $@
rm $@.tmp.html
@@ -96,7 +108,7 @@ images:
cp $(docbookxsl)/images/callouts/*.gif images/callouts
chmod -R +w images
KEEP = manual.html manual.is-valid version.txt $(MANS) NEWS.html NEWS.txt
KEEP = manual.html manual.xmli manual.is-valid version.txt $(MANS) NEWS.html NEWS.txt
EXTRA_DIST = $(MANUAL_SRCS) $(FIGURES) $(KEEP)

View File

@@ -1,67 +1,17 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id='chap-build-farm'>
xml:id='chap-distributed-builds'>
<title>Setting up a Build Farm</title>
<title>Setting Up Distributed Builds</title>
<para>This chapter provides some sketchy information on how to set up
a Nix-based build farm. Nix is particularly suited as a basis for a
build farm, since:
<itemizedlist>
<listitem><para>Nix supports distributed builds: a local Nix
installation can forward Nix builds to other machines over the
network. This allows multiple builds to be performed in parallel
(thus improving performance), but more in importantly, it allows Nix
to perform multi-platform builds in a semi-transparent way. For
instance, if you perform a build for a
<literal>powerpc-darwin</literal> on an
<literal>i686-linux</literal> machine, Nix can automatically forward
the build to a <literal>powerpc-darwin</literal> machine, if
available.</para></listitem>
<listitem><para>The Nix expression language is ideal for describing
build jobs, plus all their dependencies. For instance, if your
package has some dependency, you don't have to manually install it
on all the machines in the build farm; they will be built
automatically.</para></listitem>
<listitem><para>Proper release management requires that builds (if
deployed) are traceable: it should be possible to figure out from
exactly what sources they were built, in what configuration, etc.;
and it should be possible to reproduce the build, if necessary. Nix
makes this possible since Nix's hashing scheme uniquely identifies
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 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
available through a channel, so successful builds can be deployed to
users immediately.</para></listitem>
</itemizedlist>
</para>
<section><title>Overview</title>
<para>TODO</para>
<para>The sources of the Nix build farm are at <link
xlink:href='https://svn.nixos.org/repos/nix/release/trunk'/>.</para>
</section>
<section xml:id='sec-distributed-builds'><title>Setting up distributed builds</title>
<para>Nix supports distributed builds: a local Nix installation can
forward Nix builds to other machines over the network. This allows
multiple builds to be performed in parallel (thus improving
performance) and allows Nix to perform multi-platform builds in a
semi-transparent way. For instance, if you perform a build for a
<literal>powerpc-darwin</literal> on an <literal>i686-linux</literal>
machine, Nix can automatically forward the build to a
<literal>powerpc-darwin</literal> machine, if available.</para>
<para>You can enable distributed builds by setting the environment
variable <envar>NIX_BUILD_HOOK</envar> to point to a program that Nix
@@ -79,22 +29,23 @@ variable</link>.</para>
<filename>remote-systems.conf</filename></title>
<programlisting>
nix@mcflurry.labs.cs.uu.nl powerpc-darwin /home/nix/.ssh/id_quarterpounder_auto 2
nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 1
nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 1 kvm
nix@itchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2
nix@poochie.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2 kvm perf
</programlisting>
</example>
<para>An example build hook can be found in the Nix build farm
sources: <link
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
perform the remote build. You should define a list of available build
machines and set the environment variable
<envar>REMOTE_SYSTEMS</envar> to point to it. An example
configuration is shown in <xref linkend='ex-remote-systems' />. Each
line in the file specifies a machine, with the following bits of
information:
<para>Nix ships with a build hook that should be suitable for most
purposes. It uses <command>ssh</command> and
<command>nix-copy-closure</command> to copy the build inputs and
outputs and perform the remote build. To use it, you should set
<envar>NIX_BUILD_HOOK</envar> to
<filename><replaceable>prefix</replaceable>/libexec/nix/build-remote.pl</filename>.
You should also define a list of available build machines and point
the environment variable <envar>NIX_REMOTE_SYSTEMS</envar> to it. An
example configuration is shown in <xref linkend='ex-remote-systems'
/>. Each line in the file specifies a machine, with the following
bits of information:
<orderedlist>
@@ -104,34 +55,59 @@ information:
be an alias defined in your
<filename>~/.ssh/config</filename>.</para></listitem>
<listitem><para>The Nix platform type identifier, such as
<literal>powerpc-darwin</literal>.</para></listitem>
<listitem><para>A comma-separated list of Nix platform type
identifiers, such as <literal>powerpc-darwin</literal>. It is
possible for a machine to support multiple platform types, e.g.,
<literal>i686-linux,x86_64-linux</literal>.</para></listitem>
<listitem><para>The SSH private key to be used to log in to the
remote machine. Since builds should be non-interactive, this key
should not have a passphrase!</para></listitem>
<listitem><para>The maximum <quote>load</quote> of the remote
machine. This is just the maximum number of jobs that
<listitem><para>The maximum number of builds that
<filename>build-remote.pl</filename> will execute in parallel on the
machine. Typically this should be equal to the number of
CPUs.</para></listitem>
machine. Typically this should be equal to the number of CPU cores.
For instance, the machine <literal>itchy</literal> in the example
will execute up to 8 builds in parallel.</para></listitem>
<listitem><para>The “speed factor”, indicating the relative speed of
the machine. If there are multiple machines of the right type, Nix
will prefer the fastest, taking load into account.</para></listitem>
<listitem><para>A comma-separated list of <emphasis>supported
features</emphasis>. If a derivation has the
<varname>requiredSystemFeatures</varname> attribute, then
<filename>build-remote.pl</filename> will only perform the
derivation on a machine that has the specified features. For
instance, the attribute
<programlisting>
requiredSystemFeatures = [ "kvm" ];
</programlisting>
will cause the build to be performed on a machine that has the
<literal>kvm</literal> feature (i.e., <literal>scratchy</literal> in
the example above).</para></listitem>
<listitem><para>A comma-separated list of <emphasis>mandatory
features</emphasis>. A machine will only be used to build a
derivation if all of the machines mandatory features appear in the
derivations <varname>requiredSystemFeatures</varname> attribute.
Thus, in the example, the machine <literal>poochie</literal> will
only do derivations that have
<varname>requiredSystemFeatures</varname> set to <literal>["kvm"
"perf"]</literal> or <literal>["perf"]</literal>.</para></listitem>
</orderedlist>
You should also set up the environment variable
<envar>CURRENT_LOAD</envar> to point at a file that
<filename>build-remote.pl</filename> uses to remember how many jobs it
is currently executing remotely. It doesn't look at the actual load
on the remote machine, so if you have multiple instances of Nix
running, they should use the same <envar>CURRENT_LOAD</envar>
file<footnote><para>Although there are probably some race conditions
in the script right now.</para></footnote>. Maybe in the future
<filename>build-remote.pl</filename> will look at the actual remote
load. The load file should exist, so you should just create it as an
empty file initially.</para>
<envar>NIX_CURRENT_LOAD</envar> to point at a directory (e.g.,
<filename>/var/run/nix/current-load</filename>) that
<filename>build-remote.pl</filename> uses to remember how many builds
it is currently executing remotely. It doesn't look at the actual
load on the remote machine, so if you have multiple instances of Nix
running, they should use the same <envar>NIX_CURRENT_LOAD</envar>
file. Maybe in the future <filename>build-remote.pl</filename> will
look at the actual remote load.</para>
</section>
</chapter>

View File

@@ -43,10 +43,10 @@ is also available as <function>builtins.derivation</function>.</para>
<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:
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>
@@ -442,10 +442,10 @@ x: x + 456</programlisting>
Example:
<programlisting>
builtins.listToAttrs [
{name = "foo"; value = 123;}
{name = "bar"; value = 456;}
]
builtins.listToAttrs
[ { name = "foo"; value = 123; }
{ name = "bar"; value = 456; }
]
</programlisting>
evaluates to
@@ -466,10 +466,10 @@ builtins.listToAttrs [
example,
<programlisting>
map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
map (x: "foo" + x) [ "bar" "bla" "abc" ]</programlisting>
evaluates to <literal>["foobar" "foobla"
"fooabc"]</literal>.</para></listitem>
evaluates to <literal>[ "foobar" "foobla" "fooabc"
]</literal>.</para></listitem>
</varlistentry>
@@ -491,10 +491,10 @@ map (x: "foo" + x) ["bar" "bla" "abc"]</programlisting>
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,
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>
returns <literal>{ name = "nix"; version = "0.12pre12876";
}</literal>.</para></listitem>
</varlistentry>
@@ -550,9 +550,9 @@ in config.someSetting</programlisting>
exist in <replaceable>attrs</replaceable>. For instance,
<screen>
removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]</screen>
evaluates to <literal>{y = 2;}</literal>.</para></listitem>
evaluates to <literal>{ y = 2; }</literal>.</para></listitem>
</varlistentry>
@@ -632,7 +632,7 @@ removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"]</screen>
linkend='ex-hello-builder' /> into one file:
<programlisting>
{stdenv, fetchurl, perl}:
{ stdenv, fetchurl, perl }:
stdenv.mkDerivation {
name = "hello-2.1.1";
@@ -765,12 +765,12 @@ in foo</programlisting>
using <function>toXML</function></title>
<programlisting><![CDATA[
{stdenv, fetchurl, libxslt, jira, uberwiki}:
{ stdenv, fetchurl, libxslt, jira, uberwiki }:
stdenv.mkDerivation (rec {
name = "web-server";
buildInputs = [libxslt];
buildInputs = [ libxslt ];
builder = builtins.toFile "builder.sh" "
source $stdenv/setup

View File

@@ -6,7 +6,7 @@
<para>A number of persistent settings of Nix are stored in the file
<filename><replaceable>prefix</replaceable>/etc/nix/nix.conf</filename>.
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>.
This file is a list of <literal><replaceable>name</replaceable> =
<replaceable>value</replaceable></literal> pairs, one per line.
Comments start with a <literal>#</literal> character. An example
@@ -136,6 +136,25 @@ env-keep-derivations = false
</varlistentry>
<varlistentry xml:id="conf-build-timeout"><term><literal>build-timeout</literal></term>
<listitem>
<para>This option defines the maximum number of seconds that a
builder can run. This is useful (for instance in a automated
build system) to catch builds that are stuck in an infinite loop
but keep writing to their standard output or standard error. It
can be overriden using the <option
linkend="opt-timeout">--timeout</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>
@@ -206,6 +225,15 @@ env-keep-derivations = false
</varlistentry>
<varlistentry><term><literal>build-use-substitutes</literal></term>
<listitem><para>If set to <literal>true</literal> (default), Nix
will use binary substitutes if available. This option can be
disabled to force building from source.</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,
@@ -233,6 +261,21 @@ build-use-chroot = /dev /proc /bin</programlisting>
</varlistentry>
<varlistentry><term><literal>build-cache-failures</literal></term>
<listitem><para>If set to <literal>true</literal>, Nix will
“cache” build failures, meaning that it will remember (in its
database) that a derivation previously failed. If you then try to
build the derivation again, Nix will immediately fail rather than
perform the build again. Failures in fixed-output derivations
(such as <function>fetchurl</function> calls) are never cached.
The “failed” status of a derivation can be cleared using
<command>nix-store --clear-failed-paths</command>. By default,
failure caching is disabled.</para></listitem>
</varlistentry>
<varlistentry><term><literal>system</literal></term>
<listitem><para>This option specifies the canonical Nix system

View File

@@ -7,9 +7,43 @@
<para>Most Nix commands interpret the following environment variables:</para>
<variablelist>
<variablelist xml:id="env-common">
<varlistentry><term><envar>NIX_PATH</envar></term>
<listitem>
<para>A colon-separated list of directories used to look up Nix
expressions enclosed in angle brackets (i.e.,
<literal>&lt;<replaceable>path</replaceable>></literal>). For
instance, the value
<screen>
/home/eelco/Dev:/etc/nixos</screen>
will cause Nix to look for paths relative to
<filename>/home/eelco/Dev</filename> and
<filename>/etc/nixos</filename>, in that order. It is also
possible to match paths against a prefix. For example, the value
<screen>
nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
will cause Nix to search for
<literal>&lt;nixpkgs/<replaceable>path</replaceable>></literal> in
<filename>/home/eelco/Dev/nixpkgs-branch/<replaceable>path</replaceable></filename>
and
<filename>/etc/nixos/nixpkgs/<replaceable>path</replaceable></filename>.
</para>
<para>The search path can be extended using the
<option>-I</option> option, which takes precedence over
<envar>NIX_PATH</envar>.</para></listitem>
</varlistentry>
<varlistentry><term><envar>NIX_IGNORE_SYMLINK_STORE</envar></term>
<listitem>
@@ -119,9 +153,13 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<para>Specifies the location of the <emphasis>build hook</emphasis>,
which is a program (typically some script) that Nix will call
whenever it wants to build a derivation. This is used to implement
distributed builds (see <xref linkend="sec-distributed-builds"
/>). The protocol by which the calling Nix process and the build
hook communicate is as follows.</para>
distributed builds<phrase condition="manual"> (see <xref
linkend="chap-distributed-builds" />)</phrase>.</para>
<!--
The protocol by
which the calling Nix process and the build hook communicate is as
follows.
<para>The build hook is called with the following command-line
arguments:
@@ -131,7 +169,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>A boolean value <literal>0</literal> or
<literal>1</literal> specifying whether Nix can locally execute
more builds, as per the <link
linkend="opt-max-jobs"><option>--max-jobs</option> option</link>.
linkend="opt-max-jobs"><option>- -max-jobs</option> option</link>.
The purpose of this argument is to allow the hook to not have to
maintain bookkeeping for the local machine.</para></listitem>
@@ -216,7 +254,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>The reference graph of the inputs, in the format
accepted by the command <command>nix-store
--register-validity</command>. It is necessary to run this
- -register-validity</command>. It is necessary to run this
command on the remote machine after copying the inputs to inform
Nix on the remote machine that the inputs are valid
paths.</para></listitem>
@@ -233,6 +271,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<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>
@@ -255,12 +294,13 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<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
<phrase condition="manual">See <xref linkend="sec-sharing-packages"
/> for details.</phrase> 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

View File

@@ -15,11 +15,11 @@
<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>Mac OS X.</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>
@@ -28,6 +28,7 @@
partition.</para></warning>
</listitem>
-->
</itemizedlist>
@@ -47,17 +48,17 @@ 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.nixos.org/repos/nix/nix/trunk">Subversion
xlink:href="https://github.com/NixOS/nix">Git
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.nixos.org/repos/nix/nix/trunk nix</screen>
$ git clone https://github.com/NixOS/nix</screen>
<para>Likewise, specific releases can be obtained from the <link
xlink:href="https://svn.nixos.org/repos/nix/nix/tags">tags
directory</link> of the repository.</para>
xlink:href="https://github.com/NixOS/nix/tags">tags</link> of the
repository.</para>
</section>
@@ -69,7 +70,36 @@ from source</emphasis>. Binary releases (e.g., RPMs) have no
prerequisites.</para>
<para>A fairly recent version of GCC/G++ is required. Version 2.95
and higher should work.</para>
and higher should work. Clang will also work.</para>
<para>Nix requires Perl, version 5.8 or higher.</para>
<para>Nix requires <command>pkg-config</command> to locate its
dependencies. If your distribution does not provide it, you can get
it from <link
xlink:href="http://www.freedesktop.org/wiki/Software/pkg-config"
/>.</para>
<para>Nix requires the bzip2 compressor program and the
<literal>libbz2</literal> library. Thus you must have bzip2
installed, including development headers and libraries. If your
distribution does not provide these, you can obtain bzip2 from <link
xlink:href="http://www.bzip.org/"/>.</para>
<para>Nix requires the SQLite embedded database library, version
3.6.19 or higher. If your distribution does not provide it, please
install it from <link xlink:href="http://www.sqlite.org/" />.</para>
<para>Nix requires the Perl DBI and DBD::SQLite libraries, which are
available from <link xlink:href="http://search.cpan.org/">CPAN</link>
if your distribution does not provide them.</para>
<para>Nix can optionally use the <link
xlink:href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">Boehm
garbage collector</link> to reduce the evaluators memory consumption.
To enable it, install <literal>pkgconfig</literal> and the Boehm
garbage collector, and pass the flag <option>--enable-gc</option> to
<command>configure</command>.</para>
<para>To build this manual and the man-pages you need the
<command>xmllint</command> and <command>xsltproc</command> programs,
@@ -80,37 +110,20 @@ xlink:href="http://docbook.sourceforge.net/projects/xsl/">DocBook XSL
stylesheets</link> and optionally the <link
xlink:href="http://www.docbook.org/schemas/5x"> DocBook 5.0 RELAX NG
schemas</link>. Note that these are only required if you modify the
manual sources or when you are building from the Subversion
manual sources or when you are building from the Git
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 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 the bzip2 compressor (including the bzip2 library). It
is included in the Nix source distribution. If you build from the
Subversion repository, you must download it yourself and place it in
the <filename>externals/</filename> directory. See
<filename>externals/Makefile.am</filename> for the precise URLs of
this packages. Alternatively, if you already have it installed, you
can use <command>configure</command>'s <option>--with-bzip2</option>
options to point to their respective locations.</para>
<para>Nix can optionally use the <link
xlink:href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">Boehm
garbage collector</link> to reduce the evaluators memory consumption.
To enable it, install <literal>pkgconfig</literal> and the Boehm
garbage collector, and pass the flag <option>--enable-gc</option> to
<command>configure</command>.</para>
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 Git repository.</para>
</section>
@@ -127,8 +140,8 @@ $ make install</screen>
</para>
<para>When building from the Subversion repository, these should be
preceded by the command:
<para>When building from the Git repository, these should be preceded
by the command:
<screen>
$ ./bootstrap.sh</screen>
@@ -314,7 +327,7 @@ bit turned on (like <filename>/tmp</filename>):
<screen>
$ chgrp nixbld /nix/store
$ chmod 1777 /nix/store
$ chmod 1775 /nix/store
</screen>
</para>
@@ -323,7 +336,7 @@ $ chmod 1777 /nix/store
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>):
file</link> (usually <literal>/etc/nix/nix.conf</literal>):
<programlisting>
build-users-group = nixbld
@@ -380,7 +393,7 @@ 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>
$ chown -R nix /nix/store /nix/var/nix</screen>
and of course <command>nix-worker --daemon</command> should be started
under that user, e.g.,

View File

@@ -17,10 +17,10 @@ store</emphasis>, usually the directory
subdirectory such as
<programlisting>
/nix/store/r8vvq9kq18pz08v249h8my6r9vs7s0n3-firefox-2.0.0.1/
/nix/store/nlc4z5y1hm8w9s8vm6m1f5hy962xjmp5-firefox-12.0
</programlisting>
where <literal>r8vvq9kq</literal> is a unique identifier for the
where <literal>nlc4z5</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>
@@ -72,15 +72,14 @@ sounds risky, but it works extremely well.</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>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
@@ -264,8 +263,10 @@ 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>
support for variability in software systems. Further funding was
provided by the NIRICT LaQuSo Build Farm project. Development is
currently supported by <link
xlink:href="http://www.logicblox.com/">LogicBlox</link>.</para>
</section>
@@ -275,7 +276,7 @@ provided by the NIRICT LaQuSo Build Farm project.</para>
<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.</para>
up distributed multi-platform building.</para>
</section>
@@ -315,13 +316,12 @@ Upgrading in a Purely Functional Component Deployment Model
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. 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://nixos.org/docs/papers.html">an up-to-date list
of Nix-related papers</link>.</para>
web servers) can be deployed and managed through Nix. An overview of
NixOS is given in the JFP article <citetitle
xlink:href="http://www.st.ewi.tudelft.nl/~dolstra/pubs/nixos-jfp-final.pdf">NixOS:
A Purely Functional Linux Distribution</citetitle>. The Nix homepage
has <link xlink:href="http://nixos.org/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

View File

@@ -5,8 +5,7 @@
<title>Nix User's Guide</title>
<subtitle>Draft (Version <xi:include href="version.txt"
parse="text" />)</subtitle>
<edition>Version <xi:include href="version.txt" parse="text" /></edition>
<author>
<personname>
@@ -14,24 +13,17 @@
<surname>Dolstra</surname>
</personname>
<affiliation>
<orgname>Delft University of Technology</orgname>
<orgdiv>Department of Software Technology</orgdiv>
<orgname>LogicBlox</orgname>
</affiliation>
<contrib>Author</contrib>
</author>
<copyright>
<year>2004</year>
<year>2005</year>
<year>2006</year>
<year>2007</year>
<year>2008</year>
<year>2009</year>
<year>2010</year>
<year>2004-2012</year>
<holder>Eelco Dolstra</holder>
</copyright>
<date>August 2010</date>
<date>May 2012</date>
</info>

View File

@@ -28,8 +28,8 @@
</group>
<replaceable>attrPath</replaceable>
</arg>
<arg><option>--drv-link</option> <replaceable>drvlink</replaceable></arg>
<arg><option>--add-drv-link</option></arg>
<arg><option>--drv-link </option><replaceable>drvlink</replaceable></arg>
<arg><option>--no-out-link</option></arg>
<arg>
<group choice='req'>
@@ -38,6 +38,11 @@
</group>
<replaceable>outlink</replaceable>
</arg>
<arg>
<option>--run-env</option>
<arg><option>--command</option> <replaceable>cmd</replaceable></arg>
<arg><option>--exclude</option> <replaceable>regexp</replaceable></arg>
</arg>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -70,39 +75,45 @@ a root of the Nix garbage collector. This root disappears
automatically when the <filename>result</filename> symlink is deleted
or renamed. So dont rename the symlink.</para></warning>
<para>The subcommand <command>nix-build --run-env</command> will build
the dependencies of the derivation, but not the derivation itself. It
will then start an interactive shell in which all environment
variables defined by the derivation have been set to their
corresponding values. This is useful for reproducing the environment
of a derivation for development.</para>
</refsection>
<refsection><title>Options</title>
<para>See also <xref linkend="sec-common-options" />. All options not
listed here are passed to <command>nix-store --realise</command>,
except for <option>--arg</option> and <option>--attr</option> /
<option>-A</option> which are passed to
<command>nix-instantiate</command>.</para>
<para>All options not listed here are passed to <command>nix-store
--realise</command>, except for <option>--arg</option> and
<option>--attr</option> / <option>-A</option> which are passed to
<command>nix-instantiate</command>. <phrase condition="manual">See
also <xref linkend="sec-common-options" />.</phrase></para>
<variablelist>
<varlistentry><term><option>--add-drv-link</option></term>
<listitem><para>Add a symlink in the current directory to the
store derivation produced by <command>nix-instantiate</command>.
The symlink is called <filename>derivation</filename> (which is
numbered in the case of multiple derivations). The derivation is
a root of the garbage collector until the symlink is deleted or
renamed.</para></listitem>
</varlistentry>
<varlistentry><term><option>--drv-link</option> <replaceable>drvlink</replaceable></term>
<listitem><para>Change the name of the symlink to the derivation
created when <option>--add-drv-link</option> is used from
<filename>derivation</filename> to
<replaceable>drvlink</replaceable>.</para></listitem>
<listitem><para>Add a symlink named
<replaceable>drvlink</replaceable> to the store derivation
produced by <command>nix-instantiate</command>. The derivation is
a root of the garbage collector until the symlink is deleted or
renamed. If there are multiple derivations, numbers are suffixed
to <replaceable>drvlink</replaceable> to distinguish between
them.</para></listitem>
</varlistentry>
<varlistentry><term><option>--add-drv-link</option></term>
<listitem><para>Shorthand for <option>--drv-link</option>
<filename>./derivation</filename>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--no-out-link</option></term>
<listitem><para>Do not create a symlink to the output path. Note
@@ -116,21 +127,46 @@ except for <option>--arg</option> and <option>--attr</option> /
<option>-o</option> <replaceable>outlink</replaceable></term>
<listitem><para>Change the name of the symlink to the output path
created unless <option>--no-out-link</option> is used from
<filename>result</filename> to
created from <filename>result</filename> to
<replaceable>outlink</replaceable>.</para></listitem>
</varlistentry>
</variablelist>
<variablelist condition="manpage">
<xi:include href="opt-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='opt-common']/*)" />
</variablelist>
<para>The following options apply to <command>nix-build --run-env</command>.</para>
<variablelist>
<varlistentry><term><option>--command</option> <replaceable>cmd</replaceable></term>
<listitem><para>In the environment of the derivation, executeq the
command <replaceable>cmd</replaceable> instead of the default
interactive shell.</para></listitem>
</varlistentry>
<varlistentry><term><option>--exclude</option> <replaceable>regexp</replaceable></term>
<listitem><para>Do not build any dependencies whose store path
matches the regular expression <replaceable>regexp</replaceable>.
This option may be specified multiple times.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<screen>
$ nix-build pkgs/top-level/all-packages.nix -A firefox
$ nix-build '&lt;nixpkgs>' -A firefox
store derivation is /nix/store/qybprl8sz2lc...-firefox-1.5.0.7.drv
/nix/store/d18hyl92g30l...-firefox-1.5.0.7
@@ -140,7 +176,31 @@ lrwxrwxrwx <replaceable>...</replaceable> result -> /nix/store/d18hyl92g30l...
$ ls ./result/bin/
firefox firefox-config</screen>
<para>To build the dependencies of the package Pan, and start an
interactive shell in which to build it:
<screen>
$ nix-build '&lt;nixpkgs>' --run-env -A pan
$ tar xf $src
$ cd pan-*
$ ./configure
$ make
$ ./pan/gui/pan
</screen>
</para>
</refsection>
<refsection condition="manpage"><title>Environment variables</title>
<variablelist>
<xi:include href="env-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='env-common']/*)" />
</variablelist>
</refsection>
</refentry>

View File

@@ -19,10 +19,10 @@
<cmdsynopsis>
<command>nix-channel</command>
<group choice='req'>
<arg choice='plain'><option>--add</option> <replaceable>url</replaceable></arg>
<arg choice='plain'><option>--add</option> <replaceable>url</replaceable> <arg choice='opt'><replaceable>name</replaceable></arg></arg>
<arg choice='plain'><option>--remove</option> <replaceable>url</replaceable></arg>
<arg choice='plain'><option>--list</option></arg>
<arg choice='plain'><option>--update</option></arg>
<arg choice='plain'><option>--update</option> <arg rep='repeat'><replaceable>names</replaceable></arg></arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
@@ -31,43 +31,51 @@
<para>A Nix channel is mechanism that allows you to automatically stay
up-to-date with a set of pre-built Nix expressions. A Nix channel is
just a URL that points to a place that contains a set of Nix
expressions, as well as a <command>nix-push</command> manifest. See
also <xref linkend="sec-channels" />.</para>
just a URL that points to a place containing a set of Nix expressions
and a <command>nix-push</command> manifest. <phrase
condition="manual">See also <xref linkend="sec-channels"
/>.</phrase></para>
<para>This command has the following operations:
<variablelist>
<varlistentry><term><option>--add</option> <replaceable>url</replaceable></term>
<varlistentry><term><option>--add</option> <replaceable>url</replaceable> [<replaceable>name</replaceable>]</term>
<listitem><para>Adds <replaceable>url</replaceable> to the list of
subscribed channels.</para></listitem>
<listitem><para>Adds a channel named
<replaceable>name</replaceable> with URL
<replaceable>url</replaceable> to the list of subscribed channels.
If <replaceable>name</replaceable> is omitted, it defaults to the
last component of <replaceable>url</replaceable>, with the
suffixes <literal>-stable</literal> or
<literal>-unstable</literal> removed.</para></listitem>
</varlistentry>
<varlistentry><term><option>--remove</option> <replaceable>url</replaceable></term>
<varlistentry><term><option>--remove</option> <replaceable>name</replaceable></term>
<listitem><para>Removes <replaceable>url</replaceable> from the
list of subscribed channels.</para></listitem>
<listitem><para>Removes the channel named
<replaceable>name</replaceable> from the list of subscribed
channels.</para></listitem>
</varlistentry>
<varlistentry><term><option>--list</option></term>
<listitem><para>Prints the URLs of all subscribed channels on
standard output.</para></listitem>
<listitem><para>Prints the names and URLs of all subscribed
channels on standard output.</para></listitem>
</varlistentry>
<varlistentry><term><option>--update</option></term>
<varlistentry><term><option>--update</option> [<replaceable>names</replaceable>…]</term>
<listitem><para>Downloads the Nix expressions of all subscribed
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>
channels (or only those included in
<replaceable>names</replaceable> if specified), makes them the
default for <command>nix-env</command> operations (by symlinking
them from 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>
@@ -75,8 +83,8 @@ also <xref linkend="sec-channels" />.</para>
</para>
<para>Note that <option>--add</option> and <option>--remove</option>
do not automatically perform an update.</para>
<para>Note that <option>--add</option> does not automatically perform
an update.</para>
<para>The list of subscribed channels is stored in
<filename>~/.nix-channels</filename>.</para>
@@ -90,4 +98,15 @@ respectively.</para>
</refsection>
<refsection><title>Examples</title>
<para>To subscribe to the Nixpkgs channel and install the GNU Hello package:</para>
<screen>
$ nix-channel --add http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable
$ nix-channel --update
$ nix-env -iA nixpkgs.hello</screen>
</refsection>
</refentry>

View File

@@ -24,8 +24,12 @@
</group>
<arg><option>--sign</option></arg>
<arg><option>--gzip</option></arg>
<arg><option>--bzip2</option></arg>
<arg><option>--xz</option></arg>
<arg><option>--show-progress</option></arg>
<arg><option>--include-outputs</option></arg>
<arg choice='plain'>
<arg><replaceable>user@</replaceable></arg><replaceable>machine</replaceable>
<replaceable>user@</replaceable><replaceable>machine</replaceable>
</arg>
<arg choice='plain'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
@@ -84,25 +88,43 @@ those paths. If this bothers you, use
<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>
<filename><replaceable>sysconfdir</replaceable>/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><replaceable>sysconfdir</replaceable>/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>
<varlistentry><term><option>--gzip</option> / <option>--bzip2</option> / <option>--xz</option></term>
<listitem><para>Compress the dump of each path with
<command>gzip</command> before sending it.</para></listitem>
<listitem><para>Compress the dump of each path with respectively
<command>gzip</command>, <command>bzip2</command> or
<command>xz</command> before sending it. The corresponding
decompression program must be installed on the target
machine.</para></listitem>
</varlistentry>
<varlistentry><term><option>--show-progress</option></term>
<listitem><para>Show the progress of each path's transfer as it's made.
This requires the <command>pv</command> utility to be in <envar>PATH</envar>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--include-outputs</option></term>
<listitem><para>Also copy the outputs of store derivations included
in the closure.</para></listitem>
</varlistentry>
</variablelist>
</refsection>

View File

@@ -2,7 +2,7 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-nix-env">
<refmeta>
<refentrytitle>nix-env</refentrytitle>
<manvolnum>1</manvolnum>
@@ -18,7 +18,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>nix-env</command>
<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/*)" />
<xi:include 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>
@@ -60,7 +60,7 @@ environments.</para>
<para><command>nix-env</command> takes exactly one
<emphasis>operation</emphasis> flag which indicates the subcommand to
be performed. These are documented below.</para>
</refsection>
@@ -71,26 +71,26 @@ be performed. These are documented below.</para>
<para>This section lists the options that are common to all
operations. These options are allowed for every subcommand, though
they may not always have an effect. See also <xref
linkend="sec-common-options" />.</para>
they may not always have an effect. <phrase condition="manual">See
also <xref linkend="sec-common-options" />.</phrase></para>
<variablelist>
<varlistentry><term><option>--file</option></term>
<term><option>-f</option></term>
<listitem><para>Specifies the Nix expression (designated below as
the <emphasis>active Nix expression</emphasis>) used by the
<option>--install</option>, <option>--upgrade</option>, and
<option>--query --available</option> operations to obtain
derivations. The default is
<filename>~/.nix-defexpr</filename>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--profile</option></term>
<term><option>-p</option></term>
<listitem><para>Specifies the profile to be used by those
operations that operate on a profile (designated below as the
<emphasis>active profile</emphasis>). A profile is sequence of
@@ -98,11 +98,11 @@ linkend="sec-common-options" />.</para>
which is the <emphasis>current generation</emphasis>. The default
profile is the target of the symbolic link
<filename>~/.nix-profile</filename> (see below).</para></listitem>
</varlistentry>
<varlistentry><term><option>--dry-run</option></term>
<listitem><para>For the <option>--install</option>,
<option>--upgrade</option>, <option>--uninstall</option>,
<option>--switch-generation</option> and
@@ -117,23 +117,25 @@ linkend="sec-common-options" />.</para>
substitute is available).</para></listitem>
</varlistentry>
<varlistentry><term><option>--system-filter</option> <replaceable>system</replaceable></term>
<listitem><para>By default, operations such as <option>--query
--available</option> only include derivations matching the current
platform. This option allows you to use derivations for the
specified platform <replaceable>system</replaceable>. The special
value <literal>*</literal> causes derivations for any platform to
be included.</para></listitem>
--available</option> show derivations matching any platform. This
option allows you to use derivations for the specified platform
<replaceable>system</replaceable>.</para></listitem>
</varlistentry>
</variablelist>
<variablelist condition="manpage">
<xi:include href="opt-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='opt-common']/*)" />
</variablelist>
</refsection>
<!--######################################################################-->
@@ -170,25 +172,25 @@ linkend="sec-common-options" />.</para>
this directory.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>~/.nix-profile</filename></term>
<listitem><para>A symbolic link to the user's current profile. By
default, this symlink points to
<filename><replaceable>prefix</replaceable>/var/nix/profiles/default</filename>.
The <envar>PATH</envar> environment variable should include
<filename>~/.nix-profile/bin</filename> for the user environment
to be visible to the user.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<!--######################################################################-->
@@ -214,7 +216,7 @@ linkend="sec-common-options" />.</para>
<refsection><title>Description</title>
<para>The install operation creates a new user environment, based on
the current generation of the active profile, to which a set of store
paths described by <replaceable>args</replaceable> is added. The
@@ -256,7 +258,7 @@ number of possible ways:
<emphasis>attribute paths</emphasis> that select attributes from the
top-level Nix expression. This is faster than using derivation
names and unambiguous. To find out the attribute paths of available
packages, use <literal>nix-env -qaA '*'</literal>.</para></listitem>
packages, use <literal>nix-env -qaP '*'</literal>.</para></listitem>
<listitem><para>If <option>--from-profile</option>
<replaceable>path</replaceable> is given,
@@ -306,20 +308,20 @@ number of possible ways:
<varlistentry><term><option>--preserve-installed</option></term>
<term><option>-P</option></term>
<listitem><para>Do not remove derivations with a name matching one
of the derivations being installed. Usually, trying to have two
versions of the same package installed in the same generation of a
profile will lead to an error in building the generation, due to
file name clashes between the two versions. However, this is not
the case for all packages.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection xml:id='refsec-nix-env-install-examples'><title>Examples</title>
@@ -327,7 +329,7 @@ number of possible ways:
active Nix expression:
<screen>
$ nix-env --install gcc-3.3.2
$ nix-env --install gcc-3.3.2
installing `gcc-3.3.2'
uninstalling `gcc-3.1'</screen>
@@ -408,15 +410,15 @@ the following paths will be substituted:
/nix/store/8zbipvm4gp9jfqh9nnk1n3bary1a37gs-perl-XML-Parser-2.34
/nix/store/b8a2bg7gnyvvvjjibp4axg9x1hzkw36c-mono-1.1.4
<replaceable>...</replaceable></screen>
</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection xml:id="rsec-nix-env-upgrade"><title>Operation <option>--upgrade</option></title>
@@ -442,7 +444,7 @@ the following paths will be substituted:
</refsection>
<refsection><title>Description</title>
<para>The upgrade operation creates a new user environment, based on
the current generation of the active profile, in which all store paths
are replaced for which there are newer versions in the set of paths
@@ -459,47 +461,47 @@ the same symbolic name, only the one with the highest version is
installed.</para>
</refsection>
<refsection><title>Flags</title>
<variablelist>
<varlistentry><term><option>--lt</option></term>
<listitem><para>Only upgrade a derivation to newer versions. This
is the default.</para></listitem>
</varlistentry>
<varlistentry><term><option>--leq</option></term>
<listitem><para>In addition to upgrading to newer versions, also
“upgrade” to derivations that have the same version. Version are
not a unique identification of a derivation, so there may be many
derivations that have the same version. This flag may be useful
to force “synchronisation” between the installed and available
derivations.</para></listitem>
</varlistentry>
<varlistentry><term><option>--eq</option></term>
<listitem><para><emphasis>Only</emphasis> “upgrade” to derivations
that have the same version. This may not seem very useful, but it
actually is, e.g., when there is a new release of Nixpkgs and you
want to replace installed applications with the same versions
built against newer dependencies (to reduce the number of
dependencies floating around on your system).</para></listitem>
</varlistentry>
<varlistentry><term><option>--always</option></term>
<listitem><para>In addition to upgrading to newer versions, also
“upgrade” to derivations that have the same or a lower version.
I.e., derivations may actually be downgraded depending on what is
available in the active Nix expression.</para></listitem>
</varlistentry>
</variablelist>
@@ -523,10 +525,10 @@ $ nix-env --upgrade pan
$ nix-env -u '*' <lineannotation>(try to upgrade everything)</lineannotation>
upgrading `hello-2.1.2' to `hello-2.1.3'
upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
</refsection>
<refsection xml:id="ssec-version-comparisons"><title>Versions</title>
<para>The upgrade operation determines whether a derivation
@@ -570,14 +572,14 @@ lexicographically (i.e., using case-sensitive string comparison).</para>
2.3a &lt; 2.3c
2.3pre1 &lt; 2.3c
2.3pre1 &lt; 2.3q</screen>
</para>
</refsection>
</refsection>
<!--######################################################################-->
@@ -596,14 +598,14 @@ lexicographically (i.e., using case-sensitive string comparison).</para>
</refsection>
<refsection><title>Description</title>
<para>The uninstall operation creates a new user environment, based on
the current generation of the active profile, from which the store
paths designated by the symbolic names
<replaceable>names</replaceable> are removed.</para>
</refsection>
<refsection><title>Examples</title>
<screen>
@@ -611,11 +613,11 @@ $ nix-env --uninstall gcc
$ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection xml:id="rsec-nix-env-set-flag"><title>Operation <option>--set-flag</option></title>
@@ -632,7 +634,7 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen>
</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
@@ -670,7 +672,7 @@ script:
</para>
</refsection>
<refsection><title>Examples</title>
<para>To prevent the currently installed Firefox from being upgraded:
@@ -716,13 +718,13 @@ $ nix-env --set-flag priority 10 gcc</screen>
</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--query</option></title>
<refsection><title>Synopsis</title>
@@ -738,9 +740,9 @@ $ nix-env --set-flag priority 10 gcc</screen>
<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>
@@ -785,7 +787,7 @@ $ nix-env --set-flag priority 10 gcc</screen>
</arg>
<sbr />
<arg choice='plain' rep='repeat'><replaceable>names</replaceable></arg>
</cmdsynopsis>
@@ -793,7 +795,7 @@ $ nix-env --set-flag priority 10 gcc</screen>
<refsection><title>Description</title>
<para>The query operation displays information about either the store
paths that are installed in the current generation of the active
profile (<option>--installed</option>), or the derivations that are
@@ -817,23 +819,23 @@ operates.</para>
<variablelist>
<varlistentry><term><option>--installed</option></term>
<listitem><para>The query operates on the store paths that are
installed in the current generation of the active profile. This
is the default.</para></listitem>
</varlistentry>
<varlistentry><term><option>--available</option></term>
<term><option>-a</option></term>
<listitem><para>The query operates on the derivations that are
available in the active Nix expression.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
@@ -874,7 +876,7 @@ user environment elements, etc. -->
<varlistentry><term><option>--status</option></term>
<term><option>-s</option></term>
<listitem><para>Print the <emphasis>status</emphasis> of the
derivation. The status consists of three characters. The first
is <literal>I</literal> or <literal>-</literal>, indicating
@@ -888,7 +890,7 @@ user environment elements, etc. -->
third is <literal>S</literal> or <literal>-</literal>, indicating
whether a substitute is available for the
derivation.</para></listitem>
</varlistentry>
<varlistentry><term><option>--attr-path</option></term>
@@ -901,17 +903,17 @@ user environment elements, etc. -->
<literal>nix-env --install</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--no-name</option></term>
<listitem><para>Suppress printing of the <literal>name</literal>
attribute of each derivation.</para></listitem>
</varlistentry>
<varlistentry><term><option>--compare-versions</option> /
<option>-c</option></term>
<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
@@ -926,21 +928,21 @@ user environment elements, etc. -->
or installed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>=</literal> <replaceable>version</replaceable></term>
<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 package are
available or installed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>- ?</literal></term>
<listitem><para>No version of the package is available or
@@ -951,45 +953,45 @@ user environment elements, etc. -->
</variablelist>
</para></listitem>
</varlistentry>
<varlistentry><term><option>--system</option></term>
<listitem><para>Print the <literal>system</literal> attribute of
the derivation.</para></listitem>
</varlistentry>
<varlistentry><term><option>--drv-path</option></term>
<listitem><para>Print the path of the store
derivation.</para></listitem>
</varlistentry>
<varlistentry><term><option>--out-path</option></term>
<listitem><para>Print the output path of the
derivation.</para></listitem>
</varlistentry>
<varlistentry><term><option>--description</option></term>
<listitem><para>Print a short (one-line) description of the
derivation, if available. The description is taken from the
<literal>meta.description</literal> attribute of the
derivation.</para></listitem>
</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>
@@ -1023,7 +1025,7 @@ IP- ORBit2-2.8.3 <lineannotation>(installed and by definition present)</linea
...
<lineannotation>(show available derivations in the Nix expression <!-- !!! <filename>-->foo.nix<!-- </filename> -->)</lineannotation>
$ nix-env -f ./foo.nix -qa '*'
$ nix-env -f ./foo.nix -qa '*'
foo-1.2.3
$ nix-env -qc '*' <lineannotation>(compare installed versions to whats available)</lineannotation>
@@ -1034,7 +1036,7 @@ firefox-1.0.4 &lt; 1.0.7 <lineannotation>(a more recent version is availab
<replaceable>...</replaceable>
<lineannotation>(show info about a specific package, in XML)</lineannotation>
$ nix-env -qa --xml --description firefox
$ nix-env -qa --xml --description firefox
<![CDATA[<?xml version='1.0' encoding='utf-8'?>
<items>
<item attrPath="0.0.firefoxWrapper"
@@ -1045,8 +1047,8 @@ $ nix-env -qa --xml --description firefox
</refsection>
</refsection>
<!--######################################################################-->
@@ -1067,25 +1069,25 @@ $ nix-env -qa --xml --description firefox
<refsection><title>Description</title>
<para>This operation makes <replaceable>path</replaceable> the current
profile for the user. That is, the symlink
<filename>~/.nix-profile</filename> is made to point to
<replaceable>path</replaceable>.</para>
</refsection>
<refsection><title>Examples</title>
<screen>
$ nix-env -S ~/my-profile</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--list-generations</option></title>
@@ -1101,7 +1103,7 @@ $ nix-env -S ~/my-profile</screen>
<refsection><title>Description</title>
<para>This operation print a list of all the currently existing
generations for the active profile. These may be switched to using
the <option>--switch-generation</option> operation. It also prints
@@ -1121,11 +1123,11 @@ $ nix-env --list-generations
98 2004-02-06 16:24:33 (current)</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--delete-generations</option></title>
@@ -1142,7 +1144,7 @@ $ nix-env --list-generations
<refsection><title>Description</title>
<para>This operation deletes the specified generations of the current
profile. The generations can be a list of generation numbers, or the
special value <literal>old</literal> to delete all non-current
@@ -1150,7 +1152,7 @@ generations. Periodically deleting old generations is important to
make garbage collection effective.</para>
</refsection>
<refsection><title>Examples</title>
<screen>
@@ -1159,11 +1161,11 @@ $ nix-env --delete-generations 3 4 8
$ nix-env -p other_profile --delete-generations old</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--switch-generation</option></title>
@@ -1183,7 +1185,7 @@ $ nix-env -p other_profile --delete-generations old</screen>
<refsection><title>Description</title>
<para>This operation makes generation number
<replaceable>generation</replaceable> the current generation of the
active profile. That is, if the
@@ -1207,11 +1209,11 @@ $ nix-env -G 42
switching from generation 50 to 42</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--rollback</option></title>
@@ -1226,7 +1228,7 @@ switching from generation 50 to 42</screen>
</refsection>
<refsection><title>Description</title>
<para>This operation switches to the “previous” generation of the
active profile, that is, the highest numbered generation lower than
the current generation, if it exists. It is just a convenience
@@ -1246,9 +1248,17 @@ $ nix-env --rolback
error: no generation older than the current (91) exists</screen>
</refsection>
</refsection>
<refsection condition="manpage"><title>Environment variables</title>
<variablelist>
<xi:include href="env-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='env-common']/*)" />
</variablelist>
</refsection>
</refentry>

View File

@@ -36,6 +36,7 @@
<option>--eval-only</option>
<arg><option>--strict</option></arg>
</arg>
<arg choice='plain'><option>--find-file</option></arg>
</group>
<arg><option>--xml</option></arg>
</arg>
@@ -49,8 +50,9 @@
<para>The command <command>nix-instantiate</command> generates <link
linkend="gloss-derivation">store derivations</link> from (high-level)
Nix expressions. It loads and evaluates the Nix expressions in each
of <replaceable>files</replaceable>. Each top-level expression should
evaluate to a derivation, a list of derivations, or a set of
of <replaceable>files</replaceable> (which defaults to
<replaceable>./default.nix</replaceable>). Each top-level expression
should evaluate to a derivation, a list of derivations, or a set of
derivations. The paths of the resulting store derivations are printed
on standard output.</para>
@@ -64,8 +66,8 @@ store derivation instantiation from Nix expressions automatically).
It is most commonly used for implementing new deployment
policies.</para>
<para>See also <xref linkend="sec-common-options" /> for a list of
common options.</para>
<para condition="manual">See also <xref linkend="sec-common-options"
/> for a list of common options.</para>
</refsection>
@@ -100,6 +102,19 @@ common options.</para>
</varlistentry>
<varlistentry><term><option>--find-file</option></term>
<listitem><para>Look up the given files in Nixs search path (as
specified by the <envar>NIX_PATH</envar> environment variable).
If found, print the corresponding absolute paths on standard
output. For instance, if <envar>NIX_PATH</envar> is
<literal>nixpkgs=/home/alice/nixpkgs</literal>, then
<literal>nix-instantiate --find-file nixpkgs/default.nix</literal>
will print
<literal>/home/alice/nixpkgs/default.nix</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--xml</option></term>
<listitem><para>When used with <option>--parse-only</option> and
@@ -127,6 +142,10 @@ common options.</para>
</variablelist>
<variablelist condition="manpage">
<xi:include href="opt-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='opt-common']/*)" />
</variablelist>
</refsection>
@@ -198,4 +217,13 @@ $ echo 'rec { x = "foo"; y = x; }' | nix-instantiate --eval-only --xml --strict
</refsection>
<refsection condition="manpage"><title>Environment variables</title>
<variablelist>
<xi:include href="env-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='env-common']/*)" />
</variablelist>
</refsection>
</refentry>

View File

@@ -12,7 +12,7 @@
<refnamediv>
<refname>nix-prefetch-url</refname>
<refpurpose>copy a file from a URL into the store and print its MD5 hash</refpurpose>
<refpurpose>copy a file from a URL into the store and print its hash</refpurpose>
</refnamediv>
<refsynopsisdiv>

View File

@@ -48,8 +48,9 @@ be performed. These are documented below.</para>
<para>This section lists the options that are common to all
operations. These options are allowed for every subcommand, though
they may not always have an effect. See also <xref
linkend="sec-common-options" /> for a list of common options.</para>
they may not always have an effect. <phrase condition="manual">See
also <xref linkend="sec-common-options" /> for a list of common
options.</phrase></para>
<variablelist>
@@ -57,8 +58,9 @@ linkend="sec-common-options" /> for a list of common options.</para>
<listitem><para>Causes the result of a realisation
(<option>--realise</option> and <option>--force-realise</option>)
to be registered as a root of the garbage collector (see <xref
linkend="ssec-gc-roots" />). The root is stored in
to be registered as a root of the garbage collector<phrase
condition="manual"> (see <xref linkend="ssec-gc-roots"
/>)</phrase>. The root is stored in
<replaceable>path</replaceable>, which must be inside a directory
that is scanned for roots by the garbage collector (i.e.,
typically in a subdirectory of
@@ -112,6 +114,10 @@ lrwxrwxrwx 1 ... 2005-03-13 21:10 /home/eelco/bla/result -> /nix/store/1r1134
</variablelist>
<variablelist condition="manpage">
<xi:include href="opt-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='opt-common']/*)" />
</variablelist>
</refsection>
@@ -212,7 +218,6 @@ linkend="sec-nix-build"><command>nix-build</command></link> does.</para>
<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>
</cmdsynopsis>
</refsection>
@@ -280,16 +285,6 @@ options control what gets deleted and in what order:
</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>
</variablelist>
</para>
@@ -734,6 +729,40 @@ $ nix-store -q --roots $(which svn)
<!--######################################################################-->
<refsection><title>Operation <option>--add</option></title>
<refsection><title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--add</option></arg>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--add</option> adds the specified paths to
the Nix store. It prints the resulting paths in the Nix store on
standard output.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store --add ./foo.c
/nix/store/m7lrha58ph6rcnv109yzx1nk1cj7k7zf-foo.c</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection xml:id='refsec-nix-store-verify'><title>Operation <option>--verify</option></title>
@@ -781,6 +810,44 @@ in Nix itself.</para>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--verify-path</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--verify-path</option></arg>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--verify-paths</option> compares the
contents of the given store paths to their cryptographic hashes stored
in Nixs database. For every changed path, it prints a warning
message. The exit status is 0 if no path has changed, and 1
otherwise.</para>
</refsection>
<refsection><title>Example</title>
<para>To verify the integrity of the <command>svn</command> command and all its dependencies:
<screen>
$ nix-store --verify-path $(nix-store -qR $(which svn))
</screen>
</para>
</refsection>
</refsection>
<!--######################################################################-->
<refsection xml:id='refsec-nix-store-dump'><title>Operation <option>--dump</option></title>
@@ -1053,7 +1120,7 @@ backups and when migrating to different database schemas.</para>
<!--######################################################################-->
<refsection><title>Operation <option>--dump-db</option></title>
<refsection><title>Operation <option>--load-db</option></title>
<refsection>
<title>Synopsis</title>
@@ -1074,4 +1141,129 @@ loads it into the Nix database.</para>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--print-env</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--print-env</option></arg>
<arg choice='plain'><replaceable>drvpath</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>The operation <option>--print-env</option> prints out the
environment of a derivation in a format that can be evaluated by a
shell. The command line arguments of the builder are placed in the
variable <envar>_args</envar>.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store --print-env $(nix-instantiate '&lt;nixpkgs>' -A firefox)
<replaceable></replaceable>
export src; src='/nix/store/plpj7qrwcz94z2psh6fchsi7s8yihc7k-firefox-12.0.source.tar.bz2'
export stdenv; stdenv='/nix/store/7c8asx3yfrg5dg1gzhzyq2236zfgibnm-stdenv'
export system; system='x86_64-linux'
export _args; _args='-e /nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh'
</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--query-failed-paths</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--query-failed-paths</option></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>If build failure caching is enabled through the
<literal>build-cache-failures</literal> configuration option, the
operation <option>--query-failed-paths</option> will print out all
store paths that have failed to build.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store --query-failed-paths
/nix/store/000zi5dcla86l92jn1g997jb06sidm7x-perl-PerlMagick-6.59
/nix/store/0011iy7sfwbc1qj5a1f6ifjnbcdail8a-haskell-gitit-ghc7.0.4-0.8.1
/nix/store/001c0yn1hkh86gprvrb46cxnz3pki7q3-gamin-0.1.10
<replaceable></replaceable>
</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection><title>Operation <option>--clear-failed-paths</option></title>
<refsection>
<title>Synopsis</title>
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--clear-failed-paths</option></arg>
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
<refsection><title>Description</title>
<para>If build failure caching is enabled through the
<literal>build-cache-failures</literal> configuration option, the
operation <option>--clear-failed-paths</option> clears the “failed”
state of the given store paths, allowing them to be built again. This
is useful if the failure was actually transient (e.g. because the disk
was full).</para>
<para>If a path denotes a derivation, its output paths are cleared.
You can provide the argument <literal>*</literal> to clear all store
paths.</para>
</refsection>
<refsection><title>Example</title>
<screen>
$ nix-store --clear-failed-path /nix/store/000zi5dcla86l92jn1g997jb06sidm7x-perl-PerlMagick-6.59
$ nix-store --clear-failed-path *
</screen>
</refsection>
</refsection>
<!--######################################################################-->
<refsection condition="manpage"><title>Environment variables</title>
<variablelist>
<xi:include href="env-common.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(//db:variablelist[@xml:id='env-common']/*)" />
</variablelist>
</refsection>
</refentry>

View File

@@ -14,11 +14,15 @@
<replaceable>number</replaceable>
</arg>
<arg>
<arg><option>--cores</option></arg>
<option>--cores</option>
<replaceable>number</replaceable>
</arg>
<arg>
<arg><option>--max-silent-time</option></arg>
<option>--max-silent-time</option>
<replaceable>number</replaceable>
</arg>
<arg>
<option>--timeout</option>
<replaceable>number</replaceable>
</arg>
<arg><option>--keep-going</option></arg>
@@ -29,6 +33,10 @@
<arg><option>--readonly-mode</option></arg>
<arg><option>--log-type</option> <replaceable>type</replaceable></arg>
<arg><option>--show-trace</option></arg>
<arg>
<option>-I</option>
<replaceable>path</replaceable>
</arg>
<sbr />
</nop>

View File

@@ -5,7 +5,7 @@
<para>Most Nix commands accept the following command-line options:</para>
<variablelist>
<variablelist xml:id="opt-common">
<varlistentry><term><option>--help</option></term>
@@ -132,6 +132,16 @@
</varlistentry>
<varlistentry xml:id="opt-timeout"><term><option>--timeout</option></term>
<listitem><para>Sets the maximum number of seconds that a builder
can run. The default is specified by the <link
linkend='conf-build-timeout'><literal>build-timeout</literal></link>
configuration setting. <literal>0</literal> means no
timeout.</para></listitem>
</varlistentry>
<varlistentry><term><option>--keep-going</option></term>
<term><option>-k</option></term>
@@ -254,8 +264,8 @@
expression evaluator will automatically try to call functions that
it encounters. It can automatically call functions for which every
argument has a <link linkend='ss-functions'>default value</link>
(e.g., <literal>{<replaceable>argName</replaceable> ?
<replaceable>defaultValue</replaceable>}:
(e.g., <literal>{ <replaceable>argName</replaceable> ?
<replaceable>defaultValue</replaceable> }:
<replaceable>...</replaceable></literal>). With
<option>--arg</option>, you can also call functions that have
arguments without a default value (or override a default value).
@@ -331,6 +341,16 @@
</varlistentry>
<varlistentry><term><option>-I</option> <replaceable>path</replaceable></term>
<listitem><para>Add a path to the Nix expression search path. See
the <envar>NIX_PATH</envar> environment variable for details. Paths
added through <option>-I</option> take precedence over
<envar>NIX_PATH</envar>.</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -11,9 +11,9 @@ to the following chapters.</para>
<orderedlist>
<listitem><para>Download a source tarball, RPM or Deb from <link
xlink:href='http://nixos.org/'/>. Build source distributions using
the regular sequence:
<listitem><para>Download a source tarball or RPM or Debian/Ubuntu
package from <link xlink:href='http://nixos.org/'/>. Build source
distributions using the regular sequence:
<screen>
$ tar xvfj nix-<replaceable>version</replaceable>.tar.bz2
@@ -41,8 +41,7 @@ file).</para></listitem>
<listitem><para>Subscribe to the Nix Packages channel.
<screen>
$ nix-channel --add \
http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable</screen>
$ nix-channel --add http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable</screen>
</para></listitem>
@@ -108,10 +107,10 @@ numbers).</para></listitem>
<listitem><para>You can also install specific packages directly from
your web browser. For instance, you can go to <link
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest" />
and click on any link for the individual packages for your platform.
Associate <literal>application/nix-package</literal> with the program
<filename>/nix/bin/nix-install-package</filename>. A window should
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
/> and click on any link for the individual packages for your
platform. Associate <literal>application/nix-package</literal> with
the program <command>nix-install-package</command>. A window should
appear asking you whether its okay to install the package. Say
<literal>Y</literal>. The package and all its dependencies will be
installed.</para></listitem>

View File

@@ -8,9 +8,10 @@
<!--==================================================================-->
<section xml:id="ssec-relnotes-1.0"><title>Release 1.0 (TBA)</title>
<section xml:id="ssec-relnotes-1.0"><title>Release 1.0 (May 11, 2012)</title>
<para>This release has the following improvements:</para>
<para>There have been numerous improvements and bug fixes since the
previous release. Here are the most significant:</para>
<itemizedlist>
@@ -22,6 +23,101 @@
option.</para>
</listitem>
<listitem>
<para>Nix now uses SQLite for its database. This is faster and
more flexible than the old <emphasis>ad hoc</emphasis> format.
SQLite is also used to cache the manifests in
<filename>/nix/var/nix/manifests</filename>, resulting in a
significant speedup.</para>
</listitem>
<listitem>
<para>Nix now has an search path for expressions. The search path
is set using the environment variable <envar>NIX_PATH</envar> and
the <option>-I</option> command line option. In Nix expressions,
paths between angle brackets are used to specify files that must
be looked up in the search path. For instance, the expression
<literal>&lt;nixpkgs/default.nix></literal> looks for a file
<filename>nixpkgs/default.nix</filename> relative to every element
in the search path.</para>
</listitem>
<listitem>
<para>The new command <command>nix-build --run-env</command>
builds all dependencies of a derivation, then starts a shell in an
environment containing all variables from the derivation. This is
useful for reproducing the environment of a derivation for
development.</para>
</listitem>
<listitem>
<para>The new command <command>nix-store --verify-path</command>
verifies that the contents of a store path have not
changed.</para>
</listitem>
<listitem>
<para>The new command <command>nix-store --print-env</command>
prints out the environment of a derivation in a format that can be
evaluated by a shell.</para>
</listitem>
<listitem>
<para>Attribute names can now be arbitrary strings. For instance,
you can write <literal>{ "foo-1.2" = …; "bla bla" = …; }."bla
bla"</literal>.</para>
</listitem>
<listitem>
<para>Attribute selection can now provide a default value using
the <literal>or</literal> operator. For instance, the expression
<literal>x.y.z or e</literal> evaluates to the attribute
<literal>x.y.z</literal> if it exists, and <literal>e</literal>
otherwise.</para>
</listitem>
<listitem>
<para>The right-hand side of the <literal>?</literal> operator can
now be an attribute path, e.g., <literal>attrs ?
a.b.c</literal>.</para>
</listitem>
<listitem>
<para>On Linux, Nix will now make files in the Nix store immutable
on filesystems that support it. This prevents accidental
modification of files in the store by the root user.</para>
</listitem>
<listitem>
<para>Nix has preliminary support for derivations with multiple
outputs. This is useful because it allows parts of a package to
be deployed and garbage-collected separately. For instance,
development parts of a package such as header files or static
libraries would typically not be part of the closure of an
application, resulting in reduced disk usage and installation
time.</para>
</listitem>
<listitem>
<para>The Nix store garbage collector is faster and holds the
global lock for a shorter amount of time.</para>
</listitem>
<listitem>
<para>The option <option>--timeout</option> (corresponding to the
configuration setting <literal>build-timeout</literal>) allows you
to set an absolute timeout on builds — if a build runs for more than
the given number of seconds, it is terminated. This is useful for
recovering automatically from builds that are stuck in an infinite
loop but keep producing output, and for which
<literal>--max-silent-time</literal> is ineffective.</para>
</listitem>
<listitem>
<para>Nix development has moved to GitHub (<link
xlink:href="https://github.com/NixOS/nix" />).</para>
</listitem>
</itemizedlist>
</section>

View File

@@ -8,15 +8,14 @@
body
{
font-family: sans-serif;
font-family: "Nimbus Sans L", sans-serif;
background: white;
margin: 2em 1em 2em 1em;
}
h1,h2,h3
h1, h2, h3, h4
{
color: #005aa0;
text-align: left;
}
h1 /* title */
@@ -75,11 +74,13 @@ div.refsection h3
div.example
{
border: 1px solid #6185a0;
border: 1px solid #b0b0b0;
padding: 6px 6px;
margin-left: 1.5em;
margin-right: 1.5em;
background: #f4f4f8;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example p.title
@@ -87,6 +88,11 @@ div.example p.title
margin-top: 0em;
}
div.example pre
{
box-shadow: none;
}
/***************************************************************************
Screen dumps:
@@ -94,14 +100,15 @@ div.example p.title
pre.screen, pre.programlisting
{
border: 1px solid #6185a0;
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
color: #600000;
background: #f4f4f8;
font-family: monospace;
/* font-size: 90%; */
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.example pre.programlisting
@@ -118,13 +125,15 @@ div.example pre.programlisting
.note, .warning
{
border: 1px solid #6185a0;
border: 1px solid #b0b0b0;
padding: 3px 3px;
margin-left: 1.5em;
margin-right: 1.5em;
margin-bottom: 1em;
padding: 0.3em 0.3em 0.3em 0.3em;
background: #fffff5;
border-radius: 0.4em;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.note, div.warning
@@ -136,7 +145,6 @@ div.note h3, div.warning h3
{
color: red;
font-size: 100%;
// margin: 0 0 0 0;
padding-right: 0.5em;
display: inline;
}
@@ -167,20 +175,26 @@ div.navfooter *
Links colors and highlighting:
***************************************************************************/
a { text-decoration: none; }
a:hover { text-decoration: underline; }
a:link { color: #0048b3; }
a:visited { color: #002a6a; }
a:hover { background: #ffffcd; }
/***************************************************************************
Table of contents:
***************************************************************************/
.toc
div.toc
{
font-size: 90%;
}
div.toc dl
{
margin-top: 0em;
margin-bottom: 0em;
}
/***************************************************************************
@@ -213,76 +227,29 @@ div.glosslist dt
font-style: italic;
}
.default
{
font-style: italic;
}
.availability
{
font-style: italic;
}
.varname
{
color: #400000;
}
div.informaltable table
span.command strong
{
border: 1px solid #6185a0;
width: 100%;
}
div.informaltable td
{
border: 0;
padding: 5px;
}
div.informaltable td.default
{
text-align: right;
}
div.informaltable th
{
text-align: left;
color: #005aa0;
border: 0;
padding: 5px;
background: #fffff5;
font-weight: normal;
font-style: italic;
}
td.varname, td.tagname, td.paramname
{
font-weight: bold;
vertical-align: top;
}
div.epigraph
{
font-style: italic;
text-align: right;
}
table.productionset table.productionset
{
font-family: monospace;
}
strong.command
{
// font-family: monospace;
// font-style: italic;
// font-weight: normal;
font-weight: normal;
color: #400000;
}
div.calloutlist td
div.calloutlist table
{
padding-bottom: 1em;
box-shadow: none;
}
table
{
border-collapse: collapse;
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
}
div.affiliation
{
font-style: italic;
}

View File

@@ -11,6 +11,13 @@ the things that tell Nix how to build packages. It starts with a
simple example (a Nix expression for GNU Hello), and then moves
on to a more in-depth look at the Nix expression language.</para>
<note><para>This chapter is mostly about the Nix expression language.
For more extensive information on adding packages to the Nix Packages
collection (such as functions in the standard environment and coding
conventions), please consult <link
xlink:href="http://hydra.nixos.org/job/nixpkgs/trunk/tarball/latest/download-by-type/doc/manual">its
manual</link>.</para></note>
<section><title>A simple Nix expression</title>
@@ -52,7 +59,7 @@ need to do three things:
<example xml:id='ex-hello-nix'><title>Nix expression for GNU Hello
(<filename>default.nix</filename>)</title>
<programlisting>
{stdenv, fetchurl, perl}: <co xml:id='ex-hello-nix-co-1' />
{ stdenv, fetchurl, perl }: <co xml:id='ex-hello-nix-co-1' />
stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
name = "hello-2.1.1"; <co xml:id='ex-hello-nix-co-3' />
@@ -92,8 +99,8 @@ the single Nix expression in that directory
function that downloads files. <varname>perl</varname> is the
Perl interpreter.</para>
<para>Nix functions generally have the form <literal>{x, y, ...,
z}: e</literal> where <varname>x</varname>, <varname>y</varname>,
<para>Nix functions generally have the form <literal>{ x, y, ...,
z }: e</literal> where <varname>x</varname>, <varname>y</varname>,
etc. are the names of the expected arguments, and where
<replaceable>e</replaceable> is the body of the function. So
here, the entire remainder of the file is the body of the
@@ -114,10 +121,10 @@ the single Nix expression in that directory
<emphasis>attributes</emphasis>. An attribute set is just a list
of key/value pairs where each value is an arbitrary Nix
expression. They take the general form
<literal>{<replaceable>name1</replaceable> =
<literal>{ <replaceable>name1</replaceable> =
<replaceable>expr1</replaceable>; <replaceable>...</replaceable>
<replaceable>nameN</replaceable> =
<replaceable>exprN</replaceable>;}</literal>.</para>
<replaceable>exprN</replaceable>; }</literal>.</para>
</callout>
@@ -315,15 +322,15 @@ error check.</para>
rec { <co xml:id='ex-hello-composition-co-1' />
hello = (import ../applications/misc/hello/ex-1 <co xml:id='ex-hello-composition-co-2' />) { <co xml:id='ex-hello-composition-co-3' />
hello = import ../applications/misc/hello/ex-1 <co xml:id='ex-hello-composition-co-2' /> { <co xml:id='ex-hello-composition-co-3' />
inherit fetchurl stdenv perl;
};
perl = (import ../development/interpreters/perl) { <co xml:id='ex-hello-composition-co-4' />
perl = import ../development/interpreters/perl { <co xml:id='ex-hello-composition-co-4' />
inherit fetchurl stdenv;
};
fetchurl = (import ../build-support/fetchurl) {
fetchurl = import ../build-support/fetchurl {
inherit stdenv; ...
};
@@ -390,6 +397,23 @@ some fragments of
<varname>stdenv.mkDerivation</varname> in <xref
linkend='ex-hello-nix' />).</para>
<note><para>Nixpkgs has a convenience function
<function>callPackage</function> that imports and calls a
function, filling in any missing arguments by passing the
corresponding attribute from the Nixpkgs set, like this:
<programlisting>
hello = callPackage ../applications/misc/hello/ex-1 { };
</programlisting>
If necessary, you can set or override arguments:
<programlisting>
hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
</programlisting>
</para></note>
</callout>
<callout arearefs='ex-hello-composition-co-4'>
@@ -564,7 +588,7 @@ genericBuild <co xml:id='ex-hello-builder2-co-3' /></programlisting>
expression, like this:
<programlisting>
buildInputs = [perl];</programlisting>
buildInputs = [ perl ];</programlisting>
The <varname>perl</varname> attribute can then be removed, and the
builder becomes even shorter:
@@ -771,14 +795,14 @@ stdenv.mkDerivation {
values between square brackets. For example,
<programlisting>
[ 123 ./foo.nix "abc" (f {x=y;}) ]</programlisting>
[ 123 ./foo.nix "abc" (f { x = y; }) ]</programlisting>
defines a list of four elements, the last being the result of a call
to the function <varname>f</varname>. Note that function calls have
to be enclosed in parentheses. If they had been omitted, e.g.,
<programlisting>
[ 123 ./foo.nix "abc" f {x=y;} ]</programlisting>
[ 123 ./foo.nix "abc" f { x = y; } ]</programlisting>
the result would be a list of five elements, the fourth one being a
function and the fifth being an attribute set.</para>
@@ -813,7 +837,23 @@ occur once.</para>
<programlisting>
{ a = "Foo"; b = "Bar"; }.a</programlisting>
evaluates to <literal>"Foo"</literal>.</para>
evaluates to <literal>"Foo"</literal>. It is possible to provide a
default value in an attribute selection using the
<literal>or</literal> keyword. For example,
<programlisting>
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"</programlisting>
will evaluate to <literal>"Xyzzy"</literal> because there is no
<varname>c</varname> attribute in the set.</para>
<para>You can use arbitrary string constants as attribute names by
enclosing them in quotes:
<programlisting>
{ "foo bar" = 123; "nix-1.0" = 456; }."foo bar" </programlisting>
This will evaluate to <literal>123</literal>.</para>
</simplesect>
@@ -891,15 +931,12 @@ propagate attributes). This can be shortened using the
<literal>inherit</literal> keyword. For instance,
<programlisting>
let
x = 123;
in
{
inherit x;
y = 456;
}</programlisting>
let x = 123; in
{ inherit x;
y = 456;
}</programlisting>
evaluates to <literal>{x = 123; y = 456;}</literal>. (Note that this
evaluates to <literal>{ x = 123; y = 456; }</literal>. (Note that this
works because <varname>x</varname> is added to the lexical scope by
the <literal>let</literal> construct.) It is also possible to inherit
attributes from another attribute set. For instance, in this fragment
@@ -960,20 +997,20 @@ in if negate true then concat "foo" "bar" else ""</programlisting>
arguments of a function); e.g.,
<programlisting>
map (concat "foo") ["bar" "bla" "abc"]</programlisting>
map (concat "foo") [ "bar" "bla" "abc" ]</programlisting>
evaluates to <literal>["foobar" "foobla"
"fooabc"]</literal>.</para></listitem>
evaluates to <literal>[ "foobar" "foobla"
"fooabc" ]</literal>.</para></listitem>
<listitem><para>An <emphasis>attribute set pattern</emphasis> of the
form <literal>{name1, name2, …, nameN}</literal>
form <literal>{ name1, name2, …, nameN }</literal>
matches an attribute set containing the listed attributes, and binds
the values of those attributes to variables in the function body.
For example, the function
<programlisting>
{x, y, z}: z + y + x</programlisting>
{ x, y, z }: z + y + x</programlisting>
can only be called with a set containing exactly the attributes
<varname>x</varname>, <varname>y</varname> and
@@ -982,7 +1019,7 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
(<literal>...</literal>):
<programlisting>
{x, y, z, ....}: z + y + x</programlisting>
{ x, y, z, ... }: z + y + x</programlisting>
This works on any set that contains at least the three named
attributes.</para>
@@ -995,7 +1032,7 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
<replaceable>e</replaceable> is an arbitrary expression. For example,
<programlisting>
{x, y ? "foo", z ? "bar"}: z + y + x</programlisting>
{ x, y ? "foo", z ? "bar" }: z + y + x</programlisting>
specifies a function that only requires an attribute named
<varname>x</varname>, but optionally accepts <varname>y</varname>
@@ -1007,11 +1044,11 @@ map (concat "foo") ["bar" "bla" "abc"]</programlisting>
of the <literal>@</literal>-sign. For example:
<programlisting>
args@{x, y, z, ...}: z + y + x + args.a</programlisting>
args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
Here <varname>args</varname> is bound to the entire argument, which
is further matches against the pattern <literal>{x, y, z,
...}</literal>.</para></listitem>
is further matches against the pattern <literal>{ x, y, z,
... }</literal>.</para></listitem>
</itemizedlist>
@@ -1020,8 +1057,8 @@ args@{x, y, z, ...}: z + y + x + args.a</programlisting>
a name, you can bind them to an attribute, e.g.,
<programlisting>
let concat = {x, y}: x + y;
in concat {x = "foo"; y = "bar";}</programlisting>
let concat = { x, y }: x + y;
in concat { x = "foo"; y = "bar"; }</programlisting>
</para>
@@ -1142,7 +1179,7 @@ lexical scope of the expression <replaceable>e2</replaceable>. For
instance,
<programlisting>
let as = {x = "foo"; y = "bar";};
let as = { x = "foo"; y = "bar"; };
in with as; x + y</programlisting>
evaluates to <literal>"foobar"</literal> since the
@@ -1192,12 +1229,17 @@ weakest binding).</para>
</thead>
<tbody>
<row>
<entry><replaceable>e</replaceable> .
<replaceable>id</replaceable></entry>
<entry><replaceable>e</replaceable> <literal>.</literal>
<replaceable>attrpath</replaceable>
[ <literal>or</literal> <replaceable>def</replaceable> ]
</entry>
<entry>none</entry>
<entry>Select attribute named <replaceable>id</replaceable>
from attribute set <replaceable>e</replaceable>. Abort
evaluation if the attribute doesnt exist.</entry>
<entry>Select attribute denoted by the attribute path
<replaceable>attrpath</replaceable> from attribute set
<replaceable>e</replaceable>. (An attribute path is a
dot-separated list of attribute names.) If the attribute
doesnt exist, return <replaceable>def</replaceable> if
provided, otherwise abort evaluation.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> <replaceable>e2</replaceable></entry>
@@ -1206,31 +1248,31 @@ weakest binding).</para>
argument <replaceable>e2</replaceable>.</entry>
</row>
<row>
<entry><replaceable>e</replaceable> ?
<replaceable>id</replaceable></entry>
<entry><replaceable>e</replaceable> <literal>?</literal>
<replaceable>attrpath</replaceable></entry>
<entry>none</entry>
<entry>Test whether attribute set <replaceable>e</replaceable>
contains an attribute named <replaceable>id</replaceable>;
contains the attribute denoted by <replaceable>attrpath</replaceable>;
return <literal>true</literal> or
<literal>false</literal>.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> ++ <replaceable>e2</replaceable></entry>
<entry><replaceable>e1</replaceable> <literal>++</literal> <replaceable>e2</replaceable></entry>
<entry>right</entry>
<entry>List concatenation.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> + <replaceable>e2</replaceable></entry>
<entry><replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable></entry>
<entry>left</entry>
<entry>String or path concatenation.</entry>
</row>
<row>
<entry>! <replaceable>e</replaceable></entry>
<entry><literal>!</literal> <replaceable>e</replaceable></entry>
<entry>left</entry>
<entry>Boolean negation.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> //
<entry><replaceable>e1</replaceable> <literal>//</literal>
<replaceable>e2</replaceable></entry>
<entry>right</entry>
<entry>Return an attribute set consisting of the attributes in
@@ -1239,31 +1281,31 @@ weakest binding).</para>
precedence over the former in case of equally named attributes).</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> ==
<entry><replaceable>e1</replaceable> <literal>==</literal>
<replaceable>e2</replaceable></entry>
<entry>none</entry>
<entry>Equality.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> !=
<entry><replaceable>e1</replaceable> <literal>!=</literal>
<replaceable>e2</replaceable></entry>
<entry>none</entry>
<entry>Inequality.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> &amp;&amp;
<entry><replaceable>e1</replaceable> <literal>&amp;&amp;</literal>
<replaceable>e2</replaceable></entry>
<entry>left</entry>
<entry>Logical AND.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> ||
<entry><replaceable>e1</replaceable> <literal>||</literal>
<replaceable>e2</replaceable></entry>
<entry>left</entry>
<entry>Logical OR.</entry>
</row>
<row>
<entry><replaceable>e1</replaceable> ->
<entry><replaceable>e1</replaceable> <literal>-></literal>
<replaceable>e2</replaceable></entry>
<entry>none</entry>
<entry>Logical implication (equivalent to
@@ -1296,7 +1338,7 @@ set, the attributes of which specify the inputs of the build.</para>
can only be performed on a machine and operating system matching the
platform identifier. (Nix can automatically forward builds for
other platforms by forwarding them to other machines; see <xref
linkend='sec-distributed-builds' />.)</para></listitem>
linkend='chap-distributed-builds' />.)</para></listitem>
<listitem><para>There must be an attribute named
<varname>name</varname> whose value must be a string. This is used
@@ -1480,21 +1522,20 @@ allowedReferences = [];
references graph of their inputs. The attribute is a list of
inputs in the Nix store whose references graph the builder needs
to know. The value of this attribute should be a list of pairs
<literal>[<replaceable>name1</replaceable>
<literal>[ <replaceable>name1</replaceable>
<replaceable>path1</replaceable> <replaceable>name2</replaceable>
<replaceable>path2</replaceable>
<replaceable>...</replaceable>]</literal>. The references graph
of each <replaceable>pathN</replaceable> will be stored in a text
file <replaceable>nameN</replaceable> in the temporary build
directory. The text files have the format used by
<command>nix-store --register-validity</command> (with the deriver
fields left empty). For example, when the following derivation is
built:
<replaceable>path2</replaceable> <replaceable>...</replaceable>
]</literal>. The references graph of each
<replaceable>pathN</replaceable> will be stored in a text file
<replaceable>nameN</replaceable> in the temporary build directory.
The text files have the format used by <command>nix-store
--register-validity</command> (with the deriver fields left
empty). For example, when the following derivation is built:
<programlisting>
derivation {
...
exportReferencesGraph = ["libfoo-graph" libfoo];
exportReferencesGraph = [ "libfoo-graph" libfoo ];
};
</programlisting>
@@ -1571,14 +1612,14 @@ fetchurl {
<varname>fetchurl</varname>:
<programlisting>
{stdenv, curl}: # The <command>curl</command> program is used for downloading.
{ stdenv, curl }: # The <command>curl</command> program is used for downloading.
{url, md5}:
{ url, md5 }:
stdenv.mkDerivation {
name = baseNameOf (toString url);
builder = ./builder.sh;
buildInputs = [curl];
buildInputs = [ curl ];
# This is a fixed-output derivation; the output must be a regular
# file with MD5 hash <varname>md5</varname>.
@@ -1650,7 +1691,7 @@ stdenv.mkDerivation {
Nixpkgs has the line
<programlisting>
impureEnvVars = ["http_proxy" "https_proxy" <replaceable>...</replaceable>];
impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
</programlisting>
to make it use the proxy server configuration specified by the
@@ -1666,7 +1707,17 @@ impureEnvVars = ["http_proxy" "https_proxy" <replaceable>...</replaceable>];
</varlistentry>
<varlistentry><term><varname>preferLocalBuild</varname></term>
<listitem><para>If this attribute is set to
<literal>true</literal> and <link
linkend="chap-distributed-builds">distributed building is
enabled</link>, then, if possible, perform this build locally
instead of forwarding it to a remote machine. This is appropriate
for trivial builders where the cost of doing a remote build would
exceed the cost of building locally.</para></listitem>
</varlistentry>
</variablelist>

67
externals/Makefile.am vendored
View File

@@ -1,67 +0,0 @@
# bzip2
BZIP2 = bzip2-1.0.5
$(BZIP2).tar.gz:
@echo "Nix requires bzip2 to build."
@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
$(BZIP2): $(BZIP2).tar.gz
gunzip < $(srcdir)/$(BZIP2).tar.gz | tar xvf -
if HAVE_BZIP2
build-bzip2:
else
build-bzip2: $(BZIP2)
(cd $(BZIP2) && \
$(MAKE) CC="$(CC)" && \
$(MAKE) install PREFIX=$(abs_builddir)/inst-bzip2)
touch build-bzip2
install-exec-local:: build-bzip2
mkdir -p $(DESTDIR)${bzip2_bin}
$(INSTALL_PROGRAM) $(bzip2_bin_test)/bzip2 $(bzip2_bin_test)/bunzip2 $(DESTDIR)${bzip2_bin}
endif
# SQLite
SQLITE = sqlite-autoconf-$(SQLITE_VERSION)
SQLITE_TAR = sqlite-autoconf-$(SQLITE_VERSION).tar.gz
$(SQLITE_TAR):
@echo "Nix requires the SQLite library to build."
@echo "Please download version $(SQLITE_VERSION) from"
@echo " http://www.sqlite.org/$(SQLITE_TAR)"
@echo "and place it in the externals/ directory."
false
$(SQLITE): $(SQLITE_TAR)
gzip -d < $(srcdir)/$(SQLITE_TAR) | tar xvf -
if HAVE_SQLITE
build-sqlite:
else
build-sqlite: $(SQLITE)
(cd $(SQLITE) && \
CC="$(CC)" CFLAGS="-DSQLITE_ENABLE_COLUMN_METADATA=1" ./configure --disable-static --prefix=$(pkglibdir)/dummy --libdir=${pkglibdir} $(SUB_CONFIGURE_FLAGS) && \
$(MAKE) )
touch build-sqlite
install-exec-local:: build-sqlite
cd $(SQLITE) && $(MAKE) install
rm -rf "$(DESTDIR)/$(pkglibdir)/dummy"
endif
all: build-bzip2 build-sqlite
EXTRA_DIST = $(BZIP2).tar.gz $(SQLITE_TAR)
clean:
$(RM) -f build-bzip2 build-sqlite
$(RM) -rf $(BZIP2) $(SQLITE)
$(RM) -rf inst-bzip2

View File

@@ -1,30 +0,0 @@
{sharedLib ? true}:
rec {
inherit (import ../../../lib) compileC makeLibrary;
sources = [
./afun.c
./aterm.c
./bafio.c
./byteio.c
./gc.c
./hash.c
./list.c
./make.c
./md5c.c
./memory.c
./tafio.c
./version.c
];
compile = main: compileC {inherit main sharedLib;};
libATerm = makeLibrary {
libraryName = "ATerm";
objects = map compile sources;
inherit sharedLib;
};
}

View File

@@ -1 +0,0 @@
import test/default.nix

View File

@@ -1,15 +0,0 @@
with (import ../../../lib);
let {
inherit (import ../aterm {}) libATerm;
compileTest = main: link {
objects = [(compileC {inherit main; localIncludePath = [ ../aterm ];})];
libraries = libATerm;
};
body = [
(compileTest ./fib.c)
(compileTest ./primes.c)
];
}

View File

@@ -1,6 +0,0 @@
[ (import ./trivial)
(import ./simple-header)
(import ./not-so-simple-header)
(import ./not-so-simple-header-auto)
(import ./aterm)
]

View File

@@ -1 +0,0 @@
#define WHAT "World"

View File

@@ -1,13 +0,0 @@
with import ../../lib;
let {
hello = link {programName = "hello"; objects = compileC {
main = ./foo/hello.c;
localIncludes = "auto";
};};
# body = findIncludes {main = ./foo/hello.c;};
body = [hello];
}

View File

@@ -1,3 +0,0 @@
#define HELLO "Hello"
#include "../../bar/hello.h"

View File

@@ -1,9 +0,0 @@
#include <stdio.h>
#include "fnord/indirect.h"
int main(int argc, char * * argv)
{
printf(HELLO " " WHAT "\n");
return 0;
}

View File

@@ -1 +0,0 @@
#define WHAT "World"

View File

@@ -1,14 +0,0 @@
let {
inherit (import ../../lib) compileC link;
hello = link {programName = "hello"; objects = compileC {
main = ./foo/hello.c;
localIncludes = [
[./foo/fnord/indirect.h "fnord/indirect.h"]
[./bar/hello.h "fnord/../../bar/hello.h"]
];
};};
body = [hello];
}

View File

@@ -1,3 +0,0 @@
#define HELLO "Hello"
#include "../../bar/hello.h"

View File

@@ -1,9 +0,0 @@
#include <stdio.h>
#include "fnord/indirect.h"
int main(int argc, char * * argv)
{
printf(HELLO " " WHAT "\n");
return 0;
}

View File

@@ -1,11 +0,0 @@
let {
inherit (import ../../lib) compileC link;
hello = link {objects = compileC {
main = ./hello.c;
localIncludes = [ [./hello.h "hello.h"] ];
};};
body = [hello];
}

View File

@@ -1,9 +0,0 @@
#include <stdio.h>
#include "hello.h"
int main(int argc, char * * argv)
{
printf("Hello " WHAT "\n");
return 0;
}

View File

@@ -1 +0,0 @@
#define WHAT "World"

View File

@@ -1,8 +0,0 @@
let {
inherit (import ../../lib) compileC link;
hello = link {objects = compileC {main = ./hello.c;};};
body = [hello];
}

View File

@@ -1,7 +0,0 @@
#include <stdio.h>
int main(int argc, char * * argv)
{
printf("Hello World\n");
return 0;
}

View File

@@ -1,73 +0,0 @@
. $stdenv/setup
mainName=$(basename $main | cut -c34-)
echo "compiling \`$mainName'..."
# Turn $localIncludes into an array.
localIncludes=($localIncludes)
# Determine how many `..' levels appear in the header file references.
# E.g., if there is some reference `../../foo.h', then we have to
# insert two extra levels in the directory structure, so that `a.c' is
# stored at `dotdot/dotdot/a.c', and a reference from it to
# `../../foo.h' resolves to `dotdot/dotdot/../../foo.h' == `foo.h'.
n=0
maxDepth=0
for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do
target=${localIncludes[$((n + 1))]}
# Split the target name into path components using some IFS magic.
savedIFS="$IFS"
IFS=/
components=($target)
depth=0
for ((m = 0; m < ${#components[*]}; m++)); do
c=${components[m]}
if test "$c" = ".."; then
depth=$((depth + 1))
fi
done
IFS="$savedIFS"
if test $depth -gt $maxDepth; then
maxDepth=$depth;
fi
done
# Create the extra levels in the directory hierarchy.
prefix=
for ((n = 0; n < maxDepth; n++)); do
prefix="dotdot/$prefix"
done
# Create symlinks to the header files.
for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do
source=${localIncludes[n]}
target=${localIncludes[$((n + 1))]}
# Create missing directories. We use IFS magic to split the path
# into path components.
savedIFS="$IFS"
IFS=/
components=($prefix$target)
fullPath=(.)
for ((m = 0; m < ${#components[*]} - 1; m++)); do
fullPath=("${fullPath[@]}" ${components[m]})
if ! test -d "${fullPath[*]}"; then
mkdir "${fullPath[*]}"
fi
done
IFS="$savedIFS"
ln -sf $source $prefix$target
done
# Create a symlink to the main file.
if ! test "$(readlink $prefix$mainName)" = $main; then
ln -s $main $prefix$mainName
fi
mkdir $out
test "$prefix" && cd $prefix
gcc -Wall $cFlags -c $mainName -o $out/$mainName.o

View File

@@ -1,69 +0,0 @@
rec {
# Should point at your Nixpkgs installation.
pkgPath = ./pkgs;
pkgs = import (pkgPath + /system/all-packages.nix) {};
stdenv = pkgs.stdenv;
compileC =
{ main
, localIncludes ? "auto"
, localIncludePath ? []
, cFlags ? ""
, sharedLib ? false
}:
stdenv.mkDerivation {
name = "compile-c";
builder = ./compile-c.sh;
localIncludes =
if localIncludes == "auto" then
dependencyClosure {
scanner = main:
import (findIncludes {
inherit main;
});
searchPath = localIncludePath;
startSet = [main];
}
else
localIncludes;
inherit main;
cFlags = [
cFlags
(if sharedLib then ["-fpic"] else [])
(map (p: "-I" + (relativise (dirOf main) p)) localIncludePath)
];
};
findIncludes = {main}: stdenv.mkDerivation {
name = "find-includes";
realBuilder = pkgs.perl ~ "bin/perl";
args = [ ./find-includes.pl ];
inherit main;
};
link = {objects, programName ? "program", libraries ? []}: stdenv.mkDerivation {
name = "link";
builder = ./link.sh;
inherit objects programName libraries;
};
makeLibrary = {objects, libraryName ? [], sharedLib ? false}:
# assert sharedLib -> fold (obj: x: assert obj.sharedLib && x) false objects
stdenv.mkDerivation {
name = "library";
builder = ./make-library.sh;
inherit objects libraryName sharedLib;
};
}

View File

@@ -1,21 +0,0 @@
use strict;
my $root = $ENV{"main"};
my $out = $ENV{"out"};
open OUT, ">$out" or die "$!";
print OUT "[\n";
open IN, "<$root" or die "$!";
while (<IN>) {
if (/^\#include\s+\"(.*)\"/) {
print OUT "\"$1\"\n";
}
if (/^\#include\s+\<(.*)\>/) {
print OUT "\"$1\"\n";
}
}
close IN;
print OUT "]\n";
close OUT;

View File

@@ -1,21 +0,0 @@
. $stdenv/setup
shopt -s nullglob
objs=
for i in $objects; do
obj=$(echo $i/*.o)
objs="$objs $obj"
done
libs=
for i in $libraries; do
lib=$(echo $i/*.a; echo $i/*.so)
name=$(echo $(basename $lib) | sed -e 's/^lib//' -e 's/.a$//' -e 's/.so$//')
libs="$libs -L$(dirname $lib) -l$name"
done
echo "linking object files into \`$programName'..."
mkdir $out
gcc -o $out/$programName $objs $libs

View File

@@ -1,28 +0,0 @@
. $stdenv/setup
objs=
for i in $objects; do
obj=$(echo $i/*.o)
objs="$objs $obj"
done
echo "archiving object files into library \`$libraryName'..."
ensureDir $out
if test -z "$sharedLib"; then
outPath=$out/lib${libraryName}.a
ar crs $outPath $objs
ranlib $outPath
else
outPath=$out/lib${libraryName}.so
gcc -shared -o $outPath $objs
fi

View File

@@ -67,7 +67,7 @@ The hook `nix-mode-hook' is run when Nix mode is started.
(defvar nix-keywords
'("\\<if\\>" "\\<then\\>" "\\<else\\>" "\\<assert\\>" "\\<with\\>"
"\\<let\\>" "\\<in\\>" "\\<rec\\>" "\\<inherit\\>"
"\\<let\\>" "\\<in\\>" "\\<rec\\>" "\\<inherit\\>" "\\<or\\>"
("\\<true\\>" . font-lock-builtin-face)
("\\<false\\>" . font-lock-builtin-face)
("\\<null\\>" . font-lock-builtin-face)
@@ -80,6 +80,8 @@ The hook `nix-mode-hook' is run when Nix mode is started.
. 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)
("[a-zA-Z0-9._\\+-]*\\(/[a-zA-Z0-9._\\+-]+\\)+"
. font-lock-constant-face)
))
@@ -107,3 +109,5 @@ The hook `nix-mode-hook' is run when Nix mode is started.
(setq auto-mode-alist (cons '("\\.nix\\'" . nix-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.nix.in\\'" . nix-mode) auto-mode-alist))
(provide 'nix-mode)

View File

@@ -19,9 +19,16 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
Prefix: /usr
Requires: /usr/bin/perl
Requires: curl
Requires: perl-DBD-SQLite
Requires: perl-devel
Requires: bzip2
Requires: bzip2-libs
Requires: sqlite
BuildRequires: bzip2-devel
BuildRequires: sqlite-devel
# Hack to make that shitty RPM scanning hack shut up.
Provides: perl(readmanifest)
Provides: perl(Nix::SSH)
%description

7
perl/MANIFEST Normal file
View File

@@ -0,0 +1,7 @@
Changes
Makefile.PL
MANIFEST
Nix.xs
README
t/Nix.t
lib/Nix.pm

37
perl/Makefile.am Normal file
View File

@@ -0,0 +1,37 @@
PERL_MODULES = lib/Nix/Store.pm lib/Nix/Manifest.pm lib/Nix/GeneratePatches.pm lib/Nix/SSH.pm lib/Nix/CopyClosure.pm lib/Nix/Config.pm.in
all: $(PERL_MODULES:.in=)
install-exec-local: $(PERL_MODULES:.in=) install-perl-xs
$(INSTALL) -d $(DESTDIR)$(perllibdir)/Nix
$(INSTALL_DATA) $(PERL_MODULES:.in=) $(DESTDIR)$(perllibdir)/Nix
if PERL_BINDINGS
install-perl-xs:
$(INSTALL) -d $(DESTDIR)$(perllibdir)/auto/Nix/Store
ln -sfn $(pkglibdir)/libNixStore$(dynlib_suffix) $(DESTDIR)$(perllibdir)/auto/Nix/Store/Store$(dynlib_suffix)
# Awful hackery to get libtool to build Perl XS bindings.
pkglib_LTLIBRARIES = libNixStore.la
nodist_libNixStore_la_SOURCES = lib/Nix/Store.cc
CLEANFILES = lib/Nix/Store.cc
libNixStore_la_LIBADD = $(top_builddir)/src/libstore/libstore.la
AM_CXXFLAGS = \
-I$(top_srcdir)/src -I$(top_srcdir)/src/libutil -I$(top_srcdir)/src/libstore \
-I$(shell $(perl) -e 'use Config; print $$Config{archlibexp};')/CORE \
-D_FILE_OFFSET_BITS=64
lib/Nix/Store.cc: lib/Nix/Store.xs
xsubpp $^ -output $@
else
install-perl-xs:
endif
EXTRA_DIST = $(PERL_MODULES) lib/Nix/Store.xs
include ../substitute.mk

29
perl/lib/Nix/Config.pm.in Normal file
View File

@@ -0,0 +1,29 @@
package Nix::Config;
$binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
$libexecDir = $ENV{"NIX_LIBEXEC_DIR"} || "@libexecdir@";
$stateDir = $ENV{"NIX_STATE_DIR"} || "@localstatedir@/nix";
$manifestDir = $ENV{"NIX_MANIFESTS_DIR"} || "@localstatedir@/nix/manifests";
$logDir = $ENV{"NIX_LOG_DIR"} || "@localstatedir@/log/nix";
$confDir = $ENV{"NIX_CONF_DIR"} || "@sysconfdir@/nix";
$bzip2 = $ENV{"NIX_BZIP2"} || "@bzip2@";
$curl = "@curl@";
$useBindings = "@perlbindings@" eq "yes";
sub readConfig {
my %config;
my $config = "@sysconfdir@/nix/nix.conf";
return unless -f $config;
open CONFIG, "<$config" or die "cannot open `$config'";
while (<CONFIG>) {
/^\s*([\w|-]+)\s*=\s*(.*)$/ or next;
$config{$1} = $2;
print "|$1| -> |$2|\n";
}
close CONFIG;
}
return 1;

View File

@@ -0,0 +1,46 @@
package Nix::CopyClosure;
use strict;
use Nix::Config;
use Nix::Store;
sub copyTo {
my ($sshHost, $sshOpts, $storePaths, $compressor, $decompressor, $includeOutputs, $dryRun, $sign, $progressViewer) = @_;
$compressor = "$compressor |" if $compressor ne "";
$decompressor = "$decompressor |" if $decompressor ne "";
$progressViewer = "$progressViewer |" if $progressViewer ne "";
# Get the closure of this path.
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
map { followLinksToStorePath $_ } @{$storePaths})));
# Ask the remote host which paths are invalid. Because of limits
# to the command line length, do this in chunks. Eventually,
# we'll want to use --from-stdin, but we can't rely on the
# target having this option yet.
my @missing = ();
while (scalar(@closure) > 0) {
my @ps = splice(@closure, 0, 1500);
open(READ, "set -f; ssh $sshHost @{$sshOpts} nix-store --check-validity --print-invalid @ps|");
while (<READ>) {
chomp;
push @missing, $_;
}
close READ or die;
}
# Export the store paths and import them on the remote machine.
if (scalar @missing > 0) {
print STDERR "copying ", scalar @missing, " missing paths to $sshHost...\n";
unless ($dryRun) {
open SSH, "| $compressor $progressViewer ssh $sshHost @{$sshOpts} '$decompressor nix-store --import' > /dev/null" or die;
exportPaths(fileno(SSH), $sign, @missing);
close SSH or die "copying store paths to remote machine `$sshHost' failed: $?";
}
}
}
1;

View File

@@ -1,7 +1,13 @@
#! @perl@ -w -I@libexecdir@/nix
package Nix::GeneratePatches;
use strict;
use File::Temp qw(tempdir);
use File::stat;
use Nix::Config;
use Nix::Manifest;
our @ISA = qw(Exporter);
our @EXPORT = qw(generatePatches propagatePatches copyPatches);
# Some patch generations options.
@@ -202,41 +208,41 @@ sub generatePatches {
next;
}
system("@bunzip2@ < $srcNarBz2 > $tmpDir/A") == 0
system("$Nix::Config::bzip2 -d < $srcNarBz2 > $tmpDir/A") == 0
or die "cannot unpack $srcNarBz2";
if ((stat "$tmpDir/A")[7] >= $maxNarSize) {
if (stat("$tmpDir/A")->size >= $maxNarSize) {
print " skipping, source is too large\n";
next;
}
system("@bunzip2@ < $dstNarBz2 > $tmpDir/B") == 0
system("$Nix::Config::bzip2 -d < $dstNarBz2 > $tmpDir/B") == 0
or die "cannot unpack $dstNarBz2";
if ((stat "$tmpDir/B")[7] >= $maxNarSize) {
if (stat("$tmpDir/B")->size >= $maxNarSize) {
print " skipping, destination is too large\n";
next;
}
my $time1 = time();
my $res = system("ulimit -t $timeLimit; @libexecdir@/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF");
my $res = system("ulimit -t $timeLimit; $Nix::Config::libexecDir/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF");
my $time2 = time();
if ($res) {
warn "binary diff computation aborted after ", $time2 - $time1, " seconds\n";
next;
}
my $baseHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
my $baseHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
chomp $baseHash;
my $narHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/B` or die;
my $narHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/B` or die;
chomp $narHash;
my $narDiffHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/DIFF` or die;
my $narDiffHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/DIFF` or die;
chomp $narDiffHash;
my $narDiffSize = (stat "$tmpDir/DIFF")[7];
my $dstNarBz2Size = (stat $dstNarBz2)[7];
my $narDiffSize = stat("$tmpDir/DIFF")->size;
my $dstNarBz2Size = stat($dstNarBz2)->size;
print " size $narDiffSize; full size $dstNarBz2Size; ", $time2 - $time1, " seconds\n";

367
perl/lib/Nix/Manifest.pm Normal file
View File

@@ -0,0 +1,367 @@
package Nix::Manifest;
use strict;
use DBI;
use Cwd;
use File::stat;
use File::Path;
use Fcntl ':flock';
use Nix::Config;
our @ISA = qw(Exporter);
our @EXPORT = qw(readManifest writeManifest updateManifestDB addPatch);
sub addNAR {
my ($narFiles, $storePath, $info) = @_;
$$narFiles{$storePath} = []
unless defined $$narFiles{$storePath};
my $narFileList = $$narFiles{$storePath};
my $found = 0;
foreach my $narFile (@{$narFileList}) {
$found = 1 if $narFile->{url} eq $info->{url};
}
push @{$narFileList}, $info if !$found;
}
sub addPatch {
my ($patches, $storePath, $patch) = @_;
$$patches{$storePath} = []
unless defined $$patches{$storePath};
my $patchList = $$patches{$storePath};
my $found = 0;
foreach my $patch2 (@{$patchList}) {
$found = 1 if
$patch2->{url} eq $patch->{url} &&
$patch2->{basePath} eq $patch->{basePath};
}
push @{$patchList}, $patch if !$found;
return !$found;
}
sub readManifest_ {
my ($manifest, $addNAR, $addPatch) = @_;
# Decompress the manifest if necessary.
if ($manifest =~ /\.bz2$/) {
open MANIFEST, "$Nix::Config::bzip2 -d < $manifest |"
or die "cannot decompress `$manifest': $!";
} else {
open MANIFEST, "<$manifest"
or die "cannot open `$manifest': $!";
}
my $inside = 0;
my $type;
my $manifestVersion = 2;
my ($storePath, $url, $hash, $size, $basePath, $baseHash, $patchType);
my ($narHash, $narSize, $references, $deriver, $copyFrom, $system);
while (<MANIFEST>) {
chomp;
s/\#.*$//g;
next if (/^$/);
if (!$inside) {
if (/^\s*(\w*)\s*\{$/) {
$type = $1;
$type = "narfile" if $type eq "";
$inside = 1;
undef $storePath;
undef $url;
undef $hash;
undef $size;
undef $narHash;
undef $narSize;
undef $basePath;
undef $baseHash;
undef $patchType;
undef $system;
$references = "";
$deriver = "";
}
} else {
if (/^\}$/) {
$inside = 0;
if ($type eq "narfile") {
&$addNAR($storePath,
{ url => $url, hash => $hash, size => $size
, narHash => $narHash, narSize => $narSize
, references => $references
, deriver => $deriver
, system => $system
});
}
elsif ($type eq "patch") {
&$addPatch($storePath,
{ url => $url, hash => $hash, size => $size
, basePath => $basePath, baseHash => $baseHash
, narHash => $narHash, narSize => $narSize
, patchType => $patchType
});
}
}
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*BasePath:\s*(\/\S+)\s*$/) { $basePath = $1; }
elsif (/^\s*BaseHash:\s*(\S+)\s*$/) { $baseHash = $1; }
elsif (/^\s*Type:\s*(\S+)\s*$/) { $patchType = $1; }
elsif (/^\s*NarHash:\s*(\S+)\s*$/) { $narHash = $1; }
elsif (/^\s*NarSize:\s*(\d+)\s*$/) { $narSize = $1; }
elsif (/^\s*References:\s*(.*)\s*$/) { $references = $1; }
elsif (/^\s*Deriver:\s*(\S+)\s*$/) { $deriver = $1; }
elsif (/^\s*ManifestVersion:\s*(\d+)\s*$/) { $manifestVersion = $1; }
elsif (/^\s*System:\s*(\S+)\s*$/) { $system = $1; }
# Compatibility;
elsif (/^\s*NarURL:\s*(\S+)\s*$/) { $url = $1; }
elsif (/^\s*MD5:\s*(\S+)\s*$/) { $hash = "md5:$1"; }
}
}
close MANIFEST;
return $manifestVersion;
}
sub readManifest {
my ($manifest, $narFiles, $patches) = @_;
readManifest_($manifest,
sub { addNAR($narFiles, @_); },
sub { addPatch($patches, @_); } );
}
sub writeManifest {
my ($manifest, $narFiles, $patches, $noCompress) = @_;
open MANIFEST, ">$manifest.tmp"; # !!! check exclusive
print MANIFEST "version {\n";
print MANIFEST " ManifestVersion: 3\n";
print MANIFEST "}\n";
foreach my $storePath (sort (keys %{$narFiles})) {
my $narFileList = $$narFiles{$storePath};
foreach my $narFile (@{$narFileList}) {
print MANIFEST "{\n";
print MANIFEST " StorePath: $storePath\n";
print MANIFEST " NarURL: $narFile->{url}\n";
print MANIFEST " Hash: $narFile->{hash}\n" if defined $narFile->{hash};
print MANIFEST " Size: $narFile->{size}\n" if defined $narFile->{size};
print MANIFEST " NarHash: $narFile->{narHash}\n";
print MANIFEST " NarSize: $narFile->{narSize}\n" if $narFile->{narSize};
print MANIFEST " References: $narFile->{references}\n"
if defined $narFile->{references} && $narFile->{references} ne "";
print MANIFEST " Deriver: $narFile->{deriver}\n"
if defined $narFile->{deriver} && $narFile->{deriver} ne "";
print MANIFEST " System: $narFile->{system}\n" if defined $narFile->{system};
print MANIFEST "}\n";
}
}
foreach my $storePath (sort (keys %{$patches})) {
my $patchList = $$patches{$storePath};
foreach my $patch (@{$patchList}) {
print MANIFEST "patch {\n";
print MANIFEST " StorePath: $storePath\n";
print MANIFEST " NarURL: $patch->{url}\n";
print MANIFEST " Hash: $patch->{hash}\n";
print MANIFEST " Size: $patch->{size}\n";
print MANIFEST " NarHash: $patch->{narHash}\n";
print MANIFEST " NarSize: $patch->{narSize}\n" if $patch->{narSize};
print MANIFEST " BasePath: $patch->{basePath}\n";
print MANIFEST " BaseHash: $patch->{baseHash}\n";
print MANIFEST " Type: $patch->{patchType}\n";
print MANIFEST "}\n";
}
}
close MANIFEST;
rename("$manifest.tmp", $manifest)
or die "cannot rename $manifest.tmp: $!";
# Create a bzipped manifest.
unless (defined $noCompress) {
system("$Nix::Config::bzip2 < $manifest > $manifest.bz2.tmp") == 0
or die "cannot compress manifest";
rename("$manifest.bz2.tmp", "$manifest.bz2")
or die "cannot rename $manifest.bz2.tmp: $!";
}
}
sub updateManifestDB {
my $manifestDir = $Nix::Config::manifestDir;
mkpath($manifestDir);
my $dbPath = "$manifestDir/cache.sqlite";
# Open/create the database.
our $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
or die "cannot open database `$dbPath'";
$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
$dbh->do("pragma foreign_keys = on");
$dbh->do("pragma synchronous = off"); # we can always reproduce the cache
$dbh->do("pragma journal_mode = truncate");
# Initialise the database schema, if necessary.
$dbh->do(<<EOF);
create table if not exists Manifests (
id integer primary key autoincrement not null,
path text unique not null,
timestamp integer not null
);
EOF
$dbh->do(<<EOF);
create table if not exists NARs (
id integer primary key autoincrement not null,
manifest integer not null,
storePath text not null,
url text not null,
hash text,
size integer,
narHash text,
narSize integer,
refs text,
deriver text,
system text,
foreign key (manifest) references Manifests(id) on delete cascade
);
EOF
$dbh->do("create index if not exists NARs_storePath on NARs(storePath)");
$dbh->do(<<EOF);
create table if not exists Patches (
id integer primary key autoincrement not null,
manifest integer not null,
storePath text not null,
basePath text not null,
baseHash text not null,
url text not null,
hash text,
size integer,
narHash text,
narSize integer,
patchType text not null,
foreign key (manifest) references Manifests(id) on delete cascade
);
EOF
$dbh->do("create index if not exists Patches_storePath on Patches(storePath)");
# Acquire an exclusive lock to ensure that only one process
# updates the DB at the same time. This isn't really necessary,
# but it prevents work duplication and lock contention in SQLite.
my $lockFile = "$manifestDir/cache.lock";
open MAINLOCK, ">>$lockFile" or die "unable to acquire lock $lockFile: $!\n";
flock(MAINLOCK, LOCK_EX) or die;
our $insertNAR = $dbh->prepare(
"insert into NARs(manifest, storePath, url, hash, size, narHash, " .
"narSize, refs, deriver, system) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") or die;
our $insertPatch = $dbh->prepare(
"insert into Patches(manifest, storePath, basePath, baseHash, url, hash, " .
"size, narHash, narSize, patchType) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$dbh->begin_work;
# Read each manifest in $manifestDir and add it to the database,
# unless we've already done so on a previous run.
my %seen;
for my $manifestLink (glob "$manifestDir/*.nixmanifest") {
my $manifest = Cwd::abs_path($manifestLink);
next unless -f $manifest;
my $timestamp = lstat($manifest)->mtime;
$seen{$manifest} = 1;
next if scalar @{$dbh->selectcol_arrayref(
"select 1 from Manifests where path = ? and timestamp = ?",
{}, $manifest, $timestamp)} == 1;
print STDERR "caching $manifest...\n";
$dbh->do("delete from Manifests where path = ?", {}, $manifest);
$dbh->do("insert into Manifests(path, timestamp) values (?, ?)",
{}, $manifest, $timestamp);
our $id = $dbh->last_insert_id("", "", "", "");
sub addNARToDB {
my ($storePath, $narFile) = @_;
$insertNAR->execute(
$id, $storePath, $narFile->{url}, $narFile->{hash}, $narFile->{size},
$narFile->{narHash}, $narFile->{narSize}, $narFile->{references},
$narFile->{deriver}, $narFile->{system});
};
sub addPatchToDB {
my ($storePath, $patch) = @_;
$insertPatch->execute(
$id, $storePath, $patch->{basePath}, $patch->{baseHash}, $patch->{url},
$patch->{hash}, $patch->{size}, $patch->{narHash}, $patch->{narSize},
$patch->{patchType});
};
my $version = readManifest_($manifest, \&addNARToDB, \&addPatchToDB);
if ($version < 3) {
die "you have an old-style or corrupt manifest `$manifestLink'; please delete it\n";
}
if ($version >= 10) {
die "manifest `$manifestLink' is too new; please delete it or upgrade Nix\n";
}
}
# Removed cached information for removed manifests from the DB.
foreach my $manifest (@{$dbh->selectcol_arrayref("select path from Manifests")}) {
next if defined $seen{$manifest};
$dbh->do("delete from Manifests where path = ?", {}, $manifest);
}
$dbh->commit;
close MAINLOCK;
return $dbh;
}
return 1;

91
perl/lib/Nix/Store.pm Normal file
View File

@@ -0,0 +1,91 @@
package Nix::Store;
use strict;
use warnings;
use Nix::Config;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
isValidPath queryReferences queryPathInfo queryDeriver queryPathHash
topoSortPaths computeFSClosure followLinksToStorePath exportPaths
hashPath hashFile hashString
addToStore makeFixedOutputPath
derivationFromPath
);
our $VERSION = '0.15';
sub backtick {
open(RES, "-|", @_) or die;
local $/;
my $res = <RES> || "";
close RES or die;
return $res;
}
if ($Nix::Config::useBindings) {
require XSLoader;
XSLoader::load('Nix::Store', $VERSION);
} else {
# Provide slow fallbacks of some functions on platforms that don't
# support the Perl bindings.
use File::Temp;
use Fcntl qw/F_SETFD/;
sub hashFile {
my ($algo, $base32, $path) = @_;
my $res = backtick("$Nix::Config::binDir/nix-hash", "--flat", $path, "--type", $algo, $base32 ? "--base32" : ());
chomp $res;
return $res;
}
sub hashPath {
my ($algo, $base32, $path) = @_;
my $res = backtick("$Nix::Config::binDir/nix-hash", $path, "--type", $algo, $base32 ? "--base32" : ());
chomp $res;
return $res;
}
sub hashString {
my ($algo, $base32, $s) = @_;
my $fh = File::Temp->new();
print $fh $s;
my $res = backtick("$Nix::Config::binDir/nix-hash", $fh->filename, "--type", $algo, $base32 ? "--base32" : ());
chomp $res;
return $res;
}
sub addToStore {
my ($srcPath, $recursive, $algo) = @_;
die "not implemented" if $recursive || $algo ne "sha256";
my $res = backtick("$Nix::Config::binDir/nix-store", "--add", $srcPath);
chomp $res;
return $res;
}
sub isValidPath {
my ($path) = @_;
my $res = backtick("$Nix::Config::binDir/nix-store", "--check-validity", "--print-invalid", $path);
chomp $res;
return $res ne $path;
}
sub queryPathHash {
my ($path) = @_;
my $res = backtick("$Nix::Config::binDir/nix-store", "--query", "--hash", $path);
chomp $res;
return $res;
}
}
1;
__END__

260
perl/lib/Nix/Store.xs Normal file
View File

@@ -0,0 +1,260 @@
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/* Prevent a clash between some Perl and libstdc++ macros. */
#undef do_open
#undef do_close
#include <store-api.hh>
#include <globals.hh>
#include <misc.hh>
#include <util.hh>
using namespace nix;
void doInit()
{
if (!store) {
try {
setDefaultsFromEnvironment();
store = openStore();
} catch (Error & e) {
croak(e.what());
}
}
}
MODULE = Nix::Store PACKAGE = Nix::Store
PROTOTYPES: ENABLE
void init()
CODE:
doInit();
int isValidPath(char * path)
CODE:
try {
doInit();
RETVAL = store->isValidPath(path);
} catch (Error & e) {
croak(e.what());
}
OUTPUT:
RETVAL
SV * queryReferences(char * path)
PPCODE:
try {
doInit();
PathSet paths;
store->queryReferences(path, paths);
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * queryPathHash(char * path)
PPCODE:
try {
doInit();
Hash hash = store->queryPathHash(path);
string s = "sha256:" + printHash32(hash);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * queryDeriver(char * path)
PPCODE:
try {
doInit();
Path deriver = store->queryDeriver(path);
if (deriver == "") XSRETURN_UNDEF;
XPUSHs(sv_2mortal(newSVpv(deriver.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * queryPathInfo(char * path)
PPCODE:
try {
doInit();
ValidPathInfo info = store->queryPathInfo(path);
if (info.deriver == "")
XPUSHs(&PL_sv_undef);
else
XPUSHs(sv_2mortal(newSVpv(info.deriver.c_str(), 0)));
string s = "sha256:" + printHash(info.hash);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
mXPUSHi(info.registrationTime);
mXPUSHi(info.narSize);
AV * arr = newAV();
for (PathSet::iterator i = info.references.begin(); i != info.references.end(); ++i)
av_push(arr, newSVpv(i->c_str(), 0));
XPUSHs(sv_2mortal(newRV((SV *) arr)));
} catch (Error & e) {
croak(e.what());
}
SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
PPCODE:
try {
doInit();
PathSet paths;
for (int n = 2; n < items; ++n)
computeFSClosure(*store, SvPV_nolen(ST(n)), paths, flipDirection, includeOutputs);
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * topoSortPaths(...)
PPCODE:
try {
doInit();
PathSet paths;
for (int n = 0; n < items; ++n) paths.insert(SvPV_nolen(ST(n)));
Paths sorted = topoSortPaths(*store, paths);
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i)
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * followLinksToStorePath(char * path)
CODE:
try {
doInit();
RETVAL = newSVpv(followLinksToStorePath(path).c_str(), 0);
} catch (Error & e) {
croak(e.what());
}
OUTPUT:
RETVAL
void exportPaths(int fd, int sign, ...)
PPCODE:
try {
doInit();
Paths paths;
for (int n = 2; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
FdSink sink(fd);
exportPaths(*store, paths, sign, sink);
} catch (Error & e) {
croak(e.what());
}
SV * hashPath(char * algo, int base32, char * path)
PPCODE:
try {
Hash h = hashPath(parseHashType(algo), path).first;
string s = base32 ? printHash32(h) : printHash(h);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * hashFile(char * algo, int base32, char * path)
PPCODE:
try {
Hash h = hashFile(parseHashType(algo), path);
string s = base32 ? printHash32(h) : printHash(h);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * hashString(char * algo, int base32, char * s)
PPCODE:
try {
Hash h = hashString(parseHashType(algo), s);
string s = base32 ? printHash32(h) : printHash(h);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * addToStore(char * srcPath, int recursive, char * algo)
PPCODE:
try {
doInit();
Path path = store->addToStore(srcPath, recursive, parseHashType(algo));
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * makeFixedOutputPath(int recursive, char * algo, char * hash, char * name)
PPCODE:
try {
doInit();
HashType ht = parseHashType(algo);
Path path = makeFixedOutputPath(recursive, ht,
parseHash16or32(ht, hash), name);
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * derivationFromPath(char * drvPath)
PREINIT:
HV *hash;
CODE:
try {
doInit();
Derivation drv = derivationFromPath(*store, drvPath);
hash = newHV();
/* TODO: handle drv.outputs */
AV * inputDrvs = newAV();
for (DerivationInputs::iterator i = drv.inputDrvs.begin(); i != drv.inputDrvs.end(); ++i)
av_push(inputDrvs, newSVpv(i->first.c_str(), 0)); // !!! ignores i->second
hv_stores(hash, "inputDrvs", newRV((SV *) inputDrvs));
AV * inputSrcs = newAV();
for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i)
av_push(inputSrcs, newSVpv(i->c_str(), 0));
hv_stores(hash, "inputSrcs", newRV((SV *) inputSrcs));
hv_stores(hash, "platform", newSVpv(drv.platform.c_str(), 0));
hv_stores(hash, "builder", newSVpv(drv.builder.c_str(), 0));
AV * args = newAV();
for (Strings::iterator i = drv.args.begin(); i != drv.args.end(); ++i)
av_push(args, newSVpv(i->c_str(), 0));
hv_stores(hash, "args", newRV((SV *) args));
HV * env = newHV();
for (StringPairs::iterator i = drv.env.begin(); i != drv.env.end(); ++i)
hv_store(env, i->first.c_str(), i->first.size(), newSVpv(i->second.c_str(), 0), 0);
hv_stores(hash, "env", newRV((SV *) env));
RETVAL = newRV_noinc((SV *)hash);
} catch (Error & e) {
croak(e.what());
}
OUTPUT:
RETVAL

View File

@@ -1,5 +1,5 @@
{ nixpkgs ? ../nixpkgs
, nix ? { outPath = ./.; rev = 1234; }
{ nixpkgs ? <nixpkgs>
, nix ? { outPath = ./.; revCount = 1234; shortRev = "abcdef"; }
, officialRelease ? false
}:
@@ -14,28 +14,29 @@ let
releaseTools.sourceTarball {
name = "nix-tarball";
version = builtins.readFile ./version;
versionSuffix = if officialRelease then "" else "pre${toString nix.revCount}_${nix.shortRev}";
src = nix;
inherit officialRelease;
buildInputs =
[ curl bison24 flex2535 perl libxml2 libxslt w3m bzip2
tetex dblatex nukeReferences pkgconfig
[ curl bison25 flex2535 perl libxml2 libxslt w3m bzip2
tetex dblatex nukeReferences pkgconfig sqlite git
];
configureFlags = ''
--with-docbook-rng=${docbook5}/xml/rng/docbook
--with-docbook-xsl=${docbook5_xsl}/xml/xsl/docbook
--with-xml-flags=--nonet
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
'';
postUnpack = ''
# Clean up when building from a working tree.
(cd $sourceRoot && (git ls-files -o | xargs -r rm -v))
'';
# Include the Bzip2 tarball in the distribution.
preConfigure = ''
stripHash ${bzip2.src}
cp -pv ${bzip2.src} externals/$strippedName
stripHash ${sqlite.src}
cp -pv ${sqlite.src} externals/$strippedName
# TeX needs a writable font cache.
export VARTEXFONTS=$TMPDIR/texfonts
'';
@@ -70,13 +71,16 @@ let
name = "nix";
src = tarball;
buildInputs = [ curl perl bzip2 openssl pkgconfig boehmgc ];
buildInputs = [ curl perl bzip2 openssl pkgconfig sqlite boehmgc ];
configureFlags = ''
--disable-init-state
--with-bzip2=${bzip2} --with-sqlite=${sqlite}
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
--enable-gc
'';
doInstallCheck = true;
};
@@ -88,16 +92,21 @@ let
src = tarball;
buildInputs =
[ curl perl bzip2 openssl
[ curl perl bzip2 openssl pkgconfig sqlite
# These are for "make check" only:
graphviz libxml2 libxslt
];
configureFlags = ''
--disable-init-state --disable-shared
--with-bzip2=${bzip2} --with-sqlite=${sqlite}
--disable-init-state
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
'';
dontInstall = false;
doInstallCheck = true;
lcovFilter = [ "*/boost/*" "*-tab.*" ];
# We call `dot', and even though we just use it to
@@ -107,34 +116,38 @@ let
};
rpm_fedora5i386 = makeRPM_i686 (diskImages: diskImages.fedora5i386) 10;
rpm_fedora9i386 = makeRPM_i686 (diskImages: diskImages.fedora9i386) 20;
rpm_fedora9x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora9x86_64) 20;
rpm_fedora10i386 = makeRPM_i686 (diskImages: diskImages.fedora10i386) 30;
rpm_fedora10x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora10x86_64) 30;
rpm_fedora11i386 = makeRPM_i686 (diskImages: diskImages.fedora11i386) 40;
rpm_fedora11x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora11x86_64) 40;
rpm_fedora12i386 = makeRPM_i686 (diskImages: diskImages.fedora12i386) 50;
rpm_fedora12x86_64 = makeRPM_x86_64 (diskImages: diskImages.fedora12x86_64) 50;
rpm_opensuse103i386 = makeRPM_i686 (diskImages: diskImages.opensuse103i386) 40;
rpm_opensuse110i386 = makeRPM_i686 (diskImages: diskImages.opensuse110i386) 50;
rpm_opensuse110x86_64 = makeRPM_x86_64 (diskImages: diskImages.opensuse110x86_64) 50;
rpm_fedora13i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora13i386) 50;
rpm_fedora13x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora13x86_64) 50;
rpm_fedora16i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora16i386) 50;
rpm_fedora16x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora16x86_64) 50;
rpm_opensuse103i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.opensuse103i386) 40;
rpm_opensuse110i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.opensuse110i386) 50;
rpm_opensuse110x86_64 = makeRPM_x86_64 (diskImageFuns: diskImageFuns.opensuse110x86_64) 50;
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) 50;
deb_debian50x86_64 = makeDeb_x86_64 (diskImages: diskImages.debian50x86_64) 50;
deb_ubuntu804i386 = makeDeb_i686 (diskImages: diskImages.ubuntu804i386) 20;
deb_ubuntu804x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu804x86_64) 20;
deb_ubuntu810i386 = makeDeb_i686 (diskImages: diskImages.ubuntu810i386) 30;
deb_ubuntu810x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu810x86_64) 30;
deb_ubuntu904i386 = makeDeb_i686 (diskImages: diskImages.ubuntu904i386) 40;
deb_ubuntu904x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu904x86_64) 40;
deb_ubuntu910i386 = makeDeb_i686 (diskImages: diskImages.ubuntu910i386) 50;
deb_ubuntu910x86_64 = makeDeb_x86_64 (diskImages: diskImages.ubuntu910x86_64) 50;
deb_debian60i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian60i386) 50;
deb_debian60x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian60x86_64) 50;
deb_ubuntu1004i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1004i386) 50;
deb_ubuntu1004x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1004x86_64) 50;
deb_ubuntu1010i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1010i386) 50;
deb_ubuntu1010x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1010x86_64) 50;
deb_ubuntu1110i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1110i386) 60;
deb_ubuntu1110x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1110x86_64) 60;
deb_ubuntu1204i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1204i386) 60;
deb_ubuntu1204x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1204x86_64) 60;
# System tests.
tests.remote_builds = (import ./tests/remote-builds.nix rec {
nix = build { inherit system; }; system = "x86_64-linux";
}).test;
tests.nix_copy_closure = (import ./tests/nix-copy-closure.nix rec {
nix = build { inherit system; }; system = "x86_64-linux";
}).test;
};
@@ -149,9 +162,11 @@ let
releaseTools.rpmBuild rec {
name = "nix-rpm-${diskImage.name}";
src = jobs.tarball;
diskImage = diskImageFun vmTools.diskImages;
diskImage = (diskImageFun vmTools.diskImageFuns)
{ extraPackages = [ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" ]; };
memSize = 1024;
meta.schedulingPriority = prio;
postRPMInstall = "cd /tmp/rpmout/BUILD/nix-* && make installcheck";
};
@@ -166,11 +181,13 @@ let
releaseTools.debBuild {
name = "nix-deb";
src = jobs.tarball;
diskImage = diskImageFun vmTools.diskImages;
diskImage = (diskImageFun vmTools.diskImageFuns)
{ extraPackages = [ "libdbd-sqlite3-perl" "libsqlite3-dev" "libbz2-dev" ]; };
memSize = 1024;
meta.schedulingPriority = prio;
configureFlags = "--sysconfdir=/etc";
debRequires = [ "curl" ];
debRequires = [ "curl" "libdbd-sqlite3-perl" "libsqlite3-0" "libbz2-1.0" ];
doInstallCheck = true;
};

View File

@@ -3,20 +3,16 @@ bin_SCRIPTS = nix-collect-garbage \
nix-install-package nix-channel nix-build \
nix-copy-closure nix-generate-patches
noinst_SCRIPTS = nix-profile.sh GeneratePatches.pm \
noinst_SCRIPTS = nix-profile.sh \
find-runtime-roots.pl build-remote.pl nix-reduce-build \
copy-from-other-stores.pl nix-http-export.cgi
nix-pull nix-push: NixManifest.pm NixConfig.pm download-using-manifests.pl
nix-pull nix-push: download-using-manifests.pl
install-exec-local: NixManifest.pm GeneratePatches.pm download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl
install-exec-local: 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) NixManifest.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_DATA) NixConfig.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_DATA) SSH.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_DATA) GeneratePatches.pm $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix/substituters
@@ -30,10 +26,6 @@ EXTRA_DIST = nix-collect-garbage.in \
nix-pull.in nix-push.in nix-profile.sh.in \
nix-prefetch-url.in nix-install-package.in \
nix-channel.in \
NixManifest.pm.in \
NixConfig.pm.in \
SSH.pm \
GeneratePatches.pm.in \
nix-build.in \
download-using-manifests.pl.in \
copy-from-other-stores.pl.in \
@@ -43,3 +35,6 @@ EXTRA_DIST = nix-collect-garbage.in \
nix-reduce-build.in \
nix-http-export.cgi.in \
nix-generate-patches.in
clean:
rm -f $(bin_SCRIPTS) $(noinst_SCRIPTS)

View File

@@ -1,17 +0,0 @@
use strict;
sub readConfig {
my %config;
my $config = "@sysconfdir@/nix/nix.conf";
return unless -f $config;
open CONFIG, "<$config" or die "cannot open `$config'";
while (<CONFIG>) {
/^\s*([\w|-]+)\s*=\s*(.*)$/ or next;
$config{$1} = $2;
print "|$1| -> |$2|\n";
}
close CONFIG;
}
return 1;

View File

@@ -1,211 +0,0 @@
use strict;
sub addPatch {
my ($patches, $storePath, $patch) = @_;
$$patches{$storePath} = []
unless defined $$patches{$storePath};
my $patchList = $$patches{$storePath};
my $found = 0;
foreach my $patch2 (@{$patchList}) {
$found = 1 if
$patch2->{url} eq $patch->{url} &&
$patch2->{basePath} eq $patch->{basePath};
}
push @{$patchList}, $patch if !$found;
return !$found;
}
sub readManifest {
my ($manifest, $narFiles, $localPaths, $patches) = @_;
open MANIFEST, "<$manifest"
or die "cannot open `$manifest': $!";
my $inside = 0;
my $type;
my $manifestVersion = 2;
my ($storePath, $url, $hash, $size, $basePath, $baseHash, $patchType);
my ($narHash, $narSize, $references, $deriver, $hashAlgo, $copyFrom, $system);
while (<MANIFEST>) {
chomp;
s/\#.*$//g;
next if (/^$/);
if (!$inside) {
if (/^\s*(\w*)\s*\{$/) {
$type = $1;
$type = "narfile" if $type eq "";
$inside = 1;
undef $storePath;
undef $url;
undef $hash;
undef $size;
undef $narHash;
undef $narSize;
undef $basePath;
undef $baseHash;
undef $patchType;
undef $system;
$references = "";
$deriver = "";
$hashAlgo = "md5";
}
} else {
if (/^\}$/) {
$inside = 0;
if ($type eq "narfile") {
$$narFiles{$storePath} = []
unless defined $$narFiles{$storePath};
my $narFileList = $$narFiles{$storePath};
my $found = 0;
foreach my $narFile (@{$narFileList}) {
$found = 1 if $narFile->{url} eq $url;
}
if (!$found) {
push @{$narFileList},
{ url => $url, hash => $hash, size => $size
, narHash => $narHash, narSize => $narSize
, references => $references
, deriver => $deriver, hashAlgo => $hashAlgo
, system => $system
};
}
}
elsif ($type eq "patch") {
addPatch $patches, $storePath,
{ url => $url, hash => $hash, size => $size
, basePath => $basePath, baseHash => $baseHash
, narHash => $narHash, narSize => $narSize
, patchType => $patchType, hashAlgo => $hashAlgo
};
}
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*$/) { } # 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; }
elsif (/^\s*NarHash:\s*(\S+)\s*$/) { $narHash = $1; }
elsif (/^\s*NarSize:\s*(\d+)\s*$/) { $narSize = $1; }
elsif (/^\s*References:\s*(.*)\s*$/) { $references = $1; }
elsif (/^\s*Deriver:\s*(\S+)\s*$/) { $deriver = $1; }
elsif (/^\s*ManifestVersion:\s*(\d+)\s*$/) { $manifestVersion = $1; }
elsif (/^\s*System:\s*(\S+)\s*$/) { $system = $1; }
# Compatibility;
elsif (/^\s*NarURL:\s*(\S+)\s*$/) { $url = $1; }
elsif (/^\s*MD5:\s*(\S+)\s*$/) { $hash = "md5:$1"; }
}
}
close MANIFEST;
return $manifestVersion;
}
sub writeManifest {
my ($manifest, $narFiles, $patches, $noCompress) = @_;
open MANIFEST, ">$manifest.tmp"; # !!! check exclusive
print MANIFEST "version {\n";
print MANIFEST " ManifestVersion: 3\n";
print MANIFEST "}\n";
foreach my $storePath (sort (keys %{$narFiles})) {
my $narFileList = $$narFiles{$storePath};
foreach my $narFile (@{$narFileList}) {
print MANIFEST "{\n";
print MANIFEST " StorePath: $storePath\n";
print MANIFEST " NarURL: $narFile->{url}\n";
print MANIFEST " Hash: $narFile->{hash}\n" if defined $narFile->{hash};
print MANIFEST " Size: $narFile->{size}\n" if defined $narFile->{size};
print MANIFEST " NarHash: $narFile->{narHash}\n";
print MANIFEST " NarSize: $narFile->{narSize}\n" if $narFile->{narSize};
print MANIFEST " References: $narFile->{references}\n"
if defined $narFile->{references} && $narFile->{references} ne "";
print MANIFEST " Deriver: $narFile->{deriver}\n"
if defined $narFile->{deriver} && $narFile->{deriver} ne "";
print MANIFEST " System: $narFile->{system}\n" if defined $narFile->{system};
print MANIFEST "}\n";
}
}
foreach my $storePath (sort (keys %{$patches})) {
my $patchList = $$patches{$storePath};
foreach my $patch (@{$patchList}) {
print MANIFEST "patch {\n";
print MANIFEST " StorePath: $storePath\n";
print MANIFEST " NarURL: $patch->{url}\n";
print MANIFEST " Hash: $patch->{hash}\n";
print MANIFEST " Size: $patch->{size}\n";
print MANIFEST " NarHash: $patch->{narHash}\n";
print MANIFEST " NarSize: $patch->{narSize}\n" if $patch->{narSize};
print MANIFEST " BasePath: $patch->{basePath}\n";
print MANIFEST " BaseHash: $patch->{baseHash}\n";
print MANIFEST " Type: $patch->{patchType}\n";
print MANIFEST "}\n";
}
}
close MANIFEST;
rename("$manifest.tmp", $manifest)
or die "cannot rename $manifest.tmp: $!";
# Create a bzipped manifest.
unless (defined $noCompress) {
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: $!";
}
}
return 1;

View File

@@ -1,9 +1,11 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use Fcntl ':flock';
use Fcntl qw(:DEFAULT :flock);
use English '-no_match_vars';
use IO::Handle;
use SSH qw/sshOpts openSSHConnection/;
use Nix::Config;
use Nix::SSH qw/sshOpts openSSHConnection/;
use Nix::CopyClosure;
no warnings('once');
@@ -54,7 +56,7 @@ sub openSlotLock {
my ($machine, $slot) = @_;
my $slotLockFn = "$currentLoad/" . (join '+', @{$machine->{systemTypes}}) . "-" . $machine->{hostName} . "-$slot";
my $slotLock = new IO::Handle;
open $slotLock, ">>$slotLockFn" or die;
sysopen $slotLock, "$slotLockFn", O_RDWR|O_CREAT, 0600 or die;
return $slotLock;
}
@@ -62,19 +64,22 @@ sub openSlotLock {
# Read the list of machines.
my @machines;
if (defined $conf && -e $conf) {
open CONF, "< $conf" or die;
open CONF, "<$conf" or die;
while (<CONF>) {
chomp;
s/\#.*$//g;
next if /^\s*$/;
my @tokens = split /\s/, $_;
my @supportedFeatures = split(/,/, $tokens[5] || "");
my @mandatoryFeatures = split(/,/, $tokens[6] || "");
push @machines,
{ hostName => $tokens[0]
, systemTypes => [ split(/,/, $tokens[1]) ]
, sshKeys => $tokens[2]
, maxJobs => int($tokens[3])
, speedFactor => 1.0 * (defined $tokens[4] ? int($tokens[4]) : 1)
, features => [ split(/,/, $tokens[5] || "") ]
, supportedFeatures => [ @supportedFeatures, @mandatoryFeatures ]
, mandatoryFeatures => [ @mandatoryFeatures ]
, enabled => 1
};
}
@@ -88,8 +93,7 @@ my ($drvPath, $hostName, $slotLock);
REQ: while (1) {
$_ = <STDIN> || exit 0;
my ($amWilling, $neededSystem);
($amWilling, $neededSystem, $drvPath, $requiredFeatures) = split;
(my $amWilling, my $neededSystem, $drvPath, my $requiredFeatures) = split;
my @requiredFeatures = split /,/, $requiredFeatures;
my $canBuildLocally = $amWilling && ($localSystem eq $neededSystem);
@@ -102,7 +106,7 @@ REQ: while (1) {
# Acquire the exclusive lock on $currentLoad/main-lock.
mkdir $currentLoad, 0777 or die unless -d $currentLoad;
my $mainLock = "$currentLoad/main-lock";
open MAINLOCK, ">>$mainLock" or die;
sysopen MAINLOCK, "$mainLock", O_RDWR|O_CREAT, 0600 or die;
flock(MAINLOCK, LOCK_EX) or die;
@@ -115,7 +119,9 @@ REQ: while (1) {
LOOP: foreach my $cur (@machines) {
if ($cur->{enabled}
&& (grep { $neededSystem eq $_ } @{$cur->{systemTypes}})
&& all(map { my $f = $_; 0 != grep { $f eq $_ } @{$cur->{features}} } @requiredFeatures))
&& all(map { my $f = $_; 0 != grep { $f eq $_ } @{$cur->{supportedFeatures}} } (@requiredFeatures, @mandatoryFeatures))
&& all(map { my $f = $_; 0 != grep { $f eq $_ } @requiredFeatures } @{$cur->{mandatoryFeatures}})
)
{
$rightType = 1;
@@ -208,7 +214,7 @@ print STDERR "@ build-remote $drvPath $hostName\n" if $printBuildTrace;
my $maybeSign = "";
$maybeSign = "--sign" if -e "/nix/etc/nix/signing-key.sec";
$maybeSign = "--sign" if -e "$Nix::Config::confDir/signing-key.sec";
# Register the derivation as a temporary GC root. Note that $PPID is
@@ -223,9 +229,31 @@ sub removeRoots {
}
# Copy the derivation and its dependencies to the build machine.
system("NIX_SSHOPTS=\"@sshOpts\" @bindir@/nix-copy-closure $hostName $maybeSign $drvPath @inputs") == 0
or die "cannot copy inputs to $hostName: $?";
# Copy the derivation and its dependencies to the build machine. This
# is guarded by an exclusive lock per machine to prevent multiple
# build-remote instances from copying to a machine simultaneously.
# That's undesirable because we may end up with N instances uploading
# the same missing path simultaneously, causing the effective network
# bandwidth and target disk speed to be divided by N.
my $uploadLock = "$currentLoad/$hostName.upload-lock";
sysopen UPLOADLOCK, "$uploadLock", O_RDWR|O_CREAT, 0600 or die;
eval {
local $SIG{ALRM} = sub { die "alarm\n" };
# Don't wait forever, so that a process that gets stuck while
# holding the lock doesn't block everybody else indefinitely.
# It's safe to continue after a timeout, just (potentially)
# inefficient.
alarm 15 * 60;
flock(UPLOADLOCK, LOCK_EX);
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n";
print STDERR "somebody is hogging $uploadLock, continuing...\n";
unlink $uploadLock;
}
Nix::CopyClosure::copyTo($hostName, [ @sshOpts ], [ $drvPath, @inputs ], "", "", 0, 0, $maybeSign ne "", "");
close UPLOADLOCK;
# Perform the build.
@@ -239,7 +267,7 @@ my $buildFlags = "--max-silent-time $maxSilentTime --fallback --add-root $rootsD
# in which case every child receives SIGHUP; however, `-tt' doesn't
# work on some platforms when connection sharing is used.)
pipe STDIN, DUMMY; # make sure we have a readable STDIN
if (system("ssh $hostName @sshOpts '(read; kill -INT -\$\$) <&0 & nix-store -r $drvPath $buildFlags > /dev/null' 2>&4") != 0) {
if (system("exec ssh $hostName @sshOpts '(read; kill -INT -\$\$) <&0 & nix-store -r $drvPath $buildFlags > /dev/null' 2>&4") != 0) {
# Note that if we get exit code 100 from `nix-store -r', it
# denotes a permanent build failure (as opposed to an SSH problem
# or a temporary Nix problem). We propagate this to the caller to
@@ -259,7 +287,7 @@ foreach my $output (@outputs) {
my $maybeSignRemote = "";
$maybeSignRemote = "--sign" if $UID != 0;
system("ssh $hostName @sshOpts 'nix-store --export $maybeSignRemote $output'" .
system("exec ssh $hostName @sshOpts 'nix-store --export $maybeSignRemote $output'" .
"| NIX_HELD_LOCKS=$output @bindir@/nix-store --import > /dev/null") == 0
or die "cannot copy $output from $hostName: $?";
}

2
scripts/copy-from-other-stores.pl.in Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#! @perl@ -w
#! @perl@ -w @perlFlags@
use strict;
use File::Basename;

162
scripts/download-using-manifests.pl.in Normal file → Executable file
View File

@@ -1,48 +1,27 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use strict;
use NixManifest;
use Nix::Config;
use Nix::Manifest;
use Nix::Store;
use POSIX qw(strftime);
use File::Temp qw(tempdir);
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";
my $logFile = "$Nix::Config::logDir/downloads";
# For queries, skip expensive calls to nix-hash etc. We're just
# estimating the expected download size.
my $fast = 1;
# 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;
}
}
# Open the manifest cache and update it if necessary.
my $dbh = updateManifestDB();
sub isValidPath {
my $p = shift;
if ($fast) {
return -e $p;
} else {
return system("$binDir/nix-store --check-validity '$p' 2> /dev/null") == 0;
}
}
# $hashCache->{$algo}->{$path} yields the $algo-hash of $path.
my $hashCache;
sub parseHash {
@@ -111,18 +90,23 @@ sub computeSmallestDownload {
else {
# Add patch edges.
my $patchList = $patches{$u};
my $patchList = $dbh->selectall_arrayref(
"select * from Patches where storePath = ?",
{ Slice => {} }, $u);
foreach my $patch (@{$patchList}) {
if (isValidPath($patch->{basePath})) {
# !!! this should be cached
my ($baseHashAlgo, $baseHash) = parseHash $patch->{baseHash};
my $format = "--base32";
$format = "" if $baseHashAlgo eq "md5";
my $hash = $fast && $baseHashAlgo eq "sha256"
? `$binDir/nix-store -q --hash "$patch->{basePath}"`
: `$binDir/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
chomp $hash;
$hash =~ s/.*://;
my $hash = $hashCache->{$baseHashAlgo}->{$patch->{basePath}};
if (!defined $hash) {
$hash = $fast && $baseHashAlgo eq "sha256"
? queryPathHash($patch->{basePath})
: hashPath($baseHashAlgo, $baseHashAlgo ne "md5", $patch->{basePath});
$hash =~ s/.*://;
$hashCache->{$baseHashAlgo}->{$patch->{basePath}} = $hash;
}
next if $hash ne $baseHash;
}
push @queue, $patch->{basePath};
@@ -130,11 +114,15 @@ sub computeSmallestDownload {
}
# Add NAR file edges to the start node.
my $narFileList = $narFiles{$u};
my $narFileList = $dbh->selectall_arrayref(
"select * from NARs where storePath = ?",
{ Slice => {} }, $u);
foreach my $narFile (@{$narFileList}) {
# !!! how to handle files whose size is not known in advance?
# For now, assume some arbitrary size (1 MB).
addEdge \%graph, "start", $u, ($narFile->{size} || 1000000), "narfile", $narFile;
# For now, assume some arbitrary size (1 GB).
# This has the side-effect of preferring non-Hydra downloads.
addEdge \%graph, "start", $u, ($narFile->{size} || 1000000000), "narfile", $narFile;
}
}
}
@@ -161,7 +149,7 @@ sub computeSmallestDownload {
$v_->{d} = $u_->{d} + $edge->{weight};
# Store the edge; to edge->start is actually the
# predecessor.
$v_->{pred} = $edge;
$v_->{pred} = $edge;
}
}
}
@@ -189,19 +177,21 @@ if ($ARGV[0] eq "--query") {
if ($cmd eq "have") {
my $storePath = <STDIN>; chomp $storePath;
print STDOUT ((defined $narFiles{$storePath} or defined $localPaths{$storePath})
print STDOUT (
scalar @{$dbh->selectcol_arrayref("select 1 from NARs where storePath = ?", {}, $storePath)} > 0
? "1\n" : "0\n");
}
elsif ($cmd eq "info") {
my $storePath = <STDIN>; chomp $storePath;
my $infos = $dbh->selectall_arrayref(
"select * from NARs where storePath = ?",
{ Slice => {} }, $storePath);
my $info;
if (defined $narFiles{$storePath}) {
$info = @{$narFiles{$storePath}}[0];
}
elsif (defined $localPaths{$storePath}) {
$info = @{$localPaths{$storePath}}[0];
if (scalar @{$infos} > 0) {
$info = @{$infos}[0];
}
else {
print "0\n";
@@ -210,12 +200,12 @@ if ($ARGV[0] eq "--query") {
print "1\n";
print "$info->{deriver}\n";
my @references = split " ", $info->{references};
my @references = split " ", $info->{refs};
print scalar @references, "\n";
print "$_\n" foreach @references;
my @path = computeSmallestDownload $storePath;
my $downloadSize = 0;
while (scalar @path > 0) {
my $edge = pop @path;
@@ -228,7 +218,7 @@ if ($ARGV[0] eq "--query") {
$downloadSize += $edge->{info}->{size} || 0;
}
}
print "$downloadSize\n";
my $narSize = $info->{narSize} || 0;
@@ -264,20 +254,7 @@ 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";
print "\n*** Trying to download/patch `$targetPath'\n";
# 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;
}
}
print STDERR "\n*** Trying to download/patch `$targetPath'\n";
# Compute the shortest path.
@@ -285,6 +262,12 @@ my @path = computeSmallestDownload $targetPath;
die "don't know how to produce $targetPath\n" if scalar @path == 0;
# We don't need the manifest anymore, so close it as an optimisation:
# if we still have SQLite locks blocking other processes (we
# shouldn't), this gets rid of them.
$dbh->disconnect;
# Traverse the shortest path, perform the actions described by the
# edges.
my $curStep = 1;
@@ -294,8 +277,8 @@ sub downloadFile {
my $url = shift;
$ENV{"PRINT_PATH"} = 1;
$ENV{"QUIET"} = 1;
my ($hash, $path) = `$binDir/nix-prefetch-url '$url'`;
die "download of `$url' failed" unless $? == 0;
my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$url'`;
die "download of `$url' failed" . ($! ? ": $!" : "") . "\n" unless $? == 0;
chomp $path;
return $path;
}
@@ -307,36 +290,36 @@ while (scalar @path > 0) {
my $u = $edge->{start};
my $v = $edge->{end};
print "\n*** Step $curStep/$maxStep: ";
print STDERR "\n*** Step $curStep/$maxStep: ";
if ($edge->{type} eq "present") {
print "using already present path `$v'\n";
print STDERR "using already present path `$v'\n";
print LOGFILE "$$ present $v\n";
if ($curStep < $maxStep) {
# Since this is not the last step, the path will be used
# 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
print STDERR " packing base path...\n";
system("$Nix::Config::binDir/nix-store --dump $v > $tmpNar") == 0
or die "cannot dump `$v'";
}
}
elsif ($edge->{type} eq "patch") {
my $patch = $edge->{info};
print "applying patch `$patch->{url}' to `$u' to create `$v'\n";
print STDERR "applying patch `$patch->{url}' to `$u' to create `$v'\n";
print LOGFILE "$$ patch $patch->{url} $patch->{size} $patch->{baseHash} $u $v\n";
# Download the patch.
print " downloading patch...\n";
print STDERR " downloading patch...\n";
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).
print " applying patch...\n";
system("@libexecdir@/bspatch $tmpNar $tmpNar2 $patchPath") == 0
print STDERR " applying patch...\n";
system("$Nix::Config::libexecDir/bspatch $tmpNar $tmpNar2 $patchPath") == 0
or die "cannot apply patch `$patchPath' to $tmpNar";
if ($curStep < $maxStep) {
@@ -345,8 +328,8 @@ while (scalar @path > 0) {
} else {
# 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
print STDERR " unpacking patched archive...\n";
system("$Nix::Config::binDir/nix-store --restore $v < $tmpNar2") == 0
or die "cannot unpack $tmpNar2 into `$v'";
}
@@ -355,23 +338,23 @@ while (scalar @path > 0) {
elsif ($edge->{type} eq "narfile") {
my $narFile = $edge->{info};
print "downloading `$narFile->{url}' into `$v'\n";
print STDERR "downloading `$narFile->{url}' into `$v'\n";
my $size = $narFile->{size} || -1;
print LOGFILE "$$ narfile $narFile->{url} $size $v\n";
# Download the archive.
print " downloading archive...\n";
print STDERR " downloading archive...\n";
my $narFilePath = downloadFile "$narFile->{url}";
if ($curStep < $maxStep) {
# The archive will be used a base to a patch.
system("@bunzip2@ < '$narFilePath' > $tmpNar") == 0
system("$Nix::Config::bzip2 -d < '$narFilePath' > $tmpNar") == 0
or die "cannot unpack `$narFilePath' into `$v'";
} else {
# Unpack the archive into the target path.
print " unpacking archive...\n";
system("@bunzip2@ < '$narFilePath' | $binDir/nix-store --restore '$v'") == 0
print STDERR " unpacking archive...\n";
system("$Nix::Config::bzip2 -d < '$narFilePath' | $Nix::Config::binDir/nix-store --restore '$v'") == 0
or die "cannot unpack `$narFilePath' into `$v'";
}
@@ -390,20 +373,15 @@ if (defined $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 = hashPath($hashAlgo, $hashAlgo eq "sha256" && length($hash) != 64, $targetPath);
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"
die "hash mismatch in downloaded path $targetPath; expected $hash, got $hash2\n"
if $hash ne $hash2;
} else {
die "cannot check integrity of the downloaded path since its hash is not known";
die "cannot check integrity of the downloaded path since its hash is not known\n";
}
print STDERR "\n";
print LOGFILE "$$ success\n";
close LOGFILE;

0
scripts/find-runtime-roots.pl.in Normal file → Executable file
View File

View File

@@ -1,2 +0,0 @@
./gc-releases.pl /data/webserver/dist/*/*/MANIFEST > dead
cat dead | xargs mv --target-directory=/data/webserver/trash/

View File

@@ -1,55 +0,0 @@
#! /usr/bin/perl -w -I. -I..
use strict;
use readmanifest;
use readcache;
# Read the manifests.
my %narFiles;
my %localPaths;
my %patches;
foreach my $manifest (@ARGV) {
print STDERR "loading $manifest\n";
if (readManifest($manifest, \%narFiles, \%localPaths, \%patches, 1) < 3) {
# die "manifest `$manifest' is too old (i.e., for Nix <= 0.7)\n";
}
}
# Find the live archives.
my %usedFiles;
foreach my $narFile (keys %narFiles) {
foreach my $file (@{$narFiles{$narFile}}) {
$file->{url} =~ /\/([^\/]+)$/;
my $basename = $1;
die unless defined $basename;
# print $basename, "\n";
$usedFiles{$basename} = 1;
print STDERR "missing archive `$basename'\n"
unless defined $readcache::archives{$basename};
}
}
foreach my $patch (keys %patches) {
foreach my $file (@{$patches{$patch}}) {
$file->{url} =~ /\/([^\/]+)$/;
my $basename = $1;
die unless defined $basename;
# print $basename, "\n";
$usedFiles{$basename} = 1;
die "missing archive `$basename'"
unless defined $readcache::archives{$basename};
}
}
# Print out the dead archives.
foreach my $archive (keys %readcache::archives) {
next if $archive eq "." || $archive eq "..";
if (!defined $usedFiles{$archive}) {
print $readcache::archives{$archive}, "\n";
}
}

View File

@@ -1,21 +0,0 @@
package readcache;
use strict;
# Read the archive directories.
our %archives;
sub readDir {
my $dir = shift;
opendir(DIR, "$dir") or die "cannot open `$dir': $!";
my @as = readdir DIR;
foreach my $archive (@as) {
$archives{$archive} = "$dir/$archive";
}
closedir DIR;
}
readDir "/data/webserver/dist/nix-cache";
readDir "/data/webserver/dist/test-cache";
readDir "/data/webserver/dist/patches";
print STDERR scalar (keys %archives), "\n";

View File

@@ -1,76 +0,0 @@
#! /usr/bin/perl -w -I. -I..
use strict;
use readmanifest;
use readcache;
my %allNarFiles;
my %allLocalPaths;
my %allPatches;
foreach my $manifest (glob "/data/webserver/dist/*/*/MANIFEST") {
print STDERR "loading $manifest\n";
readManifest($manifest, \%allNarFiles, \%allLocalPaths, \%allPatches, 1);
}
foreach my $manifest (@ARGV) {
print STDERR "shrinking manifest $manifest...\n";
my %narFiles;
my %patches;
if (readManifest($manifest, \%narFiles, \%patches, 1) < 3) {
print STDERR "manifest `$manifest' is too old (i.e., for Nix <= 0.7)\n";
next;
}
my %done;
sub traverse {
my $p = shift;
my $prefix = shift;
print "$prefix$p\n";
my $reachesNAR = 0;
foreach my $patch (@{$patches{$p}}) {
next if defined $done{$patch->{url}};
$done{$patch->{url}} = 1;
$reachesNAR = 1 if traverse ($patch->{basePath}, $prefix . " ");
}
$reachesNAR = 1 if defined $allNarFiles{$p};
print " $prefix$reachesNAR\n";
return $reachesNAR;
}
# foreach my $p (keys %narFiles) {
# traverse ($p, "");
# }
my %newPatches;
foreach my $p (keys %patches) {
my $patchList = $patches{$p};
my @newList;
foreach my $patch (@{$patchList}) {
if (! defined $allNarFiles{$patch->{basePath}} ||
! defined $allNarFiles{$p} )
{
# print "REMOVING PATCH ", $patch->{basePath}, " -> ", $p, "\n";
} else {
# print "KEEPING PATCH ", $patch->{basePath}, " -> ", $p, "\n";
push @newList, $patch;
}
}
$newPatches{$p} = \@newList;
}
writeManifest ($manifest, \%narFiles, \%newPatches);
}

103
scripts/nix-build.in Normal file → Executable file
View File

@@ -1,35 +1,32 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use strict;
use Nix::Config;
use Nix::Store;
use File::Temp qw(tempdir);
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
my $addDrvLink = 0;
my $addOutLink = 1;
my $outLink;
my $drvLink;
my $dryRun = 0;
my $verbose = 0;
my $runEnv = 0;
my @instArgs = ();
my @buildArgs = ();
my @exprs = ();
my $shell = $ENV{SHELL} || "/bin/sh";
my $envCommand = "p=\$PATH; source \$stdenv/setup; PATH=\$PATH:\$p; exec $shell";
my @envExclude = ();
END {
foreach my $fn (glob ".nix-build-tmp-*") {
unlink $fn;
}
}
sub intHandler {
exit 1;
}
my $tmpDir = tempdir("nix-build.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
$SIG{'INT'} = 'intHandler';
my $outLink = "./result";
my $drvLink = "$tmpDir/derivation";
# Ensure that the $tmpDir is deleted.
$SIG{'INT'} = sub { exit 1 };
for (my $n = 0; $n < scalar @ARGV; $n++) {
@@ -48,7 +45,12 @@ Flags:
--drv-link NAME: create symlink NAME instead of `derivation'
--no-out-link: do not create the `result' symlink
--out-link / -o NAME: create symlink NAME instead of `result'
--attr ATTR: select a specific attribution from the Nix expression
--attr / -A ATTR: select a specific attribute from the Nix expression
--run-env: build dependencies of the specified derivation, then start a
shell with the environment of the derivation
--command: command to run with `--run-env'
--exclude: regexp specifying dependencies to be excluded by `--run-env'
Any additional flags are passed to `nix-store'.
EOF
@@ -57,11 +59,11 @@ EOF
}
elsif ($arg eq "--add-drv-link") {
$addDrvLink = 1;
$drvLink = "./derivation";
}
elsif ($arg eq "--no-out-link" or $arg eq "--no-link") {
$addOutLink = 0;
$outLink = "$tmpDir/result";
}
elsif ($arg eq "--drv-link") {
@@ -76,10 +78,10 @@ EOF
$outLink = $ARGV[$n];
}
elsif ($arg eq "--attr" or $arg eq "-A") {
elsif ($arg eq "--attr" or $arg eq "-A" or $arg eq "-I") {
$n++;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
push @instArgs, ("--attr", $ARGV[$n]);
push @instArgs, ($arg, $ARGV[$n]);
}
elsif ($arg eq "--arg" || $arg eq "--argstr") {
@@ -128,6 +130,22 @@ EOF
push @instArgs, $arg;
}
elsif ($arg eq "--run-env") {
$runEnv = 1;
}
elsif ($arg eq "--command") {
$n++;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
$envCommand = $ARGV[$n];
}
elsif ($arg eq "--exclude") {
$n++;
die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV;
push @envExclude, $ARGV[$n];
}
elsif (substr($arg, 0, 1) eq "-") {
push @buildArgs, $arg;
}
@@ -140,29 +158,42 @@ EOF
@exprs = ("./default.nix") if scalar @exprs == 0;
if (!defined $drvLink) {
$drvLink = "derivation";
$drvLink = ".nix-build-tmp-" . $drvLink if !$addDrvLink;
}
if (!defined $outLink) {
$outLink = "result";
$outLink = ".nix-build-tmp-" . $outLink if !$addOutLink;
}
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 "$Nix::Config::binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
while (<DRVPATHS>) {chomp; push @drvPaths, $_;}
if (!close DRVPATHS) {
die "nix-instantiate killed by signal " . ($? & 127) . "\n" if ($? & 127);
exit 1;
}
if ($runEnv) {
die "$0: --run-env requires a single derivation\n" if scalar @drvPaths != 1;
my $drvPath = readlink $drvPaths[0] or die "cannot read symlink `$drvPaths[0]'";
my $drv = derivationFromPath($drvPath);
# Build or fetch all dependencies of the derivation.
my @inputDrvs = grep { my $x = $_; (grep { $x =~ $_ } @envExclude) == 0 } @{$drv->{inputDrvs}};
system("$Nix::Config::binDir/nix-store -r @buildArgs @inputDrvs @{$drv->{inputSrcs}} > /dev/null") == 0
or die "$0: failed to build all dependencies\n";
# Set the environment.
$ENV{'NIX_BUILD_TOP'} = $ENV{'TMPDIR'} || "/tmp";
foreach (keys %{$drv->{env}}) {
$ENV{$_} = $drv->{env}->{$_};
}
# Run a shell using the derivation's environment. For
# convenience, source $stdenv/setup to setup additional
# environment variables. Also don't lose the current $PATH
# directories.
exec($ENV{SHELL}, "-c", $envCommand);
die;
}
foreach my $drvPath (@drvPaths) {
my $target = readlink $drvPath or die "cannot read symlink `$drvPath'";
print STDERR "derivation is $target\n" if $verbose;
@@ -170,7 +201,7 @@ foreach my $expr (@exprs) {
# Build.
my @outPaths;
$pid = open(OUTPATHS, "-|") || exec "$binDir/nix-store", "--add-root", $outLink, "--indirect", "-r",
$pid = open(OUTPATHS, "-|") || exec "$Nix::Config::binDir/nix-store", "--add-root", $outLink, "--indirect", "-r",
@buildArgs, @drvPaths;
while (<OUTPATHS>) {chomp; push @outPaths, $_;}
if (!close OUTPATHS) {

176
scripts/nix-channel.in Normal file → Executable file
View File

@@ -1,155 +1,151 @@
#! @perl@ -w
#! @perl@ -w @perlFlags@
use strict;
use File::Basename;
use File::Path qw(mkpath);
use Nix::Config;
my $rootsDir = "@localstatedir@/nix/gcroots";
my $stateDir = $ENV{"NIX_STATE_DIR"};
$stateDir = "@localstatedir@/nix" unless defined $stateDir;
my $manifestDir = $Nix::Config::manifestDir;
# Turn on caching in nix-prefetch-url.
my $channelCache = "$stateDir/channel-cache";
my $channelCache = "$Nix::Config::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 $home = $ENV{"HOME"} or die '$HOME not set\n';
my $channelsList = "$home/.nix-channels";
my $nixDefExpr = "$home/.nix-defexpr";
# Figure out the name of the channels profile.
my $userName = getpwuid($<) or die "cannot figure out user name";
my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels";
mkpath(dirname $profile, 0, 0755);
my @channels;
my %channels;
# Reads the list of channels from the file $channelsList;
# Reads the list of channels.
sub readChannels {
return if (!-f $channelsList);
open CHANNELS, "<$channelsList" or die "cannot open `$channelsList': $!";
while (<CHANNELS>) {
chomp;
next if /^\s*\#/;
push @channels, $_;
my ($url, $name) = split ' ', $_;
$url =~ s/\/*$//; # remove trailing slashes
$name = basename $url unless defined $name;
$channels{$name} = $url;
}
close CHANNELS;
}
# Writes the list of channels to the file $channelsList;
# Writes the list of channels.
sub writeChannels {
open CHANNELS, ">$channelsList" or die "cannot open `$channelsList': $!";
foreach my $url (@channels) {
print CHANNELS "$url\n";
foreach my $name (keys %channels) {
print CHANNELS "$channels{$name} $name\n";
}
close CHANNELS;
}
# Adds a channel to the file $channelsList;
# Adds a channel.
sub addChannel {
my $url = shift;
my ($url, $name) = @_;
readChannels;
foreach my $url2 (@channels) {
return if $url eq $url2;
}
push @channels, $url;
$channels{$name} = $url;
writeChannels;
}
# Remove a channel from the file $channelsList;
# Remove a channel.
sub removeChannel {
my $url = shift;
my @left = ();
my ($name) = @_;
readChannels;
foreach my $url2 (@channels) {
push @left, $url2 if $url ne $url2;
}
@channels = @left;
delete $channels{$name};
writeChannels;
system("$Nix::Config::binDir/nix-env --profile '$profile' -e '$name'") == 0
or die "cannot remove channel `$name'";
}
# Fetch Nix expressions and pull cache manifests from the subscribed
# Fetch Nix expressions and pull manifests from the subscribed
# channels.
sub update {
my @channelNames = @_;
readChannels;
# Create the manifests directory if it doesn't exist.
mkdir "$stateDir/manifests", 0755 unless -e "$stateDir/manifests";
mkdir $manifestDir, 0755 unless -e $manifestDir;
# 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") {
# Do we have write permission to the manifests directory?
die "$0: you do not have write permission to `$manifestDir'!\n" unless -W $manifestDir;
# 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'";
}
# Download each channel.
my $exprs = "";
foreach my $name (keys %channels) {
next if scalar @channelNames > 0 && ! grep { $_ eq $name } @{channelNames};
my $url = $channels{$name};
my $origUrl = "$url/MANIFEST";
}
# Create a Nix expression that fetches and unpacks the channel Nix
# expressions.
my $inputs = "[";
foreach my $url (@channels) {
$url =~ /\/([^\/]+)\/?$/;
my $channelName = $1;
$channelName = "unnamed" unless defined $channelName;
# Check if $url is a redirect. If so, follow it now to ensure
# consistency if the redirection is changed between
# downloading the manifest and the tarball.
my $headers = `$Nix::Config::curl --silent --head '$url'`;
die "$0: unable to check `$url'\n" if $? != 0;
$headers =~ s/\r//g;
$url = $1 if $headers =~ /^Location:\s*(.*)\s*$/m;
# Pull the channel manifest.
$ENV{'NIX_ORIG_URL'} = $origUrl;
system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
or die "cannot pull manifest from `$url'\n";
# Download the channel tarball.
my $fullURL = "$url/nixexprs.tar.bz2";
print "downloading Nix expressions from `$fullURL'...\n";
$ENV{"PRINT_PATH"} = 1;
$ENV{"QUIET"} = 1;
my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL'`;
print STDERR "downloading Nix expressions from `$fullURL'...\n";
my ($hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`;
die "cannot fetch `$fullURL'" if $? != 0;
chomp $path;
$inputs .= '"' . $channelName . '"' . " " . $path . " ";
# If the URL contains a version number, append it to the name
# attribute (so that "nix-env -q" on the channels profile
# shows something useful).
my $cname = $name;
$cname .= $1 if basename($url) =~ /(-\d.*)$/;
$exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }' ";
}
$inputs .= "]";
# Figure out a name for the GC root.
my $userName = getpwuid($<);
die "who ARE you? go away" unless defined $userName;
my $rootFile = "$rootsDir/per-user/$userName/channels";
# 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";
# Unpack the channel tarballs into the Nix store and install them
# into the channels profile.
print STDERR "unpacking channels...\n";
system("$Nix::Config::binDir/nix-env --profile '$profile' " .
"-f '<nix/unpack-channel.nix>' -i -E $exprs --quiet") == 0
or die "cannot unpack the channels";
# 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'";
symlink($profile, $channelLink) or die "cannot symlink `$channelLink' to `$profile'";
}
sub usageError {
print STDERR <<EOF;
Usage:
nix-channel --add URL
nix-channel --remove URL
nix-channel --add URL [CHANNEL-NAME]
nix-channel --remove CHANNEL-NAME
nix-channel --list
nix-channel --update
nix-channel --update [CHANNEL-NAME...]
EOF
exit 1;
}
@@ -162,29 +158,35 @@ while (scalar @ARGV) {
my $arg = shift @ARGV;
if ($arg eq "--add") {
usageError if scalar @ARGV != 1;
addChannel (shift @ARGV);
usageError if scalar @ARGV < 1 || scalar @ARGV > 2;
my $url = shift @ARGV;
my $name = shift @ARGV;
unless (defined $name) {
$name = basename $url;
$name =~ s/-unstable//;
$name =~ s/-stable//;
}
addChannel($url, $name);
last;
}
if ($arg eq "--remove") {
usageError if scalar @ARGV != 1;
removeChannel (shift @ARGV);
removeChannel(shift @ARGV);
last;
}
if ($arg eq "--list") {
usageError if scalar @ARGV != 0;
readChannels;
foreach my $url (@channels) {
print "$url\n";
foreach my $name (keys %channels) {
print "$name $channels{$name}\n";
}
last;
}
elsif ($arg eq "--update") {
usageError if scalar @ARGV != 0;
update;
update(@ARGV);
last;
}

9
scripts/nix-collect-garbage.in Normal file → Executable file
View File

@@ -1,11 +1,10 @@
#! @perl@ -w
#! @perl@ -w @perlFlags@
use strict;
use Nix::Config;
my $profilesDir = "@localstatedir@/nix/profiles";
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
# Process the command line arguments.
my @args = ();
@@ -36,7 +35,7 @@ sub removeOldGenerations {
$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("$Nix::Config::binDir/nix-env", "-p", $name, "--delete-generations", "old");
}
elsif (! -l $name && -d $name) {
removeOldGenerations $name;
@@ -50,4 +49,4 @@ removeOldGenerations $profilesDir if $removeOld;
# Run the actual garbage collector.
exec "$binDir/nix-store", "--gc", @args;
exec "$Nix::Config::binDir/nix-store", "--gc", @args;

110
scripts/nix-copy-closure.in Normal file → Executable file
View File

@@ -1,13 +1,14 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use SSH;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
use Nix::SSH;
use Nix::Config;
use Nix::Store;
use Nix::CopyClosure;
if (scalar @ARGV < 1) {
print STDERR <<EOF
Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] PATHS...
Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] [--bzip2] [--xz] PATHS...
EOF
;
exit 1;
@@ -22,8 +23,14 @@ my $sign = 0;
my $compressor = "";
my $decompressor = "";
my $progressViewer = "";
my $toMode = 1;
my $includeOutputs = 0;
my $dryRun = 0;
# !!! Copied from nix-pack-closure, should put this in a module.
my @storePaths = ();
@@ -35,8 +42,16 @@ while (@ARGV) {
$sign = 1;
}
elsif ($arg eq "--gzip") {
$compressor = "| gzip";
$decompressor = "gunzip |";
$compressor = "gzip";
$decompressor = "gunzip";
}
elsif ($arg eq "--bzip2") {
$compressor = "bzip2";
$decompressor = "bunzip2";
}
elsif ($arg eq "--xz") {
$compressor = "xz";
$decompressor = "xz -d";
}
elsif ($arg eq "--from") {
$toMode = 0;
@@ -44,6 +59,15 @@ while (@ARGV) {
elsif ($arg eq "--to") {
$toMode = 1;
}
elsif ($arg eq "--include-outputs") {
$includeOutputs = 1;
}
elsif ($arg eq "--show-progress") {
$progressViewer = "@pv@";
}
elsif ($arg eq "--dry-run") {
$dryRun = 1;
}
elsif (!defined $sshHost) {
$sshHost = $arg;
}
@@ -57,81 +81,37 @@ openSSHConnection $sshHost or die "$0: unable to start SSH\n";
if ($toMode) { # Copy TO the remote machine.
my @allStorePaths;
# Get the closure of this path.
my $pid = open(READ, "set -f; $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, "set -f; ssh $sshHost @sshOpts nix-store --check-validity --print-invalid @allStorePaths|");
my @missing = ();
while (<READ>) {
chomp;
push @missing, $_;
}
close READ or die;
# Export the store paths and import them on the remote machine.
if (scalar @missing > 0) {
print STDERR "copying these missing paths:\n";
print STDERR " $_\n" foreach @missing;
my $extraOpts = "";
$extraOpts .= "--sign" if $sign == 1;
system("set -f; nix-store --export $extraOpts @missing $compressor | ssh $sshHost @sshOpts '$decompressor nix-store --import'") == 0
or die "copying store paths to remote machine `$sshHost' failed: $?";
}
Nix::CopyClosure::copyTo($sshHost, [ @sshOpts ], [ @storePaths ], $compressor, $decompressor, $includeOutputs, $dryRun, $sign, $progressViewer);
}
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 $extraOpts = $includeOutputs ? "--include-outputs" : "";
my $pid = open(READ,
"set -f; ssh @sshOpts $sshHost nix-store --query --requisites @storePaths|") or die;
"set -f; ssh @sshOpts $sshHost nix-store --query --requisites $extraOpts @storePaths|") or die;
my @allStorePaths;
while (<READ>) {
chomp;
die "bad: $_" unless /^\//;
push @allStorePaths, $_;
push @missing, $_ unless isValidPath($_);
}
close READ or die "nix-store on remote machine `$sshHost' failed: $?";
# What paths are already valid locally?
open(READ, "set -f; @bindir@/nix-store --check-validity --print-invalid @allStorePaths|");
my @missing = ();
while (<READ>) {
chomp;
push @missing, $_;
}
close READ or die;
# Export the store paths on the remote machine and import them on locally.
# Export the store paths on the remote machine and import them locally.
if (scalar @missing > 0) {
print STDERR "copying these missing paths:\n";
print STDERR " $_\n" foreach @missing;
my $extraOpts = "";
$extraOpts .= "--sign" if $sign == 1;
system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $decompressor @bindir@/nix-store --import") == 0
or die "copying store paths from remote machine `$sshHost' failed: $?";
print STDERR "copying ", scalar @missing, " missing paths from $sshHost...\n";
$compressor = "| $compressor" if $compressor ne "";
$decompressor = "$decompressor |" if $decompressor ne "";
$progressViewer = "$progressViewer |" if $progressViewer ne "";
unless ($dryRun) {
my $extraOpts = $sign ? "--sign" : "";
system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $progressViewer $decompressor $Nix::Config::binDir/nix-store --import > /dev/null") == 0
or die "copying store paths from remote machine `$sshHost' failed: $?";
}
}
}

20
scripts/nix-generate-patches.in Normal file → Executable file
View File

@@ -1,9 +1,9 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use strict;
use File::Temp qw(tempdir);
use NixManifest;
use GeneratePatches;
use Nix::Manifest;
use Nix::GeneratePatches;
if (scalar @ARGV != 5) {
print STDERR <<EOF;
@@ -26,10 +26,10 @@ my $srcManifest = $ARGV[3];
my $dstManifest = $ARGV[4];
my (%srcNarFiles, %srcLocalPaths, %srcPatches);
readManifest $srcManifest, \%srcNarFiles, \%srcLocalPaths, \%srcPatches;
readManifest $srcManifest, \%srcNarFiles, \%srcPatches;
my (%dstNarFiles, %dstLocalPaths, %dstPatches);
readManifest $dstManifest, \%dstNarFiles, \%dstLocalPaths, \%dstPatches;
readManifest $dstManifest, \%dstNarFiles, \%dstPatches;
my $tmpDir = tempdir("nix-generate-patches.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
@@ -39,4 +39,14 @@ generatePatches \%srcNarFiles, \%dstNarFiles, \%srcPatches, \%dstPatches,
propagatePatches \%srcPatches, \%dstNarFiles, \%dstPatches;
# Optionally add all new patches to the manifest in $NIX_ALL_PATCHES.
my $allPatchesFile = $ENV{"NIX_ALL_PATCHES"};
if (defined $allPatchesFile) {
my (%dummy, %allPatches);
readManifest("$patchesPath/all-patches", \%dummy, \%allPatches)
if -f $allPatchesFile;
copyPatches \%dstPatches, \%allPatches;
writeManifest($allPatchesFile, {}, \%allPatches, 0);
}
writeManifest $dstManifest, \%dstNarFiles, \%dstPatches;

16
scripts/nix-install-package.in Normal file → Executable file
View File

@@ -1,9 +1,8 @@
#! @perl@ -w
#! @perl@ -w @perlFlags@
use strict;
use File::Temp qw(tempdir);
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
use Nix::Config;
sub usageError {
@@ -61,7 +60,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", "$Nix::Config::binDir/nix-install-package", @ARGV);
}
die "cannot execute `xterm'";
}
@@ -124,17 +123,20 @@ if ($interactive) {
# Store the manifest in the temporary directory so that we don't
# pollute /nix/var/nix/manifests.
# pollute /nix/var/nix/manifests. This also requires that we don't
# use the Nix daemon (because otherwise download-using-manifests won't
# see our NIX_MANIFESTS_DIRS environment variable).
$ENV{NIX_MANIFESTS_DIR} = $tmpDir;
$ENV{NIX_REMOTE} = "";
print "\nPulling manifests...\n";
system("$binDir/nix-pull", $manifestURL) == 0
system("$Nix::Config::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("$Nix::Config::binDir/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
or barf "nix-env failed: $?";

226
scripts/nix-prefetch-url.in Normal file → Executable file
View File

@@ -1,162 +1,128 @@
#! @shell@ -e
#! @perl@ -w @perlFlags@
url=$1
expHash=$2
use strict;
use File::Basename;
use File::Temp qw(tempdir);
use File::stat;
use Nix::Store;
use Nix::Config;
# needed to make it work on NixOS
export PATH=$PATH:@coreutils@
my $url = shift;
my $expHash = shift;
my $hashType = $ENV{'NIX_HASH_ALGO'} || "sha256";
my $cacheDir = $ENV{'NIX_DOWNLOAD_CACHE'};
hashType=$NIX_HASH_ALGO
if test -z "$hashType"; then
hashType=sha256
fi
if (!defined $url || $url eq "") {
print STDERR <<EOF
Usage: nix-prefetch-url URL [EXPECTED-HASH]
EOF
;
exit 1;
}
hashFormat=
if test "$hashType" != "md5"; then
hashFormat=--base32
fi
sub writeFile {
my ($fn, $s) = @_;
open TMP, ">$fn" or die;
print TMP "$s" or die;
close TMP or die;
}
if test -z "$url"; then
echo "syntax: nix-prefetch-url URL [EXPECTED-HASH]" >&2
exit 1
fi
sub readFile {
local $/ = undef;
my ($fn) = @_;
open TMP, "<$fn" or die;
my $s = <TMP>;
close TMP or die;
return $s;
}
my $tmpDir = tempdir("nix-prefetch-url.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
# Hack to support the mirror:// scheme from Nixpkgs.
if ($url =~ /^mirror:\/\//) {
system("$Nix::Config::binDir/nix-build '<nixpkgs>' -A resolveMirrorURLs --argstr url '$url' -o $tmpDir/urls > /dev/null") == 0
or die "$0: nix-build failed; maybe \$NIX_PATH is not set properly\n";
my @expanded = split ' ', readFile("$tmpDir/urls");
die "$0: cannot resolve $url" unless scalar @expanded > 0;
print STDERR "$url expands to $expanded[0]\n";
$url = $expanded[0];
}
# Handle escaped characters in the URI. `+', `=' and `?' are the only
# characters that are valid in Nix store path names but have a special
# meaning in URIs.
name=$(basename "$url" | @sed@ -e 's/%2b/+/g' -e 's/%3d/=/g' -e 's/%3f/\?/g')
if test -z "$name"; then echo "invalid url"; exit 1; fi
my $name = basename $url;
die "cannot figure out file name for $url\n" if $name eq "";
$name =~ s/%2b/+/g;
$name =~ s/%3d/=/g;
$name =~ s/%3f/?/g;
my $finalPath;
my $hash;
# If the hash was given, a file with that hash may already be in the
# store.
if test -n "$expHash"; then
finalPath=$(@bindir@/nix-store --print-fixed-path "$hashType" "$expHash" "$name")
if ! @bindir@/nix-store --check-validity "$finalPath" 2> /dev/null; then
finalPath=
fi
hash=$expHash
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
if (defined $expHash) {
$finalPath = makeFixedOutputPath(0, $hashType, $expHash, $name);
if (isValidPath($finalPath)) { $hash = $expHash; } else { $finalPath = undef; }
}
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
mkTempDir
tmpFile=$tmpPath/$name
if (!defined $finalPath) {
my $tmpFile = "$tmpDir/$name";
# 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
my ($cachedTimestampFN, $cachedHashFN, @cacheFlags);
if (defined $cacheDir) {
my $urlHash = hashString("sha256", 1, $url);
writeFile "$cacheDir/$urlHash.url", $url;
$cachedHashFN = "$cacheDir/$urlHash.$hashType";
$cachedTimestampFN = "$cacheDir/$urlHash.stamp";
@cacheFlags = ("--time-cond", $cachedTimestampFN) if -f $cachedHashFN && -f $cachedTimestampFN;
}
# Perform the download.
doDownload
my @curlFlags = ("curl", $url, "-o", $tmpFile, "--fail", "--location", "--max-redirs", "20", "--disable-epsv", "--cookie-jar", "$tmpDir/cookies", "--remote-time", (split " ", ($ENV{NIX_CURL_FLAGS} || "")));
(system $Nix::Config::curl @curlFlags, @cacheFlags) == 0 or die "$0: download of $url failed\n";
if test -n "$NIX_DOWNLOAD_CACHE" -a ! -e $tmpFile; then
if (defined $cacheDir && ! -e $tmpFile) {
# 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
$hash = readFile $cachedHashFN or die;
$finalPath = makeFixedOutputPath(0, $hashType, $hash, $name);
unless (isValidPath $finalPath) {
print STDERR "cached contents of $url disappeared, redownloading...\n";
$finalPath = undef;
(system $Nix::Config::curl @curlFlags) == 0 or die "$0: download of $url failed\n";
}
}
if test -z "$finalPath"; then
# 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"; 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
if (!defined $finalPath) {
fi
fi
# Compute the hash.
$hash = hashFile($hashType, $hashType ne "md5", $tmpFile);
if (defined $cacheDir) {
writeFile $cachedHashFN, $hash;
my $st = stat($tmpFile) or die;
open STAMP, ">$cachedTimestampFN" or die; close STAMP;
utime($st->atime, $st->mtime, $cachedTimestampFN) or die;
}
# Add the downloaded file to the Nix store.
$finalPath = addToStore($tmpFile, 0, $hashType);
}
if ! test -n "$QUIET"; then echo "path is $finalPath" >&2; fi
die "$0: hash mismatch for $url\n" if defined $expHash && $expHash ne $hash;
}
echo $hash
if test -n "$PRINT_PATH"; then
echo $finalPath
fi
print STDERR "path is $finalPath\n" unless $ENV{'QUIET'};
print "$hash\n";
print "$finalPath\n" if $ENV{'PRINT_PATH'};

69
scripts/nix-pull.in Normal file → Executable file
View File

@@ -1,17 +1,14 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use strict;
use File::Temp qw(tempdir);
use NixManifest;
use Nix::Config;
use Nix::Manifest;
my $tmpDir = tempdir("nix-pull.XXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "cannot create a temporary directory";
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");
my $manifestDir = $Nix::Config::manifestDir;
# Prevent access problems in shared-stored installations.
@@ -24,18 +21,21 @@ if (! -e $manifestDir) {
}
# Process the URLs specified on the command line.
my %narFiles;
my %localPaths;
my %patches;
# Make sure that the manifests directory is scanned for GC roots.
my $gcRootsDir = "$Nix::Config::stateDir/gcroots";
my $manifestDirLink = "$gcRootsDir/manifests";
if (! -l $manifestDirLink) {
symlink($manifestDir, $manifestDirLink) or die "cannot create symlink `$manifestDirLink'";
}
my $skipWrongStore = 0;
# Process the URLs specified on the command line.
sub downloadFile {
my $url = shift;
$ENV{"PRINT_PATH"} = 1;
$ENV{"QUIET"} = 1;
my ($dummy, $path) = `$binDir/nix-prefetch-url '$url'`;
my ($dummy, $path) = `$Nix::Config::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;
@@ -49,53 +49,32 @@ sub processURL {
my $manifest;
my $origUrl = $ENV{'NIX_ORIG_URL'} || $url;
# First see if a bzipped manifest is available.
if (system("@curl@ --fail --silent --head '$url'.bz2 > /dev/null") == 0) {
if (system("$Nix::Config::curl --fail --silent --location --head '$url'.bz2 > /dev/null") == 0) {
print "fetching 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;
$manifest = downloadFile "$url.bz2";
}
# Otherwise, just get the uncompressed manifest.
else {
print "obtaining list of Nix archives at `$url'...\n";
print "fetching 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/") {
print STDERR "warning: manifest `$url' assumes a Nix store at a different location than $storeDir, skipping...\n";
exit 0;
}
}
}
my $baseName = "unnamed";
if ($url =~ /\/([^\/]+)\/[^\/]+$/) { # get the forelast component
$baseName = $1;
}
my $hash = `$binDir/nix-hash --flat '$manifest'`
my $hash = `$Nix::Config::binDir/nix-hash --flat '$manifest'`
or die "cannot hash `$manifest'";
chomp $hash;
my $urlFile = "$manifestDir/$baseName-$hash.url";
open URL, ">$urlFile" or die "cannot create `$urlFile'";
print URL "$url";
print URL $origUrl;
close URL;
my $finalPath = "$manifestDir/$baseName-$hash.nixmanifest";
@@ -112,7 +91,7 @@ sub processURL {
my $url2 = <URL>;
chomp $url2;
close URL;
next unless $url eq $url2;
next unless $origUrl eq $url2;
my $base = $urlFile2; $base =~ s/.url$//;
unlink "${base}.url";
unlink "${base}.nixmanifest";
@@ -122,12 +101,12 @@ sub processURL {
while (@ARGV) {
my $url = shift @ARGV;
if ($url eq "--skip-wrong-store") {
$skipWrongStore = 1;
# No-op, no longer supported.
} else {
processURL $url;
}
}
my $size = scalar (keys %narFiles) + scalar (keys %localPaths);
print "$size store paths in manifest\n";
# Update the cache.
updateManifestDB();

43
scripts/nix-push.in Normal file → Executable file
View File

@@ -1,8 +1,10 @@
#! @perl@ -w -I@libexecdir@/nix
#! @perl@ -w @perlFlags@
use strict;
use File::Temp qw(tempdir);
use NixManifest;
use File::stat;
use Nix::Config;
use Nix::Manifest;
my $hashAlgo = "sha256";
@@ -12,15 +14,10 @@ my $tmpDir = tempdir("nix-push.XXXXXX", CLEANUP => 1, TMPDIR => 1)
my $nixExpr = "$tmpDir/create-nars.nix";
my $manifest = "$tmpDir/MANIFEST";
my $curl = "@curl@ --fail --silent";
my $curl = "$Nix::Config::curl --fail --silent";
my $extraCurlFlags = ${ENV{'CURL_FLAGS'}};
$curl = "$curl $extraCurlFlags" if defined $extraCurlFlags;
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
my $dataDir = $ENV{"NIX_DATA_DIR"};
$dataDir = "@datadir@" unless defined $dataDir;
# Parse the command line.
my $localCopy;
@@ -80,7 +77,7 @@ foreach my $path (@ARGV) {
# Get all paths referenced by the normalisation of the given
# Nix expression.
my $pid = open(READ,
"$binDir/nix-store --query --requisites --force-realise " .
"$Nix::Config::binDir/nix-store --query --requisites --force-realise " .
"--include-outputs '$path'|") or die;
while (<READ>) {
@@ -105,8 +102,8 @@ foreach my $storePath (@storePaths) {
# Construct a Nix expression that creates a Nix archive.
my $nixexpr =
"((import $dataDir/nix/corepkgs/nar/nar.nix) " .
"{storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\";}) ";
"(import <nix/nar.nix> " .
"{ storePath = builtins.storePath \"$storePath\"; hashAlgo = \"$hashAlgo\"; }) ";
print NIX $nixexpr;
}
@@ -118,7 +115,7 @@ close NIX;
# Instantiate store derivations from the Nix expression.
my @storeExprs;
print STDERR "instantiating store derivations...\n";
my $pid = open(READ, "$binDir/nix-instantiate $nixExpr|")
my $pid = open(READ, "$Nix::Config::binDir/nix-instantiate $nixExpr|")
or die "cannot run nix-instantiate";
while (<READ>) {
chomp;
@@ -140,7 +137,7 @@ while (scalar @tmp > 0) {
my @tmp2 = @tmp[0..$n - 1];
@tmp = @tmp[$n..scalar @tmp - 1];
my $pid = open(READ, "$binDir/nix-store --realise @tmp2|")
my $pid = open(READ, "$Nix::Config::binDir/nix-store --realise @tmp2|")
or die "cannot run nix-store";
while (<READ>) {
chomp;
@@ -178,22 +175,32 @@ for (my $n = 0; $n < scalar @storePaths; $n++) {
(-f $narFile) or die "narfile for $storePath not found";
push @narArchives, $narFile;
my $narbz2Size = (stat $narFile)[7];
my $narbz2Size = stat($narFile)->size;
my $references = `$binDir/nix-store --query --references '$storePath'`;
my $references = `$Nix::Config::binDir/nix-store --query --references '$storePath'`;
die "cannot query references for `$storePath'" if $? != 0;
$references = join(" ", split(" ", $references));
my $deriver = `$binDir/nix-store --query --deriver '$storePath'`;
my $deriver = `$Nix::Config::binDir/nix-store --query --deriver '$storePath'`;
die "cannot query deriver for `$storePath'" if $? != 0;
chomp $deriver;
$deriver = "" if $deriver eq "unknown-deriver";
my $narHash = `$binDir/nix-store --query --hash '$storePath'`;
my $narHash = `$Nix::Config::binDir/nix-store --query --hash '$storePath'`;
die "cannot query hash for `$storePath'" if $? != 0;
chomp $narHash;
my $narSize = `$binDir/nix-store --query --size '$storePath'`;
# In some exceptional cases (such as VM tests that use the Nix
# store of the host), the database doesn't contain the hash. So
# compute it.
if ($narHash =~ /^sha256:0*$/) {
$narHash = `$Nix::Config::binDir/nix-hash --type sha256 --base32 '$storePath'`;
die "cannot hash `$storePath'" if $? != 0;
chomp $narHash;
$narHash = "sha256:$narHash";
}
my $narSize = `$Nix::Config::binDir/nix-store --query --size '$storePath'`;
die "cannot query size for `$storePath'" if $? != 0;
chomp $narSize;

0
scripts/nix-reduce-build.in Normal file → Executable file
View File

View File

@@ -6,10 +6,9 @@ use readmanifest;
for my $p (@ARGV) {
my %narFiles;
my %localPaths;
my %patches;
readManifest $p, \%narFiles, \%localPaths, \%patches;
readManifest $p, \%narFiles, \%patches;
%patches = ();

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