Compare commits

...

75 Commits

Author SHA1 Message Date
Eelco Dolstra
a3d874175c Add builtins.unique [WIP]
This cuts ~4.5s from "nix-env -qaP -f `<nixpkgs>` --out-path" and
reduces memory allocations from 7.49 to 7.16 GiB.

Note that builtins.unique requires a less-than comparator function,
which is a change from the 'unique' function in Nixpkgs which uses an
equality function.
2019-04-12 22:47:14 +02:00
Eelco Dolstra
bb6e6923f2 Add environment variable NIX_SHOW_SYMBOLS for dumping the symbol table 2019-04-11 23:04:13 +02:00
Eelco Dolstra
41ba5135e0 primeCache(): Barf if builds are needed but not allowed
Fixes #2753.
2019-04-01 21:09:49 +02:00
Eelco Dolstra
2bc6304793 getMachines(): Cache result 2019-04-01 21:09:35 +02:00
Eelco Dolstra
2f59b30251 Use Nixpkgs 19.03 2019-04-01 21:09:25 +02:00
Eelco Dolstra
f32fbf952d Fix Bison 3.3 warning 2019-03-27 21:09:31 +01:00
Eelco Dolstra
e489f5cabf Update eval-okay-types.exp to match #1828 2019-03-27 21:07:04 +01:00
Graham Christensen
6e9e34ea1f Merge pull request #2744 from veprbl/patch-8
manual: mention the "channel:" shorthand for NIX_PATH
2019-03-25 21:49:48 -04:00
Dmitry Kalinkin
75ec68f93a manual: mention the "channel:" shorthand for NIX_PATH
Bumped to 15.09 because older channels, when downloaded from
nixos.org, require firefox to be accessed via `pkgs.firefox`
2019-03-25 20:55:28 -04:00
Eelco Dolstra
5c05c238e6 Merge pull request #1828 from zimbatm/isPath
Add isPath primop
2019-03-25 19:58:11 +01:00
Will Dietz
63e7fc5096 perl/configure.ac: fix for new version location too 2019-03-25 09:18:30 +01:00
Will Dietz
1f9c8cd68b configure.ac: update for new version file location 2019-03-25 09:18:30 +01:00
Will Dietz
42e2d5e7b7 store-api.hh: add missing include for unordered_map 2019-03-25 09:18:30 +01:00
Will Dietz
0bebca402a version -> .version, avoid conflict with C++20 <version> 2019-03-25 09:18:30 +01:00
Domen Kožar
6f0359012c Merge pull request #2693 from thoughtpolice/scripts/multi-user-sandbox
scripts: remove default 'sandbox = false' from multi-user installer
2019-03-24 19:45:56 +07:00
zimbatm
514b3c7f83 Add isPath primop
this is added for completeness' sake since all the other possible
`builtins.typeOf` results have a corresponding `builtins.is<Type>`
2019-03-24 11:36:49 +01:00
Eelco Dolstra
56f1ed5579 Merge pull request #2741 from mayflower/primop-type-desc
eval: improve type description for primops and applied primops
2019-03-21 15:49:19 +01:00
Linus Heckemann
2aa89daab3 eval: improve type description for primops and applied primops
This can make type errors a little easier to understand.
2019-03-21 15:31:46 +01:00
Eelco Dolstra
6a3dfcb623 Merge pull request #2739 from mayflower/builtins-doc-explicit
manual: include builtins.* for globally available builtins
2019-03-21 12:24:44 +01:00
Linus Heckemann
6f093073b6 manual: include builtins.* for globally available builtins
This improves searchability.
2019-03-21 09:37:22 +01:00
Eelco Dolstra
ffeabf8390 Merge pull request #2731 from nomeata/link-to-conf-builders-use-substitutes
Link to `builders-use-substitutes` in chapter on distributed builds
2019-03-18 13:54:47 +01:00
Joachim Breitner
684c7fff80 Link to builders-use-substitutes in chapter on distributed builds
fixes #2730.
2019-03-16 19:03:40 +01:00
Eelco Dolstra
806291d18c Merge pull request #2727 from Chakerbh/master
Add a 5 seconds of timeout to connecting to S3.
2019-03-15 21:25:10 +08:00
Chaker Benhamed
81a23fa7e2 Add a 5 seconds of timeouts to connect to S3.
The default is 1000ms, but we can hit it a lot of we don't have direct
link to AWS (e.g. using VPN).
2019-03-15 13:23:58 +01:00
Graham Christensen
caf297a9d3 Merge pull request #2725 from andir/docs/s3-typo
docs: fix typo in AllowDirectReads
2019-03-14 18:53:57 -04:00
Andreas Rammhold
34fade478a docs: fix typo in AllowDirectReads
It was just missing an `l` but should be fixed anyway.
2019-03-14 23:51:18 +01:00
Eelco Dolstra
1f64f4c7c8 pkg-config files: Use c++17 2019-03-14 14:11:12 +01:00
Eelco Dolstra
ef52ccf035 experimental/optional -> optional 2019-03-14 14:10:52 +01:00
Eelco Dolstra
86f3b94c8c nix-store --gc --print-roots: Sort output 2019-03-14 13:59:10 +01:00
Eelco Dolstra
578ed7a259 findRoots(): Don't censor for trusted users
They're pretty much root anyway.
2019-03-14 13:53:34 +01:00
Eelco Dolstra
53522cb6ac findRoots(): Add 'censor' parameter
This is less brittle than filtering paths after the fact in
nix-daemon.
2019-03-14 13:53:34 +01:00
Eelco Dolstra
a3f37d87ea findRuntimeRoots: Simplify/fix handling of /proc files
Scanning of /proc/<pid>/{exe,cwd} was broken because '{memory:' was
prepended twice. Also, get rid of the whole '{memory:...}' thing
because it's unnecessary, we can just list the file in /proc directly.
2019-03-14 13:30:25 +01:00
Guillaume Maudoux
115e2c8c67 Update tests to the new --roots format 2019-03-10 01:50:33 +01:00
Guillaume Maudoux
4f4391193c Fix warning about unused variable 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
38ee16ae9c Unify internal findRootsXxx() api 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
9d7221183a unify naming of roots as links & targets 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
9d87e3fbd2 require c++ 17
This fixes warnings about "structured binding declaration" requiring
"-std=c++1z".
2019-03-10 00:56:09 +01:00
Guillaume Maudoux
5c56570726 Also obfuscate the number of memory roots 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
fc02b1b3ee Also print rooted path in nix-store -q --roots 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
8574b70342 fixup! Make roots a map of store paths to pinning links 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
ebc86550f9 Make roots a map of store paths to pinning links
This new structure makes more sense as there may be many sources rooting
the same store path. Many profiles can reference the same path but this
is even more true with /proc/<pid>/maps where distinct pids can and
often do map the same store path.
This implementation is also more efficient as the `Roots` map contains
only one entry per rooted store path.
2019-03-10 00:56:09 +01:00
Guillaume Maudoux
a17f86ce3a Obfuscate memory roots for non-root users 2019-03-10 00:56:09 +01:00
Guillaume Maudoux
43331d6344 detail memory roots 2019-03-10 00:56:09 +01:00
Eelco Dolstra
5886bc5996 Merge pull request #2710 from volth/patch-6
canBuildLocally: check for features
2019-03-06 13:21:44 +08:00
volth
fff8db205c canBuildLocally: check for features
It could happen that the local builder match the system but lacks some features.
Now it results a failure.
The fix gracefully excludes the local builder from the set of available builders for derivation which requires the feature, so the derivation is built on remote builders only (as though it has incompatible system, like ```aarch64-linux``` when local is x86)
2019-03-06 05:03:25 +00:00
Eelco Dolstra
b71e1fb342 Restore --init calls in tests 2019-03-04 18:27:45 +08:00
Vladimír Čunát
4cfc131ec4 manual nitpick: document sha512 support in hashString 2019-03-01 14:30:30 +01:00
Will Dietz
0963479741 archive.cc: ignore more posix_fallocate "not supported" error codes
Fixes w/musl.
2019-03-01 10:31:17 +08:00
Eelco Dolstra
ad6dbecc1d Merge pull request #2674 from LnL7/daemon-disable-fork-safety
nix-daemon: add variable to disable fork safety
2019-03-01 02:07:50 +01:00
Eelco Dolstra
ebd4d50e6e Merge pull request #2703 from pradd/support_s3_region_param
Support parameters in S3 URLs
2019-02-26 22:59:29 +08:00
Dzmitry Zaitsau
06d6335987 fix indentation 2019-02-26 11:07:37 +01:00
Dzmitry Zaitsau
ac200c3678 Apply param values on S3Helper initialization 2019-02-25 18:06:19 +01:00
Dzmitry Zaitsau
56c18c67d9 Extend S3 URL parsing with parameters extraction 2019-02-25 18:00:55 +01:00
Dzmitry Zaitsau
07f992a74b Extract and expose splitUriAndParams function
which splits a URL into localtor and parameter parts
2019-02-25 17:59:26 +01:00
Austin Seipp
d7a7a029ff scripts: remove default 'sandbox = false' from multi-user installer
Sandboxing is now enabled by default on Linux, but is still disabled on
macOS. However, the installer always turned it off to ensure consistent
behavior.

Remove this default configuration, so we fall back to the default
platform-specific value.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2019-02-23 08:35:26 -06:00
Eelco Dolstra
6bfb082ea2 Merge pull request #2694 from zimbatm/no-store-init
remove noop uses of nix-store --init
2019-02-23 12:12:36 +01:00
zimbatm
b402148d8f remove noop uses of nix-store --init
the nix-store --init command is a noop apparently
2019-02-22 21:07:53 +01:00
Shea Levy
e58a71442a nix.sh: Be set -u compliant. 2019-02-14 13:24:16 -05:00
Eelco Dolstra
d8fe447139 Merge pull request #2579 from catern/dumpdb
nix-store: make --dump-db take a list of paths to dump
2019-02-14 13:08:02 +01:00
Eelco Dolstra
25722bd39a Merge pull request #2677 from matthewbauer/disable-shared
Support --disable-shared flag.
2019-02-13 10:09:31 +01:00
Matthew Bauer
7ce1fae59f Support --disable-shared flag.
This tells Nix to not build the shared libraries.
2019-02-13 00:03:10 -05:00
Eelco Dolstra
7a7ec22298 Merge pull request #2628 from shlevy/context-introspection
Context introspection
2019-02-12 17:57:35 +01:00
Daiderd Jordan
8ac1130cc2 nix-daemon: add variable to disable fork safety
Since macOS 10.14 this has become an error, causing problems if the
nix-daemon loads nix during substitution (this is a forked process).

Workaround for #2523.
2019-02-09 20:35:30 +01:00
Eelco Dolstra
01d07b1e92 Revert "Restore parent mount namespace before executing a child process"
This reverts commit a0ef21262f. This
doesn't work in 'nix run' and nix-shell because setns() fails in
multithreaded programs, and Boehm GC mark threads are uncancellable.

Fixes #2646.
2019-02-05 10:49:19 +01:00
Shea Levy
b30be6b450 Add builtins.appendContext.
A partner of builtins.getContext, useful for the same reasons.
2019-01-31 08:52:23 -05:00
Spencer Baugh
5f1891b795 nix-store: make --dump-db take a list of paths to dump
Inside a derivation, exportReferencesGraph already provides a way to
dump the Nix database for a specific closure. On the command line,
--dump-db gave us the same information, but only for the entire Nix
database at once.

With this change, one can now pass a list of paths to --dump-db to get
the Nix database dumped for just those paths. (The user is responsible
for ensuring this is a closure, like for --export).

Among other things, this is useful for deploying a closure to a new
host without using --import/--export; one can use tar to transfer the
store paths, and --dump-db/--load-db to transfer the validity
information. This is useful if the new host doesn't actually have Nix
yet, and the closure that is being deployed itself contains Nix.
2019-01-23 01:24:34 +00:00
Domen Kožar
92d08c02c8 Merge pull request #2635 from veprbl/patch-7
manual: "sandbox" option default is "true" on Linux
2019-01-20 09:43:26 +07:00
Dmitry Kalinkin
15efd54373 manual: "sandbox" option default is "true" on Linux
Fixes: 812e39313c ('Enable sandboxing by default')
2019-01-19 15:04:43 -05:00
Eelco Dolstra
7cc1a2593e unsupported(): Show the name of the unsupported operation 2019-01-18 13:34:53 +01:00
Eelco Dolstra
df03430586 Merge pull request #2638 from sevanspowell/update-nix-shell-interpreter-haskell-instructions
Update instructions for Haskell script using nix-shell interpreter
2019-01-18 13:17:10 +01:00
Samuel Evans-Powell
2ae5624b2f Update instructions for Haskell script using nix-shell interpreter
- The instructions for using nix-shell as an interpreter has a Haskell script
  example that doesn't work on more recent versions of Nix. Update the
  instructions with a working command
2019-01-18 10:50:54 +10:00
Shea Levy
1d757292d0 Add builtins.getContext.
This can be very helpful when debugging, as well as enabling complex
black magic like surgically removing a single dependency from a
string's context.
2019-01-14 11:27:10 -05:00
Shea Levy
087be7281a Treat plain derivation paths in context as normal paths.
Previously, plain derivation paths in the string context (e.g. those
that arose from builtins.storePath on a drv file, not those that arose
from accessing .drvPath of a derivation) were treated somewhat like
derivaiton paths derived from .drvPath, except their dependencies
weren't recursively added to the input set. With this change, such
plain derivation paths are simply treated as paths and added to the
source inputs set accordingly, simplifying context handling code and
removing the inconsistency. If drvPath-like behavior is desired, the
.drv file can be imported and then .drvPath can be accessed.

This is a backwards-incompatibility, but storePath is never used on
drv files within nixpkgs and almost never used elsewhere.
2019-01-13 11:29:55 -05:00
Eelco Dolstra
4ae6e84901 install: Use base-16 hashes
Issue #2623.
2019-01-11 16:33:59 +01:00
Eelco Dolstra
8ce1986611 Bump version 2019-01-11 16:33:59 +01:00
66 changed files with 626 additions and 350 deletions

3
.gitignore vendored
View File

@@ -81,6 +81,9 @@ perl/Makefile.config
/tests/common.sh
/tests/dummy
/tests/result*
/tests/restricted-innocent
/tests/shell
/tests/shell.drv
# /tests/lang/
/tests/lang/*.out

1
.version Normal file
View File

@@ -0,0 +1 @@
2.3

View File

@@ -1,4 +1,6 @@
AR = @AR@
BDW_GC_LIBS = @BDW_GC_LIBS@
BUILD_SHARED_LIBS = @BUILD_SHARED_LIBS@
CC = @CC@
CFLAGS = @CFLAGS@
CXX = @CXX@

View File

@@ -1,4 +1,4 @@
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./version)$VERSION_SUFFIX"]))
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./.version)$VERSION_SUFFIX"]))
AC_CONFIG_SRCDIR(README.md)
AC_CONFIG_AUX_DIR(config)
@@ -62,8 +62,9 @@ CXXFLAGS=
AC_PROG_CC
AC_PROG_CXX
AC_PROG_CPP
AX_CXX_COMPILE_STDCXX_14
AX_CXX_COMPILE_STDCXX_17
AC_CHECK_TOOL([AR], [ar])
# Use 64-bit file system calls so that we can support files > 2 GiB.
AC_SYS_LARGEFILE
@@ -267,6 +268,15 @@ AC_ARG_WITH(sandbox-shell, AC_HELP_STRING([--with-sandbox-shell=PATH],
sandbox_shell=$withval)
AC_SUBST(sandbox_shell)
AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared],
[Build shared libraries for Nix [default=yes]]),
shared=$enableval, shared=yes)
if test "$shared" = yes; then
AC_SUBST(BUILD_SHARED_LIBS, 1, [Whether to build shared libraries.])
else
AC_SUBST(BUILD_SHARED_LIBS, 0, [Whether to build shared libraries.])
fi
# Expand all variables in config.status.
test "$prefix" = NONE && prefix=$ac_default_prefix

View File

@@ -180,4 +180,8 @@ builders = @/etc/nix/machines
causes the list of machines in <filename>/etc/nix/machines</filename>
to be included. (This is the default.)</para>
<para>If you want the builders to use caches, you likely want to set
the option <link linkend='conf-builders-use-substitutes'><literal>builders-use-substitutes</literal></link>
in your local <filename>nix.conf</filename>.</para>
</chapter>

View File

@@ -657,7 +657,8 @@ password <replaceable>my-password</replaceable>
<varname>__noChroot</varname> attribute set to
<literal>true</literal> do not run in sandboxes.</para>
<para>The default is <literal>false</literal>.</para>
<para>The default is <literal>true</literal> on Linux and
<literal>false</literal> on all other platforms.</para>
</listitem>

View File

@@ -52,10 +52,15 @@ nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
<envar>NIX_PATH</envar> to
<screen>
nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz</screen>
nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-15.09.tar.gz</screen>
tells Nix to download the latest revision in the Nixpkgs/NixOS
14.12 channel.</para>
15.09 channel.</para>
<para>A following shorthand can be used to refer to the official channels:
<screen>nixpkgs=channel:nixos-15.09</screen>
</para>
<para>The search path can be extended using the <option
linkend="opt-I">-I</option> option, which takes precedence over

View File

@@ -337,7 +337,7 @@ following Haskell script uses a specific branch of Nixpkgs/NixOS (the
<programlisting><![CDATA[
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p haskellPackages.ghc haskellPackages.HTTP haskellPackages.tagsoup
#! nix-shell -i runghc -p "haskellPackages.ghcWithPackages (ps: [ps.HTTP ps.tagsoup])"
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-18.03.tar.gz
import Network.HTTP

View File

@@ -1282,6 +1282,7 @@ ktorrent-2.2.1/NEWS
<cmdsynopsis>
<command>nix-store</command>
<arg choice='plain'><option>--dump-db</option></arg>
<arg rep='repeat'><replaceable>paths</replaceable></arg>
</cmdsynopsis>
</refsection>
@@ -1292,6 +1293,13 @@ Nix database to standard output. It can be loaded into an empty Nix
store using <option>--load-db</option>. This is useful for making
backups and when migrating to different database schemas.</para>
<para>By default, <option>--dump-db</option> will dump the entire Nix
database. When one or more store paths is passed, only the subset of
the Nix database for those store paths is dumped. As with
<option>--export</option>, the user is responsible for passing all the
store paths for a closure. See <option>--export</option> for an
example.</para>
</refsection>
</refsection>

View File

@@ -23,6 +23,7 @@ available as <function>builtins.derivation</function>.</para>
<varlistentry xml:id='builtin-abort'>
<term><function>abort</function> <replaceable>s</replaceable></term>
<term><function>builtins.abort</function> <replaceable>s</replaceable></term>
<listitem><para>Abort Nix expression evaluation, print error
message <replaceable>s</replaceable>.</para></listitem>
@@ -251,6 +252,8 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
<varlistentry xml:id='builtin-derivation'>
<term><function>derivation</function>
<replaceable>attrs</replaceable></term>
<term><function>builtins.derivation</function>
<replaceable>attrs</replaceable></term>
<listitem><para><function>derivation</function> is described in
<xref linkend='ssec-derivation' />.</para></listitem>
@@ -260,6 +263,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
<varlistentry xml:id='builtin-dirOf'>
<term><function>dirOf</function> <replaceable>s</replaceable></term>
<term><function>builtins.dirOf</function> <replaceable>s</replaceable></term>
<listitem><para>Return the directory part of the string
<replaceable>s</replaceable>, that is, everything before the final
@@ -318,6 +322,8 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
<varlistentry xml:id='builtin-fetchTarball'>
<term><function>fetchTarball</function>
<replaceable>url</replaceable></term>
<term><function>builtins.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
@@ -693,8 +699,8 @@ builtins.genList (x: x * x) 5
<listitem><para>Return a base-16 representation of the
cryptographic hash of string <replaceable>s</replaceable>. The
hash algorithm specified by <replaceable>type</replaceable> must
be one of <literal>"md5"</literal>, <literal>"sha1"</literal> or
<literal>"sha256"</literal>.</para></listitem>
be one of <literal>"md5"</literal>, <literal>"sha1"</literal>,
<literal>"sha256"</literal> or <literal>"sha512"</literal>.</para></listitem>
</varlistentry>
@@ -714,6 +720,8 @@ builtins.genList (x: x * x) 5
<varlistentry xml:id='builtin-import'>
<term><function>import</function>
<replaceable>path</replaceable></term>
<term><function>builtins.import</function>
<replaceable>path</replaceable></term>
<listitem><para>Load, parse and return the Nix expression in the
file <replaceable>path</replaceable>. If <replaceable>path
@@ -853,10 +861,20 @@ x: x + 456</programlisting>
</varlistentry>
<varlistentry><term><function>builtins.isPath</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to a path, and
<literal>false</literal> otherwise.</para></listitem>
</varlistentry>
<varlistentry xml:id='builtin-isNull'>
<term><function>isNull</function>
<replaceable>e</replaceable></term>
<term><function>builtins.isNull</function>
<replaceable>e</replaceable></term>
<listitem><para>Return <literal>true</literal> if
<replaceable>e</replaceable> evaluates to <literal>null</literal>,
@@ -925,6 +943,8 @@ builtins.listToAttrs
<varlistentry xml:id='builtin-map'>
<term><function>map</function>
<replaceable>f</replaceable> <replaceable>list</replaceable></term>
<term><function>builtins.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
@@ -1119,6 +1139,8 @@ Evaluates to <literal>[ "foo" ]</literal>.
<varlistentry xml:id='builtin-removeAttrs'>
<term><function>removeAttrs</function>
<replaceable>set</replaceable> <replaceable>list</replaceable></term>
<term><function>builtins.removeAttrs</function>
<replaceable>set</replaceable> <replaceable>list</replaceable></term>
<listitem><para>Remove the attributes listed in
<replaceable>list</replaceable> from
@@ -1287,6 +1309,8 @@ builtins.substring 0 3 "nixos"
<varlistentry xml:id='builtin-throw'>
<term><function>throw</function>
<replaceable>s</replaceable></term>
<term><function>builtins.throw</function>
<replaceable>s</replaceable></term>
<listitem><para>Throw an error message
<replaceable>s</replaceable>. This usually aborts Nix expression
@@ -1405,6 +1429,7 @@ in foo</programlisting>
<varlistentry xml:id='builtin-toString'>
<term><function>toString</function> <replaceable>e</replaceable></term>
<term><function>builtins.toString</function> <replaceable>e</replaceable></term>
<listitem><para>Convert the expression
<replaceable>e</replaceable> to a string.

View File

@@ -89,7 +89,7 @@ the S3 URL:</para>
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AlowDirectReads",
"Sid": "AllowDirectReads",
"Action": [
"s3:GetObject",
"s3:GetBucketLocation"

View File

@@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</key>
<string>YES</string>
</dict>
<key>Label</key>
<string>org.nixos.nix-daemon</string>
<key>KeepAlive</key>

View File

@@ -125,7 +125,7 @@ define build-library
$(1)_PATH := $$(_d)/$$($(1)_NAME).a
$$($(1)_PATH): $$($(1)_OBJS) | $$(_d)/
$(trace-ar) ar crs $$@ $$?
$(trace-ar) $(AR) crs $$@ $$?
$(1)_LDFLAGS_USE += $$($(1)_PATH) $$($(1)_LDFLAGS)

View File

@@ -1,4 +1,4 @@
AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../version)$VERSION_SUFFIX"]))
AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../.version)$VERSION_SUFFIX"]))
AC_CONFIG_SRCDIR(MANIFEST)
AC_CONFIG_AUX_DIR(../config)

View File

@@ -1,5 +1,5 @@
{ nix ? builtins.fetchGit ./.
, nixpkgs ? builtins.fetchGit { url = https://github.com/NixOS/nixpkgs-channels.git; ref = "nixos-18.09"; }
, nixpkgs ? builtins.fetchGit { url = https://github.com/NixOS/nixpkgs-channels.git; ref = "nixos-19.03"; }
, officialRelease ? false
, systems ? [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" ]
}:
@@ -18,7 +18,7 @@ let
releaseTools.sourceTarball {
name = "nix-tarball";
version = builtins.readFile ./version;
version = builtins.readFile ./.version;
versionSuffix = if officialRelease then "" else "pre${toString nix.revCount}_${nix.shortRev}";
src = nix;
inherit officialRelease;
@@ -278,7 +278,6 @@ let
pkgs.runCommand "eval-nixos" { buildInputs = [ build.x86_64-linux ]; }
''
export NIX_STATE_DIR=$TMPDIR
nix-store --init
nix-instantiate ${nixpkgs}/nixos/release-combined.nix -A tested --dry-run \
--arg nixpkgs '{ outPath = ${nixpkgs}; revCount = 123; shortRev = "abcdefgh"; }'
@@ -296,7 +295,7 @@ let
substitute ${./scripts/install.in} $out/install \
${pkgs.lib.concatMapStrings
(system: "--replace '@binaryTarball_${system}@' $(nix hash-file --type sha256 ${binaryTarball.${system}}/*.tar.bz2) ")
(system: "--replace '@binaryTarball_${system}@' $(nix hash-file --base16 --type sha256 ${binaryTarball.${system}}/*.tar.bz2) ")
[ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" ]
} \
--replace '@nixVersion@' ${build.x86_64-linux.src.version}

View File

@@ -674,9 +674,6 @@ $NIX_INSTALLED_NIX.
EOF
fi
_sudo "to initialize the Nix Database" \
$NIX_INSTALLED_NIX/bin/nix-store --init
cat ./.reginfo \
| _sudo "to load data for the first time in to the Nix Database" \
"$NIX_INSTALLED_NIX/bin/nix-store" --load-db
@@ -747,7 +744,6 @@ build-users-group = $NIX_BUILD_GROUP_NAME
max-jobs = $NIX_USER_COUNT
cores = 1
sandbox = false
EOF
_sudo "to place the default nix daemon configuration (part 2)" \
install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf

View File

@@ -109,12 +109,6 @@ for i in $(cd "$self/store" >/dev/null && echo ./*); do
done
echo "" >&2
echo "initialising Nix database..." >&2
if ! $nix/bin/nix-store --init; then
echo "$0: failed to initialize the Nix database" >&2
exit 1
fi
if ! "$nix/bin/nix-store" --load-db < "$self/.reginfo"; then
echo "$0: unable to register valid paths" >&2
exit 1

View File

@@ -75,7 +75,7 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
fi
if [ -n "${MANPATH}" ]; then
if [ -n "${MANPATH-}" ]; then
export MANPATH="$NIX_LINK/share/man:$MANPATH"
fi

View File

@@ -1,6 +1,6 @@
{ useClang ? false }:
with import (builtins.fetchGit { url = https://github.com/NixOS/nixpkgs-channels.git; ref = "nixos-18.09"; }) {};
with import (builtins.fetchGit { url = https://github.com/NixOS/nixpkgs-channels.git; ref = "nixos-19.03"; }) {};
with import ./release-common.nix { inherit pkgs; };

View File

@@ -38,6 +38,12 @@ static AutoCloseFD openSlotLock(const Machine & m, unsigned long long slot)
return openLockFile(fmt("%s/%s-%d", currentLoad, escapeUri(m.storeUri), slot), true);
}
static bool allSupportedLocally(const std::set<std::string>& requiredFeatures) {
for (auto & feature : requiredFeatures)
if (!settings.systemFeatures.get().count(feature)) return false;
return true;
}
static int _main(int argc, char * * argv)
{
{
@@ -97,9 +103,10 @@ static int _main(int argc, char * * argv)
source >> drvPath;
auto requiredFeatures = readStrings<std::set<std::string>>(source);
auto canBuildLocally = amWilling
&& ( neededSystem == settings.thisSystem
|| settings.extraPlatforms.get().count(neededSystem) > 0);
auto canBuildLocally = amWilling
&& ( neededSystem == settings.thisSystem
|| settings.extraPlatforms.get().count(neededSystem) > 0)
&& allSupportedLocally(requiredFeatures);
/* Error ignored here, will be caught later */
mkdir(currentLoad.c_str(), 0777);

View File

@@ -130,6 +130,16 @@ std::ostream & operator << (std::ostream & str, const Value & v)
}
const Value *getPrimOp(const Value &v) {
const Value * primOp = &v;
while (primOp->type == tPrimOpApp) {
primOp = primOp->primOpApp.left;
}
assert(primOp->type == tPrimOp);
return primOp;
}
string showType(const Value & v)
{
switch (v.type) {
@@ -144,8 +154,10 @@ string showType(const Value & v)
case tApp: return "a function application";
case tLambda: return "a function";
case tBlackhole: return "a black hole";
case tPrimOp: return "a built-in function";
case tPrimOpApp: return "a partially applied built-in function";
case tPrimOp:
return fmt("the built-in function '%s'", string(v.primOp->name));
case tPrimOpApp:
return fmt("the partially applied built-in function '%s'", string(getPrimOp(v)->primOp->name));
case tExternal: return v.external->showType();
case tFloat: return "a float";
}
@@ -1799,6 +1811,7 @@ void EvalState::printStats()
gc.attr("totalBytes", totalBytes);
}
#endif
if (countCalls) {
{
auto obj = topObj.object("primops");
@@ -1834,6 +1847,11 @@ void EvalState::printStats()
}
}
}
if (getEnv("NIX_SHOW_SYMBOLS", "0") != "0") {
auto list = topObj.list("symbols");
symbols.dump([&](const std::string & s) { list.elem(s); });
}
}
}

View File

@@ -81,7 +81,7 @@ public:
/* The allowed filesystem paths in restricted or pure evaluation
mode. */
std::experimental::optional<PathSet> allowedPaths;
std::optional<PathSet> allowedPaths;
Value vEmptySet;
@@ -316,6 +316,9 @@ private:
/* Return a string representing the type of the value `v'. */
string showType(const Value & v);
/* Decode a context string !<name>!<path> into a pair <path,
name>. */
std::pair<string, string> decodeContext(const string & s);
/* If `path' refers to a directory, then append "/default.nix". */
Path resolveExprPath(Path path);

View File

@@ -295,7 +295,7 @@ static bool getDerivation(EvalState & state, Value & v,
}
std::experimental::optional<DrvInfo> getDerivation(EvalState & state, Value & v,
std::optional<DrvInfo> getDerivation(EvalState & state, Value & v,
bool ignoreAssertionFailures)
{
Done done;

View File

@@ -78,7 +78,7 @@ typedef list<DrvInfo> DrvInfos;
/* If value `v' denotes a derivation, return a DrvInfo object
describing it. Otherwise return nothing. */
std::experimental::optional<DrvInfo> getDerivation(EvalState & state,
std::optional<DrvInfo> getDerivation(EvalState & state,
Value & v, bool ignoreAssertionFailures);
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,

View File

@@ -7,4 +7,4 @@ Description: Nix Package Manager
Version: @PACKAGE_VERSION@
Requires: nix-store bdw-gc
Libs: -L${libdir} -lnixexpr
Cflags: -I${includedir}/nix -std=c++14
Cflags: -I${includedir}/nix -std=c++17

View File

@@ -1,7 +1,7 @@
%glr-parser
%pure-parser
%locations
%error-verbose
%define parse.error verbose
%defines
/* %no-lines */
%parse-param { void * scanner }

View File

@@ -315,6 +315,12 @@ static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Valu
mkBool(v, args[0]->type == tBool);
}
/* Determine whether the argument is a path. */
static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceValue(*args[0]);
mkBool(v, args[0]->type == tPath);
}
struct CompareValues
{
@@ -335,6 +341,8 @@ struct CompareValues
return strcmp(v1->string.s, v2->string.s) < 0;
case tPath:
return strcmp(v1->path, v2->path) < 0;
case tAttrs:
return v1 < v2; // FIXME
default:
throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) % showType(*v2));
}
@@ -555,7 +563,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
PathSet context;
std::experimental::optional<std::string> outputHash;
std::optional<std::string> outputHash;
std::string outputHashAlgo;
bool outputHashRecursive = false;
@@ -687,21 +695,12 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
}
}
/* See prim_unsafeDiscardOutputDependency. */
else if (path.at(0) == '~')
drv.inputSrcs.insert(string(path, 1));
/* Handle derivation outputs of the form !<name>!<path>. */
else if (path.at(0) == '!') {
std::pair<string, string> ctx = decodeContext(path);
drv.inputDrvs[ctx.first].insert(ctx.second);
}
/* Handle derivation contexts returned by
builtins.storePath. */
else if (isDerivation(path))
drv.inputDrvs[path] = state.store->queryDerivationOutputNames(path);
/* Otherwise it's a source file. */
else
drv.inputSrcs.insert(path);
@@ -1004,13 +1003,8 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
PathSet refs;
for (auto path : context) {
if (path.at(0) == '=') path = string(path, 1);
if (isDerivation(path)) {
/* See prim_unsafeDiscardOutputDependency. */
if (path.at(0) != '~')
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos);
path = string(path, 1);
}
if (path.at(0) != '/')
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos);
refs.insert(path);
}
@@ -1584,7 +1578,6 @@ static void prim_sort(EvalState & state, const Pos & pos, Value * * args, Value
v.listElems()[n] = args[1]->listElems()[n];
}
auto comparator = [&](Value * a, Value * b) {
/* Optimization: if the comparator is lessThan, bypass
callFunction. */
@@ -1604,6 +1597,62 @@ static void prim_sort(EvalState & state, const Pos & pos, Value * * args, Value
}
static void prim_unique(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceFunction(*args[0], pos);
state.forceList(*args[1], pos);
auto len = args[1]->listSize();
Value * vs[len];
for (size_t n = 0; n < len; ++n) {
auto v2 = args[1]->listElems()[n];
state.forceValue(*v2);
vs[n] = v2;
}
auto comparator = [&](Value * a, Value * b) {
/* Optimization: if the comparator is lessThan, bypass
callFunction. */
if (args[0]->type == tPrimOp && args[0]->primOp->fun == prim_lessThan)
return CompareValues()(a, b);
Value vTmp1, vTmp2;
state.callFunction(*args[0], *a, vTmp1, pos);
state.callFunction(vTmp1, *b, vTmp2, pos);
return state.forceBool(vTmp2, pos);
};
std::sort(vs, vs + len, comparator);
auto outLen = std::min((size_t) 1, len);
for (size_t n = 1; n < len; n++) {
if (comparator(vs[outLen - 1], vs[n])) {
vs[outLen++] = vs[n];
}
}
std::sort(vs, vs + outLen);
state.mkList(v, outLen);
size_t outPos = 0;
for (size_t n = 0; n < len; n++) {
auto v2 = args[1]->listElems()[n];
auto i = std::lower_bound(vs, vs + outLen, v2);
if (*i == v2) {
// Remove v2 from the set by setting its least significant
// bit. (This doesn't change the sort order.)
*i = (Value *) (((ptrdiff_t) v2) | 1);
assert(outPos < outLen);
v.listElems()[outPos++] = v2;
}
}
assert(outPos == outLen);
}
static void prim_partition(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceFunction(*args[0], pos);
@@ -1794,41 +1843,6 @@ static void prim_stringLength(EvalState & state, const Pos & pos, Value * * args
}
static void prim_unsafeDiscardStringContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
mkString(v, s, PathSet());
}
static void prim_hasContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
state.forceString(*args[0], context, pos);
mkBool(v, !context.empty());
}
/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
builder without causing the derivation to be built (for instance,
in the derivation that builds NARs in nix-push, when doing
source-only deployment). This primop marks the string context so
that builtins.derivation adds the path to drv.inputSrcs rather than
drv.inputDrvs. */
static void prim_unsafeDiscardOutputDependency(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
PathSet context2;
for (auto & p : context)
context2.insert(p.at(0) == '=' ? "~" + string(p, 1) : p);
mkString(v, s, context2);
}
/* Return the cryptographic hash of a string in base-16. */
static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
@@ -2218,6 +2232,7 @@ void EvalState::createBaseEnv()
addPrimOp("__isInt", 1, prim_isInt);
addPrimOp("__isFloat", 1, prim_isFloat);
addPrimOp("__isBool", 1, prim_isBool);
addPrimOp("__isPath", 1, prim_isPath);
addPrimOp("__genericClosure", 1, prim_genericClosure);
addPrimOp("abort", 1, prim_abort);
addPrimOp("__addErrorContext", 2, prim_addErrorContext);
@@ -2282,6 +2297,7 @@ void EvalState::createBaseEnv()
addPrimOp("__all", 2, prim_all);
addPrimOp("__genList", 2, prim_genList);
addPrimOp("__sort", 2, prim_sort);
addPrimOp("__unique", 2, prim_unique);
addPrimOp("__partition", 2, prim_partition);
addPrimOp("__concatMap", 2, prim_concatMap);
@@ -2299,9 +2315,6 @@ void EvalState::createBaseEnv()
addPrimOp("toString", 1, prim_toString);
addPrimOp("__substring", 3, prim_substring);
addPrimOp("__stringLength", 1, prim_stringLength);
addPrimOp("__hasContext", 1, prim_hasContext);
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
addPrimOp("__hashString", 2, prim_hashString);
addPrimOp("__match", 2, prim_match);
addPrimOp("__split", 2, prim_split);

View File

@@ -0,0 +1,187 @@
#include "primops.hh"
#include "eval-inline.hh"
#include "derivations.hh"
namespace nix {
static void prim_unsafeDiscardStringContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
mkString(v, s, PathSet());
}
static RegisterPrimOp r1("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
static void prim_hasContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
state.forceString(*args[0], context, pos);
mkBool(v, !context.empty());
}
static RegisterPrimOp r2("__hasContext", 1, prim_hasContext);
/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
builder without causing the derivation to be built (for instance,
in the derivation that builds NARs in nix-push, when doing
source-only deployment). This primop marks the string context so
that builtins.derivation adds the path to drv.inputSrcs rather than
drv.inputDrvs. */
static void prim_unsafeDiscardOutputDependency(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
PathSet context2;
for (auto & p : context)
context2.insert(p.at(0) == '=' ? string(p, 1) : p);
mkString(v, s, context2);
}
static RegisterPrimOp r3("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
/* Extract the context of a string as a structured Nix value.
The context is represented as an attribute set whose keys are the
paths in the context set and whose values are attribute sets with
the following keys:
path: True if the relevant path is in the context as a plain store
path (i.e. the kind of context you get when interpolating
a Nix path (e.g. ./.) into a string). False if missing.
allOutputs: True if the relevant path is a derivation and it is
in the context as a drv file with all of its outputs
(i.e. the kind of context you get when referencing
.drvPath of some derivation). False if missing.
outputs: If a non-empty list, the relevant path is a derivation
and the provided outputs are referenced in the context
(i.e. the kind of context you get when referencing
.outPath of some derivation). Empty list if missing.
Note that for a given path any combination of the above attributes
may be present.
*/
static void prim_getContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
struct ContextInfo {
bool path = false;
bool allOutputs = false;
Strings outputs;
};
PathSet context;
state.forceString(*args[0], context, pos);
auto contextInfos = std::map<Path, ContextInfo>();
for (const auto & p : context) {
Path drv;
string output;
const Path * path = &p;
if (p.at(0) == '=') {
drv = string(p, 1);
path = &drv;
} else if (p.at(0) == '!') {
std::pair<string, string> ctx = decodeContext(p);
drv = ctx.first;
output = ctx.second;
path = &drv;
}
auto isPath = drv.empty();
auto isAllOutputs = (!drv.empty()) && output.empty();
auto iter = contextInfos.find(*path);
if (iter == contextInfos.end()) {
contextInfos.emplace(*path, ContextInfo{isPath, isAllOutputs, output.empty() ? Strings{} : Strings{std::move(output)}});
} else {
if (isPath)
iter->second.path = true;
else if (isAllOutputs)
iter->second.allOutputs = true;
else
iter->second.outputs.emplace_back(std::move(output));
}
}
state.mkAttrs(v, contextInfos.size());
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs");
for (const auto & info : contextInfos) {
auto & infoVal = *state.allocAttr(v, state.symbols.create(info.first));
state.mkAttrs(infoVal, 3);
if (info.second.path)
mkBool(*state.allocAttr(infoVal, sPath), true);
if (info.second.allOutputs)
mkBool(*state.allocAttr(infoVal, sAllOutputs), true);
if (!info.second.outputs.empty()) {
auto & outputsVal = *state.allocAttr(infoVal, state.sOutputs);
state.mkList(outputsVal, info.second.outputs.size());
size_t i = 0;
for (const auto & output : info.second.outputs) {
mkString(*(outputsVal.listElems()[i++] = state.allocValue()), output);
}
}
infoVal.attrs->sort();
}
v.attrs->sort();
}
static RegisterPrimOp r4("__getContext", 1, prim_getContext);
/* Append the given context to a given string.
See the commentary above unsafeGetContext for details of the
context representation.
*/
static void prim_appendContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
auto orig = state.forceString(*args[0], context, pos);
state.forceAttrs(*args[1], pos);
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs");
for (auto & i : *args[1]->attrs) {
if (!state.store->isStorePath(i.name))
throw EvalError("Context key '%s' is not a store path, at %s", i.name, i.pos);
if (!settings.readOnlyMode)
state.store->ensurePath(i.name);
state.forceAttrs(*i.value, *i.pos);
auto iter = i.value->attrs->find(sPath);
if (iter != i.value->attrs->end()) {
if (state.forceBool(*iter->value, *iter->pos))
context.insert(i.name);
}
iter = i.value->attrs->find(sAllOutputs);
if (iter != i.value->attrs->end()) {
if (state.forceBool(*iter->value, *iter->pos)) {
if (!isDerivation(i.name)) {
throw EvalError("Tried to add all-outputs context of %s, which is not a derivation, to a string, at %s", i.name, i.pos);
}
context.insert("=" + string(i.name));
}
}
iter = i.value->attrs->find(state.sOutputs);
if (iter != i.value->attrs->end()) {
state.forceList(*iter->value, *iter->pos);
if (iter->value->listSize() && !isDerivation(i.name)) {
throw EvalError("Tried to add derivation output context of %s, which is not a derivation, to a string, at %s", i.name, i.pos);
}
for (unsigned int n = 0; n < iter->value->listSize(); ++n) {
auto name = state.forceStringNoCtx(*iter->value->listElems()[n], *iter->pos);
context.insert("!" + name + "!" + string(i.name));
}
}
}
mkString(v, orig, context);
}
static RegisterPrimOp r5("__appendContext", 2, prim_appendContext);
}

View File

@@ -26,7 +26,7 @@ struct GitInfo
std::regex revRegex("^[0-9a-fA-F]{40}$");
GitInfo exportGit(ref<Store> store, const std::string & uri,
std::experimental::optional<std::string> ref, std::string rev,
std::optional<std::string> ref, std::string rev,
const std::string & name)
{
if (evalSettings.pureEval && rev == "")
@@ -190,7 +190,7 @@ GitInfo exportGit(ref<Store> store, const std::string & uri,
static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
std::string url;
std::experimental::optional<std::string> ref;
std::optional<std::string> ref;
std::string rev;
std::string name = "source";
PathSet context;

View File

@@ -75,6 +75,13 @@ public:
}
size_t totalSize() const;
template<typename T>
void dump(T callback)
{
for (auto & s : symbols)
callback(s);
}
};
}

View File

@@ -6,4 +6,4 @@ Name: Nix
Description: Nix Package Manager
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lnixmain
Cflags: -I${includedir}/nix -std=c++14
Cflags: -I${includedir}/nix -std=c++17

View File

@@ -72,24 +72,11 @@ public:
bool isValidPathUncached(const Path & path) override;
PathSet queryAllValidPaths() override
{ unsupported(); }
void queryPathInfoUncached(const Path & path,
Callback<std::shared_ptr<ValidPathInfo>> callback) override;
void queryReferrers(const Path & path,
PathSet & referrers) override
{ unsupported(); }
PathSet queryDerivationOutputs(const Path & path) override
{ unsupported(); }
StringSet queryDerivationOutputNames(const Path & path) override
{ unsupported(); }
Path queryPathFromHashPart(const string & hashPart) override
{ unsupported(); }
{ unsupported("queryPathFromHashPart"); }
bool wantMassQuery() override { return wantMassQuery_; }
@@ -108,22 +95,10 @@ public:
BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv,
BuildMode buildMode) override
{ unsupported(); }
{ unsupported("buildDerivation"); }
void ensurePath(const Path & path) override
{ unsupported(); }
void addTempRoot(const Path & path) override
{ unsupported(); }
void addIndirectRoot(const Path & path) override
{ unsupported(); }
Roots findRoots() override
{ unsupported(); }
void collectGarbage(const GCOptions & options, GCResults & results) override
{ unsupported(); }
{ unsupported("ensurePath"); }
ref<FSAccessor> getFSAccessor() override;

View File

@@ -12,6 +12,7 @@
#include "json.hh"
#include "nar-info.hh"
#include "parsed-derivations.hh"
#include "machines.hh"
#include <algorithm>
#include <iostream>
@@ -2193,7 +2194,6 @@ void DerivationGoal::startBuilder()
userNamespaceSync.create();
options.allowVfork = false;
options.restoreMountNamespace = false;
Pid helper = startProcess([&]() {
@@ -2260,7 +2260,6 @@ void DerivationGoal::startBuilder()
#endif
{
options.allowVfork = !buildUser && !drv->isBuiltin();
options.restoreMountNamespace = false;
pid = startProcess([&]() {
runChild();
}, options);
@@ -2415,7 +2414,7 @@ void DerivationGoal::writeStructuredAttrs()
objects consisting entirely of those values. (So nested
arrays or objects are not supported.) */
auto handleSimpleType = [](const nlohmann::json & value) -> std::experimental::optional<std::string> {
auto handleSimpleType = [](const nlohmann::json & value) -> std::optional<std::string> {
if (value.is_string())
return shellEscape(value);
@@ -3313,8 +3312,8 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
struct Checks
{
bool ignoreSelfRefs = false;
std::experimental::optional<uint64_t> maxSize, maxClosureSize;
std::experimental::optional<Strings> allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites;
std::optional<uint64_t> maxSize, maxClosureSize;
std::optional<Strings> allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites;
};
/* Compute the closure and closure size of some output. This
@@ -3361,7 +3360,7 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
info.path, closureSize, *checks.maxClosureSize);
}
auto checkRefs = [&](const std::experimental::optional<Strings> & value, bool allowed, bool recursive)
auto checkRefs = [&](const std::optional<Strings> & value, bool allowed, bool recursive)
{
if (!value) return;
@@ -3415,7 +3414,7 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
if (maxClosureSize != output->end())
checks.maxClosureSize = maxClosureSize->get<uint64_t>();
auto get = [&](const std::string & name) -> std::experimental::optional<Strings> {
auto get = [&](const std::string & name) -> std::optional<Strings> {
auto i = output->find(name);
if (i != output->end()) {
Strings res;
@@ -4413,6 +4412,11 @@ static void primeCache(Store & store, const PathSet & paths)
PathSet willBuild, willSubstitute, unknown;
unsigned long long downloadSize, narSize;
store.queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
if (!willBuild.empty() && 0 == settings.maxBuildJobs && getMachines().empty())
throw Error(
"%d derivations need to be built, but neither local builds ('--max-jobs') "
"nor remote builds ('--builders') are enabled", willBuild.size());
}

View File

@@ -614,6 +614,22 @@ struct CurlDownloader : public Downloader
writeFull(wakeupPipe.writeSide.get(), " ");
}
#ifdef ENABLE_S3
std::tuple<std::string, std::string, Store::Params> parseS3Uri(std::string uri)
{
auto [path, params] = splitUriAndParams(uri);
auto slash = path.find('/', 5); // 5 is the length of "s3://" prefix
if (slash == std::string::npos)
throw nix::Error("bad S3 URI '%s'", path);
std::string bucketName(path, 5, slash - 5);
std::string key(path, slash + 1);
return {bucketName, key, params};
}
#endif
void enqueueDownload(const DownloadRequest & request,
Callback<DownloadResult> callback) override
{
@@ -622,12 +638,15 @@ struct CurlDownloader : public Downloader
// FIXME: do this on a worker thread
try {
#ifdef ENABLE_S3
S3Helper s3Helper("", Aws::Region::US_EAST_1, "", ""); // FIXME: make configurable
auto slash = request.uri.find('/', 5);
if (slash == std::string::npos)
throw nix::Error("bad S3 URI '%s'", request.uri);
std::string bucketName(request.uri, 5, slash - 5);
std::string key(request.uri, slash + 1);
auto [bucketName, key, params] = parseS3Uri(request.uri);
std::string profile = get(params, "profile", "");
std::string region = get(params, "region", Aws::Region::US_EAST_1);
std::string scheme = get(params, "scheme", "");
std::string endpoint = get(params, "endpoint", "");
S3Helper s3Helper(profile, region, scheme, endpoint);
// FIXME: implement ETag
auto s3Res = s3Helper.getObject(bucketName, key);
DownloadResult res;

View File

@@ -129,8 +129,8 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
check if the root is in a directory in or linked from the
gcroots directory. */
if (settings.checkRootReachability) {
Roots roots = findRoots();
if (roots.find(gcRoot) == roots.end())
Roots roots = findRoots(false);
if (roots[storePath].count(gcRoot) == 0)
printError(
format(
"warning: '%1%' is not in a directory where the garbage collector looks for roots; "
@@ -197,10 +197,11 @@ void LocalStore::addTempRoot(const Path & path)
}
std::set<std::pair<pid_t, Path>> LocalStore::readTempRoots(FDs & fds)
{
std::set<std::pair<pid_t, Path>> tempRoots;
static std::string censored = "{censored}";
void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor)
{
/* Read the `temproots' directory for per-process temporary root
files. */
for (auto & i : readDirectory(tempRootsDir)) {
@@ -250,14 +251,12 @@ std::set<std::pair<pid_t, Path>> LocalStore::readTempRoots(FDs & fds)
Path root(contents, pos, end - pos);
debug("got temporary root '%s'", root);
assertStorePath(root);
tempRoots.emplace(pid, root);
tempRoots[root].emplace(censor ? censored : fmt("{temp:%d}", pid));
pos = end + 1;
}
fds.push_back(fd); /* keep open */
}
return tempRoots;
}
@@ -266,7 +265,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
auto foundRoot = [&](const Path & path, const Path & target) {
Path storePath = toStorePath(target);
if (isStorePath(storePath) && isValidPath(storePath))
roots[path] = storePath;
roots[storePath].emplace(path);
else
printInfo(format("skipping invalid root from '%1%' to '%2%'") % path % storePath);
};
@@ -306,7 +305,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
else if (type == DT_REG) {
Path storePath = storeDir + "/" + baseNameOf(path);
if (isStorePath(storePath) && isValidPath(storePath))
roots[path] = storePath;
roots[storePath].emplace(path);
}
}
@@ -321,10 +320,8 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
}
Roots LocalStore::findRootsNoTemp()
void LocalStore::findRootsNoTemp(Roots & roots, bool censor)
{
Roots roots;
/* Process direct roots in {gcroots,profiles}. */
findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots);
findRoots(stateDir + "/profiles", DT_UNKNOWN, roots);
@@ -333,32 +330,22 @@ Roots LocalStore::findRootsNoTemp()
NIX_ROOT_FINDER environment variable. This is typically used
to add running programs to the set of roots (to prevent them
from being garbage collected). */
size_t n = 0;
for (auto & root : findRuntimeRoots())
roots[fmt("{memory:%d}", n++)] = root;
return roots;
findRuntimeRoots(roots, censor);
}
Roots LocalStore::findRoots()
Roots LocalStore::findRoots(bool censor)
{
Roots roots = findRootsNoTemp();
Roots roots;
findRootsNoTemp(roots, censor);
FDs fds;
pid_t prev = -1;
size_t n = 0;
for (auto & root : readTempRoots(fds)) {
if (prev != root.first) n = 0;
prev = root.first;
roots[fmt("{temp:%d:%d}", root.first, n++)] = root.second;
}
findTempRoots(fds, roots, censor);
return roots;
}
static void readProcLink(const string & file, StringSet & paths)
static void readProcLink(const string & file, Roots & roots)
{
/* 64 is the starting buffer size gnu readlink uses... */
auto bufsiz = ssize_t{64};
@@ -377,8 +364,8 @@ try_again:
goto try_again;
}
if (res > 0 && buf[0] == '/')
paths.emplace(static_cast<char *>(buf), res);
return;
roots[std::string(static_cast<char *>(buf), res)]
.emplace(file);
}
static string quoteRegexChars(const string & raw)
@@ -387,20 +374,20 @@ static string quoteRegexChars(const string & raw)
return std::regex_replace(raw, specialRegex, R"(\$&)");
}
static void readFileRoots(const char * path, StringSet & paths)
static void readFileRoots(const char * path, Roots & roots)
{
try {
paths.emplace(readFile(path));
roots[readFile(path)].emplace(path);
} catch (SysError & e) {
if (e.errNo != ENOENT && e.errNo != EACCES)
throw;
}
}
PathSet LocalStore::findRuntimeRoots()
void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
{
PathSet roots;
StringSet paths;
Roots unchecked;
auto procDir = AutoCloseDir{opendir("/proc")};
if (procDir) {
struct dirent * ent;
@@ -410,10 +397,10 @@ PathSet LocalStore::findRuntimeRoots()
while (errno = 0, ent = readdir(procDir.get())) {
checkInterrupt();
if (std::regex_match(ent->d_name, digitsRegex)) {
readProcLink((format("/proc/%1%/exe") % ent->d_name).str(), paths);
readProcLink((format("/proc/%1%/cwd") % ent->d_name).str(), paths);
readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
auto fdStr = (format("/proc/%1%/fd") % ent->d_name).str();
auto fdStr = fmt("/proc/%s/fd", ent->d_name);
auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
if (!fdDir) {
if (errno == ENOENT || errno == EACCES)
@@ -422,9 +409,8 @@ PathSet LocalStore::findRuntimeRoots()
}
struct dirent * fd_ent;
while (errno = 0, fd_ent = readdir(fdDir.get())) {
if (fd_ent->d_name[0] != '.') {
readProcLink((format("%1%/%2%") % fdStr % fd_ent->d_name).str(), paths);
}
if (fd_ent->d_name[0] != '.')
readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
}
if (errno) {
if (errno == ESRCH)
@@ -434,18 +420,19 @@ PathSet LocalStore::findRuntimeRoots()
fdDir.reset();
try {
auto mapLines =
tokenizeString<std::vector<string>>(readFile((format("/proc/%1%/maps") % ent->d_name).str(), true), "\n");
for (const auto& line : mapLines) {
auto mapFile = fmt("/proc/%s/maps", ent->d_name);
auto mapLines = tokenizeString<std::vector<string>>(readFile(mapFile, true), "\n");
for (const auto & line : mapLines) {
auto match = std::smatch{};
if (std::regex_match(line, match, mapRegex))
paths.emplace(match[1]);
unchecked[match[1]].emplace(mapFile);
}
auto envString = readFile((format("/proc/%1%/environ") % ent->d_name).str(), true);
auto envFile = fmt("/proc/%s/environ", ent->d_name);
auto envString = readFile(envFile, true);
auto env_end = std::sregex_iterator{};
for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i)
paths.emplace(i->str());
unchecked[i->str()].emplace(envFile);
} catch (SysError & e) {
if (errno == ENOENT || errno == EACCES || errno == ESRCH)
continue;
@@ -465,7 +452,7 @@ PathSet LocalStore::findRuntimeRoots()
for (const auto & line : lsofLines) {
std::smatch match;
if (std::regex_match(line, match, lsofRegex))
paths.emplace(match[1]);
unchecked[match[1]].emplace("{lsof}");
}
} catch (ExecError & e) {
/* lsof not installed, lsof failed */
@@ -473,21 +460,23 @@ PathSet LocalStore::findRuntimeRoots()
#endif
#if defined(__linux__)
readFileRoots("/proc/sys/kernel/modprobe", paths);
readFileRoots("/proc/sys/kernel/fbsplash", paths);
readFileRoots("/proc/sys/kernel/poweroff_cmd", paths);
readFileRoots("/proc/sys/kernel/modprobe", unchecked);
readFileRoots("/proc/sys/kernel/fbsplash", unchecked);
readFileRoots("/proc/sys/kernel/poweroff_cmd", unchecked);
#endif
for (auto & i : paths)
if (isInStore(i)) {
Path path = toStorePath(i);
if (roots.find(path) == roots.end() && isStorePath(path) && isValidPath(path)) {
for (auto & [target, links] : unchecked) {
if (isInStore(target)) {
Path path = toStorePath(target);
if (isStorePath(path) && isValidPath(path)) {
debug(format("got additional root '%1%'") % path);
roots.insert(path);
if (censor)
roots[path].insert(censored);
else
roots[path].insert(links.begin(), links.end());
}
}
return roots;
}
}
@@ -754,16 +743,20 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* Find the roots. Since we've grabbed the GC lock, the set of
permanent roots cannot increase now. */
printError(format("finding garbage collector roots..."));
Roots rootMap = options.ignoreLiveness ? Roots() : findRootsNoTemp();
Roots rootMap;
if (!options.ignoreLiveness)
findRootsNoTemp(rootMap, true);
for (auto & i : rootMap) state.roots.insert(i.second);
for (auto & i : rootMap) state.roots.insert(i.first);
/* Read the temporary roots. This acquires read locks on all
per-process temporary root files. So after this point no paths
can be added to the set of temporary roots. */
FDs fds;
for (auto & root : readTempRoots(fds))
state.tempRoots.insert(root.second);
Roots tempRoots;
findTempRoots(fds, tempRoots, true);
for (auto & root : tempRoots)
state.tempRoots.insert(root.first);
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
/* After this point the set of roots or temporary roots cannot

View File

@@ -187,28 +187,17 @@ struct LegacySSHStore : public Store
copyNAR(conn->from, sink);
}
PathSet queryAllValidPaths() override { unsupported(); }
void queryReferrers(const Path & path, PathSet & referrers) override
{ unsupported(); }
PathSet queryDerivationOutputs(const Path & path) override
{ unsupported(); }
StringSet queryDerivationOutputNames(const Path & path) override
{ unsupported(); }
Path queryPathFromHashPart(const string & hashPart) override
{ unsupported(); }
{ unsupported("queryPathFromHashPart"); }
Path addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo,
PathFilter & filter, RepairFlag repair) override
{ unsupported(); }
{ unsupported("addToStore"); }
Path addTextToStore(const string & name, const string & s,
const PathSet & references, RepairFlag repair) override
{ unsupported(); }
{ unsupported("addTextToStore"); }
BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv,
BuildMode buildMode) override
@@ -242,25 +231,7 @@ struct LegacySSHStore : public Store
}
void ensurePath(const Path & path) override
{ unsupported(); }
void addTempRoot(const Path & path) override
{ unsupported(); }
void addIndirectRoot(const Path & path) override
{ unsupported(); }
Roots findRoots() override
{ unsupported(); }
void collectGarbage(const GCOptions & options, GCResults & results) override
{ unsupported(); }
ref<FSAccessor> getFSAccessor() override
{ unsupported(); }
void addSignatures(const Path & storePath, const StringSet & sigs) override
{ unsupported(); }
{ unsupported("ensurePath"); }
void computeFSClosure(const PathSet & paths,
PathSet & out, bool flipDirection = false,

View File

@@ -366,8 +366,6 @@ void LocalStore::makeStoreWritable()
throw SysError("getting info about the Nix store mount point");
if (stat.f_flag & ST_RDONLY) {
saveMountNamespace();
if (unshare(CLONE_NEWNS) == -1)
throw SysError("setting up a private mount namespace");

View File

@@ -180,11 +180,11 @@ private:
typedef std::shared_ptr<AutoCloseFD> FDPtr;
typedef list<FDPtr> FDs;
std::set<std::pair<pid_t, Path>> readTempRoots(FDs & fds);
void findTempRoots(FDs & fds, Roots & roots, bool censor);
public:
Roots findRoots() override;
Roots findRoots(bool censor) override;
void collectGarbage(const GCOptions & options, GCResults & results) override;
@@ -267,9 +267,9 @@ private:
void findRoots(const Path & path, unsigned char type, Roots & roots);
Roots findRootsNoTemp();
void findRootsNoTemp(Roots & roots, bool censor);
PathSet findRuntimeRoots();
void findRuntimeRoots(Roots & roots, bool censor);
void removeUnusedLinks(const GCState & state);

View File

@@ -89,10 +89,11 @@ void parseMachines(const std::string & s, Machines & machines)
Machines getMachines()
{
Machines machines;
parseMachines(settings.builders, machines);
static auto machines = [&]() {
Machines machines;
parseMachines(settings.builders, machines);
return machines;
}();
return machines;
}

View File

@@ -6,4 +6,4 @@ Name: Nix
Description: Nix Package Manager
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lnixstore -lnixutil
Cflags: -I${includedir}/nix -std=c++14
Cflags: -I${includedir}/nix -std=c++17

View File

@@ -16,7 +16,7 @@ ParsedDerivation::ParsedDerivation(const Path & drvPath, BasicDerivation & drv)
}
}
std::experimental::optional<std::string> ParsedDerivation::getStringAttr(const std::string & name) const
std::optional<std::string> ParsedDerivation::getStringAttr(const std::string & name) const
{
if (structuredAttrs) {
auto i = structuredAttrs->find(name);
@@ -56,7 +56,7 @@ bool ParsedDerivation::getBoolAttr(const std::string & name, bool def) const
}
}
std::experimental::optional<Strings> ParsedDerivation::getStringsAttr(const std::string & name) const
std::optional<Strings> ParsedDerivation::getStringsAttr(const std::string & name) const
{
if (structuredAttrs) {
auto i = structuredAttrs->find(name);

View File

@@ -8,22 +8,22 @@ class ParsedDerivation
{
Path drvPath;
BasicDerivation & drv;
std::experimental::optional<nlohmann::json> structuredAttrs;
std::optional<nlohmann::json> structuredAttrs;
public:
ParsedDerivation(const Path & drvPath, BasicDerivation & drv);
const std::experimental::optional<nlohmann::json> & getStructuredAttrs() const
const std::optional<nlohmann::json> & getStructuredAttrs() const
{
return structuredAttrs;
}
std::experimental::optional<std::string> getStringAttr(const std::string & name) const;
std::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;
std::optional<Strings> getStringsAttr(const std::string & name) const;
StringSet getRequiredSystemFeatures() const;

View File

@@ -596,7 +596,7 @@ void RemoteStore::syncWithGC()
}
Roots RemoteStore::findRoots()
Roots RemoteStore::findRoots(bool censor)
{
auto conn(getConnection());
conn->to << wopFindRoots;
@@ -606,7 +606,7 @@ Roots RemoteStore::findRoots()
while (count--) {
Path link = readString(conn->from);
Path target = readStorePath(*this, conn->from);
result[link] = target;
result[target].emplace(link);
}
return result;
}

View File

@@ -82,7 +82,7 @@ public:
void syncWithGC() override;
Roots findRoots() override;
Roots findRoots(bool censor) override;
void collectGarbage(const GCOptions & options, GCResults & results) override;
@@ -149,7 +149,7 @@ public:
private:
ref<RemoteStore::Connection> openConnection() override;
std::experimental::optional<std::string> path;
std::optional<std::string> path;
};

View File

@@ -126,6 +126,7 @@ ref<Aws::Client::ClientConfiguration> S3Helper::makeConfig(const string & region
res->endpointOverride = endpoint;
}
res->requestTimeoutMs = 600 * 1000;
res->connectTimeoutMs = 5 * 1000;
res->retryStrategy = std::make_shared<RetryStrategy>();
res->caFile = settings.caFile;
return res;

View File

@@ -1,5 +1,4 @@
#include "ssh.hh"
#include "affinity.hh"
namespace nix {
@@ -35,9 +34,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
auto conn = std::make_unique<Connection>();
conn->sshPid = startProcess([&]() {
restoreAffinity();
restoreSignals();
restoreMountNamespace();
close(in.writeSide.get());
close(out.readSide.get());

View File

@@ -562,10 +562,10 @@ void Store::buildPaths(const PathSet & paths, BuildMode buildMode)
{
for (auto & path : paths)
if (isDerivation(path))
unsupported();
unsupported("buildPaths");
if (queryValidPaths(paths).size() != paths.size())
unsupported();
unsupported("buildPaths");
}
@@ -842,12 +842,11 @@ namespace nix {
RegisterStoreImplementation::Implementations * RegisterStoreImplementation::implementations = 0;
ref<Store> openStore(const std::string & uri_,
const Store::Params & extraParams)
/* Split URI into protocol+hierarchy part and its parameter set. */
std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri_)
{
auto uri(uri_);
Store::Params params(extraParams);
Store::Params params;
auto q = uri.find('?');
if (q != std::string::npos) {
for (auto s : tokenizeString<Strings>(uri.substr(q + 1), "&")) {
@@ -873,6 +872,15 @@ ref<Store> openStore(const std::string & uri_,
}
uri = uri_.substr(0, q);
}
return {uri, params};
}
ref<Store> openStore(const std::string & uri_,
const Store::Params & extraParams)
{
auto [uri, uriParams] = splitUriAndParams(uri_);
auto params = extraParams;
params.insert(uriParams.begin(), uriParams.end());
for (auto fun : *RegisterStoreImplementation::implementations) {
auto store = fun(uri, params);

View File

@@ -11,6 +11,8 @@
#include <atomic>
#include <limits>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include <string>
@@ -47,7 +49,7 @@ const size_t storePathHashLen = 32; // i.e. 160 bits
const uint32_t exportMagic = 0x4558494e;
typedef std::map<Path, Path> Roots;
typedef std::unordered_map<Path, std::unordered_set<std::string>> Roots;
struct GCOptions
@@ -349,7 +351,8 @@ public:
(i.e. you'll get /nix/store/<hash> rather than
/nix/store/<hash>-<name>). Use queryPathInfo() to obtain the
full store path. */
virtual PathSet queryAllValidPaths() = 0;
virtual PathSet queryAllValidPaths()
{ unsupported("queryAllValidPaths"); }
/* Query information about a valid path. It is permitted to omit
the name part of the store path. */
@@ -368,8 +371,8 @@ public:
/* Queries the set of incoming FS references for a store path.
The result is not cleared. */
virtual void queryReferrers(const Path & path,
PathSet & referrers) = 0;
virtual void queryReferrers(const Path & path, PathSet & referrers)
{ unsupported("queryReferrers"); }
/* Return all currently valid derivations that have `path' as an
output. (Note that the result of `queryDeriver()' is the
@@ -378,10 +381,12 @@ public:
virtual PathSet queryValidDerivers(const Path & path) { return {}; };
/* Query the outputs of the derivation denoted by `path'. */
virtual PathSet queryDerivationOutputs(const Path & path) = 0;
virtual PathSet queryDerivationOutputs(const Path & path)
{ unsupported("queryDerivationOutputs"); }
/* Query the output names of the derivation denoted by `path'. */
virtual StringSet queryDerivationOutputNames(const Path & path) = 0;
virtual StringSet queryDerivationOutputNames(const Path & path)
{ unsupported("queryDerivationOutputNames"); }
/* Query the full store path given the hash part of a valid store
path, or "" if the path doesn't exist. */
@@ -447,14 +452,16 @@ public:
/* Add a store path as a temporary root of the garbage collector.
The root disappears as soon as we exit. */
virtual void addTempRoot(const Path & path) = 0;
virtual void addTempRoot(const Path & path)
{ unsupported("addTempRoot"); }
/* Add an indirect root, which is merely a symlink to `path' from
/nix/var/nix/gcroots/auto/<hash of `path'>. `path' is supposed
to be a symlink to a store path. The garbage collector will
automatically remove the indirect root when it finds that
`path' has disappeared. */
virtual void addIndirectRoot(const Path & path) = 0;
virtual void addIndirectRoot(const Path & path)
{ unsupported("addIndirectRoot"); }
/* Acquire the global GC lock, then immediately release it. This
function must be called after registering a new permanent root,
@@ -478,11 +485,15 @@ public:
/* Find the roots of the garbage collector. Each root is a pair
(link, storepath) where `link' is the path of the symlink
outside of the Nix store that point to `storePath'. */
virtual Roots findRoots() = 0;
outside of the Nix store that point to `storePath'. If
'censor' is true, privacy-sensitive information about roots
found in /proc is censored. */
virtual Roots findRoots(bool censor)
{ unsupported("findRoots"); }
/* Perform a garbage collection. */
virtual void collectGarbage(const GCOptions & options, GCResults & results) = 0;
virtual void collectGarbage(const GCOptions & options, GCResults & results)
{ unsupported("collectGarbage"); }
/* Return a string representing information about the path that
can be loaded into the database using `nix-store --load-db' or
@@ -513,11 +524,13 @@ public:
virtual bool verifyStore(bool checkContents, RepairFlag repair = NoRepair) { return false; };
/* Return an object to access files in the Nix store. */
virtual ref<FSAccessor> getFSAccessor() = 0;
virtual ref<FSAccessor> getFSAccessor()
{ unsupported("getFSAccessor"); }
/* Add signatures to the specified store path. The signatures are
not verified. */
virtual void addSignatures(const Path & storePath, const StringSet & sigs) = 0;
virtual void addSignatures(const Path & storePath, const StringSet & sigs)
{ unsupported("addSignatures"); }
/* Utility functions. */
@@ -620,9 +633,9 @@ protected:
Stats stats;
/* Unsupported methods. */
[[noreturn]] void unsupported()
[[noreturn]] void unsupported(const std::string & op)
{
throw Unsupported("requested operation is not supported by store '%s'", getUri());
throw Unsupported("operation '%s' is not supported by store '%s'", op, getUri());
}
};
@@ -789,4 +802,8 @@ ValidPathInfo decodeValidPathInfo(std::istream & str,
for paths created by makeFixedOutputPath() / addToStore(). */
std::string makeFixedOutputCA(bool recursive, const Hash & hash);
/* Split URI into protocol+hierarchy part and its parameter set. */
std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri);
}

View File

@@ -331,7 +331,7 @@ struct RestoreSink : ParseSink
filesystem doesn't support preallocation (e.g. on
OpenSolaris). Since preallocation is just an
optimisation, ignore it. */
if (errno && errno != EINVAL)
if (errno && errno != EINVAL && errno != EOPNOTSUPP && errno != ENOSYS)
throw SysError(format("preallocating file of %1% bytes") % len);
}
#endif

View File

@@ -2,7 +2,7 @@
#include <map>
#include <list>
#include <experimental/optional>
#include <optional>
namespace nix {
@@ -64,7 +64,7 @@ public:
/* Look up an item in the cache. If it exists, it becomes the most
recently used item. */
std::experimental::optional<Value> get(const Key & key)
std::optional<Value> get(const Key & key)
{
auto i = data.find(key);
if (i == data.end()) return {};

View File

@@ -171,7 +171,7 @@ std::unique_ptr<Source> sinkToSource(
std::function<void(Sink &)> fun;
std::function<void()> eof;
std::experimental::optional<coro_t::pull_type> coro;
std::optional<coro_t::pull_type> coro;
bool started = false;
SinkToSource(std::function<void(Sink &)> fun, std::function<void()> eof)

View File

@@ -936,8 +936,6 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options)
throw SysError("setting death signal");
#endif
restoreAffinity();
if (options.restoreMountNamespace)
restoreMountNamespace();
fun();
} catch (std::exception & e) {
try {
@@ -967,7 +965,7 @@ std::vector<char *> stringsToCharPtrs(const Strings & ss)
string runProgram(Path program, bool searchPath, const Strings & args,
const std::experimental::optional<std::string> & input)
const std::optional<std::string> & input)
{
RunOptions opts(program, args);
opts.searchPath = searchPath;
@@ -1506,26 +1504,4 @@ std::unique_ptr<InterruptCallback> createInterruptCallback(std::function<void()>
return std::unique_ptr<InterruptCallback>(res.release());
}
static AutoCloseFD fdSavedMountNamespace;
void saveMountNamespace()
{
#if __linux__
std::once_flag done;
std::call_once(done, []() {
fdSavedMountNamespace = open("/proc/self/ns/mnt", O_RDONLY);
if (!fdSavedMountNamespace)
throw SysError("saving parent mount namespace");
});
#endif
}
void restoreMountNamespace()
{
#if __linux__
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
throw SysError("restoring parent mount namespace");
#endif
}
}

View File

@@ -14,7 +14,7 @@
#include <cstdio>
#include <map>
#include <sstream>
#include <experimental/optional>
#include <optional>
#include <future>
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
@@ -250,7 +250,6 @@ struct ProcessOptions
bool dieWithParent = true;
bool runExitHandlers = false;
bool allowVfork = true;
bool restoreMountNamespace = true;
};
pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = ProcessOptions());
@@ -260,14 +259,14 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = P
shell backtick operator). */
string runProgram(Path program, bool searchPath = false,
const Strings & args = Strings(),
const std::experimental::optional<std::string> & input = {});
const std::optional<std::string> & input = {});
struct RunOptions
{
Path program;
bool searchPath = true;
Strings args;
std::experimental::optional<std::string> input;
std::optional<std::string> input;
Source * standardIn = nullptr;
Sink * standardOut = nullptr;
bool _killStderr = false;
@@ -515,13 +514,4 @@ typedef std::function<bool(const Path & path)> PathFilter;
extern PathFilter defaultPathFilter;
/* Save the current mount namespace. Ignored if called more than
once. */
void saveMountNamespace();
/* Restore the mount namespace saved by saveMountNamespace(). Ignored
if saveMountNamespace() was never called. */
void restoreMountNamespace();
}

View File

@@ -401,6 +401,8 @@ static void _main(int argc, char * * argv)
} else
env[var.first] = var.second;
restoreAffinity();
/* Run a shell using the derivation's environment. For
convenience, source $stdenv/setup to setup additional
environment variables and shell functions. Also don't
@@ -444,9 +446,7 @@ static void _main(int argc, char * * argv)
auto argPtrs = stringsToCharPtrs(args);
restoreAffinity();
restoreSignals();
restoreMountNamespace();
execvp(shell.c_str(), argPtrs.data());

View File

@@ -475,11 +475,19 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
case wopFindRoots: {
logger->startWork();
Roots roots = store->findRoots();
Roots roots = store->findRoots(!trusted);
logger->stopWork();
to << roots.size();
size_t size = 0;
for (auto & i : roots)
to << i.first << i.second;
size += i.second.size();
to << size;
for (auto & [target, links] : roots)
for (auto & link : links)
to << link << target;
break;
}

View File

@@ -427,10 +427,11 @@ static void opQuery(Strings opFlags, Strings opArgs)
maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise),
referrers, true, settings.gcKeepOutputs, settings.gcKeepDerivations);
}
Roots roots = store->findRoots();
for (auto & i : roots)
if (referrers.find(i.second) != referrers.end())
cout << format("%1%\n") % i.first;
Roots roots = store->findRoots(false);
for (auto & [target, links] : roots)
if (referrers.find(target) != referrers.end())
for (auto & link : links)
cout << format("%1% -> %2%\n") % link % target;
break;
}
@@ -485,11 +486,16 @@ static void opReadLog(Strings opFlags, Strings opArgs)
static void opDumpDB(Strings opFlags, Strings opArgs)
{
if (!opFlags.empty()) throw UsageError("unknown flag");
if (!opArgs.empty())
throw UsageError("no arguments expected");
PathSet validPaths = store->queryAllValidPaths();
for (auto & i : validPaths)
cout << store->makeValidityRegistration({i}, true, true);
if (!opArgs.empty()) {
for (auto & i : opArgs)
i = store->followLinksToStorePath(i);
for (auto & i : opArgs)
cout << store->makeValidityRegistration({i}, true, true);
} else {
PathSet validPaths = store->queryAllValidPaths();
for (auto & i : validPaths)
cout << store->makeValidityRegistration({i}, true, true);
}
}
@@ -585,9 +591,14 @@ static void opGC(Strings opFlags, Strings opArgs)
if (!opArgs.empty()) throw UsageError("no arguments expected");
if (printRoots) {
Roots roots = store->findRoots();
for (auto & i : roots)
cout << i.first << " -> " << i.second << std::endl;
Roots roots = store->findRoots(false);
std::set<std::pair<Path, Path>> roots2;
// Transpose and sort the roots.
for (auto & [target, links] : roots)
for (auto & link : links)
roots2.emplace(link, target);
for (auto & [link, target] : roots2)
std::cout << link << " -> " << target << "\n";
}
else {

View File

@@ -8,7 +8,7 @@ using namespace nix;
struct CmdAddToStore : MixDryRun, StoreCommand
{
Path path;
std::experimental::optional<std::string> namePart;
std::optional<std::string> namePart;
CmdAddToStore()
{

View File

@@ -3,7 +3,6 @@
#include "eval.hh"
#include "attr-path.hh"
#include "progress-bar.hh"
#include "affinity.hh"
#include <unistd.h>
@@ -73,10 +72,6 @@ struct CmdEdit : InstallableCommand
stopProgressBar();
restoreAffinity();
restoreSignals();
restoreMountNamespace();
execvp(args.front().c_str(), stringsToCharPtrs(args).data());
throw SysError("cannot run editor '%s'", editor);

View File

@@ -337,8 +337,6 @@ static int runProgram(const string & program, const Strings & args)
if (pid == -1) throw SysError("forking");
if (pid == 0) {
restoreAffinity();
restoreSignals();
restoreMountNamespace();
execvp(program.c_str(), stringsToCharPtrs(args2).data());
_exit(1);
}

View File

@@ -153,9 +153,9 @@ struct CmdRun : InstallablesCommand
stopProgressBar();
restoreAffinity();
restoreSignals();
restoreMountNamespace();
restoreAffinity();
/* If this is a diverted store (i.e. its "logical" location
(typically /nix/store) differs from its "physical" location

View File

@@ -7,7 +7,7 @@ outPath=$(nix-store -rvv "$drvPath")
rm -f "$NIX_STATE_DIR"/gcroots/foo
ln -sf $outPath "$NIX_STATE_DIR"/gcroots/foo
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR"/gcroots/foo ]
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
nix-store --gc --print-roots | grep $outPath
nix-store --gc --print-live | grep $outPath

View File

@@ -0,0 +1 @@
true

View File

@@ -0,0 +1,24 @@
let
drv = derivation {
name = "fail";
builder = "/bin/false";
system = "x86_64-linux";
outputs = [ "out" "foo" ];
};
path = "${./eval-okay-context-introspection.nix}";
desired-context = {
"${builtins.unsafeDiscardStringContext path}" = {
path = true;
};
"${builtins.unsafeDiscardStringContext drv.drvPath}" = {
outputs = [ "foo" "out" ];
allOutputs = true;
};
};
legit-context = builtins.getContext "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}";
constructed-context = builtins.getContext (builtins.appendContext "" desired-context);
in legit-context == constructed-context

View File

@@ -1 +1 @@
[ true false true false true false true false true true true true true true true true true true true false true false "int" "bool" "string" "null" "set" "list" "lambda" "lambda" "lambda" "lambda" ]
[ true false true false true false true false true true true true true true true true true true true false true true true false "int" "bool" "string" "null" "set" "list" "lambda" "lambda" "lambda" "lambda" ]

View File

@@ -20,6 +20,8 @@ with builtins;
(isFloat (1 - 2.0))
(isBool (true && false))
(isBool null)
(isPath /nix/store)
(isPath ./.)
(isAttrs { x = 123; })
(isAttrs null)
(typeOf (3 * 4))

View File

@@ -1 +0,0 @@
2.2