diff options
-rw-r--r-- | doc/manual/command-ref/conf-file.xml | 27 | ||||
-rw-r--r-- | doc/manual/expressions/advanced-attributes.xml | 14 | ||||
-rw-r--r-- | doc/manual/expressions/builtins.xml | 364 | ||||
-rw-r--r-- | doc/manual/packages/s3-substituter.xml | 202 | ||||
-rw-r--r-- | doc/manual/release-notes/release-notes.xml | 1 | ||||
-rw-r--r-- | doc/manual/release-notes/rl-2.2.xml | 25 | ||||
-rw-r--r-- | scripts/nix-profile-daemon.sh.in | 2 | ||||
-rw-r--r-- | src/libstore/build.cc | 210 | ||||
-rw-r--r-- | src/libstore/derivations.cc | 14 | ||||
-rw-r--r-- | src/libstore/derivations.hh | 4 | ||||
-rw-r--r-- | src/libstore/download.cc | 45 | ||||
-rw-r--r-- | src/libstore/globals.cc | 15 | ||||
-rw-r--r-- | src/libstore/globals.hh | 6 | ||||
-rw-r--r-- | src/libstore/parsed-derivations.cc | 111 | ||||
-rw-r--r-- | src/libstore/parsed-derivations.hh | 35 | ||||
-rw-r--r-- | src/libstore/s3-binary-cache-store.cc | 28 | ||||
-rw-r--r-- | src/libstore/store-api.cc | 2 | ||||
-rw-r--r-- | src/libutil/serialise.cc | 26 | ||||
-rwxr-xr-x | src/nix-build/nix-build.cc | 8 | ||||
-rw-r--r-- | src/nix-daemon/nix-daemon.cc | 2 | ||||
-rw-r--r-- | src/nix/copy.cc | 8 | ||||
-rw-r--r-- | src/nix/verify.cc | 2 | ||||
-rw-r--r-- | tests/build-remote.sh | 3 | ||||
-rw-r--r-- | tests/signing.sh | 4 |
24 files changed, 714 insertions, 444 deletions
diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml index fd09883be402..e9947ebc673f 100644 --- a/doc/manual/command-ref/conf-file.xml +++ b/doc/manual/command-ref/conf-file.xml @@ -757,6 +757,33 @@ password <replaceable>my-password</replaceable> </varlistentry> + <varlistentry xml:id="conf-system-features"><term><literal>system-features</literal></term> + + <listitem><para>A set of system “features” supported by this + machine, e.g. <literal>kvm</literal>. Derivations can express a + dependency on such features through the derivation attribute + <varname>requiredSystemFeatures</varname>. For example, the + attribute + +<programlisting> +requiredSystemFeatures = [ "kvm" ]; +</programlisting> + + ensures that the derivation can only be built on a machine with + the <literal>kvm</literal> feature.</para> + + <para>This setting by default includes <literal>kvm</literal> if + <filename>/dev/kvm</filename> is accessible, and the + pseudo-features <literal>nixos-test</literal>, + <literal>benchmark</literal> and <literal>big-parallel</literal> + that are used in Nixpkgs to route builds to specific + machines.</para> + + </listitem> + + </varlistentry> + + <varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term> <listitem> diff --git a/doc/manual/expressions/advanced-attributes.xml b/doc/manual/expressions/advanced-attributes.xml index 9422e82ff362..2af7a51acfbb 100644 --- a/doc/manual/expressions/advanced-attributes.xml +++ b/doc/manual/expressions/advanced-attributes.xml @@ -216,7 +216,7 @@ fetchurl { <programlisting> { stdenv, curl }: # The <command>curl</command> program is used for downloading. -{ url, md5 }: +{ url, sha256 }: stdenv.mkDerivation { name = baseNameOf (toString url); @@ -224,10 +224,10 @@ stdenv.mkDerivation { buildInputs = [ curl ]; # This is a fixed-output derivation; the output must be a regular - # file with MD5 hash <varname>md5</varname>. + # file with SHA256 hash <varname>sha256</varname>. outputHashMode = "flat"; - outputHashAlgo = "md5"; - outputHash = md5; + outputHashAlgo = "sha256"; + outputHash = sha256; inherit url; } @@ -237,8 +237,8 @@ stdenv.mkDerivation { <para>The <varname>outputHashAlgo</varname> attribute specifies the hash algorithm used to compute the hash. It can currently be - <literal>"md5"</literal>, <literal>"sha1"</literal> or - <literal>"sha256"</literal>.</para> + <literal>"sha1"</literal>, <literal>"sha256"</literal> or + <literal>"sha512"</literal>.</para> <para>The <varname>outputHashMode</varname> attribute determines how the hash is computed. It must be one of the following two @@ -251,7 +251,7 @@ stdenv.mkDerivation { <listitem><para>The output must be a non-executable regular file. If it isn’t, the build fails. The hash is simply computed over the contents of that file (so it’s equal to what - Unix commands like <command>md5sum</command> or + Unix commands like <command>sha256sum</command> or <command>sha1sum</command> produce).</para> <para>This is the default.</para></listitem> diff --git a/doc/manual/expressions/builtins.xml b/doc/manual/expressions/builtins.xml index 873f30b062ee..8d12da9b1356 100644 --- a/doc/manual/expressions/builtins.xml +++ b/doc/manual/expressions/builtins.xml @@ -21,7 +21,8 @@ available as <function>builtins.derivation</function>.</para> <variablelist> - <varlistentry><term><function>abort</function> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-abort'> + <term><function>abort</function> <replaceable>s</replaceable></term> <listitem><para>Abort Nix expression evaluation, print error message <replaceable>s</replaceable>.</para></listitem> @@ -29,8 +30,10 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.add</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-add'> + <term><function>builtins.add</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable> + </term> <listitem><para>Return the sum of the numbers <replaceable>e1</replaceable> and @@ -39,8 +42,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.all</function> - <replaceable>pred</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-all'> + <term><function>builtins.all</function> + <replaceable>pred</replaceable> <replaceable>list</replaceable></term> <listitem><para>Return <literal>true</literal> if the function <replaceable>pred</replaceable> returns <literal>true</literal> @@ -50,8 +54,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.any</function> - <replaceable>pred</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-any'> + <term><function>builtins.any</function> + <replaceable>pred</replaceable> <replaceable>list</replaceable></term> <listitem><para>Return <literal>true</literal> if the function <replaceable>pred</replaceable> returns <literal>true</literal> @@ -61,8 +66,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.attrNames</function> - <replaceable>set</replaceable></term> + <varlistentry xml:id='builtin-attrNames'> + <term><function>builtins.attrNames</function> + <replaceable>set</replaceable></term> <listitem><para>Return the names of the attributes in the set <replaceable>set</replaceable> in an alphabetically sorted list. For instance, @@ -72,8 +78,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.attrValues</function> - <replaceable>set</replaceable></term> + <varlistentry xml:id='builtin-attrValues'> + <term><function>builtins.attrValues</function> + <replaceable>set</replaceable></term> <listitem><para>Return the values of the attributes in the set <replaceable>set</replaceable> in the order corresponding to the @@ -82,7 +89,8 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>baseNameOf</function> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-baseNameOf'> + <term><function>baseNameOf</function> <replaceable>s</replaceable></term> <listitem><para>Return the <emphasis>base name</emphasis> of the string <replaceable>s</replaceable>, that is, everything following @@ -92,8 +100,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.bitAnd</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-bitAnd'> + <term><function>builtins.bitAnd</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the bitwise AND of the integers <replaceable>e1</replaceable> and @@ -102,8 +111,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.bitOr</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-bitOr'> + <term><function>builtins.bitOr</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the bitwise OR of the integers <replaceable>e1</replaceable> and @@ -112,8 +122,9 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><function>builtins.bitXor</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-bitXor'> + <term><function>builtins.bitXor</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the bitwise XOR of the integers <replaceable>e1</replaceable> and @@ -122,7 +133,8 @@ available as <function>builtins.derivation</function>.</para> </varlistentry> - <varlistentry><term><varname>builtins</varname></term> + <varlistentry xml:id='builtin-builtins'> + <term><varname>builtins</varname></term> <listitem><para>The set <varname>builtins</varname> contains all the built-in functions and values. You can use @@ -139,8 +151,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.compareVersions</function> - <replaceable>s1</replaceable> <replaceable>s2</replaceable></term> + <varlistentry xml:id='builtin-compareVersions'> + <term><function>builtins.compareVersions</function> + <replaceable>s1</replaceable> <replaceable>s2</replaceable></term> <listitem><para>Compare two strings representing versions and return <literal>-1</literal> if version @@ -156,8 +169,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.splitVersion</function> - <replaceable>s</replaceable></term> + <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 @@ -167,16 +181,18 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.concatLists</function> - <replaceable>lists</replaceable></term> + <varlistentry xml:id='builtin-concatLists'> + <term><function>builtins.concatLists</function> + <replaceable>lists</replaceable></term> <listitem><para>Concatenate a list of lists into a single list.</para></listitem> </varlistentry> - <varlistentry><term><function>builtins.concatStringsSep</function> - <replaceable>separator</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-concatStringsSep'> + <term><function>builtins.concatStringsSep</function> + <replaceable>separator</replaceable> <replaceable>list</replaceable></term> <listitem><para>Concatenate a list of strings with a separator between each element, e.g. <literal>concatStringsSep "/" @@ -184,8 +200,8 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry - xml:id='builtin-currentSystem'><term><varname>builtins.currentSystem</varname></term> + <varlistentry xml:id='builtin-currentSystem'> + <term><varname>builtins.currentSystem</varname></term> <listitem><para>The built-in value <varname>currentSystem</varname> evaluates to the Nix platform identifier for the Nix installation @@ -218,8 +234,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> --> - <varlistentry><term><function>builtins.deepSeq</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-deepSeq'> + <term><function>builtins.deepSeq</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>This is like <literal>seq <replaceable>e1</replaceable> @@ -231,8 +248,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>derivation</function> - <replaceable>attrs</replaceable></term> + <varlistentry xml:id='builtin-derivation'> + <term><function>derivation</function> + <replaceable>attrs</replaceable></term> <listitem><para><function>derivation</function> is described in <xref linkend='ssec-derivation' />.</para></listitem> @@ -240,7 +258,8 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>dirOf</function> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-dirOf'> + <term><function>dirOf</function> <replaceable>s</replaceable></term> <listitem><para>Return the directory part of the string <replaceable>s</replaceable>, that is, everything before the final @@ -250,8 +269,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.div</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-div'> + <term><function>builtins.div</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the quotient of the numbers <replaceable>e1</replaceable> and @@ -259,8 +279,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.elem</function> - <replaceable>x</replaceable> <replaceable>xs</replaceable></term> + <varlistentry xml:id='builtin-elem'> + <term><function>builtins.elem</function> + <replaceable>x</replaceable> <replaceable>xs</replaceable></term> <listitem><para>Return <literal>true</literal> if a value equal to <replaceable>x</replaceable> occurs in the list @@ -270,8 +291,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.elemAt</function> - <replaceable>xs</replaceable> <replaceable>n</replaceable></term> + <varlistentry xml:id='builtin-elemAt'> + <term><function>builtins.elemAt</function> + <replaceable>xs</replaceable> <replaceable>n</replaceable></term> <listitem><para>Return element <replaceable>n</replaceable> from the list <replaceable>xs</replaceable>. Elements are counted @@ -281,8 +303,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>builtins.fetchurl</function> - <replaceable>url</replaceable></term> + <varlistentry xml:id='builtin-fetchurl'> + <term><function>builtins.fetchurl</function> + <replaceable>url</replaceable></term> <listitem><para>Download the specified URL and return the path of the downloaded file. This function is not available if <link @@ -292,8 +315,9 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting> </varlistentry> - <varlistentry><term><function>fetchTarball</function> - <replaceable>url</replaceable></term> + <varlistentry xml:id='builtin-fetchTarball'> + <term><function>fetchTarball</function> + <replaceable>url</replaceable></term> <listitem><para>Download the specified URL, unpack it and return the path of the unpacked tree. The file must be a tape archive @@ -346,7 +370,7 @@ stdenv.mkDerivation { … } </varlistentry> - <varlistentry> + <varlistentry xml:id='builtin-fetchGit'> <term> <function>builtins.fetchGit</function> <replaceable>args</replaceable> @@ -546,7 +570,8 @@ stdenv.mkDerivation { </varlistentry> - <varlistentry><term><function>builtins.foldl’</function> + <varlistentry xml:id='builtin-foldl-prime'> + <term><function>builtins.foldl’</function> <replaceable>op</replaceable> <replaceable>nul</replaceable> <replaceable>list</replaceable></term> <listitem><para>Reduce a list by applying a binary operator, from @@ -559,7 +584,8 @@ stdenv.mkDerivation { </varlistentry> - <varlistentry><term><function>builtins.functionArgs</function> + <varlistentry xml:id='builtin-functionArgs'> + <term><function>builtins.functionArgs</function> <replaceable>f</replaceable></term> <listitem><para> @@ -577,7 +603,8 @@ stdenv.mkDerivation { </varlistentry> - <varlistentry><term><function>builtins.fromJSON</function> <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-fromJSON'> + <term><function>builtins.fromJSON</function> <replaceable>e</replaceable></term> <listitem><para>Convert a JSON string to a Nix value. For example, @@ -592,8 +619,9 @@ builtins.fromJSON ''{"x": [1, 2, 3], "y": null}'' </varlistentry> - <varlistentry><term><function>builtins.genList</function> - <replaceable>generator</replaceable> <replaceable>length</replaceable></term> + <varlistentry xml:id='builtin-genList'> + <term><function>builtins.genList</function> + <replaceable>generator</replaceable> <replaceable>length</replaceable></term> <listitem><para>Generate list of size <replaceable>length</replaceable>, with each element @@ -610,8 +638,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>builtins.getAttr</function> - <replaceable>s</replaceable> <replaceable>set</replaceable></term> + <varlistentry xml:id='builtin-getAttr'> + <term><function>builtins.getAttr</function> + <replaceable>s</replaceable> <replaceable>set</replaceable></term> <listitem><para><function>getAttr</function> returns the attribute named <replaceable>s</replaceable> from @@ -623,8 +652,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>builtins.getEnv</function> - <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-getEnv'> + <term><function>builtins.getEnv</function> + <replaceable>s</replaceable></term> <listitem><para><function>getEnv</function> returns the value of the environment variable <replaceable>s</replaceable>, or an empty @@ -641,8 +671,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>builtins.hasAttr</function> - <replaceable>s</replaceable> <replaceable>set</replaceable></term> + <varlistentry xml:id='builtin-hasAttr'> + <term><function>builtins.hasAttr</function> + <replaceable>s</replaceable> <replaceable>set</replaceable></term> <listitem><para><function>hasAttr</function> returns <literal>true</literal> if <replaceable>set</replaceable> has an @@ -655,8 +686,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>builtins.hashString</function> - <replaceable>type</replaceable> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-hashString'> + <term><function>builtins.hashString</function> + <replaceable>type</replaceable> <replaceable>s</replaceable></term> <listitem><para>Return a base-16 representation of the cryptographic hash of string <replaceable>s</replaceable>. The @@ -667,8 +699,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>builtins.head</function> - <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-head'> + <term><function>builtins.head</function> + <replaceable>list</replaceable></term> <listitem><para>Return the first element of a list; abort evaluation if the argument isn’t a list or is an empty list. You @@ -678,8 +711,9 @@ builtins.genList (x: x * x) 5 </varlistentry> - <varlistentry><term><function>import</function> - <replaceable>path</replaceable></term> + <varlistentry xml:id='builtin-import'> + <term><function>import</function> + <replaceable>path</replaceable></term> <listitem><para>Load, parse and return the Nix expression in the file <replaceable>path</replaceable>. If <replaceable>path @@ -733,8 +767,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.intersectAttrs</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-intersectAttrs'> + <term><function>builtins.intersectAttrs</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return a set consisting of the attributes in the set <replaceable>e2</replaceable> that also exist in the set @@ -743,8 +778,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isAttrs</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isAttrs'> + <term><function>builtins.isAttrs</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to a set, and @@ -753,8 +789,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isList</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isList'> + <term><function>builtins.isList</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to a list, and @@ -763,7 +800,7 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isFunction</function> + <varlistentry xml:id='builtin-isFunction'><term><function>builtins.isFunction</function> <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if @@ -773,8 +810,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isString</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isString'> + <term><function>builtins.isString</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to a string, and @@ -783,8 +821,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isInt</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isInt'> + <term><function>builtins.isInt</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to an int, and @@ -793,8 +832,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isFloat</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isFloat'> + <term><function>builtins.isFloat</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to a float, and @@ -803,8 +843,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.isBool</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isBool'> + <term><function>builtins.isBool</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to a bool, and @@ -813,8 +854,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>isNull</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-isNull'> + <term><function>isNull</function> + <replaceable>e</replaceable></term> <listitem><para>Return <literal>true</literal> if <replaceable>e</replaceable> evaluates to <literal>null</literal>, @@ -828,8 +870,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.length</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-length'> + <term><function>builtins.length</function> + <replaceable>e</replaceable></term> <listitem><para>Return the length of the list <replaceable>e</replaceable>.</para></listitem> @@ -837,8 +880,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.lessThan</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-lessThan'> + <term><function>builtins.lessThan</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return <literal>true</literal> if the number <replaceable>e1</replaceable> is less than the number @@ -850,8 +894,9 @@ x: x + 456</programlisting> </varlistentry> - <varlistentry><term><function>builtins.listToAttrs</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-listToAttrs'> + <term><function>builtins.listToAttrs</function> + <replaceable>e</replaceable></term> <listitem><para>Construct a set from a list specifying the names and values of each attribute. Each element of the list should be @@ -877,8 +922,9 @@ builtins.listToAttrs </varlistentry> - <varlistentry><term><function>map</function> - <replaceable>f</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-map'> + <term><function>map</function> + <replaceable>f</replaceable> <replaceable>list</replaceable></term> <listitem><para>Apply the function <replaceable>f</replaceable> to each element in the list <replaceable>list</replaceable>. For @@ -893,14 +939,15 @@ map (x: "foo" + x) [ "bar" "bla" "abc" ]</programlisting> </varlistentry> - <varlistentry><term><function>builtins.match</function> - <replaceable>regex</replaceable> <replaceable>str</replaceable></term> + <varlistentry xml:id='builtin-match'> + <term><function>builtins.match</function> + <replaceable>regex</replaceable> <replaceable>str</replaceable></term> - <listitem><para>Returns a list if the <link - xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended - POSIX regular expression</link> <replaceable>regex</replaceable> - matches <replaceable>str</replaceable> precisely, otherwise returns - <literal>null</literal>. Each item in the list is a regex group. + <listitem><para>Returns a list if the <link + xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended + POSIX regular expression</link> <replaceable>regex</replaceable> + matches <replaceable>str</replaceable> precisely, otherwise returns + <literal>null</literal>. Each item in the list is a regex group. <programlisting> builtins.match "ab" "abc" @@ -926,11 +973,12 @@ builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO " Evaluates to <literal>[ "foo" ]</literal>. - </para></listitem> + </para></listitem> </varlistentry> - <varlistentry><term><function>builtins.mul</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-mul'> + <term><function>builtins.mul</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the product of the numbers <replaceable>e1</replaceable> and @@ -939,8 +987,9 @@ Evaluates to <literal>[ "foo" ]</literal>. </varlistentry> - <varlistentry><term><function>builtins.parseDrvName</function> - <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-parseDrvName'> + <term><function>builtins.parseDrvName</function> + <replaceable>s</replaceable></term> <listitem><para>Split the string <replaceable>s</replaceable> into a package name and version. The package name is everything up to @@ -953,7 +1002,7 @@ Evaluates to <literal>[ "foo" ]</literal>. </varlistentry> - <varlistentry> + <varlistentry xml:id='builtin-path'> <term> <function>builtins.path</function> <replaceable>args</replaceable> @@ -1023,8 +1072,9 @@ Evaluates to <literal>[ "foo" ]</literal>. </listitem> </varlistentry> - <varlistentry><term><function>builtins.pathExists</function> - <replaceable>path</replaceable></term> + <varlistentry xml:id='builtin-pathExists'> + <term><function>builtins.pathExists</function> + <replaceable>path</replaceable></term> <listitem><para>Return <literal>true</literal> if the path <replaceable>path</replaceable> exists, and @@ -1047,8 +1097,9 @@ in config.someSetting</programlisting> </varlistentry> - <varlistentry><term><function>builtins.readDir</function> - <replaceable>path</replaceable></term> + <varlistentry xml:id='builtin-readDir'> + <term><function>builtins.readDir</function> + <replaceable>path</replaceable></term> <listitem><para>Return the contents of the directory <replaceable>path</replaceable> as a set mapping directory entries @@ -1069,8 +1120,9 @@ in config.someSetting</programlisting> </varlistentry> - <varlistentry><term><function>builtins.readFile</function> - <replaceable>path</replaceable></term> + <varlistentry xml:id='builtin-readFile'> + <term><function>builtins.readFile</function> + <replaceable>path</replaceable></term> <listitem><para>Return the contents of the file <replaceable>path</replaceable> as a string.</para></listitem> @@ -1078,8 +1130,9 @@ in config.someSetting</programlisting> </varlistentry> - <varlistentry><term><function>removeAttrs</function> - <replaceable>set</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-removeAttrs'> + <term><function>removeAttrs</function> + <replaceable>set</replaceable> <replaceable>list</replaceable></term> <listitem><para>Remove the attributes listed in <replaceable>list</replaceable> from @@ -1094,8 +1147,9 @@ removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]</programlisting> </varlistentry> - <varlistentry><term><function>builtins.replaceStrings</function> - <replaceable>from</replaceable> <replaceable>to</replaceable> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-replaceStrings'> + <term><function>builtins.replaceStrings</function> + <replaceable>from</replaceable> <replaceable>to</replaceable> <replaceable>s</replaceable></term> <listitem><para>Given string <replaceable>s</replaceable>, replace every occurrence of the strings in <replaceable>from</replaceable> @@ -1111,8 +1165,9 @@ builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar" </varlistentry> - <varlistentry><term><function>builtins.seq</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-seq'> + <term><function>builtins.seq</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Evaluate <replaceable>e1</replaceable>, then evaluate and return <replaceable>e2</replaceable>. This ensures @@ -1122,8 +1177,9 @@ builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar" </varlistentry> - <varlistentry><term><function>builtins.sort</function> - <replaceable>comparator</replaceable> <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-sort'> + <term><function>builtins.sort</function> + <replaceable>comparator</replaceable> <replaceable>list</replaceable></term> <listitem><para>Return <replaceable>list</replaceable> in sorted order. It repeatedly calls the function @@ -1145,15 +1201,16 @@ builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ] </varlistentry> - <varlistentry><term><function>builtins.split</function> - <replaceable>regex</replaceable> <replaceable>str</replaceable></term> + <varlistentry xml:id='builtin-split'> + <term><function>builtins.split</function> + <replaceable>regex</replaceable> <replaceable>str</replaceable></term> - <listitem><para>Returns a list composed of non matched strings interleaved - with the lists of the <link - xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended - POSIX regular expression</link> <replaceable>regex</replaceable> matches - of <replaceable>str</replaceable>. Each item in the lists of matched - sequences is a regex group. + <listitem><para>Returns a list composed of non matched strings interleaved + with the lists of the <link + xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended + POSIX regular expression</link> <replaceable>regex</replaceable> matches + of <replaceable>str</replaceable>. Each item in the lists of matched + sequences is a regex group. <programlisting> builtins.split "(a)b" "abc" @@ -1179,11 +1236,12 @@ builtins.split "([[:upper:]]+)" " FOO " Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>. - </para></listitem> + </para></listitem> </varlistentry> - <varlistentry><term><function>builtins.stringLength</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-stringLength'> + <term><function>builtins.stringLength</function> + <replaceable>e</replaceable></term> <listitem><para>Return the length of the string <replaceable>e</replaceable>. If <replaceable>e</replaceable> is @@ -1192,8 +1250,9 @@ Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>. </varlistentry> - <varlistentry><term><function>builtins.sub</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-sub'> + <term><function>builtins.sub</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Return the difference between the numbers <replaceable>e1</replaceable> and @@ -1202,9 +1261,10 @@ Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>. </varlistentry> - <varlistentry><term><function>builtins.substring</function> - <replaceable>start</replaceable> <replaceable>len</replaceable> - <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-substring'> + <term><function>builtins.substring</function> + <replaceable>start</replaceable> <replaceable>len</replaceable> + <replaceable>s</replaceable></term> <listitem><para>Return the substring of <replaceable>s</replaceable> from character position @@ -1227,8 +1287,9 @@ builtins.substring 0 3 "nixos" </varlistentry> - <varlistentry><term><function>builtins.tail</function> - <replaceable>list</replaceable></term> + <varlistentry xml:id='builtin-tail'> + <term><function>builtins.tail</function> + <replaceable>list</replaceable></term> <listitem><para>Return the second to last elements of a list; abort evaluation if the argument isn’t a list or is an empty @@ -1237,8 +1298,9 @@ builtins.substring 0 3 "nixos" </varlistentry> - <varlistentry><term><function>throw</function> - <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-throw'> + <term><function>throw</function> + <replaceable>s</replaceable></term> <listitem><para>Throw an error message <replaceable>s</replaceable>. This usually aborts Nix expression @@ -1251,9 +1313,10 @@ builtins.substring 0 3 "nixos" </varlistentry> - <varlistentry - xml:id='builtin-toFile'><term><function>builtins.toFile</function> - <replaceable>name</replaceable> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-toFile'> + <term><function>builtins.toFile</function> + <replaceable>name</replaceable> + <replaceable>s</replaceable></term> <listitem><para>Store the string <replaceable>s</replaceable> in a file in the Nix store and return its path. The file has suffix @@ -1329,7 +1392,8 @@ in foo</programlisting> </varlistentry> - <varlistentry><term><function>builtins.toJSON</function> <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-toJSON'> + <term><function>builtins.toJSON</function> <replaceable>e</replaceable></term> <listitem><para>Return a string containing a JSON representation of <replaceable>e</replaceable>. Strings, integers, floats, booleans, @@ -1342,7 +1406,8 @@ in foo</programlisting> </varlistentry> - <varlistentry><term><function>builtins.toPath</function> <replaceable>s</replaceable></term> + <varlistentry xml:id='builtin-toPath'> + <term><function>builtins.toPath</function> <replaceable>s</replaceable></term> <listitem><para>Convert the string value <replaceable>s</replaceable> into a path value. The string @@ -1355,7 +1420,8 @@ in foo</programlisting> </varlistentry> - <varlistentry><term><function>toString</function> <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-toString'> + <term><function>toString</function> <replaceable>e</replaceable></term> <listitem><para>Convert the expression <replaceable>e</replaceable> to a string. @@ -1374,7 +1440,8 @@ in foo</programlisting> </varlistentry> - <varlistentry xml:id='builtin-toXML'><term><function>builtins.toXML</function> <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-toXML'> + <term><function>builtins.toXML</function> <replaceable>e</replaceable></term> <listitem><para>Return a string containing an XML representation of <replaceable>e</replaceable>. The main application for @@ -1489,8 +1556,9 @@ stdenv.mkDerivation (rec { </varlistentry> - <varlistentry><term><function>builtins.trace</function> - <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> + <varlistentry xml:id='builtin-trace'> + <term><function>builtins.trace</function> + <replaceable>e1</replaceable> <replaceable>e2</replaceable></term> <listitem><para>Evaluate <replaceable>e1</replaceable> and print its abstract syntax representation on standard error. Then return @@ -1499,8 +1567,9 @@ stdenv.mkDerivation (rec { </varlistentry> - <varlistentry><term><function>builtins.tryEval</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-tryEval'> + <term><function>builtins.tryEval</function> + <replaceable>e</replaceable></term> <listitem><para>Try to evaluate <replaceable>e</replaceable>. Return a set containing the attributes <literal>success</literal> @@ -1513,8 +1582,9 @@ stdenv.mkDerivation (rec { </varlistentry> - <varlistentry><term><function>builtins.typeOf</function> - <replaceable>e</replaceable></term> + <varlistentry xml:id='builtin-typeOf'> + <term><function>builtins.typeOf</function> + <replaceable>e</replaceable></term> <listitem><para>Return a string representing the type of the value <replaceable>e</replaceable>, namely <literal>"int"</literal>, diff --git a/doc/manual/packages/s3-substituter.xml b/doc/manual/packages/s3-substituter.xml index bcd91cfdbccd..ea654392c6b1 100644 --- a/doc/manual/packages/s3-substituter.xml +++ b/doc/manual/packages/s3-substituter.xml @@ -12,8 +12,49 @@ from Amazon S3 and S3 compatible services. This uses the same <emphasis>binary</emphasis> cache mechanism that Nix usually uses to fetch prebuilt binaries from <uri>cache.nixos.org</uri>.</para> +<para>The following options can be specified as URL parameters to +the S3 URL:</para> + +<variablelist> + <varlistentry><term><literal>profile</literal></term> + <listitem> + <para> + The name of the AWS configuration profile to use. By default + Nix will use the <literal>default</literal> profile. + </para> + </listitem> + </varlistentry> + + <varlistentry><term><literal>region</literal></term> + <listitem> + <para> + The region of the S3 bucket. <literal>us–east-1</literal> by + default. + </para> + + <para> + If your bucket is not in <literal>us–east-1</literal>, you + should always explicitly specify the region parameter. + </para> + </listitem> + </varlistentry> + + <varlistentry><term><literal>endpoint</literal></term> + <listitem> + <para> + The URL to your S3-compatible service, for when not using + Amazon S3. Do not specify this value if you're using Amazon + S3. + </para> + <note><para>This endpoint must support HTTPS and will use + path-based addressing instead of virtual host based + addressing.</para></note> + </listitem> + </varlistentry> +</variablelist> + <para>In this example we will use the bucket named -<literal>example-bucket</literal>.</para> +<literal>example-nix-cache</literal>.</para> <section xml:id="ssec-s3-substituter-anonymous-reads"> <title>Anonymous Reads to your S3-compatible binary cache</title> @@ -24,65 +65,56 @@ fetch prebuilt binaries from <uri>cache.nixos.org</uri>.</para> cache.</para> <para>For AWS S3 the binary cache URL for example bucket will be - exactly <uri>https://example-bucket.s3.amazonaws.com</uri>. For S3 - compatible binary caches ago have to consult your software's - documentation.</para> + exactly <uri>https://example-nix-cache.s3.amazonaws.com</uri> or + <uri>s3://example-nix-cache</uri>. For S3 compatible binary caches, + consult that cache's documentation.</para> <para>Your bucket will need the following bucket policy:</para> - <programlisting> -<![CDATA[ + <programlisting><![CDATA[ { - "Id": "DirectReads", - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "AlowDirectReads", - "Action": [ - "s3:GetObject" - ], - "Effect": "Allow", - "Resource": "arn:aws:s3:::example-bucket/*", - "Principal": "*" - } - ] + "Id": "DirectReads", + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "AlowDirectReads", + "Action": [ + "s3:GetObject", + "s3:GetBucketLocation" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::example-nix-cache", + "arn:aws:s3:::example-nix-cache/*" + ], + "Principal": "*" + } + ] } -]]> -</programlisting> +]]></programlisting> </section> <section xml:id="ssec-s3-substituter-authenticated-reads"> <title>Authenticated Reads to your S3 binary cache</title> <para>For AWS S3 the binary cache URL for example bucket will be - exactly <uri>s3://example-bucket</uri>.</para> + exactly <uri>s3://example-nix-cache</uri>.</para> <para>Nix will use the <link xlink:href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default.">default credential provider chain</link> for authenticating requests to Amazon S3.</para> - <para>Nix supports authenticated writes to S3 compatible binary - caches but only supports Authenticated reads from Amazon S3. - Additionally, the following limitations are in place for - authenticated reads:</para> - - <itemizedlist> - <listitem><para>The bucket must actually be hosted by Amazon S3 and - <emphasis>not</emphasis> an S3 compatible - service.</para></listitem> - - <listitem><para>The bucket must be within the - <literal>us-east-1</literal> region.</para></listitem> - - <listitem><para>The Amazon credentials, if stored in a credential - profile, must be stored in the <literal>default</literal> - profile.</para></listitem> - </itemizedlist> + <para>Nix supports authenticated reads from Amazon S3 and S3 + compatible binary caches.</para> <para>Your bucket will need a bucket policy allowing the desired - users to perform the <literal>s3:GetObject</literal> action on all - objects in the bucket.</para> + users to perform the <literal>s3:GetObject</literal> and + <literal>s3:GetBucketLocation</literal> action on all objects in the + bucket. The anonymous policy in <xref + linkend="ssec-s3-substituter-anonymous-reads" /> can be updated to + have a restricted <literal>Principal</literal> to support + this.</para> </section> @@ -91,69 +123,49 @@ fetch prebuilt binaries from <uri>cache.nixos.org</uri>.</para> <para>Nix support fully supports writing to Amazon S3 and S3 compatible buckets. The binary cache URL for our example bucket will - be <uri>s3://example-bucket</uri>.</para> + be <uri>s3://example-nix-cache</uri>.</para> <para>Nix will use the <link xlink:href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default.">default credential provider chain</link> for authenticating requests to Amazon S3.</para> - <para>The following options can be specified as URL parameters to - the S3 URL:</para> - <variablelist> - <varlistentry><term><literal>profile</literal></term> - <listitem> - <para> - The name of the AWS configuration profile to use. By default - Nix will use the <literal>default</literal> profile. - </para> - </listitem> - </varlistentry> - - <varlistentry><term><literal>region</literal></term> - <listitem> - <para> - The region of the S3 bucket. <literal>us–east-1</literal> by - default. - </para> - </listitem> - </varlistentry> - - <varlistentry><term><literal>endpoint</literal></term> - <listitem> - <para> - The URL to your S3-compatible service, for when not using - Amazon S3. Do not specify this value if you're using Amazon - S3. - </para> - <note><para>This endpoint must support HTTPS and will use - path-based addressing instead of virtual host based - addressing.</para></note> - </listitem> - </varlistentry> - </variablelist> - - <example><title>Uploading with non-default credential profile for Amazon S3</title> - <para><command>nix copy --to ssh://machine nixpkgs.hello s3://example-bucket?profile=cache-upload</command></para> + <para>Your account will need the following IAM policy to + upload to the cache:</para> + + <programlisting><![CDATA[ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "UploadToCache", + "Effect": "Allow", + "Action": [ + "s3:AbortMultipartUpload", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListBucket", + "s3:ListBucketMultipartUploads", + "s3:ListMultipartUploadParts", + "s3:ListObjects", + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::example-nix-cache", + "arn:aws:s3:::example-nix-cache/*" + ] + } + ] +} +]]></programlisting> + + + <example><title>Uploading with a specific credential profile for Amazon S3</title> + <para><command>nix copy --to 's3://example-nix-cache?profile=cache-upload&region=eu-west-2' nixpkgs.hello</command></para> </example> <example><title>Uploading to an S3-Compatible Binary Cache</title> - <para><command>nix copy --to ssh://machine nixpkgs.hello s3://example-bucket?profile=cache-upload&endpoint=minio.example.com</command></para> + <para><command>nix copy --to 's3://example-nix-cache?profile=cache-upload&endpoint=minio.example.com' nixpkgs.hello</command></para> </example> - - <para>The user writing to the bucket will need to perform the - following actions against the bucket:</para> - - <itemizedlist> - <listitem><para><literal>s3:ListBucket</literal></para></listitem> - <listitem><para><literal>s3:GetBucketLocation</literal></para></listitem> - <listitem><para><literal>s3:ListObjects</literal></para></listitem> - <listitem><para><literal>s3:GetObject</literal></para></listitem> - <listitem><para><literal>s3:PutObject</literal></para></listitem> - <listitem><para><literal>s3:ListBucketMultipartUploads</literal></para></listitem> - <listitem><para><literal>s3:CreateMultipartUpload</literal></para></listitem> - <listitem><para><literal>s3:ListMultipartUploadParts</literal></para></listitem> - <listitem><para><literal>s3:AbortMultipartUpload</literal></para></listitem> - </itemizedlist> </section> </section> diff --git a/doc/manual/release-notes/release-notes.xml b/doc/manual/release-notes/release-notes.xml index ff4085cb792d..e8ff586fa43f 100644 --- a/doc/manual/release-notes/release-notes.xml +++ b/doc/manual/release-notes/release-notes.xml @@ -12,6 +12,7 @@ </partintro> --> +<xi:include href="rl-2.2.xml" /> <xi:include href="rl-2.1.xml" /> <xi:include href="rl-2.0.xml" /> <xi:include href="rl-1.11.10.xml" /> diff --git a/doc/manual/release-notes/rl-2.2.xml b/doc/manual/release-notes/rl-2.2.xml new file mode 100644 index 000000000000..bc28a56c9401 --- /dev/null +++ b/doc/manual/release-notes/rl-2.2.xml @@ -0,0 +1,25 @@ +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="ssec-relnotes-2.2"> + +<title>Release 2.2 (201?-??-??)</title> + +<para>This release has the following changes:</para> + +<itemizedlist> + + <listitem> + <para>The derivation attribute + <varname>requiredSystemFeatures</varname> is now enforced for + local builds, and not just to route builds to remote builders. + The supported features of a machine can be specified through the + configuration setting <varname>system-features</varname>. + </para> + </listitem> + +</itemizedlist> + +</section> + diff --git a/scripts/nix-profile-daemon.sh.in b/scripts/nix-profile-daemon.sh.in index 1be9a0755d85..87d9fe5061a7 100644 --- a/scripts/nix-profile-daemon.sh.in +++ b/scripts/nix-profile-daemon.sh.in @@ -68,4 +68,4 @@ elif [ -e "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" ]; then # fi export NIX_PATH="nixpkgs=@localstatedir@/nix/profiles/per-user/root/channels/nixpkgs:@localstatedir@/nix/profiles/per-user/root/channels" -export PATH="$HOME/.nix-profile/bin:$HOME/.nix-profile/lib/kde4/libexec:@localstatedir@/nix/profiles/default/bin:@localstatedir@/nix/profiles/default:@localstatedir@/nix/profiles/default/lib/kde4/libexec:$PATH" +export PATH="$HOME/.nix-profile/bin:@localstatedir@/nix/profiles/default/bin:$PATH" diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 1402bd097c35..0073b9b727ec 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -11,6 +11,7 @@ #include "compression.hh" #include "json.hh" #include "nar-info.hh" +#include "parsed-derivations.hh" #include <algorithm> #include <iostream> @@ -740,6 +741,8 @@ private: /* The derivation stored at drvPath. */ std::unique_ptr<BasicDerivation> drv; + std::unique_ptr<ParsedDerivation> parsedDrv; + /* The remainder is state held during the build. */ /* Locks on the output paths. */ @@ -1139,6 +1142,8 @@ void DerivationGoal::haveDerivation() return; } + parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv); + /* We are first going to try to create the invalid output paths through substitutes. If that doesn't work, we'll build them. */ @@ -1395,7 +1400,7 @@ void DerivationGoal::tryToBuild() /* Don't do a remote build if the derivation has the attribute `preferLocalBuild' set. Also, check and repair modes are only supported for local builds. */ - bool buildLocally = buildMode != bmNormal || drv->willBuildLocally(); + bool buildLocally = buildMode != bmNormal || parsedDrv->willBuildLocally(); auto started = [&]() { auto msg = fmt( @@ -1641,19 +1646,13 @@ HookReply DerivationGoal::tryBuildHook() try { - /* Tell the hook about system features (beyond the system type) - required from the build machine. (The hook could parse the - drv file itself, but this is easier.) */ - Strings features = tokenizeString<Strings>(get(drv->env, "requiredSystemFeatures")); - for (auto & i : features) checkStoreName(i); /* !!! abuse */ - /* Send the request to the hook. */ worker.hook->sink << "try" << (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0) << drv->platform << drvPath - << features; + << parsedDrv->getRequiredSystemFeatures(); worker.hook->sink.flush(); /* Read the first line of input, which should be a word indicating @@ -1793,23 +1792,26 @@ static void preloadNSS() { void DerivationGoal::startBuilder() { /* Right platform? */ - if (!drv->canBuildLocally()) { - throw Error( - format("a '%1%' is required to build '%3%', but I am a '%2%'") - % drv->platform % settings.thisSystem % drvPath); - } + if (!parsedDrv->canBuildLocally()) + throw Error("a '%s' with features {%s} is required to build '%s', but I am a '%s' with features {%s}", + drv->platform, + concatStringsSep(", ", parsedDrv->getRequiredSystemFeatures()), + drvPath, + settings.thisSystem, + concatStringsSep(", ", settings.systemFeatures)); if (drv->isBuiltin()) preloadNSS(); #if __APPLE__ - additionalSandboxProfile = get(drv->env, "__sandboxProfile"); + additionalSandboxProfile = parsedDrv->getStringAttr("__sandboxProfile").value_or(""); #endif /* Are we doing a chroot build? */ { + auto noChroot = parsedDrv->getBoolAttr("__noChroot"); if (settings.sandboxMode == smEnabled) { - if (get(drv->env, "__noChroot") == "1") + if (noChroot) throw Error(format("derivation '%1%' has '__noChroot' set, " "but that's not allowed when 'sandbox' is 'true'") % drvPath); #if __APPLE__ @@ -1822,7 +1824,7 @@ void DerivationGoal::startBuilder() else if (settings.sandboxMode == smDisabled) useChroot = false; else if (settings.sandboxMode == smRelaxed) - useChroot = !fixedOutput && get(drv->env, "__noChroot") != "1"; + useChroot = !fixedOutput && !noChroot; } if (worker.store.storeDir != worker.store.realStoreDir) { @@ -1873,7 +1875,7 @@ void DerivationGoal::startBuilder() writeStructuredAttrs(); /* Handle exportReferencesGraph(), if set. */ - if (!drv->env.count("__json")) { + if (!parsedDrv->getStructuredAttrs()) { /* The `exportReferencesGraph' feature allows the references graph to be passed to a builder. This attribute should be a list of pairs [name1 path1 name2 path2 ...]. The references graph of @@ -1938,7 +1940,7 @@ void DerivationGoal::startBuilder() PathSet allowedPaths = settings.allowedImpureHostPrefixes; /* This works like the above, except on a per-derivation level */ - Strings impurePaths = tokenizeString<Strings>(get(drv->env, "__impureHostDeps")); + auto impurePaths = parsedDrv->getStringsAttr("__impureHostDeps").value_or(Strings()); for (auto & i : impurePaths) { bool found = false; @@ -2306,7 +2308,7 @@ void DerivationGoal::initEnv() 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 (!drv->env.count("__json")) { + if (!parsedDrv->getStructuredAttrs()) { StringSet passAsFile = tokenizeString<StringSet>(get(drv->env, "passAsFile")); int fileNr = 0; @@ -2353,8 +2355,8 @@ void DerivationGoal::initEnv() fixed-output derivations is by definition pure (since we already know the cryptographic hash of the output). */ if (fixedOutput) { - Strings varNames = tokenizeString<Strings>(get(drv->env, "impureEnvVars")); - for (auto & i : varNames) env[i] = getEnv(i); + for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings())) + env[i] = getEnv(i); } /* Currently structured log messages piggyback on stderr, but we @@ -2369,111 +2371,103 @@ static std::regex shVarName("[A-Za-z_][A-Za-z0-9_]*"); void DerivationGoal::writeStructuredAttrs() { - auto jsonAttr = drv->env.find("__json"); - if (jsonAttr == drv->env.end()) return; - - try { - - auto jsonStr = rewriteStrings(jsonAttr->second, inputRewrites); + auto & structuredAttrs = parsedDrv->getStructuredAttrs(); + if (!structuredAttrs) return; - auto json = nlohmann::json::parse(jsonStr); + auto json = *structuredAttrs; - /* Add an "outputs" object containing the output paths. */ - nlohmann::json outputs; - for (auto & i : drv->outputs) - outputs[i.first] = rewriteStrings(i.second.path, inputRewrites); - json["outputs"] = outputs; - - /* Handle exportReferencesGraph. */ - auto e = json.find("exportReferencesGraph"); - if (e != json.end() && e->is_object()) { - for (auto i = e->begin(); i != e->end(); ++i) { - std::ostringstream str; - { - JSONPlaceholder jsonRoot(str, true); - PathSet storePaths; - for (auto & p : *i) - storePaths.insert(p.get<std::string>()); - worker.store.pathInfoToJSON(jsonRoot, - exportReferences(storePaths), false, true); - } - json[i.key()] = nlohmann::json::parse(str.str()); // urgh + /* Add an "outputs" object containing the output paths. */ + nlohmann::json outputs; + for (auto & i : drv->outputs) + outputs[i.first] = rewriteStrings(i.second.path, inputRewrites); + json["outputs"] = outputs; + + /* Handle exportReferencesGraph. */ + auto e = json.find("exportReferencesGraph"); + if (e != json.end() && e->is_object()) { + for (auto i = e->begin(); i != e->end(); ++i) { + std::ostringstream str; + { + JSONPlaceholder jsonRoot(str, true); + PathSet storePaths; + for (auto & p : *i) + storePaths.insert(p.get<std::string>()); + worker.store.pathInfoToJSON(jsonRoot, + exportReferences(storePaths), false, true); } + json[i.key()] = nlohmann::json::parse(str.str()); // urgh } + } - writeFile(tmpDir + "/.attrs.json", json.dump()); - - /* As a convenience to bash scripts, write a shell file that - maps all attributes that are representable in bash - - namely, strings, integers, nulls, Booleans, and arrays and - objects consisting entirely of those values. (So nested - arrays or objects are not supported.) */ + writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites)); - auto handleSimpleType = [](const nlohmann::json & value) -> std::experimental::optional<std::string> { - if (value.is_string()) - return shellEscape(value); + /* As a convenience to bash scripts, write a shell file that + maps all attributes that are representable in bash - + namely, strings, integers, nulls, Booleans, and arrays and + objects consisting entirely of those values. (So nested + arrays or objects are not supported.) */ - if (value.is_number()) { - auto f = value.get<float>(); - if (std::ceil(f) == f) - return std::to_string(value.get<int>()); - } + auto handleSimpleType = [](const nlohmann::json & value) -> std::experimental::optional<std::string> { + if (value.is_string()) + return shellEscape(value); - if (value.is_null()) - return std::string("''"); + if (value.is_number()) { + auto f = value.get<float>(); + if (std::ceil(f) == f) + return std::to_string(value.get<int>()); + } - if (value.is_boolean()) - return value.get<bool>() ? std::string("1") : std::string(""); + if (value.is_null()) + return std::string("''"); - return {}; - }; + if (value.is_boolean()) + return value.get<bool>() ? std::string("1") : std::string(""); - std::string jsonSh; + return {}; + }; - for (auto i = json.begin(); i != json.end(); ++i) { + std::string jsonSh; - if (!std::regex_match(i.key(), shVarName)) continue; + for (auto i = json.begin(); i != json.end(); ++i) { - auto & value = i.value(); + if (!std::regex_match(i.key(), shVarName)) continue; - auto s = handleSimpleType(value); - if (s) - jsonSh += fmt("declare %s=%s\n", i.key(), *s); + auto & value = i.value(); - else if (value.is_array()) { - std::string s2; - bool good = true; + auto s = handleSimpleType(value); + if (s) + jsonSh += fmt("declare %s=%s\n", i.key(), *s); - for (auto i = value.begin(); i != value.end(); ++i) { - auto s3 = handleSimpleType(i.value()); - if (!s3) { good = false; break; } - s2 += *s3; s2 += ' '; - } + else if (value.is_array()) { + std::string s2; + bool good = true; - if (good) - jsonSh += fmt("declare -a %s=(%s)\n", i.key(), s2); + for (auto i = value.begin(); i != value.end(); ++i) { + auto s3 = handleSimpleType(i.value()); + if (!s3) { good = false; break; } + s2 += *s3; s2 += ' '; } - else if (value.is_object()) { - std::string s2; - bool good = true; + if (good) + jsonSh += fmt("declare -a %s=(%s)\n", i.key(), s2); + } - for (auto i = value.begin(); i != value.end(); ++i) { - auto s3 = handleSimpleType(i.value()); - if (!s3) { good = false; break; } - s2 += fmt("[%s]=%s ", shellEscape(i.key()), *s3); - } + else if (value.is_object()) { + std::string s2; + bool good = true; - if (good) - jsonSh += fmt("declare -A %s=(%s)\n", i.key(), s2); + for (auto i = value.begin(); i != value.end(); ++i) { + auto s3 = handleSimpleType(i.value()); + if (!s3) { good = false; break; } + s2 += fmt("[%s]=%s ", shellEscape(i.key()), *s3); } - } - - writeFile(tmpDir + "/.attrs.sh", jsonSh); - } catch (std::exception & e) { - throw Error("cannot process __json attribute of '%s': %s", drvPath, e.what()); + if (good) + jsonSh += fmt("declare -A %s=(%s)\n", i.key(), s2); + } } + + writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites)); } @@ -2628,7 +2622,7 @@ void DerivationGoal::runChild() createDirs(chrootRootDir + "/dev/shm"); createDirs(chrootRootDir + "/dev/pts"); ss.push_back("/dev/full"); - if (pathExists("/dev/kvm")) + if (settings.systemFeatures.get().count("kvm") && pathExists("/dev/kvm")) ss.push_back("/dev/kvm"); ss.push_back("/dev/null"); ss.push_back("/dev/random"); @@ -2917,7 +2911,7 @@ void DerivationGoal::runChild() writeFile(sandboxFile, sandboxProfile); - bool allowLocalNetworking = get(drv->env, "__darwinAllowLocalNetworking") == "1"; + bool allowLocalNetworking = parsedDrv->getBoolAttr("__darwinAllowLocalNetworking"); /* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms to find temporary directories, so we want to open up a broader place for them to dump their files, if needed. */ @@ -2989,10 +2983,9 @@ void DerivationGoal::runChild() /* Parse a list of reference specifiers. Each element must either be a store path, or the symbolic name of the output of the derivation (such as `out'). */ -PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, string attr) +PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, const Strings & paths) { PathSet result; - Paths paths = tokenizeString<Paths>(attr); for (auto & i : paths) { if (store.isStorePath(i)) result.insert(i); @@ -3121,7 +3114,7 @@ void DerivationGoal::registerOutputs() the derivation to its content-addressed location. */ Hash h2 = recursive ? hashPath(h.type, actualPath).first : hashFile(h.type, actualPath); - Path dest = worker.store.makeFixedOutputPath(recursive, h2, drv->env["name"]); + Path dest = worker.store.makeFixedOutputPath(recursive, h2, storePathToName(path)); if (h != h2) { @@ -3204,9 +3197,10 @@ void DerivationGoal::registerOutputs() /* Enforce `allowedReferences' and friends. */ auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) { - if (drv->env.find(attrName) == drv->env.end()) return; + auto value = parsedDrv->getStringsAttr(attrName); + if (!value) return; - PathSet spec = parseReferenceSpecifiers(worker.store, *drv, get(drv->env, attrName)); + PathSet spec = parseReferenceSpecifiers(worker.store, *drv, *value); PathSet used; if (recursive) { diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 1e187ec5e954..3961126fff9c 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -36,12 +36,6 @@ Path BasicDerivation::findOutput(const string & id) const } -bool BasicDerivation::willBuildLocally() const -{ - return get(env, "preferLocalBuild") == "1" && canBuildLocally(); -} - - bool BasicDerivation::substitutesAllowed() const { return get(env, "allowSubstitutes", "1") == "1"; @@ -54,14 +48,6 @@ bool BasicDerivation::isBuiltin() const } -bool BasicDerivation::canBuildLocally() const -{ - return platform == settings.thisSystem - || settings.extraPlatforms.get().count(platform) > 0 - || isBuiltin(); -} - - Path writeDerivation(ref<Store> store, const Derivation & drv, const string & name, RepairFlag repair) { diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 7b97730d3bf2..9753e796db5f 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -56,14 +56,10 @@ struct BasicDerivation the given derivation. */ Path findOutput(const string & id) const; - bool willBuildLocally() const; - bool substitutesAllowed() const; bool isBuiltin() const; - bool canBuildLocally() const; - /* Return true iff this is a fixed-output derivation. */ bool isFixedOutput() const; diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 13913d031daa..f44f1836b31e 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -710,11 +710,12 @@ void Downloader::download(DownloadRequest && request, Sink & sink) /* If the buffer is full, then go to sleep until the calling thread wakes us up (i.e. when it has removed data from the - buffer). Note: this does stall the download thread. */ - while (state->data.size() > 1024 * 1024) { - if (state->quit) return; + buffer). We don't wait forever to prevent stalling the + download thread. (Hopefully sleeping will throttle the + sender.) */ + if (state->data.size() > 1024 * 1024) { debug("download buffer is full; going to sleep"); - state.wait(state->request); + state.wait_for(state->request, std::chrono::seconds(10)); } /* Append data to the buffer and wake up the calling @@ -736,30 +737,36 @@ void Downloader::download(DownloadRequest && request, Sink & sink) state->request.notify_one(); }}); - auto state(_state->lock()); - while (true) { checkInterrupt(); - /* If no data is available, then wait for the download thread - to wake us up. */ - if (state->data.empty()) { + std::string chunk; + + /* Grab data if available, otherwise wait for the download + thread to wake us up. */ + { + auto state(_state->lock()); + + while (state->data.empty()) { - if (state->quit) { - if (state->exc) std::rethrow_exception(state->exc); - break; + if (state->quit) { + if (state->exc) std::rethrow_exception(state->exc); + return; + } + + state.wait(state->avail); } - state.wait(state->avail); - } + chunk = std::move(state->data); - /* If data is available, then flush it to the sink and wake up - the download thread if it's blocked on a full buffer. */ - if (!state->data.empty()) { - sink((unsigned char *) state->data.data(), state->data.size()); - state->data.clear(); state->request.notify_one(); } + + /* Flush the data to the sink and wake up the download thread + if it's blocked on a full buffer. We don't hold the state + lock while doing this to prevent blocking the download + thread if sink() takes a long time. */ + sink((unsigned char *) chunk.data(), chunk.size()); } } diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index d95db56726cb..a9c07b23a6f3 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -86,6 +86,21 @@ unsigned int Settings::getDefaultCores() return std::max(1U, std::thread::hardware_concurrency()); } +StringSet Settings::getDefaultSystemFeatures() +{ + /* For backwards compatibility, accept some "features" that are + used in Nixpkgs to route builds to certain machines but don't + actually require anything special on the machines. */ + StringSet features{"nixos-test", "benchmark", "big-parallel"}; + + #if __linux__ + if (access("/dev/kvm", R_OK | W_OK) == 0) + features.insert("kvm"); + #endif + + return features; +} + const string nixVersion = PACKAGE_VERSION; template<> void BaseSetting<SandboxMode>::set(const std::string & str) diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index f589078dbb98..cf4ae63cdc2f 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -32,6 +32,8 @@ class Settings : public Config { unsigned int getDefaultCores(); + StringSet getDefaultSystemFeatures(); + public: Settings(); @@ -261,6 +263,10 @@ public: "These may be supported natively (e.g. armv7 on some aarch64 CPUs " "or using hacks like qemu-user."}; + Setting<StringSet> systemFeatures{this, getDefaultSystemFeatures(), + "system-features", + "Optional features that this system implements (like \"kvm\")."}; + Setting<Strings> substituters{this, nixStore == "/nix/store" ? Strings{"https://cache.nixos.org/"} : Strings(), "substituters", diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc new file mode 100644 index 000000000000..dc3286482736 --- /dev/null +++ b/src/libstore/parsed-derivations.cc @@ -0,0 +1,111 @@ +#include "parsed-derivations.hh" + +namespace nix { + +ParsedDerivation::ParsedDerivation(const Path & drvPath, BasicDerivation & drv) + : drvPath(drvPath), drv(drv) +{ + /* Parse the __json attribute, if any. */ + auto jsonAttr = drv.env.find("__json"); + if (jsonAttr != drv.env.end()) { + try { + structuredAttrs = nlohmann::json::parse(jsonAttr->second); + } catch (std::exception & e) { + throw Error("cannot process __json attribute of '%s': %s", drvPath, e.what()); + } + } +} + +std::experimental::optional<std::string> ParsedDerivation::getStringAttr(const std::string & name) const +{ + if (structuredAttrs) { + auto i = structuredAttrs->find(name); + if (i == structuredAttrs->end()) + return {}; + else { + if (!i->is_string()) + throw Error("attribute '%s' of derivation '%s' must be a string", name, drvPath); + return i->get<std::string>(); + } + } else { + auto i = drv.env.find(name); + if (i == drv.env.end()) + return {}; + else + return i->second; + } +} + +bool ParsedDerivation::getBoolAttr(const std::string & name, bool def) const +{ + if (structuredAttrs) { + auto i = structuredAttrs->find(name); + if (i == structuredAttrs->end()) + return def; + else { + if (!i->is_boolean()) + throw Error("attribute '%s' of derivation '%s' must be a Boolean", name, drvPath); + return i->get<bool>(); + } + } else { + auto i = drv.env.find(name); + if (i == drv.env.end()) + return def; + else + return i->second == "1"; + } +} + +std::experimental::optional<Strings> ParsedDerivation::getStringsAttr(const std::string & name) const +{ + if (structuredAttrs) { + auto i = structuredAttrs->find(name); + if (i == structuredAttrs->end()) + return {}; + else { + if (!i->is_array()) + throw Error("attribute '%s' of derivation '%s' must be a list of strings", name, drvPath); + Strings res; + for (auto j = i->begin(); j != i->end(); ++j) { + if (!j->is_string()) + throw Error("attribute '%s' of derivation '%s' must be a list of strings", name, drvPath); + res.push_back(j->get<std::string>()); + } + return res; + } + } else { + auto i = drv.env.find(name); + if (i == drv.env.end()) + return {}; + else + return tokenizeString<Strings>(i->second); + } +} + +StringSet ParsedDerivation::getRequiredSystemFeatures() const +{ + StringSet res; + for (auto & i : getStringsAttr("requiredSystemFeatures").value_or(Strings())) + res.insert(i); + return res; +} + +bool ParsedDerivation::canBuildLocally() const +{ + if (drv.platform != settings.thisSystem.get() + && !settings.extraPlatforms.get().count(drv.platform) + && !drv.isBuiltin()) + return false; + + for (auto & feature : getRequiredSystemFeatures()) + if (!settings.systemFeatures.get().count(feature)) return false; + + return true; +} + +bool ParsedDerivation::willBuildLocally() const +{ + return getBoolAttr("preferLocalBuild") && canBuildLocally(); +} + +} diff --git a/src/libstore/parsed-derivations.hh b/src/libstore/parsed-derivations.hh new file mode 100644 index 000000000000..0a82c146172b --- /dev/null +++ b/src/libstore/parsed-derivations.hh @@ -0,0 +1,35 @@ +#include "derivations.hh" + +#include <nlohmann/json.hpp> + +namespace nix { + +class ParsedDerivation +{ + Path drvPath; + BasicDerivation & drv; + std::experimental::optional<nlohmann::json> structuredAttrs; + +public: + + ParsedDerivation(const Path & drvPath, BasicDerivation & drv); + + const std::experimental::optional<nlohmann::json> & getStructuredAttrs() const + { + return structuredAttrs; + } + + std::experimental::optional<std::string> getStringAttr(const std::string & name) const; + + bool getBoolAttr(const std::string & name, bool def = false) const; + + std::experimental::optional<Strings> getStringsAttr(const std::string & name) const; + + StringSet getRequiredSystemFeatures() const; + + bool canBuildLocally() const; + + bool willBuildLocally() const; +}; + +} diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 7711388f05a9..ba11ce6bb6de 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -19,8 +19,6 @@ #include <aws/core/utils/logging/LogMacros.h> #include <aws/core/utils/threading/Executor.h> #include <aws/s3/S3Client.h> -#include <aws/s3/model/CreateBucketRequest.h> -#include <aws/s3/model/GetBucketLocationRequest.h> #include <aws/s3/model/GetObjectRequest.h> #include <aws/s3/model/HeadObjectRequest.h> #include <aws/s3/model/ListObjectsRequest.h> @@ -202,32 +200,6 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore { if (!diskCache->cacheExists(getUri(), wantMassQuery_, priority)) { - /* Create the bucket if it doesn't already exists. */ - // FIXME: HeadBucket would be more appropriate, but doesn't return - // an easily parsed 404 message. - auto res = s3Helper.client->GetBucketLocation( - Aws::S3::Model::GetBucketLocationRequest().WithBucket(bucketName)); - - if (!res.IsSuccess()) { - if (res.GetError().GetErrorType() != Aws::S3::S3Errors::NO_SUCH_BUCKET) - throw Error(format("AWS error checking bucket '%s': %s") % bucketName % res.GetError().GetMessage()); - - printInfo("creating S3 bucket '%s'...", bucketName); - - // Stupid S3 bucket locations. - auto bucketConfig = Aws::S3::Model::CreateBucketConfiguration(); - if (s3Helper.config->region != "us-east-1") - bucketConfig.SetLocationConstraint( - Aws::S3::Model::BucketLocationConstraintMapper::GetBucketLocationConstraintForName( - s3Helper.config->region)); - - checkAws(format("AWS error creating bucket '%s'") % bucketName, - s3Helper.client->CreateBucket( - Aws::S3::Model::CreateBucketRequest() - .WithBucket(bucketName) - .WithCreateBucketConfiguration(bucketConfig))); - } - BinaryCacheStore::init(); diskCache->createCache(getUri(), storeDir, wantMassQuery_, priority); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 1f42097fccfb..2c0f68651e4f 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -610,7 +610,7 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore, }); srcStore->narFromPath({storePath}, wrapperSink); }, [&]() { - throw EndOfFile("NAR for '%s' fetched from '%s' is incomplete", storePath, srcStore->getUri()); + throw EndOfFile("NAR for '%s' fetched from '%s' is incomplete", storePath, srcStore->getUri()); }); dstStore->addToStore(*info, *source, repair, checkSigs); diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 31df6fdfde86..0e75eeec2bfe 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -169,17 +169,13 @@ std::unique_ptr<Source> sinkToSource( { typedef boost::coroutines2::coroutine<std::string> coro_t; + std::function<void(Sink &)> fun; std::function<void()> eof; - coro_t::pull_type coro; + std::experimental::optional<coro_t::pull_type> coro; + bool started = false; SinkToSource(std::function<void(Sink &)> fun, std::function<void()> eof) - : eof(eof) - , coro([&](coro_t::push_type & yield) { - LambdaSink sink([&](const unsigned char * data, size_t len) { - if (len) yield(std::string((const char *) data, len)); - }); - fun(sink); - }) + : fun(fun), eof(eof) { } @@ -188,11 +184,19 @@ std::unique_ptr<Source> sinkToSource( size_t read(unsigned char * data, size_t len) override { - if (!coro) { eof(); abort(); } + if (!coro) + coro = coro_t::pull_type([&](coro_t::push_type & yield) { + LambdaSink sink([&](const unsigned char * data, size_t len) { + if (len) yield(std::string((const char *) data, len)); + }); + fun(sink); + }); + + if (!*coro) { eof(); abort(); } if (pos == cur.size()) { - if (!cur.empty()) coro(); - cur = coro.get(); + if (!cur.empty()) (*coro)(); + cur = coro->get(); pos = 0; } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 94d3a27560fe..b78f3d9e424e 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -417,16 +417,20 @@ void mainWrapped(int argc, char * * argv) "dontAddDisableDepTrack=1; " "[ -e $stdenv/setup ] && source $stdenv/setup; " "%3%" + "PATH=\"%4%:$PATH\"; " + "SHELL=%5%; " "set +e; " R"s([ -n "$PS1" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s" "if [ \"$(type -t runHook)\" = function ]; then runHook shellHook; fi; " "unset NIX_ENFORCE_PURITY; " "shopt -u nullglob; " - "unset TZ; %4%" - "%5%", + "unset TZ; %6%" + "%7%", (Path) tmpDir, (pure ? "" : "p=$PATH; "), (pure ? "" : "PATH=$PATH:$p; unset p; "), + dirOf(shell), + shell, (getenv("TZ") ? (string("export TZ='") + getenv("TZ") + "'; ") : ""), envCommand)); diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 615c1f5dc065..423ba15e2ad0 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -709,7 +709,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store, logger->startWork(); // FIXME: race if addToStore doesn't read source? - store.cast<Store>()->addToStore(info, *source, (RepairFlag) repair, + store->addToStore(info, *source, (RepairFlag) repair, dontCheckSigs ? NoCheckSigs : CheckSigs, nullptr); logger->stopWork(); diff --git a/src/nix/copy.cc b/src/nix/copy.cc index 91711c8b46da..96bd453d87b4 100644 --- a/src/nix/copy.cc +++ b/src/nix/copy.cc @@ -69,12 +69,12 @@ struct CmdCopy : StorePathsCommand }, #ifdef ENABLE_S3 Example{ - "To populate the current folder build output to a S3 binary cache:", - "nix copy --to s3://my-bucket?region=eu-west-1" + "To copy Hello to an S3 binary cache:", + "nix copy --to s3://my-bucket?region=eu-west-1 nixpkgs.hello" }, Example{ - "To populate the current folder build output to an S3-compatible binary cache:", - "nix copy --to s3://my-bucket?region=eu-west-1&endpoint=example.com" + "To copy Hello to an S3-compatible binary cache:", + "nix copy --to s3://my-bucket?region=eu-west-1&endpoint=example.com nixpkgs.hello" }, #endif }; diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 6540208a8a2c..7ef571561a0e 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -120,7 +120,7 @@ struct CmdVerify : StorePathsCommand for (auto sig : sigs) { if (sigsSeen.count(sig)) continue; sigsSeen.insert(sig); - if (info->checkSignature(publicKeys, sig)) + if (validSigs < ValidPathInfo::maxSigs && info->checkSignature(publicKeys, sig)) validSigs++; } }; diff --git a/tests/build-remote.sh b/tests/build-remote.sh index 9bca0f4a3856..ddd68f327a15 100644 --- a/tests/build-remote.sh +++ b/tests/build-remote.sh @@ -11,7 +11,8 @@ rm -rf $TEST_ROOT/store0 $TEST_ROOT/store1 nix build -f build-hook.nix -o $TEST_ROOT/result --max-jobs 0 \ --sandbox-paths /nix/store --sandbox-build-dir /build-tmp \ - --builders "$TEST_ROOT/store0; $TEST_ROOT/store1 - - 1 1 foo" + --builders "$TEST_ROOT/store0; $TEST_ROOT/store1 - - 1 1 foo" \ + --system-features foo outPath=$TEST_ROOT/result diff --git a/tests/signing.sh b/tests/signing.sh index 46929639199d..9e29e3fbf063 100644 --- a/tests/signing.sh +++ b/tests/signing.sh @@ -62,6 +62,10 @@ outPathCA=$(IMPURE_VAR1=foo IMPURE_VAR2=bar nix-build ./fixed.nix -A good.0 --no nix verify $outPathCA nix verify $outPathCA --sigs-needed 1000 +# Check that signing a content-addressed path doesn't overflow validSigs +nix sign-paths --key-file $TEST_ROOT/sk1 $outPathCA +nix verify -r $outPathCA --sigs-needed 1000 --trusted-public-keys $pk1 + # Copy to a binary cache. nix copy --to file://$cacheDir $outPath2 |