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.cc
|
||||||
/src/libexpr/parser-tab.hh
|
/src/libexpr/parser-tab.hh
|
||||||
/src/libexpr/parser-tab.output
|
/src/libexpr/parser-tab.output
|
||||||
/src/libexpr/nixexpr-ast.hh
|
|
||||||
/src/libexpr/nixexpr-ast.cc
|
|
||||||
/src/libexpr/nix.tbl
|
/src/libexpr/nix.tbl
|
||||||
|
|
||||||
# /src/libstore/
|
# /src/libstore/
|
||||||
/src/libstore/derivations-ast.cc
|
|
||||||
/src/libstore/derivations-ast.hh
|
|
||||||
/src/libstore/schema.sql.hh
|
/src/libstore/schema.sql.hh
|
||||||
|
|
||||||
# /src/nix-env/
|
# /src/nix-env/
|
||||||
|
|||||||
+1
-5
@@ -1,6 +1,6 @@
|
|||||||
SUBDIRS = src perl scripts corepkgs doc misc tests
|
SUBDIRS = src perl scripts corepkgs doc misc tests
|
||||||
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
|
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
|
pkginclude_HEADERS = config.h
|
||||||
|
|
||||||
@@ -10,10 +10,6 @@ nix.spec: nix.spec.in
|
|||||||
|
|
||||||
install-data-local: init-state
|
install-data-local: init-state
|
||||||
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix
|
$(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) -d $(DESTDIR)$(docdir)
|
||||||
$(INSTALL_DATA) README $(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
|
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-exec-local:
|
||||||
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
|
$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ in {
|
|||||||
bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
|
bzip2 = fromEnv "NIX_BZIP2" "@bzip2@";
|
||||||
tar = "@tar@";
|
tar = "@tar@";
|
||||||
tr = "@tr@";
|
tr = "@tr@";
|
||||||
|
curl = "@curl@";
|
||||||
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
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-prefetch-url.1 nix-channel.1 \
|
||||||
nix-install-package.1 nix-hash.1 nix-copy-closure.1
|
nix-install-package.1 nix-hash.1 nix-copy-closure.1
|
||||||
|
|
||||||
|
man5_MANS = nix.conf.5
|
||||||
|
|
||||||
man8_MANS = nix-worker.8
|
man8_MANS = nix-worker.8
|
||||||
|
|
||||||
FIGURES = figures/user-environments.png
|
FIGURES = figures/user-environments.png
|
||||||
|
|||||||
+43
-11
@@ -1,27 +1,36 @@
|
|||||||
<section xmlns="http://docbook.org/ns/docbook"
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xml:id="sec-conf-file">
|
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
|
<para>A number of persistent settings of Nix are stored in the file
|
||||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>.
|
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>.
|
||||||
This file is a list of <literal><replaceable>name</replaceable> =
|
This file is a list of <literal><replaceable>name</replaceable> =
|
||||||
<replaceable>value</replaceable></literal> pairs, one per line.
|
<replaceable>value</replaceable></literal> pairs, one per line.
|
||||||
Comments start with a <literal>#</literal> character. An example
|
Comments start with a <literal>#</literal> character. Here is an example
|
||||||
configuration file is shown in <xref linkend="ex-nix-conf" />.</para>
|
configuration file:</para>
|
||||||
|
|
||||||
<example xml:id='ex-nix-conf'><title>Nix configuration file</title>
|
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
gc-keep-outputs = true # Nice for developers
|
gc-keep-outputs = true # Nice for developers
|
||||||
gc-keep-derivations = true # Idem
|
gc-keep-derivations = true # Idem
|
||||||
env-keep-derivations = false
|
env-keep-derivations = false
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>The following variables are currently available:
|
<para>The following settings are currently available:
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
@@ -276,6 +285,28 @@ build-use-chroot = /dev /proc /bin</programlisting>
|
|||||||
</varlistentry>
|
</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>
|
<varlistentry><term><literal>system</literal></term>
|
||||||
|
|
||||||
<listitem><para>This option specifies the canonical Nix system
|
<listitem><para>This option specifies the canonical Nix system
|
||||||
@@ -311,5 +342,6 @@ build-use-chroot = /dev /proc /bin</programlisting>
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
</section>
|
</refentry>
|
||||||
|
|||||||
+148
-96
@@ -40,11 +40,155 @@ platforms as well.</para>
|
|||||||
</section>
|
</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
|
<para>The easiest way to install Nix is to use a binary package.
|
||||||
xlink:href="http://nixos.org/">source distribution</link>. RPMs
|
Binary packages of the latest stable release are available for Fedora,
|
||||||
for Red Hat, SuSE, and Fedora Core are also available.</para>
|
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
|
<para>Alternatively, the most recent sources of Nix can be obtained
|
||||||
from its <link
|
from its <link
|
||||||
@@ -63,71 +207,6 @@ repository.</para>
|
|||||||
</section>
|
</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>
|
<section><title>Building Nix from source</title>
|
||||||
|
|
||||||
<para>After unpacking or checking out the Nix sources, issue the
|
<para>After unpacking or checking out the Nix sources, issue the
|
||||||
@@ -180,33 +259,6 @@ options.</para>
|
|||||||
</section>
|
</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>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ href="docs/papers.html#servicecm">SCM-12 paper</a>.</para>
|
|||||||
<simplesect><title>Portability</title>
|
<simplesect><title>Portability</title>
|
||||||
|
|
||||||
<para>Nix should run on most Unix systems, including Linux, FreeBSD and
|
<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>
|
</simplesect>
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
<title>Command Reference</title>
|
<title>Command Reference</title>
|
||||||
<xi:include href="opt-common.xml" />
|
<xi:include href="opt-common.xml" />
|
||||||
<xi:include href="env-common.xml" />
|
<xi:include href="env-common.xml" />
|
||||||
<xi:include href="conf-file.xml" />
|
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Main commands</title>
|
<title>Main commands</title>
|
||||||
@@ -63,6 +62,11 @@
|
|||||||
<xi:include href="nix-worker.xml" />
|
<xi:include href="nix-worker.xml" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Files</title>
|
||||||
|
<xi:include href="conf-file.xml" />
|
||||||
|
</section>
|
||||||
|
|
||||||
</appendix>
|
</appendix>
|
||||||
|
|
||||||
<xi:include href="troubleshooting.xml" />
|
<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>
|
<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 ""
|
%global nixbld_user "nix-builder-"
|
||||||
%define nix_user "nix"
|
%global nixbld_group "nix-builders"
|
||||||
%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 ""
|
|
||||||
|
|
||||||
Summary: The Nix software deployment system
|
Summary: The Nix software deployment system
|
||||||
Name: nix
|
Name: nix
|
||||||
Version: @version@
|
Version: @version@
|
||||||
Release: 1
|
Release: 2%{?dist}
|
||||||
License: GPL
|
License: LGPLv2+
|
||||||
Group: Software Deployment
|
%if 0%{?rhel}
|
||||||
|
Group: Applications/System
|
||||||
|
%endif
|
||||||
URL: http://nixos.org/
|
URL: http://nixos.org/
|
||||||
Source0: %{name}-@version@.tar.bz2
|
Source0: %{name}-%{version}.tar.bz2
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
|
%if 0%{?el5}
|
||||||
Prefix: /usr
|
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: /usr/bin/perl
|
||||||
Requires: curl
|
Requires: curl
|
||||||
Requires: perl-DBD-SQLite
|
Requires: perl-DBD-SQLite
|
||||||
Requires: perl-devel
|
|
||||||
Requires: bzip2
|
Requires: bzip2
|
||||||
Requires: bzip2-libs
|
|
||||||
Requires: sqlite
|
|
||||||
BuildRequires: bzip2-devel
|
BuildRequires: bzip2-devel
|
||||||
BuildRequires: sqlite-devel
|
BuildRequires: sqlite-devel
|
||||||
|
|
||||||
@@ -31,7 +28,6 @@ BuildRequires: sqlite-devel
|
|||||||
Provides: perl(Nix::SSH)
|
Provides: perl(Nix::SSH)
|
||||||
|
|
||||||
%description
|
%description
|
||||||
|
|
||||||
Nix is a purely functional package manager. It allows multiple
|
Nix is a purely functional package manager. It allows multiple
|
||||||
versions of a package to be installed side-by-side, ensures that
|
versions of a package to be installed side-by-side, ensures that
|
||||||
dependency specifications are complete, supports atomic upgrades and
|
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
|
other features. It is the basis of the NixOS Linux distribution, but
|
||||||
it can be used equally well under other Unix systems.
|
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
|
%prep
|
||||||
%setup -q
|
%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
|
%build
|
||||||
extraFlags=
|
extraFlags=
|
||||||
if test -n "%{enable_setuid}"; then
|
# - override docdir so large documentation files are owned by the
|
||||||
extraFlags="$extraFlags --enable-setuid"
|
# -doc subpackage
|
||||||
if test -n "%{nix_user}"; then
|
# - set localstatedir by hand to the preferred nix value
|
||||||
extraFlags="$extraFlags --with-nix-user=%{nix_user}"
|
%configure --localstatedir=/nix/var \
|
||||||
fi
|
--docdir=%{_defaultdocdir}/%{name}-doc-%{version} \
|
||||||
if test -n "%{nix_group}"; then
|
$extraFlags
|
||||||
extraFlags="$extraFlags --with-nix-group=%{nix_group}"
|
make %{?_smp_flags}
|
||||||
fi
|
%{_emacs_bytecompile} misc/emacs/nix-mode.el
|
||||||
fi
|
|
||||||
./configure --prefix=%{_prefix} --sysconfdir=/etc $extraFlags
|
|
||||||
make
|
|
||||||
make check
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
|
%if 0%{?el5}
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
%endif
|
||||||
make DESTDIR=$RPM_BUILD_ROOT install
|
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
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
|
||||||
%pre
|
%pre
|
||||||
if test -n "%{nix_group_gid}"; then
|
getent group %{nixbld_group} >/dev/null || groupadd -r %{nixbld_group}
|
||||||
/usr/sbin/groupadd -g %{nix_group_gid} %{nix_group} || true
|
for i in $(seq 10);
|
||||||
fi
|
do
|
||||||
if test -n "%{nix_user_uid}"; then
|
getent passwd %{nixbld_user}$i >/dev/null || \
|
||||||
/usr/sbin/useradd -c "Nix" -u %{nix_user_uid} \
|
useradd -r -g %{nixbld_group} -G %{nixbld_group} -d /var/empty \
|
||||||
-s /sbin/nologin -r -d /var/empty %{nix_user} \
|
-s %{_sbindir}/nologin \
|
||||||
-g %{nix_group} || true
|
-c "Nix build user $i" %{nixbld_user}$i
|
||||||
fi
|
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
|
%files
|
||||||
#%defattr(-,root,root)
|
%doc COPYING AUTHORS README
|
||||||
%{_prefix}/bin
|
%{_bindir}/nix-*
|
||||||
%{_prefix}/lib
|
%dir %{_libdir}/nix
|
||||||
%{_prefix}/libexec
|
%{_libdir}/nix/*.so.*
|
||||||
%{_prefix}/include
|
%{perl_vendorarch}/*
|
||||||
%{_prefix}/share
|
%exclude %dir %{perl_vendorarch}/auto/
|
||||||
/etc/profile.d/nix.sh
|
%{_prefix}/libexec/*
|
||||||
/nix/var
|
%if ! 0%{?rhel}
|
||||||
/nix/store
|
%{_prefix}/lib/systemd/system/nix-worker.service
|
||||||
%config
|
%endif
|
||||||
/etc/nix
|
%{_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(
|
our @EXPORT = qw(
|
||||||
isValidPath queryReferences queryPathInfo queryDeriver queryPathHash
|
isValidPath queryReferences queryPathInfo queryDeriver queryPathHash
|
||||||
|
queryPathFromHashPart
|
||||||
topoSortPaths computeFSClosure followLinksToStorePath exportPaths
|
topoSortPaths computeFSClosure followLinksToStorePath exportPaths
|
||||||
hashPath hashFile hashString
|
hashPath hashFile hashString
|
||||||
addToStore makeFixedOutputPath
|
addToStore makeFixedOutputPath
|
||||||
|
|||||||
+13
-2
@@ -86,7 +86,7 @@ SV * queryDeriver(char * path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SV * queryPathInfo(char * path)
|
SV * queryPathInfo(char * path, int base32)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
doInit();
|
doInit();
|
||||||
@@ -95,7 +95,7 @@ SV * queryPathInfo(char * path)
|
|||||||
XPUSHs(&PL_sv_undef);
|
XPUSHs(&PL_sv_undef);
|
||||||
else
|
else
|
||||||
XPUSHs(sv_2mortal(newSVpv(info.deriver.c_str(), 0)));
|
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)));
|
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||||
mXPUSHi(info.registrationTime);
|
mXPUSHi(info.registrationTime);
|
||||||
mXPUSHi(info.narSize);
|
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, ...)
|
SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
|
|||||||
+35
-6
@@ -63,7 +63,7 @@ let
|
|||||||
|
|
||||||
|
|
||||||
build =
|
build =
|
||||||
{ system ? "i686-linux" }:
|
{ system ? "x86_64-linux" }:
|
||||||
|
|
||||||
with import nixpkgs { inherit system; };
|
with import nixpkgs { inherit system; };
|
||||||
|
|
||||||
@@ -80,9 +80,42 @@ let
|
|||||||
--enable-gc
|
--enable-gc
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
doInstallCheck = 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 =
|
coverage =
|
||||||
with import nixpkgs { system = "x86_64-linux"; };
|
with import nixpkgs { system = "x86_64-linux"; };
|
||||||
@@ -120,10 +153,6 @@ let
|
|||||||
rpm_fedora13x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora13x86_64) 50;
|
rpm_fedora13x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora13x86_64) 50;
|
||||||
rpm_fedora16i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora16i386) 50;
|
rpm_fedora16i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora16i386) 50;
|
||||||
rpm_fedora16x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora16x86_64) 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;
|
deb_debian60i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian60i386) 50;
|
||||||
@@ -163,7 +192,7 @@ let
|
|||||||
name = "nix-rpm-${diskImage.name}";
|
name = "nix-rpm-${diskImage.name}";
|
||||||
src = jobs.tarball;
|
src = jobs.tarball;
|
||||||
diskImage = (diskImageFun vmTools.diskImageFuns)
|
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;
|
memSize = 1024;
|
||||||
meta.schedulingPriority = prio;
|
meta.schedulingPriority = prio;
|
||||||
postRPMInstall = "cd /tmp/rpmout/BUILD/nix-* && make installcheck";
|
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-exec-local: download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl
|
||||||
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d
|
$(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) -d $(DESTDIR)$(libexecdir)/nix
|
||||||
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
|
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
|
||||||
$(INSTALL_PROGRAM) build-remote.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
|
export NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER
|
||||||
NIX_LINK="$HOME/.nix-profile"
|
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
|
||||||
|
|
||||||
if ! test -L "$NIX_LINK"; then
|
# Set up the per-user profile.
|
||||||
echo "creating $NIX_LINK" >&2
|
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
|
||||||
_NIX_DEF_LINK=@localstatedir@/nix/profiles/default
|
if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then
|
||||||
@coreutils@/ln -s "$_NIX_DEF_LINK" "$NIX_LINK"
|
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
|
fi
|
||||||
|
|
||||||
export PATH=$NIX_LINK/bin:$PATH
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# This is a quick hack to make fontconfig-based packages in Nixpkgs
|
export PATH="$HOME/.nix-profile/bin:$PATH"
|
||||||
# work out of the box on non-NixOS systems. Of course, we should
|
|
||||||
# really fix fontconfig...
|
# Subscribe the root user to the NixOS channel by default.
|
||||||
if test -z "$FONTCONFIG_FILE" -a -e /etc/fonts/fonts.conf; then
|
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
|
||||||
export FONTCONFIG_FILE=/etc/fonts/fonts.conf
|
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
|
fi
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
#ifndef __ATTR_PATH_H
|
#pragma once
|
||||||
#define __ATTR_PATH_H
|
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
Bindings & autoArgs, Expr * e, Value & v);
|
Bindings & autoArgs, Expr * e, Value & v);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__ATTR_PATH_H */
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#ifndef __COMMON_OPTS_H
|
#pragma once
|
||||||
#define __COMMON_OPTS_H
|
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
/* Some common option parsing between nix-env and nix-instantiate. */
|
/* 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);
|
Path lookupFileArg(EvalState & state, string s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__COMMON_OPTS_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __EVAL_INLINE_H
|
#pragma once
|
||||||
#define __EVAL_INLINE_H
|
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
|
||||||
@@ -8,7 +7,6 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s))
|
||||||
{
|
{
|
||||||
throw EvalError(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));
|
throwTypeError("value is %1% while a list was expected", showType(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__EVAL_INLINE_H */
|
|
||||||
|
|||||||
@@ -143,9 +143,7 @@ EvalState::EvalState()
|
|||||||
, staticBaseEnv(false, 0)
|
, staticBaseEnv(false, 0)
|
||||||
{
|
{
|
||||||
nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0;
|
nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0;
|
||||||
nrEvaluated = recursionDepth = maxRecursionDepth = 0;
|
|
||||||
nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0;
|
nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0;
|
||||||
deepestStack = (char *) -1;
|
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
static bool gcInitialised = true;
|
static bool gcInitialised = true;
|
||||||
@@ -190,7 +188,6 @@ EvalState::EvalState()
|
|||||||
|
|
||||||
EvalState::~EvalState()
|
EvalState::~EvalState()
|
||||||
{
|
{
|
||||||
assert(recursionDepth == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1206,12 +1203,6 @@ void EvalState::printStats()
|
|||||||
|
|
||||||
printMsg(v, format(" time elapsed: %1%") % cpuTime);
|
printMsg(v, format(" time elapsed: %1%") % cpuTime);
|
||||||
printMsg(v, format(" size of a value: %1%") % sizeof(Value));
|
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)")
|
printMsg(v, format(" environments allocated: %1% (%2% bytes)")
|
||||||
% nrEnvs % (nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *)));
|
% nrEnvs % (nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *)));
|
||||||
printMsg(v, format(" list elements: %1% (%2% bytes)")
|
printMsg(v, format(" list elements: %1% (%2% bytes)")
|
||||||
|
|||||||
+1
-9
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __EVAL_H
|
#pragma once
|
||||||
#define __EVAL_H
|
|
||||||
|
|
||||||
#include "value.hh"
|
#include "value.hh"
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
@@ -242,13 +241,9 @@ private:
|
|||||||
unsigned long nrValuesInEnvs;
|
unsigned long nrValuesInEnvs;
|
||||||
unsigned long nrValues;
|
unsigned long nrValues;
|
||||||
unsigned long nrListElems;
|
unsigned long nrListElems;
|
||||||
unsigned long nrEvaluated;
|
|
||||||
unsigned long nrAttrsets;
|
unsigned long nrAttrsets;
|
||||||
unsigned long nrOpUpdates;
|
unsigned long nrOpUpdates;
|
||||||
unsigned long nrOpUpdateValuesCopied;
|
unsigned long nrOpUpdateValuesCopied;
|
||||||
unsigned int recursionDepth;
|
|
||||||
unsigned int maxRecursionDepth;
|
|
||||||
char * deepestStack; /* for measuring stack usage */
|
|
||||||
|
|
||||||
friend class RecursionCounter;
|
friend class RecursionCounter;
|
||||||
friend class ExprOpUpdate;
|
friend class ExprOpUpdate;
|
||||||
@@ -260,6 +255,3 @@ string showType(const Value & v);
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__EVAL_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __GET_DRVS_H
|
#pragma once
|
||||||
#define __GET_DRVS_H
|
|
||||||
|
|
||||||
#include "eval.hh"
|
#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
|
#pragma once
|
||||||
#define __NAMES_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
struct DrvName
|
struct DrvName
|
||||||
{
|
{
|
||||||
string fullName;
|
string fullName;
|
||||||
@@ -19,15 +16,9 @@ struct DrvName
|
|||||||
bool matches(DrvName & n);
|
bool matches(DrvName & n);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef list<DrvName> DrvNames;
|
typedef list<DrvName> DrvNames;
|
||||||
|
|
||||||
|
|
||||||
int compareVersions(const string & v1, const string & v2);
|
int compareVersions(const string & v1, const string & v2);
|
||||||
DrvNames drvNamesFromArgs(const Strings & opArgs);
|
DrvNames drvNamesFromArgs(const Strings & opArgs);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__NAMES_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __NIXEXPR_H
|
#pragma once
|
||||||
#define __NIXEXPR_H
|
|
||||||
|
|
||||||
#include "value.hh"
|
#include "value.hh"
|
||||||
#include "symbol-table.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 {
|
try {
|
||||||
/* !!! If using a substitute, we only need to fetch
|
/* !!! If using a substitute, we only need to fetch
|
||||||
the selected output of this derivation. */
|
the selected output of this derivation. */
|
||||||
store->buildDerivations(singleton<PathSet>(ctx));
|
store->buildPaths(singleton<PathSet>(ctx));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
throw ImportError(e.msg());
|
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)
|
static void prim_storePath(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
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))
|
if (!isInStore(path))
|
||||||
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
||||||
Path path2 = toStorePath(path);
|
Path path2 = toStorePath(path);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __SYMBOL_TABLE_H
|
#pragma once
|
||||||
#define __SYMBOL_TABLE_H
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -88,5 +87,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__SYMBOL_TABLE_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __VALUE_TO_XML_H
|
#pragma once
|
||||||
#define __VALUE_TO_XML_H
|
|
||||||
|
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
@@ -13,5 +12,3 @@ void printValueAsXML(EvalState & state, bool strict, bool location,
|
|||||||
Value & v, std::ostream & out, PathSet & context);
|
Value & v, std::ostream & out, PathSet & context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__VALUE_TO_XML_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __VALUE_H
|
#pragma once
|
||||||
#define __VALUE_H
|
|
||||||
|
|
||||||
#include "symbol-table.hh"
|
#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
|
#pragma once
|
||||||
#define __SHARED_H
|
|
||||||
|
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
@@ -54,6 +53,3 @@ extern int exitCode;
|
|||||||
extern char * * argvSaved;
|
extern char * * argvSaved;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__SHARED_H */
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pkginclude_HEADERS = \
|
|||||||
globals.hh references.hh pathlocks.hh \
|
globals.hh references.hh pathlocks.hh \
|
||||||
worker-protocol.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
|
EXTRA_DIST = schema.sql
|
||||||
|
|
||||||
|
|||||||
+280
-149
@@ -31,6 +31,8 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
|
#include <bzlib.h>
|
||||||
|
|
||||||
|
|
||||||
/* Includes required for chroot support. */
|
/* Includes required for chroot support. */
|
||||||
#if HAVE_SYS_PARAM_H
|
#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)
|
#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
|
#if HAVE_SYS_PERSONALITY_H
|
||||||
#include <sys/personality.h>
|
#include <sys/personality.h>
|
||||||
@@ -758,6 +767,8 @@ private:
|
|||||||
Path tmpDir;
|
Path tmpDir;
|
||||||
|
|
||||||
/* File descriptor for the log file. */
|
/* File descriptor for the log file. */
|
||||||
|
FILE * fLogFile;
|
||||||
|
BZFILE * bzLogFile;
|
||||||
AutoCloseFD fdLogFile;
|
AutoCloseFD fdLogFile;
|
||||||
|
|
||||||
/* Pipe for the builder's standard output/error. */
|
/* Pipe for the builder's standard output/error. */
|
||||||
@@ -783,6 +794,11 @@ private:
|
|||||||
typedef void (DerivationGoal::*GoalState)();
|
typedef void (DerivationGoal::*GoalState)();
|
||||||
GoalState state;
|
GoalState state;
|
||||||
|
|
||||||
|
/* Stuff we need to pass to initChild(). */
|
||||||
|
PathSet dirsInChroot;
|
||||||
|
typedef map<string, string> Environment;
|
||||||
|
Environment env;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DerivationGoal(const Path & drvPath, Worker & worker);
|
DerivationGoal(const Path & drvPath, Worker & worker);
|
||||||
~DerivationGoal();
|
~DerivationGoal();
|
||||||
@@ -811,6 +827,11 @@ private:
|
|||||||
/* Start building a derivation. */
|
/* Start building a derivation. */
|
||||||
void startBuilder();
|
void startBuilder();
|
||||||
|
|
||||||
|
/* Initialise the builder's process. */
|
||||||
|
void initChild();
|
||||||
|
|
||||||
|
friend int childEntry(void *);
|
||||||
|
|
||||||
/* Must be called after the output paths have become valid (either
|
/* Must be called after the output paths have become valid (either
|
||||||
due to a successful build or hook, or because they already
|
due to a successful build or hook, or because they already
|
||||||
were). */
|
were). */
|
||||||
@@ -819,6 +840,9 @@ private:
|
|||||||
/* Open a log file and a pipe to it. */
|
/* Open a log file and a pipe to it. */
|
||||||
Path openLogFile();
|
Path openLogFile();
|
||||||
|
|
||||||
|
/* Close the log file. */
|
||||||
|
void closeLogFile();
|
||||||
|
|
||||||
/* Delete the temporary directory, if we have one. */
|
/* Delete the temporary directory, if we have one. */
|
||||||
void deleteTmpDir(bool force);
|
void deleteTmpDir(bool force);
|
||||||
|
|
||||||
@@ -839,6 +863,8 @@ private:
|
|||||||
|
|
||||||
DerivationGoal::DerivationGoal(const Path & drvPath, Worker & worker)
|
DerivationGoal::DerivationGoal(const Path & drvPath, Worker & worker)
|
||||||
: Goal(worker)
|
: Goal(worker)
|
||||||
|
, fLogFile(0)
|
||||||
|
, bzLogFile(0)
|
||||||
, useChroot(false)
|
, useChroot(false)
|
||||||
{
|
{
|
||||||
this->drvPath = drvPath;
|
this->drvPath = drvPath;
|
||||||
@@ -855,6 +881,7 @@ DerivationGoal::~DerivationGoal()
|
|||||||
try {
|
try {
|
||||||
killChild();
|
killChild();
|
||||||
deleteTmpDir(false);
|
deleteTmpDir(false);
|
||||||
|
closeLogFile();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1268,7 @@ void DerivationGoal::buildDone()
|
|||||||
else builderOut.readSide.close();
|
else builderOut.readSide.close();
|
||||||
|
|
||||||
/* Close the log file. */
|
/* Close the log file. */
|
||||||
fdLogFile.close();
|
closeLogFile();
|
||||||
|
|
||||||
/* When running under a build user, make sure that all processes
|
/* When running under a build user, make sure that all processes
|
||||||
running under that uid are gone. This is to prevent a
|
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()
|
void DerivationGoal::startBuilder()
|
||||||
{
|
{
|
||||||
startNest(nest, lvlInfo,
|
startNest(nest, lvlInfo,
|
||||||
@@ -1464,8 +1498,6 @@ void DerivationGoal::startBuilder()
|
|||||||
% drv.platform % thisSystem % drvPath);
|
% drv.platform % thisSystem % drvPath);
|
||||||
|
|
||||||
/* Construct the environment passed to the builder. */
|
/* 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
|
/* 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
|
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
|
work properly. Purity checking for fixed-output derivations
|
||||||
is somewhat pointless anyway. */
|
is somewhat pointless anyway. */
|
||||||
useChroot = queryBoolSetting("build-use-chroot", false);
|
useChroot = queryBoolSetting("build-use-chroot", false);
|
||||||
PathSet dirsInChroot;
|
|
||||||
|
|
||||||
if (fixedOutput) useChroot = false;
|
if (fixedOutput) useChroot = false;
|
||||||
|
|
||||||
@@ -1675,7 +1706,6 @@ void DerivationGoal::startBuilder()
|
|||||||
Paths defaultDirs;
|
Paths defaultDirs;
|
||||||
defaultDirs.push_back("/dev");
|
defaultDirs.push_back("/dev");
|
||||||
defaultDirs.push_back("/dev/pts");
|
defaultDirs.push_back("/dev/pts");
|
||||||
defaultDirs.push_back("/proc");
|
|
||||||
|
|
||||||
Paths dirsInChroot_ = querySetting("build-chroot-dirs", defaultDirs);
|
Paths dirsInChroot_ = querySetting("build-chroot-dirs", defaultDirs);
|
||||||
dirsInChroot.insert(dirsInChroot_.begin(), dirsInChroot_.end());
|
dirsInChroot.insert(dirsInChroot_.begin(), dirsInChroot_.end());
|
||||||
@@ -1744,146 +1774,46 @@ void DerivationGoal::startBuilder()
|
|||||||
/* Fork a child to build the package. Note that while we
|
/* Fork a child to build the package. Note that while we
|
||||||
currently use forks to run and wait for the children, it
|
currently use forks to run and wait for the children, it
|
||||||
shouldn't be hard to use threads for this on systems where
|
shouldn't be hard to use threads for this on systems where
|
||||||
fork() is unavailable or inefficient. */
|
fork() is unavailable or inefficient.
|
||||||
pid = fork();
|
|
||||||
switch (pid) {
|
|
||||||
|
|
||||||
case -1:
|
If we're building in a chroot, then also set up private
|
||||||
throw SysError("unable to fork");
|
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
|
- The private mount namespace ensures that all the bind mounts
|
||||||
SQLite calls! */
|
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 CHROOT_ENABLED
|
||||||
if (useChroot) {
|
if (useChroot) {
|
||||||
/* Create our own mount namespace. This means that
|
char stack[32 * 1024];
|
||||||
all the bind mounts we do will only show up in this
|
pid = clone(childEntry, stack + sizeof(stack) - 8,
|
||||||
process and its children, and will disappear
|
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, this);
|
||||||
automatically when we're done. */
|
} else
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
commonChildInit(builderOut);
|
pid = fork();
|
||||||
|
if (pid == 0) initChild();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pid == -1) throw SysError("unable to fork");
|
||||||
|
|
||||||
/* parent */
|
/* parent */
|
||||||
pid.setSeparatePG(true);
|
pid.setSeparatePG(true);
|
||||||
builderOut.writeSide.close();
|
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
|
/* Parse a list of reference specifiers. Each element must either be
|
||||||
a store path, or the symbolic name of the output of the derivation
|
a store path, or the symbolic name of the output of the derivation
|
||||||
(such as `out'). */
|
(such as `out'). */
|
||||||
@@ -2032,18 +2117,53 @@ string drvsLogDir = "drvs";
|
|||||||
|
|
||||||
Path DerivationGoal::openLogFile()
|
Path DerivationGoal::openLogFile()
|
||||||
{
|
{
|
||||||
|
if (!queryBoolSetting("build-keep-log", true)) return "";
|
||||||
|
|
||||||
/* Create a log file. */
|
/* Create a log file. */
|
||||||
Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
|
Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
|
||||||
createDirs(dir);
|
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)
|
if (verbosity >= buildVerbosity)
|
||||||
writeToStderr((unsigned char *) data.data(), data.size());
|
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)
|
if (hook && fd == hook->fromHook.readSide)
|
||||||
@@ -2109,6 +2234,7 @@ bool DerivationGoal::pathFailed(const Path & path)
|
|||||||
if (printBuildTrace)
|
if (printBuildTrace)
|
||||||
printMsg(lvlError, format("@ build-failed %1% %2% cached") % drvPath % path);
|
printMsg(lvlError, format("@ build-failed %1% %2% cached") % drvPath % path);
|
||||||
|
|
||||||
|
worker.permanentFailure = true;
|
||||||
amDone(ecFailed);
|
amDone(ecFailed);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2166,6 +2292,8 @@ public:
|
|||||||
/* Callback used by the worker to write to the log. */
|
/* Callback used by the worker to write to the log. */
|
||||||
void handleChildOutput(int fd, const string & data);
|
void handleChildOutput(int fd, const string & data);
|
||||||
void handleEOF(int fd);
|
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,
|
startNest(nest, lvlDebug,
|
||||||
format("building %1%") % showPaths(drvPaths));
|
format("building %1%") % showPaths(drvPaths));
|
||||||
@@ -2838,7 +2966,10 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
|
|||||||
|
|
||||||
Goals goals;
|
Goals goals;
|
||||||
foreach (PathSet::const_iterator, i, drvPaths)
|
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);
|
worker.run(goals);
|
||||||
|
|
||||||
@@ -2846,8 +2977,8 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
|
|||||||
foreach (Goals::iterator, i, goals)
|
foreach (Goals::iterator, i, goals)
|
||||||
if ((*i)->getExitCode() == Goal::ecFailed) {
|
if ((*i)->getExitCode() == Goal::ecFailed) {
|
||||||
DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i->get());
|
DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i->get());
|
||||||
assert(i2);
|
if (i2) failed.insert(i2->getDrvPath());
|
||||||
failed.insert(i2->getDrvPath());
|
else failed.insert(dynamic_cast<SubstitutionGoal *>(i->get())->getStorePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failed.empty())
|
if (!failed.empty())
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __DERIVATIONS_H
|
#pragma once
|
||||||
#define __DERIVATIONS_H
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -81,6 +80,3 @@ typedef std::map<Path, Hash> DrvHashes;
|
|||||||
extern DrvHashes drvHashes;
|
extern DrvHashes drvHashes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__DERIVATIONS_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __GLOBALS_H
|
#pragma once
|
||||||
#define __GLOBALS_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#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;
|
substitutablePathsLoaded = false;
|
||||||
|
|
||||||
@@ -221,6 +221,24 @@ LocalStore::LocalStore()
|
|||||||
|
|
||||||
checkStoreNotSymlink();
|
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
|
/* Acquire the big fat lock in shared mode to make sure that no
|
||||||
schema upgrade is in progress. */
|
schema upgrade is in progress. */
|
||||||
try {
|
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 = ?;");
|
"select v.id, v.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where d.path = ?;");
|
||||||
stmtQueryDerivationOutputs.create(db,
|
stmtQueryDerivationOutputs.create(db,
|
||||||
"select id, path from DerivationOutputs where drv = ?;");
|
"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)
|
void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run)
|
||||||
{
|
{
|
||||||
if (run.pid != -1) return;
|
if (run.pid != -1) return;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __LOCAL_STORE_H
|
#pragma once
|
||||||
#define __LOCAL_STORE_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ public:
|
|||||||
|
|
||||||
/* Initialise the local store, upgrading the schema if
|
/* Initialise the local store, upgrading the schema if
|
||||||
necessary. */
|
necessary. */
|
||||||
LocalStore();
|
LocalStore(bool reserveSpace = true);
|
||||||
|
|
||||||
~LocalStore();
|
~LocalStore();
|
||||||
|
|
||||||
@@ -121,6 +120,8 @@ public:
|
|||||||
|
|
||||||
StringSet queryDerivationOutputNames(const Path & path);
|
StringSet queryDerivationOutputNames(const Path & path);
|
||||||
|
|
||||||
|
Path queryPathFromHashPart(const string & hashPart);
|
||||||
|
|
||||||
PathSet querySubstitutablePaths();
|
PathSet querySubstitutablePaths();
|
||||||
|
|
||||||
bool hasSubstitutes(const Path & path);
|
bool hasSubstitutes(const Path & path);
|
||||||
@@ -150,7 +151,7 @@ public:
|
|||||||
|
|
||||||
Paths importPaths(bool requireSignature, Source & source);
|
Paths importPaths(bool requireSignature, Source & source);
|
||||||
|
|
||||||
void buildDerivations(const PathSet & drvPaths);
|
void buildPaths(const PathSet & paths);
|
||||||
|
|
||||||
void ensurePath(const Path & path);
|
void ensurePath(const Path & path);
|
||||||
|
|
||||||
@@ -217,6 +218,7 @@ private:
|
|||||||
SQLiteStmt stmtAddDerivationOutput;
|
SQLiteStmt stmtAddDerivationOutput;
|
||||||
SQLiteStmt stmtQueryValidDerivers;
|
SQLiteStmt stmtQueryValidDerivers;
|
||||||
SQLiteStmt stmtQueryDerivationOutputs;
|
SQLiteStmt stmtQueryDerivationOutputs;
|
||||||
|
SQLiteStmt stmtQueryPathFromHashPart;
|
||||||
|
|
||||||
int getSchema();
|
int getSchema();
|
||||||
|
|
||||||
@@ -299,6 +301,3 @@ void deletePathWrapped(const Path & path,
|
|||||||
void deletePathWrapped(const Path & path);
|
void deletePathWrapped(const Path & path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__LOCAL_STORE_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __MISC_H
|
#pragma once
|
||||||
#define __MISC_H
|
|
||||||
|
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
|
||||||
@@ -35,6 +34,3 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__MISC_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __PATHLOCKS_H
|
#pragma once
|
||||||
#define __PATHLOCKS_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
@@ -44,6 +43,3 @@ bool pathIsLockedByMe(const Path & path);
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__PATHLOCKS_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __REFERENCES_H
|
#pragma once
|
||||||
#define __REFERENCES_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
@@ -10,5 +9,3 @@ PathSet scanForReferences(const Path & path, const PathSet & refs,
|
|||||||
HashResult & hash);
|
HashResult & hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__REFERENCES_H */
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ RemoteStore::RemoteStore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::openConnection()
|
void RemoteStore::openConnection(bool reserveSpace)
|
||||||
{
|
{
|
||||||
if (initialised) return;
|
if (initialised) return;
|
||||||
initialised = true;
|
initialised = true;
|
||||||
@@ -75,6 +75,8 @@ void RemoteStore::openConnection()
|
|||||||
if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
|
if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
|
||||||
throw Error("Nix daemon protocol version not supported");
|
throw Error("Nix daemon protocol version not supported");
|
||||||
writeInt(PROTOCOL_VERSION, to);
|
writeInt(PROTOCOL_VERSION, to);
|
||||||
|
if (GET_PROTOCOL_MINOR(daemonVersion) >= 11)
|
||||||
|
writeInt(reserveSpace, to);
|
||||||
processStderr();
|
processStderr();
|
||||||
}
|
}
|
||||||
catch (Error & e) {
|
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,
|
Path RemoteStore::addToStore(const Path & _srcPath,
|
||||||
bool recursive, HashType hashAlgo, PathFilter & filter)
|
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();
|
openConnection();
|
||||||
writeInt(wopBuildDerivations, to);
|
writeInt(wopBuildPaths, to);
|
||||||
writeStrings(drvPaths, to);
|
writeStrings(drvPaths, to);
|
||||||
processStderr();
|
processStderr();
|
||||||
readInt(from);
|
readInt(from);
|
||||||
@@ -462,7 +476,7 @@ Roots RemoteStore::findRoots()
|
|||||||
|
|
||||||
void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results)
|
void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
{
|
{
|
||||||
openConnection();
|
openConnection(false);
|
||||||
|
|
||||||
writeInt(wopCollectGarbage, to);
|
writeInt(wopCollectGarbage, to);
|
||||||
writeInt(options.action, to);
|
writeInt(options.action, to);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __REMOTE_STORE_H
|
#pragma once
|
||||||
#define __REMOTE_STORE_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -43,6 +42,8 @@ public:
|
|||||||
|
|
||||||
StringSet queryDerivationOutputNames(const Path & path);
|
StringSet queryDerivationOutputNames(const Path & path);
|
||||||
|
|
||||||
|
Path queryPathFromHashPart(const string & hashPart);
|
||||||
|
|
||||||
bool hasSubstitutes(const Path & path);
|
bool hasSubstitutes(const Path & path);
|
||||||
|
|
||||||
bool querySubstitutablePathInfo(const Path & path,
|
bool querySubstitutablePathInfo(const Path & path,
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
|
|
||||||
Paths importPaths(bool requireSignature, Source & source);
|
Paths importPaths(bool requireSignature, Source & source);
|
||||||
|
|
||||||
void buildDerivations(const PathSet & drvPaths);
|
void buildPaths(const PathSet & paths);
|
||||||
|
|
||||||
void ensurePath(const Path & path);
|
void ensurePath(const Path & path);
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ private:
|
|||||||
unsigned int daemonVersion;
|
unsigned int daemonVersion;
|
||||||
bool initialised;
|
bool initialised;
|
||||||
|
|
||||||
void openConnection();
|
void openConnection(bool reserveSpace = true);
|
||||||
|
|
||||||
void processStderr(Sink * sink = 0, Source * source = 0);
|
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> store;
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<StoreAPI> openStore()
|
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace)
|
||||||
{
|
{
|
||||||
if (getEnv("NIX_REMOTE") == "")
|
if (getEnv("NIX_REMOTE") == "")
|
||||||
return boost::shared_ptr<StoreAPI>(new LocalStore());
|
return boost::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
|
||||||
else
|
else
|
||||||
return boost::shared_ptr<StoreAPI>(new RemoteStore());
|
return boost::shared_ptr<StoreAPI>(new RemoteStore());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __STOREAPI_H
|
#pragma once
|
||||||
#define __STOREAPI_H
|
|
||||||
|
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
#include "serialise.hh"
|
#include "serialise.hh"
|
||||||
@@ -139,6 +138,10 @@ public:
|
|||||||
|
|
||||||
/* Query the output names of the derivation denoted by `path'. */
|
/* Query the output names of the derivation denoted by `path'. */
|
||||||
virtual StringSet queryDerivationOutputNames(const Path & path) = 0;
|
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. */
|
/* Query whether a path has substitutes. */
|
||||||
virtual bool hasSubstitutes(const Path & path) = 0;
|
virtual bool hasSubstitutes(const Path & path) = 0;
|
||||||
@@ -172,13 +175,15 @@ public:
|
|||||||
the Nix store. */
|
the Nix store. */
|
||||||
virtual Paths importPaths(bool requireSignature, Source & source) = 0;
|
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
|
they are already valid, this is a no-op. Otherwise, validity
|
||||||
can be reached in two ways. First, if the output paths is
|
can be reached in two ways. First, if the output paths is
|
||||||
substitutable, then build the path that way. Second, the
|
substitutable, then build the path that way. Second, the
|
||||||
output paths can be created by running the builder, after
|
output paths can be created by running the builder, after
|
||||||
recursively building any sub-derivations. */
|
recursively building any sub-derivations. For inputs that are
|
||||||
virtual void buildDerivations(const PathSet & drvPaths) = 0;
|
not derivations, substitute them. */
|
||||||
|
virtual void buildPaths(const PathSet & paths) = 0;
|
||||||
|
|
||||||
/* Ensure that a path is valid. If it is not currently valid, it
|
/* 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
|
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
|
/* Factory method: open the Nix database, either through the local or
|
||||||
remote implementation. */
|
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
|
/* 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
|
#pragma once
|
||||||
#define __WORKER_PROTOCOL_H
|
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
@@ -8,7 +6,7 @@ namespace nix {
|
|||||||
#define WORKER_MAGIC_1 0x6e697863
|
#define WORKER_MAGIC_1 0x6e697863
|
||||||
#define WORKER_MAGIC_2 0x6478696f
|
#define WORKER_MAGIC_2 0x6478696f
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 0x10a
|
#define PROTOCOL_VERSION 0x10b
|
||||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ typedef enum {
|
|||||||
wopQueryReferrers = 6,
|
wopQueryReferrers = 6,
|
||||||
wopAddToStore = 7,
|
wopAddToStore = 7,
|
||||||
wopAddTextToStore = 8,
|
wopAddTextToStore = 8,
|
||||||
wopBuildDerivations = 9,
|
wopBuildPaths = 9,
|
||||||
wopEnsurePath = 10,
|
wopEnsurePath = 10,
|
||||||
wopAddTempRoot = 11,
|
wopAddTempRoot = 11,
|
||||||
wopAddIndirectRoot = 12,
|
wopAddIndirectRoot = 12,
|
||||||
@@ -40,6 +38,7 @@ typedef enum {
|
|||||||
wopQueryPathInfo = 26,
|
wopQueryPathInfo = 26,
|
||||||
wopImportPaths = 27,
|
wopImportPaths = 27,
|
||||||
wopQueryDerivationOutputNames = 28,
|
wopQueryDerivationOutputNames = 28,
|
||||||
|
wopQueryPathFromHashPart = 29,
|
||||||
} WorkerOp;
|
} WorkerOp;
|
||||||
|
|
||||||
|
|
||||||
@@ -63,6 +62,3 @@ template<class T> T readStorePaths(Source & from);
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__WORKER_PROTOCOL_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __ARCHIVE_H
|
#pragma once
|
||||||
#define __ARCHIVE_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "serialise.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
|
#pragma once
|
||||||
#define __HASH_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "serialise.hh"
|
#include "serialise.hh"
|
||||||
@@ -109,6 +108,3 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__HASH_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __IMMUTABLE_H
|
#pragma once
|
||||||
#define __IMMUTABLE_H
|
|
||||||
|
|
||||||
#include <types.hh>
|
#include <types.hh>
|
||||||
|
|
||||||
@@ -15,5 +14,3 @@ void makeImmutable(const Path & path);
|
|||||||
void makeMutable(const Path & path);
|
void makeMutable(const Path & path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__IMMUTABLE_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __SERIALISE_H
|
#pragma once
|
||||||
#define __SERIALISE_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
@@ -130,6 +129,3 @@ MakeError(SerialisationError, Error)
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__SERIALISE_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __TYPES_H
|
#pragma once
|
||||||
#define __TYPES_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
@@ -74,6 +73,3 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__TYPES_H */
|
|
||||||
|
|||||||
+5
-2
@@ -779,8 +779,11 @@ void Pid::kill()
|
|||||||
int status;
|
int status;
|
||||||
while (waitpid(pid, &status, 0) == -1) {
|
while (waitpid(pid, &status, 0) == -1) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (errno != EINTR) printMsg(lvlError,
|
if (errno != EINTR) {
|
||||||
(SysError(format("waiting for process %1%") % pid).msg()));
|
printMsg(lvlError,
|
||||||
|
(SysError(format("waiting for process %1%") % pid).msg()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = -1;
|
pid = -1;
|
||||||
|
|||||||
+1
-5
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __UTIL_H
|
#pragma once
|
||||||
#define __UTIL_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
@@ -333,6 +332,3 @@ void ignoreException();
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__UTIL_H */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __XML_WRITER_H
|
#pragma once
|
||||||
#define __XML_WRITER_H
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#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));
|
PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state));
|
||||||
printMissing(*store, paths);
|
printMissing(*store, paths);
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
store->buildDerivations(paths);
|
store->buildPaths(paths);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state)));
|
printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state)));
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __PROFILES_H
|
#pragma once
|
||||||
#define __PROFILES_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "pathlocks.hh"
|
#include "pathlocks.hh"
|
||||||
@@ -54,6 +53,3 @@ void lockProfile(PathLocks & lock, const Path & profile);
|
|||||||
string optimisticLockProfile(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));
|
drvsToBuild.insert(i->queryDrvPath(state));
|
||||||
|
|
||||||
debug(format("building user environment dependencies"));
|
debug(format("building user environment dependencies"));
|
||||||
store->buildDerivations(drvsToBuild);
|
store->buildPaths(drvsToBuild);
|
||||||
|
|
||||||
/* Construct the whole top level derivation. */
|
/* Construct the whole top level derivation. */
|
||||||
PathSet references;
|
PathSet references;
|
||||||
@@ -132,7 +132,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
|||||||
|
|
||||||
/* Realise the resulting store expression. */
|
/* Realise the resulting store expression. */
|
||||||
debug("building user environment");
|
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. */
|
/* Switch the current user environment to the output path. */
|
||||||
PathLocks lock;
|
PathLocks lock;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __USER_ENV_H
|
#pragma once
|
||||||
#define __USER_ENV_H
|
|
||||||
|
|
||||||
#include "get-drvs.hh"
|
#include "get-drvs.hh"
|
||||||
|
|
||||||
@@ -12,9 +11,3 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
|||||||
const string & lockToken);
|
const string & lockToken);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__USER_ENV_H */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ nix_store_SOURCES = \
|
|||||||
xmlgraph.cc xmlgraph.hh
|
xmlgraph.cc xmlgraph.hh
|
||||||
|
|
||||||
nix_store_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
|
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
|
nix-store.o: help.txt.hh
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __DOTGRAPH_H
|
#pragma once
|
||||||
#define __DOTGRAPH_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
@@ -8,5 +7,3 @@ namespace nix {
|
|||||||
void printDotGraph(const PathSet & roots);
|
void printDotGraph(const PathSet & roots);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__DOTGRAPH_H */
|
|
||||||
|
|||||||
+39
-16
@@ -10,6 +10,13 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <bzlib.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
@@ -55,7 +62,7 @@ static Path useDeriver(Path path)
|
|||||||
static PathSet realisePath(const Path & path)
|
static PathSet realisePath(const Path & path)
|
||||||
{
|
{
|
||||||
if (isDerivation(path)) {
|
if (isDerivation(path)) {
|
||||||
store->buildDerivations(singleton<PathSet>(path));
|
store->buildPaths(singleton<PathSet>(path));
|
||||||
Derivation drv = derivationFromPath(*store, path);
|
Derivation drv = derivationFromPath(*store, path);
|
||||||
|
|
||||||
PathSet outputs;
|
PathSet outputs;
|
||||||
@@ -94,13 +101,11 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
|||||||
|
|
||||||
if (dryRun) return;
|
if (dryRun) return;
|
||||||
|
|
||||||
/* Build all derivations at the same time to exploit parallelism. */
|
/* Build all paths at the same time to exploit parallelism. */
|
||||||
PathSet drvPaths;
|
PathSet paths(opArgs.begin(), opArgs.end());
|
||||||
foreach (Strings::iterator, i, opArgs)
|
store->buildPaths(paths);
|
||||||
if (isDerivation(*i)) drvPaths.insert(*i);
|
|
||||||
store->buildDerivations(drvPaths);
|
|
||||||
|
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Paths::iterator, i, opArgs) {
|
||||||
PathSet paths = realisePath(*i);
|
PathSet paths = realisePath(*i);
|
||||||
foreach (PathSet::iterator, j, paths)
|
foreach (PathSet::iterator, j, paths)
|
||||||
cout << format("%1%\n") % *j;
|
cout << format("%1%\n") % *j;
|
||||||
@@ -419,20 +424,38 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
|||||||
{
|
{
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
|
|
||||||
for (Strings::iterator i = opArgs.begin();
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
i != opArgs.end(); ++i)
|
|
||||||
{
|
|
||||||
Path path = useDeriver(followLinksToStorePath(*i));
|
Path path = useDeriver(followLinksToStorePath(*i));
|
||||||
|
|
||||||
Path logPath = (format("%1%/%2%/%3%") %
|
Path logPath = (format("%1%/%2%/%3%") %
|
||||||
nixLogDir % drvsLogDir % baseNameOf(path)).str();
|
nixLogDir % drvsLogDir % baseNameOf(path)).str();
|
||||||
|
Path logBz2Path = logPath + ".bz2";
|
||||||
|
|
||||||
if (!pathExists(logPath))
|
if (pathExists(logPath)) {
|
||||||
throw Error(format("build log of derivation `%1%' is not available") % path);
|
/* !!! 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. */
|
else if (pathExists(logBz2Path)) {
|
||||||
string log = readFile(logPath);
|
AutoCloseFD fd = open(logBz2Path.c_str(), O_RDONLY);
|
||||||
writeFull(STDOUT_FILENO, (const unsigned char *) log.data(), log.size());
|
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) throw UsageError("no operation specified");
|
||||||
|
|
||||||
if (op != opDump && op != opRestore) /* !!! hack */
|
if (op != opDump && op != opRestore) /* !!! hack */
|
||||||
store = openStore();
|
store = openStore(op != opGC);
|
||||||
|
|
||||||
op(opFlags, opArgs);
|
op(opFlags, opArgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef __XMLGRAPH_H
|
#pragma once
|
||||||
#define __XMLGRAPH_H
|
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
@@ -8,5 +7,3 @@ namespace nix {
|
|||||||
void printXmlGraph(const PathSet & roots);
|
void printXmlGraph(const PathSet & roots);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__XMLGRAPH_H */
|
|
||||||
|
|||||||
@@ -350,6 +350,15 @@ static void performOp(unsigned int clientVersion,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case wopQueryPathFromHashPart: {
|
||||||
|
string hashPart = readString(from);
|
||||||
|
startWork();
|
||||||
|
Path path = store->queryPathFromHashPart(hashPart);
|
||||||
|
stopWork();
|
||||||
|
writeString(path, to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case wopAddToStore: {
|
case wopAddToStore: {
|
||||||
string baseName = readString(from);
|
string baseName = readString(from);
|
||||||
bool fixed = readInt(from) == 1; /* obsolete */
|
bool fixed = readInt(from) == 1; /* obsolete */
|
||||||
@@ -415,10 +424,10 @@ static void performOp(unsigned int clientVersion,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopBuildDerivations: {
|
case wopBuildPaths: {
|
||||||
PathSet drvs = readStorePaths<PathSet>(from);
|
PathSet drvs = readStorePaths<PathSet>(from);
|
||||||
startWork();
|
startWork();
|
||||||
store->buildDerivations(drvs);
|
store->buildPaths(drvs);
|
||||||
stopWork();
|
stopWork();
|
||||||
writeInt(1, to);
|
writeInt(1, to);
|
||||||
break;
|
break;
|
||||||
@@ -625,8 +634,12 @@ static void processConnection()
|
|||||||
throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!");
|
throw Error("if you run `nix-worker' as root, then you MUST set `build-users-group'!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool reserveSpace = true;
|
||||||
|
if (GET_PROTOCOL_MINOR(clientVersion) >= 11)
|
||||||
|
reserveSpace = readInt(from) != 0;
|
||||||
|
|
||||||
/* Open the store. */
|
/* Open the store. */
|
||||||
store = boost::shared_ptr<StoreAPI>(new LocalStore());
|
store = boost::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
|
||||||
|
|
||||||
stopWork();
|
stopWork();
|
||||||
to.flush();
|
to.flush();
|
||||||
@@ -691,51 +704,67 @@ static void setSigChldAction(bool autoReap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SD_LISTEN_FDS_START 3
|
||||||
|
|
||||||
|
|
||||||
static void daemonLoop()
|
static void daemonLoop()
|
||||||
{
|
{
|
||||||
/* Get rid of children automatically; don't let them become
|
/* Get rid of children automatically; don't let them become
|
||||||
zombies. */
|
zombies. */
|
||||||
setSigChldAction(true);
|
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. */
|
/* Create and bind to a Unix domain socket. */
|
||||||
AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
|
fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
if (fdSocket == -1)
|
if (fdSocket == -1)
|
||||||
throw SysError("cannot create Unix domain socket");
|
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);
|
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. */
|
/* Loop accepting connections. */
|
||||||
while (1) {
|
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 \
|
gc-runtime.sh install-package.sh check-refs.sh filter-source.sh \
|
||||||
remote-store.sh export.sh export-graph.sh negative-caching.sh \
|
remote-store.sh export.sh export-graph.sh negative-caching.sh \
|
||||||
binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.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 =
|
XFAIL_TESTS =
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ EXTRA_DIST = $(TESTS) \
|
|||||||
secure-drv-outputs.nix \
|
secure-drv-outputs.nix \
|
||||||
multiple-outputs.nix \
|
multiple-outputs.nix \
|
||||||
import-derivation.nix \
|
import-derivation.nix \
|
||||||
|
fetchurl.nix \
|
||||||
$(wildcard lang/*.nix) $(wildcard lang/*.exp) $(wildcard lang/*.exp.xml) $(wildcard lang/*.flags) $(wildcard lang/dir*/*.nix) \
|
$(wildcard lang/*.nix) $(wildcard lang/*.exp) $(wildcard lang/*.exp.xml) $(wildcard lang/*.flags) $(wildcard lang/dir*/*.nix) \
|
||||||
common.sh.in
|
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