Compare commits

...

139 Commits

Author SHA1 Message Date
Eelco Dolstra 33d58a1904
Bump version 2017-12-12 17:48:02 +01:00
Eelco Dolstra c6e15c4322
Disable shellcheck
This breaks eval on aarch64-linux due to the dependency on GHC.
2017-12-12 15:33:53 +01:00
Eelco Dolstra 7487debaf5
Merge pull request #1700 from grahamc/fixup-darwin-hs
darwin installer: fix on High Sierra
2017-12-12 11:51:14 +01:00
Eelco Dolstra a18c085af8
Merge pull request #1716 from grahamc/build-1.11-on-aarch
Build 1.11 on aarch64-linux
2017-12-08 14:00:21 +01:00
Graham Christensen 6b887844d6
replace lolcat with nix-info
(cherry picked from commit 1db034364a)
2017-12-08 07:30:51 -05:00
Graham Christensen c32bdf0548
darwin installer: fix on High Sierra
(cherry picked from commit be79d1f189)
2017-12-08 07:30:44 -05:00
Eelco Dolstra e462fa746b
Build on aarch64-linux
(cherry picked from commit da76c72bc9)
2017-12-07 17:22:28 -05:00
Eelco Dolstra 3454356001
Merge pull request #1648 from danbst/patch-1
nix-collect-garbage: little doc fix
2017-11-03 10:51:16 +01:00
Danylo Hlynskyi c7c806ec21
nix-collect-garbage: little doc fix
This removes confusing documentation. It's better to remove doc than add implementation, because Nix 1.12 will surely have new GC interface anyway.

Fixes https://github.com/NixOS/nix/issues/641
2017-10-31 05:12:08 +02:00
Eelco Dolstra 76431e0a26
nix-shell -p: Use runCommandCC
This restores pre-17.03 behaviour by making gcc available.

(Ported from 9b63bb88c8)
2017-10-13 17:28:04 +02:00
Shea Levy 3c52567b3e
darwin installer: Fix on systems where sudo -i is disabled.
(cherry picked from commit fb98e29067)
2017-10-12 13:08:33 +02:00
Anthony Cowley b03066835c
install-darwin-multi-user: relax assumption check
The installer will error out if a user's shell configuration includes any mention of ~nix-profile~, even if this is in a comment. This change is designed to do the bare minimum to ignore lines beginning with a `#`.

(cherry picked from commit 92f9d18aa0)
2017-10-12 13:06:46 +02:00
Eelco Dolstra aa57c32318
Bump version 2017-09-15 16:40:20 +02:00
Eelco Dolstra f217acd9e7 Merge pull request #1566 from FPtje/1.11-maintenance
scripts/nix-copy-closure.in: Automatically flush STDERR handle
2017-09-10 17:51:31 +02:00
Falco Peijnenburg b3ad7c5052 scripts/nix-copy-closure.in: Automatically flush STDERR handle
Fixes https://github.com/NixOS/nixops/issues/455
2017-09-10 17:38:18 +02:00
Eelco Dolstra e8235c4f3e
Bump version 2017-09-01 11:13:16 +02:00
Sergei Trofimovich 41352d50db
src/libmain/stack.cc: fix 'ucontext' usage on glibc-2.26
Build fails as:

$ make
  CXX    src/libmain/stack.o
src/libmain/stack.cc: In function 'void nix::sigsegvHandler(int, siginfo_t*, void*)':
src/libmain/stack.cc:21:21: error: 'ucontext' was not declared in this scope
     sp = (char *) ((ucontext *) ctx)->uc_mcontext.gregs[REG_RSP];
                     ^~~~~~~~
src/libmain/stack.cc:21:21: note: suggested alternative: 'ucontext_t'
     sp = (char *) ((ucontext *) ctx)->uc_mcontext.gregs[REG_RSP];
                     ^~~~~~~~
                     ucontext_t

It's caused by upstream rename:
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=251287734e89a52da3db682a8241eb6bccc050c9

which basically changes
    typedef struct ucontext {} ucontext_t;
to
    typedef struct ucontext_t {} ucontext_t;

The change uses ucontext_t.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
(cherry picked from commit c9857ef262)
2017-09-01 11:12:49 +02:00
Eelco Dolstra b3a616e860
Bump version 2017-08-30 20:03:33 +02:00
Eelco Dolstra 617dab1515 Merge pull request #1543 from matthewbauer/1.11-maintenance
OS X sandbox: Store .sb file in $TMPDIR rather than the Nix store
2017-08-30 19:50:40 +02:00
Eelco Dolstra 35f541a7a0 OS X sandbox: Store .sb file in $TMPDIR rather than the Nix store
The filename used was not unique and owned by the build user, so
builds could fail with

error: while setting up the build environment: cannot unlink ‘/nix/store/99i210ihnsjacajaw8r33fmgjvzpg6nr-bison-3.0.4.drv.sb’: Permission denied
2017-08-30 12:06:31 -05:00
Eelco Dolstra 23795d47fb Merge pull request #1540 from grahamc/test-o
1.11: Replace stat / uid comparison with test -O
2017-08-30 15:43:47 +02:00
Graham Christensen d07697de5f
Replace stat / uid comparison with test -O 2017-08-29 18:56:32 -04:00
Domen Kožar 3afb744185 Merge pull request #1313 from neilmayhew/topic/cores
Propagate NIX_BUILD_CORES to nix-shell environments
2017-08-02 15:02:25 +02:00
Eelco Dolstra 04532ee2c8
Fix test failure
(cherry picked from commit 46e36f9b73)
Signed-off-by: Domen Kožar <domen@dev.si>
2017-07-25 11:50:31 +02:00
Eelco Dolstra 24883645a6 Merge pull request #1486 from grahamc/detect-already-running
Test to see if nix-daemon is running already
2017-07-25 09:24:06 +02:00
Graham Christensen 9a04bc6f5e
Test to see if nix-daemon is running already
A user had an install, uninstalled it via the instructions, and found their nix broken.

The issue was based around nix-daemon already running.

I tried to be very smart around searching their launchctl files:

  $ grep -ri nix-daemon  ~/Library/LaunchAgents /Library/LaunchAgents /Library/LaunchDaemons /System/Library/LaunchAgents /System/Library/LaunchDaemons

but then couldn't figure out how to write out (nicely) commands for uninstalling
or unloading them based on their name, and also couching the instrunctions in a
bit of doubt so we don't piss off some poor mac admin because their users just
deleted some important launchd files.
2017-07-24 22:37:22 -04:00
Eelco Dolstra 0ec723375b Merge pull request #1469 from grahamc/domen-feedback-nix
Show users how to source the profile, to get a working Nix.
2017-07-17 15:05:17 +02:00
Graham Christensen 4b45f94b5c
Show users how to source the profile, to get a working Nix. 2017-07-17 08:39:14 -04:00
Eelco Dolstra 16daed49dc Merge pull request #1463 from grahamc/fix-stdin-errors
Fix stdin errors
2017-07-14 15:07:57 +02:00
Graham Christensen 41f0a08a31
bump version to 1.11.13 2017-07-14 06:28:47 -04:00
Graham Christensen e4831a4412
Rename PINCH_ME_IM_SILLY to ALLOW_PREEXISTING_INSTALLATION 2017-07-14 06:28:24 -04:00
Graham Christensen 6ba624f25a
If there is no TTY, also skip verbose sudo messages 2017-07-14 06:23:51 -04:00
Graham Christensen 6b6d4b69c1
Ensure PINCH_ME_IM_SILLY allows a /nix/store to stick around between builds
Also output in the status report that the user is very silly
2017-07-13 19:45:00 -04:00
Graham Christensen b01eaa6114
Assume yes if we have no TTY
Starve the TTY of input to ensure this works, but provide yes to the
current installer to handle the current broken case.
2017-07-13 18:03:53 -04:00
Eelco Dolstra 04e071a5e4
Bump version 2017-07-13 15:10:09 +02:00
Domen Kožar 44f51a5dd2
Fix rpm build 2017-07-13 14:11:21 +02:00
Eelco Dolstra e135db704f Merge pull request #1453 from grahamc/multi-user-darwin
Multi user darwin installer
2017-07-13 13:03:28 +02:00
Graham Christensen c82126790d
Cleanup and more specificity around set -e 2017-07-12 20:43:57 -04:00
Graham Christensen 85acfcd6bd
Only clean if the file exists 2017-07-12 20:31:33 -04:00
Graham Christensen b2917c8246
Clean up nix hints from the old insstaller 2017-07-12 20:29:58 -04:00
Graham Christensen a31347d6ec
release: don't build libseccomp if we're on darwin 2017-07-12 19:23:42 -04:00
Graham Christensen c4f349d572
Run nix-build inside a fresh bash login 2017-07-12 17:10:14 -04:00
Graham Christensen 163d93125e
chmod 2017-07-12 12:58:37 -04:00
Graham Christensen 302e820660
Test the installer 2017-07-12 11:45:38 -04:00
Graham Christensen 2442c4684d
Address feedback around printf & exec 2017-07-12 11:45:35 -04:00
Graham Christensen d4f128352e
Don't install a second nix after the initial installation, and the rsync change fixes a bug hidden by the nix replacement where the store files were being owned by the installing user due to rsync's -a implying -og. 2017-07-12 11:45:32 -04:00
Graham Christensen 0c13077d83
nix: build with libsodium on macOS 2017-07-12 11:45:28 -04:00
Graham Christensen 661daed683
Clean up issues around uninstall directions, and only show
relevant directions
2017-07-12 11:45:25 -04:00
Graham Christensen 262a08c0e2
Prompt for sudo before validating assumptions, and check ourselves for root-owned files instead of making a scary warning. 2017-07-12 11:45:22 -04:00
Graham Christensen 3ebd25a644
multi-user install: move the profile in to the nix etc/profiles.d output 2017-07-12 11:45:19 -04:00
Graham Christensen 218978154a
Switch to a fancy multi-user installer on Darwin 2017-07-12 11:45:13 -04:00
Graham Christensen 799f5adf79
Shellcheck the existing installer 2017-07-12 11:44:28 -04:00
Eelco Dolstra 84d10d248e
Fix build 2017-07-12 13:00:41 +02:00
Robert Vollmert 758a3044f1
Fix nix-instantiate manpage indentation
The second command variant is now its own cmdsynopsis, which ensures
it's not indented as was the case using sbrk.

(cherry picked from commit 60da5d2b8f)
2017-07-12 11:31:24 +02:00
Matthew Bauer 5a7d00ced8
Don’t hardlink disallowed paths in OS X.
Fixes #1443

(cherry picked from commit 72e80c59b5)
2017-07-12 11:31:17 +02:00
Eelco Dolstra 9943f98c35
Add X32 to the seccomp filter
Fixes #1432.

(cherry picked from commit a3dc1e65ab)
2017-07-12 11:30:28 +02:00
Eelco Dolstra b59788fc48
fetchTarball: Prevent concurrent downloads of the same file
Fixes #849.

(cherry picked from commit 8e8caf7f3e)
2017-07-12 11:28:59 +02:00
Eelco Dolstra 7577d35895
replaceSymlink(): Handle the case where the temporary file already exists
Not really necessary anymore for #849, but still nice to have.

(cherry picked from commit 2965d40612)
2017-07-12 11:28:05 +02:00
Shea Levy 2a0112a370 Merge branch 'add-nix-profile-daemon' of git://github.com/grahamc/nix into 1.11-maintenance 2017-07-09 16:03:15 -04:00
Graham Christensen 3e0a503bf7
Create a profile suitable for multi-user installs 2017-07-09 14:52:33 -04:00
Eelco Dolstra 026f4f9ae8
macOS: Remove flags
In particular, UF_IMMUTABLE (uchg) needs to be cleared to allow the
path to be garbage-collected or optimised.

See https://github.com/NixOS/nixpkgs/issues/25819.
+       the file from being garbage-collected.

(cherry picked from commit b5bdfdef73)
2017-06-19 14:32:38 +02:00
Eelco Dolstra 11dd08f02e
macOS: Ugly hack to make the tests succeed
Sandboxes cannot be nested, so if Nix's build runs inside a sandbox,
it cannot use a sandbox itself. I don't see a clean way to detect
whether we're in a sandbox, so use a test-specific hack.

https://github.com/NixOS/nix/issues/1413
(cherry picked from commit 1888f7889b)
2017-06-19 14:28:04 +02:00
Shea Levy 3e574c3691 Merge branch '1.11-maintenance' of git://github.com/cyraxjoe/nix into 1.11-maintenance 2017-06-14 07:52:36 -04:00
Eelco Dolstra 5ac7088726
Bump version 2017-06-14 11:43:51 +02:00
Eelco Dolstra 35ea3d62dc
canonicalisePathMetaData(): Ignore security.selinux attribute
Untested, hopefully fixes #1406.

(cherry picked from commit 88b291ffc4)
2017-06-14 11:43:33 +02:00
Joel Rivera 7917494c45 Add support for the curl netrc file in nix-channel/nix-pull.
Based on the implementation in download-from-binary-cache.pl.in.
2017-06-13 18:18:20 -05:00
Eelco Dolstra 1e4885e316
Grmbl 2017-06-12 18:52:26 +02:00
Eelco Dolstra 36f363b8f0
On macOS, don't use /var/folders for TMPDIR
This broke "nix-store --serve".

(cherry picked from commit 25230a17a9)
2017-06-12 18:39:34 +02:00
Eelco Dolstra c33854513a
Remove Ubuntu 13.10 build
Seccomp is too old there.
2017-06-12 16:47:16 +02:00
Eelco Dolstra 0be5b949d3
Don't run pre-build-hook if we don't have a derivation
This fixes a build failure on OS X when using Hydra or Nix 1.12's
build-remote (since they don't copy the derivation to the build
machine).

(cherry picked from commit 7f5b750b40)
2017-06-12 16:46:31 +02:00
Eelco Dolstra c20641ce56
OS X -> macOS 2017-06-12 14:04:52 +02:00
Eelco Dolstra 0fb60e4e0f
Add 1.11.10 release notes 2017-06-12 13:56:38 +02:00
Eelco Dolstra 3414f3804c
Fix build 2017-06-12 13:55:59 +02:00
Eelco Dolstra 8e298e8ad9
Always use the Darwin sandbox
Even with "build-use-sandbox = false", we now use sandboxing with a
permissive profile that allows everything except the creation of
setuid/setgid binaries.

Based on 85e93d7b87.
2017-06-06 20:35:55 +02:00
Eelco Dolstra f534627929
Fix bad cherrypick 2017-06-06 19:52:40 +02:00
Eelco Dolstra 0ca9502264
Disable the build user mechanism on all platforms except Linux and OS X
(cherry picked from commit c8cc50d46e)
2017-06-06 19:52:24 +02:00
Eelco Dolstra bcc21744df
Bump version 2017-06-01 16:53:10 +02:00
Eelco Dolstra 833aae4509
Fix coverage job
(cherry picked from commit b4b1f4525f)
2017-06-01 16:51:32 +02:00
Eelco Dolstra aabe20bf78
RPM, Deb: Add dependency on libseccomp
(cherry picked from commit ab5834f7a1)
2017-06-01 16:51:03 +02:00
Eelco Dolstra c48697d617
Remove listxattr assertion
It appears that sometimes, listxattr() returns a different value for
the query case (i.e. when the buffer size is 0).

(cherry picked from commit 52fec8dde8)
2017-06-01 16:50:23 +02:00
Eelco Dolstra 4be5a65b39
Fix seccomp build failure on clang
Fixes

  src/libstore/build.cc:2321:45: error: non-constant-expression cannot be narrowed from type 'int' to 'scmp_datum_t' (aka 'unsigned long') in initializer list [-Wc++11-narrowing]

(cherry picked from commit fe08d17934)
2017-06-01 16:50:08 +02:00
Eelco Dolstra 634d117ede
Add a seccomp rule to disallow setxattr()
(cherry picked from commit 2ac99a32da)
2017-06-01 16:50:04 +02:00
Eelco Dolstra 66618dbad5
canonicalisePathMetaData(): Remove extended attributes / ACLs
EAs/ACLs are not part of the NAR canonicalisation. Worse, setting an
ACL allows a builder to create writable files in the Nix store. So get
rid of them.

Closes #185.

(cherry picked from commit d798349ede)
2017-06-01 16:50:00 +02:00
Eelco Dolstra 1e0f1dab1e
Require seccomp only in multi-user setups
(cherry picked from commit ff6becafa8)
2017-06-01 16:49:52 +02:00
Eelco Dolstra 17da82e04d
Add test for setuid seccomp filter
(cherry picked from commit 1d9ab273ba)
2017-06-01 16:49:47 +02:00
Eelco Dolstra a2cf0f1018
Fix seccomp initialisation on i686-linux
(cherry picked from commit cf93397d3f)
2017-06-01 16:49:42 +02:00
Eelco Dolstra e296b8884e
Add a seccomp filter to prevent creating setuid/setgid binaries
This prevents builders from setting the S_ISUID or S_ISGID bits,
preventing users from using a nixbld* user to create a setuid/setgid
binary to interfere with subsequent builds under the same nixbld* uid.

This is based on aszlig's seccomp code
(47f587700d).

Reported by Linus Heckemann.

(cherry picked from commit 6cc6c15a2d)
2017-06-01 16:48:57 +02:00
Guillaume Maudoux a8d13e66ee
lexer: remove catch-all rules hiding real errors
With catch-all rules, we hide potential errors.
It turns out that a4744254 made one cath-all useless. Flex detected that
is was impossible to reach.
The other is more subtle, as it can only trigger on unfinished escapes
in unfinished strings, which only occurs at EOF.

(cherry picked from commit a143014d73)
2017-05-01 11:26:44 +02:00
Guillaume Maudoux a10bd3355a
Fix lexer to support `$'` in multiline strings.
(cherry picked from commit a474425425)
2017-05-01 11:26:41 +02:00
Eelco Dolstra 26f7e8305b
Fix hash computation when importing NARs greater than 4 GiB
This caused "nix-store --import" to compute an incorrect hash on NARs
that don't fit in an unsigned int. The import would succeed, but
"nix-store --verify-path" or subsequent exports would detect an
incorrect hash.

A deeper issue is that the export/import format does not contain a
hash, so we can't detect such issues early.

Also, I learned that -Wall does not warn about this.

(cherry picked from commit 41c4558afe)
2017-05-01 11:26:27 +02:00
Eelco Dolstra 5d59ec86d4
Bump version to 1.11.9 2017-04-25 16:58:00 +02:00
Eelco Dolstra 1ab5cc0f5a Merge pull request #1333 from copumpkin/fix-schema-version
Ensure that curSchema is set before opening the DB
2017-04-14 20:58:06 +02:00
Dan Peebles ad9e6037a4 Ensure that curSchema is set before opening the DB
Without this, it's possible to get `curSchema = 0` which then causes us
not to trigger the branch that maintains forward compatibility with the
1.12 schema.

Fixes #1332
2017-04-14 14:44:28 -04:00
Neil Mayhew de4e706776 Propagate NIX_BUILD_CORES to nix-shell environments 2017-04-08 21:31:44 -06:00
Shea Levy eb6f3d5159 builtins.exec: Make the argument just a list
(cherry picked from commit 3ecb09a40a)
2017-03-31 11:58:51 -04:00
Shea Levy 967f231981 Add exec primop behind allow-unsafe-native-code-during-evaluation.
Execute a given program with the (optional) given arguments as the
user running the evaluation, parsing stdout as an expression to be
evaluated.

There are many use cases for nix that would benefit from being able to
run arbitrary code during evaluation, including but not limited to:

* Automatic git fetching to get a sha256 from a git revision
* git rev-parse HEAD
* Automatic extraction of information from build specifications from
  other tools, particularly language-specific package managers like
  cabal or npm
* Secrets decryption (e.g. with nixops)
* Private repository fetching

Ideally, we would add this functionality in a more principled way to
nix, but in the mean time 'builtins.exec' can be used to get these
tasks done.

The primop is only available when the
'allow-unsafe-native-code-during-evaluation' nix option is true. That
flag also enables the 'importNative' primop, which is strictly more
powerful but less convenient (since it requires compiling a plugin
against the running version of nix).

(cherry picked from commit 0bb8db257d)
2017-03-30 10:08:38 -04:00
Daiderd Jordan 773313591f
use std::tuple for ValueMap allocator
(cherry picked from commit 023217f07c)
2017-03-24 23:31:47 +01:00
Eelco Dolstra 206b61b074
useChroot -> useSandbox
(cherry picked from commit 8d7c6644c5)
2017-03-21 13:50:47 +01:00
Eelco Dolstra 201ad43d1a
Bump version to 1.11.8 2017-03-21 11:34:29 +01:00
Vladimír Čunát 9504bcf03c
nix-env: respect meta.outputsToInstall
Discussed on https://github.com/NixOS/nixpkgs/pull/12653#discussion_r51601849

(cherry picked from commit 03cbb9ad59)
2017-03-21 11:33:21 +01:00
Eelco Dolstra d8638ae6b4 Merge pull request #1259 from shlevy/1.11-netrc
Backport netrc-file option to 1.11
2017-03-20 17:37:54 +01:00
Shea Levy a437b8c5d2 download-from-binary-cache.pl: Respect netrc-file 2017-03-05 17:40:17 -05:00
Shea Levy 37bdb9d7f2 Backport netrc-file option to 1.11 2017-03-04 09:55:49 -05:00
Domen Kožar 13fe83dc8e
bail out if macOS 10.9 or lower is used during installer
(cherry picked from commit 48d4a23aa0)
Signed-off-by: Domen Kožar <domen@dev.si>

cc @edolstra
2017-02-23 15:12:35 +01:00
Eelco Dolstra 697b5755e4 Merge pull request #1247 from veprbl/ssl_fix2
use --cacert instead of --capath
2017-02-22 20:14:47 +01:00
Dmitry Kalinkin 06b46f646d
use --cacert instead of --capath
This forces curl to use nix bundled crt instead of picking one up from
system.

Fixes: 142c77711 ('Propagate path of CA bundle to curl child processes')
2017-02-22 14:04:47 -05:00
Eelco Dolstra 2936a8d1ca
Bump version 2017-02-22 12:43:54 +01:00
Eelco Dolstra 142c777112
Propagate path of CA bundle to curl child processes 2017-02-22 12:43:13 +01:00
Eelco Dolstra 41230dd463
SSL_CERT_FILE -> NIX_SSL_CERT_FILE
This prevents collisions with the "native" OpenSSL, in particular on
OS X.

Fixes #921.

(cherry picked from commit fb2dd32100)
2017-02-22 12:30:45 +01:00
Eelco Dolstra 8ca944e009
Add forward compatibility with the Nix 1.12 database schema 2017-02-22 12:19:42 +01:00
Eelco Dolstra 1fa2c86db5
Bump version to 1.11.6 2017-01-13 11:02:55 +01:00
Eelco Dolstra 0085fc6d3e Merge pull request #1178 from dezgeg/bash-env-breakage-stable
nix-shell: Fix 'nix-shell --command' doing nothing without TTY (stable backport)
2017-01-09 16:47:14 +01:00
Tuomas Tynkkynen a4ad1ffa25 nix-shell: Fix 'nix-shell --command' doing nothing without TTY
Regression from 8bddc3d4 ("Fix early removal of rc-file for nix-shell").
The removal of BASH_ENV causes nothing to be executed by bash if it
detects itself in a non-interactive context. Instead, just
use the same condition used by bash to launch bash differently.

According to bash sources, the condition (stdin and stder both
must be TTYs) is specified by POSIX so this should be pretty
safe to rely on.

Fixes #1171 on 1.11.
2017-01-07 19:36:45 +02:00
Scott R. Parish 0c67498be9
fix "nix-build" examples
The existing "nix-build" examples were failing:

  error: cannot auto-call a function that has an argument without a default value (‘system’)

Thanks to @groxxda on irc for pointing out the fix!

Updated to completely remove unneeded path argument, suggested by @joachifm

Updated to remove other occurences of `all-packages.nix` from files as
suggested by @domenkozar

(cherry picked from commit 96d3534a9e)
2017-01-03 16:38:48 +01:00
Eelco Dolstra d39f51fa34
Bump version number 2017-01-02 15:18:50 +01:00
Dmitry Kalinkin 5bf9689e0c
override rx directory permissions in deletePath()
This fixes instantiation of pythonPackages.pytest that produces a
directory with less permissions during one of it's tests that leads to
a nix error like:

error: opening directory ‘/tmp/nix-build-python2.7-pytest-2.9.2.drv-0/pytest-of-user/pytest-0/testdir/test_cache_failure_warns0/.cache’: Permission denied
(cherry picked from commit f91748ba73)
2016-12-19 14:28:57 +01:00
Shea Levy 612c77a399
Update darwin build for optional sandbox paths
Fixes #1132

(cherry picked from commit 8bf378e999)
2016-11-22 10:46:26 +01:00
Eelco Dolstra 2eb840eefa
Support optional sandbox paths
For example, you can now set

  build-sandbox-paths = /dev/nvidiactl?

to specify that /dev/nvidiactl should only be mounted in the sandbox
if it exists in the host filesystem. This is useful e.g. for EC2
images that should support both CUDA and non-CUDA instances.

(cherry picked from commit 18b7363a69)
2016-11-22 10:46:26 +01:00
Shea Levy fd9fc15c0c Add nix.conf options for -k and -K
Fixes #1084
2016-10-27 12:51:27 -04:00
Shea Levy 8bddc3d406 Fix early removal of rc-file for nix-shell
BASH_ENV causes all non-interactive shells called via eg. /etc/bashrc to
remove the rc-file before the main shell gets to run it. Completion
scripts will often do this. Fixes #976.

Adapted from and fixes #1034.
2016-09-08 09:10:50 -04:00
Eelco Dolstra fb577a431f Fix Debian 8 build
http://hydra.nixos.org/build/36462150
(cherry picked from commit 88b79cd55c)
2016-09-06 13:12:53 +02:00
Eelco Dolstra 8c353ea698 Fix incomplete cherry-pick in 0eb8bbb31e 2016-09-06 13:12:04 +02:00
Eelco Dolstra a566927003 Fix OOM in the installer test
http://hydra.nixos.org/build/36462209
(cherry picked from commit 1b5b654fe2)
2016-09-06 13:07:54 +02:00
Dan Peebles f2495212b1 Kill the temporary darwin-specific channel
The issues have been resolved upstream in the main nixpkgs channel now
(cherry picked from commit c89783b6a7)
2016-09-06 13:06:51 +02:00
Eelco Dolstra 7ead75ca85 Drop all distros that are not down with C++11
(cherry picked from commit 7251a81bde)
2016-09-06 13:06:40 +02:00
Eelco Dolstra f668fdb026 Fix nix-copy-closure test on 16.03
(cherry picked from commit b86555aa2b)
2016-09-06 12:59:48 +02:00
aszlig 16e88f0b5a Don't hardcode docbook XSL namespace URL
Docbook XSL got updated to version 1.79.1 in NixOS/nixpkgs@fb893a8 and
we're still referring to the hardcoded previous version.

So instead of just updating this to 1.79.1 we're going to use "current"
in the hope that this won't happen again.

I have tested this by building the manual under Nix(OS) but I haven't
tested this in a non-Nix environment, so I'm not sure whether this could
have implications.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @edolstra
(cherry picked from commit 72fb2ccfa1)
2016-09-06 12:52:49 +02:00
Eelco Dolstra 2179dd3e5b Bump version 2016-09-02 14:58:47 +02:00
Eelco Dolstra efa2e451fb Make the search path lazier with non-fatal errors
Thus, -I / $NIX_PATH entries are now downloaded only when they are
needed for evaluation. An error to download an entry is a non-fatal
warning (just like non-existant paths).

This does change the semantics of builtins.nixPath, which now returns
the original, rather than resulting path. E.g., before we had

  [ { path = "/nix/store/hgm3yxf1lrrwa3z14zpqaj5p9vs0qklk-nixexprs.tar.xz"; prefix = "nixpkgs"; } ... ]

but now

  [ { path = "https://nixos.org/channels/nixos-16.03/nixexprs.tar.xz"; prefix = "nixpkgs"; } ... ]

Fixes #792.

(cherry picked from commit 363f37d084)
2016-09-02 11:55:14 +02:00
Shea Levy dea9de79b7 callFunction: Copy functors to the heap
Normally it's impossible to take a reference to the function passed to
callFunction, so some callers (e.g. ExprApp::eval) allocate that value
on the stack. For functors, a reference to the functor itself may be
kept, so we need to have it on the heap.

Fixes #1045

(cherry picked from commit 9fa21765e7)
2016-08-29 07:40:03 -04:00
Shea Levy 2ac966a464 Bump version to 1.11.3 2016-08-22 10:20:41 -04:00
Eelco Dolstra 6a493a7c44 launchd: Set $SSL_CERT_FILE
Otherwise in particular https://cache.nixos.org won't work in the
daemon.

(cherry picked from commit eff80419c7)
2016-08-19 13:11:03 +02:00
Shea Levy 7bb4d028a8 builtins.fetch{url,tarball}: Allow name attribute
(cherry picked from commit d52d391164)
2016-08-15 07:42:51 -04:00
Shea Levy 66151dc154 Respect --keep-going when a substituter fails.
Fixes #977

(cherry picked from commit 18b0808475)
2016-07-23 13:22:52 -04:00
Domen Kožar 0eb8bbb31e add Ubuntu 16.03 .deb builds
(cherry picked from commit bf386de9f2)
Signed-off-by: Domen Kožar <domen@dev.si>
2016-05-26 15:55:51 +01:00
Eelco Dolstra 437d3cdc7a Bump version to 1.11.2 2016-02-10 12:10:03 +01:00
Alex Cruice 0322c92560 Check shell profile is writeable before modifying
The `set -e` at the top of the script causes the installation to fail to
complete if the shell profile is not writeable. Checking file existence
only is not enough.

(cherry picked from commit ad0dc41899)
2016-02-10 12:04:47 +01:00
Brian McKenna 1852f7dbf3 Fix broken call to shellwords
nix-shell shebangs were broken by 9018deab

(cherry picked from commit 3baf8be1d1)
2016-02-10 12:04:18 +01:00
Eelco Dolstra 08500066ea Revert "Revert "next try for "don't abort when given unmatched '}' with 'start-condition stack underflow'. This fixes #751"""
This reverts commit b669d3d2e8.

(cherry picked from commit 5d8b7eb3e1)
2016-02-10 12:04:08 +01:00
63 changed files with 1885 additions and 297 deletions

1
.gitignore vendored
View File

@ -34,6 +34,7 @@ Makefile.config
# /scripts/
/scripts/nix-profile.sh
/scripts/nix-profile-daemon.sh
/scripts/nix-pull
/scripts/nix-push
/scripts/nix-switch

2
.travis.yml Normal file
View File

@ -0,0 +1,2 @@
os: osx
script: ./tests/install-darwin.sh

View File

@ -200,6 +200,13 @@ AC_SUBST(HAVE_SODIUM, [$have_sodium])
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])
# Look for libseccomp, required for Linux sandboxing.
if test "$sys_name" = linux; then
PKG_CHECK_MODULES([LIBSECCOMP], [libseccomp],
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
fi
# Whether to use the Boehm garbage collector.
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]),

View File

@ -268,7 +268,12 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
to mount a path in a different location in the sandbox; for
instance, <literal>/bin=/nix-bin</literal> will mount the path
<literal>/nix-bin</literal> as <literal>/bin</literal> inside the
sandbox.</para>
sandbox. If <replaceable>source</replaceable> is followed by
<literal>?</literal>, then it is not an error if
<replaceable>source</replaceable> does not exist; for example,
<literal>/dev/nvidiactl?</literal> specifies that
<filename>/dev/nvidiactl</filename> will only be mounted in the
sandbox if it exists in the host filesystem.</para>
<para>Depending on how Nix was built, the default value for this option
may be empty or provide <filename>/bin/sh</filename> as a
@ -452,6 +457,29 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry>
<varlistentry><term><literal>netrc-file</literal></term>
<listitem><para>If set to an absolute path to a <filename>netrc</filename>
file, Nix will use the HTTP authentication credentials in this file when
trying to download from a remote host through HTTP or HTTPS. Defaults to
<filename>$NIX_CONF_DIR/netrc</filename>.</para>
<para>The <filename>netrc</filename> file consists of a list of
accounts in the following format:
<screen>
machine <replaceable>my-machine</replaceable>
login <replaceable>my-username</replaceable>
password <replaceable>my-password</replaceable>
</screen>
For the exact syntax, see <link
xlink:href="https://ec.haxx.se/usingcurl-netrc.html">the
<literal>curl</literal> documentation.</link></para></listitem>
</varlistentry>
<varlistentry><term><literal>system</literal></term>
<listitem><para>This option specifies the canonical Nix system

View File

@ -22,12 +22,6 @@
<arg><option>--delete-old</option></arg>
<arg><option>-d</option></arg>
<arg><option>--delete-older-than</option> <replaceable>period</replaceable></arg>
<group choice='opt'>
<arg choice='plain'><option>--print-roots</option></arg>
<arg choice='plain'><option>--print-live</option></arg>
<arg choice='plain'><option>--print-dead</option></arg>
<arg choice='plain'><option>--delete</option></arg>
</group>
<arg><option>--max-freed</option> <replaceable>bytes</replaceable></arg>
<arg><option>--dry-run</option></arg>
</cmdsynopsis>

View File

@ -367,6 +367,10 @@ number of possible ways:
linkend="rsec-nix-store-realise">realised</link> and
installed.</para></listitem>
<listitem><para>By default all outputs are installed for each derivation.
That can be reduced by setting <literal>meta.outputsToInstall</literal>.
</para></listitem> <!-- TODO: link nixpkgs docs on the ability to override those. -->
</itemizedlist>
</para>

View File

@ -43,7 +43,8 @@
<arg choice='plain'><option>-E</option></arg>
</group>
<arg choice='plain' rep='repeat'><replaceable>files</replaceable></arg>
<sbr/>
</cmdsynopsis>
<cmdsynopsis>
<command>nix-instantiate</command>
<arg choice='plain'><option>--find-file</option></arg>
<arg choice='plain' rep='repeat'><replaceable>files</replaceable></arg>

View File

@ -7,15 +7,14 @@
<title>Building and Testing</title>
<para>You can now try to build Hello. Of course, you could do
<literal>nix-env -f pkgs/top-level/all-packages.nix -i hello</literal>,
but you may not want to install a possibly broken package just yet.
The best way to test the package is by using the command <command
linkend="sec-nix-build">nix-build</command>, which builds a Nix
expression and creates a symlink named <filename>result</filename> in
the current directory:
<literal>nix-env -i hello</literal>, but you may not want to install a
possibly broken package just yet. The best way to test the package is by
using the command <command linkend="sec-nix-build">nix-build</command>,
which builds a Nix expression and creates a symlink named
<filename>result</filename> in the current directory:
<screen>
$ nix-build pkgs/top-level/all-packages.nix -A hello
$ nix-build -A hello
building path `/nix/store/632d2b22514d...-hello-2.1.1'
hello-2.1.1/
hello-2.1.1/intl/
@ -29,8 +28,7 @@ $ ./result/bin/hello
Hello, world!</screen>
The <link linkend='opt-attr'><option>-A</option></link> option selects
the <literal>hello</literal> attribute from
<filename>all-packages.nix</filename>. This is faster than using the
the <literal>hello</literal> attribute. This is faster than using the
symbolic package name specified by the <literal>name</literal>
attribute (which also happens to be <literal>hello</literal>) and is
unambiguous (there can be multiple packages with the symbolic name
@ -69,7 +67,7 @@ block (or perform other derivations if available) until the build
finishes:
<screen>
$ nix-build pkgs/top-level/all-packages.nix -A hello
$ nix-build -A hello
waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'</screen>
So it is always safe to run multiple instances of Nix in parallel

View File

@ -10,7 +10,7 @@ XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
--stringparam generate.toc "book toc" \
--param keep.relative.image.uris 0
docbookxsl = http://docbook.sourceforge.net/release/xsl-ns/1.78.1
docbookxsl = http://docbook.sourceforge.net/release/xsl-ns/current
docbookrng = http://docbook.org/xml/5.0/rng/docbook.rng
MANUAL_SRCS := $(call rwildcard, $(d), *.xml)

View File

@ -12,6 +12,7 @@
</partintro>
-->
<xi:include href="rl-1.11.10.xml" />
<xi:include href="rl-1.11.xml" />
<xi:include href="rl-1.10.xml" />
<xi:include href="rl-1.9.xml" />

View File

@ -0,0 +1,31 @@
<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-1.11.10">
<title>Release 1.11.10 (2017-06-12)</title>
<para>This release fixes a security bug in Nixs “build user” build
isolation mechanism. Previously, Nix builders had the ability to
create setuid binaries owned by a <literal>nixbld</literal>
user. Such a binary could then be used by an attacker to assume a
<literal>nixbld</literal> identity and interfere with subsequent
builds running under the same UID.</para>
<para>To prevent this issue, Nix now disallows builders to create
setuid and setgid binaries. On Linux, this is done using a seccomp BPF
filter. Note that this imposes a small performance penalty (e.g. 1%
when building GNU Hello). Using seccomp, we now also prevent the
creation of extended attributes and POSIX ACLs since these cannot be
represented in the NAR format and (in the case of POSIX ACLs) allow
bypassing regular Nix store permissions. On macOS, the restriction is
implemented using the existing sandbox mechanism, which now uses a
minimal “allow all except the creation of setuid/setgid binaries”
profile when regular sandboxing is disabled. On other platforms, the
“build user” mechanism is now disabled.</para>
<para>Thanks go to Linus Heckemann for discovering and reporting this
bug.</para>
</section>

View File

@ -13,11 +13,11 @@ RUN set -x \
ONBUILD ENV \
ENV=/etc/profile \
PATH=/root/.nix-profile/bin:/root/.nix-profile/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
GIT_SSL_CAINFO=/root/.nix-profile/etc/ca-bundle.crt \
SSL_CERT_FILE=/root/.nix-profile/etc/ca-bundle.crt
GIT_SSL_CAINFO=/root/.nix-profile/etc/ssl/certs/ca-bundle.crt \
NIX_SSL_CERT_FILE=/root/.nix-profile/etc/ssl/certs/ca-bundle.crt
ENV \
ENV=/etc/profile \
PATH=/root/.nix-profile/bin:/root/.nix-profile/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
GIT_SSL_CAINFO=/root/.nix-profile/etc/ca-bundle.crt \
SSL_CERT_FILE=/root/.nix-profile/etc/ca-bundle.crt
GIT_SSL_CAINFO=/root/.nix-profile/etc/ssl/certs/ca-bundle.crt \
NIX_SSL_CERT_FILE=/root/.nix-profile/etc/ssl/certs/ca-bundle.crt

View File

@ -12,5 +12,10 @@
<string>/var/log/nix-daemon.log</string>
<key>StandardOutPath</key>
<string>/dev/null</string>
<key>EnvironmentVariables</key>
<dict>
<key>NIX_SSL_CERT_FILE</key>
<string>/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt</string>
</dict>
</dict>
</plist>

View File

@ -24,9 +24,11 @@ Requires: perl-DBD-SQLite
Requires: bzip2
Requires: gzip
Requires: xz
Requires: libseccomp
BuildRequires: bzip2-devel
BuildRequires: sqlite-devel
BuildRequires: libcurl-devel
BuildRequires: libseccomp-devel
# Hack to make that shitty RPM scanning hack shut up.
Provides: perl(Nix::SSH)
@ -178,6 +180,7 @@ systemctl start nix-daemon.socket
%{_mandir}/man5/*.5*
%{_mandir}/man8/*.8*
%config(noreplace) %{_sysconfdir}/profile.d/nix.sh
%config(noreplace) %{_sysconfdir}/profile.d/nix-daemon.sh
/nix
%files devel

View File

@ -12,6 +12,12 @@ $logDir = $ENV{"NIX_LOG_DIR"} || "@localstatedir@/log/nix";
$confDir = $ENV{"NIX_CONF_DIR"} || "@sysconfdir@/nix";
$storeDir = $ENV{"NIX_STORE_DIR"} || "@storedir@";
$caBundle = $ENV{"NIX_SSL_CERT_FILE"} // $ENV{"SSL_CERT_FILE"} // $ENV{"CURL_CA_BUNDLE"} // $ENV{"OPENSSL_X509_CERT_FILE"};
$caBundle = "/etc/ssl/certs/ca-bundle.crt" if !$caBundle && -f "/etc/ssl/certs/ca-bundle.crt";
$caBundle = "/etc/ssl/certs/ca-certificates.crt" if !$caBundle && -f "/etc/ssl/certs/ca-certificates.crt";
$curlCaFlag = defined $caBundle ? "--cacert $caBundle" : "";
$bzip2 = "@bzip2@";
$xz = "@xz@";
$curl = "@curl@";

View File

@ -7,7 +7,7 @@ let
pkgs = import <nixpkgs> {};
systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" /* "x86_64-freebsd" "i686-freebsd" */ ];
systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" /* "x86_64-freebsd" "i686-freebsd" */ ];
jobs = rec {
@ -27,7 +27,8 @@ let
[ curl bison flex perl libxml2 libxslt bzip2 xz
dblatex (dblatex.tex or tetex) nukeReferences pkgconfig sqlite libsodium
docbook5 docbook5_xsl
] ++ lib.optional (!lib.inNixShell) git;
] ++ lib.optional stdenv.isLinux libseccomp
++ lib.optional (!lib.inNixShell) git;
configureFlags = ''
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
@ -77,8 +78,7 @@ let
build = pkgs.lib.genAttrs systems (system:
# FIXME: temporarily use a different branch for the Darwin build.
with import (if system == "x86_64-darwin" then <nixpkgs-darwin> else <nixpkgs>) { inherit system; };
with import <nixpkgs> { inherit system; };
releaseTools.nixBuild {
name = "nix";
@ -86,7 +86,8 @@ let
buildInputs =
[ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ]
++ lib.optional stdenv.isLinux libsodium;
++ lib.optional stdenv.isLinux libseccomp
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium;
configureFlags = ''
--disable-init-state
@ -113,7 +114,7 @@ let
binaryTarball = pkgs.lib.genAttrs systems (system:
# FIXME: temporarily use a different branch for the Darwin build.
with import (if system == "x86_64-darwin" then <nixpkgs-darwin> else <nixpkgs>) { inherit system; };
with import <nixpkgs> { inherit system; };
let
toplevel = builtins.getAttr system jobs.build;
@ -122,7 +123,7 @@ let
runCommand "nix-binary-tarball-${version}"
{ exportReferencesGraph = [ "closure1" toplevel "closure2" cacert ];
buildInputs = [ perl ];
buildInputs = [ perl /* shellcheck */ ];
meta.description = "Distribution-independent Nix bootstrap binaries for ${system}";
}
''
@ -131,7 +132,15 @@ let
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
--subst-var-by nix ${toplevel} \
--subst-var-by cacert ${cacert}
substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user \
--subst-var-by nix ${toplevel} \
--subst-var-by cacert ${cacert}
#shellcheck -e SC1090 $TMPDIR/install
#shellcheck -e SC1091,SC2002 $TMPDIR/install-darwin-multi-user
chmod +x $TMPDIR/install
chmod +x $TMPDIR/install-darwin-multi-user
dir=nix-${version}-${system}
fn=$out/$dir.tar.bz2
mkdir -p $out/nix-support
@ -143,7 +152,7 @@ let
--transform "s,$TMPDIR/install,$dir/install," \
--transform "s,$TMPDIR/reginfo,$dir/.reginfo," \
--transform "s,$NIX_STORE,$dir/store,S" \
$TMPDIR/install $TMPDIR/reginfo $storePaths
$TMPDIR/install $TMPDIR/install-darwin-multi-user $TMPDIR/reginfo $storePaths
'');
@ -155,7 +164,7 @@ let
src = tarball;
buildInputs =
[ curl perl bzip2 openssl pkgconfig sqlite xz libsodium
[ curl perl bzip2 openssl pkgconfig sqlite xz libsodium libseccomp
# These are for "make check" only:
graphviz libxml2 libxslt
];
@ -180,8 +189,6 @@ let
};
rpm_fedora18i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora18i386) [];
rpm_fedora18x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora18x86_64) [];
rpm_fedora19i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora19i386) [];
rpm_fedora19x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora19x86_64) [];
rpm_fedora20i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora20i386) [];
@ -190,23 +197,19 @@ let
rpm_fedora21x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora21x86_64) [ "libsodium-devel" ];
deb_debian7i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian7i386) [];
deb_debian7x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian7x86_64) [];
deb_debian8i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian8i386) [ "libsodium-dev" ];
deb_debian8x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian8x86_64) [ "libsodium-dev" ];
deb_debian8i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian8i386) [ "libsodium-dev" ] [ "libsodium13" ];
deb_debian8x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian8x86_64) [ "libsodium-dev" ] [ "libsodium13" ];
deb_ubuntu1210i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1210i386) [];
deb_ubuntu1210x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1210x86_64) [];
deb_ubuntu1304i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1304i386) [];
deb_ubuntu1304x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1304x86_64) [];
deb_ubuntu1310i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1310i386) [];
deb_ubuntu1310x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1310x86_64) [];
deb_ubuntu1404i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1404i386) [];
deb_ubuntu1404x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1404x86_64) [];
deb_ubuntu1410i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1410i386) [];
deb_ubuntu1410x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1410x86_64) [];
deb_ubuntu1504i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1504i386) [ "libsodium-dev" ];
deb_ubuntu1504x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1504x86_64) [ "libsodium-dev" ];
deb_ubuntu1404i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1404i386) [] [];
deb_ubuntu1404x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1404x86_64) [] [];
deb_ubuntu1410i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1410i386) [] [];
deb_ubuntu1410x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1410x86_64) [] [];
deb_ubuntu1504i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1504i386) [ "libsodium-dev" ] [ "libsodium13" ];
deb_ubuntu1504x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1504x86_64) [ "libsodium-dev" ] [ "libsodium13" ];
deb_ubuntu1510i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1510i386) [ "libsodium-dev" ] [ "libsodium13"];
deb_ubuntu1510x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1510x86_64) [ "libsodium-dev" ] [ "libsodium13" ];
deb_ubuntu1604i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1604i386) [ "libsodium-dev" ] [ "libsodium18" ];
deb_ubuntu1604x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1604x86_64) [ "libsodium-dev" ] [ "libsodium18" ];
# System tests.
@ -218,6 +221,11 @@ let
nix = build.x86_64-linux; system = "x86_64-linux";
});
tests.setuid = pkgs.lib.genAttrs (pkgs.lib.filter (pkgs.lib.hasSuffix "-linux") systems) (system:
import ./tests/setuid.nix rec {
nix = build.${system}; inherit system;
});
tests.binaryTarball =
with import <nixpkgs> { system = "x86_64-linux"; };
vmTools.runInLinuxImage (runCommand "nix-binary-tarball-test"
@ -226,13 +234,15 @@ let
''
useradd -m alice
su - alice -c 'tar xf ${binaryTarball.x86_64-linux}/*.tar.*'
mount -t tmpfs none /nix # Provide a writable /nix.
mkdir /dest-nix
mount -o bind /dest-nix /nix # Provide a writable /nix.
chown alice /nix
su - alice -c '_NIX_INSTALLER_TEST=1 ./nix-*/install'
su - alice -c 'nix-store --verify'
su - alice -c 'nix-store -qR ${build.x86_64-linux}'
su - alice -c 'PAGER= nix-store -qR ${build.x86_64-linux}'
mkdir -p $out/nix-support
touch $out/nix-support/hydra-build-products
umount /nix
''); # */
tests.evalNixpkgs =
@ -272,8 +282,8 @@ let
binaryTarball.x86_64-darwin
#binaryTarball.x86_64-freebsd
binaryTarball.x86_64-linux
deb_debian7i386
deb_debian7x86_64
deb_debian8i386
deb_debian8x86_64
deb_ubuntu1404i386 # LTS
deb_ubuntu1404x86_64 # LTS
deb_ubuntu1504i386
@ -306,7 +316,7 @@ let
src = jobs.tarball;
diskImage = (diskImageFun vmTools.diskImageFuns)
{ extraPackages =
[ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" "emacs" "perl-WWW-Curl" "libcurl-devel" "openssl-devel" "xz-devel" ]
[ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" "emacs" "perl-WWW-Curl" "libcurl-devel" "openssl-devel" "xz-devel" "libseccomp-devel" ]
++ extraPackages; };
memSize = 1024;
meta.schedulingPriority = 50;
@ -318,7 +328,7 @@ let
makeDeb_x86_64 = makeDeb "x86_64-linux";
makeDeb =
system: diskImageFun: extraPackages:
system: diskImageFun: extraPackages: extraDebPackages:
with import <nixpkgs> { inherit system; };
@ -327,14 +337,15 @@ let
src = jobs.tarball;
diskImage = (diskImageFun vmTools.diskImageFuns)
{ extraPackages =
[ "libdbd-sqlite3-perl" "libsqlite3-dev" "libbz2-dev" "libwww-curl-perl" "libcurl-dev" "libcurl3-nss" "libssl-dev" "liblzma-dev" ]
[ "libdbd-sqlite3-perl" "libsqlite3-dev" "libbz2-dev" "libwww-curl-perl" "libcurl-dev" "libcurl3-nss" "libssl-dev" "liblzma-dev" "libseccomp-dev" ]
++ extraPackages; };
memSize = 1024;
meta.schedulingPriority = 50;
postInstall = "make installcheck";
configureFlags = "--sysconfdir=/etc";
debRequires =
[ "curl" "libdbd-sqlite3-perl" "libsqlite3-0" "libbz2-1.0" "bzip2" "xz-utils" "libwww-curl-perl" "libssl1.0.0" "liblzma5" ]
++ lib.optionals (lib.elem "libsodium-dev" extraPackages) [ "libsodium13" ] ;
[ "curl" "libdbd-sqlite3-perl" "libsqlite3-0" "libbz2-1.0" "bzip2" "xz-utils" "libwww-curl-perl" "libssl1.0.0" "liblzma5" "libseccomp2" ]
++ extraDebPackages;
debMaintainer = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
doInstallCheck = true;
};

View File

@ -41,9 +41,6 @@ my $activeRequests = 0;
my $curlIdCount = 1;
my %requests;
my %scheduled;
my $caBundle = $ENV{"SSL_CERT_FILE"} // $ENV{"CURL_CA_BUNDLE"} // $ENV{"OPENSSL_X509_CERT_FILE"};
$caBundle = "/etc/ssl/certs/ca-bundle.crt" if !$caBundle && -f "/etc/ssl/certs/ca-bundle.crt";
$caBundle = "/etc/ssl/certs/ca-certificates.crt" if !$caBundle && -f "/etc/ssl/certs/ca-certificates.crt";
my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name";
@ -65,6 +62,8 @@ my $curlConnectTimeout = int(
$Nix::Config::config{"connect-timeout"} //
$ENV{"NIX_CONNECT_TIMEOUT"} // 0);
my $netrcFile = $Nix::Config::config{"netrc-file"} //
"$Nix::Config::confDir/netrc";
sub addRequest {
my ($storePath, $url, $head) = @_;
@ -79,7 +78,7 @@ sub addRequest {
open (my $fh, ">", \$requests{$curlId}->{content});
$curl->setopt(CURLOPT_WRITEDATA, $fh);
$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
$curl->setopt(CURLOPT_CAINFO, $caBundle) if defined $caBundle;
$curl->setopt(CURLOPT_CAINFO, $Nix::Config::caBundle) if defined $Nix::Config::caBundle;
unless (isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1")) {
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 0);
@ -91,6 +90,8 @@ sub addRequest {
$curl->setopt(CURLOPT_FAILONERROR, 1);
$curl->setopt(CURLOPT_CONNECTTIMEOUT, $curlConnectTimeout);
$curl->setopt(CURLOPT_TIMEOUT, 20 * 60);
$curl->setopt(CURLOPT_NETRC_FILE, $netrcFile);
$curl->setopt(CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
if ($activeRequests >= $maxParallelRequests) {
$scheduled{$curlId} = 1;
@ -566,7 +567,7 @@ sub downloadBinary {
die if $requireSignedBinaryCaches && !defined $info->{signedBy};
print STDERR "\n*** Downloading $url ", ($requireSignedBinaryCaches ? "(signed by $info->{signedBy}) " : ""), "to $storePath...\n";
checkURL $url;
if (system("$Nix::Config::curl --fail --location --connect-timeout $curlConnectTimeout -A '$userAgent' '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) {
if (system("$Nix::Config::curl --fail --location --netrc-file $netrcFile --netrc-optional --connect-timeout $curlConnectTimeout -A '$userAgent' $Nix::Config::curlCaFlag '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) {
warn "download of $url failed" . ($! ? ": $!" : "") . "\n";
next;
}

View File

@ -17,7 +17,7 @@ my $logFile = "$Nix::Config::logDir/downloads";
# estimating the expected download size.
my $fast = 1;
my $curl = "$Nix::Config::curl --fail --location";
my $curl = "$Nix::Config::curl $Nix::Config::curlCaFlag --fail --location";
# Open the manifest cache and update it if necessary.

View File

@ -0,0 +1,845 @@
#!/bin/bash
set -eu
set -o pipefail
# Sourced from:
# - https://github.com/LnL7/nix-darwin/blob/8c29d0985d74b4a990238497c47a2542a5616b3c/bootstrap.sh
# - https://gist.github.com/expipiplus1/e571ce88c608a1e83547c918591b149f/ac504c6c1b96e65505fbda437a28ce563408ecb0
# - https://github.com/NixOS/nixos-org-configurations/blob/a122f418797713d519aadf02e677fce0dc1cb446/delft/scripts/nix-mac-installer.sh
# - https://github.com/matthewbauer/macNixOS/blob/f6045394f9153edea417be90c216788e754feaba/install-macNixOS.sh
# - https://gist.github.com/LnL7/9717bd6cdcb30b086fd7f2093e5f8494/86b26f852ce563e973acd30f796a9a416248c34a
#
# however tracking which bits came from which would be impossible.
readonly ESC='\033[0m'
readonly BOLD='\033[38;1m'
readonly BLUE='\033[38;34m'
readonly BLUE_UL='\033[38;4;34m'
readonly GREEN='\033[38;32m'
readonly GREEN_UL='\033[38;4;32m'
readonly RED='\033[38;31m'
readonly RED_UL='\033[38;4;31m'
readonly YELLOW='\033[38;33m'
readonly YELLOW_UL='\033[38;4;33m'
readonly CORES=$(sysctl -n hw.ncpu)
readonly NIX_USER_COUNT="$CORES"
readonly NIX_BUILD_GROUP_ID="30000"
readonly NIX_BUILD_GROUP_NAME="nixbld"
readonly NIX_FIRST_BUILD_UID="30001"
# Please don't change this. We don't support it, because the
# default shell profile that comes with Nix doesn't support it.
readonly NIX_ROOT="/nix"
readonly PLIST_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist
readonly PROFILE_TARGETS=("/etc/profile" "/etc/bashrc" "/etc/zshrc")
readonly PROFILE_BACKUP_SUFFIX=".backup-before-nix"
readonly PROFILE_NIX_FILE="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
readonly NIX_INSTALLED_NIX="@nix@"
readonly NIX_INSTALLED_CACERT="@cacert@"
readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
readonly ROOT_HOME="/var/root"
if [ -t 0 ]; then
readonly IS_HEADLESS='no'
else
readonly IS_HEADLESS='yes'
fi
headless() {
if [ "$IS_HEADLESS" = "yes" ]; then
return 0
else
return 1
fi
}
contactme() {
echo "We'd love to help if you need it."
echo ""
echo "If you can, open an issue at https://github.com/nixos/nix/issues"
echo ""
echo "Or feel free to contact the team,"
echo " - on IRC #nixos on irc.freenode.net"
echo " - on twitter @nixos_org"
}
uninstall_directions() {
subheader "Uninstalling nix:"
local step=0
if [ -e "$PLIST_DEST" ]; then
step=$((step + 1))
cat <<EOF
$step. Delete $PLIST_DEST
sudo launchctl unload $PLIST_DEST
sudo rm $PLIST_DEST
EOF
fi
for profile_target in "${PROFILE_TARGETS[@]}"; do
if [ -e "$profile_target" ] && [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
step=$((step + 1))
cat <<EOF
$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target
sudo mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
(after this one, you may need to re-open any terminals that were
opened while it existed.)
EOF
fi
done
step=$((step + 1))
cat <<EOF
$step. Delete the files Nix added to your system:
sudo rm -rf /etc/nix $NIX_ROOT $ROOT_HOME/.nix-profile $ROOT_HOME/.nix-defexpr $ROOT_HOME/.nix-channels $HOME/.nix-profile $HOME/.nix-defexpr $HOME/.nix-channels
and that is it.
EOF
}
nix_user_for_core() {
printf "nixbld%d" "$1"
}
nix_uid_for_core() {
echo $((NIX_FIRST_BUILD_UID + $1 - 1))
}
dsclattr() {
/usr/bin/dscl . -read "$1" \
| awk "/$2/ { print \$2 }"
}
_textout() {
echo -en "$1"
shift
if [ "$*" = "" ]; then
cat
else
echo "$@"
fi
echo -en "$ESC"
}
header() {
follow="---------------------------------------------------------"
header=$(echo "---- $* $follow$follow$follow" | head -c 80)
echo ""
_textout "$BLUE" "$header"
}
warningheader() {
follow="---------------------------------------------------------"
header=$(echo "---- $* $follow$follow$follow" | head -c 80)
echo ""
_textout "$RED" "$header"
}
subheader() {
echo ""
_textout "$BLUE_UL" "$*"
}
row() {
printf "$BOLD%s$ESC:\t%s\n" "$1" "$2"
}
task() {
echo ""
ok "~~> $1"
}
bold() {
echo "$BOLD$*$ESC"
}
ok() {
_textout "$GREEN" "$@"
}
warning() {
warningheader "warning!"
cat
echo ""
}
failure() {
header "oh no!"
_textout "$RED" "$@"
echo ""
_textout "$RED" "$(contactme)"
trap finish_cleanup EXIT
exit 1
}
ui_confirm() {
_textout "$GREEN$GREEN_UL" "$1"
if headless; then
echo "No TTY, assuming you would say yes :)"
return 0
fi
local prompt="[y/n] "
echo -n "$prompt"
while read -r y; do
if [ "$y" = "y" ]; then
echo ""
return 0
elif [ "$y" = "n" ]; then
echo ""
return 1
else
_textout "$RED" "Sorry, I didn't understand. I can only understand answers of y or n"
echo -n "$prompt"
fi
done
echo ""
return 1
}
__sudo() {
local expl="$1"
local cmd="$2"
shift
header "sudo execution"
echo "I am executing:"
echo ""
printf " $ sudo %s\n" "$cmd"
echo ""
echo "$expl"
echo ""
return 0
}
_sudo() {
local expl="$1"
shift
if ! headless; then
__sudo "$expl" "$*"
fi
sudo "$@"
}
readonly SCRATCH=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish_cleanup {
rm -rf "$SCRATCH"
}
function finish_fail {
finish_cleanup
failure <<EOF
Jeeze, something went wrong. If you can take all the output and open
an issue, we'd love to fix the problem so nobody else has this issue.
:(
EOF
}
trap finish_fail EXIT
function finish_success {
finish_cleanup
ok "Alright! We're done!"
cat <<EOF
Before Nix will work in your existing shells, you'll need to either
run:
$ source $PROFILE_NIX_FILE
or close them and open them again. Other than that, you should be
ready to go.
Try it! Open a new terminal, and type:
$ nix-shell -p nix-info --run "nix-info -m"
Thank you for using this installer. If you have any feedback, don't
hesitate:
$(contactme)
EOF
}
validate_starting_assumptions() {
if [ "$(uname -s)" != "Darwin" ]; then
failure "This script is for use with macOS!"
fi
if [ $EUID -eq 0 ]; then
failure <<EOF
Please do not run this script with root privileges. We will call sudo
when we need to.
EOF
fi
if type nix-env 2> /dev/null >&2; then
failure <<EOF
Nix already appears to be installed, and this tool assumes it is
_not_ yet installed.
$(uninstall_directions)
EOF
fi
if pgrep nix-daemon 2> /dev/null >&2; then
failure <<EOF
Nix seems to be partially installed, because the nix-daemon is
currently running. It may be in a launchd service. Please stop the
the old nix-daemon, and try again.
If you have an existing launchd plist for nix-daemon, please delete
it.
$(uninstall_directions)
EOF
fi
if [ "${NIX_REMOTE:-}" != "" ]; then
failure <<EOF
For some reason, \$NIX_REMOTE is set. It really should not be set
before this installer runs, and it hints that Nix is currently
installed. Please delete the old Nix installation and start again.
Note: You might need to close your shell window and open a new shell
to clear the variable.
EOF
fi
if echo "${SSL_CERT_FILE:-}" | grep -qE "(nix/var/nix|nix-profile)"; then
failure <<EOF
It looks like \$SSL_CERT_FILE is set to a path that used to be part of
the old Nix installation. Please unset that variable and try again:
$ unset SSL_CERT_FILE
EOF
fi
for file in ~/.bash_profile ~/.bash_login ~/.profile ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
if [ -f "$file" ]; then
if grep -l "^[^#].*.nix-profile" "$file"; then
failure <<EOF
I found a reference to a ".nix-profile" in $file.
This has a high chance of breaking a new nix installation. It was most
likely put there by a previous Nix installer.
Please remove this reference and try running this again. You should
also look for similar references in:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
or other shell init files that you may have.
$(uninstall_directions)
EOF
fi
fi
done
if [ -d /nix ]; then
failure <<EOF
There are some relics of a previous installation of Nix at /nix, and
this scripts assumes Nix is _not_ yet installed. Please delete the old
Nix installation and start again.
$(uninstall_directions)
EOF
fi
if [ -d /etc/nix ]; then
failure <<EOF
There are some relics of a previous installation of Nix at /etc/nix, and
this scripts assumes Nix is _not_ yet installed. Please delete the old
Nix installation and start again.
$(uninstall_directions)
EOF
fi
for profile_target in "${PROFILE_TARGETS[@]}"; do
if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
failure <<EOF
When this script runs, it backs up the current $profile_target to
$profile_target$PROFILE_BACKUP_SUFFIX. This backup file already exists, though.
Please follow these instructions to clean up the old backup file:
1. Copy $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX to another place, just
in case.
2. Take care to make sure that $profile_target$PROFILE_BACKUP_SUFFIX doesn't look like
it has anything nix-related in it. If it does, something is probably
quite wrong. Please open an issue or get in touch immediately.
3. Take care to make sure that $profile_target doesn't look like it has
anything nix-related in it. If it does, and $profile_target _did not_,
run:
$ /usr/bin/sudo /bin/mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
and try again.
EOF
fi
if grep -qi "nix" "$profile_target"; then
failure <<EOF
It looks like $profile_target already has some Nix configuration in
there. There should be no reason to run this again. If you're having
trouble, please open an issue.
EOF
fi
done
danger_paths=("$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.nix-profile")
for danger_path in "${danger_paths[@]}"; do
if _sudo "making sure that $danger_path doesn't exist" \
test -e "$danger_path"; then
failure <<EOF
I found a file at $danger_path, which is a relic of a previous
installation. You must first delete this file before continuing.
$(uninstall_directions)
EOF
fi
done
}
setup_report() {
header "hardware report"
row " Cores" "$CORES"
header "Nix config report"
row " Temp Dir" "$SCRATCH"
row " Nix Root" "$NIX_ROOT"
row " Build Users" "$NIX_USER_COUNT"
row " Build Group ID" "$NIX_BUILD_GROUP_ID"
row "Build Group Name" "$NIX_BUILD_GROUP_NAME"
if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" != "" ]; then
row "Preexisting Install" "Allowed"
fi
subheader "build users:"
row " Username" "UID"
for i in $(seq 1 "$NIX_USER_COUNT"); do
row " $(nix_user_for_core "$i")" "$(nix_uid_for_core "$i")"
done
echo ""
}
create_build_group() {
local primary_group_id
task "Setting up the build group $NIX_BUILD_GROUP_NAME"
if ! /usr/bin/dscl . -read "/Groups/$NIX_BUILD_GROUP_NAME" > /dev/null 2>&1; then
_sudo "Create the Nix build group, $NIX_BUILD_GROUP_NAME" \
/usr/sbin/dseditgroup -o create \
-r "Nix build group for nix-daemon" \
-i "$NIX_BUILD_GROUP_ID" \
"$NIX_BUILD_GROUP_NAME" >&2
row " Created" "Yes"
else
primary_group_id=$(dsclattr "/Groups/$NIX_BUILD_GROUP_NAME" "PrimaryGroupID")
if [ "$primary_group_id" -ne "$NIX_BUILD_GROUP_ID" ]; then
failure <<EOF
It seems the build group $NIX_BUILD_GROUP_NAME already exists, but
with the UID $primary_group_id. This script can't really handle
that right now, so I'm going to give up.
You can fix this by editing this script and changing the
NIX_BUILD_GROUP_ID variable near the top to from $NIX_BUILD_GROUP_ID
to $primary_group_id and re-run.
EOF
else
row " Exists" "Yes"
fi
fi
}
create_build_user_for_core() {
local coreid
local username
local uid
coreid="$1"
username=$(nix_user_for_core "$coreid")
uid=$(nix_uid_for_core "$coreid")
dsclpath="/Users/$username"
task "Setting up the build user $username"
if ! /usr/bin/dscl . -read "$dsclpath" > /dev/null 2>&1; then
_sudo "Creating the Nix build user, $username" \
/usr/bin/dscl . create "$dsclpath" \
UniqueID "${uid}"
row " Created" "Yes"
else
actual_uid=$(dsclattr "$dsclpath" "UniqueID")
if [ "$actual_uid" -ne "$uid" ]; then
failure <<EOF
It seems the build user $username already exists, but with the UID
with the UID $actual_uid. This script can't really handle that right
now, so I'm going to give up.
If you already created the users and you know they start from
$actual_uid and go up from there, you can edit this script and change
NIX_FIRST_BUILD_UID near the top of the file to $actual_uid and try
again.
EOF
else
row " Exists" "Yes"
fi
fi
if [ "$(dsclattr "$dsclpath" "IsHidden")" = "1" ]; then
row " IsHidden" "Yes"
else
_sudo "in order to make $username a hidden user" \
/usr/bin/dscl . -create "$dsclpath" "IsHidden" "1"
row " IsHidden" "Yes"
fi
if [ "$(dsclattr "$dsclpath" "NFSHomeDirectory")" = "/var/empty" ]; then
row " NFSHomeDirectory" "/var/empty"
else
_sudo "in order to give $username a safe home directory" \
/usr/bin/dscl . -create "$dsclpath" "NFSHomeDirectory" "/var/empty"
row " NFSHomeDirectory" "/var/empty"
fi
if [ "$(dsclattr "$dsclpath" "RealName")" = "Nix build user $coreid" ]; then
row " RealName" "Nix build user $coreid"
else
_sudo "in order to give $username a useful name" \
/usr/bin/dscl . -create "$dsclpath" "RealName" "Nix build user $coreid"
row " RealName" "Nix build user $coreid"
fi
if [ "$(dsclattr "$dsclpath" "UserShell")" = "/sbin/nologin" ]; then
row " Logins Disabled" "Yes"
else
_sudo "in order to prevent $username from logging in" \
/usr/bin/dscl . -create "$dsclpath" "UserShell" "/sbin/nologin"
row " Logins Disabled" "Yes"
fi
if dseditgroup -o checkmember -m "$username" "$NIX_BUILD_GROUP_NAME" > /dev/null 2>&1 ; then
row " Member of $NIX_BUILD_GROUP_NAME" "Yes"
else
_sudo "Add $username to the $NIX_BUILD_GROUP_NAME group"\
/usr/sbin/dseditgroup -o edit -t user \
-a "$username" "$NIX_BUILD_GROUP_NAME"
row " Member of $NIX_BUILD_GROUP_NAME" "Yes"
fi
if [ "$(dsclattr "$dsclpath" "PrimaryGroupID")" = "$NIX_BUILD_GROUP_ID" ]; then
row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
else
_sudo "to let the nix daemon use this user for builds (this might seem redundant, but there are two concepts of group membership)" \
/usr/bin/dscl . -create "$dsclpath" "PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
fi
}
create_build_users() {
for i in $(seq 1 "$NIX_USER_COUNT"); do
create_build_user_for_core "$i"
done
}
create_directories() {
_sudo "to make the basic directory structure of Nix (part 1)" \
mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool}
_sudo "to make the basic directory structure of Nix (part 2)" \
mkdir -pv -m 1777 /nix/var/nix/{gcroots,profiles}/per-user
_sudo "to make the basic directory structure of Nix (part 3)" \
mkdir -pv -m 1775 /nix/store
_sudo "to make the basic directory structure of Nix (part 4)" \
chgrp "$NIX_BUILD_GROUP_NAME" /nix/store
_sudo "to set up the root user's profile (part 1)" \
mkdir -pv -m 0755 /nix/var/nix/profiles/per-user/root
_sudo "to set up the root user's profile (part 2)" \
mkdir -pv -m 0700 "$ROOT_HOME/.nix-defexpr"
_sudo "to place the default nix daemon configuration (part 1)" \
mkdir -pv -m 0555 /etc/nix
}
place_channel_configuration() {
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
_sudo "to set up the default system channel (part 1)" \
install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
}
welcome_to_nix() {
ok "Welcome to the Multi-User Nix Installation"
cat <<EOF
This installation tool will set up your computer with the Nix package
manager. This will happen in a few stages:
1. Make sure your computer doesn't already have Nix. If it does, I
will show you instructions on how to clean up your old one.
2. Show you what we are going to install and where. Then we will ask
if you are ready to continue.
3. Create the system users and groups that the Nix daemon uses to run
builds.
4. Perform the basic installation of the Nix files daemon.
5. Configure your shell to import special Nix Profile files, so you
can use Nix.
6. Start the Nix daemon.
EOF
if ui_confirm "Would you like to see a more detailed list of what we will do?"; then
cat <<EOF
We will:
- make sure your computer doesn't already have Nix files
(if it does, I will tell you how to clean them up.)
- create local users (see the list above for the users we'll make)
- create a local group ($NIX_BUILD_GROUP_NAME)
- install Nix in to $NIX_ROOT
- create a configuration file in /etc/nix
- set up the "default profile" by creating some Nix-related files in
$ROOT_HOME
EOF
for profile_target in "${PROFILE_TARGETS[@]}"; do
if [ -e "$profile_target" ]; then
cat <<EOF
- back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX
- update $profile_target to include some Nix configuration
EOF
fi
done
cat <<EOF
- load and start a LaunchDaemon (at $PLIST_DEST) for nix-daemon
EOF
if ! ui_confirm "Ready to continue?"; then
failure <<EOF
Okay, maybe you would like to talk to the team.
EOF
fi
fi
}
chat_about_sudo() {
header "let's talk about sudo"
if headless; then
cat <<EOF
This script is going to call sudo a lot. Normally, it would show you
exactly what commands it is running and why. However, the script is
run in a headless fashion, like this:
$ curl https://nixos.org/nix/install | sh
or maybe in a CI pipeline. Because of that, we're going to skip the
verbose output in the interest of brevity.
If you would like to
see the output, try like this:
$ curl -o install-nix https://nixos.org/nix/install
$ sh ./install-nix
EOF
return 0
fi
cat <<EOF
This script is going to call sudo a lot. Every time we do, it'll
output exactly what it'll do, and why.
Just like this:
EOF
__sudo "to demonstrate how our sudo prompts look" \
echo "this is a sudo prompt"
cat <<EOF
This might look scary, but everything can be undone by running just a
few commands. We used to ask you to confirm each time sudo ran, but it
was too many times. Instead, I'll just ask you this one time:
EOF
if ui_confirm "Can we use sudo?"; then
ok "Yay! Thanks! Let's get going!"
else
failure <<EOF
That is okay, but we can't install.
EOF
fi
}
install_from_extracted_nix() {
(
cd "$EXTRACTED_NIX_PATH"
_sudo "to copy the basic Nix files to the new store at $NIX_ROOT/store" \
rsync -rlpt "$(pwd)/store/" "$NIX_ROOT/store/"
if [ -d "$NIX_INSTALLED_NIX" ]; then
echo " Alright! We have our first nix at $NIX_INSTALLED_NIX"
else
failure <<EOF
Something went wrong, and I didn't find Nix installed at
$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
echo " Just finished getting the nix database ready."
)
}
shell_source_lines() {
cat <<EOF
# Nix
if [ -e '$PROFILE_NIX_FILE' ]; then
. '$PROFILE_NIX_FILE'
fi
# End Nix
EOF
}
configure_shell_profile() {
for profile_target in "${PROFILE_TARGETS[@]}"; do
if [ -e "$profile_target" ]; then
_sudo "to back up your current $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX" \
cp "$profile_target" "$profile_target$PROFILE_BACKUP_SUFFIX"
shell_source_lines \
| _sudo "extend your $profile_target with nix-daemon settings" \
tee -a "$profile_target"
fi
done
}
setup_default_profile() {
_sudo "to installing a bootstrapping Nix in to the default Profile" \
HOME=$ROOT_HOME "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_NIX"
_sudo "to installing a bootstrapping SSL certificate just for Nix in to the default Profile" \
HOME=$ROOT_HOME "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_CACERT"
_sudo "to update the default channel in the default profile" \
HOME=$ROOT_HOME NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt "$NIX_INSTALLED_NIX/bin/nix-channel" --update nixpkgs
}
place_nix_configuration() {
cat <<EOF > "$SCRATCH/nix.conf"
build-users-group = $NIX_BUILD_GROUP_NAME
build-max-jobs = $NIX_USER_COUNT
build-cores = 1
build-use-sandbox = false
binary-caches = https://cache.nixos.org/
trusted-binary-caches =
binary-cache-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
signed-binary-caches = *
trusted-users = root
allowed-users = *
EOF
_sudo "to place the default nix daemon configuration (part 2)" \
install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf
}
configure_nix_daemon_plist() {
_sudo "to set up the nix-daemon as a LaunchDaemon" \
ln -sfn "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST"
_sudo "to load the LaunchDaemon plist for nix-daemon" \
launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
_sudo "to start the nix-daemon" \
launchctl start org.nixos.nix-daemon
}
main() {
welcome_to_nix
chat_about_sudo
if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" = "" ]; then
validate_starting_assumptions
fi
setup_report
if ! ui_confirm "Ready to continue?"; then
ok "Alright, no changes have been made :)"
contactme
trap finish_cleanup EXIT
exit 1
fi
create_build_group
create_build_users
create_directories
place_channel_configuration
install_from_extracted_nix
configure_shell_profile
set +eu
. /etc/profile
set -eu
setup_default_profile
place_nix_configuration
configure_nix_daemon_plist
trap finish_success EXIT
}
main

View File

@ -7,7 +7,7 @@ self="$(dirname "$0")"
nix="@nix@"
cacert="@cacert@"
if ! [ -e $self/.reginfo ]; then
if ! [ -e "$self/.reginfo" ]; then
echo "$0: incomplete installer (.reginfo is missing)" >&2
exit 1
fi
@ -17,6 +17,23 @@ if [ -z "$USER" ]; then
exit 1
fi
if [ -z "$HOME" ]; then
echo "$0: \$HOME is not set" >&2
exit 1
fi
# macOS support for 10.10 or higher
if [[ "$(uname -s)" = "Darwin" ]]; then
if [[ $(($(sw_vers -productVersion | cut -d '.' -f 2))) -lt 10 ]]; then
echo "$0: macOS $(sw_vers -productVersion) is not supported, upgrade to 10.10 or higher"
exit 1
fi
printf '\e[1;31mSwitching to the Multi-User Darwin Installer\e[0m\n'
exec "$self/install-darwin-multi-user"
exit 0
fi
if [ "$(id -u)" -eq 0 ]; then
printf '\e[1;31mwarning: installing Nix as root is not supported by this script!\e[0m\n'
fi
@ -41,7 +58,7 @@ mkdir -p $dest/store
echo -n "copying Nix to $dest/store..." >&2
for i in $(cd $self/store >/dev/null && echo *); do
for i in $(cd "$self/store" >/dev/null && echo ./*); do
echo -n "." >&2
i_tmp="$dest/store/$i.$$"
if [ -e "$i_tmp" ]; then
@ -55,47 +72,47 @@ done
echo "" >&2
echo "initialising Nix database..." >&2
if ! $nix/bin/nix-store --init; then
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
if ! "$nix/bin/nix-store" --load-db < "$self/.reginfo"; then
echo "$0: unable to register valid paths" >&2
exit 1
fi
. $nix/etc/profile.d/nix.sh
. "$nix/etc/profile.d/nix.sh"
if ! $nix/bin/nix-env -i "$nix"; then
if ! "$nix/bin/nix-env" -i "$nix"; then
echo "$0: unable to install Nix into your default profile" >&2
exit 1
fi
# Install an SSL certificate bundle.
if [ -z "$SSL_CERT_FILE" -o ! -f "$SSL_CERT_FILE" ]; then
$nix/bin/nix-env -i "$cacert"
export SSL_CERT_FILE="$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt"
if [ -z "$NIX_SSL_CERT_FILE" ] || [ ! -f "$NIX_SSL_CERT_FILE" ]; then
"$nix/bin/nix-env" -i "$cacert"
export NIX_SSL_CERT_FILE="$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt"
fi
# Subscribe the user to the Nixpkgs channel and fetch it.
if ! $nix/bin/nix-channel --list | grep -q "^nixpkgs "; then
$nix/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
if ! "$nix/bin/nix-channel" --list | grep -q "^nixpkgs "; then
"$nix/bin/nix-channel" --add https://nixos.org/channels/nixpkgs-unstable
fi
if [ -z "$_NIX_INSTALLER_TEST" ]; then
$nix/bin/nix-channel --update nixpkgs
"$nix/bin/nix-channel" --update nixpkgs
fi
# Make the shell source nix.sh during login.
p=$NIX_LINK/etc/profile.d/nix.sh
p="$NIX_LINK/etc/profile.d/nix.sh"
added=
for i in .bash_profile .bash_login .profile; do
fn="$HOME/$i"
if [ -e "$fn" ]; then
if [ -w "$fn" ]; then
if ! grep -q "$p" "$fn"; then
echo "modifying $fn..." >&2
echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> $fn
echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
fi
added=1
break

View File

@ -20,6 +20,7 @@ nix_noinst_scripts := \
$(d)/resolve-system-dependencies.pl \
$(d)/nix-http-export.cgi \
$(d)/nix-profile.sh \
$(d)/nix-profile-daemon.sh \
$(d)/nix-reduce-build \
$(nix_substituters)
@ -28,6 +29,7 @@ noinst-scripts += $(nix_noinst_scripts)
profiledir = $(sysconfdir)/profile.d
$(eval $(call install-file-as, $(d)/nix-profile.sh, $(profiledir)/nix.sh, 0644))
$(eval $(call install-file-as, $(d)/nix-profile-daemon.sh, $(profiledir)/nix-daemon.sh, 0644))
$(eval $(call install-program-in, $(d)/find-runtime-roots.pl, $(libexecdir)/nix))
$(eval $(call install-program-in, $(d)/build-remote.pl, $(libexecdir)/nix))
$(eval $(call install-program-in, $(d)/resolve-system-dependencies.pl, $(libexecdir)/nix))

View File

@ -11,13 +11,16 @@ use Cwd;
binmode STDERR, ":encoding(utf8)";
Nix::Config::readConfig;
my $dryRun = 0;
my $verbose = 0;
my $runEnv = $0 =~ /nix-shell$/;
my $pure = 0;
my $fromArgs = 0;
my $packages = 0;
my $interactive = 1;
# Same condition as bash uses for interactive shells
my $interactive = -t STDIN && -t STDERR;
my @instArgs = ();
my @buildArgs = ();
@ -57,7 +60,7 @@ if ($runEnv && defined $ARGV[0] && $ARGV[0] !~ /nix-shell/) {
while (<SCRIPT>) {
chomp;
if (/^\#\!\s*nix-shell (.*)$/) {
push @ARGV, shellwords(/ /, $1);
push @ARGV, shellwords($1);
}
}
}
@ -223,7 +226,7 @@ die "$0: -p and -E are mutually exclusive\n" if $packages && $fromAr
if ($packages) {
push @instArgs, "--expr";
@exprs = (
'with import <nixpkgs> { }; runCommand "shell" { buildInputs = [ '
'with import <nixpkgs> { }; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ '
. (join " ", map { "($_)" } @exprs) . ']; } ""');
} elsif (!$fromArgs) {
@exprs = ("shell.nix") if scalar @exprs == 0 && $runEnv && -e "shell.nix";
@ -278,6 +281,9 @@ foreach my $expr (@exprs) {
}
$ENV{'NIX_BUILD_TOP'} = $ENV{'TMPDIR'} = $ENV{'TEMPDIR'} = $ENV{'TMP'} = $ENV{'TEMP'} = $tmp;
$ENV{'NIX_STORE'} = $Nix::Config::storeDir;
if (defined $Nix::Config::config{"build-cores"}) {
$ENV{'NIX_BUILD_CORES'} = $Nix::Config::config{"build-cores"};
}
$ENV{$_} = $drv->{env}->{$_} foreach keys %{$drv->{env}};
# Run a shell using the derivation's environment. For
@ -288,7 +294,6 @@ foreach my $expr (@exprs) {
writeFile(
$rcfile,
"rm -rf '$tmpDir'; " .
'unset BASH_ENV; ' .
'[ -n "$PS1" ] && [ -e ~/.bashrc ] && source ~/.bashrc; ' .
($pure ? '' : 'p=$PATH; ' ) .
'dontAddDisableDepTrack=1; ' .
@ -302,7 +307,6 @@ foreach my $expr (@exprs) {
'shopt -u nullglob; ' .
'unset TZ; ' . (defined $ENV{'TZ'} ? "export TZ='${ENV{'TZ'}}'; " : '') .
$envCommand);
$ENV{BASH_ENV} = $rcfile;
my @args = ($ENV{NIX_BUILD_SHELL} // "bash");
push @args, "--rcfile" if $interactive;
push @args, $rcfile;

View File

@ -32,6 +32,9 @@ mkpath(dirname $profile, 0, 0755);
my %channels;
my $netrcFile = $Nix::Config::config{"netrc-file"} //
"$Nix::Config::confDir/netrc";
# Reads the list of channels.
sub readChannels {
@ -104,7 +107,7 @@ sub update {
# definition from a consistent location if the redirect changes mid-download.
my $tmpdir = tempdir( CLEANUP => 1 );
my $filename;
($url, $filename) = `cd $tmpdir && $Nix::Config::curl --silent --write-out '%{url_effective}\n%{filename_effective}' -L '$url' -O`;
($url, $filename) = `cd $tmpdir && $Nix::Config::curl $Nix::Config::curlCaFlag --netrc-file $netrcFile --netrc-optional --silent --write-out '%{url_effective}\n%{filename_effective}' -L '$url' -O`;
chomp $url;
die "$0: unable to check $url\n" if $? != 0;
@ -131,7 +134,7 @@ sub update {
my $extraAttrs = "";
if ($ret != 0) {
# Check if the channel advertises a binary cache.
my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
my $binaryCacheURL = `$Nix::Config::curl $Nix::Config::curlCaFlag --netrc-file $netrcFile --netrc-optional --silent '$url'/binary-cache-url`;
my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
if ($? == 0 && $binaryCacheURL ne "") {
$extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
@ -151,7 +154,7 @@ sub update {
# Download the channel tarball.
my $fullURL = "$url/nixexprs.tar.xz";
system("$Nix::Config::curl --fail --silent --head '$fullURL' > /dev/null") == 0 or
system("$Nix::Config::curl $Nix::Config::curlCaFlag --netrc-file $netrcFile --netrc-optional --fail --silent --head '$fullURL' > /dev/null") == 0 or
$fullURL = "$url/nixexprs.tar.bz2";
print STDERR "downloading Nix expressions from $fullURL...\n";
(my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`;

View File

@ -7,8 +7,10 @@ use Nix::Config;
use Nix::Store;
use Nix::CopyClosure;
use List::Util qw(sum);
use IO::Handle;
binmode STDERR, ":encoding(utf8)";
STDERR->autoflush(1);
if (scalar @ARGV < 1) {
print STDERR <<EOF

View File

@ -0,0 +1,54 @@
# Only execute this file once per shell.
if [ -n "$__ETC_PROFILE_NIX_SOURCED" ]; then return; fi
__ETC_PROFILE_NIX_SOURCED=1
# Set up secure multi-user builds: non-root users build through the
# Nix daemon.
if [ "$USER" != root -o ! -w @localstatedir@/nix/db ]; then
export NIX_REMOTE=daemon
fi
export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER"
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
# Set up the per-user profile.
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
if ! test -O "$NIX_USER_PROFILE_DIR"; then
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2
fi
if test -w $HOME; then
if ! test -L $HOME/.nix-profile; then
if test "$USER" != root; then
ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile
else
# Root installs in the system-wide profile by default.
ln -s @localstatedir@/nix/profiles/default $HOME/.nix-profile
fi
fi
# Subscribe the root user to the NixOS channel by default.
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels
fi
# Create the per-user garbage collector roots directory.
NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER
mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR
if ! test -O "$NIX_USER_GCROOTS_DIR"; then
echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2
fi
# Set up a default Nix expression from which to install stuff.
if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then
rm -f $HOME/.nix-defexpr
mkdir -p $HOME/.nix-defexpr
if [ "$USER" != root ]; then
ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root
fi
fi
fi
export NIX_SSL_CERT_FILE="@localstatedir@/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
export NIX_PATH="@localstatedir@/nix/profiles/per-user/root/channels"
export PATH="$HOME/.nix-profile/bin:$HOME/.nix-profile/sbin:$HOME/.nix-profile/lib/kde4/libexec:@localstatedir@/nix/profiles/default/bin:@localstatedir@/nix/profiles/default/sbin:@localstatedir@/nix/profiles/default/lib/kde4/libexec:$PATH"

View File

@ -20,16 +20,18 @@ if [ -n "$HOME" ]; then
# channel.
export NIX_PATH=${NIX_PATH:+$NIX_PATH:}nixpkgs=$HOME/.nix-defexpr/channels/nixpkgs
# Set $SSL_CERT_FILE so that Nixpkgs applications like curl work.
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed
export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem
elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS
export SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS
export SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
elif [ -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" ]; then # fall back to cacert in Nix profile
export SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt"
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt"
elif [ -e "$NIX_LINK/etc/ca-bundle.crt" ]; then # old cacert in Nix profile
export SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
fi
fi

View File

@ -8,7 +8,8 @@ use Nix::Manifest;
binmode STDERR, ":encoding(utf8)";
my $manifestDir = $Nix::Config::manifestDir;
my $netrcFile = $Nix::Config::config{"netrc-file"} //
"$Nix::Config::confDir/netrc";
# Prevent access problems in shared-stored installations.
umask 0022;
@ -51,7 +52,7 @@ sub processURL {
my $origUrl = $ENV{'NIX_ORIG_URL'} || $url;
# First see if a bzipped manifest is available.
if (system("$Nix::Config::curl --fail --silent --location --head '$url'.bz2 > /dev/null") == 0) {
if (system("$Nix::Config::curl $Nix::Config::curlCaFlag --netrc-file $netrcFile --netrc-optional --fail --silent --location --head '$url'.bz2 > /dev/null") == 0) {
print "fetching list of Nix archives at $url.bz2...\n";
$manifest = downloadFile "$url.bz2";
}

View File

@ -273,7 +273,7 @@ EvalState::EvalState(const Strings & _searchPath)
/* Initialise the Nix expression search path. */
Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
for (auto & i : _searchPath) addToSearchPath(i, true);
for (auto & i : _searchPath) addToSearchPath(i);
for (auto & i : paths) addToSearchPath(i);
addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs");
@ -296,11 +296,15 @@ Path EvalState::checkSourcePath(const Path & path_)
if (!restricted) return path_;
/* Resolve symlinks. */
debug(format("checking access to %s") % path_);
Path path = canonPath(path_, true);
for (auto & i : searchPath)
if (path == i.second || isInDir(path, i.second))
for (auto & i : searchPath) {
auto r = resolveSearchPathElem(i);
if (!r.first) continue;
if (path == r.second || isInDir(path, r.second))
return path;
}
/* To support import-from-derivation, allow access to anything in
the store. FIXME: only allow access to paths that have been
@ -946,11 +950,18 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
if (fun.type == tAttrs) {
auto found = fun.attrs->find(sFunctor);
if (found != fun.attrs->end()) {
/* fun may be allocated on the stack of the calling function,
* but for functors we may keep a reference, so heap-allocate
* a copy and use that instead.
*/
auto & fun2 = *allocValue();
fun2 = fun;
/* !!! Should we use the attr pos here? */
forceValue(*found->value, pos);
Value * v2 = allocValue();
callFunction(*found->value, fun, *v2, pos);
forceValue(*v2, pos);
return callFunction(*v2, arg, v, pos);
Value v2;
callFunction(*found->value, fun2, v2, pos);
forceValue(v2, pos);
return callFunction(v2, arg, v, pos);
}
}

View File

@ -55,7 +55,8 @@ typedef std::map<Path, Path> SrcToStore;
std::ostream & operator << (std::ostream & str, const Value & v);
typedef list<std::pair<string, Path> > SearchPath;
typedef std::pair<std::string, std::string> SearchPathElem;
typedef std::list<SearchPathElem> SearchPath;
/* Initialise the Boehm GC, if applicable. */
@ -95,12 +96,14 @@ private:
SearchPath searchPath;
std::map<std::string, std::pair<bool, std::string>> searchPathResolved;
public:
EvalState(const Strings & _searchPath);
~EvalState();
void addToSearchPath(const string & s, bool warn = false);
void addToSearchPath(const string & s);
Path checkSourcePath(const Path & path);
@ -122,6 +125,9 @@ public:
Path findFile(const string & path);
Path findFile(SearchPath & searchPath, const string & path, const Pos & pos = noPos);
/* If the specified search path element is a URI, download it. */
std::pair<bool, std::string> resolveSearchPathElem(const SearchPathElem & elem);
/* Evaluate an expression to normal form, storing the result in
value `v'. */
void eval(Expr * e, Value & v);

View File

@ -30,7 +30,7 @@ string DrvInfo::queryOutPath()
}
DrvInfo::Outputs DrvInfo::queryOutputs()
DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
{
if (outputs.empty()) {
/* Get the outputs list. */
@ -55,7 +55,23 @@ DrvInfo::Outputs DrvInfo::queryOutputs()
} else
outputs["out"] = queryOutPath();
}
return outputs;
if (!onlyOutputsToInstall || !attrs)
return outputs;
/* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
const Value * outTI = queryMeta("outputsToInstall");
if (!outTI) return outputs;
const auto errMsg = Error("this derivation has bad meta.outputsToInstall");
/* ^ this shows during `nix-env -i` right under the bad derivation */
if (!outTI->isList()) throw errMsg;
Outputs result;
for (auto i = outTI->listElems(); i != outTI->listElems() + outTI->listSize(); ++i) {
if ((*i)->type != tString) throw errMsg;
auto out = outputs.find((*i)->string.s);
if (out == outputs.end()) throw errMsg;
result.insert(*out);
}
return result;
}
@ -177,8 +193,8 @@ typedef set<Bindings *> Done;
/* Evaluate value `v'. If it evaluates to a set of type `derivation',
then put information about it in `drvs' (unless it's already in
`doneExprs'). The result boolean indicates whether it makes sense
then put information about it in `drvs' (unless it's already in `done').
The result boolean indicates whether it makes sense
for the caller to recursively search for derivations in `v'. */
static bool getDerivation(EvalState & state, Value & v,
const string & attrPath, DrvInfos & drvs, Done & done,

View File

@ -42,7 +42,8 @@ public:
string queryDrvPath();
string queryOutPath();
string queryOutputName();
Outputs queryOutputs();
/** Return the list of outputs. The "outputs to install" are determined by `mesa.outputsToInstall`. */
Outputs queryOutputs(bool onlyOutputsToInstall = false);
StringSet queryMetaNames();
Value * queryMeta(const string & name);

View File

@ -14,7 +14,7 @@ static void skipWhitespace(const char * & s)
#if HAVE_BOEHMGC
typedef std::vector<Value *, gc_allocator<Value *> > ValueVector;
typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<Value *> > ValueMap;
typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> > > ValueMap;
#else
typedef std::vector<Value *> ValueVector;
typedef std::map<Symbol, Value *> ValueMap;

View File

@ -8,6 +8,7 @@
%x STRING
%x IND_STRING
%x INSIDE_DOLLAR_CURLY
%{
@ -93,6 +94,8 @@ URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~
%%
<INITIAL,INSIDE_DOLLAR_CURLY>{
if { return IF; }
then { return THEN; }
@ -124,29 +127,42 @@ or { return OR_KW; }
return INT;
}
\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
\{ { PUSH_STATE(INITIAL); return '{'; }
\} { POP_STATE(); return '}'; }
\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
}
\" { PUSH_STATE(STRING); return '"'; }
\} { return '}'; }
<INSIDE_DOLLAR_CURLY>\} { POP_STATE(); return '}'; }
\{ { return '{'; }
<INSIDE_DOLLAR_CURLY>\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return '{'; }
<INITIAL,INSIDE_DOLLAR_CURLY>\" {
PUSH_STATE(STRING); return '"';
}
<STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)*\$/\" |
<STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)+ {
/* It is impossible to match strings ending with '$' with one
regex because trailing contexts are only valid at the end
of a rule. (A sane but undocumented limitation.) */
yylval->e = unescapeStr(data->symbols, yytext);
return STR;
}
<STRING>\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
<STRING>\" { POP_STATE(); return '"'; }
<STRING>. return yytext[0]; /* just in case: shouldn't be reached */
/* It is impossible to match strings ending with '$' with one
regex because trailing contexts are only valid at the end
of a rule. (A sane but undocumented limitation.) */
yylval->e = unescapeStr(data->symbols, yytext);
return STR;
}
<STRING>\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
<STRING>\" { POP_STATE(); return '"'; }
<STRING>\$|\\|\$\\ {
/* This can only occur when we reach EOF, otherwise the above
(...|\$[^\{\"\\]|\\.|\$\\.)+ would have triggered.
This is technically invalid, but we leave the problem to the
parser who fails with exact location. */
return STR;
}
\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
<INITIAL,INSIDE_DOLLAR_CURLY>\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
yylval->e = new ExprIndStr(yytext);
return IND_STR;
}
<IND_STRING>\'\'\$ {
<IND_STRING>\'\'\$ |
<IND_STRING>\$ {
yylval->e = new ExprIndStr("$");
return IND_STR;
}
@ -158,13 +174,14 @@ or { return OR_KW; }
yylval->e = unescapeStr(data->symbols, yytext + 2);
return IND_STR;
}
<IND_STRING>\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
<IND_STRING>\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
<IND_STRING>\'\' { POP_STATE(); return IND_STRING_CLOSE; }
<IND_STRING>\' {
yylval->e = new ExprIndStr("'");
return IND_STR;
}
<IND_STRING>. return yytext[0]; /* just in case: shouldn't be reached */
<INITIAL,INSIDE_DOLLAR_CURLY>{
{PATH} { yylval->path = strdup(yytext); return PATH; }
{HPATH} { yylval->path = strdup(yytext); return HPATH; }
@ -177,6 +194,7 @@ or { return OR_KW; }
. return yytext[0];
}
%%

View File

@ -590,7 +590,7 @@ Expr * EvalState::parseExprFromString(const string & s, const Path & basePath)
}
void EvalState::addToSearchPath(const string & s, bool warn)
void EvalState::addToSearchPath(const string & s)
{
size_t pos = s.find('=');
string prefix;
@ -602,16 +602,7 @@ void EvalState::addToSearchPath(const string & s, bool warn)
path = string(s, pos + 1);
}
if (isUri(path))
path = downloadFileCached(path, true);
path = absPath(path);
if (pathExists(path)) {
debug(format("adding path %1% to the search path") % path);
/* Resolve symlinks in the path to support restricted mode. */
searchPath.push_back(std::pair<string, Path>(prefix, canonPath(path, true)));
} else if (warn)
printMsg(lvlError, format("warning: Nix search path entry %1% does not exist, ignoring") % path);
searchPath.emplace_back(prefix, path);
}
@ -624,17 +615,19 @@ Path EvalState::findFile(const string & path)
Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos & pos)
{
for (auto & i : searchPath) {
assert(!isUri(i.second));
Path res;
std::string suffix;
if (i.first.empty())
res = i.second + "/" + path;
suffix = "/" + path;
else {
if (path.compare(0, i.first.size(), i.first) != 0 ||
(path.size() > i.first.size() && path[i.first.size()] != '/'))
auto s = i.first.size();
if (path.compare(0, s, i.first) != 0 ||
(path.size() > s && path[s] != '/'))
continue;
res = i.second +
(path.size() == i.first.size() ? "" : "/" + string(path, i.first.size()));
suffix = path.size() == s ? "" : "/" + string(path, s);
}
auto r = resolveSearchPathElem(i);
if (!r.first) continue;
Path res = r.second + suffix;
if (pathExists(res)) return canonPath(res);
}
format f = format(
@ -645,4 +638,35 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos
}
std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathElem & elem)
{
auto i = searchPathResolved.find(elem.second);
if (i != searchPathResolved.end()) return i->second;
std::pair<bool, std::string> res;
if (isUri(elem.second)) {
try {
res = { true, downloadFileCached(elem.second, true) };
} catch (DownloadError & e) {
printMsg(lvlError, format("warning: Nix search path entry %1% cannot be downloaded, ignoring") % elem.second);
res = { false, "" };
}
} else {
auto path = absPath(elem.second);
if (pathExists(path))
res = { true, path };
else {
printMsg(lvlError, format("warning: Nix search path entry %1% does not exist, ignoring") % elem.second);
res = { false, "" };
}
}
debug(format("resolved search path element %s to %s") % elem.second % res.second);
searchPathResolved[elem.second] = res;
return res;
}
}

View File

@ -176,6 +176,45 @@ static void prim_importNative(EvalState & state, const Pos & pos, Value * * args
}
/* Execute a program and parse its output */
static void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceList(*args[0], pos);
auto elems = args[0]->listElems();
auto count = args[0]->listSize();
if (count == 0) {
throw EvalError(format("at least one argument to 'exec' required, at %1%") % pos);
}
PathSet context;
auto program = state.coerceToString(pos, *elems[0], context, false, false);
Strings commandArgs;
for (unsigned int i = 1; i < args[0]->listSize(); ++i) {
commandArgs.emplace_back(state.coerceToString(pos, *elems[i], context, false, false));
}
try {
realiseContext(context);
} catch (InvalidPathError & e) {
throw EvalError(format("cannot execute %1%, since path %2% is not valid, at %3%")
% program % e.path % pos);
}
auto output = runProgram(program, true, commandArgs);
Expr * parsed;
try {
parsed = state.parseExprFromString(output, pos.file);
} catch (Error & e) {
e.addPrefix(format("While parsing the output from %1%, at %2%\n") % program % pos);
throw;
}
try {
state.eval(parsed, v);
} catch (Error & e) {
e.addPrefix(format("While evaluating the output from %1%, at %2%\n") % program % pos);
throw;
}
}
/* Return a string representing the type of the expression. */
static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
@ -765,7 +804,6 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
SearchPath searchPath;
PathSet context;
for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
Value & v2(*args[0]->listElems()[n]);
state.forceAttrs(v2, pos);
@ -778,21 +816,23 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
i = v2.attrs->find(state.symbols.create("path"));
if (i == v2.attrs->end())
throw EvalError(format("attribute path missing, at %1%") % pos);
string path = state.coerceToPath(pos, *i->value, context);
searchPath.push_back(std::pair<string, Path>(prefix, state.checkSourcePath(path)));
PathSet context;
string path = state.coerceToString(pos, *i->value, context, false, false);
try {
realiseContext(context);
} catch (InvalidPathError & e) {
throw EvalError(format("cannot find %1%, since path %2% is not valid, at %3%")
% path % e.path % pos);
}
searchPath.emplace_back(prefix, path);
}
string path = state.forceStringNoCtx(*args[1], pos);
try {
realiseContext(context);
} catch (InvalidPathError & e) {
throw EvalError(format("cannot find %1%, since path %2% is not valid, at %3%")
% path % e.path % pos);
}
mkPath(v, state.findFile(searchPath, path, pos).c_str());
mkPath(v, state.checkSourcePath(state.findFile(searchPath, path, pos)).c_str());
}
/* Read a directory (without . or ..) */
@ -1657,6 +1697,7 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
if (state.restricted) throw Error(format("%1% is not allowed in restricted mode") % who);
string url;
string name;
state.forceValue(*args[0]);
@ -1665,9 +1706,11 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
state.forceAttrs(*args[0], pos);
for (auto & attr : *args[0]->attrs) {
string name(attr.name);
if (name == "url")
string n(attr.name);
if (n == "url")
url = state.forceStringNoCtx(*attr.value, *attr.pos);
else if (n == "name")
name = state.forceStringNoCtx(*attr.value, *attr.pos);
else
throw EvalError(format("unsupported argument %1% to %2%, at %3%") % attr.name % who % attr.pos);
}
@ -1678,7 +1721,7 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
} else
url = state.forceStringNoCtx(*args[0], pos);
Path res = downloadFileCached(url, unpack);
Path res = downloadFileCached(url, unpack, name);
mkString(v, res, PathSet({res}));
}
@ -1746,8 +1789,10 @@ void EvalState::createBaseEnv()
mkApp(v, *baseEnv.values[baseEnvDispl - 1], *v2);
forceValue(v);
addConstant("import", v);
if (settings.enableImportNative)
if (settings.enableNativeCode) {
addPrimOp("__importNative", 2, prim_importNative);
addPrimOp("__exec", 1, prim_exec);
}
addPrimOp("__typeOf", 1, prim_typeOf);
addPrimOp("isNull", 1, prim_isNull);
addPrimOp("__isFunction", 1, prim_isFunction);

View File

@ -162,6 +162,14 @@ void initNix()
if (char *pack = getenv("_NIX_OPTIONS"))
settings.unpack(pack);
/* On macOS, don't use the per-session TMPDIR (as set e.g. by
sshd). This breaks build users because they don't have access
to the TMPDIR, in particular in nix-store --serve. */
#if __APPLE__
if (getuid() == 0 && hasPrefix(getEnv("TMPDIR"), "/var/folders/"))
unsetenv("TMPDIR");
#endif
}

View File

@ -20,9 +20,9 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
bool haveSP = true;
char * sp = 0;
#if defined(__x86_64__) && defined(REG_RSP)
sp = (char *) ((ucontext *) ctx)->uc_mcontext.gregs[REG_RSP];
sp = (char *) ((ucontext_t *) ctx)->uc_mcontext.gregs[REG_RSP];
#elif defined(REG_ESP)
sp = (char *) ((ucontext *) ctx)->uc_mcontext.gregs[REG_ESP];
sp = (char *) ((ucontext_t *) ctx)->uc_mcontext.gregs[REG_ESP];
#else
haveSP = false;
#endif

View File

@ -9,6 +9,7 @@
#include "archive.hh"
#include "affinity.hh"
#include "builtins.hh"
#include "finally.hh"
#include <algorithm>
#include <iostream>
@ -54,6 +55,7 @@
#include <sys/mount.h>
#include <sys/syscall.h>
#include <linux/fs.h>
#include <seccomp.h>
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
#endif
@ -761,7 +763,14 @@ private:
GoalState state;
/* Stuff we need to pass to initChild(). */
typedef map<Path, Path> DirsInChroot; // maps target path to source path
struct ChrootPath {
Path source;
bool optional;
ChrootPath(Path source = "", bool optional = false)
: source(source), optional(optional)
{ }
};
typedef map<Path, ChrootPath> DirsInChroot; // maps target path to source path
DirsInChroot dirsInChroot;
typedef map<string, string> Environment;
Environment env;
@ -769,7 +778,6 @@ private:
#if __APPLE__
typedef string SandboxProfile;
SandboxProfile additionalSandboxProfile;
AutoDelete autoDelSandbox;
#endif
/* Hash rewriting. */
@ -1063,8 +1071,10 @@ void DerivationGoal::outputsSubstituted()
{
trace("all outputs substituted (maybe)");
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback)
throw Error(format("some substitutes for the outputs of derivation %1% failed (usually happens due to networking issues); try --fallback to build derivation from source ") % drvPath);
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) {
done(BuildResult::TransientFailure, (format("some substitutes for the outputs of derivation %1% failed (usually happens due to networking issues); try --fallback to build derivation from source ") % drvPath).str());
return;
}
/* If the substitutes form an incomplete closure, then we should
build the dependencies of this derivation, but after that, we
@ -1884,7 +1894,13 @@ void DerivationGoal::startBuilder()
/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
if (settings.buildUsersGroup != "") {
#if defined(__linux__) || defined(__APPLE__)
buildUser.acquire();
#else
/* Don't know how to block the creation of setuid/setgid
binaries on this platform. */
throw Error("build users are not supported on this platform for security reasons");
#endif
assert(buildUser.getUID() != 0);
assert(buildUser.getGID() != 0);
@ -1922,20 +1938,30 @@ void DerivationGoal::startBuilder()
dirsInChroot.clear();
for (auto & i : dirs) {
for (auto i : dirs) {
if (i.empty()) continue;
bool optional = false;
if (i[i.size() - 1] == '?') {
optional = true;
i.pop_back();
}
size_t p = i.find('=');
if (p == string::npos)
dirsInChroot[i] = i;
dirsInChroot[i] = {i, optional};
else
dirsInChroot[string(i, 0, p)] = string(i, p + 1);
dirsInChroot[string(i, 0, p)] = {string(i, p + 1), optional};
}
dirsInChroot[tmpDirInSandbox] = tmpDir;
/* Add the closure of store paths to the chroot. */
PathSet closure;
for (auto & i : dirsInChroot)
if (isInStore(i.second))
computeFSClosure(worker.store, toStorePath(i.second), closure);
try {
if (isInStore(i.second.source))
computeFSClosure(worker.store, toStorePath(i.second.source), closure);
} catch (Error & e) {
throw Error(format("while processing build-sandbox-paths: %s") % e.what());
}
for (auto & i : closure)
dirsInChroot[i] = i;
@ -2094,7 +2120,7 @@ void DerivationGoal::startBuilder()
}
}
if (settings.preBuildHook != "") {
if (useChroot && settings.preBuildHook != "" && dynamic_cast<Derivation *>(drv.get())) {
printMsg(lvlChatty, format("executing pre-build hook %1%")
% settings.preBuildHook);
auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
@ -2232,6 +2258,55 @@ void DerivationGoal::startBuilder()
}
void setupSeccomp()
{
#if __linux__
scmp_filter_ctx ctx;
if (!(ctx = seccomp_init(SCMP_ACT_ALLOW)))
throw SysError("unable to initialize seccomp mode 2");
Finally cleanup([&]() {
seccomp_release(ctx);
});
if (settings.thisSystem == "x86_64-linux" &&
seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0)
throw SysError("unable to add 32-bit seccomp architecture");
if (settings.thisSystem == "x86_64-linux" &&
seccomp_arch_add(ctx, SCMP_ARCH_X32) != 0)
throw SysError("unable to add X32 seccomp architecture");
/* Prevent builders from creating setuid/setgid binaries. */
for (int perm : { S_ISUID, S_ISGID }) {
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 1,
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
throw SysError("unable to add seccomp rule");
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 1,
SCMP_A1(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
throw SysError("unable to add seccomp rule");
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1,
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
throw SysError("unable to add seccomp rule");
}
/* Prevent builders from creating EAs or ACLs. Not all filesystems
support these, and they're not allowed in the Nix store because
they're not representable in the NAR serialisation. */
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(setxattr), 0) != 0 ||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(lsetxattr), 0) != 0 ||
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
throw SysError("unable to add seccomp rule");
if (seccomp_load(ctx) != 0)
throw SysError("unable to load seccomp BPF program");
#endif
}
void DerivationGoal::runChild()
{
/* Warning: in the child we should absolutely not make any SQLite
@ -2243,6 +2318,12 @@ void DerivationGoal::runChild()
commonChildInit(builderOut);
try {
setupSeccomp();
} catch (...) {
if (buildUser.enabled()) throw;
}
#if __linux__
if (useChroot) {
@ -2326,12 +2407,16 @@ void DerivationGoal::runChild()
environment. */
for (auto & i : dirsInChroot) {
struct stat st;
Path source = i.second;
Path source = i.second.source;
Path target = chrootRootDir + i.first;
if (source == "/proc") continue; // backwards compatibility
debug(format("bind mounting %1% to %2%") % source % target);
if (stat(source.c_str(), &st) == -1)
throw SysError(format("getting attributes of path %1%") % source);
if (stat(source.c_str(), &st) == -1) {
if (i.second.optional && errno == ENOENT)
continue;
else
throw SysError(format("getting attributes of path %1%") % source);
}
if (S_ISDIR(st.st_mode))
createDirs(target);
else {
@ -2456,46 +2541,100 @@ void DerivationGoal::runChild()
const char *builder = "invalid";
string sandboxProfile;
if (isBuiltin(*drv)) {
;
}
#if __APPLE__
} else if (useChroot) {
/* Lots and lots and lots of file functions freak out if they can't stat their full ancestry */
PathSet ancestry;
else if (getEnv("_NIX_TEST_NO_SANDBOX") == "") {
/* This has to appear before import statements. */
std::string sandboxProfile = "(version 1)\n";
/* We build the ancestry before adding all inputPaths to the store because we know they'll
all have the same parents (the store), and there might be lots of inputs. This isn't
particularly efficient... I doubt it'll be a bottleneck in practice */
for (auto & i : dirsInChroot) {
Path cur = i.first;
while (cur.compare("/") != 0) {
cur = dirOf(cur);
ancestry.insert(cur);
if (useChroot) {
/* Lots and lots and lots of file functions freak out if they can't stat their full ancestry */
PathSet ancestry;
/* We build the ancestry before adding all inputPaths to the store because we know they'll
all have the same parents (the store), and there might be lots of inputs. This isn't
particularly efficient... I doubt it'll be a bottleneck in practice */
for (auto & i : dirsInChroot) {
Path cur = i.first;
while (cur.compare("/") != 0) {
cur = dirOf(cur);
ancestry.insert(cur);
}
}
}
/* And we want the store in there regardless of how empty dirsInChroot. We include the innermost
path component this time, since it's typically /nix/store and we care about that. */
Path cur = settings.nixStore;
while (cur.compare("/") != 0) {
ancestry.insert(cur);
cur = dirOf(cur);
}
/* And we want the store in there regardless of how empty dirsInChroot. We include the innermost
path component this time, since it's typically /nix/store and we care about that. */
Path cur = settings.nixStore;
while (cur.compare("/") != 0) {
ancestry.insert(cur);
cur = dirOf(cur);
}
/* Add all our input paths to the chroot */
for (auto & i : inputPaths)
dirsInChroot[i] = i;
/* Add all our input paths to the chroot */
for (auto & i : inputPaths)
dirsInChroot[i] = i;
/* This has to appear before import statements */
sandboxProfile += "(version 1)\n";
/* Violations will go to the syslog if you set this. Unfortunately the destination does not appear to be configurable */
if (settings.get("darwin-log-sandbox-violations", false)) {
sandboxProfile += "(deny default)\n";
} else {
sandboxProfile += "(deny default (with no-log))\n";
}
/* Violations will go to the syslog if you set this. Unfortunately the destination does not appear to be configurable */
if (settings.get("darwin-log-sandbox-violations", false)) {
sandboxProfile += "(deny default)\n";
} else {
sandboxProfile += "(deny default (with no-log))\n";
}
/* Our rwx outputs */
sandboxProfile += "(allow file-read* file-write* process-exec\n";
for (auto & i : missingPaths) {
sandboxProfile += (format("\t(subpath \"%1%\")\n") % i.c_str()).str();
}
sandboxProfile += ")\n";
/* Our inputs (transitive dependencies and any impurities computed above)
without file-write* allowed, access() incorrectly returns EPERM
*/
sandboxProfile += "(allow file-read* file-write* process-exec\n";
for (auto & i : dirsInChroot) {
if (i.first != i.second.source)
throw Error(format(
"can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin")
% i.first % i.second.source);
string path = i.first;
struct stat st;
if (lstat(path.c_str(), &st)) {
if (i.second.optional && errno == ENOENT)
continue;
throw SysError(format("getting attributes of path %1%") % path);
}
if (S_ISDIR(st.st_mode))
sandboxProfile += (format("\t(subpath \"%1%\")\n") % path).str();
else
sandboxProfile += (format("\t(literal \"%1%\")\n") % path).str();
}
sandboxProfile += ")\n";
/* Allow file-read* on full directory hierarchy to self. Allows realpath() */
sandboxProfile += "(allow file-read*\n";
for (auto & i : ancestry) {
sandboxProfile += (format("\t(literal \"%1%\")\n") % i.c_str()).str();
}
sandboxProfile += ")\n";
sandboxProfile += additionalSandboxProfile;
} else
sandboxProfile += "(allow default)\n";
sandboxProfile += "(deny file-write-setugid)\n";
debug("Generated sandbox profile:");
debug(sandboxProfile);
Path sandboxFile = tmpDir + "/.sandbox.sb";
writeFile(sandboxFile, sandboxProfile);
/* 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. */
@ -2504,53 +2643,6 @@ void DerivationGoal::runChild()
/* They don't like trailing slashes on subpath directives */
if (globalTmpDir.back() == '/') globalTmpDir.pop_back();
/* Our rwx outputs */
sandboxProfile += "(allow file-read* file-write* process-exec\n";
for (auto & i : missingPaths) {
sandboxProfile += (format("\t(subpath \"%1%\")\n") % i.c_str()).str();
}
sandboxProfile += ")\n";
/* Our inputs (transitive dependencies and any impurities computed above)
without file-write* allowed, access() incorrectly returns EPERM
*/
sandboxProfile += "(allow file-read* file-write* process-exec\n";
for (auto & i : dirsInChroot) {
if (i.first != i.second)
throw Error(format(
"can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin")
% i.first % i.second);
string path = i.first;
struct stat st;
if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path %1%") % path);
if (S_ISDIR(st.st_mode))
sandboxProfile += (format("\t(subpath \"%1%\")\n") % path).str();
else
sandboxProfile += (format("\t(literal \"%1%\")\n") % path).str();
}
sandboxProfile += ")\n";
/* Allow file-read* on full directory hierarchy to self. Allows realpath() */
sandboxProfile += "(allow file-read*\n";
for (auto & i : ancestry) {
sandboxProfile += (format("\t(literal \"%1%\")\n") % i.c_str()).str();
}
sandboxProfile += ")\n";
sandboxProfile += additionalSandboxProfile;
debug("Generated sandbox profile:");
debug(sandboxProfile);
Path sandboxFile = drvPath + ".sb";
if (pathExists(sandboxFile)) deletePath(sandboxFile);
autoDelSandbox.reset(sandboxFile, false);
writeFile(sandboxFile, sandboxProfile);
builder = "/usr/bin/sandbox-exec";
args.push_back("sandbox-exec");
args.push_back("-f");
@ -2558,8 +2650,9 @@ void DerivationGoal::runChild()
args.push_back("-D");
args.push_back("_GLOBAL_TMP_DIR=" + globalTmpDir);
args.push_back(drv->builder);
}
#endif
} else {
else {
builder = drv->builder.c_str();
string builderBasename = baseNameOf(drv->builder);
args.push_back(builderBasename);

View File

@ -3,6 +3,7 @@
#include "globals.hh"
#include "hash.hh"
#include "store-api.hh"
#include "pathlocks.hh"
#include <curl/curl.h>
@ -114,6 +115,10 @@ struct Curl
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback_);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void *) &curl);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
/* If no file exist in the specified path, curl continues to work
* anyway as if netrc support was disabled. */
curl_easy_setopt(curl, CURLOPT_NETRC_FILE, settings.netrcFile.c_str());
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
}
~Curl()
@ -129,7 +134,8 @@ struct Curl
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
if (options.verifyTLS)
curl_easy_setopt(curl, CURLOPT_CAINFO, getEnv("SSL_CERT_FILE", "/etc/ssl/certs/ca-certificates.crt").c_str());
curl_easy_setopt(curl, CURLOPT_CAINFO,
getEnv("NIX_SSL_CERT_FILE", getEnv("SSL_CERT_FILE", "/etc/ssl/certs/ca-certificates.crt")).c_str());
else {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
@ -188,7 +194,7 @@ DownloadResult downloadFile(string url, const DownloadOptions & options)
}
Path downloadFileCached(const string & url, bool unpack)
Path downloadFileCached(const string & url, bool unpack, string name)
{
Path cacheDir = getEnv("XDG_CACHE_HOME", getEnv("HOME", "") + "/.cache") + "/nix/tarballs";
createDirs(cacheDir);
@ -198,6 +204,8 @@ Path downloadFileCached(const string & url, bool unpack)
Path dataFile = cacheDir + "/" + urlHash + ".info";
Path fileLink = cacheDir + "/" + urlHash + "-file";
PathLocks lock({fileLink}, (format("waiting for lock on %1%...") % fileLink).str());
Path storePath;
string expectedETag;
@ -223,9 +231,10 @@ Path downloadFileCached(const string & url, bool unpack)
storePath = "";
}
string name;
auto p = url.rfind('/');
if (p != string::npos) name = string(url, p + 1);
if (name == "") {
auto p = url.rfind('/');
if (p != string::npos) name = string(url, p + 1);
}
if (!skip) {
@ -249,6 +258,7 @@ Path downloadFileCached(const string & url, bool unpack)
if (unpack) {
Path unpackedLink = cacheDir + "/" + baseNameOf(storePath) + "-unpacked";
PathLocks lock({unpackedLink}, (format("waiting for lock on %1%...") % unpackedLink).str());
Path unpackedStorePath;
if (pathExists(unpackedLink)) {
unpackedStorePath = readLink(unpackedLink);

View File

@ -20,7 +20,7 @@ struct DownloadResult
DownloadResult downloadFile(string url, const DownloadOptions & options);
Path downloadFileCached(const string & url, bool unpack);
Path downloadFileCached(const string & url, bool unpack, string name = "");
MakeError(DownloadError, Error)

View File

@ -61,7 +61,8 @@ Settings::Settings()
envKeepDerivations = false;
lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
showTrace = false;
enableImportNative = false;
enableNativeCode = false;
netrcFile = (format("%1%/%2%") % nixConfDir % "netrc").str();
}
@ -185,9 +186,12 @@ void Settings::update()
_get(sshSubstituterHosts, "ssh-substituter-hosts");
_get(useSshSubstituter, "use-ssh-substituter");
_get(logServers, "log-servers");
_get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
_get(enableNativeCode, "allow-unsafe-native-code-during-evaluation");
_get(useCaseHack, "use-case-hack");
_get(preBuildHook, "pre-build-hook");
_get(keepGoing, "keep-going");
_get(keepFailed, "keep-failed");
_get(netrcFile, "netrc-file");
string subs = getEnv("NIX_SUBSTITUTERS", "default");
if (subs == "default") {

View File

@ -203,13 +203,17 @@ struct Settings {
/* A list of URL prefixes that can return Nix build logs. */
Strings logServers;
/* Whether the importNative primop should be enabled */
bool enableImportNative;
/* Whether native-code enabling primops should be enabled */
bool enableNativeCode;
/* The hook to run just before a build to set derivation-specific
build settings */
Path preBuildHook;
/* Path to the netrc file used to obtain usernames/passwords for
downloads. */
Path netrcFile;
private:
SettingsMap settings, overrides;

View File

@ -28,6 +28,7 @@
#include <sys/statvfs.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
#include <sys/xattr.h>
#endif
#include <sqlite3.h>
@ -225,6 +226,7 @@ LocalStore::LocalStore(bool reserveSpace)
schemaPath = settings.nixDBPath + "/schema";
if (settings.readOnlyMode) {
curSchema = getSchema();
openDB(false);
return;
}
@ -309,6 +311,7 @@ LocalStore::LocalStore(bool reserveSpace)
} catch (SysError & e) {
if (e.errNo != EACCES) throw;
settings.readOnlyMode = true;
curSchema = getSchema();
openDB(false);
return;
}
@ -320,8 +323,8 @@ LocalStore::LocalStore(bool reserveSpace)
/* Check the current database schema and if necessary do an
upgrade. */
int curSchema = getSchema();
if (curSchema > nixSchemaVersion)
curSchema = getSchema();
if (curSchema >= 0x100)
throw Error(format("current Nix store schema is version %1%, but I only support %2%")
% curSchema % nixSchemaVersion);
@ -470,16 +473,18 @@ void LocalStore::openDB(bool create)
"select path from Refs join ValidPaths on referrer = id where reference = (select id from ValidPaths where path = ?);");
stmtInvalidatePath.create(db,
"delete from ValidPaths where path = ?;");
stmtRegisterFailedPath.create(db,
"insert or ignore into FailedPaths (path, time) values (?, ?);");
stmtHasPathFailed.create(db,
"select time from FailedPaths where path = ?;");
stmtQueryFailedPaths.create(db,
"select path from FailedPaths;");
// If the path is a derivation, then clear its outputs.
stmtClearFailedPath.create(db,
"delete from FailedPaths where ?1 = '*' or path = ?1 "
"or path in (select d.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where v.path = ?1);");
if (curSchema < 9) {
stmtRegisterFailedPath.create(db,
"insert or ignore into FailedPaths (path, time) values (?, ?);");
stmtHasPathFailed.create(db,
"select time from FailedPaths where path = ?;");
stmtQueryFailedPaths.create(db,
"select path from FailedPaths;");
// If the path is a derivation, then clear its outputs.
stmtClearFailedPath.create(db,
"delete from FailedPaths where ?1 = '*' or path = ?1 "
"or path in (select d.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where v.path = ?1);");
}
stmtAddDerivationOutput.create(db,
"insert or replace into DerivationOutputs (drv, id, path) values (?, ?, ?);");
stmtQueryValidDerivers.create(db,
@ -566,6 +571,16 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
{
checkInterrupt();
#if __APPLE__
/* Remove flags, in particular UF_IMMUTABLE which would prevent
the file from being garbage-collected. FIXME: Use
setattrlist() to remove other attributes as well. */
if (lchflags(path.c_str(), 0)) {
if (errno != ENOTSUP)
throw SysError(format("clearing flags of path %1%") % path);
}
#endif
struct stat st;
if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path %1%") % path);
@ -574,6 +589,29 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
throw Error(format("file %1% has an unsupported type") % path);
#if __linux__
/* Remove extended attributes / ACLs. */
ssize_t eaSize = llistxattr(path.c_str(), nullptr, 0);
if (eaSize < 0) {
if (errno != ENOTSUP)
throw SysError(format("querying extended attributes of %s") % path);
} else if (eaSize > 0) {
std::vector<char> eaBuf(eaSize);
if ((eaSize = llistxattr(path.c_str(), eaBuf.data(), eaBuf.size())) < 0)
throw SysError(format("querying extended attributes of %s") % path);
for (auto & eaName: tokenizeString<Strings>(std::string(eaBuf.data(), eaSize), std::string("\000", 1))) {
/* Ignore SELinux security labels since these cannot be
removed even by root. */
if (eaName == "security.selinux") continue;
if (lremovexattr(path.c_str(), eaName.c_str()) == -1)
throw SysError(format("removing extended attribute %s from %s") % eaName % path);
}
}
#endif
/* Fail if the file is not owned by the build user. This prevents
us from messing up the ownership/permissions of files
hard-linked into the output (e.g. "ln /etc/shadow $out/foo").
@ -742,6 +780,7 @@ void LocalStore::addReference(unsigned long long referrer, unsigned long long re
void LocalStore::registerFailedPath(const Path & path)
{
if (curSchema >= 9) return;
retry_sqlite {
SQLiteStmtUse use(stmtRegisterFailedPath);
stmtRegisterFailedPath.bind(path);
@ -754,6 +793,7 @@ void LocalStore::registerFailedPath(const Path & path)
bool LocalStore::hasPathFailed(const Path & path)
{
if (curSchema >= 9) return false;
retry_sqlite {
SQLiteStmtUse use(stmtHasPathFailed);
stmtHasPathFailed.bind(path);
@ -767,6 +807,8 @@ bool LocalStore::hasPathFailed(const Path & path)
PathSet LocalStore::queryFailedPaths()
{
if (curSchema >= 9) return {};
retry_sqlite {
SQLiteStmtUse use(stmtQueryFailedPaths);
@ -788,6 +830,8 @@ PathSet LocalStore::queryFailedPaths()
void LocalStore::clearFailedPaths(const PathSet & paths)
{
if (curSchema >= 9) return;
retry_sqlite {
SQLiteTxn txn(db);

View File

@ -88,6 +88,8 @@ private:
Path linksDir;
int curSchema = 0;
public:
/* Initialise the local store, upgrading the schema if

View File

@ -14,6 +14,10 @@ ifeq ($(OS), SunOS)
libstore_LDFLAGS += -lsocket
endif
ifeq ($(OS), Linux)
libstore_LDFLAGS += -lseccomp
endif
libstore_CXXFLAGS = \
-DNIX_PREFIX=\"$(prefix)\" \
-DNIX_STORE_DIR=\"$(storedir)\" \

View File

@ -10,6 +10,7 @@
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <regex>
namespace nix {
@ -97,6 +98,19 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path %1%") % path);
#if __APPLE__
/* HFS/OS X has some undocumented security feature disabling hardlinking for
special files within .app dirs. *.app/Contents/PkgInfo and
*.app/Contents/Resources/\*.lproj seem to be the only paths affected. See
https://github.com/NixOS/nix/issues/1443 for more discussion. */
if (std::regex_search(path, std::regex("\\.app/Contents/PkgInfo$")) ||
std::regex_search(path, std::regex("\\.app/Contents/Resources/.+\\.lproj$"))) {
debug(format("%1% is not allowed to be linked in OS X") % path);
return;
}
#endif
if (S_ISDIR(st.st_mode)) {
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
for (auto & i : names)

14
src/libutil/finally.hh Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <functional>
/* A trivial class to run a function at the end of a scope. */
class Finally
{
private:
std::function<void()> fun;
public:
Finally(std::function<void()> fun) : fun(fun) { }
~Finally() { fun(); }
};

View File

@ -205,7 +205,7 @@ static void start(HashType ht, Ctx & ctx)
static void update(HashType ht, Ctx & ctx,
const unsigned char * bytes, unsigned int len)
const unsigned char * bytes, size_t len)
{
if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len);
else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len);

View File

@ -327,10 +327,11 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
bytesFreed += st.st_blocks * 512;
if (S_ISDIR(st.st_mode)) {
/* Make the directory writable. */
if (!(st.st_mode & S_IWUSR)) {
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
throw SysError(format("making %1% writable") % path);
/* Make the directory accessible. */
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
if ((st.st_mode & PERM_MASK) != PERM_MASK) {
if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1)
throw SysError(format("chmod %1%") % path);
}
for (auto & i : readDirectory(path))
@ -430,12 +431,21 @@ void createSymlink(const Path & target, const Path & link)
void replaceSymlink(const Path & target, const Path & link)
{
Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link));
for (unsigned int n = 0; true; n++) {
Path tmp = canonPath((format("%s/.%d_%s") % dirOf(link) % n % baseNameOf(link)).str());
createSymlink(target, tmp);
try {
createSymlink(target, tmp);
} catch (SysError & e) {
if (e.errNo == EEXIST) continue;
throw;
}
if (rename(tmp.c_str(), link.c_str()) != 0)
throw SysError(format("renaming %1% to %2%") % tmp % link);
if (rename(tmp.c_str(), link.c_str()) != 0)
throw SysError(format("renaming %1% to %2%") % tmp % link);
break;
}
}
@ -1170,6 +1180,12 @@ bool statusOk(int status)
}
bool hasPrefix(const string & s, const string & suffix)
{
return s.compare(0, suffix.size(), suffix) == 0;
}
bool hasSuffix(const string & s, const string & suffix)
{
return s.size() >= suffix.size() && string(s, s.size() - suffix.size()) == suffix;

View File

@ -365,6 +365,10 @@ template<class N> bool string2Int(const string & s, N & n)
}
/* Return true iff `s' starts with `prefix'. */
bool hasPrefix(const string & s, const string & prefix);
/* Return true iff `s' ends in `suffix'. */
bool hasSuffix(const string & s, const string & suffix);

View File

@ -63,8 +63,8 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
if (drvPath != "")
mkString(*state.allocAttr(v, state.sDrvPath), i.queryDrvPath());
// Copy each output.
DrvInfo::Outputs outputs = i.queryOutputs();
// Copy each output meant for installation.
DrvInfo::Outputs outputs = i.queryOutputs(true);
Value & vOutputs = *state.allocAttr(v, state.sOutputs);
state.mkList(vOutputs, outputs.size());
unsigned int m = 0;

View File

@ -16,6 +16,10 @@ export NIX_DB_DIR=$TEST_ROOT/db
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
export _NIX_TEST_SHARED=$TEST_ROOT/shared
if [[ -n $NIX_STORE ]]; then
export _NIX_TEST_NO_SANDBOX=1
fi
export _NIX_IN_TEST=$TEST_ROOT/shared
export NIX_REMOTE=$NIX_REMOTE_
export PATH=@bindir@:$PATH

96
tests/install-darwin.sh Executable file
View File

@ -0,0 +1,96 @@
#!/bin/sh
set -eux
cleanup() {
PLIST="/Library/LaunchDaemons/org.nixos.nix-daemon.plist"
if sudo launchctl list | grep -q nix-daemon; then
sudo launchctl unload "$PLIST"
fi
if [ -f "$PLIST" ]; then
sudo rm /Library/LaunchDaemons/org.nixos.nix-daemon.plist
fi
profiles=(/etc/profile /etc/bashrc /etc/zshrc)
for profile in "${profiles[@]}"; do
if [ -f "${profile}.backup-before-nix" ]; then
sudo mv "${profile}.backup-before-nix" "${profile}"
fi
done
for file in ~/.bash_profile ~/.bash_login ~/.profile ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
if [ -e "$file" ]; then
cat "$file" | grep -v nix-profile > "$file.next"
mv "$file.next" "$file"
fi
done
for i in $(seq 1 $(sysctl -n hw.ncpu)); do
sudo /usr/bin/dscl . -delete "/Users/nixbld$i" || true
done
sudo /usr/bin/dscl . -delete "/Groups/nixbld" || true
sudo rm -rf /etc/nix \
/nix \
/var/root/.nix-profile /var/root/.nix-defexpr /var/root/.nix-channels \
"$USER/.nix-profile" "$USER/.nix-defexpr" "$USER/.nix-channels"
}
verify() {
set +e
output=$(echo "nix-shell -p bash --run 'echo toow | rev'" | bash -l)
set -e
test "$output" = "woot"
}
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
rm -rf "$scratch"
}
trap finish EXIT
# First setup Nix
cleanup
curl -o install https://nixos.org/nix/install
yes | bash ./install
verify
(
set +e
(
echo "cd $(pwd)"
echo nix-build ./release.nix -A binaryTarball.x86_64-darwin
) | bash -l
set -e
cp ./result/nix-*.tar.bz2 $scratch/nix.tar.bz2
)
(
cd $scratch
tar -xf ./nix.tar.bz2
cd nix-*
set -eux
cleanup
yes | ./install
verify
cleanup
echo -n "" | ./install
verify
cleanup
sudo mkdir -p /nix/store
sudo touch /nix/store/.silly-hint
echo -n "" | ALLOW_PREEXISTING_INSTALLATION=true ./install
verify
test -e /nix/store/.silly-hint
cleanup
)

View File

@ -1 +1 @@
"This is an indented multi-line string\nliteral. An amount of whitespace at\nthe start of each line matching the minimum\nindentation of all lines in the string\nliteral together will be removed. Thus,\nin this case four spaces will be\nstripped from each line, even though\n THIS LINE is indented six spaces.\n\nAlso, empty lines don't count in the\ndetermination of the indentation level (the\nprevious empty line has indentation 0, but\nit doesn't matter).\nIf the string starts with whitespace\n followed by a newline, it's stripped, but\n that's not the case here. Two spaces are\n stripped because of the \" \" at the start. \nThis line is indented\na bit further.\nAnti-quotations, like so, are\nalso allowed.\n The \\ is not special here.\n' can be followed by any character except another ', e.g. 'x'.\nLikewise for $, e.g. $$ or $varName.\nBut ' followed by ' is special, as is $ followed by {.\nIf you want them, use anti-quotations: '', ${.\n Tabs are not interpreted as whitespace (since we can't guess\n what tab settings are intended), so don't use them.\n\tThis line starts with a space and a tab, so only one\n space will be stripped from each line.\nAlso note that if the last line (just before the closing ' ')\nconsists only of whitespace, it's ignored. But here there is\nsome non-whitespace stuff, so the line isn't removed. \nThis shows a hacky way to preserve an empty line after the start.\nBut there's no reason to do so: you could just repeat the empty\nline.\n Similarly you can force an indentation level,\n in this case to 2 spaces. This works because the anti-quote\n is significant (not whitespace).\nstart on network-interfaces\n\nstart script\n\n rm -f /var/run/opengl-driver\n ln -sf 123 /var/run/opengl-driver\n\n rm -f /var/log/slim.log\n \nend script\n\nenv SLIM_CFGFILE=abc\nenv SLIM_THEMESDIR=def\nenv FONTCONFIG_FILE=/etc/fonts/fonts.conf \t\t\t\t# !!! cleanup\nenv XKB_BINDIR=foo/bin \t\t\t\t# Needed for the Xkb extension.\nenv LD_LIBRARY_PATH=libX11/lib:libXext/lib:/usr/lib/ # related to xorg-sys-opengl - needed to load libglx for (AI)GLX support (for compiz)\n\nenv XORG_DRI_DRIVER_PATH=nvidiaDrivers/X11R6/lib/modules/drivers/ \n\nexec slim/bin/slim\nEscaping of ' followed by ': ''\nEscaping of $ followed by {: ${\nAnd finally to interpret \\n etc. as in a string: \n, \r, \t.\nfoo\n'bla'\nbar\n"
"This is an indented multi-line string\nliteral. An amount of whitespace at\nthe start of each line matching the minimum\nindentation of all lines in the string\nliteral together will be removed. Thus,\nin this case four spaces will be\nstripped from each line, even though\n THIS LINE is indented six spaces.\n\nAlso, empty lines don't count in the\ndetermination of the indentation level (the\nprevious empty line has indentation 0, but\nit doesn't matter).\nIf the string starts with whitespace\n followed by a newline, it's stripped, but\n that's not the case here. Two spaces are\n stripped because of the \" \" at the start. \nThis line is indented\na bit further.\nAnti-quotations, like so, are\nalso allowed.\n The \\ is not special here.\n' can be followed by any character except another ', e.g. 'x'.\nLikewise for $, e.g. $$ or $varName.\nBut ' followed by ' is special, as is $ followed by {.\nIf you want them, use anti-quotations: '', ${.\n Tabs are not interpreted as whitespace (since we can't guess\n what tab settings are intended), so don't use them.\n\tThis line starts with a space and a tab, so only one\n space will be stripped from each line.\nAlso note that if the last line (just before the closing ' ')\nconsists only of whitespace, it's ignored. But here there is\nsome non-whitespace stuff, so the line isn't removed. \nThis shows a hacky way to preserve an empty line after the start.\nBut there's no reason to do so: you could just repeat the empty\nline.\n Similarly you can force an indentation level,\n in this case to 2 spaces. This works because the anti-quote\n is significant (not whitespace).\nstart on network-interfaces\n\nstart script\n\n rm -f /var/run/opengl-driver\n ln -sf 123 /var/run/opengl-driver\n\n rm -f /var/log/slim.log\n \nend script\n\nenv SLIM_CFGFILE=abc\nenv SLIM_THEMESDIR=def\nenv FONTCONFIG_FILE=/etc/fonts/fonts.conf \t\t\t\t# !!! cleanup\nenv XKB_BINDIR=foo/bin \t\t\t\t# Needed for the Xkb extension.\nenv LD_LIBRARY_PATH=libX11/lib:libXext/lib:/usr/lib/ # related to xorg-sys-opengl - needed to load libglx for (AI)GLX support (for compiz)\n\nenv XORG_DRI_DRIVER_PATH=nvidiaDrivers/X11R6/lib/modules/drivers/ \n\nexec slim/bin/slim\nEscaping of ' followed by ': ''\nEscaping of $ followed by {: ${\nAnd finally to interpret \\n etc. as in a string: \n, \r, \t.\nfoo\n'bla'\nbar\ncut -d $'\\t' -f 1\nending dollar $$\n"

View File

@ -117,4 +117,12 @@ let
bar
'';
in s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15
# Regression test: accept $'.
s16 = ''
cut -d $'\t' -f 1
'';
# Accept dollars at end of strings
s17 = ''ending dollar $'' + ''$'' + "\n";
in s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15 + s16 + s17

2
tests/lexer.nix Normal file
View File

@ -0,0 +1,2 @@
let const = a: "const"; in
''${ const { x = "q"; }}''

3
tests/lexer.sh Normal file
View File

@ -0,0 +1,3 @@
source common.sh
nix-instantiate --eval ./lexer.nix

View File

@ -11,7 +11,7 @@ nix_tests = \
binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
multiple-outputs.sh import-derivation.sh fetchurl.sh optimise-store.sh \
binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh \
check-reqs.sh pass-as-file.sh tarball.sh
check-reqs.sh pass-as-file.sh tarball.sh lexer.sh
# parallel.sh
install-tests += $(foreach x, $(nix_tests), tests/$(x))

View File

@ -4,7 +4,7 @@
with import <nixpkgs/nixos/lib/testing.nix> { inherit system; };
makeTest (let pkgA = pkgs.aterm; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
nodes =
{ client =

View File

@ -14,7 +14,7 @@ let
{ services.openssh.enable = true;
virtualisation.writableStore = true;
nix.package = nix;
nix.useChroot = true;
nix.useSandbox = true;
};
# Trivial Nix expression to build remotely.

108
tests/setuid.nix Normal file
View File

@ -0,0 +1,108 @@
# Verify that Linux builds cannot create setuid or setgid binaries.
{ system, nix }:
with import <nixpkgs/nixos/lib/testing.nix> { inherit system; };
makeTest {
machine =
{ config, lib, pkgs, ... }:
{ virtualisation.writableStore = true;
nix.package = nix;
nix.binaryCaches = [ ];
nix.nixPath = [ "nixpkgs=${lib.cleanSource pkgs.path}" ];
virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
};
testScript = { nodes }:
''
startAll;
# Copying to /tmp should succeed.
$machine->succeed('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
# Creating a setuid binary should fail.
$machine->fail('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
chmod 4755 /tmp/id
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
# Creating a setgid binary should fail.
$machine->fail('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
chmod 2755 /tmp/id
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
# The checks should also work on 32-bit binaries.
$machine->fail('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> { system = "i686-linux"; }; runCommand "foo" {} "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
chmod 2755 /tmp/id
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
# The tests above use fchmodat(). Test chmod() as well.
$machine->succeed('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
perl -e \"chmod 0666, qw(/tmp/id) or die\"
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 666 ]]');
$machine->succeed("rm /tmp/id");
$machine->fail('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
perl -e \"chmod 04755, qw(/tmp/id) or die\"
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
# And test fchmod().
$machine->succeed('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 01750, \\\$x or die\"
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 1750 ]]');
$machine->succeed("rm /tmp/id");
$machine->fail('nix-build --option build-use-sandbox false -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
mkdir -p $out
cp ${pkgs.coreutils}/bin/id /tmp/id
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 04777, \\\$x or die\"
")\' ');
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
$machine->succeed("rm /tmp/id");
'';
}

View File

@ -16,8 +16,14 @@ tarball=$TEST_ROOT/tarball.tar.xz
nix-env -f file://$tarball -qa --out-path | grep -q dependencies
nix-build file://$tarball
nix-build -o $TEST_ROOT/result file://$tarball
nix-build '<foo>' -I foo=file://$tarball
nix-build -o $TEST_ROOT/result '<foo>' -I foo=file://$tarball
nix-build -E "import (fetchTarball file://$tarball)"
nix-build -o $TEST_ROOT/result -E "import (fetchTarball file://$tarball)"
nix-instantiate --eval -E '1 + 2' -I fnord=file://no-such-tarball.tar.xz
nix-instantiate --eval -E 'with <fnord/xyzzy>; 1 + 2' -I fnord=file://no-such-tarball.tar.xz
(! nix-instantiate --eval -E '<fnord/xyzzy> 1' -I fnord=file://no-such-tarball.tar.xz)
nix-instantiate --eval -E '<fnord/config.nix>' -I fnord=file://no-such-tarball.tar.xz -I fnord=.

View File

@ -1 +1 @@
1.11.1
1.11.17