Compare commits
80 Commits
cache-getf
...
2.3.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90b3b31dc2 | ||
|
|
f5941e14e0 | ||
|
|
a25214a2bc | ||
|
|
6d01e9a623 | ||
|
|
7afd8321ed | ||
|
|
2007b4a89b | ||
|
|
eba0892d08 | ||
|
|
7fee49ef37 | ||
|
|
e914cfb06f | ||
|
|
d77eaf7976 | ||
|
|
8999beacc3 | ||
|
|
2097983218 | ||
|
|
2f0122b23c | ||
|
|
db3d3a5618 | ||
|
|
91030eae50 | ||
|
|
8950ae95a4 | ||
|
|
6605ea0197 | ||
|
|
b51ecc02c8 | ||
|
|
ed25fdd66e | ||
|
|
475c2e5de7 | ||
|
|
e3eecb5927 | ||
|
|
f84c3f9d65 | ||
|
|
c94fd5f51a | ||
|
|
60429b86ba | ||
|
|
95be8d3b12 | ||
|
|
9879e25473 | ||
|
|
59bbc31701 | ||
|
|
195cc3f883 | ||
|
|
a118444f36 | ||
|
|
3130aafd01 | ||
|
|
6c90e3b9ac | ||
|
|
9f524d9423 | ||
|
|
93d6814847 | ||
|
|
e9c0c772b0 | ||
|
|
1ea63a5931 | ||
|
|
e1fb586138 | ||
|
|
34bf1a8b5f | ||
|
|
7a011ded77 | ||
|
|
eacc510572 | ||
|
|
9cf52dd1cc | ||
|
|
5526f725a8 | ||
|
|
421f1f4493 | ||
|
|
10bf5340ca | ||
|
|
8b44ed08e7 | ||
|
|
1ac8c0269a | ||
|
|
c7b4bf1c9c | ||
|
|
a53e4e217b | ||
|
|
61855a4e7b | ||
|
|
9b4e99801f | ||
|
|
8be0440d44 | ||
|
|
61e816217b | ||
|
|
21f48ff26a | ||
|
|
e3d44a3b83 | ||
|
|
0fb4744467 | ||
|
|
f66108f738 | ||
|
|
2070d55b0b | ||
|
|
fe51fbaf81 | ||
|
|
7c4589854b | ||
|
|
1c10f739eb | ||
|
|
2522757e83 | ||
|
|
923b6bd83c | ||
|
|
65953789bc | ||
|
|
910b0fcc11 | ||
|
|
e232bf2b69 | ||
|
|
7c9ad4d0d7 | ||
|
|
fa028194e9 | ||
|
|
ff7fcd3805 | ||
|
|
ceddbc921f | ||
|
|
62d1c60fb3 | ||
|
|
f4106e76ff | ||
|
|
f3ce4453a6 | ||
|
|
9f53bc33e7 | ||
|
|
4d83eb6206 | ||
|
|
3919093e9a | ||
|
|
b0ae8fe2db | ||
|
|
3c5788d094 | ||
|
|
9f698c4530 | ||
|
|
1b78bbb414 | ||
|
|
1d5cb6ad48 | ||
|
|
22d4ea7a98 |
@@ -1,12 +1,11 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p python3 --pure
|
||||
|
||||
# To be used with `--trace-function-calls` and `-vvvv` and
|
||||
# `flamegraph.pl`.
|
||||
# To be used with `--trace-function-calls` and `flamegraph.pl`.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# nix-instantiate --trace-function-calls -vvvv '<nixpkgs>' -A hello 2> nix-function-calls.trace
|
||||
# nix-instantiate --trace-function-calls '<nixpkgs>' -A hello 2> nix-function-calls.trace
|
||||
# ./contrib/stack-collapse.py nix-function-calls.trace > nix-function-calls.folded
|
||||
# nix-shell -p flamegraph --run "flamegraph.pl nix-function-calls.folded > nix-function-calls.svg"
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ builtins.fetchurl {
|
||||
<varlistentry xml:id="conf-keep-env-derivations"><term><literal>keep-env-derivations</literal></term>
|
||||
|
||||
<listitem><para>If <literal>false</literal> (default), derivations
|
||||
are not stored in Nix user environments. That is, the derivation
|
||||
are not stored in Nix user environments. That is, the derivations of
|
||||
any build-time-only dependencies may be garbage-collected.</para>
|
||||
|
||||
<para>If <literal>true</literal>, when you add a Nix derivation to
|
||||
|
||||
@@ -122,7 +122,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
|
||||
<varlistentry><term><envar>NIX_LOG_DIR</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the Nix log directory
|
||||
(default <filename><replaceable>prefix</replaceable>/log/nix</filename>).</para></listitem>
|
||||
(default <filename><replaceable>prefix</replaceable>/var/log/nix</filename>).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<replaceable>attrPath</replaceable>
|
||||
</arg>
|
||||
<arg><option>--no-out-link</option></arg>
|
||||
<arg><option>--dry-run</option></arg>
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--out-link</option></arg>
|
||||
@@ -98,6 +99,10 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--dry-run</option></term>
|
||||
<listitem><para>Show what store paths would be built or downloaded</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='opt-out-link'><term><option>--out-link</option> /
|
||||
<option>-o</option> <replaceable>outlink</replaceable></term>
|
||||
|
||||
|
||||
@@ -659,7 +659,7 @@ upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
|
||||
<literal>gcc-3.3.1</literal> are split into two parts: the package
|
||||
name (<literal>gcc</literal>), and the version
|
||||
(<literal>3.3.1</literal>). The version part starts after the first
|
||||
dash not following by a letter. <varname>x</varname> is considered an
|
||||
dash not followed by a letter. <varname>x</varname> is considered an
|
||||
upgrade of <varname>y</varname> if their package names match, and the
|
||||
version of <varname>y</varname> is higher that that of
|
||||
<varname>x</varname>.</para>
|
||||
|
||||
@@ -53,7 +53,7 @@ avoided.</para>
|
||||
<para>If <replaceable>hash</replaceable> is specified, then a download
|
||||
is not performed if the Nix store already contains a file with the
|
||||
same hash and base name. Otherwise, the file is downloaded, and an
|
||||
error if signaled if the actual hash of the file does not match the
|
||||
error is signaled if the actual hash of the file does not match the
|
||||
specified hash.</para>
|
||||
|
||||
<para>This command prints the hash on standard output. Additionally,
|
||||
|
||||
@@ -170,18 +170,6 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-splitVersion'>
|
||||
<term><function>builtins.splitVersion</function>
|
||||
<replaceable>s</replaceable></term>
|
||||
|
||||
<listitem><para>Split a string representing a version into its
|
||||
components, by the same version splitting logic underlying the
|
||||
version comparison in <link linkend="ssec-version-comparisons">
|
||||
<command>nix-env -u</command></link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-concatLists'>
|
||||
<term><function>builtins.concatLists</function>
|
||||
<replaceable>lists</replaceable></term>
|
||||
@@ -301,7 +289,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
|
||||
<listitem><para>Return element <replaceable>n</replaceable> from
|
||||
the list <replaceable>xs</replaceable>. Elements are counted
|
||||
starting from 0. A fatal error occurs in the index is out of
|
||||
starting from 0. A fatal error occurs if the index is out of
|
||||
bounds.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
@@ -448,7 +436,7 @@ stdenv.mkDerivation { … }
|
||||
<example>
|
||||
<title>Fetching an arbitrary ref</title>
|
||||
<programlisting>builtins.fetchGit {
|
||||
url = "https://gitub.com/NixOS/nix.git";
|
||||
url = "https://github.com/NixOS/nix.git";
|
||||
ref = "refs/heads/0.5-release";
|
||||
}</programlisting>
|
||||
</example>
|
||||
@@ -499,11 +487,8 @@ stdenv.mkDerivation { … }
|
||||
<title>Fetching a tag</title>
|
||||
<programlisting>builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
ref = "tags/1.9";
|
||||
ref = "refs/tags/1.9";
|
||||
}</programlisting>
|
||||
<note><para>Due to a bug (<link
|
||||
xlink:href="https://github.com/NixOS/nix/issues/2385">#2385</link>),
|
||||
only non-annotated tags can be fetched.</para></note>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
@@ -761,6 +746,11 @@ builtins.genList (x: x * x) 5
|
||||
separate file, and use it from Nix expressions in other
|
||||
files.</para>
|
||||
|
||||
<note><para>Unlike some languages, <function>import</function> is a regular
|
||||
function in Nix. Paths using the angle bracket syntax (e.g., <function>
|
||||
import</function> <replaceable><foo></replaceable>) are normal path
|
||||
values (see <xref linkend='ssec-values' />).</para></note>
|
||||
|
||||
<para>A Nix expression loaded by <function>import</function> must
|
||||
not contain any <emphasis>free variables</emphasis> (identifiers
|
||||
that are not defined in the Nix expression itself and are not
|
||||
@@ -1130,6 +1120,16 @@ Evaluates to <literal>[ "foo" ]</literal>.
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='builtin-placeholder'>
|
||||
<term><function>builtins.placeholder</function>
|
||||
<replaceable>output</replaceable></term>
|
||||
|
||||
<listitem><para>Return a placeholder string for the specified
|
||||
<replaceable>output</replaceable> that will be substituted by the
|
||||
corresponding output path at build time. Typical outputs would be
|
||||
<literal>"out"</literal>, <literal>"bin"</literal> or
|
||||
<literal>"dev"</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='builtin-readDir'>
|
||||
<term><function>builtins.readDir</function>
|
||||
@@ -1275,6 +1275,19 @@ Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-splitVersion'>
|
||||
<term><function>builtins.splitVersion</function>
|
||||
<replaceable>s</replaceable></term>
|
||||
|
||||
<listitem><para>Split a string representing a version into its
|
||||
components, by the same version splitting logic underlying the
|
||||
version comparison in <link linkend="ssec-version-comparisons">
|
||||
<command>nix-env -u</command></link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-stringLength'>
|
||||
<term><function>builtins.stringLength</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
@@ -1468,7 +1481,7 @@ in foo</programlisting>
|
||||
<listitem><para>A set containing <literal>{ __toString = self: ...; }</literal>.</para></listitem>
|
||||
<listitem><para>An integer.</para></listitem>
|
||||
<listitem><para>A list, in which case the string representations of its elements are joined with spaces.</para></listitem>
|
||||
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>.</para></listitem>
|
||||
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>).</para></listitem>
|
||||
<listitem><para><literal>null</literal>, which yields the empty string.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
@@ -1607,12 +1620,18 @@ stdenv.mkDerivation (rec {
|
||||
<term><function>builtins.tryEval</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Try to evaluate <replaceable>e</replaceable>.
|
||||
<listitem><para>Try to shallowly evaluate <replaceable>e</replaceable>.
|
||||
Return a set containing the attributes <literal>success</literal>
|
||||
(<literal>true</literal> if <replaceable>e</replaceable> evaluated
|
||||
successfully, <literal>false</literal> if an error was thrown) and
|
||||
<literal>value</literal>, equalling <replaceable>e</replaceable>
|
||||
if successful and <literal>false</literal> otherwise.
|
||||
if successful and <literal>false</literal> otherwise. Note that this
|
||||
doesn't evaluate <replaceable>e</replaceable> deeply, so
|
||||
<literal>let e = { x = throw ""; }; in (builtins.tryEval e).success
|
||||
</literal> will be <literal>true</literal>. Using <literal>builtins.deepSeq
|
||||
</literal> one can get the expected result: <literal>let e = { x = throw "";
|
||||
}; in (builtins.tryEval (builtins.deepSeq e e)).success</literal> will be
|
||||
<literal>false</literal>.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -43,7 +43,7 @@ use <command>nix-build</command>’s <option
|
||||
linkend='opt-out-link'>-o</option> switch to give the symlink another
|
||||
name.</para>
|
||||
|
||||
<para>Nix has a transactional semantics. Once a build finishes
|
||||
<para>Nix has transactional semantics. Once a build finishes
|
||||
successfully, Nix makes a note of this in its database: it registers
|
||||
that the path denoted by <envar>out</envar> is now
|
||||
<quote>valid</quote>. If you try to build the derivation again, Nix
|
||||
|
||||
@@ -4,7 +4,6 @@ ifeq ($(doc_generate),yes)
|
||||
XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
|
||||
--param section.autolabel 1 \
|
||||
--param section.label.includes.component.label 1 \
|
||||
--param html.stylesheet \'style.css\' \
|
||||
--param xref.with.number.and.title 1 \
|
||||
--param toc.section.depth 3 \
|
||||
--param admon.style \'\' \
|
||||
@@ -66,7 +65,7 @@ $(d)/manual.html: $(d)/manual.xml $(MANUAL_SRCS) $(d)/manual.is-valid
|
||||
$(docbookxsl)/profiling/profile.xsl $< | \
|
||||
$(XSLTPROC) --output $@ $(docbookxsl)/xhtml/docbook.xsl -
|
||||
|
||||
$(foreach file, $(d)/manual.html $(d)/style.css, $(eval $(call install-data-in, $(file), $(docdir)/manual)))
|
||||
$(foreach file, $(d)/manual.html, $(eval $(call install-data-in, $(file), $(docdir)/manual)))
|
||||
|
||||
$(foreach file, $(wildcard $(d)/figures/*.png), $(eval $(call install-data-in, $(file), $(docdir)/manual/figures)))
|
||||
|
||||
|
||||
@@ -52,12 +52,13 @@ garbage collector as follows:
|
||||
<screen>
|
||||
$ nix-store --gc</screen>
|
||||
|
||||
The behaviour of the gargage collector is affected by the <literal>keep-
|
||||
derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
||||
The behaviour of the gargage collector is affected by the
|
||||
<literal>keep-derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
||||
(default: false) options in the Nix configuration file. The defaults will ensure
|
||||
that all derivations that are not build-time dependencies of garbage collector roots
|
||||
will be collected but that all output paths that are not runtime dependencies
|
||||
will be collected. (This is usually what you want, but while you are developing
|
||||
that all derivations that are build-time dependencies of garbage collector roots
|
||||
will be kept and that all output paths that are runtime dependencies
|
||||
will be kept as well. All other derivations or paths will be collected.
|
||||
(This is usually what you want, but while you are developing
|
||||
it may make sense to keep outputs to ensure that rebuild times are quick.)
|
||||
|
||||
If you are feeling uncertain, you can also first view what files would
|
||||
|
||||
@@ -159,7 +159,6 @@ the S3 URL:</para>
|
||||
"s3:ListBucket",
|
||||
"s3:ListBucketMultipartUploads",
|
||||
"s3:ListMultipartUploadParts",
|
||||
"s3:ListObjects",
|
||||
"s3:PutObject"
|
||||
],
|
||||
"Resource": [
|
||||
|
||||
@@ -13,9 +13,8 @@ incompatible changes:</para>
|
||||
|
||||
<listitem>
|
||||
<para>Nix now uses BSD file locks instead of POSIX file
|
||||
locks. Since previous releases used POSIX file locks, you should
|
||||
not use Nix 2.2 and previous releases at the same time on a Nix
|
||||
store.</para>
|
||||
locks. Because of this, you should not use Nix 2.3 and previous
|
||||
releases at the same time on a Nix store.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
@@ -34,9 +33,13 @@ incompatible changes:</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The installer now enables sandboxing by default on
|
||||
Linux. The <literal>max-jobs</literal> setting now defaults to
|
||||
1.</para>
|
||||
<para>The installer now enables sandboxing by default on Linux when the
|
||||
system has the necessary kernel support.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <literal>max-jobs</literal> setting now defaults to 1.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -47,9 +50,9 @@ incompatible changes:</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>nix</command>: Add
|
||||
<para>The <command>nix</command> command has a new
|
||||
<option>--print-build-logs</option> (<option>-L</option>) flag to
|
||||
print build log output to stderr rather than showing the last log
|
||||
print build log output to stderr, rather than showing the last log
|
||||
line in the progress bar. To distinguish between concurrent
|
||||
builds, log lines are prefixed by the name of the package.
|
||||
</para>
|
||||
@@ -57,7 +60,7 @@ incompatible changes:</para>
|
||||
|
||||
<listitem>
|
||||
<para>Builds are now executed in a pseudo-terminal, and the
|
||||
<envar>TERM</envar> evnironment variable is set to
|
||||
<envar>TERM</envar> environment variable is set to
|
||||
<literal>xterm-256color</literal>. This allows many programs
|
||||
(e.g. <command>gcc</command>, <command>clang</command>,
|
||||
<command>cmake</command>) to print colorized log output.</para>
|
||||
@@ -83,11 +86,6 @@ incompatible changes:</para>
|
||||
the duration of Nix function calls to stderr.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>On Linux, sandboxing is now disabled by default on systems
|
||||
that don’t have the necessary kernel support.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
/* Copied from http://bakefile.sourceforge.net/, which appears
|
||||
licensed under the GNU GPL. */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Basic headers and text:
|
||||
***************************************************************************/
|
||||
|
||||
body
|
||||
{
|
||||
font-family: "Nimbus Sans L", sans-serif;
|
||||
background: white;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4
|
||||
{
|
||||
color: #005aa0;
|
||||
}
|
||||
|
||||
h1 /* title */
|
||||
{
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
div.part h1
|
||||
{
|
||||
font-size: 240%;
|
||||
}
|
||||
|
||||
h2 /* chapters, appendices, subtitle */
|
||||
{
|
||||
font-size: 180%;
|
||||
}
|
||||
|
||||
div.part
|
||||
{
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
/* Extra space between chapters, appendices. */
|
||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||
{
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.section > div.titlepage h2 /* sections */
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
h3 /* subsections */
|
||||
{
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.simplesect h2
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.appendix h3
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.refentry\.separator
|
||||
{
|
||||
margin-top: 2.5em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
|
||||
{
|
||||
margin-top: 1.4em;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.refsection h3
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Examples:
|
||||
***************************************************************************/
|
||||
|
||||
div.example
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
background: #f4f4f8;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
|
||||
div.example p.title
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.example pre
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Screen dumps:
|
||||
***************************************************************************/
|
||||
|
||||
pre.screen, pre.programlisting
|
||||
{
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
color: #600000;
|
||||
background: #f4f4f8;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
div.example pre.programlisting
|
||||
{
|
||||
border: 0px;
|
||||
padding: 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Notes, warnings etc:
|
||||
***************************************************************************/
|
||||
|
||||
.note, .warning
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0.3em 0.3em 0.3em 0.3em;
|
||||
background: #fffff5;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
|
||||
div.note, div.warning
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.note h3, div.warning h3
|
||||
{
|
||||
color: red;
|
||||
font-size: 100%;
|
||||
padding-right: 0.5em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note p, div.warning p
|
||||
{
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
div.note h3 + p, div.warning h3 + p
|
||||
{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note h3
|
||||
{
|
||||
color: blue;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
div.navfooter *
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Links colors and highlighting:
|
||||
***************************************************************************/
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
a:link { color: #0048b3; }
|
||||
a:visited { color: #002a6a; }
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Table of contents:
|
||||
***************************************************************************/
|
||||
|
||||
div.toc
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.toc dl
|
||||
{
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Special elements:
|
||||
***************************************************************************/
|
||||
|
||||
tt, code
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
.term
|
||||
{
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
div.variablelist dd p, div.glosslist dd p
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.variablelist dd, div.glosslist dd
|
||||
{
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
div.glosslist dt
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.varname
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
span.command strong
|
||||
{
|
||||
font-weight: normal;
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
div.calloutlist table
|
||||
{
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div.affiliation
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
<array>
|
||||
<string>/bin/sh</string>
|
||||
<string>-c</string>
|
||||
<string>/bin/wait4path @bindir@/nix-daemon && @bindir@/nix-daemon</string>
|
||||
<string>/bin/wait4path /nix/var/nix/profiles/default/bin/nix-daemon && /nix/var/nix/profiles/default/bin/nix-daemon</string>
|
||||
</array>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/log/nix-daemon.log</string>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
This is a set of helper Makefiles for doing non-recursive builds with
|
||||
GNU Make. The canonical source can be found at
|
||||
https://github.com/edolstra/make-rules. You should copy the files
|
||||
into the `mk` subdirectory of your project.
|
||||
|
||||
TODO: write more documentation.
|
||||
@@ -106,7 +106,7 @@ chmod 1775 $RPM_BUILD_ROOT/nix/store
|
||||
for d in profiles gcroots;
|
||||
do
|
||||
mkdir -p $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
|
||||
chmod 1777 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
|
||||
chmod 755 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
|
||||
done
|
||||
|
||||
# fix permission of nix profile
|
||||
|
||||
@@ -50,7 +50,7 @@ rec {
|
||||
buildDeps =
|
||||
[ curl
|
||||
bzip2 xz brotli editline
|
||||
openssl pkgconfig sqlite boehmgc
|
||||
openssl pkgconfig sqlite
|
||||
boost
|
||||
|
||||
# Tests
|
||||
@@ -72,6 +72,10 @@ rec {
|
||||
*/
|
||||
}));
|
||||
|
||||
propagatedDeps =
|
||||
[ (boehmgc.override { enableLargeConfig = true; })
|
||||
];
|
||||
|
||||
perlDeps =
|
||||
[ perl
|
||||
perlPackages.DBDSQLite
|
||||
|
||||
18
release.nix
18
release.nix
@@ -23,7 +23,7 @@ let
|
||||
src = nix;
|
||||
inherit officialRelease;
|
||||
|
||||
buildInputs = tarballDeps ++ buildDeps;
|
||||
buildInputs = tarballDeps ++ buildDeps ++ propagatedDeps;
|
||||
|
||||
configureFlags = "--enable-gc";
|
||||
|
||||
@@ -67,6 +67,8 @@ let
|
||||
|
||||
buildInputs = buildDeps;
|
||||
|
||||
propagatedBuildInputs = propagatedDeps;
|
||||
|
||||
preConfigure =
|
||||
# Copy libboost_context so we don't get all of Boost in our closure.
|
||||
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||
@@ -91,6 +93,8 @@ let
|
||||
|
||||
doInstallCheck = true;
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
separateDebugInfo = true;
|
||||
});
|
||||
|
||||
|
||||
@@ -128,7 +132,7 @@ let
|
||||
in
|
||||
|
||||
runCommand "nix-binary-tarball-${version}"
|
||||
{ nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
|
||||
{ #nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
|
||||
meta.description = "Distribution-independent Nix bootstrap binaries for ${system}";
|
||||
}
|
||||
''
|
||||
@@ -196,7 +200,9 @@ let
|
||||
name = "nix-build";
|
||||
src = tarball;
|
||||
|
||||
buildInputs = buildDeps;
|
||||
enableParallelBuilding = true;
|
||||
|
||||
buildInputs = buildDeps ++ propagatedDeps;
|
||||
|
||||
dontInstall = false;
|
||||
|
||||
@@ -271,6 +277,7 @@ let
|
||||
umount /nix
|
||||
''); # */
|
||||
|
||||
/*
|
||||
tests.evalNixpkgs =
|
||||
import (nixpkgs + "/pkgs/top-level/make-tarball.nix") {
|
||||
inherit nixpkgs;
|
||||
@@ -289,6 +296,7 @@ let
|
||||
|
||||
touch $out
|
||||
'';
|
||||
*/
|
||||
|
||||
|
||||
installerScript =
|
||||
@@ -326,8 +334,8 @@ let
|
||||
tests.remoteBuilds
|
||||
tests.nix-copy-closure
|
||||
tests.binaryTarball
|
||||
tests.evalNixpkgs
|
||||
tests.evalNixOS
|
||||
#tests.evalNixpkgs
|
||||
#tests.evalNixOS
|
||||
installerScript
|
||||
];
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ EOF
|
||||
|
||||
poly_configure_nix_daemon_service() {
|
||||
_sudo "to set up the nix-daemon as a LaunchDaemon" \
|
||||
ln -sfn "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST"
|
||||
cp -f "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST"
|
||||
|
||||
_sudo "to load the LaunchDaemon plist for nix-daemon" \
|
||||
launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||
|
||||
@@ -13,15 +13,12 @@ set -o pipefail
|
||||
# however tracking which bits came from which would be impossible.
|
||||
|
||||
readonly ESC='\033[0m'
|
||||
readonly BOLD='\033[38;1m'
|
||||
readonly BLUE='\033[38;34m'
|
||||
readonly BLUE_UL='\033[38;4;34m'
|
||||
readonly GREEN='\033[38;32m'
|
||||
readonly GREEN_UL='\033[38;4;32m'
|
||||
readonly RED='\033[38;31m'
|
||||
readonly RED_UL='\033[38;4;31m'
|
||||
readonly YELLOW='\033[38;33m'
|
||||
readonly YELLOW_UL='\033[38;4;33m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly BLUE_UL='\033[4;34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly GREEN_UL='\033[4;32m'
|
||||
readonly RED='\033[31m'
|
||||
|
||||
readonly NIX_USER_COUNT="32"
|
||||
readonly NIX_BUILD_GROUP_ID="30000"
|
||||
@@ -529,24 +526,17 @@ create_build_users() {
|
||||
}
|
||||
|
||||
create_directories() {
|
||||
# FIXME: remove all of this because it duplicates LocalStore::LocalStore().
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 1)" \
|
||||
mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool}
|
||||
mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool} /nix/var/nix/{gcroots,profiles}/per-user
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 2)" \
|
||||
mkdir -pv -m 1777 /nix/var/nix/{gcroots,profiles}/per-user
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 3)" \
|
||||
mkdir -pv -m 1775 /nix/store
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 4)" \
|
||||
_sudo "to make the basic directory structure of Nix (part 3)" \
|
||||
chgrp "$NIX_BUILD_GROUP_NAME" /nix/store
|
||||
|
||||
_sudo "to set up the root user's profile (part 1)" \
|
||||
mkdir -pv -m 0755 /nix/var/nix/profiles/per-user/root
|
||||
|
||||
_sudo "to set up the root user's profile (part 2)" \
|
||||
mkdir -pv -m 0700 "$ROOT_HOME/.nix-defexpr"
|
||||
|
||||
_sudo "to place the default nix daemon configuration (part 1)" \
|
||||
mkdir -pv -m 0555 /etc/nix
|
||||
}
|
||||
@@ -589,7 +579,7 @@ EOF
|
||||
We will:
|
||||
|
||||
- make sure your computer doesn't already have Nix files
|
||||
(if it does, I will tell you how to clean them up.)
|
||||
(if it does, I will tell you how to clean them up.)
|
||||
- create local users (see the list above for the users we'll make)
|
||||
- create a local group ($NIX_BUILD_GROUP_NAME)
|
||||
- install Nix in to $NIX_ROOT
|
||||
|
||||
@@ -141,11 +141,9 @@ if [ -z "$_NIX_INSTALLER_TEST" ]; then
|
||||
fi
|
||||
|
||||
added=
|
||||
p=$HOME/.nix-profile/etc/profile.d/nix.sh
|
||||
if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
|
||||
|
||||
# Make the shell source nix.sh during login.
|
||||
p=$HOME/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
for i in .bash_profile .bash_login .profile; do
|
||||
fn="$HOME/$i"
|
||||
if [ -w "$fn" ]; then
|
||||
@@ -157,7 +155,6 @@ if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if [ -z "$added" ]; then
|
||||
|
||||
@@ -5,45 +5,6 @@ __ETC_PROFILE_NIX_SOURCED=1
|
||||
export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER"
|
||||
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
|
||||
|
||||
# Set up the per-user profile.
|
||||
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
|
||||
if ! test -O "$NIX_USER_PROFILE_DIR"; then
|
||||
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2
|
||||
fi
|
||||
|
||||
if test -w $HOME; then
|
||||
if ! test -L $HOME/.nix-profile; then
|
||||
if test "$USER" != root; then
|
||||
ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile
|
||||
else
|
||||
# Root installs in the system-wide profile by default.
|
||||
ln -s @localstatedir@/nix/profiles/default $HOME/.nix-profile
|
||||
fi
|
||||
fi
|
||||
|
||||
# Subscribe the root user to the NixOS channel by default.
|
||||
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $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 -O "$NIX_USER_GCROOTS_DIR"; 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
|
||||
rm -f $HOME/.nix-defexpr
|
||||
mkdir -p $HOME/.nix-defexpr
|
||||
if [ "$USER" != root ]; then
|
||||
ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
|
||||
if [ ! -z "${NIX_SSL_CERT_FILE:-}" ]; then
|
||||
: # Allow users to override the NIX_SSL_CERT_FILE
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
||||
__savedpath="$PATH"
|
||||
export PATH=@coreutils@
|
||||
|
||||
# Set up the per-user profile.
|
||||
# This part should be kept in sync with nixpkgs:nixos/modules/programs/shell.nix
|
||||
@@ -9,48 +7,6 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
||||
|
||||
NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER
|
||||
|
||||
mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR"
|
||||
|
||||
if [ "$(stat --printf '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then
|
||||
echo "Nix: WARNING: bad ownership on "$NIX_USER_PROFILE_DIR", should be $(id -u)" >&2
|
||||
fi
|
||||
|
||||
if [ -w "$HOME" ]; then
|
||||
if ! [ -L "$NIX_LINK" ]; then
|
||||
echo "Nix: creating $NIX_LINK" >&2
|
||||
if [ "$USER" != root ]; then
|
||||
if ! ln -s "$NIX_USER_PROFILE_DIR"/profile "$NIX_LINK"; then
|
||||
echo "Nix: WARNING: could not create $NIX_LINK -> $NIX_USER_PROFILE_DIR/profile" >&2
|
||||
fi
|
||||
else
|
||||
# Root installs in the system-wide profile by default.
|
||||
ln -s @localstatedir@/nix/profiles/default "$NIX_LINK"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Subscribe the user to the unstable Nixpkgs channel by default.
|
||||
if [ ! -e "$HOME/.nix-channels" ]; then
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
|
||||
fi
|
||||
|
||||
# Create the per-user garbage collector roots directory.
|
||||
__user_gcroots=@localstatedir@/nix/gcroots/per-user/"$USER"
|
||||
mkdir -m 0755 -p "$__user_gcroots"
|
||||
if [ "$(stat --printf '%u' "$__user_gcroots")" != "$(id -u)" ]; then
|
||||
echo "Nix: WARNING: bad ownership on $__user_gcroots, should be $(id -u)" >&2
|
||||
fi
|
||||
unset __user_gcroots
|
||||
|
||||
# Set up a default Nix expression from which to install stuff.
|
||||
__nix_defexpr="$HOME"/.nix-defexpr
|
||||
[ -L "$__nix_defexpr" ] && rm -f "$__nix_defexpr"
|
||||
mkdir -m 0755 -p "$__nix_defexpr"
|
||||
if [ "$USER" != root ] && [ ! -L "$__nix_defexpr"/channels_root ]; then
|
||||
ln -s @localstatedir@/nix/profiles/per-user/root/channels "$__nix_defexpr"/channels_root
|
||||
fi
|
||||
unset __nix_defexpr
|
||||
fi
|
||||
|
||||
# Append ~/.nix-defexpr/channels to $NIX_PATH so that <nixpkgs>
|
||||
# paths work when the user has fetched the Nixpkgs channel.
|
||||
export NIX_PATH=${NIX_PATH:+$NIX_PATH:}$HOME/.nix-defexpr/channels
|
||||
@@ -78,6 +34,6 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
||||
export MANPATH="$NIX_LINK/share/man:$MANPATH"
|
||||
fi
|
||||
|
||||
export PATH="$NIX_LINK/bin:$__savedpath"
|
||||
unset __savedpath NIX_LINK NIX_USER_PROFILE_DIR
|
||||
export PATH="$NIX_LINK/bin:$PATH"
|
||||
unset NIX_LINK NIX_USER_PROFILE_DIR
|
||||
fi
|
||||
|
||||
@@ -7,7 +7,7 @@ with import ./release-common.nix { inherit pkgs; };
|
||||
(if useClang then clangStdenv else stdenv).mkDerivation {
|
||||
name = "nix";
|
||||
|
||||
buildInputs = buildDeps ++ tarballDeps ++ perlDeps;
|
||||
buildInputs = buildDeps ++ propagatedDeps ++ tarballDeps ++ perlDeps;
|
||||
|
||||
inherit configureFlags;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "eval-inline.hh"
|
||||
#include "download.hh"
|
||||
#include "json.hh"
|
||||
#include "function-trace.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@@ -519,9 +520,9 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun
|
||||
throw TypeError(format(s) % fun.showNamePos() % s2 % pos);
|
||||
}
|
||||
|
||||
LocalNoInlineNoReturn(void throwAssertionError(const char * s, const Pos & pos))
|
||||
LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos))
|
||||
{
|
||||
throw AssertionError(format(s) % pos);
|
||||
throw AssertionError(format(s) % s1 % pos);
|
||||
}
|
||||
|
||||
LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos))
|
||||
@@ -877,7 +878,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||
if (hasOverrides) {
|
||||
Value * vOverrides = (*v.attrs)[overrides->second.displ].value;
|
||||
state.forceAttrs(*vOverrides);
|
||||
Bindings * newBnds = state.allocBindings(v.attrs->size() + vOverrides->attrs->size());
|
||||
Bindings * newBnds = state.allocBindings(v.attrs->capacity() + vOverrides->attrs->size());
|
||||
for (auto & i : *v.attrs)
|
||||
newBnds->push_back(i);
|
||||
for (auto & i : *vOverrides->attrs) {
|
||||
@@ -1096,10 +1097,7 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos)
|
||||
|
||||
void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos)
|
||||
{
|
||||
std::optional<FunctionCallTrace> trace;
|
||||
if (evalSettings.traceFunctionCalls) {
|
||||
trace.emplace(pos);
|
||||
}
|
||||
auto trace = evalSettings.traceFunctionCalls ? std::make_unique<FunctionCallTrace>(pos) : nullptr;
|
||||
|
||||
forceValue(fun, pos);
|
||||
|
||||
@@ -1255,8 +1253,11 @@ void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
||||
|
||||
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
if (!state.evalBool(env, cond, pos))
|
||||
throwAssertionError("assertion failed at %1%", pos);
|
||||
if (!state.evalBool(env, cond, pos)) {
|
||||
std::ostringstream out;
|
||||
cond->show(out);
|
||||
throwAssertionError("assertion %1% failed at %2%", out.str(), pos);
|
||||
}
|
||||
body->eval(state, env, v);
|
||||
}
|
||||
|
||||
@@ -1569,6 +1570,19 @@ bool EvalState::isDerivation(Value & v)
|
||||
}
|
||||
|
||||
|
||||
std::optional<string> EvalState::tryAttrsToString(const Pos & pos, Value & v,
|
||||
PathSet & context, bool coerceMore, bool copyToStore)
|
||||
{
|
||||
auto i = v.attrs->find(sToString);
|
||||
if (i != v.attrs->end()) {
|
||||
Value v1;
|
||||
callFunction(*i->value, v, v1, pos);
|
||||
return coerceToString(pos, v1, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||
bool coerceMore, bool copyToStore)
|
||||
{
|
||||
@@ -1587,13 +1601,11 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||
}
|
||||
|
||||
if (v.type == tAttrs) {
|
||||
auto i = v.attrs->find(sToString);
|
||||
if (i != v.attrs->end()) {
|
||||
Value v1;
|
||||
callFunction(*i->value, v, v1, pos);
|
||||
return coerceToString(pos, v1, context, coerceMore, copyToStore);
|
||||
auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
|
||||
if (maybeString) {
|
||||
return *maybeString;
|
||||
}
|
||||
i = v.attrs->find(sOutPath);
|
||||
auto i = v.attrs->find(sOutPath);
|
||||
if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos);
|
||||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "symbol-table.hh"
|
||||
#include "hash.hh"
|
||||
#include "config.hh"
|
||||
#include "function-trace.hh"
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
@@ -196,6 +196,9 @@ public:
|
||||
set with attribute `type = "derivation"'). */
|
||||
bool isDerivation(Value & v);
|
||||
|
||||
std::optional<string> tryAttrsToString(const Pos & pos, Value & v,
|
||||
PathSet & context, bool coerceMore = false, bool copyToStore = true);
|
||||
|
||||
/* String coercion. Converts strings, paths and derivations to a
|
||||
string. If `coerceMore' is set, also converts nulls, integers,
|
||||
booleans and lists to a string. If `copyToStore' is set,
|
||||
|
||||
17
src/libexpr/function-trace.cc
Normal file
17
src/libexpr/function-trace.cc
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "function-trace.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
FunctionCallTrace::FunctionCallTrace(const Pos & pos) : pos(pos) {
|
||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||
printMsg(lvlInfo, "function-trace entered %1% at %2%", pos, ns.count());
|
||||
}
|
||||
|
||||
FunctionCallTrace::~FunctionCallTrace() {
|
||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||
printMsg(lvlInfo, "function-trace exited %1% at %2%", pos, ns.count());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "eval.hh"
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct FunctionCallTrace
|
||||
{
|
||||
const Pos & pos;
|
||||
|
||||
FunctionCallTrace(const Pos & pos) : pos(pos) {
|
||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||
vomit("function-trace entered %1% at %2%", pos, ns.count());
|
||||
}
|
||||
|
||||
~FunctionCallTrace() {
|
||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||
vomit("function-trace exited %1% at %2%", pos, ns.count());
|
||||
}
|
||||
FunctionCallTrace(const Pos & pos);
|
||||
~FunctionCallTrace();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -111,9 +111,9 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
|
||||
mkFloat(v, stod(tmp_number));
|
||||
else
|
||||
mkInt(v, stol(tmp_number));
|
||||
} catch (std::invalid_argument e) {
|
||||
} catch (std::invalid_argument & e) {
|
||||
throw JSONParseError("invalid JSON number");
|
||||
} catch (std::out_of_range e) {
|
||||
} catch (std::out_of_range & e) {
|
||||
throw JSONParseError("out-of-range JSON number");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2089,12 +2089,12 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
|
||||
if (evalSettings.pureEval && !request.expectedHash)
|
||||
throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument", who);
|
||||
|
||||
Path res = getDownloader()->downloadCached(state.store, request).path;
|
||||
auto res = getDownloader()->downloadCached(state.store, request);
|
||||
|
||||
if (state.allowedPaths)
|
||||
state.allowedPaths->insert(res);
|
||||
state.allowedPaths->insert(res.path);
|
||||
|
||||
mkString(v, res, PathSet({res}));
|
||||
mkString(v, res.storePath, PathSet({res.storePath}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ GitInfo exportGit(ref<Store> store, const std::string & uri,
|
||||
|
||||
try {
|
||||
runProgram("git", true, { "-C", uri, "diff-index", "--quiet", "HEAD", "--" });
|
||||
} catch (ExecError e) {
|
||||
} catch (ExecError & e) {
|
||||
if (!WIFEXITED(e.status) || WEXITSTATUS(e.status) != 1) throw;
|
||||
clean = false;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,12 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||
break;
|
||||
|
||||
case tAttrs: {
|
||||
Bindings::iterator i = v.attrs->find(state.sOutPath);
|
||||
auto maybeString = state.tryAttrsToString(noPos, v, context, false, false);
|
||||
if (maybeString) {
|
||||
out.write(*maybeString);
|
||||
break;
|
||||
}
|
||||
auto i = v.attrs->find(state.sOutPath);
|
||||
if (i == v.attrs->end()) {
|
||||
auto obj(out.object());
|
||||
StringSet names;
|
||||
|
||||
@@ -80,6 +80,7 @@ string getArg(const string & opt,
|
||||
}
|
||||
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
||||
/* OpenSSL is not thread-safe by default - it will randomly crash
|
||||
unless the user supplies a mutex locking function. So let's do
|
||||
that. */
|
||||
@@ -92,6 +93,7 @@ static void opensslLockCallback(int mode, int type, const char * file, int line)
|
||||
else
|
||||
opensslLocks[type].unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void sigHandler(int signo) { }
|
||||
@@ -105,9 +107,11 @@ void initNix()
|
||||
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
||||
/* Initialise OpenSSL locking. */
|
||||
opensslLocks = std::vector<std::mutex>(CRYPTO_num_locks());
|
||||
CRYPTO_set_locking_callback(opensslLockCallback);
|
||||
#endif
|
||||
|
||||
loadConfFile();
|
||||
|
||||
|
||||
@@ -957,6 +957,9 @@ private:
|
||||
/* Fill in the environment for the builder. */
|
||||
void initEnv();
|
||||
|
||||
/* Setup tmp dir location. */
|
||||
void initTmpDir();
|
||||
|
||||
/* Write a JSON file containing the derivation attributes. */
|
||||
void writeStructuredAttrs();
|
||||
|
||||
@@ -1961,13 +1964,6 @@ void DerivationGoal::startBuilder()
|
||||
auto drvName = storePathToName(drvPath);
|
||||
tmpDir = createTempDir("", "nix-build-" + drvName, false, false, 0700);
|
||||
|
||||
/* In a sandbox, for determinism, always use the same temporary
|
||||
directory. */
|
||||
#if __linux__
|
||||
tmpDirInSandbox = useChroot ? settings.sandboxBuildDir : tmpDir;
|
||||
#else
|
||||
tmpDirInSandbox = tmpDir;
|
||||
#endif
|
||||
chownToBuilder(tmpDir);
|
||||
|
||||
/* Substitute output placeholders with the actual output paths. */
|
||||
@@ -2385,7 +2381,7 @@ void DerivationGoal::startBuilder()
|
||||
int res = helper.wait();
|
||||
if (res != 0 && settings.sandboxFallback) {
|
||||
useChroot = false;
|
||||
tmpDirInSandbox = tmpDir;
|
||||
initTmpDir();
|
||||
goto fallback;
|
||||
} else if (res != 0)
|
||||
throw Error("unable to start build process");
|
||||
@@ -2442,6 +2438,54 @@ void DerivationGoal::startBuilder()
|
||||
}
|
||||
|
||||
|
||||
void DerivationGoal::initTmpDir() {
|
||||
/* In a sandbox, for determinism, always use the same temporary
|
||||
directory. */
|
||||
#if __linux__
|
||||
tmpDirInSandbox = useChroot ? settings.sandboxBuildDir : tmpDir;
|
||||
#else
|
||||
tmpDirInSandbox = tmpDir;
|
||||
#endif
|
||||
|
||||
/* In non-structured mode, add all bindings specified in the
|
||||
derivation via the environment, except those listed in the
|
||||
passAsFile attribute. Those are passed as file names pointing
|
||||
to temporary files containing the contents. Note that
|
||||
passAsFile is ignored in structure mode because it's not
|
||||
needed (attributes are not passed through the environment, so
|
||||
there is no size constraint). */
|
||||
if (!parsedDrv->getStructuredAttrs()) {
|
||||
|
||||
StringSet passAsFile = tokenizeString<StringSet>(get(drv->env, "passAsFile"));
|
||||
int fileNr = 0;
|
||||
for (auto & i : drv->env) {
|
||||
if (passAsFile.find(i.first) == passAsFile.end()) {
|
||||
env[i.first] = i.second;
|
||||
} else {
|
||||
string fn = ".attr-" + std::to_string(fileNr++);
|
||||
Path p = tmpDir + "/" + fn;
|
||||
writeFile(p, rewriteStrings(i.second, inputRewrites));
|
||||
chownToBuilder(p);
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* For convenience, set an environment pointing to the top build
|
||||
directory. */
|
||||
env["NIX_BUILD_TOP"] = tmpDirInSandbox;
|
||||
|
||||
/* Also set TMPDIR and variants to point to this directory. */
|
||||
env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDirInSandbox;
|
||||
|
||||
/* Explicitly set PWD to prevent problems with chroot builds. In
|
||||
particular, dietlibc cannot figure out the cwd because the
|
||||
inode of the current directory doesn't appear in .. (because
|
||||
getdents returns the inode of the mount point). */
|
||||
env["PWD"] = tmpDirInSandbox;
|
||||
}
|
||||
|
||||
void DerivationGoal::initEnv()
|
||||
{
|
||||
env.clear();
|
||||
@@ -2468,43 +2512,7 @@ void DerivationGoal::initEnv()
|
||||
/* The maximum number of cores to utilize for parallel building. */
|
||||
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
|
||||
|
||||
/* In non-structured mode, add all bindings specified in the
|
||||
derivation via the environment, except those listed in the
|
||||
passAsFile attribute. Those are passed as file names pointing
|
||||
to temporary files containing the contents. Note that
|
||||
passAsFile is ignored in structure mode because it's not
|
||||
needed (attributes are not passed through the environment, so
|
||||
there is no size constraint). */
|
||||
if (!parsedDrv->getStructuredAttrs()) {
|
||||
|
||||
StringSet passAsFile = tokenizeString<StringSet>(get(drv->env, "passAsFile"));
|
||||
int fileNr = 0;
|
||||
for (auto & i : drv->env) {
|
||||
if (passAsFile.find(i.first) == passAsFile.end()) {
|
||||
env[i.first] = i.second;
|
||||
} else {
|
||||
string fn = ".attr-" + std::to_string(fileNr++);
|
||||
Path p = tmpDir + "/" + fn;
|
||||
writeFile(p, i.second);
|
||||
chownToBuilder(p);
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* For convenience, set an environment pointing to the top build
|
||||
directory. */
|
||||
env["NIX_BUILD_TOP"] = tmpDirInSandbox;
|
||||
|
||||
/* Also set TMPDIR and variants to point to this directory. */
|
||||
env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDirInSandbox;
|
||||
|
||||
/* Explicitly set PWD to prevent problems with chroot builds. In
|
||||
particular, dietlibc cannot figure out the cwd because the
|
||||
inode of the current directory doesn't appear in .. (because
|
||||
getdents returns the inode of the mount point). */
|
||||
env["PWD"] = tmpDirInSandbox;
|
||||
initTmpDir();
|
||||
|
||||
/* Compatibility hack with Nix <= 0.7: if this is a fixed-output
|
||||
derivation, tell the builder, so that for instance `fetchurl'
|
||||
@@ -2570,6 +2578,7 @@ void DerivationGoal::writeStructuredAttrs()
|
||||
}
|
||||
|
||||
writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
chownToBuilder(tmpDir + "/.attrs.json");
|
||||
|
||||
/* As a convenience to bash scripts, write a shell file that
|
||||
maps all attributes that are representable in bash -
|
||||
@@ -2638,6 +2647,7 @@ void DerivationGoal::writeStructuredAttrs()
|
||||
}
|
||||
|
||||
writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,8 +86,15 @@ struct CurlDownloader : public Downloader
|
||||
, callback(std::move(callback))
|
||||
, finalSink([this](const unsigned char * data, size_t len) {
|
||||
if (this->request.dataCallback) {
|
||||
writtenToSink += len;
|
||||
this->request.dataCallback((char *) data, len);
|
||||
long httpStatus = 0;
|
||||
curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &httpStatus);
|
||||
|
||||
/* Only write data to the sink if this is a
|
||||
successful response. */
|
||||
if (httpStatus == 0 || httpStatus == 200 || httpStatus == 201 || httpStatus == 206) {
|
||||
writtenToSink += len;
|
||||
this->request.dataCallback((char *) data, len);
|
||||
}
|
||||
} else
|
||||
this->result.data->append((char *) data, len);
|
||||
})
|
||||
@@ -357,9 +364,10 @@ struct CurlDownloader : public Downloader
|
||||
} else if (httpStatus == 401 || httpStatus == 403 || httpStatus == 407) {
|
||||
// Don't retry on authentication/authorization failures
|
||||
err = Forbidden;
|
||||
} else if (httpStatus >= 400 && httpStatus < 500 && httpStatus != 408) {
|
||||
} else if (httpStatus >= 400 && httpStatus < 500 && httpStatus != 408 && httpStatus != 429) {
|
||||
// Most 4xx errors are client errors and are probably not worth retrying:
|
||||
// * 408 means the server timed out waiting for us, so we try again
|
||||
// * 429 means too many requests, so we retry (with a delay)
|
||||
err = Misc;
|
||||
} else if (httpStatus == 501 || httpStatus == 505 || httpStatus == 511) {
|
||||
// Let's treat most 5xx (server) errors as transient, except for a handful:
|
||||
@@ -383,6 +391,7 @@ struct CurlDownloader : public Downloader
|
||||
case CURLE_SSL_CACERT_BADFILE:
|
||||
case CURLE_TOO_MANY_REDIRECTS:
|
||||
case CURLE_WRITE_ERROR:
|
||||
case CURLE_UNSUPPORTED_PROTOCOL:
|
||||
err = Misc;
|
||||
break;
|
||||
default: // Shut up warnings
|
||||
|
||||
@@ -91,6 +91,8 @@ class Store;
|
||||
|
||||
struct Downloader
|
||||
{
|
||||
virtual ~Downloader() { }
|
||||
|
||||
/* Enqueue a download request, returning a future to the result of
|
||||
the download. The future may throw a DownloadError
|
||||
exception. */
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
uint64_t narOffset = 0; // regular files only
|
||||
};
|
||||
|
||||
virtual ~FSAccessor() { }
|
||||
|
||||
virtual Stat stat(const Path & path) = 0;
|
||||
|
||||
virtual StringSet readDirectory(const Path & path) = 0;
|
||||
|
||||
@@ -319,7 +319,7 @@ public:
|
||||
"A program to run just before a build to set derivation-specific build settings."};
|
||||
|
||||
Setting<std::string> postBuildHook{this, "", "post-build-hook",
|
||||
"A program to run just after each succesful build."};
|
||||
"A program to run just after each successful build."};
|
||||
|
||||
Setting<std::string> netrcFile{this, fmt("%s/%s", nixConfDir, "netrc"), "netrc-file",
|
||||
"Path to the netrc file used to obtain usernames/passwords for downloads."};
|
||||
|
||||
@@ -70,15 +70,17 @@ LocalStore::LocalStore(const Params & params)
|
||||
createSymlink(profilesDir, gcRootsDir + "/profiles");
|
||||
}
|
||||
|
||||
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
|
||||
createDirs(perUserDir);
|
||||
if (chmod(perUserDir.c_str(), 0755) == -1)
|
||||
throw SysError("could not set permissions on '%s' to 755", perUserDir);
|
||||
}
|
||||
|
||||
createUser(getUserName(), getuid());
|
||||
|
||||
/* Optionally, create directories and set permissions for a
|
||||
multi-user install. */
|
||||
if (getuid() == 0 && settings.buildUsersGroup != "") {
|
||||
|
||||
Path perUserDir = profilesDir + "/per-user";
|
||||
createDirs(perUserDir);
|
||||
if (chmod(perUserDir.c_str(), 01777) == -1)
|
||||
throw SysError(format("could not set permissions on '%1%' to 1777") % perUserDir);
|
||||
|
||||
mode_t perm = 01775;
|
||||
|
||||
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
||||
@@ -879,8 +881,8 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
|
||||
info->references,
|
||||
narInfo ? narInfo->fileSize : 0,
|
||||
info->narSize};
|
||||
} catch (InvalidPath) {
|
||||
} catch (SubstituterDisabled) {
|
||||
} catch (InvalidPath &) {
|
||||
} catch (SubstituterDisabled &) {
|
||||
} catch (Error & e) {
|
||||
if (settings.tryFallback)
|
||||
printError(e.what());
|
||||
@@ -1433,4 +1435,19 @@ void LocalStore::signPathInfo(ValidPathInfo & info)
|
||||
}
|
||||
|
||||
|
||||
void LocalStore::createUser(const std::string & userName, uid_t userId)
|
||||
{
|
||||
for (auto & dir : {
|
||||
fmt("%s/profiles/per-user/%s", stateDir, userName),
|
||||
fmt("%s/gcroots/per-user/%s", stateDir, userName)
|
||||
}) {
|
||||
createDirs(dir);
|
||||
if (chmod(dir.c_str(), 0755) == -1)
|
||||
throw SysError("changing permissions of directory '%s'", dir);
|
||||
if (chown(dir.c_str(), userId, getgid()) == -1)
|
||||
throw SysError("changing owner of directory '%s'", dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -293,6 +293,8 @@ private:
|
||||
|
||||
Path getRealStoreDir() override { return realStoreDir; }
|
||||
|
||||
void createUser(const std::string & userName, uid_t userId) override;
|
||||
|
||||
friend class DerivationGoal;
|
||||
friend class SubstitutionGoal;
|
||||
};
|
||||
|
||||
@@ -39,9 +39,12 @@ libstore_CXXFLAGS = \
|
||||
-DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \
|
||||
-DNIX_BIN_DIR=\"$(bindir)\" \
|
||||
-DNIX_MAN_DIR=\"$(mandir)\" \
|
||||
-DSANDBOX_SHELL="\"$(sandbox_shell)\"" \
|
||||
-DLSOF=\"$(lsof)\"
|
||||
|
||||
ifneq ($(sandbox_shell),)
|
||||
libstore_CXXFLAGS += -DSANDBOX_SHELL="\"$(sandbox_shell)\""
|
||||
endif
|
||||
|
||||
$(d)/local-store.cc: $(d)/schema.sql.gen.hh
|
||||
|
||||
$(d)/build.cc:
|
||||
|
||||
@@ -151,7 +151,7 @@ void RemoteStore::initConnection(Connection & conn)
|
||||
conn.to << PROTOCOL_VERSION;
|
||||
|
||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 14) {
|
||||
int cpu = settings.lockCPU ? lockToCurrentCPU() : -1;
|
||||
int cpu = sameMachine() && settings.lockCPU ? lockToCurrentCPU() : -1;
|
||||
if (cpu != -1)
|
||||
conn.to << 1 << cpu;
|
||||
else
|
||||
@@ -198,6 +198,7 @@ void RemoteStore::setOptions(Connection & conn)
|
||||
overrides.erase(settings.maxSilentTime.name);
|
||||
overrides.erase(settings.buildCores.name);
|
||||
overrides.erase(settings.useSubstitutes.name);
|
||||
overrides.erase(settings.showTrace.name);
|
||||
conn.to << overrides.size();
|
||||
for (auto & i : overrides)
|
||||
conn.to << i.first << i.second.value;
|
||||
|
||||
@@ -29,6 +29,8 @@ public:
|
||||
const Setting<unsigned int> maxConnectionAge{(Store*) this, std::numeric_limits<unsigned int>::max(),
|
||||
"max-connection-age", "number of seconds to reuse a connection"};
|
||||
|
||||
virtual bool sameMachine() = 0;
|
||||
|
||||
RemoteStore(const Params & params);
|
||||
|
||||
/* Implementations of abstract store API methods. */
|
||||
@@ -146,6 +148,9 @@ public:
|
||||
|
||||
std::string getUri() override;
|
||||
|
||||
bool sameMachine()
|
||||
{ return true; }
|
||||
|
||||
private:
|
||||
|
||||
ref<RemoteStore::Connection> openConnection() override;
|
||||
|
||||
@@ -35,6 +35,9 @@ public:
|
||||
return uriScheme + host;
|
||||
}
|
||||
|
||||
bool sameMachine()
|
||||
{ return false; }
|
||||
|
||||
void narFromPath(const Path & path, Sink & sink) override;
|
||||
|
||||
ref<FSAccessor> getFSAccessor() override;
|
||||
|
||||
@@ -33,6 +33,9 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
|
||||
out.create();
|
||||
|
||||
auto conn = std::make_unique<Connection>();
|
||||
ProcessOptions options;
|
||||
options.dieWithParent = false;
|
||||
|
||||
conn->sshPid = startProcess([&]() {
|
||||
restoreSignals();
|
||||
|
||||
@@ -62,8 +65,9 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
|
||||
args.push_back(command);
|
||||
execvp(args.begin()->c_str(), stringsToCharPtrs(args).data());
|
||||
|
||||
throw SysError("executing '%s' on '%s'", command, host);
|
||||
});
|
||||
// could not exec ssh/bash
|
||||
throw SysError("unable to execute '%s'", args.front());
|
||||
}, options);
|
||||
|
||||
|
||||
in.readSide = -1;
|
||||
@@ -90,6 +94,9 @@ Path SSHMaster::startMaster()
|
||||
Pipe out;
|
||||
out.create();
|
||||
|
||||
ProcessOptions options;
|
||||
options.dieWithParent = false;
|
||||
|
||||
state->sshMaster = startProcess([&]() {
|
||||
restoreSignals();
|
||||
|
||||
@@ -108,8 +115,8 @@ Path SSHMaster::startMaster()
|
||||
addCommonSSHOpts(args);
|
||||
execvp(args.begin()->c_str(), stringsToCharPtrs(args).data());
|
||||
|
||||
throw SysError("starting SSH master");
|
||||
});
|
||||
throw SysError("unable to execute '%s'", args.front());
|
||||
}, options);
|
||||
|
||||
out.writeSide = -1;
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ public:
|
||||
unsigned long long & downloadSize, unsigned long long & narSize);
|
||||
|
||||
/* Sort a set of paths topologically under the references
|
||||
relation. If p refers to q, then p preceeds q in this list. */
|
||||
relation. If p refers to q, then p precedes q in this list. */
|
||||
Paths topoSortPaths(const PathSet & paths);
|
||||
|
||||
/* Export multiple paths in the format expected by ‘nix-store
|
||||
@@ -628,6 +628,9 @@ public:
|
||||
return storePath;
|
||||
}
|
||||
|
||||
virtual void createUser(const std::string & userName, uid_t userId)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
Stats stats;
|
||||
|
||||
@@ -475,6 +475,16 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
|
||||
}
|
||||
|
||||
|
||||
std::string getUserName()
|
||||
{
|
||||
auto pw = getpwuid(geteuid());
|
||||
std::string name = pw ? pw->pw_name : getEnv("USER", "");
|
||||
if (name.empty())
|
||||
throw Error("cannot figure out user name");
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
static Lazy<Path> getHome2([]() {
|
||||
Path homeDir = getEnv("HOME");
|
||||
if (homeDir.empty()) {
|
||||
@@ -1442,7 +1452,7 @@ static Sync<std::pair<unsigned short, unsigned short>> windowSize{{0, 0}};
|
||||
static void updateWindowSize()
|
||||
{
|
||||
struct winsize ws;
|
||||
if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
|
||||
if (ioctl(2, TIOCGWINSZ, &ws) == 0) {
|
||||
auto windowSize_(windowSize.lock());
|
||||
windowSize_->first = ws.ws_row;
|
||||
windowSize_->second = ws.ws_col;
|
||||
|
||||
@@ -126,6 +126,8 @@ void deletePath(const Path & path, unsigned long long & bytesFreed);
|
||||
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
|
||||
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
|
||||
|
||||
std::string getUserName();
|
||||
|
||||
/* Return $HOME or the user's home directory from /etc/passwd. */
|
||||
Path getHome();
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ static void _main(int argc, char * * argv)
|
||||
auto absolute = i;
|
||||
try {
|
||||
absolute = canonPath(absPath(i), true);
|
||||
} catch (Error e) {};
|
||||
} catch (Error & e) {};
|
||||
if (store->isStorePath(absolute) && std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
|
||||
drvs.push_back(DrvInfo(*state, store, absolute));
|
||||
else
|
||||
|
||||
@@ -159,13 +159,7 @@ static int _main(int argc, char ** argv)
|
||||
nixDefExpr = home + "/.nix-defexpr";
|
||||
|
||||
// Figure out the name of the channels profile.
|
||||
;
|
||||
auto pw = getpwuid(geteuid());
|
||||
std::string name = pw ? pw->pw_name : getEnv("USER", "");
|
||||
if (name.empty())
|
||||
throw Error("cannot figure out user name");
|
||||
profile = settings.nixStateDir + "/profiles/per-user/" + name + "/channels";
|
||||
createDirs(dirOf(profile));
|
||||
profile = fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName());
|
||||
|
||||
enum {
|
||||
cNone,
|
||||
|
||||
@@ -742,7 +742,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||
}
|
||||
|
||||
|
||||
static void processConnection(bool trusted)
|
||||
static void processConnection(bool trusted,
|
||||
const std::string & userName, uid_t userId)
|
||||
{
|
||||
MonitorFdHup monitor(from.fd);
|
||||
|
||||
@@ -793,6 +794,8 @@ static void processConnection(bool trusted)
|
||||
params["path-info-cache-size"] = "0";
|
||||
auto store = openStore(settings.storeUri, params);
|
||||
|
||||
store->createUser(userName, userId);
|
||||
|
||||
tunnelLogger->stopWork();
|
||||
to.flush();
|
||||
|
||||
@@ -1053,7 +1056,7 @@ static void daemonLoop(char * * argv)
|
||||
/* Handle the connection. */
|
||||
from.fd = remote.get();
|
||||
to.fd = remote.get();
|
||||
processConnection(trusted);
|
||||
processConnection(trusted, user, peer.uid);
|
||||
|
||||
exit(0);
|
||||
}, options);
|
||||
@@ -1133,7 +1136,7 @@ static int _main(int argc, char * * argv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
processConnection(true);
|
||||
processConnection(true, "root", 0);
|
||||
}
|
||||
} else {
|
||||
daemonLoop(argv);
|
||||
|
||||
@@ -193,12 +193,6 @@ static void loadDerivations(EvalState & state, Path nixExprPath,
|
||||
}
|
||||
|
||||
|
||||
static Path getDefNixExprPath()
|
||||
{
|
||||
return getHome() + "/.nix-defexpr";
|
||||
}
|
||||
|
||||
|
||||
static long getPriority(EvalState & state, DrvInfo & drv)
|
||||
{
|
||||
return drv.queryMetaInt("priority", 0);
|
||||
@@ -1330,9 +1324,22 @@ static int _main(int argc, char * * argv)
|
||||
Globals globals;
|
||||
|
||||
globals.instSource.type = srcUnknown;
|
||||
globals.instSource.nixExprPath = getDefNixExprPath();
|
||||
globals.instSource.nixExprPath = getHome() + "/.nix-defexpr";
|
||||
globals.instSource.systemFilter = "*";
|
||||
|
||||
if (!pathExists(globals.instSource.nixExprPath)) {
|
||||
try {
|
||||
createDirs(globals.instSource.nixExprPath);
|
||||
replaceSymlink(
|
||||
fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()),
|
||||
globals.instSource.nixExprPath + "/channels");
|
||||
if (getuid() != 0)
|
||||
replaceSymlink(
|
||||
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir),
|
||||
globals.instSource.nixExprPath + "/channels_root");
|
||||
} catch (Error &) { }
|
||||
}
|
||||
|
||||
globals.dryRun = false;
|
||||
globals.preserveInstalled = false;
|
||||
globals.removeAll = false;
|
||||
@@ -1425,9 +1432,18 @@ static int _main(int argc, char * * argv)
|
||||
|
||||
if (globals.profile == "") {
|
||||
Path profileLink = getHome() + "/.nix-profile";
|
||||
globals.profile = pathExists(profileLink)
|
||||
? absPath(readLink(profileLink), dirOf(profileLink))
|
||||
: canonPath(settings.nixStateDir + "/profiles/default");
|
||||
try {
|
||||
if (!pathExists(profileLink)) {
|
||||
replaceSymlink(
|
||||
getuid() == 0
|
||||
? settings.nixStateDir + "/profiles/default"
|
||||
: fmt("%s/profiles/per-user/%s/profile", settings.nixStateDir, getUserName()),
|
||||
profileLink);
|
||||
}
|
||||
globals.profile = absPath(readLink(profileLink), dirOf(profileLink));
|
||||
} catch (Error &) {
|
||||
globals.profile = profileLink;
|
||||
}
|
||||
}
|
||||
|
||||
op(globals, opFlags, opArgs);
|
||||
|
||||
@@ -55,7 +55,7 @@ struct CmdEdit : InstallableCommand
|
||||
int lineno;
|
||||
try {
|
||||
lineno = std::stoi(std::string(pos, colon + 1));
|
||||
} catch (std::invalid_argument e) {
|
||||
} catch (std::invalid_argument & e) {
|
||||
throw Error("cannot parse line number '%s'", pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,31 +39,32 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
|
||||
|
||||
auto searchPath = state.getSearchPath();
|
||||
|
||||
state.mkAttrs(*vSourceExpr, searchPath.size() + 1);
|
||||
state.mkAttrs(*vSourceExpr, 1024);
|
||||
|
||||
mkBool(*state.allocAttr(*vSourceExpr, sToplevel), true);
|
||||
|
||||
std::unordered_set<std::string> seen;
|
||||
|
||||
for (auto & i : searchPath) {
|
||||
if (i.first == "") continue;
|
||||
if (seen.count(i.first)) continue;
|
||||
seen.insert(i.first);
|
||||
#if 0
|
||||
auto res = state.resolveSearchPathElem(i);
|
||||
if (!res.first) continue;
|
||||
if (!pathExists(res.second)) continue;
|
||||
mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
|
||||
state.getBuiltin("import"),
|
||||
mkString(*state.allocValue(), res.second));
|
||||
#endif
|
||||
auto addEntry = [&](const std::string & name) {
|
||||
if (name == "") return;
|
||||
if (!seen.insert(name).second) return;
|
||||
Value * v1 = state.allocValue();
|
||||
mkPrimOpApp(*v1, state.getBuiltin("findFile"), state.getBuiltin("nixPath"));
|
||||
Value * v2 = state.allocValue();
|
||||
mkApp(*v2, *v1, mkString(*state.allocValue(), i.first));
|
||||
mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(i.first)),
|
||||
mkApp(*v2, *v1, mkString(*state.allocValue(), name));
|
||||
mkApp(*state.allocAttr(*vSourceExpr, state.symbols.create(name)),
|
||||
state.getBuiltin("import"), *v2);
|
||||
}
|
||||
};
|
||||
|
||||
for (auto & i : searchPath)
|
||||
/* Hack to handle channels. */
|
||||
if (i.first.empty() && pathExists(i.second + "/manifest.nix")) {
|
||||
for (auto & j : readDirectory(i.second))
|
||||
if (j.name != "manifest.nix"
|
||||
&& pathExists(fmt("%s/%s/default.nix", i.second, j.name)))
|
||||
addEntry(j.name);
|
||||
} else
|
||||
addEntry(i.first);
|
||||
|
||||
vSourceExpr->attrs->sort();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
extern std::string chrootHelperName;
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
void log(State & state, Verbosity lvl, const std::string & s)
|
||||
{
|
||||
if (state.active) {
|
||||
writeToStderr("\r\e[K" + s + ANSI_NORMAL "\n");
|
||||
writeToStderr("\r\e[K" + filterANSIEscapes(s, !isTTY) + ANSI_NORMAL "\n");
|
||||
draw(state);
|
||||
} else {
|
||||
auto s2 = s + ANSI_NORMAL "\n";
|
||||
@@ -341,7 +341,7 @@ public:
|
||||
}
|
||||
|
||||
auto width = getWindowSize().second;
|
||||
if (width <= 0) std::numeric_limits<decltype(width)>::max();
|
||||
if (width <= 0) width = std::numeric_limits<decltype(width)>::max();
|
||||
|
||||
writeToStderr("\r" + filterANSIEscapes(line, false, width) + "\e[K");
|
||||
}
|
||||
@@ -439,7 +439,9 @@ public:
|
||||
|
||||
void startProgressBar(bool printBuildLogs)
|
||||
{
|
||||
logger = new ProgressBar(printBuildLogs, isatty(STDERR_FILENO));
|
||||
logger = new ProgressBar(
|
||||
printBuildLogs,
|
||||
isatty(STDERR_FILENO) && getEnv("TERM", "dumb") != "dumb");
|
||||
}
|
||||
|
||||
void stopProgressBar()
|
||||
|
||||
@@ -80,10 +80,6 @@ struct CmdSearch : SourceExprCommand, MixJSON
|
||||
Example{
|
||||
"To search for git and frontend or gui:",
|
||||
"nix search git 'frontend|gui'"
|
||||
},
|
||||
Example{
|
||||
"To display the description of the found packages:",
|
||||
"nix search git --verbose"
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -265,6 +261,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */
|
||||
if (!jsonCacheFile)
|
||||
throw Error("error writing to %s", tmpFile);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (writeCache && rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1)
|
||||
|
||||
@@ -13,7 +13,7 @@ struct CmdVerify : StorePathsCommand
|
||||
bool noContents = false;
|
||||
bool noTrust = false;
|
||||
Strings substituterUris;
|
||||
size_t sigsNeeded;
|
||||
size_t sigsNeeded = 0;
|
||||
|
||||
CmdVerify()
|
||||
{
|
||||
@@ -113,7 +113,7 @@ struct CmdVerify : StorePathsCommand
|
||||
else {
|
||||
|
||||
StringSet sigsSeen;
|
||||
size_t actualSigsNeeded = sigsNeeded ? sigsNeeded : 1;
|
||||
size_t actualSigsNeeded = std::max(sigsNeeded, (size_t) 1);
|
||||
size_t validSigs = 0;
|
||||
|
||||
auto doSigs = [&](StringSet sigs) {
|
||||
|
||||
@@ -8,7 +8,6 @@ expect_trace() {
|
||||
actual=$(
|
||||
nix-instantiate \
|
||||
--trace-function-calls \
|
||||
-vvvv \
|
||||
--expr "$expr" 2>&1 \
|
||||
| grep "function-trace" \
|
||||
| sed -e 's/ [0-9]*$//'
|
||||
|
||||
1
tests/lang/eval-okay-attrs6.exp
Normal file
1
tests/lang/eval-okay-attrs6.exp
Normal file
@@ -0,0 +1 @@
|
||||
{ __overrides = { bar = "qux"; }; bar = "qux"; foo = "bar"; }
|
||||
4
tests/lang/eval-okay-attrs6.nix
Normal file
4
tests/lang/eval-okay-attrs6.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
rec {
|
||||
"${"foo"}" = "bar";
|
||||
__overrides = { bar = "qux"; };
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
"{\"a\":123,\"b\":-456,\"c\":\"foo\",\"d\":\"foo\\n\\\"bar\\\"\",\"e\":true,\"f\":false,\"g\":[1,2,3],\"h\":[\"a\",[\"b\",{\"foo\\nbar\":{}}]],\"i\":3,\"j\":1.44}"
|
||||
"{\"a\":123,\"b\":-456,\"c\":\"foo\",\"d\":\"foo\\n\\\"bar\\\"\",\"e\":true,\"f\":false,\"g\":[1,2,3],\"h\":[\"a\",[\"b\",{\"foo\\nbar\":{}}]],\"i\":3,\"j\":1.44,\"k\":\"foo\"}"
|
||||
|
||||
@@ -9,4 +9,5 @@ builtins.toJSON
|
||||
h = [ "a" [ "b" { "foo\nbar" = {}; } ] ];
|
||||
i = 1 + 2;
|
||||
j = 1.44;
|
||||
k = { __toString = self: self.a; a = "foo"; };
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
|
||||
|
||||
# Do an install.
|
||||
nix-env -i dependencies
|
||||
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
|
||||
[ -e $TEST_HOME/.nix-profile/foobar ]
|
||||
|
||||
clearProfiles
|
||||
rm -f $TEST_HOME/.nix-channels
|
||||
@@ -55,5 +55,5 @@ grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
|
||||
|
||||
# Do an install.
|
||||
nix-env -i dependencies
|
||||
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
|
||||
[ -e $TEST_HOME/.nix-profile/foobar ]
|
||||
|
||||
|
||||
@@ -7,8 +7,3 @@ rm -rf $TEST_HOME $TEST_ROOT/profile-var
|
||||
mkdir -p $TEST_HOME
|
||||
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set"
|
||||
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency
|
||||
|
||||
[ -L $TEST_HOME/.nix-profile ]
|
||||
[ -e $TEST_HOME/.nix-channels ]
|
||||
[ -e $TEST_ROOT/profile-var/nix/gcroots/per-user/$user ]
|
||||
[ -e $TEST_ROOT/profile-var/nix/profiles/per-user/$user ]
|
||||
|
||||
@@ -13,3 +13,7 @@ cmp $TEST_ROOT/d1 $TEST_ROOT/d2
|
||||
nix-store --gc --max-freed 1K
|
||||
|
||||
killDaemon
|
||||
|
||||
user=$(whoami)
|
||||
[ -e $NIX_STATE_DIR/gcroots/per-user/$user ]
|
||||
[ -e $NIX_STATE_DIR/profiles/per-user/$user ]
|
||||
|
||||
@@ -20,7 +20,7 @@ drvPath10=$(nix-env -f ./user-envs.nix -qa --drv-path --no-name '*' | grep foo-1
|
||||
|
||||
# Query descriptions.
|
||||
nix-env -f ./user-envs.nix -qa '*' --description | grep -q silly
|
||||
rm -f $HOME/.nix-defexpr
|
||||
rm -rf $HOME/.nix-defexpr
|
||||
ln -s $(pwd)/user-envs.nix $HOME/.nix-defexpr
|
||||
nix-env -qa '*' --description | grep -q silly
|
||||
|
||||
|
||||
Reference in New Issue
Block a user