Compare commits

...
56 Commits
Author SHA1 Message Date
Eelco Dolstra 98193bb440 Remove RPM builds that don't evaluate 2012-07-18 16:50:56 -04:00
Eelco Dolstra b7fd2c2822 Use "#pragma once" to prevent repeated header file inclusion 2012-07-18 14:59:03 -04:00
Eelco Dolstra 58337e0e61 Set release date 2012-07-18 11:51:27 -04:00
Eelco Dolstra ccc52adfb2 Add function queryPathFromHashPart()
To implement binary caches efficiently, Hydra needs to be able to map
the hash part of a store path (e.g. "gbg...zr7") to the full store
path (e.g. "/nix/store/gbg...kzr7-subversion-1.7.5").  (The binary
cache mechanism uses hash parts as a key for looking up store paths to
ensure privacy.)  However, doing a search in the Nix store for
/nix/store/<hash>* is expensive since it requires reading the entire
directory.  queryPathFromHashPart() prevents this by doing a cheap
database lookup.
2012-07-17 18:55:39 -04:00
Eelco Dolstra 220818f758 queryPathInfo(): return hash in base-32 if desired
Cherry-picked from the no-manifests branch.
2012-07-17 16:55:45 -04:00
Eelco Dolstra 3a9fdf2747 Return an exit code of 100 for cached failed builds
Exit code 100 should be returned for all permanent failures.  This
includes cached failures.

Fixes #34.
2012-07-17 15:55:30 -04:00
Eelco Dolstra 1217204c81 Remove dead code 2012-07-17 14:07:52 -04:00
Eelco Dolstra 51d71ad3d7 Manual: Don't claim we support Cygwin 2012-07-17 11:49:47 -04:00
Eelco Dolstra 6c01fb4d68 Update Nix 1.1 release notes 2012-07-17 10:06:20 -04:00
Eelco Dolstra 53b24f3518 Allow disabling log compression 2012-07-17 09:40:12 -04:00
Eelco Dolstra a7a43adb79 builtins.storePath: resolve symlinks
Needed for Charon/Hydra interaction.
2012-07-12 18:25:01 -04:00
Eelco Dolstra eae802459d Pass --insecure to curl so that https works 2012-07-09 15:49:20 -04:00
Eelco Dolstra 2dd3117c27 Inline fetchurl.sh 2012-07-09 15:48:55 -04:00
Eelco Dolstra 51f9f9924b Add a test for the fetchurl function 2012-07-09 15:41:43 -04:00
Shea LevyandEelco Dolstra 035aa11403 Remove obsolete comment 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra a2865f6b3d corepkgs/fetchurl: Build locally and outside of the chroot 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra 53f52c2111 corepkgs/fetchurl: the 'system' argument can be optional 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra 543bf742c9 corepkgs: distribute fetchurl files 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra f863673a90 corepkgs/fetchurl: Call the shell directly instead of using the shebang 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra a994eb92a4 corepkgs/fetchurl.sh: Use config.nix's curl 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra 9d94a28bed The fetchurl builder is now fetchurl.sh 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra fd2630e1f7 Remove old fetchurl makefile 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra 6450f5699f Move fetchurl files out of their subdirectory 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra 40c01ec467 corepkgs/config.nix.in: We'll need curl 2012-07-09 15:29:49 -04:00
Shea LevyandEelco Dolstra c4df747267 Resurrect old corepkgs fetchurl 2012-07-09 15:29:49 -04:00
Eelco Dolstra 27f0c34390 Really fix RPM builds 2012-07-09 13:16:09 -04:00
Eelco Dolstra a560124cdf Fix RPM builds
http://hydra.nixos.org/build/2784908
2012-07-09 11:58:12 -04:00
Eelco Dolstra 087dee6e1b Get rid of nix.conf.example
No need to duplicate the nix.conf manpage.
2012-07-09 11:56:55 -04:00
Eelco Dolstra 5755a5c354 Install a nix.conf manpage 2012-07-09 11:33:38 -04:00
Eelco Dolstra 1aba0bf0fa nix-store -r: do substitutions in parallel
I.e. when multiple non-derivation arguments are passed to ‘nix-store
-r’ to be substituted, do them in parallel.
2012-06-27 16:58:15 -04:00
Eelco Dolstra 42f5a2fc29 Mount an empty /dev/shm tmpfs in the chroot
This ensures that whatever the builder writes in /dev/shm is
automatically cleaned up.
2012-06-27 09:52:27 -04:00
Eelco Dolstra 3ee208516f Check the return code of the clone() call 2012-06-27 09:52:06 -04:00
Eelco Dolstra 1db38ae81b When using chroots, use a private PID namespace
In a private PID namespace, processes have PIDs that are separate from
the rest of the system.  The initial child gets PID 1.  Processes in
the chroot cannot see processes outside of the chroot.  This improves
isolation between builds.  However, processes on the outside can see
processes in the chroot and send signals to them (if they have
appropriate rights).

Since the builder gets PID 1, it serves as the reaper for zombies in
the chroot.  This might turn out to be a problem.  In that case we'll
need to have a small PID 1 process that sits in a loop calling wait().
2012-06-25 15:45:16 -04:00
Eelco Dolstra 5489086456 Use a private UTS namespace to provide a deterministic host/domain name to builders
In chroot builds, set the host name to "localhost" and the domain name
to "(none)" (the latter being the kernel's default).  This improves
determinism a bit further.

P.S. I have to idea what UTS stands for.
2012-06-25 14:12:17 -04:00
Eelco Dolstra 8da6772ed4 Update release notes 2012-06-23 14:59:13 -04:00
Eelco Dolstra 723a68c826 Improve error message 2012-06-23 00:57:14 -04:00
Eelco Dolstra 7ffa523fd1 In chroot builds, use a private SysV IPC namespace
This improves isolation a bit further, and it's just one extra flag in
the unshare() call.

P.S. It would be very cool to use CLONE_NEWPID (to put the builder in
a private PID namespace) as well, but that's slightly more risky since
having a builder start as PID 1 may cause problems.
2012-06-23 00:51:40 -04:00
Eelco Dolstra df716c98d2 In chroot builds, use a private network namespace
On Linux it's possible to run a process in its own network namespace,
meaning that it gets its own set of network interfaces, disjunct from
the rest of the system.  We use this to completely remove network
access to chroot builds, except that they get a private loopback
interface.  This means that:

- Builders cannot connect to the outside network or to other processes
  on the same machine, except processes within the same build.

- Vice versa, other processes cannot connect to processes in a chroot
  build, and open ports/connections do not show up in "netstat".

- If two concurrent builders try to listen on the same port (e.g. as
  part of a test), they no longer conflict with each other.

This was inspired by the "PrivateNetwork" flag in systemd.
2012-06-23 00:28:35 -04:00
Eelco Dolstra 2f3f413e91 Support socket-based, on-demand activation of the Nix daemon with systemd
Systemd can start the Nix daemon on demand when the Nix daemon socket
is first accessed.  This is signalled through the LISTEN_FDS
environment variable, so all we need to do is check for that and then
use file descriptor 3 as the listen socket instead of creating one
ourselves.
2012-06-18 23:01:46 -04:00
Eelco Dolstra 02fb6323e0 Add Emacs to the disk image 2012-05-31 09:50:58 -04:00
Michel Alexandre SalimandEelco Dolstra 221626e715 fixes to nix-worker systemd service descriptor: - remove commented-out lines - register the file for distribution in Makefile.am 2012-05-31 08:59:36 -04:00
Michel Alexandre SalimandEelco Dolstra a7ed1f67ee On systems with SystemD, install the service descriptor for nix-worker, and enable and start it 2012-05-31 08:59:36 -04:00
Michel Alexandre SalimandEelco Dolstra 8922346305 Major spec update: - Fix license field - Split into subpackages - Update build dependencies - Configure users and groups for multi-user mode - Fix installation location of Perl modules 2012-05-31 08:59:36 -04:00
Michel Alexandre SalimandEelco Dolstra 6a214f3e06 Update nix profile: - incorporate NixOS's configuration so that nix is usable by normal users - install as a data file, not a program file 2012-05-31 08:59:36 -04:00
Michel Alexandre SalimandEelco Dolstra d0308073c3 - only enable deprecated spec sections when building on systems with older RPM versions - move tests to dedicated %check section - use standard build macros 2012-05-31 08:59:36 -04:00
Michel Alexandre SalimandEelco Dolstra e545a7f9a8 - replace %define with %global 2012-05-31 08:59:36 -04:00
Eelco Dolstra f5398d374b Compress build logs on the fly using bzip2 2012-05-30 10:12:29 -04:00
Eelco Dolstra 881beb170d "nix-store -l": support compressed logs 2012-05-30 00:00:02 -04:00
Eelco Dolstra 4bc4da331a Reserve some disk space for the garbage collector
We can't open a SQLite database if the disk is full.  Since this
prevents the garbage collector from running when it's most needed, we
reserve some dummy space that we can free just before doing a garbage
collection.  This actually revives some old code from the Berkeley DB
days.

Fixes #27.
2012-05-29 22:59:12 -04:00
Eelco Dolstra 2c26985835 Add option ‘build-keep-log’ to enable/disable writing of build logs
Fixes #26.
2012-05-29 16:42:05 -04:00
Eelco Dolstra 8058dab26e Clean up the installation section; document the generic binary tarballs 2012-05-24 12:04:07 -04:00
Eelco Dolstra 0301525e6c Fix owner/group in tar invocation 2012-05-22 19:40:40 -04:00
Eelco Dolstra 6814b1dfa1 Generate binary tarballs for installing Nix
For several platforms we don't currently have "native" Nix packages
(e.g. Mac OS X and FreeBSD).  This provides the next best thing: a
tarball containing the closure of Nix, plus a simple script
"nix-finish-install" that initialises the Nix database, registers the
paths in the closure as valid, and runs "nix-env -i /path/to/nix" to
initialise the user profile.

The tarball must be unpacked in the root directory.  It creates
/nix/store/... and /usr/bin/nix-finish-install.  Typical installation
is as follows:

  $ cd /
  $ tar xvf /path/to/nix-1.1pre1234_abcdef-x86_64-linux.tar.bz2
  $ nix-finish-install
  (if necessary add ~/.nix-profile/etc/profile.d/nix.sh to the shell
  login scripts)

After this, /usr/bin/nix-finish-install can be deleted, if desired.

The downside to the binary tarball is that it's pretty big (~55 MiB
for x86_64-linux).
2012-05-22 18:36:54 -04:00
Eelco Dolstra 591aab7e21 Remove $FONTCONFIG_FILE hack from nix-profile.sh
It's no longer needed because Nixpkgs' fontconfig uses
/etc/fonts/fonts.conf as a default, just like other distributions.
2012-05-22 14:00:08 -04:00
Eelco Dolstra e071f87dc5 Add an experimental nix-make file
To use it, just do (e.g.) "nix-build build.nix -A nix_env".
2012-05-21 09:43:01 -04:00
Eelco Dolstra cac9eb39fe Bump version number 2012-05-12 00:07:08 -04:00
69 changed files with 1351 additions and 781 deletions
-4
View File
@@ -78,13 +78,9 @@ Makefile.in
/src/libexpr/parser-tab.cc
/src/libexpr/parser-tab.hh
/src/libexpr/parser-tab.output
/src/libexpr/nixexpr-ast.hh
/src/libexpr/nixexpr-ast.cc
/src/libexpr/nix.tbl
# /src/libstore/
/src/libstore/derivations-ast.cc
/src/libstore/derivations-ast.hh
/src/libstore/schema.sql.hh
# /src/nix-env/
+1 -5
View File
@@ -1,6 +1,6 @@
SUBDIRS = src perl scripts corepkgs doc misc tests
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
nix.conf.example NEWS version
NEWS version misc/systemd/nix-worker.service
pkginclude_HEADERS = config.h
@@ -10,10 +10,6 @@ nix.spec: nix.spec.in
install-data-local: init-state
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix
$(INSTALL_DATA) $(srcdir)/nix.conf.example $(DESTDIR)$(sysconfdir)/nix
if ! test -e $(DESTDIR)$(sysconfdir)/nix/nix.conf; then \
$(INSTALL_DATA) $(srcdir)/nix.conf.example $(DESTDIR)$(sysconfdir)/nix/nix.conf; \
fi
$(INSTALL) -d $(DESTDIR)$(docdir)
$(INSTALL_DATA) README $(DESTDIR)$(docdir)/
+169
View File
@@ -0,0 +1,169 @@
with import <nix-make/lib>;
with pkgs;
rec {
bin2c = link {
objects = [ (compileC { main = ./src/bin2c/bin2c.c; }) ];
programName = "bin2c";
};
bsdiff = link {
objects = [ (compileC { main = ./src/bsdiff-4.3/bsdiff.c; buildInputs = [ pkgs.bzip2 ]; }) ];
programName = "bsdiff";
buildInputs = [ pkgs.bzip2 ];
flags = "-lbz2";
};
bspatch = link {
objects = [ (compileC { main = ./src/bsdiff-4.3/bspatch.c; buildInputs = [ pkgs.bzip2 ]; }) ];
programName = "bspatch";
buildInputs = [ pkgs.bzip2 ];
flags = "-lbz2";
};
libformat = makeLibrary {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src ];
})
[ ./src/boost/format/format_implementation.cc
./src/boost/format/free_funcs.cc
./src/boost/format/parsing.cc
];
libraryName = "format";
};
libutil = makeLibrary {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/libutil ./src ./. ];
buildInputs = [ pkgs.openssl ];
})
[ ./src/libutil/util.cc
./src/libutil/hash.cc
./src/libutil/serialise.cc
./src/libutil/archive.cc
./src/libutil/xml-writer.cc
./src/libutil/immutable.cc
];
libraryName = "util";
};
libstore = makeLibrary {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/libstore ./src/libutil ./src ./. ];
buildInputs = [ pkgs.sqlite ];
cFlags = "-DNIX_STORE_DIR=\"/nix/store\" -DNIX_DATA_DIR=\"/home/eelco/Dev/nix/inst/share\" -DNIX_STATE_DIR=\"/nix/var/nix\" -DNIX_LOG_DIR=\"/foo\" -DNIX_CONF_DIR=\"/foo\" -DNIX_LIBEXEC_DIR=\"/foo\" -DNIX_BIN_DIR=\"/home/eelco/Dev/nix/inst/bin\"";
})
[ ./src/libstore/store-api.cc
./src/libstore/local-store.cc
./src/libstore/remote-store.cc
./src/libstore/derivations.cc
./src/libstore/build.cc
./src/libstore/misc.cc
./src/libstore/globals.cc
./src/libstore/references.cc
./src/libstore/pathlocks.cc
./src/libstore/gc.cc
./src/libstore/optimise-store.cc
];
libraryName = "store";
};
libmain = makeLibrary {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/libmain ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/libmain/shared.cc ];
libraryName = "main";
};
nix_hash = link {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/nix-hash ./src/libmain ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/nix-hash/nix-hash.cc
];
libraries = [ libformat libutil libstore libmain ];
buildInputs = [ pkgs.openssl pkgs.sqlite ];
flags = "-lssl -lsqlite3 -lstdc++";
programName = "nix-hash";
};
nix_store = link {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/nix-store ./src/libmain ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/nix-store/nix-store.cc
./src/nix-store/dotgraph.cc
./src/nix-store/xmlgraph.cc
];
libraries = [ libformat libutil libstore libmain ];
buildInputs = [ pkgs.openssl pkgs.sqlite ];
flags = "-lssl -lsqlite3 -lstdc++";
programName = "nix-store";
};
libexpr = makeLibrary {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/libexpr ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/libexpr/nixexpr.cc
./src/libexpr/eval.cc
./src/libexpr/primops.cc
./src/libexpr/lexer-tab.cc
./src/libexpr/parser-tab.cc
./src/libexpr/get-drvs.cc
./src/libexpr/attr-path.cc
./src/libexpr/value-to-xml.cc
./src/libexpr/common-opts.cc
./src/libexpr/names.cc
];
libraryName = "expr";
};
nix_instantiate = link {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/nix-instantiate ./src/libexpr ./src/libmain ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/nix-instantiate/nix-instantiate.cc ];
libraries = [ libformat libutil libstore libmain libexpr ];
buildInputs = [ pkgs.openssl pkgs.sqlite ];
flags = "-lssl -lsqlite3 -lstdc++";
programName = "nix-instantiate";
};
nix_env = link {
objects =
map (fn: compileC {
main = fn;
localIncludePath = [ ./src/nix-env ./src/libexpr ./src/libmain ./src/libstore ./src/libutil ./src ./. ];
})
[ ./src/nix-env/nix-env.cc
./src/nix-env/profiles.cc
./src/nix-env/user-env.cc
];
libraries = [ libformat libutil libstore libmain libexpr ];
buildInputs = [ pkgs.openssl pkgs.sqlite ];
flags = "-lssl -lsqlite3 -lstdc++";
programName = "nix-env";
};
all = [ bsdiff bspatch nix_hash nix_store nix_instantiate nix_env ];
}
+1 -1
View File
@@ -1,6 +1,6 @@
all-local: config.nix
files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh derivation.nix
files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh derivation.nix fetchurl.nix
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
+1
View File
@@ -9,5 +9,6 @@ in {
bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
tar = "@tar@";
tr = "@tr@";
curl = "@curl@";
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
}
+36
View File
@@ -0,0 +1,36 @@
with import <nix/config.nix>;
{system ? builtins.currentSystem, url, outputHash ? "", outputHashAlgo ? "", md5 ? "", sha1 ? "", sha256 ? ""}:
assert (outputHash != "" && outputHashAlgo != "")
|| md5 != "" || sha1 != "" || sha256 != "";
let
builder = builtins.toFile "fetchurl.sh"
''
echo "downloading $url into $out"
${curl} --fail --location --max-redirs 20 --insecure "$url" > "$out"
'';
in
derivation {
name = baseNameOf (toString url);
builder = shell;
args = [ "-e" builder ];
# New-style output content requirements.
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
if sha256 != "" then "sha256" else if sha1 != "" then "sha1" else "md5";
outputHash = if outputHash != "" then outputHash else
if sha256 != "" then sha256 else if sha1 != "" then sha1 else md5;
inherit system url;
# No need to double the amount of network traffic
preferLocalBuild = true;
# Don't build in a chroot because Nix's dependencies may not be there.
__noChroot = true;
}
+2
View File
@@ -21,6 +21,8 @@ man1_MANS = nix-env.1 nix-build.1 nix-store.1 nix-instantiate.1 \
nix-prefetch-url.1 nix-channel.1 \
nix-install-package.1 nix-hash.1 nix-copy-closure.1
man5_MANS = nix.conf.5
man8_MANS = nix-worker.8
FIGURES = figures/user-environments.png
+43 -11
View File
@@ -1,27 +1,36 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-conf-file">
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-conf-file">
<title>Nix configuration file</title>
<refmeta>
<refentrytitle>nix.conf</refentrytitle>
<manvolnum>5</manvolnum>
<refmiscinfo class="source">Nix</refmiscinfo>
<refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo>
</refmeta>
<refnamediv>
<refname>nix.conf</refname>
<refpurpose>Nix configuration file</refpurpose>
</refnamediv>
<refsection><title>Description</title>
<para>A number of persistent settings of Nix are stored in the file
<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
configuration file is shown in <xref linkend="ex-nix-conf" />.</para>
<example xml:id='ex-nix-conf'><title>Nix configuration file</title>
Comments start with a <literal>#</literal> character. Here is an example
configuration file:</para>
<programlisting>
gc-keep-outputs = true # Nice for developers
gc-keep-derivations = true # Idem
env-keep-derivations = false
</programlisting>
</example>
<para>The following variables are currently available:
<para>The following settings are currently available:
<variablelist>
@@ -276,6 +285,28 @@ build-use-chroot = /dev /proc /bin</programlisting>
</varlistentry>
<varlistentry><term><literal>build-keep-log</literal></term>
<listitem><para>If set to <literal>true</literal> (the default),
Nix will write the build log of a derivation (i.e. the standard
output and error of its builder) to the directory
<filename>/nix/var/log/nix/drvs</filename>. The build log can be
retrieved using the command <command>nix-store -l
<replaceable>path</replaceable></command>.</para></listitem>
</varlistentry>
<varlistentry><term><literal>build-compress-log</literal></term>
<listitem><para>If set to <literal>true</literal> (the default),
build logs written to <filename>/nix/var/log/nix/drvs</filename>
will be compressed on the fly using bzip2. Otherwise, they will
not be compressed.</para></listitem>
</varlistentry>
<varlistentry><term><literal>system</literal></term>
<listitem><para>This option specifies the canonical Nix system
@@ -311,5 +342,6 @@ build-use-chroot = /dev /proc /bin</programlisting>
</para>
</refsection>
</section>
</refentry>
+148 -96
View File
@@ -40,11 +40,155 @@ platforms as well.</para>
</section>
<section><title>Obtaining Nix</title>
<section><title>Installing a binary distribution</title>
<para>The easiest way to obtain Nix is to download a <link
xlink:href="http://nixos.org/">source distribution</link>. RPMs
for Red Hat, SuSE, and Fedora Core are also available.</para>
<para>The easiest way to install Nix is to use a binary package.
Binary packages of the latest stable release are available for Fedora,
Debian, Ubuntu, Mac OS X and various other systems from the <link
xlink:href="http://nixos.org/nix/download.html">Nix homepage</link>.
You can also get builds of the latest development release from our
<link
xlink:href="http://hydra.nixos.org/view/nix/trunk/latest">continuous
build system</link>.</para>
<para>For Fedora, RPM packages are available. These can be installed
or upgraded using <command>rpm -U</command>. For example,
<screen>
$ rpm -U nix-1.0-1.i386.rpm</screen>
</para>
<para>For Debian and Ubuntu, you can download a Deb package and
install it like this:
<screen>
$ dpkg -i nix_1.0-1_amd64.deb</screen>
</para>
<para>For other platforms, including Mac OS X (Darwin), FreeBSD and
other Linux distributions, you can download a binary tarball. It
contains Nix and all its dependencies. You should unpack it in the
root directory, then run <command>nix-finish-install</command>:
<screen>
$ cd /
$ tar xfj nix-1.1-x86_64-darwin.tar.bz2
$ nix-finish-install
</screen>
After this you can delete
<filename>/usr/bin/nix-finish-install</filename>.</para>
<para>If you plan to use Nix from a single non-root user account, its
probably convenient to change the ownership of the entire Nix store
and database to that user account. In that case, install as follows:
<screen>
alice$ cd /
alice$ sudo tar xfj nix-1.1-x86_64-darwin.tar.bz2
alice$ sudo chown -R alice /nix
alice$ nix-finish-install
</screen>
</para>
<para>Nix can be uninstalled using <command>rpm -e nix</command> or
<command>dpkg -r nix</command> on RPM- and Dpkg-based systems,
respectively. After this you should manually remove the Nix store and
other auxiliary data, if desired:
<screen>
$ rm -rf /nix</screen>
</para>
</section>
<section><title>Installing Nix from source</title>
<para>If no binary package is available, you can download and compile
a source distribution.</para>
<section><title>Prerequisites</title>
<itemizedlist>
<listitem><para>A fairly recent version of GCC/G++. Version 2.95
and higher should work. Clang will also work.</para></listitem>
<listitem><para>Perl 5.8 or higher.</para></listitem>
<listitem><para><command>pkg-config</command> to locate
dependencies. If your distribution does not provide it, you can get
it from <link
xlink:href="http://www.freedesktop.org/wiki/Software/pkg-config"
/>.</para></listitem>
<listitem><para>The 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></listitem>
<listitem><para>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></listitem>
<listitem><para>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></listitem>
<listitem><para>The <link
xlink:href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">Boehm
garbage collector</link> to reduce the evaluators memory
consumption (optional). 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></listitem>
<listitem><para>The <command>xmllint</command> and
<command>xsltproc</command> programs to build this manual and the
man-pages. These are part of the <literal>libxml2</literal> and
<literal>libxslt</literal> packages, respectively. You also need
the <link
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 Git
repository.</para></listitem>
<listitem><para>Recent versions of Bison and Flex to build the
parser. (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 Git
repository.</para></listitem>
</itemizedlist>
</section>
<section><title>Obtaining a source distribution</title>
<para>The source tarball of the most recent stable release can be
downloaded from the <link
xlink:href="http://nixos.org/nix/download.html">Nix homepage</link>.
You can also grab the <link
xlink:href="http://hydra.nixos.org/view/nix/trunk/latest/tarball/download-by-type/file/source-dist">most
recent development release</link>.</para>
<para>Alternatively, the most recent sources of Nix can be obtained
from its <link
@@ -63,71 +207,6 @@ repository.</para>
</section>
<section><title>Prerequisites</title>
<para><emphasis>The following prerequisites only apply when you build
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. 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,
which are part of the <literal>libxml2</literal> and
<literal>libxslt</literal> packages, respectively. You also need the
<link
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 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 Git repository.</para>
</section>
<section><title>Building Nix from source</title>
<para>After unpacking or checking out the Nix sources, issue the
@@ -180,33 +259,6 @@ options.</para>
</section>
<section><title>Installing a binary distribution</title>
<para>RPM and Deb packages of Nix for a number of different versions
of Fedora, openSUSE, Debian and Ubuntu can be downloaded from <link
xlink:href="http://nixos.org/" />. Once downloaded, the RPMs can be
installed or upgraded using <command>rpm -U</command>. For example,
<screen>
$ rpm -U nix-0.13pre18104-1.i386.rpm</screen>
Likewise, for a Deb package:
<screen>
$ dpkg -i nix_0.13pre18104-1_amd64.deb</screen>
</para>
<para>Nix can be uninstalled using <command>rpm -e nix</command> or
<command>dpkg -r nix</command>. After this you should manually remove
the Nix store and other auxiliary data, if desired:
<screen>
$ rm -rf /nix/store
$ rm -rf /nix/var</screen>
</para>
</section>
+1 -1
View File
@@ -225,7 +225,7 @@ href="docs/papers.html#servicecm">SCM-12 paper</a>.</para>
<simplesect><title>Portability</title>
<para>Nix should run on most Unix systems, including Linux, FreeBSD and
Mac OS X. It is also supported on Windows using Cygwin.</para>
Mac OS X.<!-- It is also supported on Windows using Cygwin.--></para>
</simplesect>
+5 -1
View File
@@ -40,7 +40,6 @@
<title>Command Reference</title>
<xi:include href="opt-common.xml" />
<xi:include href="env-common.xml" />
<xi:include href="conf-file.xml" />
<section>
<title>Main commands</title>
@@ -63,6 +62,11 @@
<xi:include href="nix-worker.xml" />
</section>
<section>
<title>Files</title>
<xi:include href="conf-file.xml" />
</section>
</appendix>
<xi:include href="troubleshooting.xml" />
+93
View File
@@ -6,6 +6,99 @@
<!--==================================================================-->
<section xml:id="ssec-relnotes-1.1"><title>Release 1.1 (July 18, 2012)</title>
<para>This release has the following improvements:</para>
<itemizedlist>
<listitem>
<para>On Linux, when doing a chroot build, Nix now uses various
namespace features provided by the Linux kernel to improve
build isolation. Namely:
<itemizedlist>
<listitem><para>The private network namespace ensures that
builders cannot talk to the outside world (or vice versa): each
build only sees a private loopback interface. This also means
that two concurrent builds can listen on the same port (e.g. as
part of a test) without conflicting with each
other.</para></listitem>
<listitem><para>The PID namespace causes each build to start as
PID 1. Processes outside of the chroot are not visible to those
on the inside. On the other hand, processes inside the chroot
<emphasis>are</emphasis> visible from the outside (though with
different PIDs).</para></listitem>
<listitem><para>The IPC namespace prevents the builder from
communicating with outside processes using SysV IPC mechanisms
(shared memory, message queues, semaphores). It also ensures
that all IPC objects are destroyed when the builder
exits.</para></listitem>
<listitem><para>The UTS namespace ensures that builders see a
hostname of <literal>localhost</literal> rather than the actual
hostname.</para></listitem>
<listitem><para>The private mount namespace was already used by
Nix to ensure that the bind-mounts used to set up the chroot are
cleaned up automatically.</para></listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>Build logs are now compressed using
<command>bzip2</command>. The command <command>nix-store
-l</command> decompresses them on the fly. This can be disabled
by setting the option <literal>build-compress-log</literal> to
<literal>false</literal>.</para>
</listitem>
<listitem>
<para>The creation of build logs in
<filename>/nix/var/log/nix/drvs</filename> can be disabled by
setting the new option <literal>build-keep-log</literal> to
<literal>false</literal>. This is useful, for instance, for Hydra
build machines.</para>
</listitem>
<listitem>
<para>Nix now reserves some space in
<filename>/nix/var/nix/db/reserved</filename> to ensure that the
garbage collector can run successfully if the disk is full. This
is necessary because SQLite transactions fail if the disk is
full.</para>
</listitem>
<listitem>
<para>Added a basic <function>fetchurl</function> function. This
is not intended to replace the <function>fetchurl</function> in
Nixpkgs, but is useful for bootstrapping; e.g., it will allow us
to get rid of the bootstrap binaries in the Nixpkgs source tree
and download them instead. You can use it by doing
<literal>import &lt;nix/fetchurl.nix> { url =
<replaceable>url</replaceable>; sha256 =
"<replaceable>hash</replaceable>"; }</literal>. (Shea Levy)</para>
</listitem>
<listitem>
<para>Improved RPM spec file. (Michel Alexandre Salim)</para>
</listitem>
<listitem>
<para>Support for on-demand socket-based activation in the Nix
daemon with <command>systemd</command>.</para>
</listitem>
<listitem>
<para>Added a manpage for
<citerefentry><refentrytitle>nix.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</itemizedlist>
</section>
<!--==================================================================-->
<section xml:id="ssec-relnotes-1.0"><title>Release 1.0 (May 11, 2012)</title>
+10
View File
@@ -0,0 +1,10 @@
[Unit]
Description=Helper daemon for managing secure, multi-user Nix stores
After=syslog.target
[Service]
Type=simple
ExecStart=/usr/bin/nix-worker --daemon
[Install]
WantedBy=multi-user.target
-181
View File
@@ -1,181 +0,0 @@
### Option `gc-keep-outputs'
#
# If `true', the garbage collector will keep the outputs of
# non-garbage derivations. If `false' (default), outputs will be
# deleted unless they are GC roots themselves (or reachable from other
# roots).
#
# In general, outputs must be registered as roots separately.
# However, even if the output of a derivation is registered as a root,
# the collector will still delete store paths that are used only at
# build time (e.g., the C compiler, or source tarballs downloaded from
# the network). To prevent it from doing so, set this option to
# `true'.
#gc-keep-outputs = false
### Option `gc-keep-derivations'
#
# If `true' (default), the garbage collector will keep the derivations
# from which non-garbage store paths were built. If `false', they
# will be deleted unless explicitly registered as a root (or reachable
# from other roots).
#
# Keeping derivation around is useful for querying and traceability
# (e.g., it allows you to ask with what dependencies or options a
# store path was built), so by default this option is on. Turn it off
# to safe a bit of disk space (or a lot if `gc-keep-outputs' is also
# turned on).
#gc-keep-derivations = true
### Option `env-keep-derivations'
#
# If `false' (default), derivations are not stored in Nix user
# environments. That is, the derivation any build-time-only
# dependencies may be garbage-collected.
#
# If `true', when you add a Nix derivation to a user environment, the
# path of the derivation is stored in the user environment. Thus, the
# derivation will not be garbage-collected until the user environment
# generation is deleted (`nix-env --delete-generations'). To prevent
# build-time-only dependencies from being collected, you should also
# turn on `gc-keep-outputs'.
#
# The difference between this option and `gc-keep-derivations' is that
# this one is `sticky': it applies to any user environment created
# while this option was enabled, while `gc-keep-derivations' only
# applies at the moment the garbage collector is run.
#env-keep-derivations = false
### Option `build-max-jobs'
#
# This option defines the maximum number of jobs that Nix will try to
# build in parallel. The default is 1. You should generally set it
# to the number of CPUs in your system (e.g., 2 on a Athlon 64 X2).
# It can be overriden using the `--max-jobs' / `-j' command line
# switch.
#build-max-jobs = 1
### Option `build-cores'
#
# This option defines the number of CPU cores to utilize in parallel
# within a build job, i.e. by passing an appropriate `-jN' flag to GNU
# Make. The default is 1, meaning that parallel building within jobs
# is disabled. Passing the special value `0' causes Nix to try and
# auto-detect the number of available cores on the local host. This
# setting can be overridden using the `--cores' command line switch.
#build-cores = 1
### Option `build-max-silent-time'
#
# This option defines the maximum number of seconds that a builder can
# go without producing any data on standard output or standard error.
# This is useful (for instance in a automated build system) to catch
# builds that are stuck in an infinite loop, or to catch remote builds
# that are hanging due to network problems. It can be overriden using
# the `--max-silent-time' command line switch.
#
# The value 0 means that there is no timeout. This is also the
# default.
#
# Example:
# build-max-silent-time = 600 # = 10 minutes
#build-max-silent-time = 0
### Option `build-users-group'
#
# This options specifies the Unix group containing the Nix build user
# accounts. In multi-user Nix installations, builds should not
# be performed by the Nix account since that would allow users to
# arbitrarily modify the Nix store and database by supplying specially
# crafted builders; and they cannot be performed by the calling user
# since that would allow him/her to influence the build result.
#
# Therefore, if this option is non-empty and specifies a valid group,
# builds will be performed under the user accounts that are a member
# of the group specified here (as listed in /etc/group). Those user
# accounts should not be used for any other purpose!
#
# Nix will never run two builds under the same user account at the
# same time. This is to prevent an obvious security hole: a malicious
# user writing a Nix expression that modifies the build result of a
# legitimate Nix expression being built by another user. Therefore it
# is good to have as many Nix build user accounts as you can spare.
# (Remember: uids are cheap.)
#
# The build users should have permission to create files in the Nix
# store, but not delete them. Therefore, /nix/store should be owned
# by the Nix account, its group should be the group specified here,
# and its mode should be 1775.
#
# If the build users group is empty, builds will be performed under
# the uid of the Nix process (that is, the uid of the caller if
# $NIX_REMOTE is empty, the uid under which the Nix daemon runs if
# $NIX_REMOTE is `daemon', or the uid that owns the setuid nix-worker
# program if $NIX_REMOTE is `slave'). Obviously, this should not be
# used in multi-user settings with untrusted users.
#
# The default is empty.
#
# Example:
# build-users-group = nix-builders
#build-users-group =
### Option `build-use-chroot'
#
# If set to `true', builds will be performed in a chroot environment,
# i.e., the build will be isolated from the normal file system
# hierarchy and will only see the Nix store, the temporary build
# directory, and the directories configured with the
# `build-chroot-dirs' option (such as /proc and /dev). This is useful
# to prevent undeclared dependencies on files in directories such as
# /usr/bin.
#
# The use of a chroot requires that Nix is run as root (but you can
# still use the "build users" feature to perform builds under
# different users than root). Currently, chroot builds only work on
# Linux because Nix uses "bind mounts" to make the Nix store and other
# directories available inside the chroot.
#
# The default is `false'.
#
# Example:
# build-use-chroot = true
#build-use-chroot = false
### Option `build-chroot-dirs'
#
# When builds are performed in a chroot environment, Nix will mount
# (using `mount --bind' on Linux) some directories from the normal
# file system hierarchy inside the chroot. These are the Nix store,
# the temporary build directory (usually /tmp/nix-<pid>-<number>) and
# the directories listed here. The default is "/dev /dev/pts /proc".
# Files in /dev (such as /dev/null) are needed by many builds, and
# some files in /proc may also be needed occasionally.
#
# Example:
# build-use-chroot = /dev /proc /bin
#build-chroot-dirs = /dev /dev/pts /proc
### Option `build-cache-failure'
#
# If this option is enabled, Nix will do negative caching; that is, it
# will remember failed builds, and won't attempt to try to build them
# again if you ask for it. Negative caching is disabled by default
# because Nix cannot distinguish between permanent build errors (e.g.,
# a syntax error in a source file) and transient build errors (e.g., a
# full disk), as they both cause the builder to return a non-zero exit
# code. You can clear the cache by doing `rm -f
# /nix/var/nix/db/failed/*'.
#
# Example:
# build-cache-failure = true
#build-cache-failure = false
+174 -51
View File
@@ -1,29 +1,26 @@
%define enable_setuid ""
%define nix_user "nix"
%define nix_group "nix"
# If set, the Nix user and group will be created by the RPM
# pre-install script.
%define nix_user_uid ""
%define nix_group_gid ""
%global nixbld_user "nix-builder-"
%global nixbld_group "nix-builders"
Summary: The Nix software deployment system
Name: nix
Version: @version@
Release: 1
License: GPL
Group: Software Deployment
Release: 2%{?dist}
License: LGPLv2+
%if 0%{?rhel}
Group: Applications/System
%endif
URL: http://nixos.org/
Source0: %{name}-@version@.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
Prefix: /usr
Source0: %{name}-%{version}.tar.bz2
%if 0%{?el5}
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%endif
BuildRequires: perl(DBD::SQLite)
BuildRequires: perl(DBI)
BuildRequires: perl(ExtUtils::ParseXS)
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
@@ -31,7 +28,6 @@ BuildRequires: sqlite-devel
Provides: perl(Nix::SSH)
%description
Nix is a purely functional package manager. It allows multiple
versions of a package to be installed side-by-side, ensures that
dependency specifications are complete, supports atomic upgrades and
@@ -39,52 +35,179 @@ rollbacks, allows non-root users to install software, and has many
other features. It is the basis of the NixOS Linux distribution, but
it can be used equally well under other Unix systems.
%package devel
Summary: Development files for %{name}
%if 0%{?rhel}
Group: Development/Libraries
%endif
Requires: %{name}%{?_isa} = %{version}-%{release}
%description devel
The %{name}-devel package contains libraries and header files for
developing applications that use %{name}.
%package doc
Summary: Documentation files for %{name}
%if 0%{?rhel}
Group: Documentation
%endif
BuildArch: noarch
Requires: %{name} = %{version}-%{release}
%description doc
The %{name}-doc package contains documentation files for %{name}.
%package -n emacs-%{name}
Summary: Nix mode for Emacs
%if 0%{?rhel}
Group: Applications/Editors
%endif
BuildArch: noarch
BuildRequires: emacs
Requires: emacs(bin) >= %{_emacs_version}
%description -n emacs-%{name}
This package provides a major mode for editing Nix expressions.
%package -n emacs-%{name}-el
Summary: Elisp source files for emacs-%{name}
%if 0%{?rhel}
Group: Applications/Editors
%endif
BuildArch: noarch
Requires: emacs-%{name} = %{version}-%{release}
%description -n emacs-%{name}-el
This package contains the elisp source file for the Nix major mode for
GNU Emacs. You do not need to install this package to run Nix. Install
the emacs-%{name} package to edit Nix expressions with GNU Emacs.
%prep
%setup -q
# Install Perl modules to vendor_perl
# configure.ac need to be changed to make this global; however, this will
# also affect NixOS. Use discretion.
%{__sed} -i 's|perl5/site_perl/$perlversion/$perlarchname|perl5/vendor_perl|' \
configure
%build
extraFlags=
if test -n "%{enable_setuid}"; then
extraFlags="$extraFlags --enable-setuid"
if test -n "%{nix_user}"; then
extraFlags="$extraFlags --with-nix-user=%{nix_user}"
fi
if test -n "%{nix_group}"; then
extraFlags="$extraFlags --with-nix-group=%{nix_group}"
fi
fi
./configure --prefix=%{_prefix} --sysconfdir=/etc $extraFlags
make
make check
# - override docdir so large documentation files are owned by the
# -doc subpackage
# - set localstatedir by hand to the preferred nix value
%configure --localstatedir=/nix/var \
--docdir=%{_defaultdocdir}/%{name}-doc-%{version} \
$extraFlags
make %{?_smp_flags}
%{_emacs_bytecompile} misc/emacs/nix-mode.el
%install
%if 0%{?el5}
rm -rf $RPM_BUILD_ROOT
%endif
make DESTDIR=$RPM_BUILD_ROOT install
rm $RPM_BUILD_ROOT/etc/nix/nix.conf
strip $RPM_BUILD_ROOT/%{_prefix}/bin/* || true
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
# Fix symlink: we want to link to the versioned soname, not to the
# unversioned one that'd be put in -devel
pushd $RPM_BUILD_ROOT%{perl_vendorarch}/auto/Nix/Store
ln -sf %{_libdir}/nix/libNixStore.so.0 Store.so
popd
# Specify build users group
echo "build-users-group = %{nixbld_group}" > $RPM_BUILD_ROOT%{_sysconfdir}/nix/nix.conf
# make per-user directories
for d in profiles gcroots;
do
mkdir $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
chmod 1777 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
done
# fix permission of nix profile
# (until this is fixed in the relevant Makefile)
chmod -x $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/nix.sh
# systemd not available on RHEL yet
%if ! 0%{?rhel}
# install systemd service descriptor
mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system
cp -p misc/systemd/nix-worker.service \
$RPM_BUILD_ROOT%{_prefix}/lib/systemd/system/
%endif
# Copy the byte-compiled mode file by hand
cp -p misc/emacs/nix-mode.elc $RPM_BUILD_ROOT%{_emacs_sitelispdir}/
# we ship this file in the base package
rm $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}-doc-%{version}/README
%check
make check
%clean
rm -rf $RPM_BUILD_ROOT
%pre
if test -n "%{nix_group_gid}"; then
/usr/sbin/groupadd -g %{nix_group_gid} %{nix_group} || true
fi
if test -n "%{nix_user_uid}"; then
/usr/sbin/useradd -c "Nix" -u %{nix_user_uid} \
-s /sbin/nologin -r -d /var/empty %{nix_user} \
-g %{nix_group} || true
fi
getent group %{nixbld_group} >/dev/null || groupadd -r %{nixbld_group}
for i in $(seq 10);
do
getent passwd %{nixbld_user}$i >/dev/null || \
useradd -r -g %{nixbld_group} -G %{nixbld_group} -d /var/empty \
-s %{_sbindir}/nologin \
-c "Nix build user $i" %{nixbld_user}$i
done
%post
chgrp %{nixbld_group} /nix/store
chmod 1775 /nix/store
%if ! 0%{?rhel}
# Enable and start Nix worker
systemctl enable nix-worker.service
systemctl start nix-worker.service
%endif
%files
#%defattr(-,root,root)
%{_prefix}/bin
%{_prefix}/lib
%{_prefix}/libexec
%{_prefix}/include
%{_prefix}/share
/etc/profile.d/nix.sh
/nix/var
/nix/store
%config
/etc/nix
%doc COPYING AUTHORS README
%{_bindir}/nix-*
%dir %{_libdir}/nix
%{_libdir}/nix/*.so.*
%{perl_vendorarch}/*
%exclude %dir %{perl_vendorarch}/auto/
%{_prefix}/libexec/*
%if ! 0%{?rhel}
%{_prefix}/lib/systemd/system/nix-worker.service
%endif
%{_datadir}/emacs/site-lisp/nix-mode.el
%{_datadir}/nix
%{_mandir}/man1/*.1*
%{_mandir}/man5/*.5*
%{_mandir}/man8/*.8*
%config(noreplace) %{_sysconfdir}/profile.d/nix.sh
/nix
%dir %{_sysconfdir}/nix
%config(noreplace) %{_sysconfdir}/nix/nix.conf
%files devel
%{_includedir}/nix
%{_libdir}/nix/*.so
%files doc
%docdir %{_defaultdocdir}/%{name}-doc-%{version}
%{_defaultdocdir}/%{name}-doc-%{version}
%files -n emacs-%{name}
%{_emacs_sitelispdir}/*.elc
#{_emacs_sitestartdir}/*.el
%files -n emacs-%{name}-el
%{_emacs_sitelispdir}/*.el
+1
View File
@@ -14,6 +14,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
isValidPath queryReferences queryPathInfo queryDeriver queryPathHash
queryPathFromHashPart
topoSortPaths computeFSClosure followLinksToStorePath exportPaths
hashPath hashFile hashString
addToStore makeFixedOutputPath
+13 -2
View File
@@ -86,7 +86,7 @@ SV * queryDeriver(char * path)
}
SV * queryPathInfo(char * path)
SV * queryPathInfo(char * path, int base32)
PPCODE:
try {
doInit();
@@ -95,7 +95,7 @@ SV * queryPathInfo(char * path)
XPUSHs(&PL_sv_undef);
else
XPUSHs(sv_2mortal(newSVpv(info.deriver.c_str(), 0)));
string s = "sha256:" + printHash(info.hash);
string s = "sha256:" + (base32 ? printHash32(info.hash) : printHash(info.hash));
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
mXPUSHi(info.registrationTime);
mXPUSHi(info.narSize);
@@ -108,6 +108,17 @@ SV * queryPathInfo(char * path)
}
SV * queryPathFromHashPart(char * hashPart)
PPCODE:
try {
doInit();
Path path = store->queryPathFromHashPart(hashPart);
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}
SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
PPCODE:
try {
+35 -6
View File
@@ -63,7 +63,7 @@ let
build =
{ system ? "i686-linux" }:
{ system ? "x86_64-linux" }:
with import nixpkgs { inherit system; };
@@ -80,9 +80,42 @@ let
--enable-gc
'';
enableParallelBuilding = true;
doInstallCheck = true;
};
binaryTarball =
{ system ? "x86_64-linux" }:
with import nixpkgs { inherit system; };
let
toplevel = build { inherit system; };
version = toplevel.src.version;
in
runCommand "nix-binary-tarball-${version}"
{ exportReferencesGraph = [ "closure" toplevel ];
buildInputs = [ perl ];
meta.description = "Distribution-independent Nix bootstrap binaries for ${system}";
}
''
storePaths=$(perl ${pathsFromGraph} ./closure)
printRegistration=1 perl ${pathsFromGraph} ./closure > $TMPDIR/reginfo
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
--subst-var-by nix ${toplevel} --subst-var-by regInfo /nix/store/reginfo
chmod +x $TMPDIR/install
fn=$out/nix-${version}-${system}.tar.bz2
mkdir -p $out/nix-support
echo "file binary-dist $fn" >> $out/nix-support/hydra-build-products
tar cvfj $fn \
--owner=0 --group=0 --absolute-names \
--transform "s,$TMPDIR/install,/usr/bin/nix-finish-install," \
--transform "s,$TMPDIR/reginfo,/nix/store/reginfo," \
$TMPDIR/install $TMPDIR/reginfo $storePaths
'';
coverage =
with import nixpkgs { system = "x86_64-linux"; };
@@ -120,10 +153,6 @@ let
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_debian60i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian60i386) 50;
@@ -163,7 +192,7 @@ let
name = "nix-rpm-${diskImage.name}";
src = jobs.tarball;
diskImage = (diskImageFun vmTools.diskImageFuns)
{ extraPackages = [ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" ]; };
{ extraPackages = [ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" "emacs" ]; };
memSize = 1024;
meta.schedulingPriority = prio;
postRPMInstall = "cd /tmp/rpmout/BUILD/nix-* && make installcheck";
+1 -1
View File
@@ -11,7 +11,7 @@ nix-pull nix-push: download-using-manifests.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_DATA) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh
$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
$(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix
+34
View File
@@ -0,0 +1,34 @@
#! /bin/sh -e
nix=@nix@
regInfo=@regInfo@
if ! $nix/bin/nix-store --load-db < $regInfo; then
echo "$0: unable to register valid paths"
exit 1
fi
. @nix@/etc/profile.d/nix.sh
if ! $nix/bin/nix-env -i @nix@; then
echo "$0: unable to install Nix into your default profile"
exit 1
fi
# Add nix.sh to the shell's profile.d directory.
p=$NIX_LINK/etc/profile.d/nix.sh
if [ -w /etc/profile.d ]; then
ln -s $p /etc/profile.d/
elif [ -w /usr/local/etc/profile.d ]; then
ln -s $p /usr/local/etc/profile.d/
else
cat <<EOF
Installation finished. To ensure that the necessary environment
variables are set, please add the line
source $p
to your shell profile (e.g. ~/.profile).
EOF
fi
+45 -13
View File
@@ -1,18 +1,50 @@
if test -n "$HOME"; then
NIX_LINK="$HOME/.nix-profile"
export NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
if ! test -L "$NIX_LINK"; then
echo "creating $NIX_LINK" >&2
_NIX_DEF_LINK=@localstatedir@/nix/profiles/default
@coreutils@/ln -s "$_NIX_DEF_LINK" "$NIX_LINK"
# Set up the per-user profile.
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2
fi
if ! test -L $HOME/.nix-profile; then
echo "creating $HOME/.nix-profile" >&2
if test "$USER" != root; then
@coreutils@/ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile
else
# Root installs in the system-wide profile by default.
@coreutils@/ln -s /nix/var/nix/profiles/default $HOME/.nix-profile
fi
export PATH=$NIX_LINK/bin:$PATH
fi
# This is a quick hack to make fontconfig-based packages in Nixpkgs
# work out of the box on non-NixOS systems. Of course, we should
# really fix fontconfig...
if test -z "$FONTCONFIG_FILE" -a -e /etc/fonts/fonts.conf; then
export FONTCONFIG_FILE=/etc/fonts/fonts.conf
export PATH="$HOME/.nix-profile/bin:$PATH"
# Subscribe the root user to the NixOS channel by default.
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
echo "http://nixos.org/releases/nixos/channels/nixos-unstable nixos" > $HOME/.nix-channels
fi
# Create the per-user garbage collector roots directory.
NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER
mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR
if test "$(stat --printf '%u' $NIX_USER_GCROOTS_DIR)" != "$(id -u)"; then
echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2
fi
# Set up a default Nix expression from which to install stuff.
if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then
echo "creating $HOME/.nix-defexpr" >&2
rm -f $HOME/.nix-defexpr
mkdir $HOME/.nix-defexpr
if [ "$USER" != root ]; then
@coreutils@/ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root
fi
fi
# Set up secure multi-user builds: non-root users build through the
# Nix daemon.
if test "$USER" != root; then
export NIX_REMOTE=daemon
else
unset NIX_REMOTE
fi
+1 -8
View File
@@ -1,20 +1,13 @@
#ifndef __ATTR_PATH_H
#define __ATTR_PATH_H
#pragma once
#include "eval.hh"
#include <string>
#include <map>
namespace nix {
void findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings & autoArgs, Expr * e, Value & v);
}
#endif /* !__ATTR_PATH_H */
+1 -6
View File
@@ -1,9 +1,7 @@
#ifndef __COMMON_OPTS_H
#define __COMMON_OPTS_H
#pragma once
#include "eval.hh"
namespace nix {
/* Some common option parsing between nix-env and nix-instantiate. */
@@ -17,6 +15,3 @@ bool parseSearchPathArg(const string & arg, Strings::iterator & i,
Path lookupFileArg(EvalState & state, string s);
}
#endif /* !__COMMON_OPTS_H */
+1 -6
View File
@@ -1,5 +1,4 @@
#ifndef __EVAL_INLINE_H
#define __EVAL_INLINE_H
#pragma once
#include "eval.hh"
@@ -8,7 +7,6 @@
namespace nix {
LocalNoInlineNoReturn(void throwEvalError(const char * s))
{
throw EvalError(s);
@@ -55,7 +53,4 @@ inline void EvalState::forceList(Value & v)
throwTypeError("value is %1% while a list was expected", showType(v));
}
}
#endif /* !__EVAL_INLINE_H */
-9
View File
@@ -143,9 +143,7 @@ EvalState::EvalState()
, staticBaseEnv(false, 0)
{
nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0;
nrEvaluated = recursionDepth = maxRecursionDepth = 0;
nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0;
deepestStack = (char *) -1;
#if HAVE_BOEHMGC
static bool gcInitialised = true;
@@ -190,7 +188,6 @@ EvalState::EvalState()
EvalState::~EvalState()
{
assert(recursionDepth == 0);
}
@@ -1206,12 +1203,6 @@ void EvalState::printStats()
printMsg(v, format(" time elapsed: %1%") % cpuTime);
printMsg(v, format(" size of a value: %1%") % sizeof(Value));
printMsg(v, format(" expressions evaluated: %1%") % nrEvaluated);
char x;
printMsg(v, format(" stack space used: %1% bytes") % (&x - deepestStack));
printMsg(v, format(" max eval() nesting depth: %1%") % maxRecursionDepth);
printMsg(v, format(" stack space per eval() level: %1% bytes")
% ((&x - deepestStack) / (float) maxRecursionDepth));
printMsg(v, format(" environments allocated: %1% (%2% bytes)")
% nrEnvs % (nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *)));
printMsg(v, format(" list elements: %1% (%2% bytes)")
+1 -9
View File
@@ -1,5 +1,4 @@
#ifndef __EVAL_H
#define __EVAL_H
#pragma once
#include "value.hh"
#include "nixexpr.hh"
@@ -242,13 +241,9 @@ private:
unsigned long nrValuesInEnvs;
unsigned long nrValues;
unsigned long nrListElems;
unsigned long nrEvaluated;
unsigned long nrAttrsets;
unsigned long nrOpUpdates;
unsigned long nrOpUpdateValuesCopied;
unsigned int recursionDepth;
unsigned int maxRecursionDepth;
char * deepestStack; /* for measuring stack usage */
friend class RecursionCounter;
friend class ExprOpUpdate;
@@ -260,6 +255,3 @@ string showType(const Value & v);
}
#endif /* !__EVAL_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __GET_DRVS_H
#define __GET_DRVS_H
#pragma once
#include "eval.hh"
@@ -78,6 +77,3 @@ void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
}
#endif /* !__GET_DRVS_H */
+1 -10
View File
@@ -1,12 +1,9 @@
#ifndef __NAMES_H
#define __NAMES_H
#pragma once
#include "types.hh"
namespace nix {
struct DrvName
{
string fullName;
@@ -19,15 +16,9 @@ struct DrvName
bool matches(DrvName & n);
};
typedef list<DrvName> DrvNames;
int compareVersions(const string & v1, const string & v2);
DrvNames drvNamesFromArgs(const Strings & opArgs);
}
#endif /* !__NAMES_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __NIXEXPR_H
#define __NIXEXPR_H
#pragma once
#include "value.hh"
#include "symbol-table.hh"
@@ -290,6 +289,3 @@ struct StaticEnv
}
#endif /* !__NIXEXPR_H */
+6 -2
View File
@@ -53,7 +53,7 @@ static void prim_import(EvalState & state, Value * * args, Value & v)
try {
/* !!! If using a substitute, we only need to fetch
the selected output of this derivation. */
store->buildDerivations(singleton<PathSet>(ctx));
store->buildPaths(singleton<PathSet>(ctx));
} catch (Error & e) {
throw ImportError(e.msg());
}
@@ -502,7 +502,11 @@ static void prim_toPath(EvalState & state, Value * * args, Value & v)
static void prim_storePath(EvalState & state, Value * * args, Value & v)
{
PathSet context;
Path path = canonPath(state.coerceToPath(*args[0], context));
Path path = state.coerceToPath(*args[0], context);
/* Resolve symlinks in path, unless path itself is a symlink
directly in the store. The latter condition is necessary so
e.g. nix-push does the right thing. */
if (!isStorePath(path)) path = canonPath(path, true);
if (!isInStore(path))
throw EvalError(format("path `%1%' is not in the Nix store") % path);
Path path2 = toStorePath(path);
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __SYMBOL_TABLE_H
#define __SYMBOL_TABLE_H
#pragma once
#include "config.h"
@@ -88,5 +87,3 @@ public:
};
}
#endif /* !__SYMBOL_TABLE_H */
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __VALUE_TO_XML_H
#define __VALUE_TO_XML_H
#pragma once
#include "nixexpr.hh"
#include "eval.hh"
@@ -13,5 +12,3 @@ void printValueAsXML(EvalState & state, bool strict, bool location,
Value & v, std::ostream & out, PathSet & context);
}
#endif /* !__VALUE_TO_XML_H */
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __VALUE_H
#define __VALUE_H
#pragma once
#include "symbol-table.hh"
@@ -151,5 +150,3 @@ void mkPath(Value & v, const char * s);
}
#endif /* !__VALUE_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __SHARED_H
#define __SHARED_H
#pragma once
#include "util.hh"
@@ -54,6 +53,3 @@ extern int exitCode;
extern char * * argvSaved;
}
#endif /* !__SHARED_H */
+1 -1
View File
@@ -10,7 +10,7 @@ pkginclude_HEADERS = \
globals.hh references.hh pathlocks.hh \
worker-protocol.hh
libstore_la_LIBADD = ../libutil/libutil.la ../boost/format/libformat.la @SQLITE3_LIBS@
libstore_la_LIBADD = ../libutil/libutil.la ../boost/format/libformat.la @SQLITE3_LIBS@ -lbz2
EXTRA_DIST = schema.sql
+280 -149
View File
@@ -31,6 +31,8 @@
#include <pwd.h>
#include <grp.h>
#include <bzlib.h>
/* Includes required for chroot support. */
#if HAVE_SYS_PARAM_H
@@ -45,6 +47,13 @@
#define CHROOT_ENABLED HAVE_CHROOT && HAVE_UNSHARE && HAVE_SYS_MOUNT_H && defined(MS_BIND) && defined(CLONE_NEWNS)
#if CHROOT_ENABLED
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/ip.h>
#endif
#if HAVE_SYS_PERSONALITY_H
#include <sys/personality.h>
@@ -758,6 +767,8 @@ private:
Path tmpDir;
/* File descriptor for the log file. */
FILE * fLogFile;
BZFILE * bzLogFile;
AutoCloseFD fdLogFile;
/* Pipe for the builder's standard output/error. */
@@ -783,6 +794,11 @@ private:
typedef void (DerivationGoal::*GoalState)();
GoalState state;
/* Stuff we need to pass to initChild(). */
PathSet dirsInChroot;
typedef map<string, string> Environment;
Environment env;
public:
DerivationGoal(const Path & drvPath, Worker & worker);
~DerivationGoal();
@@ -811,6 +827,11 @@ private:
/* Start building a derivation. */
void startBuilder();
/* Initialise the builder's process. */
void initChild();
friend int childEntry(void *);
/* Must be called after the output paths have become valid (either
due to a successful build or hook, or because they already
were). */
@@ -819,6 +840,9 @@ private:
/* Open a log file and a pipe to it. */
Path openLogFile();
/* Close the log file. */
void closeLogFile();
/* Delete the temporary directory, if we have one. */
void deleteTmpDir(bool force);
@@ -839,6 +863,8 @@ private:
DerivationGoal::DerivationGoal(const Path & drvPath, Worker & worker)
: Goal(worker)
, fLogFile(0)
, bzLogFile(0)
, useChroot(false)
{
this->drvPath = drvPath;
@@ -855,6 +881,7 @@ DerivationGoal::~DerivationGoal()
try {
killChild();
deleteTmpDir(false);
closeLogFile();
} catch (...) {
ignoreException();
}
@@ -1241,7 +1268,7 @@ void DerivationGoal::buildDone()
else builderOut.readSide.close();
/* Close the log file. */
fdLogFile.close();
closeLogFile();
/* When running under a build user, make sure that all processes
running under that uid are gone. This is to prevent a
@@ -1452,6 +1479,13 @@ void chmod(const Path & path, mode_t mode)
}
int childEntry(void * arg)
{
((DerivationGoal *) arg)->initChild();
return 1;
}
void DerivationGoal::startBuilder()
{
startNest(nest, lvlInfo,
@@ -1464,8 +1498,6 @@ void DerivationGoal::startBuilder()
% drv.platform % thisSystem % drvPath);
/* Construct the environment passed to the builder. */
typedef map<string, string> Environment;
Environment env;
/* Most shells initialise PATH to some default (/bin:/usr/bin:...) when
PATH is not set. We don't want this, so we fill it in with some dummy
@@ -1619,7 +1651,6 @@ void DerivationGoal::startBuilder()
work properly. Purity checking for fixed-output derivations
is somewhat pointless anyway. */
useChroot = queryBoolSetting("build-use-chroot", false);
PathSet dirsInChroot;
if (fixedOutput) useChroot = false;
@@ -1675,7 +1706,6 @@ void DerivationGoal::startBuilder()
Paths defaultDirs;
defaultDirs.push_back("/dev");
defaultDirs.push_back("/dev/pts");
defaultDirs.push_back("/proc");
Paths dirsInChroot_ = querySetting("build-chroot-dirs", defaultDirs);
dirsInChroot.insert(dirsInChroot_.begin(), dirsInChroot_.end());
@@ -1744,146 +1774,46 @@ void DerivationGoal::startBuilder()
/* Fork a child to build the package. Note that while we
currently use forks to run and wait for the children, it
shouldn't be hard to use threads for this on systems where
fork() is unavailable or inefficient. */
pid = fork();
switch (pid) {
fork() is unavailable or inefficient.
case -1:
throw SysError("unable to fork");
If we're building in a chroot, then also set up private
namespaces for the build:
case 0:
- The PID namespace causes the build to start as PID 1.
Processes outside of the chroot are not visible to those on
the inside, but processes inside the chroot are visible from
the outside (though with different PIDs).
/* Warning: in the child we should absolutely not make any
SQLite calls! */
- The private mount namespace ensures that all the bind mounts
we do will only show up in this process and its children, and
will disappear automatically when we're done.
- The private network namespace ensures that the builder cannot
talk to the outside world (or vice versa). It only has a
private loopback interface.
try { /* child */
- The IPC namespace prevents the builder from communicating
with outside processes using SysV IPC mechanisms (shared
memory, message queues, semaphores). It also ensures that
all IPC objects are destroyed when the builder exits.
- The UTS namespace ensures that builders see a hostname of
localhost rather than the actual hostname.
*/
#if CHROOT_ENABLED
if (useChroot) {
/* Create our own mount namespace. This means that
all the bind mounts we do will only show up in this
process and its children, and will disappear
automatically when we're done. */
if (unshare(CLONE_NEWNS) == -1)
throw SysError(format("cannot set up a private mount namespace"));
/* Bind-mount all the directories from the "host"
filesystem that we want in the chroot
environment. */
foreach (PathSet::iterator, i, dirsInChroot) {
Path source = *i;
Path target = chrootRootDir + source;
debug(format("bind mounting `%1%' to `%2%'") % source % target);
createDirs(target);
if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == -1)
throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target);
}
/* Do the chroot(). Below we do a chdir() to the
temporary build directory to make sure the current
directory is in the chroot. (Actually the order
doesn't matter, since due to the bind mount tmpDir
and tmpRootDit/tmpDir are the same directories.) */
if (chroot(chrootRootDir.c_str()) == -1)
throw SysError(format("cannot change root directory to `%1%'") % chrootRootDir);
}
if (useChroot) {
char stack[32 * 1024];
pid = clone(childEntry, stack + sizeof(stack) - 8,
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, this);
} else
#endif
commonChildInit(builderOut);
if (chdir(tmpDir.c_str()) == -1)
throw SysError(format("changing into `%1%'") % tmpDir);
/* Close all other file descriptors. */
closeMostFDs(set<int>());
#ifdef CAN_DO_LINUX32_BUILDS
/* Change the personality to 32-bit if we're doing an
i686-linux build on an x86_64-linux machine. */
if (drv.platform == "i686-linux" && thisSystem == "x86_64-linux") {
if (personality(0x0008 | 0x8000000 /* == PER_LINUX32_3GB */) == -1)
throw SysError("cannot set i686-linux personality");
}
/* Impersonate a Linux 2.6 machine to get some determinism
in builds that depend on the kernel version. */
if ((drv.platform == "i686-linux" || drv.platform == "x86_64-linux") &&
queryBoolSetting("build-impersonate-linux-26", true))
{
int cur = personality(0xffffffff);
if (cur != -1) personality(cur | 0x0020000 /* == UNAME26 */);
}
#endif
/* Fill in the environment. */
Strings envStrs;
foreach (Environment::const_iterator, i, env)
envStrs.push_back(i->first + "=" + i->second);
const char * * envArr = strings2CharPtrs(envStrs);
Path program = drv.builder.c_str();
std::vector<const char *> args; /* careful with c_str()! */
string user; /* must be here for its c_str()! */
/* If we are running in `build-users' mode, then switch to
the user we allocated above. Make sure that we drop
all root privileges. Note that above we have closed
all file descriptors except std*, so that's safe. Also
note that setuid() when run as root sets the real,
effective and saved UIDs. */
if (buildUser.enabled()) {
printMsg(lvlChatty, format("switching to user `%1%'") % buildUser.getUser());
if (amPrivileged()) {
if (setgroups(0, 0) == -1)
throw SysError("cannot clear the set of supplementary groups");
if (setgid(buildUser.getGID()) == -1 ||
getgid() != buildUser.getGID() ||
getegid() != buildUser.getGID())
throw SysError("setgid failed");
if (setuid(buildUser.getUID()) == -1 ||
getuid() != buildUser.getUID() ||
geteuid() != buildUser.getUID())
throw SysError("setuid failed");
} else {
/* Let the setuid helper take care of it. */
program = nixLibexecDir + "/nix-setuid-helper";
args.push_back(program.c_str());
args.push_back("run-builder");
user = buildUser.getUser().c_str();
args.push_back(user.c_str());
args.push_back(drv.builder.c_str());
}
}
/* Fill in the arguments. */
string builderBasename = baseNameOf(drv.builder);
args.push_back(builderBasename.c_str());
foreach (Strings::iterator, i, drv.args)
args.push_back(i->c_str());
args.push_back(0);
restoreSIGPIPE();
/* Execute the program. This should not return. */
execve(program.c_str(), (char * *) &args[0], (char * *) envArr);
throw SysError(format("executing `%1%'")
% drv.builder);
} catch (std::exception & e) {
std::cerr << format("build error: %1%") % e.what() << std::endl;
}
quickExit(1);
{
pid = fork();
if (pid == 0) initChild();
}
if (pid == -1) throw SysError("unable to fork");
/* parent */
pid.setSeparatePG(true);
builderOut.writeSide.close();
@@ -1897,6 +1827,161 @@ void DerivationGoal::startBuilder()
}
void DerivationGoal::initChild()
{
/* Warning: in the child we should absolutely not make any SQLite
calls! */
try { /* child */
#if CHROOT_ENABLED
if (useChroot) {
/* Initialise the loopback interface. */
AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP));
if (fd == -1) throw SysError("cannot open IP socket");
struct ifreq ifr;
strcpy(ifr.ifr_name, "lo");
ifr.ifr_flags = IFF_UP | IFF_LOOPBACK | IFF_RUNNING;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1)
throw SysError("cannot set loopback interface flags");
fd.close();
/* Set the hostname etc. to fixed values. */
char hostname[] = "localhost";
sethostname(hostname, sizeof(hostname));
char domainname[] = "(none)"; // kernel default
setdomainname(domainname, sizeof(domainname));
/* Bind-mount all the directories from the "host"
filesystem that we want in the chroot
environment. */
foreach (PathSet::iterator, i, dirsInChroot) {
Path source = *i;
Path target = chrootRootDir + source;
debug(format("bind mounting `%1%' to `%2%'") % source % target);
createDirs(target);
if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == -1)
throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target);
}
/* Bind a new instance of procfs on /proc to reflect our
private PID namespace. */
if (mount("none", (chrootRootDir + "/proc").c_str(), "proc", 0, 0) == -1)
throw SysError("mounting /proc");
/* Mount a new tmpfs on /dev/shm to ensure that whatever
the builder puts in /dev/shm is cleaned up automatically. */
if (pathExists("/dev/shm"))
if (mount("none", (chrootRootDir + "/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
throw SysError("mounting /dev/shm");
/* Do the chroot(). Below we do a chdir() to the
temporary build directory to make sure the current
directory is in the chroot. (Actually the order
doesn't matter, since due to the bind mount tmpDir and
tmpRootDit/tmpDir are the same directories.) */
if (chroot(chrootRootDir.c_str()) == -1)
throw SysError(format("cannot change root directory to `%1%'") % chrootRootDir);
}
#endif
commonChildInit(builderOut);
if (chdir(tmpDir.c_str()) == -1)
throw SysError(format("changing into `%1%'") % tmpDir);
/* Close all other file descriptors. */
closeMostFDs(set<int>());
#ifdef CAN_DO_LINUX32_BUILDS
/* Change the personality to 32-bit if we're doing an
i686-linux build on an x86_64-linux machine. */
if (drv.platform == "i686-linux" && thisSystem == "x86_64-linux") {
if (personality(0x0008 | 0x8000000 /* == PER_LINUX32_3GB */) == -1)
throw SysError("cannot set i686-linux personality");
}
/* Impersonate a Linux 2.6 machine to get some determinism in
builds that depend on the kernel version. */
if ((drv.platform == "i686-linux" || drv.platform == "x86_64-linux") &&
queryBoolSetting("build-impersonate-linux-26", true))
{
int cur = personality(0xffffffff);
if (cur != -1) personality(cur | 0x0020000 /* == UNAME26 */);
}
#endif
/* Fill in the environment. */
Strings envStrs;
foreach (Environment::const_iterator, i, env)
envStrs.push_back(i->first + "=" + i->second);
const char * * envArr = strings2CharPtrs(envStrs);
Path program = drv.builder.c_str();
std::vector<const char *> args; /* careful with c_str()! */
string user; /* must be here for its c_str()! */
/* If we are running in `build-users' mode, then switch to the
user we allocated above. Make sure that we drop all root
privileges. Note that above we have closed all file
descriptors except std*, so that's safe. Also note that
setuid() when run as root sets the real, effective and
saved UIDs. */
if (buildUser.enabled()) {
printMsg(lvlChatty, format("switching to user `%1%'") % buildUser.getUser());
if (amPrivileged()) {
if (setgroups(0, 0) == -1)
throw SysError("cannot clear the set of supplementary groups");
if (setgid(buildUser.getGID()) == -1 ||
getgid() != buildUser.getGID() ||
getegid() != buildUser.getGID())
throw SysError("setgid failed");
if (setuid(buildUser.getUID()) == -1 ||
getuid() != buildUser.getUID() ||
geteuid() != buildUser.getUID())
throw SysError("setuid failed");
} else {
/* Let the setuid helper take care of it. */
program = nixLibexecDir + "/nix-setuid-helper";
args.push_back(program.c_str());
args.push_back("run-builder");
user = buildUser.getUser().c_str();
args.push_back(user.c_str());
args.push_back(drv.builder.c_str());
}
}
/* Fill in the arguments. */
string builderBasename = baseNameOf(drv.builder);
args.push_back(builderBasename.c_str());
foreach (Strings::iterator, i, drv.args)
args.push_back(i->c_str());
args.push_back(0);
restoreSIGPIPE();
/* Execute the program. This should not return. */
execve(program.c_str(), (char * *) &args[0], (char * *) envArr);
throw SysError(format("executing `%1%'")
% drv.builder);
} catch (std::exception & e) {
std::cerr << format("build error: %1%") % e.what() << std::endl;
}
quickExit(1);
}
/* Parse a list of reference specifiers. Each element must either be
a store path, or the symbolic name of the output of the derivation
(such as `out'). */
@@ -2032,18 +2117,53 @@ string drvsLogDir = "drvs";
Path DerivationGoal::openLogFile()
{
if (!queryBoolSetting("build-keep-log", true)) return "";
/* Create a log file. */
Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
createDirs(dir);
Path logFileName = (format("%1%/%2%") % dir % baseNameOf(drvPath)).str();
fdLogFile = open(logFileName.c_str(),
O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdLogFile == -1)
throw SysError(format("creating log file `%1%'") % logFileName);
closeOnExec(fdLogFile);
return logFileName;
if (queryBoolSetting("build-compress-log", true)) {
Path logFileName = (format("%1%/%2%.bz2") % dir % baseNameOf(drvPath)).str();
AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
closeOnExec(fd);
if (!(fLogFile = fdopen(fd.borrow(), "w")))
throw SysError(format("opening file `%1%'") % logFileName);
int err;
if (!(bzLogFile = BZ2_bzWriteOpen(&err, fLogFile, 9, 0, 0)))
throw Error(format("cannot open compressed log file `%1%'") % logFileName);
return logFileName;
} else {
Path logFileName = (format("%1%/%2%") % dir % baseNameOf(drvPath)).str();
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdLogFile == -1) throw SysError(format("creating log file `%1%'") % logFileName);
closeOnExec(fdLogFile);
return logFileName;
}
}
void DerivationGoal::closeLogFile()
{
if (bzLogFile) {
int err;
BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0);
bzLogFile = 0;
if (err != BZ_OK) throw Error(format("cannot close compressed log file (BZip2 error = %1%)") % err);
}
if (fLogFile) {
fclose(fLogFile);
fLogFile = 0;
}
fdLogFile.close();
}
@@ -2071,7 +2191,12 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
{
if (verbosity >= buildVerbosity)
writeToStderr((unsigned char *) data.data(), data.size());
writeFull(fdLogFile, (unsigned char *) data.data(), data.size());
if (bzLogFile) {
int err;
BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());
if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err);
} else if (fdLogFile != -1)
writeFull(fdLogFile, (unsigned char *) data.data(), data.size());
}
if (hook && fd == hook->fromHook.readSide)
@@ -2109,6 +2234,7 @@ bool DerivationGoal::pathFailed(const Path & path)
if (printBuildTrace)
printMsg(lvlError, format("@ build-failed %1% %2% cached") % drvPath % path);
worker.permanentFailure = true;
amDone(ecFailed);
return true;
@@ -2166,6 +2292,8 @@ public:
/* Callback used by the worker to write to the log. */
void handleChildOutput(int fd, const string & data);
void handleEOF(int fd);
Path getStorePath() { return storePath; }
};
@@ -2829,7 +2957,7 @@ unsigned int Worker::exitStatus()
//////////////////////////////////////////////////////////////////////
void LocalStore::buildDerivations(const PathSet & drvPaths)
void LocalStore::buildPaths(const PathSet & drvPaths)
{
startNest(nest, lvlDebug,
format("building %1%") % showPaths(drvPaths));
@@ -2838,7 +2966,10 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
Goals goals;
foreach (PathSet::const_iterator, i, drvPaths)
goals.insert(worker.makeDerivationGoal(*i));
if (isDerivation(*i))
goals.insert(worker.makeDerivationGoal(*i));
else
goals.insert(worker.makeSubstitutionGoal(*i));
worker.run(goals);
@@ -2846,8 +2977,8 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
foreach (Goals::iterator, i, goals)
if ((*i)->getExitCode() == Goal::ecFailed) {
DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i->get());
assert(i2);
failed.insert(i2->getDrvPath());
if (i2) failed.insert(i2->getDrvPath());
else failed.insert(dynamic_cast<SubstitutionGoal *>(i->get())->getStorePath());
}
if (!failed.empty())
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __DERIVATIONS_H
#define __DERIVATIONS_H
#pragma once
#include <map>
@@ -81,6 +80,3 @@ typedef std::map<Path, Hash> DrvHashes;
extern DrvHashes drvHashes;
}
#endif /* !__DERIVATIONS_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __GLOBALS_H
#define __GLOBALS_H
#pragma once
#include "types.hh"
@@ -118,6 +117,3 @@ void setDefaultsFromEnvironment();
}
#endif /* !__GLOBALS_H */
+43 -1
View File
@@ -195,7 +195,7 @@ void checkStoreNotSymlink()
}
LocalStore::LocalStore()
LocalStore::LocalStore(bool reserveSpace)
{
substitutablePathsLoaded = false;
@@ -221,6 +221,24 @@ LocalStore::LocalStore()
checkStoreNotSymlink();
/* We can't open a SQLite database if the disk is full. Since
this prevents the garbage collector from running when it's most
needed, we reserve some dummy space that we can free just
before doing a garbage collection. */
try {
Path reservedPath = nixDBPath + "/reserved";
if (reserveSpace) {
int reservedSize = queryIntSetting("gc-reserved-space", 1024 * 1024);
struct stat st;
if (stat(reservedPath.c_str(), &st) == -1 ||
st.st_size != reservedSize)
writeFile(reservedPath, string(reservedSize, 'X'));
}
else
deletePath(reservedPath);
} catch (SysError & e) { /* don't care about errors */
}
/* Acquire the big fat lock in shared mode to make sure that no
schema upgrade is in progress. */
try {
@@ -387,6 +405,10 @@ void LocalStore::openDB(bool create)
"select v.id, v.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where d.path = ?;");
stmtQueryDerivationOutputs.create(db,
"select id, path from DerivationOutputs where drv = ?;");
// Use "path >= ?" with limit 1 rather than "path like '?%'" to
// ensure efficient lookup.
stmtQueryPathFromHashPart.create(db,
"select path from ValidPaths where path >= ? limit 1;");
}
@@ -847,6 +869,26 @@ StringSet LocalStore::queryDerivationOutputNames(const Path & path)
}
Path LocalStore::queryPathFromHashPart(const string & hashPart)
{
if (hashPart.size() != 32) throw Error("invalid hash part");
SQLiteTxn txn(db);
Path prefix = nixStore + "/" + hashPart;
SQLiteStmtUse use(stmtQueryPathFromHashPart);
stmtQueryPathFromHashPart.bind(prefix);
int res = sqlite3_step(stmtQueryPathFromHashPart);
if (res == SQLITE_DONE) return "";
if (res != SQLITE_ROW) throwSQLiteError(db, "finding path in database");
const char * s = (const char *) sqlite3_column_text(stmtQueryPathFromHashPart, 0);
return s && prefix.compare(0, prefix.size(), s, prefix.size()) == 0 ? s : "";
}
void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run)
{
if (run.pid != -1) return;
+6 -7
View File
@@ -1,5 +1,4 @@
#ifndef __LOCAL_STORE_H
#define __LOCAL_STORE_H
#pragma once
#include <string>
@@ -91,7 +90,7 @@ public:
/* Initialise the local store, upgrading the schema if
necessary. */
LocalStore();
LocalStore(bool reserveSpace = true);
~LocalStore();
@@ -121,6 +120,8 @@ public:
StringSet queryDerivationOutputNames(const Path & path);
Path queryPathFromHashPart(const string & hashPart);
PathSet querySubstitutablePaths();
bool hasSubstitutes(const Path & path);
@@ -150,7 +151,7 @@ public:
Paths importPaths(bool requireSignature, Source & source);
void buildDerivations(const PathSet & drvPaths);
void buildPaths(const PathSet & paths);
void ensurePath(const Path & path);
@@ -217,6 +218,7 @@ private:
SQLiteStmt stmtAddDerivationOutput;
SQLiteStmt stmtQueryValidDerivers;
SQLiteStmt stmtQueryDerivationOutputs;
SQLiteStmt stmtQueryPathFromHashPart;
int getSchema();
@@ -299,6 +301,3 @@ void deletePathWrapped(const Path & path,
void deletePathWrapped(const Path & path);
}
#endif /* !__LOCAL_STORE_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __MISC_H
#define __MISC_H
#pragma once
#include "derivations.hh"
@@ -35,6 +34,3 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
}
#endif /* !__MISC_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __PATHLOCKS_H
#define __PATHLOCKS_H
#pragma once
#include "types.hh"
@@ -44,6 +43,3 @@ bool pathIsLockedByMe(const Path & path);
}
#endif /* !__PATHLOCKS_H */
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __REFERENCES_H
#define __REFERENCES_H
#pragma once
#include "types.hh"
#include "hash.hh"
@@ -10,5 +9,3 @@ PathSet scanForReferences(const Path & path, const PathSet & refs,
HashResult & hash);
}
#endif /* !__REFERENCES_H */
+18 -4
View File
@@ -43,7 +43,7 @@ RemoteStore::RemoteStore()
}
void RemoteStore::openConnection()
void RemoteStore::openConnection(bool reserveSpace)
{
if (initialised) return;
initialised = true;
@@ -75,6 +75,8 @@ void RemoteStore::openConnection()
if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
throw Error("Nix daemon protocol version not supported");
writeInt(PROTOCOL_VERSION, to);
if (GET_PROTOCOL_MINOR(daemonVersion) >= 11)
writeInt(reserveSpace, to);
processStderr();
}
catch (Error & e) {
@@ -339,6 +341,18 @@ PathSet RemoteStore::queryDerivationOutputNames(const Path & path)
}
Path RemoteStore::queryPathFromHashPart(const string & hashPart)
{
openConnection();
writeInt(wopQueryPathFromHashPart, to);
writeString(hashPart, to);
processStderr();
Path path = readString(from);
if (!path.empty()) assertStorePath(path);
return path;
}
Path RemoteStore::addToStore(const Path & _srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter)
{
@@ -395,10 +409,10 @@ Paths RemoteStore::importPaths(bool requireSignature, Source & source)
}
void RemoteStore::buildDerivations(const PathSet & drvPaths)
void RemoteStore::buildPaths(const PathSet & drvPaths)
{
openConnection();
writeInt(wopBuildDerivations, to);
writeInt(wopBuildPaths, to);
writeStrings(drvPaths, to);
processStderr();
readInt(from);
@@ -462,7 +476,7 @@ Roots RemoteStore::findRoots()
void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results)
{
openConnection();
openConnection(false);
writeInt(wopCollectGarbage, to);
writeInt(options.action, to);
+5 -7
View File
@@ -1,5 +1,4 @@
#ifndef __REMOTE_STORE_H
#define __REMOTE_STORE_H
#pragma once
#include <string>
@@ -43,6 +42,8 @@ public:
StringSet queryDerivationOutputNames(const Path & path);
Path queryPathFromHashPart(const string & hashPart);
bool hasSubstitutes(const Path & path);
bool querySubstitutablePathInfo(const Path & path,
@@ -60,7 +61,7 @@ public:
Paths importPaths(bool requireSignature, Source & source);
void buildDerivations(const PathSet & drvPaths);
void buildPaths(const PathSet & paths);
void ensurePath(const Path & path);
@@ -86,7 +87,7 @@ private:
unsigned int daemonVersion;
bool initialised;
void openConnection();
void openConnection(bool reserveSpace = true);
void processStderr(Sink * sink = 0, Source * source = 0);
@@ -99,6 +100,3 @@ private:
}
#endif /* !__REMOTE_STORE_H */
+2 -2
View File
@@ -322,10 +322,10 @@ namespace nix {
boost::shared_ptr<StoreAPI> store;
boost::shared_ptr<StoreAPI> openStore()
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace)
{
if (getEnv("NIX_REMOTE") == "")
return boost::shared_ptr<StoreAPI>(new LocalStore());
return boost::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
else
return boost::shared_ptr<StoreAPI>(new RemoteStore());
}
+11 -9
View File
@@ -1,5 +1,4 @@
#ifndef __STOREAPI_H
#define __STOREAPI_H
#pragma once
#include "hash.hh"
#include "serialise.hh"
@@ -139,6 +138,10 @@ public:
/* Query the output names of the derivation denoted by `path'. */
virtual StringSet queryDerivationOutputNames(const Path & path) = 0;
/* Query the full store path given the hash part of a valid store
path, or "" if the path doesn't exist. */
virtual Path queryPathFromHashPart(const string & hashPart) = 0;
/* Query whether a path has substitutes. */
virtual bool hasSubstitutes(const Path & path) = 0;
@@ -172,13 +175,15 @@ public:
the Nix store. */
virtual Paths importPaths(bool requireSignature, Source & source) = 0;
/* Ensure that the output paths of the derivation are valid. If
/* For each path, if it's a derivation, build it. Building a
derivation means ensuring that the output paths are valid. If
they are already valid, this is a no-op. Otherwise, validity
can be reached in two ways. First, if the output paths is
substitutable, then build the path that way. Second, the
output paths can be created by running the builder, after
recursively building any sub-derivations. */
virtual void buildDerivations(const PathSet & drvPaths) = 0;
recursively building any sub-derivations. For inputs that are
not derivations, substitute them. */
virtual void buildPaths(const PathSet & paths) = 0;
/* Ensure that a path is valid. If it is not currently valid, it
may be made valid by running a substitute (if defined for the
@@ -327,7 +332,7 @@ extern boost::shared_ptr<StoreAPI> store;
/* Factory method: open the Nix database, either through the local or
remote implementation. */
boost::shared_ptr<StoreAPI> openStore();
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace = true);
/* Display a set of paths in human-readable form (i.e., between quotes
@@ -350,6 +355,3 @@ MakeError(BuildError, Error) /* denotes a permanent build failure */
}
#endif /* !__STOREAPI_H */
+4 -8
View File
@@ -1,6 +1,4 @@
#ifndef __WORKER_PROTOCOL_H
#define __WORKER_PROTOCOL_H
#pragma once
namespace nix {
@@ -8,7 +6,7 @@ namespace nix {
#define WORKER_MAGIC_1 0x6e697863
#define WORKER_MAGIC_2 0x6478696f
#define PROTOCOL_VERSION 0x10a
#define PROTOCOL_VERSION 0x10b
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
@@ -22,7 +20,7 @@ typedef enum {
wopQueryReferrers = 6,
wopAddToStore = 7,
wopAddTextToStore = 8,
wopBuildDerivations = 9,
wopBuildPaths = 9,
wopEnsurePath = 10,
wopAddTempRoot = 11,
wopAddIndirectRoot = 12,
@@ -40,6 +38,7 @@ typedef enum {
wopQueryPathInfo = 26,
wopImportPaths = 27,
wopQueryDerivationOutputNames = 28,
wopQueryPathFromHashPart = 29,
} WorkerOp;
@@ -63,6 +62,3 @@ template<class T> T readStorePaths(Source & from);
}
#endif /* !__WORKER_PROTOCOL_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __ARCHIVE_H
#define __ARCHIVE_H
#pragma once
#include "types.hh"
#include "serialise.hh"
@@ -74,6 +73,3 @@ void restorePath(const Path & path, Source & source);
}
#endif /* !__ARCHIVE_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __HASH_H
#define __HASH_H
#pragma once
#include "types.hh"
#include "serialise.hh"
@@ -109,6 +108,3 @@ public:
}
#endif /* !__HASH_H */
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __IMMUTABLE_H
#define __IMMUTABLE_H
#pragma once
#include <types.hh>
@@ -15,5 +14,3 @@ void makeImmutable(const Path & path);
void makeMutable(const Path & path);
}
#endif /* !__IMMUTABLE_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __SERIALISE_H
#define __SERIALISE_H
#pragma once
#include "types.hh"
@@ -130,6 +129,3 @@ MakeError(SerialisationError, Error)
}
#endif /* !__SERIALISE_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __TYPES_H
#define __TYPES_H
#pragma once
#include <string>
#include <list>
@@ -74,6 +73,3 @@ typedef enum {
}
#endif /* !__TYPES_H */
+5 -2
View File
@@ -779,8 +779,11 @@ void Pid::kill()
int status;
while (waitpid(pid, &status, 0) == -1) {
checkInterrupt();
if (errno != EINTR) printMsg(lvlError,
(SysError(format("waiting for process %1%") % pid).msg()));
if (errno != EINTR) {
printMsg(lvlError,
(SysError(format("waiting for process %1%") % pid).msg()));
break;
}
}
pid = -1;
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __UTIL_H
#define __UTIL_H
#pragma once
#include "types.hh"
@@ -333,6 +332,3 @@ void ignoreException();
}
#endif /* !__UTIL_H */
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __XML_WRITER_H
#define __XML_WRITER_H
#pragma once
#include <iostream>
#include <string>
@@ -70,6 +69,3 @@ public:
}
#endif /* !__XML_WRITER_H */
+1 -1
View File
@@ -695,7 +695,7 @@ static void opSet(Globals & globals,
PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state));
printMissing(*store, paths);
if (globals.dryRun) return;
store->buildDerivations(paths);
store->buildPaths(paths);
}
else {
printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state)));
+1 -5
View File
@@ -1,5 +1,4 @@
#ifndef __PROFILES_H
#define __PROFILES_H
#pragma once
#include "types.hh"
#include "pathlocks.hh"
@@ -54,6 +53,3 @@ void lockProfile(PathLocks & lock, const Path & profile);
string optimisticLockProfile(const Path & profile);
}
#endif /* !__PROFILES_H */
+2 -2
View File
@@ -45,7 +45,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
drvsToBuild.insert(i->queryDrvPath(state));
debug(format("building user environment dependencies"));
store->buildDerivations(drvsToBuild);
store->buildPaths(drvsToBuild);
/* Construct the whole top level derivation. */
PathSet references;
@@ -132,7 +132,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
/* Realise the resulting store expression. */
debug("building user environment");
store->buildDerivations(singleton<PathSet>(topLevelDrv.queryDrvPath(state)));
store->buildPaths(singleton<PathSet>(topLevelDrv.queryDrvPath(state)));
/* Switch the current user environment to the output path. */
PathLocks lock;
+1 -8
View File
@@ -1,5 +1,4 @@
#ifndef __USER_ENV_H
#define __USER_ENV_H
#pragma once
#include "get-drvs.hh"
@@ -12,9 +11,3 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
const string & lockToken);
}
#endif /* !__USER_ENV_H */
+1 -1
View File
@@ -5,7 +5,7 @@ nix_store_SOURCES = \
xmlgraph.cc xmlgraph.hh
nix_store_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
../boost/format/libformat.la
../boost/format/libformat.la -lbz2
nix-store.o: help.txt.hh
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __DOTGRAPH_H
#define __DOTGRAPH_H
#pragma once
#include "types.hh"
@@ -8,5 +7,3 @@ namespace nix {
void printDotGraph(const PathSet & roots);
}
#endif /* !__DOTGRAPH_H */
+39 -16
View File
@@ -10,6 +10,13 @@
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <bzlib.h>
using namespace nix;
@@ -55,7 +62,7 @@ static Path useDeriver(Path path)
static PathSet realisePath(const Path & path)
{
if (isDerivation(path)) {
store->buildDerivations(singleton<PathSet>(path));
store->buildPaths(singleton<PathSet>(path));
Derivation drv = derivationFromPath(*store, path);
PathSet outputs;
@@ -94,13 +101,11 @@ static void opRealise(Strings opFlags, Strings opArgs)
if (dryRun) return;
/* Build all derivations at the same time to exploit parallelism. */
PathSet drvPaths;
foreach (Strings::iterator, i, opArgs)
if (isDerivation(*i)) drvPaths.insert(*i);
store->buildDerivations(drvPaths);
/* Build all paths at the same time to exploit parallelism. */
PathSet paths(opArgs.begin(), opArgs.end());
store->buildPaths(paths);
foreach (Strings::iterator, i, opArgs) {
foreach (Paths::iterator, i, opArgs) {
PathSet paths = realisePath(*i);
foreach (PathSet::iterator, j, paths)
cout << format("%1%\n") % *j;
@@ -419,20 +424,38 @@ static void opReadLog(Strings opFlags, Strings opArgs)
{
if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
foreach (Strings::iterator, i, opArgs) {
Path path = useDeriver(followLinksToStorePath(*i));
Path logPath = (format("%1%/%2%/%3%") %
nixLogDir % drvsLogDir % baseNameOf(path)).str();
Path logBz2Path = logPath + ".bz2";
if (!pathExists(logPath))
throw Error(format("build log of derivation `%1%' is not available") % path);
if (pathExists(logPath)) {
/* !!! Make this run in O(1) memory. */
string log = readFile(logPath);
writeFull(STDOUT_FILENO, (const unsigned char *) log.data(), log.size());
}
/* !!! Make this run in O(1) memory. */
string log = readFile(logPath);
writeFull(STDOUT_FILENO, (const unsigned char *) log.data(), log.size());
else if (pathExists(logBz2Path)) {
AutoCloseFD fd = open(logBz2Path.c_str(), O_RDONLY);
FILE * f = 0;
if (fd == -1 || (f = fdopen(fd.borrow(), "r")) == 0)
throw SysError(format("opening file `%1%'") % logBz2Path);
int err;
BZFILE * bz = BZ2_bzReadOpen(&err, f, 0, 0, 0, 0);
if (!bz) throw Error(format("cannot open bzip2 file `%1%'") % logBz2Path);
unsigned char buf[128 * 1024];
do {
int n = BZ2_bzRead(&err, bz, buf, sizeof(buf));
if (err != BZ_OK && err != BZ_STREAM_END)
throw Error(format("error reading bzip2 file `%1%'") % logBz2Path);
writeFull(STDOUT_FILENO, buf, n);
} while (err != BZ_STREAM_END);
BZ2_bzReadClose(&err, bz);
}
else throw Error(format("build log of derivation `%1%' is not available") % path);
}
}
@@ -843,7 +866,7 @@ void run(Strings args)
if (!op) throw UsageError("no operation specified");
if (op != opDump && op != opRestore) /* !!! hack */
store = openStore();
store = openStore(op != opGC);
op(opFlags, opArgs);
}
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef __XMLGRAPH_H
#define __XMLGRAPH_H
#pragma once
#include "types.hh"
@@ -8,5 +7,3 @@ namespace nix {
void printXmlGraph(const PathSet & roots);
}
#endif /* !__XMLGRAPH_H */
+69 -40
View File
@@ -350,6 +350,15 @@ static void performOp(unsigned int clientVersion,
break;
}
case wopQueryPathFromHashPart: {
string hashPart = readString(from);
startWork();
Path path = store->queryPathFromHashPart(hashPart);
stopWork();
writeString(path, to);
break;
}
case wopAddToStore: {
string baseName = readString(from);
bool fixed = readInt(from) == 1; /* obsolete */
@@ -415,10 +424,10 @@ static void performOp(unsigned int clientVersion,
break;
}
case wopBuildDerivations: {
case wopBuildPaths: {
PathSet drvs = readStorePaths<PathSet>(from);
startWork();
store->buildDerivations(drvs);
store->buildPaths(drvs);
stopWork();
writeInt(1, to);
break;
@@ -625,8 +634,12 @@ static void processConnection()
throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!");
#endif
bool reserveSpace = true;
if (GET_PROTOCOL_MINOR(clientVersion) >= 11)
reserveSpace = readInt(from) != 0;
/* Open the store. */
store = boost::shared_ptr<StoreAPI>(new LocalStore());
store = boost::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
stopWork();
to.flush();
@@ -691,51 +704,67 @@ static void setSigChldAction(bool autoReap)
}
#define SD_LISTEN_FDS_START 3
static void daemonLoop()
{
/* Get rid of children automatically; don't let them become
zombies. */
setSigChldAction(true);
AutoCloseFD fdSocket;
/* Handle socket-based activation by systemd. */
if (getEnv("LISTEN_FDS") != "") {
if (getEnv("LISTEN_PID") != int2String(getpid()) || getEnv("LISTEN_FDS") != "1")
throw Error("unexpected systemd environment variables");
fdSocket = SD_LISTEN_FDS_START;
}
/* Otherwise, create and bind to a Unix domain socket. */
else {
/* Create and bind to a Unix domain socket. */
AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
if (fdSocket == -1)
throw SysError("cannot create Unix domain socket");
/* Create and bind to a Unix domain socket. */
fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
if (fdSocket == -1)
throw SysError("cannot create Unix domain socket");
string socketPath = nixStateDir + DEFAULT_SOCKET_PATH;
createDirs(dirOf(socketPath));
/* Urgh, sockaddr_un allows path names of only 108 characters.
So chdir to the socket directory so that we can pass a
relative path name. */
chdir(dirOf(socketPath).c_str());
Path socketPathRel = "./" + baseNameOf(socketPath);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
if (socketPathRel.size() >= sizeof(addr.sun_path))
throw Error(format("socket path `%1%' is too long") % socketPathRel);
strcpy(addr.sun_path, socketPathRel.c_str());
unlink(socketPath.c_str());
/* Make sure that the socket is created with 0666 permission
(everybody can connect --- provided they have access to the
directory containing the socket). */
mode_t oldMode = umask(0111);
int res = bind(fdSocket, (struct sockaddr *) &addr, sizeof(addr));
umask(oldMode);
if (res == -1)
throw SysError(format("cannot bind to socket `%1%'") % socketPath);
chdir("/"); /* back to the root */
if (listen(fdSocket, 5) == -1)
throw SysError(format("cannot listen on socket `%1%'") % socketPath);
}
closeOnExec(fdSocket);
string socketPath = nixStateDir + DEFAULT_SOCKET_PATH;
createDirs(dirOf(socketPath));
/* Urgh, sockaddr_un allows path names of only 108 characters. So
chdir to the socket directory so that we can pass a relative
path name. */
chdir(dirOf(socketPath).c_str());
Path socketPathRel = "./" + baseNameOf(socketPath);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
if (socketPathRel.size() >= sizeof(addr.sun_path))
throw Error(format("socket path `%1%' is too long") % socketPathRel);
strcpy(addr.sun_path, socketPathRel.c_str());
unlink(socketPath.c_str());
/* Make sure that the socket is created with 0666 permission
(everybody can connect --- provided they have access to the
directory containing the socket). */
mode_t oldMode = umask(0111);
int res = bind(fdSocket, (struct sockaddr *) &addr, sizeof(addr));
umask(oldMode);
if (res == -1)
throw SysError(format("cannot bind to socket `%1%'") % socketPath);
chdir("/"); /* back to the root */
if (listen(fdSocket, 5) == -1)
throw SysError(format("cannot listen on socket `%1%'") % socketPath);
/* Loop accepting connections. */
while (1) {
+2 -1
View File
@@ -9,7 +9,7 @@ TESTS = init.sh hash.sh lang.sh add.sh simple.sh dependencies.sh \
gc-runtime.sh install-package.sh check-refs.sh filter-source.sh \
remote-store.sh export.sh export-graph.sh negative-caching.sh \
binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
multiple-outputs.sh import-derivation.sh
multiple-outputs.sh import-derivation.sh fetchurl.sh
XFAIL_TESTS =
@@ -38,6 +38,7 @@ EXTRA_DIST = $(TESTS) \
secure-drv-outputs.nix \
multiple-outputs.nix \
import-derivation.nix \
fetchurl.nix \
$(wildcard lang/*.nix) $(wildcard lang/*.exp) $(wildcard lang/*.exp.xml) $(wildcard lang/*.flags) $(wildcard lang/dir*/*.nix) \
common.sh.in
+6
View File
@@ -0,0 +1,6 @@
{ filename, sha256 }:
import <nix/fetchurl.nix> {
url = "file://${filename}";
inherit sha256;
}
+9
View File
@@ -0,0 +1,9 @@
source common.sh
clearStore
hash=$(nix-hash --flat --type sha256 ./fetchurl.nix)
outPath=$(nix-build ./fetchurl.nix --argstr filename $(pwd)/fetchurl.nix --argstr sha256 $hash)
cmp $outPath fetchurl.nix
+1 -1
View File
@@ -1 +1 @@
1.0
1.1