Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98193bb440 | ||
|
|
b7fd2c2822 | ||
|
|
58337e0e61 | ||
|
|
ccc52adfb2 | ||
|
|
220818f758 | ||
|
|
3a9fdf2747 | ||
|
|
1217204c81 | ||
|
|
51d71ad3d7 | ||
|
|
6c01fb4d68 | ||
|
|
53b24f3518 | ||
|
|
a7a43adb79 | ||
|
|
eae802459d | ||
|
|
2dd3117c27 | ||
|
|
51f9f9924b | ||
|
|
035aa11403 | ||
|
|
a2865f6b3d | ||
|
|
53f52c2111 | ||
|
|
543bf742c9 | ||
|
|
f863673a90 | ||
|
|
a994eb92a4 | ||
|
|
9d94a28bed | ||
|
|
fd2630e1f7 | ||
|
|
6450f5699f | ||
|
|
40c01ec467 | ||
|
|
c4df747267 | ||
|
|
27f0c34390 | ||
|
|
a560124cdf | ||
|
|
087dee6e1b | ||
|
|
5755a5c354 | ||
|
|
1aba0bf0fa | ||
|
|
42f5a2fc29 | ||
|
|
3ee208516f | ||
|
|
1db38ae81b | ||
|
|
5489086456 | ||
|
|
8da6772ed4 | ||
|
|
723a68c826 | ||
|
|
7ffa523fd1 | ||
|
|
df716c98d2 | ||
|
|
2f3f413e91 | ||
|
|
02fb6323e0 | ||
|
|
221626e715 | ||
|
|
a7ed1f67ee | ||
|
|
8922346305 | ||
|
|
6a214f3e06 | ||
|
|
d0308073c3 | ||
|
|
e545a7f9a8 | ||
|
|
f5398d374b | ||
|
|
881beb170d | ||
|
|
4bc4da331a | ||
|
|
2c26985835 | ||
|
|
8058dab26e | ||
|
|
0301525e6c | ||
|
|
6814b1dfa1 | ||
|
|
591aab7e21 | ||
|
|
e071f87dc5 | ||
|
|
cac9eb39fe |
@@ -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
@@ -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)/
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -9,5 +9,6 @@ in {
|
||||
bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
|
||||
tar = "@tar@";
|
||||
tr = "@tr@";
|
||||
curl = "@curl@";
|
||||
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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, it’s
|
||||
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 evaluator’s 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 evaluator’s 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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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 <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>
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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,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,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,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 */
|
||||
|
||||
@@ -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
@@ -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 +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
@@ -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 +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 */
|
||||
|
||||
@@ -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,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,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,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 +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 */
|
||||
|
||||
@@ -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
@@ -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 +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 +1,4 @@
|
||||
#ifndef __GLOBALS_H
|
||||
#define __GLOBALS_H
|
||||
#pragma once
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
@@ -118,6 +117,3 @@ void setDefaultsFromEnvironment();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* !__GLOBALS_H */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 +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 +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,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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 +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
@@ -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,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 +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 +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
@@ -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
@@ -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 +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 */
|
||||
|
||||
@@ -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 +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 */
|
||||
|
||||
@@ -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,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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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,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
@@ -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,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 */
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{ filename, sha256 }:
|
||||
|
||||
import <nix/fetchurl.nix> {
|
||||
url = "file://${filename}";
|
||||
inherit sha256;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user