forked from lix-project/lix
Merge branch 'path-info' into ca-drv-exotic
This commit is contained in:
commit
938650700f
.github
.gitignore.versionMakefile.config.inboehmgc-coroutine-sp-fallback.diffconfigure.acdefault.nixdoc/manual
generate-builtins.nixgenerate-options.nixlocal.mk
docker.nixflake.lockflake.nixsrc
SUMMARY.md.in
advanced-topics
command-ref
contributing
expressions
advanced-attributes.mdbuiltins-prefix.mdexpression-syntax.mdlanguage-constructs.mdlanguage-operators.mdlanguage-values.mdsimple-building-testing.md
glossary.mdinstallation
building-source.mdinstalling-binary.mdinstalling-docker.mdinstalling-source.mdobtaining-source.mdprerequisites-source.mdsupported-platforms.md
introduction.mdpackage-management
quick-start.mdrelease-notes
maintainers
misc
mk
nix-rust
perl
scripts
check-hydra-status.shcreate-darwin-volume.shinstall-darwin-multi-user.shinstall-multi-user.shinstall-nix-from-closure.shinstall-systemd-multi-user.shinstall.inlocal.mknix-http-export.cgi.innix-profile-daemon.sh.innix-profile.sh.innix-reduce-build.inprepare-installer-for-github-actions
shell.nixsrc
build-remote
cpptoml
libcmd
libexpr
7
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
7
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
**Release Notes**
|
||||
Please include relevant [release notes](https://github.com/NixOS/nix/blob/master/doc/manual/src/release-notes/rl-next.md) as needed.
|
||||
|
||||
|
||||
**Testing**
|
||||
|
||||
If this issue is a regression or something that should block release, please consider including a test either in the [testsuite](https://github.com/NixOS/nix/tree/master/tests) or as a [hydraJob]( https://github.com/NixOS/nix/blob/master/flake.nix#L396) so that it can be part of the [automatic checks](https://hydra.nixos.org/jobset/nix/master).
|
26
.github/workflows/backport.yml
vendored
Normal file
26
.github/workflows/backport.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed, labeled]
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport Pull Request
|
||||
if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
# required to find all branches
|
||||
fetch-depth: 0
|
||||
- name: Create backport PRs
|
||||
# should be kept in sync with `version`
|
||||
uses: zeebe-io/backport-action@v0.0.7
|
||||
with:
|
||||
# Config README: https://github.com/zeebe-io/backport-action#backport-action
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
pull_description: |-
|
||||
Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.
|
||||
# should be kept in sync with `uses`
|
||||
version: v0.0.5
|
|
@ -1,20 +1,23 @@
|
|||
name: "Test"
|
||||
name: "CI"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
|
||||
tests:
|
||||
needs: [check_cachix]
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: cachix/install-nix-action@v14
|
||||
- uses: cachix/install-nix-action@v16
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- uses: cachix/cachix-action@v10
|
||||
if: needs.check_cachix.outputs.secret == 'true'
|
||||
|
@ -22,7 +25,8 @@ jobs:
|
|||
name: '${{ env.CACHIX_NAME }}'
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
- run: nix-build -A checks.$(nix-instantiate --eval -E '(builtins.currentSystem)')
|
||||
- run: nix --experimental-features 'nix-command flakes' flake check -L
|
||||
|
||||
check_cachix:
|
||||
name: Cachix secret present for installer tests
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -34,6 +38,7 @@ jobs:
|
|||
env:
|
||||
_CACHIX_SECRETS: ${{ secrets.CACHIX_SIGNING_KEY }}${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||
run: echo "::set-output name=secret::${{ env._CACHIX_SECRETS != '' }}"
|
||||
|
||||
installer:
|
||||
needs: [tests, check_cachix]
|
||||
if: github.event_name == 'push' && needs.check_cachix.outputs.secret == 'true'
|
||||
|
@ -41,11 +46,11 @@ jobs:
|
|||
outputs:
|
||||
installerURL: ${{ steps.prepare-installer.outputs.installerURL }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- uses: cachix/install-nix-action@v14
|
||||
- uses: cachix/install-nix-action@v16
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: '${{ env.CACHIX_NAME }}'
|
||||
|
@ -53,6 +58,7 @@ jobs:
|
|||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
- id: prepare-installer
|
||||
run: scripts/prepare-installer-for-github-actions
|
||||
|
||||
installer_test:
|
||||
needs: [installer, check_cachix]
|
||||
if: github.event_name == 'push' && needs.check_cachix.outputs.secret == 'true'
|
||||
|
@ -61,10 +67,42 @@ jobs:
|
|||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- uses: cachix/install-nix-action@v14
|
||||
- uses: cachix/install-nix-action@v16
|
||||
with:
|
||||
install_url: '${{needs.installer.outputs.installerURL}}'
|
||||
install_options: "--tarball-url-prefix https://${{ env.CACHIX_NAME }}.cachix.org/serve"
|
||||
- run: nix-instantiate -E 'builtins.currentTime' --eval
|
||||
|
||||
docker_push_image:
|
||||
needs: [check_cachix, tests]
|
||||
if: >-
|
||||
github.event_name == 'push' &&
|
||||
github.ref_name == 'master' &&
|
||||
needs.check_cachix.outputs.secret == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: cachix/install-nix-action@v16
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- run: echo NIX_VERSION="$(nix-instantiate --eval -E '(import ./default.nix).defaultPackage.${builtins.currentSystem}.version' | tr -d \")" >> $GITHUB_ENV
|
||||
- uses: cachix/cachix-action@v10
|
||||
if: needs.check_cachix.outputs.secret == 'true'
|
||||
with:
|
||||
name: '${{ env.CACHIX_NAME }}'
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
- run: nix --experimental-features 'nix-command flakes' build .#dockerImage -L
|
||||
- run: docker load -i ./result/image.tar.gz
|
||||
- run: docker tag nix:$NIX_VERSION nixos/nix:$NIX_VERSION
|
||||
- run: docker tag nix:$NIX_VERSION nixos/nix:master
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- run: docker push nixos/nix:$NIX_VERSION
|
||||
- run: docker push nixos/nix:master
|
16
.github/workflows/hydra_status.yml
vendored
Normal file
16
.github/workflows/hydra_status.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
name: Hydra status
|
||||
on:
|
||||
schedule:
|
||||
- cron: "12,42 * * * *"
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
check_hydra_status:
|
||||
name: Check Hydra status
|
||||
if: github.repository_owner == 'NixOS'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: bash scripts/check-hydra-status.sh
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -26,8 +26,6 @@ perl/Makefile.config
|
|||
|
||||
# /scripts/
|
||||
/scripts/nix-profile.sh
|
||||
/scripts/nix-reduce-build
|
||||
/scripts/nix-http-export.cgi
|
||||
/scripts/nix-profile-daemon.sh
|
||||
|
||||
# /src/libexpr/
|
||||
|
@ -122,3 +120,7 @@ GTAGS
|
|||
compile_commands.json
|
||||
|
||||
nix-rust/target
|
||||
|
||||
result
|
||||
|
||||
.vscode/
|
||||
|
|
|
@ -16,6 +16,7 @@ LDFLAGS = @LDFLAGS@
|
|||
LIBARCHIVE_LIBS = @LIBARCHIVE_LIBS@
|
||||
LIBBROTLI_LIBS = @LIBBROTLI_LIBS@
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
LOWDOWN_LIBS = @LOWDOWN_LIBS@
|
||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
||||
LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
|
||||
index 1cee6a0b..46c3acd9 100644
|
||||
index 4b2c429..1fb4c52 100644
|
||||
--- a/pthread_stop_world.c
|
||||
+++ b/pthread_stop_world.c
|
||||
@@ -674,6 +674,8 @@ GC_INNER void GC_push_all_stacks(void)
|
||||
@@ -673,6 +673,8 @@ GC_INNER void GC_push_all_stacks(void)
|
||||
struct GC_traced_stack_sect_s *traced_stack_sect;
|
||||
pthread_t self = pthread_self();
|
||||
word total_size = 0;
|
||||
|
@ -11,7 +11,7 @@ index 1cee6a0b..46c3acd9 100644
|
|||
|
||||
if (!EXPECT(GC_thr_initialized, TRUE))
|
||||
GC_thr_init();
|
||||
@@ -723,6 +725,28 @@ GC_INNER void GC_push_all_stacks(void)
|
||||
@@ -722,6 +724,31 @@ GC_INNER void GC_push_all_stacks(void)
|
||||
hi = p->altstack + p->altstack_size;
|
||||
/* FIXME: Need to scan the normal stack too, but how ? */
|
||||
/* FIXME: Assume stack grows down */
|
||||
|
@ -22,6 +22,9 @@ index 1cee6a0b..46c3acd9 100644
|
|||
+ if (pthread_attr_getstacksize(&pattr, &stack_limit)) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!");
|
||||
+ }
|
||||
+ if (pthread_attr_destroy(&pattr)) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_destroy failed!");
|
||||
+ }
|
||||
+ // When a thread goes into a coroutine, we lose its original sp until
|
||||
+ // control flow returns to the thread.
|
||||
+ // While in the coroutine, the sp points outside the thread stack,
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -188,17 +188,24 @@ PKG_CHECK_MODULES([EDITLINE], [libeditline], [CXXFLAGS="$EDITLINE_CFLAGS $CXXFLA
|
|||
[AC_MSG_ERROR([Nix requires libeditline; it was not found via pkg-config, but via its header, but required functions do not work. Maybe it is too old? >= 1.14 is required.])])
|
||||
])
|
||||
|
||||
# Look for libsodium, an optional dependency.
|
||||
# Look for libsodium.
|
||||
PKG_CHECK_MODULES([SODIUM], [libsodium], [CXXFLAGS="$SODIUM_CFLAGS $CXXFLAGS"])
|
||||
|
||||
# Look for libbrotli{enc,dec}.
|
||||
PKG_CHECK_MODULES([LIBBROTLI], [libbrotlienc libbrotlidec], [CXXFLAGS="$LIBBROTLI_CFLAGS $CXXFLAGS"])
|
||||
|
||||
# Look for libcpuid.
|
||||
have_libcpuid=
|
||||
if test "$machine_name" = "x86_64"; then
|
||||
PKG_CHECK_MODULES([LIBCPUID], [libcpuid], [CXXFLAGS="$LIBCPUID_CFLAGS $CXXFLAGS"])
|
||||
have_libcpuid=1
|
||||
AC_DEFINE([HAVE_LIBCPUID], [1], [Use libcpuid])
|
||||
AC_ARG_ENABLE([cpuid],
|
||||
AS_HELP_STRING([--disable-cpuid], [Do not determine microarchitecture levels with libcpuid (relevant to x86_64 only)]))
|
||||
if test "x$enable_cpuid" != "xno"; then
|
||||
PKG_CHECK_MODULES([LIBCPUID], [libcpuid],
|
||||
[CXXFLAGS="$LIBCPUID_CFLAGS $CXXFLAGS"
|
||||
have_libcpuid=1
|
||||
AC_DEFINE([HAVE_LIBCPUID], [1], [Use libcpuid])]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LIBCPUID, [$have_libcpuid])
|
||||
|
||||
|
@ -255,13 +262,17 @@ fi
|
|||
PKG_CHECK_MODULES([GTEST], [gtest_main])
|
||||
|
||||
|
||||
# Look for nlohmann/json.
|
||||
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])
|
||||
|
||||
|
||||
# documentation generation switch
|
||||
AC_ARG_ENABLE(doc-gen, AS_HELP_STRING([--disable-doc-gen],[disable documentation generation]),
|
||||
doc_generate=$enableval, doc_generate=yes)
|
||||
AC_SUBST(doc_generate)
|
||||
|
||||
# Look for lowdown library.
|
||||
PKG_CHECK_MODULES([LOWDOWN], [lowdown >= 0.8.0], [CXXFLAGS="$LOWDOWN_CFLAGS $CXXFLAGS"])
|
||||
PKG_CHECK_MODULES([LOWDOWN], [lowdown >= 0.9.0], [CXXFLAGS="$LOWDOWN_CFLAGS $CXXFLAGS"])
|
||||
|
||||
# Setuid installations.
|
||||
AC_CHECK_FUNCS([setresuid setreuid lchown])
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) {
|
||||
(import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") {
|
||||
src = ./.;
|
||||
}).defaultNix
|
||||
|
|
|
@ -6,9 +6,9 @@ builtins:
|
|||
concatStrings (map
|
||||
(name:
|
||||
let builtin = builtins.${name}; in
|
||||
"<dt><code>${name} "
|
||||
"<dt id=\"builtins-${name}\"><a href=\"#builtins-${name}\"><code>${name} "
|
||||
+ concatStringsSep " " (map (s: "<var>${s}</var>") builtin.args)
|
||||
+ "</code></dt>"
|
||||
+ "</code></a></dt>"
|
||||
+ "<dd>\n\n"
|
||||
+ builtin.doc
|
||||
+ "\n\n</dd>"
|
||||
|
|
|
@ -8,17 +8,19 @@ concatStrings (map
|
|||
let option = options.${name}; in
|
||||
" - `${name}` \n\n"
|
||||
+ concatStrings (map (s: " ${s}\n") (splitLines option.description)) + "\n\n"
|
||||
+ " **Default:** " + (
|
||||
if option.value == "" || option.value == []
|
||||
then "*empty*"
|
||||
else if isBool option.value
|
||||
then (if option.value then "`true`" else "`false`")
|
||||
else
|
||||
# n.b. a StringMap value type is specified as a string, but
|
||||
# this shows the value type. The empty stringmap is "null" in
|
||||
# JSON, but that converts to "{ }" here.
|
||||
(if isAttrs option.value then "`\"\"`"
|
||||
else "`" + toString option.value + "`")) + "\n\n"
|
||||
+ (if option.documentDefault
|
||||
then " **Default:** " + (
|
||||
if option.value == "" || option.value == []
|
||||
then "*empty*"
|
||||
else if isBool option.value
|
||||
then (if option.value then "`true`" else "`false`")
|
||||
else
|
||||
# n.b. a StringMap value type is specified as a string, but
|
||||
# this shows the value type. The empty stringmap is "null" in
|
||||
# JSON, but that converts to "{ }" here.
|
||||
(if isAttrs option.value then "`\"\"`"
|
||||
else "`" + toString option.value + "`")) + "\n\n"
|
||||
else " **Default:** *machine-specific*\n")
|
||||
+ (if option.aliases != []
|
||||
then " **Deprecated alias:** " + (concatStringsSep ", " (map (s: "`${s}`") option.aliases)) + "\n\n"
|
||||
else "")
|
||||
|
|
|
@ -12,11 +12,13 @@ man-pages := $(foreach n, \
|
|||
clean-files += $(d)/*.1 $(d)/*.5 $(d)/*.8
|
||||
|
||||
# Provide a dummy environment for nix, so that it will not access files outside the macOS sandbox.
|
||||
# Set cores to 0 because otherwise nix show-config resolves the cores based on the current machine
|
||||
dummy-env = env -i \
|
||||
HOME=/dummy \
|
||||
NIX_CONF_DIR=/dummy \
|
||||
NIX_SSL_CERT_FILE=/dummy/no-ca-bundle.crt \
|
||||
NIX_STATE_DIR=/dummy
|
||||
NIX_STATE_DIR=/dummy \
|
||||
NIX_CONFIG='cores = 0'
|
||||
|
||||
nix-eval = $(dummy-env) $(bindir)/nix eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
|
||||
|
||||
|
@ -70,6 +72,7 @@ $(d)/builtins.json: $(bindir)/nix
|
|||
@mv $@.tmp $@
|
||||
|
||||
# Generate the HTML manual.
|
||||
html: $(docdir)/manual/index.html
|
||||
install: $(docdir)/manual/index.html
|
||||
|
||||
# Generate 'nix' manpages.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
- [Prerequisites](installation/prerequisites-source.md)
|
||||
- [Obtaining a Source Distribution](installation/obtaining-source.md)
|
||||
- [Building Nix from Source](installation/building-source.md)
|
||||
- [Using Nix within Docker](installation/installing-docker.md)
|
||||
- [Security](installation/nix-security.md)
|
||||
- [Single-User Mode](installation/single-user.md)
|
||||
- [Multi-User Mode](installation/multi-user.md)
|
||||
|
@ -70,7 +71,11 @@
|
|||
- [Hacking](contributing/hacking.md)
|
||||
- [CLI guideline](contributing/cli-guideline.md)
|
||||
- [Release Notes](release-notes/release-notes.md)
|
||||
- [Release 2.4 (2021-XX-XX)](release-notes/rl-2.4.md)
|
||||
- [Release X.Y (202?-??-??)](release-notes/rl-next.md)
|
||||
- [Release 2.7 (2022-03-07)](release-notes/rl-2.7.md)
|
||||
- [Release 2.6 (2022-01-24)](release-notes/rl-2.6.md)
|
||||
- [Release 2.5 (2021-12-13)](release-notes/rl-2.5.md)
|
||||
- [Release 2.4 (2021-11-01)](release-notes/rl-2.4.md)
|
||||
- [Release 2.3 (2019-09-04)](release-notes/rl-2.3.md)
|
||||
- [Release 2.2 (2019-01-11)](release-notes/rl-2.2.md)
|
||||
- [Release 2.1 (2018-09-02)](release-notes/rl-2.1.md)
|
||||
|
|
|
@ -53,8 +53,8 @@ example, the following command allows you to build a derivation for
|
|||
$ uname
|
||||
Linux
|
||||
|
||||
$ nix build \
|
||||
'(with import <nixpkgs> { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \
|
||||
$ nix build --impure \
|
||||
--expr '(with import <nixpkgs> { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \
|
||||
--builders 'ssh://mac x86_64-darwin'
|
||||
[1/0/1 built, 0.0 MiB DL] building foo on ssh://mac
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ By default Nix reads settings from the following places:
|
|||
will be loaded in reverse order.
|
||||
|
||||
Otherwise it will look for `nix/nix.conf` files in `XDG_CONFIG_DIRS`
|
||||
and `XDG_CONFIG_HOME`. If these are unset, it will look in
|
||||
`$HOME/.config/nix.conf`.
|
||||
and `XDG_CONFIG_HOME`. If unset, `XDG_CONFIG_DIRS` defaults to
|
||||
`/etc/xdg`, and `XDG_CONFIG_HOME` defaults to `$HOME/.config`
|
||||
as per [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
||||
|
||||
- If `NIX_CONFIG` is set, its contents is treated as the contents of
|
||||
a configuration file.
|
||||
|
|
|
@ -238,7 +238,16 @@ a number of possible ways:
|
|||
|
||||
## Examples
|
||||
|
||||
To install a specific version of `gcc` from the active Nix expression:
|
||||
To install a package using a specific attribute path from the active Nix expression:
|
||||
|
||||
```console
|
||||
$ nix-env -iA gcc40mips
|
||||
installing `gcc-4.0.2'
|
||||
$ nix-env -iA xorg.xorgserver
|
||||
installing `xorg-server-1.2.0'
|
||||
```
|
||||
|
||||
To install a specific version of `gcc` using the derivation name:
|
||||
|
||||
```console
|
||||
$ nix-env --install gcc-3.3.2
|
||||
|
@ -246,6 +255,9 @@ installing `gcc-3.3.2'
|
|||
uninstalling `gcc-3.1'
|
||||
```
|
||||
|
||||
Using attribute path for selecting a package is preferred,
|
||||
as it is much faster and there will not be multiple matches.
|
||||
|
||||
Note the previously installed version is removed, since
|
||||
`--preserve-installed` was not specified.
|
||||
|
||||
|
@ -256,13 +268,6 @@ $ nix-env --install gcc
|
|||
installing `gcc-3.3.2'
|
||||
```
|
||||
|
||||
To install using a specific attribute:
|
||||
|
||||
```console
|
||||
$ nix-env -i -A gcc40mips
|
||||
$ nix-env -i -A xorg.xorgserver
|
||||
```
|
||||
|
||||
To install all derivations in the Nix expression `foo.nix`:
|
||||
|
||||
```console
|
||||
|
@ -374,22 +379,29 @@ For the other flags, see `--install`.
|
|||
## Examples
|
||||
|
||||
```console
|
||||
$ nix-env --upgrade gcc
|
||||
$ nix-env --upgrade -A nixpkgs.gcc
|
||||
upgrading `gcc-3.3.1' to `gcc-3.4'
|
||||
```
|
||||
|
||||
When there are no updates available, nothing will happen:
|
||||
|
||||
```console
|
||||
$ nix-env -u gcc-3.3.2 --always (switch to a specific version)
|
||||
$ nix-env --upgrade -A nixpkgs.pan
|
||||
```
|
||||
|
||||
Using `-A` is preferred when possible, as it is faster and unambiguous but
|
||||
it is also possible to upgrade to a specific version by matching the derivation name:
|
||||
|
||||
```console
|
||||
$ nix-env -u gcc-3.3.2 --always
|
||||
upgrading `gcc-3.4' to `gcc-3.3.2'
|
||||
```
|
||||
|
||||
```console
|
||||
$ nix-env --upgrade pan
|
||||
(no upgrades available, so nothing happens)
|
||||
```
|
||||
To try to upgrade everything
|
||||
(matching packages based on the part of the derivation name without version):
|
||||
|
||||
```console
|
||||
$ nix-env -u (try to upgrade everything)
|
||||
$ nix-env -u
|
||||
upgrading `hello-2.1.2' to `hello-2.1.3'
|
||||
upgrading `mozilla-1.2' to `mozilla-1.4'
|
||||
```
|
||||
|
@ -401,7 +413,7 @@ of a derivation `x` by looking at their respective `name` attributes.
|
|||
The names (e.g., `gcc-3.3.1` are split into two parts: the package name
|
||||
(`gcc`), and the version (`3.3.1`). The version part starts after the
|
||||
first dash not followed by a letter. `x` is considered an upgrade of `y`
|
||||
if their package names match, and the version of `y` is higher that that
|
||||
if their package names match, and the version of `y` is higher than that
|
||||
of `x`.
|
||||
|
||||
The versions are compared by splitting them into contiguous components
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
[`--command` *cmd*]
|
||||
[`--run` *cmd*]
|
||||
[`--exclude` *regexp*]
|
||||
[--pure]
|
||||
[--keep *name*]
|
||||
[`--pure`]
|
||||
[`--keep` *name*]
|
||||
{{`--packages` | `-p`} {*packages* | *expressions*} … | [*path*]}
|
||||
|
||||
# Description
|
||||
|
@ -101,7 +101,8 @@ The following common options are supported:
|
|||
|
||||
- `NIX_BUILD_SHELL`\
|
||||
Shell used to start the interactive environment. Defaults to the
|
||||
`bash` found in `PATH`.
|
||||
`bash` found in `<nixpkgs>`, falling back to the `bash` found in
|
||||
`PATH` if not found.
|
||||
|
||||
# Examples
|
||||
|
||||
|
@ -110,13 +111,19 @@ shell in which to build it:
|
|||
|
||||
```console
|
||||
$ nix-shell '<nixpkgs>' -A pan
|
||||
[nix-shell]$ unpackPhase
|
||||
[nix-shell]$ eval ${unpackPhase:-unpackPhase}
|
||||
[nix-shell]$ cd pan-*
|
||||
[nix-shell]$ configurePhase
|
||||
[nix-shell]$ buildPhase
|
||||
[nix-shell]$ eval ${configurePhase:-configurePhase}
|
||||
[nix-shell]$ eval ${buildPhase:-buildPhase}
|
||||
[nix-shell]$ ./pan/gui/pan
|
||||
```
|
||||
|
||||
The reason we use form `eval ${configurePhase:-configurePhase}` here is because
|
||||
those packages that override these phases do so by exporting the overridden
|
||||
values in the environment variable of the same name.
|
||||
Here bash is being told to either evaluate the contents of 'configurePhase',
|
||||
if it exists as a variable, otherwise evaluate the configurePhase function.
|
||||
|
||||
To clear the environment first, and do some additional automatic
|
||||
initialisation of the interactive shell:
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ Special exit codes:
|
|||
|
||||
- `104`\
|
||||
Not deterministic, the build succeeded in check mode but the
|
||||
resulting output is not binary reproducable.
|
||||
resulting output is not binary reproducible.
|
||||
|
||||
With the `--keep-going` flag it's possible for multiple failures to
|
||||
occur, in this case the 1xx status codes are or combined using binary
|
||||
|
@ -321,8 +321,8 @@ symlink.
|
|||
This query has one option:
|
||||
|
||||
- `--include-outputs`
|
||||
Also include the output path of store derivations, and their
|
||||
closures.
|
||||
Also include the existing output paths of store derivations,
|
||||
and their closures.
|
||||
|
||||
This query can be used to implement various kinds of deployment. A
|
||||
*source deployment* is obtained by distributing the closure of a
|
||||
|
|
|
@ -162,11 +162,11 @@ Most Nix commands accept the following command-line options:
|
|||
}: ...
|
||||
```
|
||||
|
||||
So if you call this Nix expression (e.g., when you do `nix-env -i
|
||||
So if you call this Nix expression (e.g., when you do `nix-env -iA
|
||||
pkgname`), the function will be called automatically using the
|
||||
value [`builtins.currentSystem`](../expressions/builtins.md) for
|
||||
the `system` argument. You can override this using `--arg`, e.g.,
|
||||
`nix-env -i pkgname --arg system \"i686-freebsd\"`. (Note that
|
||||
`nix-env -iA pkgname --arg system \"i686-freebsd\"`. (Note that
|
||||
since the argument is a Nix string literal, you have to escape the
|
||||
quotes.)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Goals
|
||||
|
||||
Purpose of this document is to provide a clear direction to **help design
|
||||
delightful command line** experience. This document contain guidelines to
|
||||
delightful command line** experience. This document contains guidelines to
|
||||
follow to ensure a consistent and approachable user experience.
|
||||
|
||||
## Overview
|
||||
|
@ -103,7 +103,7 @@ impacted the most by bad user experience.
|
|||
# Help is essential
|
||||
|
||||
Help should be built into your command line so that new users can gradually
|
||||
discover new features when they need them.
|
||||
discover new features when they need them.
|
||||
|
||||
## Looking for help
|
||||
|
||||
|
@ -115,7 +115,7 @@ The rules are:
|
|||
|
||||
- Help is shown by using `--help` or `help` command (eg `nix` `--``help` or
|
||||
`nix help`).
|
||||
- For non-COMMANDs (eg. `nix` `--``help` and `nix store` `--``help`) we **show
|
||||
- For non-COMMANDs (eg. `nix` `--``help` and `nix store` `--``help`) we **show
|
||||
a summary** of most common use cases. Summary is presented on the STDOUT
|
||||
without any use of PAGER.
|
||||
- For COMMANDs (eg. `nix init` `--``help` or `nix help init`) we display the
|
||||
|
@ -176,7 +176,7 @@ $ nix init --template=template#pyton
|
|||
------------------------------------------------------------------------
|
||||
Initializing Nix project at `/path/to/here`.
|
||||
Select a template for you new project:
|
||||
|> template#pyton
|
||||
|> template#python
|
||||
template#python-pip
|
||||
template#python-poetry
|
||||
```
|
||||
|
@ -230,17 +230,17 @@ Now **Learn** part of the output is where you educate users. You should only
|
|||
show it when you know that a build will take some time and not annoy users of
|
||||
the builds that take only few seconds.
|
||||
|
||||
Every feature like this should go though a intensive review and testing to
|
||||
collect as much a feedback as possible and to fine tune every little detail. If
|
||||
Every feature like this should go through an intensive review and testing to
|
||||
collect as much feedback as possible and to fine tune every little detail. If
|
||||
done right this can be an awesome features beginners and advance users will
|
||||
love, but if not done perfectly it will annoy users and leave bad impression.
|
||||
|
||||
# Input
|
||||
|
||||
Input to a command is provided via `ARGUMENTS` and `OPTIONS`.
|
||||
Input to a command is provided via `ARGUMENTS` and `OPTIONS`.
|
||||
|
||||
`ARGUMENTS` represent a required input for a function. When choosing to use
|
||||
`ARGUMENT` over function please be aware of the downsides that come with it:
|
||||
`ARGUMENTS` over `OPTIONS` please be aware of the downsides that come with it:
|
||||
|
||||
- User will need to remember the order of `ARGUMENTS`. This is not a problem if
|
||||
there is only one `ARGUMENT`.
|
||||
|
@ -253,7 +253,7 @@ developer consider the downsides and choose wisely.
|
|||
|
||||
## Naming the `OPTIONS`
|
||||
|
||||
Then only naming convention - apart from the ones mentioned in Naming the
|
||||
The only naming convention - apart from the ones mentioned in Naming the
|
||||
`COMMANDS` section is how flags are named.
|
||||
|
||||
Flags are a type of `OPTION` that represent an option that can be turned ON of
|
||||
|
@ -271,12 +271,12 @@ to improve the discoverability of possible input. A new user will most likely
|
|||
not know which `ARGUMENTS` and `OPTIONS` are required or which values are
|
||||
possible for those options.
|
||||
|
||||
In cases, the user might not provide the input or they provide wrong input,
|
||||
rather then show the error, prompt a user with an option to find and select
|
||||
In case the user does not provide the input or they provide wrong input,
|
||||
rather than show the error, prompt a user with an option to find and select
|
||||
correct input (see examples).
|
||||
|
||||
Prompting is of course not required when TTY is not attached to STDIN. This
|
||||
would mean that scripts wont need to handle prompt, but rather handle errors.
|
||||
would mean that scripts won't need to handle prompt, but rather handle errors.
|
||||
|
||||
A place to use prompt and provide user with interactive select
|
||||
|
||||
|
@ -300,9 +300,9 @@ going to happen.
|
|||
```shell
|
||||
$ nix build --option substitutors https://cache.example.org
|
||||
------------------------------------------------------------------------
|
||||
Warning! A security related question need to be answered.
|
||||
Warning! A security related question needs to be answered.
|
||||
------------------------------------------------------------------------
|
||||
The following substitutors will be used to in `my-project`:
|
||||
The following substitutors will be used to in `my-project`:
|
||||
- https://cache.example.org
|
||||
|
||||
Do you allow `my-project` to use above mentioned substitutors?
|
||||
|
@ -311,14 +311,14 @@ $ nix build --option substitutors https://cache.example.org
|
|||
|
||||
# Output
|
||||
|
||||
Terminal output can be quite limiting in many ways. Which should forces us to
|
||||
Terminal output can be quite limiting in many ways. Which should force us to
|
||||
think about the experience even more. As with every design the output is a
|
||||
compromise between being terse and being verbose, between showing help to
|
||||
beginners and annoying advance users. For this it is important that we know
|
||||
what are the priorities.
|
||||
|
||||
Nix command line should be first and foremost written with beginners in mind.
|
||||
But users wont stay beginners for long and what was once useful might quickly
|
||||
But users won't stay beginners for long and what was once useful might quickly
|
||||
become annoying. There is no golden rule that we can give in this guideline
|
||||
that would make it easier how to draw a line and find best compromise.
|
||||
|
||||
|
@ -342,7 +342,7 @@ also allowing them to redirect content to a file. For example:
|
|||
```shell
|
||||
$ nix build > build.txt
|
||||
------------------------------------------------------------------------
|
||||
Error! Atrribute `bin` missing at (1:94) from string.
|
||||
Error! Attribute `bin` missing at (1:94) from string.
|
||||
------------------------------------------------------------------------
|
||||
|
||||
1| with import <nixpkgs> { }; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (surge.bin) ]; } ""
|
||||
|
@ -408,7 +408,7 @@ Above command clearly states that command successfully completed. And in case
|
|||
of `nix build`, which is a command that might take some time to complete, it is
|
||||
equally important to also show that a command started.
|
||||
|
||||
## Text alignment
|
||||
## Text alignment
|
||||
|
||||
Text alignment is the number one design element that will present all of the
|
||||
Nix commands as a family and not as separate tools glued together.
|
||||
|
@ -419,7 +419,7 @@ The format we should follow is:
|
|||
$ nix COMMAND
|
||||
VERB_1 NOUN and other words
|
||||
VERB__1 NOUN and other words
|
||||
|> Some details
|
||||
|> Some details
|
||||
```
|
||||
|
||||
Few rules that we can extract from above example:
|
||||
|
@ -444,13 +444,13 @@ is not even notable, therefore relying on it wouldn’t make much sense.
|
|||
|
||||
**The bright text is much better supported** across terminals and color
|
||||
schemes. Most of the time the difference is perceived as if the bright text
|
||||
would be bold.
|
||||
would be bold.
|
||||
|
||||
## Colors
|
||||
|
||||
Humans are already conditioned by society to attach certain meaning to certain
|
||||
colors. While the meaning is not universal, a simple collection of colors is
|
||||
used to represent basic emotions.
|
||||
used to represent basic emotions.
|
||||
|
||||
Colors that can be used in output
|
||||
|
||||
|
@ -508,7 +508,7 @@ can, with a few key strokes, be changed into and advance introspection tool.
|
|||
|
||||
### Progress
|
||||
|
||||
For longer running commands we should provide and overview of the progress.
|
||||
For longer running commands we should provide and overview the progress.
|
||||
This is shown best in `nix build` example:
|
||||
|
||||
```shell
|
||||
|
@ -553,9 +553,9 @@ going to happen.
|
|||
```shell
|
||||
$ nix build --option substitutors https://cache.example.org
|
||||
------------------------------------------------------------------------
|
||||
Warning! A security related question need to be answered.
|
||||
Warning! A security related question needs to be answered.
|
||||
------------------------------------------------------------------------
|
||||
The following substitutors will be used to in `my-project`:
|
||||
The following substitutors will be used to in `my-project`:
|
||||
- https://cache.example.org
|
||||
|
||||
Do you allow `my-project` to use above mentioned substitutors?
|
||||
|
@ -566,7 +566,7 @@ $ nix build --option substitutors https://cache.example.org
|
|||
|
||||
There are many ways that you can control verbosity.
|
||||
|
||||
Verbosity levels are:
|
||||
Verbosity levels are:
|
||||
|
||||
- `ERROR` (level 0)
|
||||
- `WARN` (level 1)
|
||||
|
@ -586,4 +586,4 @@ There are also two shortcuts, `--debug` to run in `DEBUG` verbosity level and
|
|||
|
||||
# Appendix 1: Commands naming exceptions
|
||||
|
||||
`nix init` and `nix repl` are well established
|
||||
`nix init` and `nix repl` are well established
|
||||
|
|
|
@ -35,6 +35,25 @@ variables are set up so that those dependencies can be found:
|
|||
$ nix-shell
|
||||
```
|
||||
|
||||
or if you have a flake-enabled nix:
|
||||
|
||||
```console
|
||||
$ nix develop
|
||||
```
|
||||
|
||||
To get a shell with a different compilation environment (e.g. stdenv,
|
||||
gccStdenv, clangStdenv, clang11Stdenv):
|
||||
|
||||
```console
|
||||
$ nix-shell -A devShells.x86_64-linux.clang11StdenvPackages
|
||||
```
|
||||
|
||||
or if you have a flake-enabled nix:
|
||||
|
||||
```console
|
||||
$ nix develop .#clang11StdenvPackages
|
||||
```
|
||||
|
||||
To build Nix itself in this shell:
|
||||
|
||||
```console
|
||||
|
|
|
@ -237,7 +237,7 @@ Derivations can declare some infrequently used optional attributes.
|
|||
- `preferLocalBuild`\
|
||||
If this attribute is set to `true` and [distributed building is
|
||||
enabled](../advanced-topics/distributed-builds.md), then, if
|
||||
possible, the derivaton will be built locally instead of forwarded
|
||||
possible, the derivation will be built locally instead of forwarded
|
||||
to a remote machine. This is appropriate for trivial builders
|
||||
where the cost of doing a download or remote build would exceed
|
||||
the cost of building locally.
|
||||
|
|
|
@ -12,5 +12,5 @@ For instance, `derivation` is also available as `builtins.derivation`.
|
|||
<dl>
|
||||
<dt><code>derivation <var>attrs</var></code>;
|
||||
<code>builtins.derivation <var>attrs</var></code></dt>
|
||||
<dd><p><var>derivation</var> in described in
|
||||
<dd><p><var>derivation</var> is described in
|
||||
<a href="derivations.md">its own section</a>.</p></dd>
|
||||
|
|
|
@ -26,7 +26,7 @@ elements (referenced from the figure by number):
|
|||
called with three arguments: `stdenv`, `fetchurl`, and `perl`. They
|
||||
are needed to build Hello, but we don't know how to build them here;
|
||||
that's why they are function arguments. `stdenv` is a package that
|
||||
is used by almost all Nix Packages packages; it provides a
|
||||
is used by almost all Nix Packages; it provides a
|
||||
“standard” environment consisting of the things you would expect
|
||||
in a basic Unix environment: a C/C++ compiler (GCC, to be precise),
|
||||
the Bash shell, fundamental Unix tools such as `cp`, `grep`, `tar`,
|
||||
|
|
|
@ -284,6 +284,10 @@ The points of interest are:
|
|||
function is called with the `localServer` argument set to `true` but
|
||||
the `db4` argument set to `null`, then the evaluation fails.
|
||||
|
||||
Note that `->` is the [logical
|
||||
implication](https://en.wikipedia.org/wiki/Truth_table#Logical_implication)
|
||||
Boolean operation.
|
||||
|
||||
2. This is a more subtle condition: if Subversion is built with Apache
|
||||
(`httpServer`) support, then the Expat library (an XML library) used
|
||||
by Subversion should be same as the one used by Apache. This is
|
||||
|
|
|
@ -17,12 +17,12 @@ order of precedence (from strongest to weakest binding).
|
|||
| String Concatenation | *string1* `+` *string2* | left | String concatenation. | 7 |
|
||||
| Not | `!` *e* | none | Boolean negation. | 8 |
|
||||
| Update | *e1* `//` *e2* | right | Return a set consisting of the attributes in *e1* and *e2* (with the latter taking precedence over the former in case of equally named attributes). | 9 |
|
||||
| Less Than | *e1* `<` *e2*, | none | Arithmetic comparison. | 10 |
|
||||
| Less Than or Equal To | *e1* `<=` *e2* | none | Arithmetic comparison. | 10 |
|
||||
| Greater Than | *e1* `>` *e2* | none | Arithmetic comparison. | 10 |
|
||||
| Greater Than or Equal To | *e1* `>=` *e2* | none | Arithmetic comparison. | 10 |
|
||||
| Less Than | *e1* `<` *e2*, | none | Arithmetic/lexicographic comparison. | 10 |
|
||||
| Less Than or Equal To | *e1* `<=` *e2* | none | Arithmetic/lexicographic comparison. | 10 |
|
||||
| Greater Than | *e1* `>` *e2* | none | Arithmetic/lexicographic comparison. | 10 |
|
||||
| Greater Than or Equal To | *e1* `>=` *e2* | none | Arithmetic/lexicographic comparison. | 10 |
|
||||
| Equality | *e1* `==` *e2* | none | Equality. | 11 |
|
||||
| Inequality | *e1* `!=` *e2* | none | Inequality. | 11 |
|
||||
| Logical AND | *e1* `&&` *e2* | left | Logical AND. | 12 |
|
||||
| Logical OR | *e1* `\|\|` *e2* | left | Logical OR. | 13 |
|
||||
| Logical Implication | *e1* `->` *e2* | none | Logical implication (equivalent to `!e1 \|\| e2`). | 14 |
|
||||
| Logical OR | *e1* <code>||</code> *e2* | left | Logical OR. | 13 |
|
||||
| Logical Implication | *e1* `->` *e2* | none | Logical implication (equivalent to <code>!e1 || e2</code>). | 14 |
|
||||
|
|
|
@ -64,7 +64,7 @@ Nix has the following basic data types:
|
|||
the start of each line. To be precise, it strips from each line a
|
||||
number of spaces equal to the minimal indentation of the string as a
|
||||
whole (disregarding the indentation of empty lines). For instance,
|
||||
the first and second line are indented two space, while the third
|
||||
the first and second line are indented two spaces, while the third
|
||||
line is indented four spaces. Thus, two spaces are stripped from
|
||||
each line, so the resulting string is
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Building and Testing
|
||||
|
||||
You can now try to build Hello. Of course, you could do `nix-env -i
|
||||
You can now try to build Hello. Of course, you could do `nix-env -f . -iA
|
||||
hello`, 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
|
||||
`nix-build`, which builds a Nix expression and creates a symlink named
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
the store object at `P` contains the path `Q` somewhere. The
|
||||
*references* of a store path are the set of store paths to which it
|
||||
has a reference.
|
||||
|
||||
|
||||
A derivation can reference other derivations and sources (but not
|
||||
output paths), whereas an output path only references other output
|
||||
paths.
|
||||
|
@ -66,7 +66,7 @@
|
|||
is necessary to deploy whole closures, since otherwise at runtime
|
||||
files could be missing. The command `nix-store -qR` prints out
|
||||
closures of store paths.
|
||||
|
||||
|
||||
As an example, if the store object at path `P` contains a reference
|
||||
to path `Q`, then `Q` is in the closure of `P`. Further, if `Q`
|
||||
references `R` then `R` is also in the closure of `P`.
|
||||
|
@ -98,3 +98,7 @@
|
|||
store. It can contain regular files, directories and symbolic
|
||||
links. NARs are generated and unpacked using `nix-store --dump`
|
||||
and `nix-store --restore`.
|
||||
- `∅` \
|
||||
The empty set symbol. In the context of profile history, this denotes a package is not present in a particular version of the profile.
|
||||
- `ε` \
|
||||
The epsilon symbol. In the context of a package, this means the version is empty. More precisely, the derivation does not have a version attribute.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Building Nix from Source
|
||||
|
||||
After unpacking or checking out the Nix sources, issue the following
|
||||
commands:
|
||||
After cloning Nix's Git repository, issue the following commands:
|
||||
|
||||
```console
|
||||
$ ./bootstrap.sh
|
||||
$ ./configure options...
|
||||
$ make
|
||||
$ make install
|
||||
|
@ -11,13 +11,6 @@ $ make install
|
|||
|
||||
Nix requires GNU Make so you may need to invoke `gmake` instead.
|
||||
|
||||
When building from the Git repository, these should be preceded by the
|
||||
command:
|
||||
|
||||
```console
|
||||
$ ./bootstrap.sh
|
||||
```
|
||||
|
||||
The installation path can be specified by passing the `--prefix=prefix`
|
||||
to `configure`. The default installation directory is `/usr/local`. You
|
||||
can change this to any location you like. You must have write permission
|
||||
|
|
|
@ -119,6 +119,30 @@ this to run the installer, but it may help if you run into trouble:
|
|||
- update `/etc/synthetic.conf` to direct macOS to create a "synthetic"
|
||||
empty root directory to mount your volume
|
||||
- specify mount options for the volume in `/etc/fstab`
|
||||
- `rw`: read-write
|
||||
- `noauto`: prevent the system from auto-mounting the volume (so the
|
||||
LaunchDaemon mentioned below can control mounting it, and to avoid
|
||||
masking problems with that mounting service).
|
||||
- `nobrowse`: prevent the Nix Store volume from showing up on your
|
||||
desktop; also keeps Spotlight from spending resources to index
|
||||
this volume
|
||||
<!-- TODO:
|
||||
- `suid`: honor setuid? surely not? ...
|
||||
- `owners`: honor file ownership on the volume
|
||||
|
||||
For now I'll avoid pretending to understand suid/owners more
|
||||
than I do. There've been some vague reports of file-ownership
|
||||
and permission issues, particularly in cloud/VM/headless setups.
|
||||
My pet theory is that this has something to do with these setups
|
||||
not having a token that gets delegated to initial/admin accounts
|
||||
on macOS. See scripts/create-darwin-volume.sh for a little more.
|
||||
|
||||
In any case, by Dec 4 2021, it _seems_ like some combination of
|
||||
suid, owners, and calling diskutil enableOwnership have stopped
|
||||
new reports from coming in. But I hesitate to celebrate because we
|
||||
haven't really named and catalogued the behavior, understood what
|
||||
we're fixing, and validated that all 3 components are essential.
|
||||
-->
|
||||
- if you have FileVault enabled
|
||||
- generate an encryption password
|
||||
- put it in your system Keychain
|
||||
|
|
59
doc/manual/src/installation/installing-docker.md
Normal file
59
doc/manual/src/installation/installing-docker.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Using Nix within Docker
|
||||
|
||||
To run the latest stable release of Nix with Docker run the following command:
|
||||
|
||||
```console
|
||||
$ docker run -ti nixos/nix
|
||||
Unable to find image 'nixos/nix:latest' locally
|
||||
latest: Pulling from nixos/nix
|
||||
5843afab3874: Pull complete
|
||||
b52bf13f109c: Pull complete
|
||||
1e2415612aa3: Pull complete
|
||||
Digest: sha256:27f6e7f60227e959ee7ece361f75d4844a40e1cc6878b6868fe30140420031ff
|
||||
Status: Downloaded newer image for nixos/nix:latest
|
||||
35ca4ada6e96:/# nix --version
|
||||
nix (Nix) 2.3.12
|
||||
35ca4ada6e96:/# exit
|
||||
```
|
||||
|
||||
# What is included in Nix's Docker image?
|
||||
|
||||
The official Docker image is created using `pkgs.dockerTools.buildLayeredImage`
|
||||
(and not with `Dockerfile` as it is usual with Docker images). You can still
|
||||
base your custom Docker image on it as you would do with any other Docker
|
||||
image.
|
||||
|
||||
The Docker image is also not based on any other image and includes minimal set
|
||||
of runtime dependencies that are required to use Nix:
|
||||
|
||||
- pkgs.nix
|
||||
- pkgs.bashInteractive
|
||||
- pkgs.coreutils-full
|
||||
- pkgs.gnutar
|
||||
- pkgs.gzip
|
||||
- pkgs.gnugrep
|
||||
- pkgs.which
|
||||
- pkgs.curl
|
||||
- pkgs.less
|
||||
- pkgs.wget
|
||||
- pkgs.man
|
||||
- pkgs.cacert.out
|
||||
- pkgs.findutils
|
||||
|
||||
# Docker image with the latest development version of Nix
|
||||
|
||||
To get the latest image that was built by [Hydra](https://hydra.nixos.org) run
|
||||
the following command:
|
||||
|
||||
```console
|
||||
$ curl -L https://hydra.nixos.org/job/nix/master/dockerImage.x86_64-linux/latest/download/1 | docker load
|
||||
$ docker run -ti nix:2.5pre20211105
|
||||
```
|
||||
|
||||
You can also build a Docker image from source yourself:
|
||||
|
||||
```console
|
||||
$ nix build ./\#hydraJobs.dockerImage.x86_64-linux
|
||||
$ docker load -i ./result/image.tar.gz
|
||||
$ docker run -ti nix:2.5pre20211105
|
||||
```
|
|
@ -1,4 +1,4 @@
|
|||
# Installing Nix from Source
|
||||
|
||||
If no binary package is available, you can download and compile a source
|
||||
distribution.
|
||||
If no binary package is available or if you want to hack on Nix, you
|
||||
can build Nix from its Git repository.
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
# Obtaining a Source Distribution
|
||||
# Obtaining the Source
|
||||
|
||||
The source tarball of the most recent stable release can be downloaded
|
||||
from the [Nix homepage](http://nixos.org/nix/download.html). You can
|
||||
also grab the [most recent development
|
||||
release](http://hydra.nixos.org/job/nix/master/release/latest-finished#tabs-constituents).
|
||||
|
||||
Alternatively, the most recent sources of Nix can be obtained from its
|
||||
[Git repository](https://github.com/NixOS/nix). For example, the
|
||||
following command will check out the latest revision into a directory
|
||||
called `nix`:
|
||||
The most recent sources of Nix can be obtained from its [Git
|
||||
repository](https://github.com/NixOS/nix). For example, the following
|
||||
command will check out the latest revision into a directory called
|
||||
`nix`:
|
||||
|
||||
```console
|
||||
$ git clone https://github.com/NixOS/nix
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
- GNU Autoconf (<https://www.gnu.org/software/autoconf/>) and the
|
||||
autoconf-archive macro collection
|
||||
(<https://www.gnu.org/software/autoconf-archive/>). These are only
|
||||
needed to run the bootstrap script, and are not necessary if your
|
||||
source distribution came with a pre-built `./configure` script.
|
||||
(<https://www.gnu.org/software/autoconf-archive/>). These are
|
||||
needed to run the bootstrap script.
|
||||
|
||||
- GNU Make.
|
||||
|
||||
|
@ -45,6 +44,11 @@
|
|||
obtained from the its repository
|
||||
<https://github.com/troglobit/editline>.
|
||||
|
||||
- The `libsodium` library for verifying cryptographic signatures
|
||||
of contents fetched from binary caches.
|
||||
It can be obtained from the official web site
|
||||
<https://libsodium.org>.
|
||||
|
||||
- Recent versions of Bison and Flex to build the parser. (This is
|
||||
because Nix needs GLR support in Bison and reentrancy support in
|
||||
Flex.) For Bison, you need version 2.6, which can be obtained from
|
||||
|
@ -52,11 +56,18 @@
|
|||
you need version 2.5.35, which is available on
|
||||
[SourceForge](http://lex.sourceforge.net/). Slightly older versions
|
||||
may also work, but ancient versions like the ubiquitous 2.5.4a
|
||||
won't. Note that these are only required if you modify the parser or
|
||||
when you are building from the Git repository.
|
||||
won't.
|
||||
|
||||
- The `libseccomp` is used to provide syscall filtering on Linux. This
|
||||
is an optional dependency and can be disabled passing a
|
||||
`--disable-seccomp-sandboxing` option to the `configure` script (Not
|
||||
recommended unless your system doesn't support `libseccomp`). To get
|
||||
the library, visit <https://github.com/seccomp/libseccomp>.
|
||||
|
||||
- On 64-bit x86 machines only, `libcpuid` library
|
||||
is used to determine which microarchitecture levels are supported
|
||||
(e.g., as whether to have `x86_64-v2-linux` among additional system types).
|
||||
The library is available from its homepage
|
||||
<http://libcpuid.sourceforge.net>.
|
||||
This is an optional dependency and can be disabled
|
||||
by providing a `--disable-cpuid` to the `configure` script.
|
||||
|
|
|
@ -4,4 +4,4 @@ Nix is currently supported on the following platforms:
|
|||
|
||||
- Linux (i686, x86\_64, aarch64).
|
||||
|
||||
- macOS (x86\_64).
|
||||
- macOS (x86\_64, aarch64).
|
||||
|
|
|
@ -76,7 +76,7 @@ there after an upgrade. This means that you can _roll back_ to the
|
|||
old version:
|
||||
|
||||
```console
|
||||
$ nix-env --upgrade some-packages
|
||||
$ nix-env --upgrade -A nixpkgs.some-package
|
||||
$ nix-env --rollback
|
||||
```
|
||||
|
||||
|
@ -122,12 +122,12 @@ Nix expressions generally describe how to build a package from
|
|||
source, so an installation action like
|
||||
|
||||
```console
|
||||
$ nix-env --install firefox
|
||||
$ nix-env --install -A nixpkgs.firefox
|
||||
```
|
||||
|
||||
_could_ cause quite a bit of build activity, as not only Firefox but
|
||||
also all its dependencies (all the way up to the C library and the
|
||||
compiler) would have to built, at least if they are not already in the
|
||||
compiler) would have to be built, at least if they are not already in the
|
||||
Nix store. This is a _source deployment model_. For most users,
|
||||
building from source is not very pleasant as it takes far too long.
|
||||
However, Nix can automatically skip building from source and instead
|
||||
|
|
|
@ -24,7 +24,7 @@ collection; you could write your own Nix expressions based on Nixpkgs,
|
|||
or completely new ones.)
|
||||
|
||||
You can manually download the latest version of Nixpkgs from
|
||||
<http://nixos.org/nixpkgs/download.html>. However, it’s much more
|
||||
<https://github.com/NixOS/nixpkgs>. However, it’s much more
|
||||
convenient to use the Nixpkgs [*channel*](channels.md), since it makes
|
||||
it easy to stay up to date with new versions of Nixpkgs. Nixpkgs is
|
||||
automatically added to your list of “subscribed” channels when you
|
||||
|
@ -40,48 +40,52 @@ $ nix-channel --update
|
|||
>
|
||||
> On NixOS, you’re automatically subscribed to a NixOS channel
|
||||
> corresponding to your NixOS major release (e.g.
|
||||
> <http://nixos.org/channels/nixos-14.12>). A NixOS channel is identical
|
||||
> <http://nixos.org/channels/nixos-21.11>). A NixOS channel is identical
|
||||
> to the Nixpkgs channel, except that it contains only Linux binaries
|
||||
> and is updated only if a set of regression tests succeed.
|
||||
|
||||
You can view the set of available packages in Nixpkgs:
|
||||
|
||||
```console
|
||||
$ nix-env -qa
|
||||
aterm-2.2
|
||||
bash-3.0
|
||||
binutils-2.15
|
||||
bison-1.875d
|
||||
blackdown-1.4.2
|
||||
bzip2-1.0.2
|
||||
$ nix-env -qaP
|
||||
nixpkgs.aterm aterm-2.2
|
||||
nixpkgs.bash bash-3.0
|
||||
nixpkgs.binutils binutils-2.15
|
||||
nixpkgs.bison bison-1.875d
|
||||
nixpkgs.blackdown blackdown-1.4.2
|
||||
nixpkgs.bzip2 bzip2-1.0.2
|
||||
…
|
||||
```
|
||||
|
||||
The flag `-q` specifies a query operation, and `-a` means that you want
|
||||
The flag `-q` specifies a query operation, `-a` means that you want
|
||||
to show the “available” (i.e., installable) packages, as opposed to the
|
||||
installed packages. If you downloaded Nixpkgs yourself, or if you
|
||||
checked it out from GitHub, then you need to pass the path to your
|
||||
Nixpkgs tree using the `-f` flag:
|
||||
installed packages, and `-P` prints the attribute paths that can be used
|
||||
to unambiguously select a package for installation (listed in the first column).
|
||||
If you downloaded Nixpkgs yourself, or if you checked it out from GitHub,
|
||||
then you need to pass the path to your Nixpkgs tree using the `-f` flag:
|
||||
|
||||
```console
|
||||
$ nix-env -qaf /path/to/nixpkgs
|
||||
$ nix-env -qaPf /path/to/nixpkgs
|
||||
aterm aterm-2.2
|
||||
bash bash-3.0
|
||||
…
|
||||
```
|
||||
|
||||
where */path/to/nixpkgs* is where you’ve unpacked or checked out
|
||||
Nixpkgs.
|
||||
|
||||
You can select specific packages by name:
|
||||
You can filter the packages by name:
|
||||
|
||||
```console
|
||||
$ nix-env -qa firefox
|
||||
firefox-34.0.5
|
||||
firefox-with-plugins-34.0.5
|
||||
$ nix-env -qaP firefox
|
||||
nixpkgs.firefox-esr firefox-91.3.0esr
|
||||
nixpkgs.firefox firefox-94.0.1
|
||||
```
|
||||
|
||||
and using regular expressions:
|
||||
|
||||
```console
|
||||
$ nix-env -qa 'firefox.*'
|
||||
$ nix-env -qaP 'firefox.*'
|
||||
```
|
||||
|
||||
It is also possible to see the *status* of available packages, i.e.,
|
||||
|
@ -89,11 +93,11 @@ whether they are installed into the user environment and/or present in
|
|||
the system:
|
||||
|
||||
```console
|
||||
$ nix-env -qas
|
||||
$ nix-env -qaPs
|
||||
…
|
||||
-PS bash-3.0
|
||||
--S binutils-2.15
|
||||
IPS bison-1.875d
|
||||
-PS nixpkgs.bash bash-3.0
|
||||
--S nixpkgs.binutils binutils-2.15
|
||||
IPS nixpkgs.bison bison-1.875d
|
||||
…
|
||||
```
|
||||
|
||||
|
@ -106,13 +110,13 @@ which is Nix’s mechanism for doing binary deployment. It just means that
|
|||
Nix knows that it can fetch a pre-built package from somewhere
|
||||
(typically a network server) instead of building it locally.
|
||||
|
||||
You can install a package using `nix-env -i`. For instance,
|
||||
You can install a package using `nix-env -iA`. For instance,
|
||||
|
||||
```console
|
||||
$ nix-env -i subversion
|
||||
$ nix-env -iA nixpkgs.subversion
|
||||
```
|
||||
|
||||
will install the package called `subversion` (which is, of course, the
|
||||
will install the package called `subversion` from `nixpkgs` channel (which is, of course, the
|
||||
[Subversion version management system](http://subversion.tigris.org/)).
|
||||
|
||||
> **Note**
|
||||
|
@ -122,7 +126,7 @@ will install the package called `subversion` (which is, of course, the
|
|||
> binary cache <https://cache.nixos.org>; it contains binaries for most
|
||||
> packages in Nixpkgs. Only if no binary is available in the binary
|
||||
> cache, Nix will build the package from source. So if `nix-env
|
||||
> -i subversion` results in Nix building stuff from source, then either
|
||||
> -iA nixpkgs.subversion` results in Nix building stuff from source, then either
|
||||
> the package is not built for your platform by the Nixpkgs build
|
||||
> servers, or your version of Nixpkgs is too old or too new. For
|
||||
> instance, if you have a very recent checkout of Nixpkgs, then the
|
||||
|
@ -133,7 +137,10 @@ will install the package called `subversion` (which is, of course, the
|
|||
> using a Git checkout of the Nixpkgs tree), you will get binaries for
|
||||
> most packages.
|
||||
|
||||
Naturally, packages can also be uninstalled:
|
||||
Naturally, packages can also be uninstalled. Unlike when installing, you will
|
||||
need to use the derivation name (though the version part can be omitted),
|
||||
instead of the attribute path, as `nix-env` does not record which attribute
|
||||
was used for installing:
|
||||
|
||||
```console
|
||||
$ nix-env -e subversion
|
||||
|
@ -143,7 +150,7 @@ Upgrading to a new version is just as easy. If you have a new release of
|
|||
Nix Packages, you can do:
|
||||
|
||||
```console
|
||||
$ nix-env -u subversion
|
||||
$ nix-env -uA nixpkgs.subversion
|
||||
```
|
||||
|
||||
This will *only* upgrade Subversion if there is a “newer” version in the
|
||||
|
|
|
@ -9,7 +9,7 @@ The daemon that handles binary cache requests via HTTP, `nix-serve`, is
|
|||
not part of the Nix distribution, but you can install it from Nixpkgs:
|
||||
|
||||
```console
|
||||
$ nix-env -i nix-serve
|
||||
$ nix-env -iA nixpkgs.nix-serve
|
||||
```
|
||||
|
||||
You can then start the server, listening for HTTP connections on
|
||||
|
@ -35,7 +35,7 @@ On the client side, you can tell Nix to use your binary cache using
|
|||
`--option extra-binary-caches`, e.g.:
|
||||
|
||||
```console
|
||||
$ nix-env -i firefox --option extra-binary-caches http://avalon:8080/
|
||||
$ nix-env -iA nixpkgs.firefox --option extra-binary-caches http://avalon:8080/
|
||||
```
|
||||
|
||||
The option `extra-binary-caches` tells Nix to use this binary cache in
|
||||
|
|
|
@ -44,7 +44,7 @@ collector as follows:
|
|||
$ nix-store --gc
|
||||
```
|
||||
|
||||
The behaviour of the gargage collector is affected by the
|
||||
The behaviour of the garbage collector is affected by the
|
||||
`keep-derivations` (default: true) and `keep-outputs` (default: false)
|
||||
options in the Nix configuration file. The defaults will ensure that all
|
||||
derivations that are build-time dependencies of garbage collector roots
|
||||
|
|
|
@ -39,7 +39,7 @@ just Subversion 1.1.2 (arrows in the figure indicate symlinks). This
|
|||
would be what we would obtain if we had done
|
||||
|
||||
```console
|
||||
$ nix-env -i subversion
|
||||
$ nix-env -iA nixpkgs.subversion
|
||||
```
|
||||
|
||||
on a set of Nix expressions that contained Subversion 1.1.2.
|
||||
|
@ -54,7 +54,7 @@ environment is generated based on the current one. For instance,
|
|||
generation 43 was created from generation 42 when we did
|
||||
|
||||
```console
|
||||
$ nix-env -i subversion firefox
|
||||
$ nix-env -iA nixpkgs.subversion nixpkgs.firefox
|
||||
```
|
||||
|
||||
on a set of Nix expressions that contained Firefox and a new version of
|
||||
|
@ -127,7 +127,7 @@ All `nix-env` operations work on the profile pointed to by
|
|||
(abbreviation `-p`):
|
||||
|
||||
```console
|
||||
$ nix-env -p /nix/var/nix/profiles/other-profile -i subversion
|
||||
$ nix-env -p /nix/var/nix/profiles/other-profile -iA nixpkgs.subversion
|
||||
```
|
||||
|
||||
This will *not* change the `~/.nix-profile` symlink.
|
||||
|
|
|
@ -6,7 +6,7 @@ automatically fetching any store paths in Firefox’s closure if they are
|
|||
available on the server `avalon`:
|
||||
|
||||
```console
|
||||
$ nix-env -i firefox --substituters ssh://alice@avalon
|
||||
$ nix-env -iA nixpkgs.firefox --substituters ssh://alice@avalon
|
||||
```
|
||||
|
||||
This works similar to the binary cache substituter that Nix usually
|
||||
|
|
|
@ -19,19 +19,19 @@ to subsequent chapters.
|
|||
channel:
|
||||
|
||||
```console
|
||||
$ nix-env -qa
|
||||
docbook-xml-4.3
|
||||
docbook-xml-4.5
|
||||
firefox-33.0.2
|
||||
hello-2.9
|
||||
libxslt-1.1.28
|
||||
$ nix-env -qaP
|
||||
nixpkgs.docbook_xml_dtd_43 docbook-xml-4.3
|
||||
nixpkgs.docbook_xml_dtd_45 docbook-xml-4.5
|
||||
nixpkgs.firefox firefox-33.0.2
|
||||
nixpkgs.hello hello-2.9
|
||||
nixpkgs.libxslt libxslt-1.1.28
|
||||
…
|
||||
```
|
||||
|
||||
1. Install some packages from the channel:
|
||||
|
||||
```console
|
||||
$ nix-env -i hello
|
||||
$ nix-env -iA nixpkgs.hello
|
||||
```
|
||||
|
||||
This should download pre-built packages; it should not build them
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Release 2.4 (2021-10-XX)
|
||||
# Release 2.4 (2021-11-01)
|
||||
|
||||
This is the first release in more than two years and is the result of
|
||||
more than 2800 commits from 195 contributors since release 2.3.
|
||||
|
@ -276,18 +276,62 @@ more than 2800 commits from 195 contributors since release 2.3.
|
|||
|
||||
* Plugins can now register `nix` subcommands.
|
||||
|
||||
* The `--indirect` flag to `nix-store --add-root` has become a no-op.
|
||||
`--add-root` will always generate indirect GC roots from now on.
|
||||
|
||||
## Incompatible changes
|
||||
|
||||
* The `nix` command is now marked as an experimental feature. This
|
||||
means that you need to add
|
||||
|
||||
> experimental-features = nix-command
|
||||
```
|
||||
experimental-features = nix-command
|
||||
```
|
||||
|
||||
to your `nix.conf` if you want to use it, or pass
|
||||
`--extra-experimental-features nix-command` on the command line.
|
||||
|
||||
* The old `nix run` has been renamed to `nix shell` (and there is a
|
||||
new `nix run` that does something else, as described above).
|
||||
* The `nix` command no longer has a syntax for referring to packages
|
||||
in a channel. This means that the following no longer works:
|
||||
|
||||
```console
|
||||
nix build nixpkgs.hello # Nix 2.3
|
||||
```
|
||||
|
||||
Instead, you can either use the `#` syntax to select a package from
|
||||
a flake, e.g.
|
||||
|
||||
```console
|
||||
nix build nixpkgs#hello
|
||||
```
|
||||
|
||||
Or, if you want to use the `nixpkgs` channel in the `NIX_PATH`
|
||||
environment variable:
|
||||
|
||||
```console
|
||||
nix build -f '<nixpkgs>' hello
|
||||
```
|
||||
|
||||
* The old `nix run` has been renamed to `nix shell`, while there is a
|
||||
new `nix run` that runs a default command. So instead of
|
||||
|
||||
```console
|
||||
nix run nixpkgs.hello -c hello # Nix 2.3
|
||||
```
|
||||
|
||||
you should use
|
||||
|
||||
```console
|
||||
nix shell nixpkgs#hello -c hello
|
||||
```
|
||||
|
||||
or just
|
||||
|
||||
```console
|
||||
nix run nixpkgs#hello
|
||||
```
|
||||
|
||||
if the command you want to run has the same name as the package.
|
||||
|
||||
* It is now an error to modify the `plugin-files` setting via a
|
||||
command-line flag that appears after the first non-flag argument to
|
||||
|
@ -354,6 +398,7 @@ dramforever,
|
|||
Dustin DeWeese,
|
||||
edef,
|
||||
Eelco Dolstra,
|
||||
Ellie Hermaszewska,
|
||||
Emilio Karakey,
|
||||
Emily,
|
||||
Eric Culp,
|
||||
|
@ -364,7 +409,7 @@ Federico Pellegrin,
|
|||
Finn Behrens,
|
||||
Florian Franzen,
|
||||
Félix Baylac-Jacqué,
|
||||
Gabriel Gonzalez,
|
||||
Gabriella Gonzalez,
|
||||
Geoff Reedy,
|
||||
Georges Dubus,
|
||||
Graham Christensen,
|
||||
|
@ -387,7 +432,6 @@ Jaroslavas Pocepko,
|
|||
Jarrett Keifer,
|
||||
Jeremy Schlatter,
|
||||
Joachim Breitner,
|
||||
Joe Hermaszewski,
|
||||
Joe Pea,
|
||||
John Ericson,
|
||||
Jonathan Ringer,
|
||||
|
|
|
@ -1,2 +1,16 @@
|
|||
# Release 2.5 (2021-XX-XX)
|
||||
# Release 2.5 (2021-12-13)
|
||||
|
||||
* The garbage collector no longer blocks new builds, so the message
|
||||
`waiting for the big garbage collector lock...` is a thing of the
|
||||
past.
|
||||
|
||||
* Binary cache stores now have a setting `compression-level`.
|
||||
|
||||
* `nix develop` now has a flag `--unpack` to run `unpackPhase`.
|
||||
|
||||
* Lists can now be compared lexicographically using the `<` operator.
|
||||
|
||||
* New built-in function: `builtins.groupBy`, with the same functionality as
|
||||
Nixpkgs' `lib.groupBy`, but faster.
|
||||
|
||||
* `nix repl` now has a `:log` command.
|
||||
|
|
21
doc/manual/src/release-notes/rl-2.6.md
Normal file
21
doc/manual/src/release-notes/rl-2.6.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Release 2.6 (2022-01-24)
|
||||
|
||||
* The Nix CLI now searches for a `flake.nix` up until the root of the current
|
||||
Git repository or a filesystem boundary rather than just in the current
|
||||
directory.
|
||||
* The TOML parser used by `builtins.fromTOML` has been replaced by [a
|
||||
more compliant one](https://github.com/ToruNiina/toml11).
|
||||
* Added `:st`/`:show-trace` commands to `nix repl`, which are used to
|
||||
set or toggle display of error traces.
|
||||
* New builtin function `builtins.zipAttrsWith` with the same
|
||||
functionality as `lib.zipAttrsWith` from Nixpkgs, but much more
|
||||
efficient.
|
||||
* New command `nix store copy-log` to copy build logs from one store
|
||||
to another.
|
||||
* The `commit-lockfile-summary` option can be set to a non-empty
|
||||
string to override the commit summary used when commiting an updated
|
||||
lockfile. This may be used in conjunction with the `nixConfig`
|
||||
attribute in `flake.nix` to better conform to repository
|
||||
conventions.
|
||||
* `docker run -ti nixos/nix:master` will place you in the Docker
|
||||
container with the latest version of Nix from the `master` branch.
|
33
doc/manual/src/release-notes/rl-2.7.md
Normal file
33
doc/manual/src/release-notes/rl-2.7.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Release X.Y (2022-03-07)
|
||||
|
||||
* Nix will now make some helpful suggestions when you mistype
|
||||
something on the command line. For instance, if you type `nix build
|
||||
nixpkgs#thunderbrd`, it will suggest `thunderbird`.
|
||||
|
||||
* A number of "default" flake output attributes have been
|
||||
renamed. These are:
|
||||
|
||||
* `defaultPackage.<system>` → `packages.<system>.default`
|
||||
* `defaultApps.<system>` → `apps.<system>.default`
|
||||
* `defaultTemplate` → `templates.default`
|
||||
* `defaultBundler.<system>` → `bundlers.<system>.default`
|
||||
* `overlay` → `overlays.default`
|
||||
* `devShell.<system>` → `devShells.<system>.default`
|
||||
|
||||
The old flake output attributes still work, but `nix flake check`
|
||||
will warn about them.
|
||||
|
||||
* Breaking API change: `nix bundle` now supports bundlers of the form
|
||||
`bundler.<system>.<name>= derivation: another-derivation;`. This
|
||||
supports additional functionality to inspect evaluation information
|
||||
during bundling. A new
|
||||
[repository](https://github.com/NixOS/bundlers) has various bundlers
|
||||
implemented.
|
||||
|
||||
* `nix store ping` now reports the version of the remote Nix daemon.
|
||||
|
||||
* `nix flake {init,new}` now display information about which files have been
|
||||
created.
|
||||
|
||||
* Templates can now define a `welcomeText` attribute, which is printed out by
|
||||
`nix flake {init,new} --template <template>`.
|
1
doc/manual/src/release-notes/rl-next.md
Normal file
1
doc/manual/src/release-notes/rl-next.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Release X.Y (202?-??-??)
|
264
docker.nix
Normal file
264
docker.nix
Normal file
|
@ -0,0 +1,264 @@
|
|||
{ pkgs ? import <nixpkgs> { }
|
||||
, lib ? pkgs.lib
|
||||
, name ? "nix"
|
||||
, tag ? "latest"
|
||||
, channelName ? "nixpkgs"
|
||||
, channelURL ? "https://nixos.org/channels/nixpkgs-unstable"
|
||||
}:
|
||||
let
|
||||
defaultPkgs = with pkgs; [
|
||||
nix
|
||||
bashInteractive
|
||||
coreutils-full
|
||||
gnutar
|
||||
gzip
|
||||
gnugrep
|
||||
which
|
||||
curl
|
||||
less
|
||||
wget
|
||||
man
|
||||
cacert.out
|
||||
findutils
|
||||
iana-etc
|
||||
git
|
||||
];
|
||||
|
||||
users = {
|
||||
|
||||
root = {
|
||||
uid = 0;
|
||||
shell = "/bin/bash";
|
||||
home = "/root";
|
||||
gid = 0;
|
||||
};
|
||||
|
||||
} // lib.listToAttrs (
|
||||
map
|
||||
(
|
||||
n: {
|
||||
name = "nixbld${toString n}";
|
||||
value = {
|
||||
uid = 30000 + n;
|
||||
gid = 30000;
|
||||
groups = [ "nixbld" ];
|
||||
description = "Nix build user ${toString n}";
|
||||
};
|
||||
}
|
||||
)
|
||||
(lib.lists.range 1 32)
|
||||
);
|
||||
|
||||
groups = {
|
||||
root.gid = 0;
|
||||
nixbld.gid = 30000;
|
||||
};
|
||||
|
||||
userToPasswd = (
|
||||
k:
|
||||
{ uid
|
||||
, gid ? 65534
|
||||
, home ? "/var/empty"
|
||||
, description ? ""
|
||||
, shell ? "/bin/false"
|
||||
, groups ? [ ]
|
||||
}: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}"
|
||||
);
|
||||
passwdContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs userToPasswd users))
|
||||
);
|
||||
|
||||
userToShadow = k: { ... }: "${k}:!:1::::::";
|
||||
shadowContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs userToShadow users))
|
||||
);
|
||||
|
||||
# Map groups to members
|
||||
# {
|
||||
# group = [ "user1" "user2" ];
|
||||
# }
|
||||
groupMemberMap = (
|
||||
let
|
||||
# Create a flat list of user/group mappings
|
||||
mappings = (
|
||||
builtins.foldl'
|
||||
(
|
||||
acc: user:
|
||||
let
|
||||
groups = users.${user}.groups or [ ];
|
||||
in
|
||||
acc ++ map
|
||||
(group: {
|
||||
inherit user group;
|
||||
})
|
||||
groups
|
||||
)
|
||||
[ ]
|
||||
(lib.attrNames users)
|
||||
);
|
||||
in
|
||||
(
|
||||
builtins.foldl'
|
||||
(
|
||||
acc: v: acc // {
|
||||
${v.group} = acc.${v.group} or [ ] ++ [ v.user ];
|
||||
}
|
||||
)
|
||||
{ }
|
||||
mappings)
|
||||
);
|
||||
|
||||
groupToGroup = k: { gid }:
|
||||
let
|
||||
members = groupMemberMap.${k} or [ ];
|
||||
in
|
||||
"${k}:x:${toString gid}:${lib.concatStringsSep "," members}";
|
||||
groupContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs groupToGroup groups))
|
||||
);
|
||||
|
||||
nixConf = {
|
||||
sandbox = "false";
|
||||
build-users-group = "nixbld";
|
||||
trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=";
|
||||
};
|
||||
nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n";
|
||||
|
||||
baseSystem =
|
||||
let
|
||||
nixpkgs = pkgs.path;
|
||||
channel = pkgs.runCommand "channel-nixos" { } ''
|
||||
mkdir $out
|
||||
ln -s ${nixpkgs} $out/nixpkgs
|
||||
echo "[]" > $out/manifest.nix
|
||||
'';
|
||||
rootEnv = pkgs.buildPackages.buildEnv {
|
||||
name = "root-profile-env";
|
||||
paths = defaultPkgs;
|
||||
};
|
||||
manifest = pkgs.buildPackages.runCommand "manifest.nix" { } ''
|
||||
cat > $out <<EOF
|
||||
[
|
||||
${lib.concatStringsSep "\n" (builtins.map (drv: let
|
||||
outputs = drv.outputsToInstall or [ "out" ];
|
||||
in ''
|
||||
{
|
||||
${lib.concatStringsSep "\n" (builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'') outputs)}
|
||||
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
|
||||
name = "${drv.name}";
|
||||
outPath = "${drv}";
|
||||
system = "${drv.system}";
|
||||
type = "derivation";
|
||||
meta = { };
|
||||
}
|
||||
'') defaultPkgs)}
|
||||
]
|
||||
EOF
|
||||
'';
|
||||
profile = pkgs.buildPackages.runCommand "user-environment" { } ''
|
||||
mkdir $out
|
||||
cp -a ${rootEnv}/* $out/
|
||||
ln -s ${manifest} $out/manifest.nix
|
||||
'';
|
||||
in
|
||||
pkgs.runCommand "base-system"
|
||||
{
|
||||
inherit passwdContents groupContents shadowContents nixConfContents;
|
||||
passAsFile = [
|
||||
"passwdContents"
|
||||
"groupContents"
|
||||
"shadowContents"
|
||||
"nixConfContents"
|
||||
];
|
||||
allowSubstitutes = false;
|
||||
preferLocalBuild = true;
|
||||
} ''
|
||||
env
|
||||
set -x
|
||||
mkdir -p $out/etc
|
||||
|
||||
mkdir -p $out/etc/ssl/certs
|
||||
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
|
||||
|
||||
cat $passwdContentsPath > $out/etc/passwd
|
||||
echo "" >> $out/etc/passwd
|
||||
|
||||
cat $groupContentsPath > $out/etc/group
|
||||
echo "" >> $out/etc/group
|
||||
|
||||
cat $shadowContentsPath > $out/etc/shadow
|
||||
echo "" >> $out/etc/shadow
|
||||
|
||||
mkdir -p $out/usr
|
||||
ln -s /nix/var/nix/profiles/share $out/usr/
|
||||
|
||||
mkdir -p $out/nix/var/nix/gcroots
|
||||
|
||||
mkdir $out/tmp
|
||||
|
||||
mkdir -p $out/var/tmp
|
||||
|
||||
mkdir -p $out/etc/nix
|
||||
cat $nixConfContentsPath > $out/etc/nix/nix.conf
|
||||
|
||||
mkdir -p $out/root
|
||||
mkdir -p $out/nix/var/nix/profiles/per-user/root
|
||||
|
||||
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
||||
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
|
||||
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile
|
||||
|
||||
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
|
||||
ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels
|
||||
|
||||
mkdir -p $out/root/.nix-defexpr
|
||||
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
|
||||
echo "${channelURL} ${channelName}" > $out/root/.nix-channels
|
||||
|
||||
mkdir -p $out/bin $out/usr/bin
|
||||
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
|
||||
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
|
||||
'';
|
||||
|
||||
in
|
||||
pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||
|
||||
inherit name tag;
|
||||
|
||||
contents = [ baseSystem ];
|
||||
|
||||
extraCommands = ''
|
||||
rm -rf nix-support
|
||||
ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles
|
||||
'';
|
||||
fakeRootCommands = ''
|
||||
chmod 1777 tmp
|
||||
chmod 1777 var/tmp
|
||||
'';
|
||||
|
||||
config = {
|
||||
Cmd = [ "/root/.nix-profile/bin/bash" ];
|
||||
Env = [
|
||||
"USER=root"
|
||||
"PATH=${lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/bin"
|
||||
"/nix/var/nix/profiles/default/bin"
|
||||
"/nix/var/nix/profiles/default/sbin"
|
||||
]}"
|
||||
"MANPATH=${lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/share/man"
|
||||
"/nix/var/nix/profiles/default/share/man"
|
||||
]}"
|
||||
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels"
|
||||
];
|
||||
};
|
||||
|
||||
}
|
18
flake.lock
18
flake.lock
|
@ -31,10 +31,26 @@
|
|||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-regression": {
|
||||
"locked": {
|
||||
"lastModified": 1643052045,
|
||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"lowdown-src": "lowdown-src",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-regression": "nixpkgs-regression"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
498
flake.nix
498
flake.nix
|
@ -2,9 +2,10 @@
|
|||
description = "The purely functional package manager";
|
||||
|
||||
inputs.nixpkgs.url = "nixpkgs/nixos-21.05-small";
|
||||
inputs.nixpkgs-regression.url = "nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||
inputs.lowdown-src = { url = "github:kristapsdz/lowdown"; flake = false; };
|
||||
|
||||
outputs = { self, nixpkgs, lowdown-src }:
|
||||
outputs = { self, nixpkgs, nixpkgs-regression, lowdown-src }:
|
||||
|
||||
let
|
||||
|
||||
|
@ -22,15 +23,36 @@
|
|||
|
||||
crossSystems = [ "armv6l-linux" "armv7l-linux" ];
|
||||
|
||||
stdenvs = [ "gccStdenv" "clangStdenv" "clang11Stdenv" "stdenv" ];
|
||||
|
||||
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
|
||||
forAllSystemsAndStdenvs = f: forAllSystems (system:
|
||||
nixpkgs.lib.listToAttrs
|
||||
(map
|
||||
(n:
|
||||
nixpkgs.lib.nameValuePair "${n}Packages" (
|
||||
f system n
|
||||
)) stdenvs
|
||||
)
|
||||
);
|
||||
|
||||
forAllStdenvs = stdenvs: f: nixpkgs.lib.genAttrs stdenvs (stdenv: f stdenv);
|
||||
|
||||
# Memoize nixpkgs for different platforms for efficiency.
|
||||
nixpkgsFor = forAllSystems (system:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ self.overlay ];
|
||||
}
|
||||
);
|
||||
nixpkgsFor =
|
||||
let stdenvsPackages = forAllSystemsAndStdenvs
|
||||
(system: stdenv:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(overlayFor (p: p.${stdenv}))
|
||||
];
|
||||
}
|
||||
);
|
||||
in
|
||||
# Add the `stdenvPackages` at toplevel, both because these are the ones
|
||||
# we want most of the time and for backwards compatibility
|
||||
forAllSystems (system: stdenvsPackages.${system} // stdenvsPackages.${system}.stdenvPackages);
|
||||
|
||||
commonDeps = pkgs: with pkgs; rec {
|
||||
# Use "busybox-sandbox-shell" if present,
|
||||
|
@ -61,6 +83,7 @@
|
|||
|
||||
configureFlags =
|
||||
lib.optionals stdenv.isLinux [
|
||||
"--with-boost=${boost}/lib"
|
||||
"--with-sandbox-shell=${sh}/bin/busybox"
|
||||
"LDFLAGS=-fuse-ld=gold"
|
||||
];
|
||||
|
@ -74,7 +97,7 @@
|
|||
buildPackages.mdbook
|
||||
buildPackages.autoconf-archive
|
||||
buildPackages.autoreconfHook
|
||||
buildPackages.pkgconfig
|
||||
buildPackages.pkg-config
|
||||
|
||||
# Tests
|
||||
buildPackages.git
|
||||
|
@ -90,7 +113,7 @@
|
|||
libarchive
|
||||
boost
|
||||
lowdown-nix
|
||||
gmock
|
||||
gtest
|
||||
]
|
||||
++ lib.optionals stdenv.isLinux [libseccomp]
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
||||
|
@ -110,6 +133,7 @@
|
|||
./boehmgc-coroutine-sp-fallback.diff
|
||||
];
|
||||
}))
|
||||
nlohmann_json
|
||||
];
|
||||
|
||||
perlDeps =
|
||||
|
@ -118,8 +142,8 @@
|
|||
];
|
||||
};
|
||||
|
||||
installScriptFor = systems:
|
||||
with nixpkgsFor.x86_64-linux;
|
||||
installScriptFor = systems:
|
||||
with nixpkgsFor.x86_64-linux;
|
||||
runCommand "installer-script"
|
||||
{ buildInputs = [ nix ];
|
||||
}
|
||||
|
@ -183,191 +207,209 @@
|
|||
installCheckPhase = "make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES";
|
||||
};
|
||||
|
||||
binaryTarball = buildPackages: nix: pkgs: let
|
||||
inherit (pkgs) cacert;
|
||||
installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix cacert ]; };
|
||||
in
|
||||
binaryTarball = buildPackages: nix: pkgs:
|
||||
let
|
||||
inherit (pkgs) cacert;
|
||||
installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix cacert ]; };
|
||||
in
|
||||
|
||||
buildPackages.runCommand "nix-binary-tarball-${version}"
|
||||
{ #nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
|
||||
meta.description = "Distribution-independent Nix bootstrap binaries for ${pkgs.system}";
|
||||
}
|
||||
''
|
||||
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
|
||||
cp ${./scripts/create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
|
||||
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
buildPackages.runCommand "nix-binary-tarball-${version}"
|
||||
{ #nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
|
||||
meta.description = "Distribution-independent Nix bootstrap binaries for ${pkgs.system}";
|
||||
}
|
||||
''
|
||||
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
|
||||
cp ${./scripts/create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
|
||||
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
|
||||
substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-multi-user.sh} $TMPDIR/install-multi-user \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-multi-user.sh} $TMPDIR/install-multi-user \
|
||||
--subst-var-by nix ${nix} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
|
||||
if type -p shellcheck; then
|
||||
# SC1090: Don't worry about not being able to find
|
||||
# $nix/etc/profile.d/nix.sh
|
||||
shellcheck --exclude SC1090 $TMPDIR/install
|
||||
shellcheck $TMPDIR/create-darwin-volume.sh
|
||||
shellcheck $TMPDIR/install-darwin-multi-user.sh
|
||||
shellcheck $TMPDIR/install-systemd-multi-user.sh
|
||||
if type -p shellcheck; then
|
||||
# SC1090: Don't worry about not being able to find
|
||||
# $nix/etc/profile.d/nix.sh
|
||||
shellcheck --exclude SC1090 $TMPDIR/install
|
||||
shellcheck $TMPDIR/create-darwin-volume.sh
|
||||
shellcheck $TMPDIR/install-darwin-multi-user.sh
|
||||
shellcheck $TMPDIR/install-systemd-multi-user.sh
|
||||
|
||||
# SC1091: Don't panic about not being able to source
|
||||
# /etc/profile
|
||||
# SC2002: Ignore "useless cat" "error", when loading
|
||||
# .reginfo, as the cat is a much cleaner
|
||||
# implementation, even though it is "useless"
|
||||
# SC2116: Allow ROOT_HOME=$(echo ~root) for resolving
|
||||
# root's home directory
|
||||
shellcheck --external-sources \
|
||||
--exclude SC1091,SC2002,SC2116 $TMPDIR/install-multi-user
|
||||
fi
|
||||
# SC1091: Don't panic about not being able to source
|
||||
# /etc/profile
|
||||
# SC2002: Ignore "useless cat" "error", when loading
|
||||
# .reginfo, as the cat is a much cleaner
|
||||
# implementation, even though it is "useless"
|
||||
# SC2116: Allow ROOT_HOME=$(echo ~root) for resolving
|
||||
# root's home directory
|
||||
shellcheck --external-sources \
|
||||
--exclude SC1091,SC2002,SC2116 $TMPDIR/install-multi-user
|
||||
fi
|
||||
|
||||
chmod +x $TMPDIR/install
|
||||
chmod +x $TMPDIR/create-darwin-volume.sh
|
||||
chmod +x $TMPDIR/install-darwin-multi-user.sh
|
||||
chmod +x $TMPDIR/install-systemd-multi-user.sh
|
||||
chmod +x $TMPDIR/install-multi-user
|
||||
dir=nix-${version}-${pkgs.system}
|
||||
fn=$out/$dir.tar.xz
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist $fn" >> $out/nix-support/hydra-build-products
|
||||
tar cvfJ $fn \
|
||||
--owner=0 --group=0 --mode=u+rw,uga+r \
|
||||
--absolute-names \
|
||||
--hard-dereference \
|
||||
--transform "s,$TMPDIR/install,$dir/install," \
|
||||
--transform "s,$TMPDIR/create-darwin-volume.sh,$dir/create-darwin-volume.sh," \
|
||||
--transform "s,$TMPDIR/reginfo,$dir/.reginfo," \
|
||||
--transform "s,$NIX_STORE,$dir/store,S" \
|
||||
$TMPDIR/install \
|
||||
$TMPDIR/create-darwin-volume.sh \
|
||||
$TMPDIR/install-darwin-multi-user.sh \
|
||||
$TMPDIR/install-systemd-multi-user.sh \
|
||||
$TMPDIR/install-multi-user \
|
||||
$TMPDIR/reginfo \
|
||||
$(cat ${installerClosureInfo}/store-paths)
|
||||
'';
|
||||
chmod +x $TMPDIR/install
|
||||
chmod +x $TMPDIR/create-darwin-volume.sh
|
||||
chmod +x $TMPDIR/install-darwin-multi-user.sh
|
||||
chmod +x $TMPDIR/install-systemd-multi-user.sh
|
||||
chmod +x $TMPDIR/install-multi-user
|
||||
dir=nix-${version}-${pkgs.system}
|
||||
fn=$out/$dir.tar.xz
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist $fn" >> $out/nix-support/hydra-build-products
|
||||
tar cvfJ $fn \
|
||||
--owner=0 --group=0 --mode=u+rw,uga+r \
|
||||
--absolute-names \
|
||||
--hard-dereference \
|
||||
--transform "s,$TMPDIR/install,$dir/install," \
|
||||
--transform "s,$TMPDIR/create-darwin-volume.sh,$dir/create-darwin-volume.sh," \
|
||||
--transform "s,$TMPDIR/reginfo,$dir/.reginfo," \
|
||||
--transform "s,$NIX_STORE,$dir/store,S" \
|
||||
$TMPDIR/install \
|
||||
$TMPDIR/create-darwin-volume.sh \
|
||||
$TMPDIR/install-darwin-multi-user.sh \
|
||||
$TMPDIR/install-systemd-multi-user.sh \
|
||||
$TMPDIR/install-multi-user \
|
||||
$TMPDIR/reginfo \
|
||||
$(cat ${installerClosureInfo}/store-paths)
|
||||
'';
|
||||
|
||||
overlayFor = getStdenv: final: prev:
|
||||
let currentStdenv = getStdenv final; in
|
||||
{
|
||||
nixStable = prev.nix;
|
||||
|
||||
# Forward from the previous stage as we don’t want it to pick the lowdown override
|
||||
nixUnstable = prev.nixUnstable;
|
||||
|
||||
nix = with final; with commonDeps pkgs; currentStdenv.mkDerivation {
|
||||
name = "nix-${version}";
|
||||
inherit version;
|
||||
|
||||
src = self;
|
||||
|
||||
VERSION_SUFFIX = versionSuffix;
|
||||
|
||||
outputs = [ "out" "dev" "doc" ];
|
||||
|
||||
nativeBuildInputs = nativeBuildDeps;
|
||||
buildInputs = buildDeps ++ awsDeps;
|
||||
|
||||
propagatedBuildInputs = propagatedDeps;
|
||||
|
||||
disallowedReferences = [ boost ];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
# Copy libboost_context so we don't get all of Boost in our closure.
|
||||
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||
mkdir -p $out/lib
|
||||
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
|
||||
rm -f $out/lib/*.a
|
||||
${lib.optionalString currentStdenv.isLinux ''
|
||||
chmod u+w $out/lib/*.so.*
|
||||
patchelf --set-rpath $out/lib:${currentStdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
|
||||
''}
|
||||
${lib.optionalString currentStdenv.isDarwin ''
|
||||
for LIB in $out/lib/*.dylib; do
|
||||
chmod u+w $LIB
|
||||
install_name_tool -id $LIB $LIB
|
||||
done
|
||||
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
|
||||
''}
|
||||
'';
|
||||
|
||||
configureFlags = configureFlags ++
|
||||
[ "--sysconfdir=/etc" ];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||
|
||||
doCheck = true;
|
||||
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $doc/nix-support
|
||||
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
|
||||
${lib.optionalString currentStdenv.isDarwin ''
|
||||
install_name_tool \
|
||||
-change ${boost}/lib/libboost_context.dylib \
|
||||
$out/lib/libboost_context.dylib \
|
||||
$out/lib/libnixutil.dylib
|
||||
''}
|
||||
'';
|
||||
|
||||
doInstallCheck = true;
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
separateDebugInfo = true;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
passthru.perl-bindings = with final; currentStdenv.mkDerivation {
|
||||
name = "nix-perl-${version}";
|
||||
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs =
|
||||
[ buildPackages.autoconf-archive
|
||||
buildPackages.autoreconfHook
|
||||
buildPackages.pkg-config
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[ nix
|
||||
curl
|
||||
bzip2
|
||||
xz
|
||||
pkgs.perl
|
||||
boost
|
||||
]
|
||||
++ lib.optional (currentStdenv.isLinux || currentStdenv.isDarwin) libsodium
|
||||
++ lib.optional currentStdenv.isDarwin darwin.apple_sdk.frameworks.Security;
|
||||
|
||||
configureFlags = ''
|
||||
--with-dbi=${perlPackages.DBI}/${pkgs.perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${pkgs.perl.libPrefix}
|
||||
'';
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
postUnpack = "sourceRoot=$sourceRoot/perl";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
||||
name = "lowdown-0.9.0";
|
||||
|
||||
src = lowdown-src;
|
||||
|
||||
outputs = [ "out" "bin" "dev" ];
|
||||
|
||||
nativeBuildInputs = [ buildPackages.which ];
|
||||
|
||||
configurePhase = ''
|
||||
${if (currentStdenv.isDarwin && currentStdenv.isAarch64) then "echo \"HAVE_SANDBOX_INIT=false\" > configure.local" else ""}
|
||||
./configure \
|
||||
PREFIX=${placeholder "dev"} \
|
||||
BINDIR=${placeholder "bin"}/bin
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
# A Nixpkgs overlay that overrides the 'nix' and
|
||||
# 'nix.perl-bindings' packages.
|
||||
overlay = final: prev: {
|
||||
|
||||
nixStable = prev.nix;
|
||||
|
||||
# Forward from the previous stage as we don’t want it to pick the lowdown override
|
||||
nixUnstable = prev.nixUnstable;
|
||||
|
||||
nix = with final; with commonDeps pkgs; stdenv.mkDerivation {
|
||||
name = "nix-${version}";
|
||||
inherit version;
|
||||
|
||||
src = self;
|
||||
|
||||
VERSION_SUFFIX = versionSuffix;
|
||||
|
||||
outputs = [ "out" "dev" "doc" ];
|
||||
|
||||
nativeBuildInputs = nativeBuildDeps;
|
||||
buildInputs = buildDeps ++ awsDeps;
|
||||
|
||||
propagatedBuildInputs = propagatedDeps;
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
# Copy libboost_context so we don't get all of Boost in our closure.
|
||||
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||
mkdir -p $out/lib
|
||||
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
|
||||
rm -f $out/lib/*.a
|
||||
${lib.optionalString stdenv.isLinux ''
|
||||
chmod u+w $out/lib/*.so.*
|
||||
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
|
||||
''}
|
||||
'';
|
||||
|
||||
configureFlags = configureFlags ++
|
||||
[ "--sysconfdir=/etc" ];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||
|
||||
doCheck = true;
|
||||
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $doc/nix-support
|
||||
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
doInstallCheck = true;
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
separateDebugInfo = true;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
passthru.perl-bindings = with final; stdenv.mkDerivation {
|
||||
name = "nix-perl-${version}";
|
||||
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs =
|
||||
[ buildPackages.autoconf-archive
|
||||
buildPackages.autoreconfHook
|
||||
buildPackages.pkgconfig
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[ nix
|
||||
curl
|
||||
bzip2
|
||||
xz
|
||||
pkgs.perl
|
||||
boost
|
||||
]
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
||||
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security;
|
||||
|
||||
configureFlags = ''
|
||||
--with-dbi=${perlPackages.DBI}/${pkgs.perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${pkgs.perl.libPrefix}
|
||||
'';
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
postUnpack = "sourceRoot=$sourceRoot/perl";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
lowdown-nix = with final; stdenv.mkDerivation rec {
|
||||
name = "lowdown-0.9.0";
|
||||
|
||||
src = lowdown-src;
|
||||
|
||||
outputs = [ "out" "bin" "dev" ];
|
||||
|
||||
nativeBuildInputs = [ buildPackages.which ];
|
||||
|
||||
configurePhase = ''
|
||||
${if (stdenv.isDarwin && stdenv.isAarch64) then "echo \"HAVE_SANDBOX_INIT=false\" > configure.local" else ""}
|
||||
./configure \
|
||||
PREFIX=${placeholder "dev"} \
|
||||
BINDIR=${placeholder "bin"}/bin
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
overlay = overlayFor (p: p.stdenv);
|
||||
|
||||
hydraJobs = {
|
||||
|
||||
|
@ -404,6 +446,9 @@
|
|||
installerScript = installScriptFor [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" "armv6l-linux" "armv7l-linux" ];
|
||||
installerScriptForGHA = installScriptFor [ "x86_64-linux" "x86_64-darwin" "armv6l-linux" "armv7l-linux"];
|
||||
|
||||
# docker image with Nix inside
|
||||
dockerImage = nixpkgs.lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
||||
|
||||
# Line coverage analysis.
|
||||
coverage =
|
||||
with nixpkgsFor.x86_64-linux;
|
||||
|
@ -456,6 +501,12 @@
|
|||
inherit (self) overlay;
|
||||
});
|
||||
|
||||
tests.sourcehutFlakes = (import ./tests/sourcehut-flakes.nix rec {
|
||||
system = "x86_64-linux";
|
||||
inherit nixpkgs;
|
||||
inherit (self) overlay;
|
||||
});
|
||||
|
||||
tests.setuid = nixpkgs.lib.genAttrs
|
||||
["i686-linux" "x86_64-linux"]
|
||||
(system:
|
||||
|
@ -464,36 +515,25 @@
|
|||
inherit (self) overlay;
|
||||
});
|
||||
|
||||
/*
|
||||
# Check whether we can still evaluate all of Nixpkgs.
|
||||
# Make sure that nix-env still produces the exact same result
|
||||
# on a particular version of Nixpkgs.
|
||||
tests.evalNixpkgs =
|
||||
import (nixpkgs + "/pkgs/top-level/make-tarball.nix") {
|
||||
# FIXME: fix pkgs/top-level/make-tarball.nix in NixOS to not require a revCount.
|
||||
inherit nixpkgs;
|
||||
pkgs = nixpkgsFor.x86_64-linux;
|
||||
officialRelease = false;
|
||||
};
|
||||
|
||||
# Check whether we can still evaluate NixOS.
|
||||
tests.evalNixOS =
|
||||
with nixpkgsFor.x86_64-linux;
|
||||
runCommand "eval-nixos" { buildInputs = [ nix ]; }
|
||||
''
|
||||
export NIX_STATE_DIR=$TMPDIR
|
||||
|
||||
nix-instantiate ${nixpkgs}/nixos/release-combined.nix -A tested --dry-run \
|
||||
--arg nixpkgs '{ outPath = ${nixpkgs}; revCount = 123; shortRev = "abcdefgh"; }'
|
||||
|
||||
touch $out
|
||||
type -p nix-env
|
||||
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
|
||||
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
|
||||
[[ $(sha1sum < packages | cut -c1-40) = ff451c521e61e4fe72bdbe2d0ca5d1809affa733 ]]
|
||||
mkdir $out
|
||||
'';
|
||||
*/
|
||||
|
||||
};
|
||||
metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" {
|
||||
pkgs = nixpkgsFor.x86_64-linux;
|
||||
nixpkgs = nixpkgs-regression;
|
||||
};
|
||||
|
||||
checks = forAllSystems (system: {
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
perlBindings = self.hydraJobs.perlBindings.${system};
|
||||
installTests =
|
||||
installTests = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system}; in
|
||||
pkgs.runCommand "install-tests" {
|
||||
againstSelf = testNixVersions pkgs pkgs.nix pkgs.pkgs.nix;
|
||||
|
@ -505,7 +545,16 @@
|
|||
# Disabled because the latest stable version doesn't handle
|
||||
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
|
||||
# againstLatestStable = testNixVersions pkgs pkgs.nix pkgs.nixStable;
|
||||
} "touch $out";
|
||||
} "touch $out");
|
||||
|
||||
};
|
||||
|
||||
checks = forAllSystems (system: {
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
perlBindings = self.hydraJobs.perlBindings.${system};
|
||||
installTests = self.hydraJobs.installTests.${system};
|
||||
} // (nixpkgs.lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
|
||||
dockerImage = self.hydraJobs.dockerImage.${system};
|
||||
});
|
||||
|
||||
packages = forAllSystems (system: {
|
||||
|
@ -551,6 +600,20 @@
|
|||
|
||||
hardeningDisable = [ "pie" ];
|
||||
};
|
||||
dockerImage =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system};
|
||||
image = import ./docker.nix { inherit pkgs; tag = version; };
|
||||
in
|
||||
pkgs.runCommand
|
||||
"docker-image-tarball-${version}"
|
||||
{ meta.description = "Docker image with Nix for ${system}"; }
|
||||
''
|
||||
mkdir -p $out/nix-support
|
||||
image=$out/image.tar.gz
|
||||
ln -s ${image} $image
|
||||
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
} // builtins.listToAttrs (map (crossSystem: {
|
||||
name = "nix-${crossSystem}";
|
||||
value = let
|
||||
|
@ -590,15 +653,21 @@
|
|||
doInstallCheck = true;
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
};
|
||||
}) crossSystems)));
|
||||
}) crossSystems)) // (builtins.listToAttrs (map (stdenvName:
|
||||
nixpkgsFor.${system}.lib.nameValuePair
|
||||
"nix-${stdenvName}"
|
||||
nixpkgsFor.${system}."${stdenvName}Packages".nix
|
||||
) stdenvs)));
|
||||
|
||||
defaultPackage = forAllSystems (system: self.packages.${system}.nix);
|
||||
|
||||
devShell = forAllSystems (system:
|
||||
devShell = forAllSystems (system: self.devShells.${system}.stdenvPackages);
|
||||
|
||||
devShells = forAllSystemsAndStdenvs (system: stdenv:
|
||||
with nixpkgsFor.${system};
|
||||
with commonDeps pkgs;
|
||||
|
||||
stdenv.mkDerivation {
|
||||
nixpkgsFor.${system}.${stdenv}.mkDerivation {
|
||||
name = "nix";
|
||||
|
||||
outputs = [ "out" "dev" "doc" ];
|
||||
|
@ -617,6 +686,9 @@
|
|||
PATH=$prefix/bin:$PATH
|
||||
unset PYTHONPATH
|
||||
export MANPATH=$out/share/man:$MANPATH
|
||||
|
||||
# Make bash completion work.
|
||||
XDG_DATA_DIRS+=:$out/share
|
||||
'';
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ use LWP::UserAgent;
|
|||
use Net::Amazon::S3;
|
||||
|
||||
my $evalId = $ARGV[0] or die "Usage: $0 EVAL-ID\n";
|
||||
my $nixRev = $ARGV[1] or die; # FIXME
|
||||
|
||||
my $releasesBucketName = "nix-releases";
|
||||
my $channelsBucketName = "nix-channels";
|
||||
|
@ -36,10 +35,11 @@ sub fetch {
|
|||
}
|
||||
|
||||
my $evalUrl = "https://hydra.nixos.org/eval/$evalId";
|
||||
#my $evalInfo = decode_json(fetch($evalUrl, 'application/json'));
|
||||
my $evalInfo = decode_json(fetch($evalUrl, 'application/json'));
|
||||
#print Dumper($evalInfo);
|
||||
|
||||
#my $nixRev = $evalInfo->{jobsetevalinputs}->{nix}->{revision} or die;
|
||||
my $flakeUrl = $evalInfo->{flake} or die;
|
||||
my $flakeInfo = decode_json(`nix flake metadata --json "$flakeUrl"` or die);
|
||||
my $nixRev = $flakeInfo->{revision} or die;
|
||||
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/build.x86_64-linux", 'application/json'));
|
||||
#print Dumper($buildInfo);
|
||||
|
@ -48,13 +48,18 @@ my $releaseName = $buildInfo->{nixname};
|
|||
$releaseName =~ /nix-(.*)$/ or die;
|
||||
my $version = $1;
|
||||
|
||||
print STDERR "Nix revision is $nixRev, version is $version\n";
|
||||
print STDERR "Flake URL is $flakeUrl, Nix revision is $nixRev, version is $version\n";
|
||||
|
||||
my $releaseDir = "nix/$releaseName";
|
||||
|
||||
my $tmpDir = "$TMPDIR/nix-release/$releaseName";
|
||||
File::Path::make_path($tmpDir);
|
||||
|
||||
my $narCache = "$TMPDIR/nar-cache";
|
||||
File::Path::make_path($narCache);
|
||||
|
||||
my $binaryCache = "https://cache.nixos.org/?local-nar-cache=$narCache";
|
||||
|
||||
# S3 setup.
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "No AWS_ACCESS_KEY_ID given.";
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "No AWS_SECRET_ACCESS_KEY given.";
|
||||
|
@ -80,6 +85,7 @@ sub downloadFile {
|
|||
my ($jobName, $productNr, $dstName) = @_;
|
||||
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
|
||||
#print STDERR "$jobName: ", Dumper($buildInfo), "\n";
|
||||
|
||||
my $srcFile = $buildInfo->{buildproducts}->{$productNr}->{path} or die "job '$jobName' lacks product $productNr\n";
|
||||
$dstName //= basename($srcFile);
|
||||
|
@ -87,19 +93,27 @@ sub downloadFile {
|
|||
|
||||
if (!-e $tmpFile) {
|
||||
print STDERR "downloading $srcFile to $tmpFile...\n";
|
||||
system("NIX_REMOTE=https://cache.nixos.org/ nix store cat '$srcFile' > '$tmpFile'") == 0
|
||||
|
||||
my $fileInfo = decode_json(`NIX_REMOTE=$binaryCache nix store ls --json '$srcFile'`);
|
||||
|
||||
$srcFile = $fileInfo->{target} if $fileInfo->{type} eq 'symlink';
|
||||
|
||||
#print STDERR $srcFile, " ", Dumper($fileInfo), "\n";
|
||||
|
||||
system("NIX_REMOTE=$binaryCache nix store cat '$srcFile' > '$tmpFile'.tmp") == 0
|
||||
or die "unable to fetch $srcFile\n";
|
||||
rename("$tmpFile.tmp", $tmpFile) or die;
|
||||
}
|
||||
|
||||
my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash} or die;
|
||||
my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash};
|
||||
my $sha256_actual = `nix hash file --base16 --type sha256 '$tmpFile'`;
|
||||
chomp $sha256_actual;
|
||||
if ($sha256_expected ne $sha256_actual) {
|
||||
if (defined($sha256_expected) && $sha256_expected ne $sha256_actual) {
|
||||
print STDERR "file $tmpFile is corrupt, got $sha256_actual, expected $sha256_expected\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
write_file("$tmpFile.sha256", $sha256_expected);
|
||||
write_file("$tmpFile.sha256", $sha256_actual);
|
||||
|
||||
if (! -e "$tmpFile.asc") {
|
||||
system("gpg2 --detach-sign --armor $tmpFile") == 0 or die "unable to sign $tmpFile\n";
|
||||
|
@ -117,6 +131,60 @@ downloadFile("binaryTarballCross.x86_64-linux.armv6l-linux", "1");
|
|||
downloadFile("binaryTarballCross.x86_64-linux.armv7l-linux", "1");
|
||||
downloadFile("installerScript", "1");
|
||||
|
||||
# Upload docker images to dockerhub.
|
||||
my $dockerManifest = "";
|
||||
my $dockerManifestLatest = "";
|
||||
|
||||
for my $platforms (["x86_64-linux", "amd64"], ["aarch64-linux", "arm64"]) {
|
||||
my $system = $platforms->[0];
|
||||
my $dockerPlatform = $platforms->[1];
|
||||
my $fn = "nix-$version-docker-image-$dockerPlatform.tar.gz";
|
||||
downloadFile("dockerImage.$system", "1", $fn);
|
||||
|
||||
print STDERR "loading docker image for $dockerPlatform...\n";
|
||||
system("docker load -i $tmpDir/$fn") == 0 or die;
|
||||
|
||||
my $tag = "nixos/nix:$version-$dockerPlatform";
|
||||
my $latestTag = "nixos/nix:latest-$dockerPlatform";
|
||||
|
||||
print STDERR "tagging $version docker image for $dockerPlatform...\n";
|
||||
system("docker tag nix:$version $tag") == 0 or die;
|
||||
|
||||
if ($isLatest) {
|
||||
print STDERR "tagging latest docker image for $dockerPlatform...\n";
|
||||
system("docker tag nix:$version $latestTag") == 0 or die;
|
||||
}
|
||||
|
||||
print STDERR "pushing $version docker image for $dockerPlatform...\n";
|
||||
system("docker push -q $tag") == 0 or die;
|
||||
|
||||
if ($isLatest) {
|
||||
print STDERR "pushing latest docker image for $dockerPlatform...\n";
|
||||
system("docker push -q $latestTag") == 0 or die;
|
||||
}
|
||||
|
||||
$dockerManifest .= " --amend $tag";
|
||||
$dockerManifestLatest .= " --amend $latestTag"
|
||||
}
|
||||
|
||||
print STDERR "creating multi-platform docker manifest...\n";
|
||||
system("docker manifest rm nixos/nix:$version");
|
||||
system("docker manifest create nixos/nix:$version $dockerManifest") == 0 or die;
|
||||
if ($isLatest) {
|
||||
print STDERR "creating latest multi-platform docker manifest...\n";
|
||||
system("docker manifest rm nixos/nix:latest");
|
||||
system("docker manifest create nixos/nix:latest $dockerManifestLatest") == 0 or die;
|
||||
}
|
||||
|
||||
print STDERR "pushing multi-platform docker manifest...\n";
|
||||
system("docker manifest push nixos/nix:$version") == 0 or die;
|
||||
|
||||
if ($isLatest) {
|
||||
print STDERR "pushing latest multi-platform docker manifest...\n";
|
||||
system("docker manifest push nixos/nix:latest") == 0 or die;
|
||||
}
|
||||
|
||||
# Upload release files to S3.
|
||||
for my $fn (glob "$tmpDir/*") {
|
||||
my $name = basename($fn);
|
||||
my $dstKey = "$releaseDir/" . $name;
|
||||
|
@ -143,12 +211,7 @@ if ($isLatest) {
|
|||
sub getStorePath {
|
||||
my ($jobName) = @_;
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
|
||||
for my $product (values %{$buildInfo->{buildproducts}}) {
|
||||
next unless $product->{type} eq "nix-build";
|
||||
next if $product->{path} =~ /[a-z]+$/;
|
||||
return $product->{path};
|
||||
}
|
||||
die;
|
||||
return $buildInfo->{buildoutputs}->{out}->{path} or die "cannot get store path for '$jobName'";
|
||||
}
|
||||
|
||||
write_file("$nixpkgsDir/nixos/modules/installer/tools/nix-fallback-paths.nix",
|
||||
|
|
|
@ -7,13 +7,15 @@ function _complete_nix {
|
|||
local completion=${line%% *}
|
||||
if [[ -z $have_type ]]; then
|
||||
have_type=1
|
||||
if [[ $completion = filenames ]]; then
|
||||
if [[ $completion == filenames ]]; then
|
||||
compopt -o filenames
|
||||
elif [[ $completion == attrs ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
else
|
||||
COMPREPLY+=("$completion")
|
||||
fi
|
||||
done < <(NIX_GET_COMPLETIONS=$cword "${words[@]}")
|
||||
done < <(NIX_GET_COMPLETIONS=$cword "${words[@]/#\~/$HOME}" 2>/dev/null)
|
||||
__ltrim_colon_completions "$cur"
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ end
|
|||
|
||||
function _nix_accepts_files
|
||||
set -l response (_nix_complete)
|
||||
# First line is either filenames or no-filenames.
|
||||
test $response[1] = 'filenames'
|
||||
end
|
||||
|
||||
|
|
|
@ -25,5 +25,10 @@
|
|||
<string>/var/log/nix-daemon.log</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/dev/null</string>
|
||||
<key>SoftResourceLimits</key>
|
||||
<dict>
|
||||
<key>NumberOfFiles</key>
|
||||
<integer>4096</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -4,7 +4,7 @@ function _nix() {
|
|||
local ifs_bk="$IFS"
|
||||
local input=("${(Q)words[@]}")
|
||||
IFS=$'\n'
|
||||
local res=($(NIX_GET_COMPLETIONS=$((CURRENT - 1)) "$input[@]"))
|
||||
local res=($(NIX_GET_COMPLETIONS=$((CURRENT - 1)) "$input[@]" 2>/dev/null))
|
||||
IFS="$ifs_bk"
|
||||
local tpe="${${res[1]}%%> *}"
|
||||
local -a suggestions
|
||||
|
|
|
@ -125,8 +125,8 @@ define build-library
|
|||
$(1)_PATH := $$(_d)/$$($(1)_NAME).a
|
||||
|
||||
$$($(1)_PATH): $$($(1)_OBJS) | $$(_d)/
|
||||
$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$?
|
||||
$(trace-ar) $(AR) crs $$@ $$(_d)/$$($(1)_NAME).o
|
||||
$$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$?
|
||||
$$(trace-ar) $(AR) crs $$@ $$(_d)/$$($(1)_NAME).o
|
||||
|
||||
$(1)_LDFLAGS_USE += $$($(1)_PATH) $$($(1)_LDFLAGS)
|
||||
|
||||
|
|
|
@ -14,9 +14,27 @@ if [ -t 1 ]; then
|
|||
yellow="[33;1m"
|
||||
normal="[m"
|
||||
fi
|
||||
(cd tests && env ${TESTS_ENVIRONMENT} init.sh 2>/dev/null > /dev/null)
|
||||
log="$(cd $(dirname $1) && env ${TESTS_ENVIRONMENT} $(basename $1) 2>&1)"
|
||||
status=$?
|
||||
|
||||
run_test () {
|
||||
(cd tests && env ${TESTS_ENVIRONMENT} init.sh 2>/dev/null > /dev/null)
|
||||
log="$(cd $(dirname $1) && env ${TESTS_ENVIRONMENT} $(basename $1) 2>&1)"
|
||||
status=$?
|
||||
}
|
||||
|
||||
run_test "$1"
|
||||
|
||||
# Hack: Retry the test if it fails with “unexpected EOF reading a line” as these
|
||||
# appear randomly without anyone knowing why.
|
||||
# See https://github.com/NixOS/nix/issues/3605 for more info
|
||||
if [[ $status -ne 0 && $status -ne 99 && \
|
||||
"$(uname)" == "Darwin" && \
|
||||
"$log" =~ "unexpected EOF reading a line" \
|
||||
]]; then
|
||||
echo "$post_run_msg [${yellow}FAIL$normal] (possibly flaky, so will be retried)"
|
||||
echo "$log" | sed 's/^/ /'
|
||||
run_test "$1"
|
||||
fi
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "$post_run_msg [${green}PASS$normal]"
|
||||
elif [ $status -eq 99 ]; then
|
||||
|
|
399
nix-rust/Cargo.lock
generated
399
nix-rust/Cargo.lock
generated
|
@ -1,399 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "assert_matches"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "c2-chacha"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "nix-rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proptest"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusty-fork"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
|
||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
|
||||
"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
|
||||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
"checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae"
|
||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
"checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -1,23 +0,0 @@
|
|||
[package]
|
||||
name = "nix-rust"
|
||||
version = "0.1.0"
|
||||
authors = ["Eelco Dolstra <edolstra@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "nixrust"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
#futures-preview = { version = "=0.3.0-alpha.19" }
|
||||
#hyper = "0.13.0-alpha.4"
|
||||
#http = "0.1"
|
||||
#tokio = { version = "0.2.0-alpha.6", default-features = false, features = ["rt-full"] }
|
||||
lazy_static = "1.4"
|
||||
#byteorder = "1.3"
|
||||
|
||||
[dev-dependencies]
|
||||
hex = "0.3"
|
||||
assert_matches = "1.3"
|
||||
proptest = "0.9"
|
|
@ -1,48 +0,0 @@
|
|||
ifeq ($(OPTIMIZE), 1)
|
||||
RUST_MODE = --release
|
||||
RUST_DIR = release
|
||||
else
|
||||
RUST_MODE =
|
||||
RUST_DIR = debug
|
||||
endif
|
||||
|
||||
libnixrust_PATH := $(d)/target/$(RUST_DIR)/libnixrust.$(SO_EXT)
|
||||
libnixrust_INSTALL_PATH := $(libdir)/libnixrust.$(SO_EXT)
|
||||
libnixrust_LDFLAGS_USE := -L$(d)/target/$(RUST_DIR) -lnixrust
|
||||
libnixrust_LDFLAGS_USE_INSTALLED := -L$(libdir) -lnixrust
|
||||
|
||||
ifdef HOST_LINUX
|
||||
libnixrust_LDFLAGS_USE += -ldl
|
||||
libnixrust_LDFLAGS_USE_INSTALLED += -ldl
|
||||
endif
|
||||
|
||||
ifdef HOST_DARWIN
|
||||
libnixrust_BUILD_FLAGS = NIX_LDFLAGS="-undefined dynamic_lookup"
|
||||
else
|
||||
libnixrust_LDFLAGS_USE += -Wl,-rpath,$(abspath $(d)/target/$(RUST_DIR))
|
||||
libnixrust_LDFLAGS_USE_INSTALLED += -Wl,-rpath,$(libdir)
|
||||
endif
|
||||
|
||||
$(libnixrust_PATH): $(call rwildcard, $(d)/src, *.rs) $(d)/Cargo.toml
|
||||
$(trace-gen) cd nix-rust && CARGO_HOME=$$(if [[ -d vendor ]]; then echo vendor; fi) \
|
||||
$(libnixrust_BUILD_FLAGS) \
|
||||
cargo build $(RUST_MODE) $$(if [[ -d vendor ]]; then echo --offline; fi) \
|
||||
&& touch target/$(RUST_DIR)/libnixrust.$(SO_EXT)
|
||||
|
||||
$(libnixrust_INSTALL_PATH): $(libnixrust_PATH)
|
||||
$(target-gen) cp $^ $@
|
||||
ifdef HOST_DARWIN
|
||||
install_name_tool -id $@ $@
|
||||
endif
|
||||
|
||||
clean: clean-rust
|
||||
|
||||
clean-rust:
|
||||
$(suppress) rm -rfv nix-rust/target
|
||||
|
||||
ifndef HOST_DARWIN
|
||||
check: rust-tests
|
||||
|
||||
rust-tests:
|
||||
$(trace-test) cd nix-rust && CARGO_HOME=$$(if [[ -d vendor ]]; then echo vendor; fi) cargo test --release $$(if [[ -d vendor ]]; then echo --offline; fi)
|
||||
endif
|
|
@ -1,77 +0,0 @@
|
|||
use super::{error, store::path, store::StorePath, util};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_String_new(s: &str, out: *mut String) {
|
||||
// FIXME: check whether 's' is valid UTF-8?
|
||||
out.write(s.to_string())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_String_drop(self_: *mut String) {
|
||||
std::ptr::drop_in_place(self_);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_new(
|
||||
path: &str,
|
||||
store_dir: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::new(std::path::Path::new(path), std::path::Path::new(store_dir))
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_new2(
|
||||
hash: &[u8; crate::store::path::STORE_PATH_HASH_BYTES],
|
||||
name: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::from_parts(*hash, name).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_fromBaseName(
|
||||
base_name: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::new_from_base_name(base_name).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_StorePath_drop(self_: *mut StorePath) {
|
||||
std::ptr::drop_in_place(self_);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_to_string(self_: &StorePath) -> Vec<u8> {
|
||||
let mut buf = vec![0; path::STORE_PATH_HASH_CHARS + 1 + self_.name.name().len()];
|
||||
util::base32::encode_into(self_.hash.hash(), &mut buf[0..path::STORE_PATH_HASH_CHARS]);
|
||||
buf[path::STORE_PATH_HASH_CHARS] = b'-';
|
||||
buf[path::STORE_PATH_HASH_CHARS + 1..].clone_from_slice(self_.name.name().as_bytes());
|
||||
buf
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_less_than(a: &StorePath, b: &StorePath) -> bool {
|
||||
a < b
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_eq(a: &StorePath, b: &StorePath) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_clone(self_: &StorePath) -> StorePath {
|
||||
self_.clone()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_name(self_: &StorePath) -> &str {
|
||||
self_.name.name()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_hash_data(
|
||||
self_: &StorePath,
|
||||
) -> &[u8; crate::store::path::STORE_PATH_HASH_BYTES] {
|
||||
self_.hash.hash()
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidPath(crate::store::StorePath),
|
||||
BadStorePath(std::path::PathBuf),
|
||||
NotInStore(std::path::PathBuf),
|
||||
BadNarInfo,
|
||||
BadBase32,
|
||||
StorePathNameEmpty,
|
||||
StorePathNameTooLong,
|
||||
BadStorePathName,
|
||||
NarSizeFieldTooBig,
|
||||
BadNarString,
|
||||
BadNarPadding,
|
||||
BadNarVersionMagic,
|
||||
MissingNarOpenTag,
|
||||
MissingNarCloseTag,
|
||||
MissingNarField,
|
||||
BadNarField(String),
|
||||
BadExecutableField,
|
||||
IOError(std::io::Error),
|
||||
#[cfg(unused)]
|
||||
HttpError(hyper::error::Error),
|
||||
Misc(String),
|
||||
#[cfg(not(test))]
|
||||
Foreign(CppException),
|
||||
BadTarFileMemberName(String),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Error::IOError(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unused)]
|
||||
impl From<hyper::error::Error> for Error {
|
||||
fn from(err: hyper::error::Error) -> Self {
|
||||
Error::HttpError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::InvalidPath(_) => write!(f, "invalid path"),
|
||||
Error::BadNarInfo => write!(f, ".narinfo file is corrupt"),
|
||||
Error::BadStorePath(path) => write!(f, "path '{}' is not a store path", path.display()),
|
||||
Error::NotInStore(path) => {
|
||||
write!(f, "path '{}' is not in the Nix store", path.display())
|
||||
}
|
||||
Error::BadBase32 => write!(f, "invalid base32 string"),
|
||||
Error::StorePathNameEmpty => write!(f, "store path name is empty"),
|
||||
Error::StorePathNameTooLong => {
|
||||
write!(f, "store path name is longer than 211 characters")
|
||||
}
|
||||
Error::BadStorePathName => write!(f, "store path name contains forbidden character"),
|
||||
Error::NarSizeFieldTooBig => write!(f, "size field in NAR is too big"),
|
||||
Error::BadNarString => write!(f, "NAR string is not valid UTF-8"),
|
||||
Error::BadNarPadding => write!(f, "NAR padding is not zero"),
|
||||
Error::BadNarVersionMagic => write!(f, "unsupported NAR version"),
|
||||
Error::MissingNarOpenTag => write!(f, "NAR open tag is missing"),
|
||||
Error::MissingNarCloseTag => write!(f, "NAR close tag is missing"),
|
||||
Error::MissingNarField => write!(f, "expected NAR field is missing"),
|
||||
Error::BadNarField(s) => write!(f, "unrecognized NAR field '{}'", s),
|
||||
Error::BadExecutableField => write!(f, "bad 'executable' field in NAR"),
|
||||
Error::IOError(err) => write!(f, "I/O error: {}", err),
|
||||
#[cfg(unused)]
|
||||
Error::HttpError(err) => write!(f, "HTTP error: {}", err),
|
||||
#[cfg(not(test))]
|
||||
Error::Foreign(_) => write!(f, "<C++ exception>"), // FIXME
|
||||
Error::Misc(s) => write!(f, "{}", s),
|
||||
Error::BadTarFileMemberName(s) => {
|
||||
write!(f, "tar archive contains illegal file name '{}'", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl From<Error> for CppException {
|
||||
fn from(err: Error) -> Self {
|
||||
match err {
|
||||
Error::Foreign(ex) => ex,
|
||||
_ => CppException::new(&err.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct CppException(*const libc::c_void); // == std::exception_ptr*
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl CppException {
|
||||
fn new(s: &str) -> Self {
|
||||
Self(unsafe { make_error(s) })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Drop for CppException {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
destroy_error(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern "C" {
|
||||
#[allow(improper_ctypes)] // YOLO
|
||||
fn make_error(s: &str) -> *const libc::c_void;
|
||||
|
||||
fn destroy_error(exc: *const libc::c_void);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
#[allow(improper_ctypes_definitions)]
|
||||
#[cfg(not(test))]
|
||||
mod c;
|
||||
mod error;
|
||||
#[cfg(unused)]
|
||||
mod nar;
|
||||
mod store;
|
||||
mod util;
|
||||
|
||||
pub use error::Error;
|
|
@ -1,126 +0,0 @@
|
|||
use crate::Error;
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::convert::TryFrom;
|
||||
use std::io::Read;
|
||||
|
||||
pub fn parse<R: Read>(input: &mut R) -> Result<(), Error> {
|
||||
if String::read(input)? != NAR_VERSION_MAGIC {
|
||||
return Err(Error::BadNarVersionMagic);
|
||||
}
|
||||
|
||||
parse_file(input)
|
||||
}
|
||||
|
||||
const NAR_VERSION_MAGIC: &str = "nix-archive-1";
|
||||
|
||||
fn parse_file<R: Read>(input: &mut R) -> Result<(), Error> {
|
||||
if String::read(input)? != "(" {
|
||||
return Err(Error::MissingNarOpenTag);
|
||||
}
|
||||
|
||||
if String::read(input)? != "type" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
|
||||
match String::read(input)?.as_ref() {
|
||||
"regular" => {
|
||||
let mut _executable = false;
|
||||
let mut tag = String::read(input)?;
|
||||
if tag == "executable" {
|
||||
_executable = true;
|
||||
if String::read(input)? != "" {
|
||||
return Err(Error::BadExecutableField);
|
||||
}
|
||||
tag = String::read(input)?;
|
||||
}
|
||||
if tag != "contents" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _contents = Vec::<u8>::read(input)?;
|
||||
if String::read(input)? != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
"directory" => loop {
|
||||
match String::read(input)?.as_ref() {
|
||||
"entry" => {
|
||||
if String::read(input)? != "(" {
|
||||
return Err(Error::MissingNarOpenTag);
|
||||
}
|
||||
if String::read(input)? != "name" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _name = String::read(input)?;
|
||||
if String::read(input)? != "node" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
parse_file(input)?;
|
||||
let tag = String::read(input)?;
|
||||
if tag != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
")" => break,
|
||||
s => return Err(Error::BadNarField(s.into())),
|
||||
}
|
||||
},
|
||||
"symlink" => {
|
||||
if String::read(input)? != "target" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _target = String::read(input)?;
|
||||
if String::read(input)? != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
s => return Err(Error::BadNarField(s.into())),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
trait Deserialize: Sized {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
impl Deserialize for String {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let buf = Deserialize::read(input)?;
|
||||
Ok(String::from_utf8(buf).map_err(|_| Error::BadNarString)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for Vec<u8> {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let n: usize = Deserialize::read(input)?;
|
||||
let mut buf = vec![0; n];
|
||||
input.read_exact(&mut buf)?;
|
||||
skip_padding(input, n)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_padding<R: Read>(input: &mut R, len: usize) -> Result<(), Error> {
|
||||
if len % 8 != 0 {
|
||||
let mut buf = [0; 8];
|
||||
let buf = &mut buf[0..8 - (len % 8)];
|
||||
input.read_exact(buf)?;
|
||||
if !buf.iter().all(|b| *b == 0) {
|
||||
return Err(Error::BadNarPadding);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Deserialize for u64 {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
Ok(input.read_u64::<LittleEndian>()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for usize {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let n: u64 = Deserialize::read(input)?;
|
||||
Ok(usize::try_from(n).map_err(|_| Error::NarSizeFieldTooBig)?)
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
use super::{PathInfo, Store, StorePath};
|
||||
use crate::Error;
|
||||
use hyper::client::Client;
|
||||
|
||||
pub struct BinaryCacheStore {
|
||||
base_uri: String,
|
||||
client: Client<hyper::client::HttpConnector, hyper::Body>,
|
||||
}
|
||||
|
||||
impl BinaryCacheStore {
|
||||
pub fn new(base_uri: String) -> Self {
|
||||
Self {
|
||||
base_uri,
|
||||
client: Client::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Store for BinaryCacheStore {
|
||||
fn query_path_info(
|
||||
&self,
|
||||
path: &StorePath,
|
||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<PathInfo, Error>> + Send>> {
|
||||
let uri = format!("{}/{}.narinfo", self.base_uri.clone(), path.hash);
|
||||
let path = path.clone();
|
||||
let client = self.client.clone();
|
||||
let store_dir = self.store_dir().to_string();
|
||||
|
||||
Box::pin(async move {
|
||||
let response = client.get(uri.parse::<hyper::Uri>().unwrap()).await?;
|
||||
|
||||
if response.status() == hyper::StatusCode::NOT_FOUND
|
||||
|| response.status() == hyper::StatusCode::FORBIDDEN
|
||||
{
|
||||
return Err(Error::InvalidPath(path));
|
||||
}
|
||||
|
||||
let mut body = response.into_body();
|
||||
|
||||
let mut bytes = Vec::new();
|
||||
while let Some(next) = body.next().await {
|
||||
bytes.extend(next?);
|
||||
}
|
||||
|
||||
PathInfo::parse_nar_info(std::str::from_utf8(&bytes).unwrap(), &store_dir)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
pub mod path;
|
||||
|
||||
#[cfg(unused)]
|
||||
mod binary_cache_store;
|
||||
#[cfg(unused)]
|
||||
mod path_info;
|
||||
#[cfg(unused)]
|
||||
mod store;
|
||||
|
||||
pub use path::{StorePath, StorePathHash, StorePathName};
|
||||
|
||||
#[cfg(unused)]
|
||||
pub use binary_cache_store::BinaryCacheStore;
|
||||
#[cfg(unused)]
|
||||
pub use path_info::PathInfo;
|
||||
#[cfg(unused)]
|
||||
pub use store::Store;
|
|
@ -1,224 +0,0 @@
|
|||
use crate::error::Error;
|
||||
use crate::util::base32;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct StorePath {
|
||||
pub hash: StorePathHash,
|
||||
pub name: StorePathName,
|
||||
}
|
||||
|
||||
pub const STORE_PATH_HASH_BYTES: usize = 20;
|
||||
pub const STORE_PATH_HASH_CHARS: usize = 32;
|
||||
|
||||
impl StorePath {
|
||||
pub fn new(path: &Path, store_dir: &Path) -> Result<Self, Error> {
|
||||
if path.parent() != Some(store_dir) {
|
||||
return Err(Error::NotInStore(path.into()));
|
||||
}
|
||||
Self::new_from_base_name(
|
||||
path.file_name()
|
||||
.ok_or_else(|| Error::BadStorePath(path.into()))?
|
||||
.to_str()
|
||||
.ok_or_else(|| Error::BadStorePath(path.into()))?,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_parts(hash: [u8; STORE_PATH_HASH_BYTES], name: &str) -> Result<Self, Error> {
|
||||
Ok(StorePath {
|
||||
hash: StorePathHash(hash),
|
||||
name: StorePathName::new(name)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_from_base_name(base_name: &str) -> Result<Self, Error> {
|
||||
if base_name.len() < STORE_PATH_HASH_CHARS + 1
|
||||
|| base_name.as_bytes()[STORE_PATH_HASH_CHARS] != b'-'
|
||||
{
|
||||
return Err(Error::BadStorePath(base_name.into()));
|
||||
}
|
||||
|
||||
Ok(StorePath {
|
||||
hash: StorePathHash::new(&base_name[0..STORE_PATH_HASH_CHARS])?,
|
||||
name: StorePathName::new(&base_name[STORE_PATH_HASH_CHARS + 1..])?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}-{}", self.hash, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct StorePathHash([u8; STORE_PATH_HASH_BYTES]);
|
||||
|
||||
impl StorePathHash {
|
||||
pub fn new(s: &str) -> Result<Self, Error> {
|
||||
assert_eq!(s.len(), STORE_PATH_HASH_CHARS);
|
||||
let v = base32::decode(s)?;
|
||||
assert_eq!(v.len(), STORE_PATH_HASH_BYTES);
|
||||
let mut bytes: [u8; 20] = Default::default();
|
||||
bytes.copy_from_slice(&v[0..STORE_PATH_HASH_BYTES]);
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> &[u8; STORE_PATH_HASH_BYTES] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePathHash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut buf = vec![0; STORE_PATH_HASH_CHARS];
|
||||
base32::encode_into(&self.0, &mut buf);
|
||||
f.write_str(std::str::from_utf8(&buf).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for StorePathHash {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
// Historically we've sorted store paths by their base32
|
||||
// serialization, but our base32 encodes bytes in reverse
|
||||
// order. So compare them in reverse order as well.
|
||||
self.0.iter().rev().cmp(other.0.iter().rev())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for StorePathHash {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct StorePathName(String);
|
||||
|
||||
impl StorePathName {
|
||||
pub fn new(s: &str) -> Result<Self, Error> {
|
||||
if s.is_empty() {
|
||||
return Err(Error::StorePathNameEmpty);
|
||||
}
|
||||
|
||||
if s.len() > 211 {
|
||||
return Err(Error::StorePathNameTooLong);
|
||||
}
|
||||
|
||||
let is_good_path_name = s.chars().all(|c| {
|
||||
c.is_ascii_alphabetic()
|
||||
|| c.is_ascii_digit()
|
||||
|| c == '+'
|
||||
|| c == '-'
|
||||
|| c == '.'
|
||||
|| c == '_'
|
||||
|| c == '?'
|
||||
|| c == '='
|
||||
});
|
||||
if s.starts_with('.') || !is_good_path_name {
|
||||
return Err(Error::BadStorePathName);
|
||||
}
|
||||
|
||||
Ok(Self(s.to_string()))
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePathName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
let p = StorePath::new_from_base_name(&s).unwrap();
|
||||
assert_eq!(p.name.0, "konsole-18.12.3");
|
||||
assert_eq!(
|
||||
p.hash.0,
|
||||
[
|
||||
0x9f, 0x76, 0x49, 0x20, 0xf6, 0x5d, 0xe9, 0x71, 0xc4, 0xca, 0x46, 0x21, 0xab, 0xff,
|
||||
0x9b, 0x44, 0xef, 0x87, 0x0f, 0x3c
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::StorePathNameEmpty)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_dash() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePath(_))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_hash() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxl-konsole-18.12.3";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePath(_))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_hash() {
|
||||
let s = "7h7qgvs4kgzsn8e6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
assert_matches!(StorePath::new_from_base_name(&s), Err(Error::BadBase32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
assert_matches!(StorePath::new_from_base_name(&s), Ok(_));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_long_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::StorePathNameTooLong)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bad_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-foo bar";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePathName)
|
||||
);
|
||||
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-kónsole";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePathName)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
assert_eq!(StorePath::new_from_base_name(&s).unwrap().to_string(), s);
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
use crate::store::StorePath;
|
||||
use crate::Error;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PathInfo {
|
||||
pub path: StorePath,
|
||||
pub references: BTreeSet<StorePath>,
|
||||
pub nar_size: u64,
|
||||
pub deriver: Option<StorePath>,
|
||||
|
||||
// Additional binary cache info.
|
||||
pub url: Option<String>,
|
||||
pub compression: Option<String>,
|
||||
pub file_size: Option<u64>,
|
||||
}
|
||||
|
||||
impl PathInfo {
|
||||
pub fn parse_nar_info(nar_info: &str, store_dir: &str) -> Result<Self, Error> {
|
||||
let mut path = None;
|
||||
let mut references = BTreeSet::new();
|
||||
let mut nar_size = None;
|
||||
let mut deriver = None;
|
||||
let mut url = None;
|
||||
let mut compression = None;
|
||||
let mut file_size = None;
|
||||
|
||||
for line in nar_info.lines() {
|
||||
let colon = line.find(':').ok_or(Error::BadNarInfo)?;
|
||||
|
||||
let (name, value) = line.split_at(colon);
|
||||
|
||||
if !value.starts_with(": ") {
|
||||
return Err(Error::BadNarInfo);
|
||||
}
|
||||
|
||||
let value = &value[2..];
|
||||
|
||||
if name == "StorePath" {
|
||||
path = Some(StorePath::new(std::path::Path::new(value), store_dir)?);
|
||||
} else if name == "NarSize" {
|
||||
nar_size = Some(u64::from_str_radix(value, 10).map_err(|_| Error::BadNarInfo)?);
|
||||
} else if name == "References" {
|
||||
if !value.is_empty() {
|
||||
for r in value.split(' ') {
|
||||
references.insert(StorePath::new_from_base_name(r)?);
|
||||
}
|
||||
}
|
||||
} else if name == "Deriver" {
|
||||
deriver = Some(StorePath::new_from_base_name(value)?);
|
||||
} else if name == "URL" {
|
||||
url = Some(value.into());
|
||||
} else if name == "Compression" {
|
||||
compression = Some(value.into());
|
||||
} else if name == "FileSize" {
|
||||
file_size = Some(u64::from_str_radix(value, 10).map_err(|_| Error::BadNarInfo)?);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PathInfo {
|
||||
path: path.ok_or(Error::BadNarInfo)?,
|
||||
references,
|
||||
nar_size: nar_size.ok_or(Error::BadNarInfo)?,
|
||||
deriver,
|
||||
url: Some(url.ok_or(Error::BadNarInfo)?),
|
||||
compression,
|
||||
file_size,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
use super::{PathInfo, StorePath};
|
||||
use crate::Error;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::Path;
|
||||
|
||||
pub trait Store: Send + Sync {
|
||||
fn store_dir(&self) -> &str {
|
||||
"/nix/store"
|
||||
}
|
||||
|
||||
fn query_path_info(
|
||||
&self,
|
||||
store_path: &StorePath,
|
||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<PathInfo, Error>> + Send>>;
|
||||
}
|
||||
|
||||
impl dyn Store {
|
||||
pub fn parse_store_path(&self, path: &Path) -> Result<StorePath, Error> {
|
||||
StorePath::new(path, self.store_dir())
|
||||
}
|
||||
|
||||
pub async fn compute_path_closure(
|
||||
&self,
|
||||
roots: BTreeSet<StorePath>,
|
||||
) -> Result<BTreeMap<StorePath, PathInfo>, Error> {
|
||||
let mut done = BTreeSet::new();
|
||||
let mut result = BTreeMap::new();
|
||||
let mut pending = vec![];
|
||||
|
||||
for root in roots {
|
||||
pending.push(self.query_path_info(&root));
|
||||
done.insert(root);
|
||||
}
|
||||
|
||||
while !pending.is_empty() {
|
||||
let (info, _, remaining) = futures::future::select_all(pending).await;
|
||||
pending = remaining;
|
||||
|
||||
let info = info?;
|
||||
|
||||
for path in &info.references {
|
||||
if !done.contains(path) {
|
||||
pending.push(self.query_path_info(&path));
|
||||
done.insert(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
result.insert(info.path.clone(), info);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
use crate::error::Error;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub fn encoded_len(input_len: usize) -> usize {
|
||||
if input_len == 0 {
|
||||
0
|
||||
} else {
|
||||
(input_len * 8 - 1) / 5 + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decoded_len(input_len: usize) -> usize {
|
||||
input_len * 5 / 8
|
||||
}
|
||||
|
||||
static BASE32_CHARS: &[u8; 32] = &b"0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
||||
lazy_static! {
|
||||
static ref BASE32_CHARS_REVERSE: Box<[u8; 256]> = {
|
||||
let mut xs = [0xffu8; 256];
|
||||
for (n, c) in BASE32_CHARS.iter().enumerate() {
|
||||
xs[*c as usize] = n as u8;
|
||||
}
|
||||
Box::new(xs)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn encode(input: &[u8]) -> String {
|
||||
let mut buf = vec![0; encoded_len(input.len())];
|
||||
encode_into(input, &mut buf);
|
||||
std::str::from_utf8(&buf).unwrap().to_string()
|
||||
}
|
||||
|
||||
pub fn encode_into(input: &[u8], output: &mut [u8]) {
|
||||
let len = encoded_len(input.len());
|
||||
assert_eq!(len, output.len());
|
||||
|
||||
let mut nr_bits_left: usize = 0;
|
||||
let mut bits_left: u16 = 0;
|
||||
let mut pos = len;
|
||||
|
||||
for b in input {
|
||||
bits_left |= (*b as u16) << nr_bits_left;
|
||||
nr_bits_left += 8;
|
||||
while nr_bits_left > 5 {
|
||||
output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
|
||||
pos -= 1;
|
||||
bits_left >>= 5;
|
||||
nr_bits_left -= 5;
|
||||
}
|
||||
}
|
||||
|
||||
if nr_bits_left > 0 {
|
||||
output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
|
||||
pos -= 1;
|
||||
}
|
||||
|
||||
assert_eq!(pos, 0);
|
||||
}
|
||||
|
||||
pub fn decode(input: &str) -> Result<Vec<u8>, crate::Error> {
|
||||
let mut res = Vec::with_capacity(decoded_len(input.len()));
|
||||
|
||||
let mut nr_bits_left: usize = 0;
|
||||
let mut bits_left: u16 = 0;
|
||||
|
||||
for c in input.chars().rev() {
|
||||
let b = BASE32_CHARS_REVERSE[c as usize];
|
||||
if b == 0xff {
|
||||
return Err(Error::BadBase32);
|
||||
}
|
||||
bits_left |= (b as u16) << nr_bits_left;
|
||||
nr_bits_left += 5;
|
||||
if nr_bits_left >= 8 {
|
||||
res.push((bits_left & 0xff) as u8);
|
||||
bits_left >>= 8;
|
||||
nr_bits_left -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
if nr_bits_left > 0 && bits_left != 0 {
|
||||
return Err(Error::BadBase32);
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
use hex;
|
||||
use proptest::proptest;
|
||||
|
||||
#[test]
|
||||
fn test_encode() {
|
||||
assert_eq!(encode(&[]), "");
|
||||
|
||||
assert_eq!(
|
||||
encode(&hex::decode("0839703786356bca59b0f4a32987eb2e6de43ae8").unwrap()),
|
||||
"x0xf8v9fxf3jk8zln1cwlsrmhqvp0f88"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode(
|
||||
&hex::decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
|
||||
.unwrap()
|
||||
),
|
||||
"1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode(
|
||||
&hex::decode("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
|
||||
.unwrap()
|
||||
),
|
||||
"2gs8k559z4rlahfx0y688s49m2vvszylcikrfinm30ly9rak69236nkam5ydvly1ai7xac99vxfc4ii84hawjbk876blyk1jfhkbbyx"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
assert_eq!(hex::encode(decode("").unwrap()), "");
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("x0xf8v9fxf3jk8zln1cwlsrmhqvp0f88").unwrap()),
|
||||
"0839703786356bca59b0f4a32987eb2e6de43ae8"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s").unwrap()),
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("2gs8k559z4rlahfx0y688s49m2vvszylcikrfinm30ly9rak69236nkam5ydvly1ai7xac99vxfc4ii84hawjbk876blyk1jfhkbbyx").unwrap()),
|
||||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
|
||||
);
|
||||
|
||||
assert_matches!(
|
||||
decode("xoxf8v9fxf3jk8zln1cwlsrmhqvp0f88"),
|
||||
Err(Error::BadBase32)
|
||||
);
|
||||
assert_matches!(
|
||||
decode("2b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s"),
|
||||
Err(Error::BadBase32)
|
||||
);
|
||||
assert_matches!(decode("2"), Err(Error::BadBase32));
|
||||
assert_matches!(decode("2gs"), Err(Error::BadBase32));
|
||||
assert_matches!(decode("2gs8"), Err(Error::BadBase32));
|
||||
}
|
||||
|
||||
proptest! {
|
||||
|
||||
#[test]
|
||||
fn roundtrip(s: Vec<u8>) {
|
||||
assert_eq!(s, decode(&encode(&s)).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
pub mod base32;
|
|
@ -41,7 +41,7 @@ perlarchname=$($perl -e 'use Config; print $Config{archname};')
|
|||
AC_SUBST(perllibdir, [${libdir}/perl5/site_perl/$perlversion/$perlarchname])
|
||||
AC_MSG_RESULT($perllibdir)
|
||||
|
||||
# Look for libsodium, an optional dependency.
|
||||
# Look for libsodium.
|
||||
PKG_CHECK_MODULES([SODIUM], [libsodium], [CXXFLAGS="$SODIUM_CFLAGS $CXXFLAGS"])
|
||||
|
||||
# Check for the required Perl dependencies (DBI and DBD::SQLite).
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package Nix::Config;
|
||||
|
||||
use MIME::Base64;
|
||||
use Nix::Store;
|
||||
|
||||
$version = "@PACKAGE_VERSION@";
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ SV * convertHash(char * algo, char * s, int toBase32)
|
|||
PPCODE:
|
||||
try {
|
||||
auto h = Hash::parseAny(s, parseHashType(algo));
|
||||
string s = h.to_string(toBase32 ? Base32 : Base16, false);
|
||||
auto s = h.to_string(toBase32 ? Base32 : Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
|
|
33
scripts/check-hydra-status.sh
Normal file
33
scripts/check-hydra-status.sh
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
# set -x
|
||||
|
||||
|
||||
# mapfile BUILDS_FOR_LATEST_EVAL < <(
|
||||
# curl -H 'Accept: application/json' https://hydra.nixos.org/jobset/nix/master/evals | \
|
||||
# jq -r '.evals[0].builds[] | @sh')
|
||||
BUILDS_FOR_LATEST_EVAL=$(
|
||||
curl -sS -H 'Accept: application/json' https://hydra.nixos.org/jobset/nix/master/evals | \
|
||||
jq -r '.evals[0].builds[]')
|
||||
|
||||
someBuildFailed=0
|
||||
|
||||
for buildId in $BUILDS_FOR_LATEST_EVAL; do
|
||||
buildInfo=$(curl -sS -H 'Accept: application/json' "https://hydra.nixos.org/build/$buildId")
|
||||
|
||||
finished=$(echo "$buildInfo" | jq -r '.finished')
|
||||
|
||||
if [[ $finished = 0 ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
buildStatus=$(echo "$buildInfo" | jq -r '.buildstatus')
|
||||
|
||||
if [[ $buildStatus != 0 ]]; then
|
||||
someBuildFailed=1
|
||||
echo "Job “$(echo "$buildInfo" | jq -r '.job')” failed on hydra: $buildInfo"
|
||||
fi
|
||||
done
|
||||
|
||||
exit "$someBuildFailed"
|
|
@ -246,7 +246,8 @@ get_volume_pass() {
|
|||
verify_volume_pass() {
|
||||
local volume_special="$1" # (i.e., disk1s7)
|
||||
local volume_uuid="$2"
|
||||
/usr/sbin/diskutil apfs unlockVolume "$volume_special" -verify -stdinpassphrase -user "$volume_uuid"
|
||||
_sudo "to confirm the password actually unlocks the volume" \
|
||||
/usr/sbin/diskutil apfs unlockVolume "$volume_special" -verify -stdinpassphrase -user "$volume_uuid"
|
||||
}
|
||||
|
||||
volume_pass_works() {
|
||||
|
@ -440,7 +441,22 @@ add_nix_vol_fstab_line() {
|
|||
# shellcheck disable=SC1003,SC2026
|
||||
local escaped_mountpoint="${NIX_ROOT/ /'\\\'040}"
|
||||
shift
|
||||
EDITOR="/usr/bin/ex" _sudo "to add nix to fstab" "$@" <<EOF
|
||||
|
||||
# wrap `ex` to work around a problem with vim plugins breaking exit codes;
|
||||
# (see https://github.com/NixOS/nix/issues/5468)
|
||||
# we'd prefer EDITOR="/usr/bin/ex --noplugin" but vifs doesn't word-split
|
||||
# the EDITOR env.
|
||||
#
|
||||
# TODO: at some point we should switch to `--clean`, but it wasn't added
|
||||
# until https://github.com/vim/vim/releases/tag/v8.0.1554 while the macOS
|
||||
# minver 10.12.6 seems to have released with vim 7.4
|
||||
cat > "$SCRATCH/ex_cleanroom_wrapper" <<EOF
|
||||
#!/bin/sh
|
||||
/usr/bin/ex --noplugin "\$@"
|
||||
EOF
|
||||
chmod 755 "$SCRATCH/ex_cleanroom_wrapper"
|
||||
|
||||
EDITOR="$SCRATCH/ex_cleanroom_wrapper" _sudo "to add nix to fstab" "$@" <<EOF
|
||||
:a
|
||||
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,suid,owners
|
||||
.
|
||||
|
@ -631,7 +647,7 @@ EOF
|
|||
# technically /etc/synthetic.d/nix is supported in Big Sur+
|
||||
# but handling both takes even more code...
|
||||
_sudo "to add Nix to /etc/synthetic.conf" \
|
||||
/usr/bin/ex /etc/synthetic.conf <<EOF
|
||||
/usr/bin/ex --noplugin /etc/synthetic.conf <<EOF
|
||||
:a
|
||||
${NIX_ROOT:1}
|
||||
.
|
||||
|
@ -670,22 +686,27 @@ encrypt_volume() {
|
|||
local volume_uuid="$1"
|
||||
local volume_label="$2"
|
||||
local password
|
||||
|
||||
task "Encrypt the Nix volume" >&2
|
||||
|
||||
# Note: mount/unmount are late additions to support the right order
|
||||
# of operations for creating the volume and then baking its uuid into
|
||||
# other artifacts; not as well-trod wrt to potential errors, race
|
||||
# conditions, etc.
|
||||
|
||||
/usr/sbin/diskutil mount "$volume_label"
|
||||
_sudo "to mount your Nix volume for encrypting" \
|
||||
/usr/sbin/diskutil mount "$volume_label"
|
||||
|
||||
password="$(/usr/bin/xxd -l 32 -p -c 256 /dev/random)"
|
||||
_sudo "to add your Nix volume's password to Keychain" \
|
||||
/usr/bin/security -i <<EOF
|
||||
add-generic-password -a "$volume_label" -s "$volume_uuid" -l "$volume_label encryption password" -D "Encrypted volume password" -j "Added automatically by the Nix installer for use by $NIX_VOLUME_MOUNTD_DEST" -w "$password" -T /System/Library/CoreServices/APFSUserAgent -T /System/Library/CoreServices/CSUserAgent -T /usr/bin/security "/Library/Keychains/System.keychain"
|
||||
EOF
|
||||
builtin printf "%s" "$password" | _sudo "to encrypt your Nix volume" \
|
||||
builtin printf "%s" "$password" | _sudo "to actually encrypt your Nix volume" \
|
||||
/usr/sbin/diskutil apfs encryptVolume "$volume_label" -user disk -stdinpassphrase
|
||||
|
||||
/usr/sbin/diskutil unmount force "$volume_label"
|
||||
_sudo "to unmount the encrypted volume" \
|
||||
/usr/sbin/diskutil unmount force "$volume_label"
|
||||
}
|
||||
|
||||
create_volume() {
|
||||
|
@ -742,6 +763,9 @@ setup_volume() {
|
|||
|
||||
use_special="${NIX_VOLUME_USE_SPECIAL:-$(create_volume)}"
|
||||
|
||||
_sudo "to ensure the Nix volume is not mounted" \
|
||||
/usr/sbin/diskutil unmount force "$use_special" || true # might not be mounted
|
||||
|
||||
use_uuid=${NIX_VOLUME_USE_UUID:-$(volume_uuid_from_special "$use_special")}
|
||||
|
||||
setup_fstab "$use_uuid"
|
||||
|
@ -791,7 +815,7 @@ setup_volume_daemon() {
|
|||
local volume_uuid="$2"
|
||||
if ! test_voldaemon; then
|
||||
task "Configuring LaunchDaemon to mount '$NIX_VOLUME_LABEL'" >&2
|
||||
_sudo "to install the Nix volume mounter" /usr/bin/ex "$NIX_VOLUME_MOUNTD_DEST" <<EOF
|
||||
_sudo "to install the Nix volume mounter" /usr/bin/ex --noplugin "$NIX_VOLUME_MOUNTD_DEST" <<EOF
|
||||
:a
|
||||
$(generate_mount_daemon "$cmd_type" "$volume_uuid")
|
||||
.
|
||||
|
|
|
@ -78,7 +78,7 @@ poly_service_installed_check() {
|
|||
poly_service_uninstall_directions() {
|
||||
echo "$1. Remove macOS-specific components:"
|
||||
if should_create_volume && test_nix_volume_mountd_installed; then
|
||||
darwin_volume_uninstall_directions
|
||||
nix_volume_mountd_uninstall_directions
|
||||
fi
|
||||
if test_nix_daemon_installed; then
|
||||
nix_daemon_uninstall_directions
|
||||
|
@ -218,7 +218,7 @@ EOF
|
|||
setup_darwin_volume
|
||||
fi
|
||||
|
||||
if [ "$(diskutil info -plist /nix | xmllint --xpath "(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1]" -)" = "<false/>" ]; then
|
||||
failure "This script needs a /nix volume with global permissions! This may require running sudo diskutil enableOwnership /nix."
|
||||
if [ "$(/usr/sbin/diskutil info -plist /nix | xmllint --xpath "(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1]" -)" = "<false/>" ]; then
|
||||
failure "This script needs a /nix volume with global permissions! This may require running sudo /usr/sbin/diskutil enableOwnership /nix."
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ readonly RED='\033[31m'
|
|||
# installer allows overriding build user count to speed up installation
|
||||
# as creating each user takes non-trivial amount of time on macos
|
||||
readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32}
|
||||
readonly NIX_BUILD_GROUP_ID="30000"
|
||||
readonly NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-30000}"
|
||||
readonly NIX_BUILD_GROUP_NAME="nixbld"
|
||||
# darwin installer needs to override these
|
||||
NIX_FIRST_BUILD_UID="30001"
|
||||
NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
|
||||
NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
|
||||
# Please don't change this. We don't support it, because the
|
||||
# default shell profile that comes with Nix doesn't support it.
|
||||
|
@ -377,6 +377,11 @@ cure_artifacts() {
|
|||
}
|
||||
|
||||
validate_starting_assumptions() {
|
||||
task "Checking for artifacts of previous installs"
|
||||
cat <<EOF
|
||||
Before I try to install, I'll check for signs Nix already is or has
|
||||
been installed on this system.
|
||||
EOF
|
||||
if type nix-env 2> /dev/null >&2; then
|
||||
warning <<EOF
|
||||
Nix already appears to be installed. This installer may run into issues.
|
||||
|
@ -386,20 +391,34 @@ $(uninstall_directions)
|
|||
EOF
|
||||
fi
|
||||
|
||||
# TODO: I think it would be good for this step to accumulate more
|
||||
# knowledge of older obsolete artifacts, if there are any.
|
||||
# We could issue a "reminder" here that the user might want
|
||||
# to clean them up?
|
||||
|
||||
for profile_target in "${PROFILE_TARGETS[@]}"; do
|
||||
# TODO: I think it would be good to accumulate a list of all
|
||||
# of the copies so that people don't hit this 2 or 3x in
|
||||
# a row for different files.
|
||||
if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
|
||||
# this backup process first released in Nix 2.1
|
||||
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.
|
||||
I back up shell profile/rc scripts before I add Nix to them.
|
||||
I need to back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX,
|
||||
but the latter already exists.
|
||||
|
||||
Please follow these instructions to clean up the old backup file:
|
||||
Here's how to clean up the old backup file:
|
||||
|
||||
1. Copy $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX to another place, just
|
||||
in case.
|
||||
1. Back up (copy) $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX
|
||||
to another location, 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.
|
||||
2. Ensure $profile_target$PROFILE_BACKUP_SUFFIX does not have anything
|
||||
Nix-related in it. If it does, something is probably quite
|
||||
wrong. Please open an issue or get in touch immediately.
|
||||
|
||||
3. Once you confirm $profile_target is backed up and
|
||||
$profile_target$PROFILE_BACKUP_SUFFIX doesn't mention Nix, run:
|
||||
mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
@ -557,21 +576,40 @@ create_directories() {
|
|||
# since this bit is cross-platform:
|
||||
# - first try with `command -vp` to try and find
|
||||
# chown in the usual places
|
||||
# * to work around some sort of deficiency in
|
||||
# `command -p` in macOS bash 3.2, we also add
|
||||
# PATH="$(getconf PATH 2>/dev/null)". As long as
|
||||
# getconf is found, this should set a sane PATH
|
||||
# which `command -p` in bash 3.2 appears to use.
|
||||
# A bash with a properly-working `command -p`
|
||||
# should ignore this hard-set PATH in favor of
|
||||
# whatever it obtains internally. See
|
||||
# github.com/NixOS/nix/issues/5768
|
||||
# - fall back on `command -v` which would find
|
||||
# any chown on path
|
||||
# if we don't find one, the command is already
|
||||
# hiding behind || true, and the general state
|
||||
# should be one the user can repair once they
|
||||
# figure out where chown is...
|
||||
local get_chr_own="$(command -vp chown)"
|
||||
local get_chr_own="$(PATH="$(getconf PATH 2>/dev/null)" command -vp chown)"
|
||||
if [[ -z "$get_chr_own" ]]; then
|
||||
get_chr_own="$(command -v chown)"
|
||||
fi
|
||||
_sudo "to take root ownership of existing Nix store files" \
|
||||
"$get_chr_own" -R "root:$NIX_BUILD_GROUP_NAME" "$NIX_ROOT" || true
|
||||
|
||||
if [[ -z "$get_chr_own" ]]; then
|
||||
reminder <<EOF
|
||||
I wanted to take root ownership of existing Nix store files,
|
||||
but I couldn't locate 'chown'. (You may need to fix your PATH.)
|
||||
To manually change file ownership, you can run:
|
||||
sudo chown -R 'root:$NIX_BUILD_GROUP_NAME' '$NIX_ROOT'
|
||||
EOF
|
||||
else
|
||||
_sudo "to take root ownership of existing Nix store files" \
|
||||
"$get_chr_own" -R "root:$NIX_BUILD_GROUP_NAME" "$NIX_ROOT" || true
|
||||
fi
|
||||
fi
|
||||
_sudo "to make the basic directory structure of Nix (part 1)" \
|
||||
install -dv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool} /nix/var/nix/{gcroots,profiles}/per-user
|
||||
install -dv -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,/daemon-socket} /nix/var/nix/{gcroots,profiles}/per-user
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 2)" \
|
||||
install -dv -g "$NIX_BUILD_GROUP_NAME" -m 1775 /nix/store
|
||||
|
@ -599,7 +637,7 @@ 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 install.
|
||||
|
||||
2. Show you what we are going to install and where. Then we will ask
|
||||
2. Show you what I am going to install and where. Then I will ask
|
||||
if you are ready to continue.
|
||||
|
||||
3. Create the system users and groups that the Nix daemon uses to run
|
||||
|
@ -614,14 +652,14 @@ manager. This will happen in a few stages:
|
|||
|
||||
EOF
|
||||
|
||||
if ui_confirm "Would you like to see a more detailed list of what we will do?"; then
|
||||
if ui_confirm "Would you like to see a more detailed list of what I will do?"; then
|
||||
cat <<EOF
|
||||
|
||||
We will:
|
||||
I 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 local users (see the list above for the users I'll make)
|
||||
- create a local group ($NIX_BUILD_GROUP_NAME)
|
||||
- install Nix in to $NIX_ROOT
|
||||
- create a configuration file in /etc/nix
|
||||
|
@ -656,7 +694,7 @@ run in a headless fashion, like this:
|
|||
|
||||
$ curl -L https://nixos.org/nix/install | sh
|
||||
|
||||
or maybe in a CI pipeline. Because of that, we're going to skip the
|
||||
or maybe in a CI pipeline. Because of that, I'm going to skip the
|
||||
verbose output in the interest of brevity.
|
||||
|
||||
If you would like to
|
||||
|
@ -670,7 +708,7 @@ EOF
|
|||
fi
|
||||
|
||||
cat <<EOF
|
||||
This script is going to call sudo a lot. Every time we do, it'll
|
||||
This script is going to call sudo a lot. Every time I do, it'll
|
||||
output exactly what it'll do, and why.
|
||||
|
||||
Just like this:
|
||||
|
@ -682,15 +720,15 @@ EOF
|
|||
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
|
||||
few commands. I 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
|
||||
if ui_confirm "Can I use sudo?"; then
|
||||
ok "Yay! Thanks! Let's get going!"
|
||||
else
|
||||
failure <<EOF
|
||||
That is okay, but we can't install.
|
||||
That is okay, but I can't install.
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
@ -809,10 +847,10 @@ main() {
|
|||
# can fail faster in this case. Sourcing install-darwin... now runs
|
||||
# `touch /` to detect Read-only root, but it could update times on
|
||||
# pre-Catalina macOS if run as root user.
|
||||
if [ $EUID -eq 0 ]; then
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
failure <<EOF
|
||||
Please do not run this script with root privileges. We will call sudo
|
||||
when we need to.
|
||||
Please do not run this script with root privileges. I will call sudo
|
||||
when I need to.
|
||||
EOF
|
||||
fi
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ fi
|
|||
|
||||
# Determine if we could use the multi-user installer or not
|
||||
if [ "$(uname -s)" = "Linux" ]; then
|
||||
echo "Note: a multi-user installation is possible. See https://nixos.org/nix/manual/#sect-multi-user-installation" >&2
|
||||
echo "Note: a multi-user installation is possible. See https://nixos.org/manual/nix/stable/installation/installing-binary.html#multi-user-installation" >&2
|
||||
fi
|
||||
|
||||
case "$(uname -s)" in
|
||||
|
@ -98,7 +98,7 @@ while [ $# -gt 0 ]; do
|
|||
echo " providing multi-user support and better isolation for local builds."
|
||||
echo " Both for security and reproducibility, this method is recommended if"
|
||||
echo " supported on your platform."
|
||||
echo " See https://nixos.org/nix/manual/#sect-multi-user-installation"
|
||||
echo " See https://nixos.org/manual/nix/stable/installation/installing-binary.html#multi-user-installation"
|
||||
echo ""
|
||||
echo " --no-daemon: Simple, single-user installation that does not require root and is"
|
||||
echo " trivial to uninstall."
|
||||
|
@ -134,7 +134,7 @@ fi
|
|||
|
||||
echo "performing a single-user installation of Nix..." >&2
|
||||
|
||||
if ! [ -e $dest ]; then
|
||||
if ! [ -e "$dest" ]; then
|
||||
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
||||
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
||||
if ! sudo sh -c "$cmd"; then
|
||||
|
@ -143,12 +143,12 @@ if ! [ -e $dest ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if ! [ -w $dest ]; then
|
||||
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see https://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
||||
if ! [ -w "$dest" ]; then
|
||||
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see https://nixos.org/manual/nix/stable/installation/multi-user.html. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $dest/store
|
||||
mkdir -p "$dest/store"
|
||||
|
||||
printf "copying Nix to %s..." "${dest}/store" >&2
|
||||
# Insert a newline if no progress is shown.
|
||||
|
@ -189,17 +189,17 @@ fi
|
|||
|
||||
# Install an SSL certificate bundle.
|
||||
if [ -z "$NIX_SSL_CERT_FILE" ] || ! [ -f "$NIX_SSL_CERT_FILE" ]; then
|
||||
$nix/bin/nix-env -i "$cacert"
|
||||
"$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 [ -z "$NIX_INSTALLER_NO_CHANNEL_ADD" ]; then
|
||||
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
|
||||
if ! $nix/bin/nix-channel --update nixpkgs; then
|
||||
if ! "$nix/bin/nix-channel" --update nixpkgs; then
|
||||
echo "Fetching the nixpkgs channel failed. (Are you offline?)"
|
||||
echo "To try again later, run \"nix-channel --update nixpkgs\"."
|
||||
fi
|
||||
|
@ -215,7 +215,7 @@ if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
|
|||
if [ -w "$fn" ]; then
|
||||
if ! grep -q "$p" "$fn"; then
|
||||
echo "modifying $fn..." >&2
|
||||
echo -e "\nif [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
|
||||
printf '\nif [ -e %s ]; then . %s; fi # added by Nix installer\n' "$p" "$p" >> "$fn"
|
||||
fi
|
||||
added=1
|
||||
break
|
||||
|
@ -226,7 +226,7 @@ if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
|
|||
if [ -w "$fn" ]; then
|
||||
if ! grep -q "$p" "$fn"; then
|
||||
echo "modifying $fn..." >&2
|
||||
echo -e "\nif [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
|
||||
printf '\nif [ -e %s ]; then . %s; fi # added by Nix installer\n' "$p" "$p" >> "$fn"
|
||||
fi
|
||||
added=1
|
||||
break
|
||||
|
|
|
@ -15,7 +15,7 @@ readonly SERVICE_OVERRIDE=${SERVICE_DEST}.d/override.conf
|
|||
|
||||
create_systemd_override() {
|
||||
header "Configuring proxy for the nix-daemon service"
|
||||
_sudo "create directory for systemd unit override" mkdir -p "$(dirname $SERVICE_OVERRIDE)"
|
||||
_sudo "create directory for systemd unit override" mkdir -p "$(dirname "$SERVICE_OVERRIDE")"
|
||||
cat <<EOF | _sudo "create systemd unit override" tee "$SERVICE_OVERRIDE"
|
||||
[Service]
|
||||
$1
|
||||
|
|
|
@ -81,10 +81,10 @@ if [ "$(uname -s)" != "Darwin" ]; then
|
|||
require_util xz "unpack the binary tarball"
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null 2>&1; then
|
||||
fetch() { wget "$1" -O "$2"; }
|
||||
elif command -v curl > /dev/null 2>&1; then
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
fetch() { curl -L "$1" -o "$2"; }
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
fetch() { wget "$1" -O "$2"; }
|
||||
else
|
||||
oops "you don't have wget or curl installed, which I need to download the binary tarball"
|
||||
fi
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
nix_noinst_scripts := \
|
||||
$(d)/nix-http-export.cgi \
|
||||
$(d)/nix-profile.sh \
|
||||
$(d)/nix-reduce-build
|
||||
$(d)/nix-profile.sh
|
||||
|
||||
noinst-scripts += $(nix_noinst_scripts)
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
export HOME=/tmp
|
||||
export NIX_REMOTE=daemon
|
||||
|
||||
TMP_DIR="${TMP_DIR:-/tmp/nix-export}"
|
||||
|
||||
@coreutils@/mkdir -p "$TMP_DIR" || true
|
||||
@coreutils@/chmod a+r "$TMP_DIR"
|
||||
|
||||
needed_path="?$QUERY_STRING"
|
||||
needed_path="${needed_path#*[?&]needed_path=}"
|
||||
needed_path="${needed_path%%&*}"
|
||||
#needed_path="$(echo $needed_path | ./unhttp)"
|
||||
needed_path="${needed_path//%2B/+}"
|
||||
needed_path="${needed_path//%3D/=}"
|
||||
|
||||
echo needed_path: "$needed_path" >&2
|
||||
|
||||
NIX_STORE="${NIX_STORE_DIR:-/nix/store}"
|
||||
|
||||
echo NIX_STORE: "${NIX_STORE}" >&2
|
||||
|
||||
full_path="${NIX_STORE}"/"$needed_path"
|
||||
|
||||
if [ "$needed_path" != "${needed_path%.drv}" ]; then
|
||||
echo "Status: 403 You should create the derivation file yourself"
|
||||
echo "Content-Type: text/plain"
|
||||
echo
|
||||
echo "Refusing to disclose derivation contents"
|
||||
exit
|
||||
fi
|
||||
|
||||
if @bindir@/nix-store --check-validity "$full_path"; then
|
||||
if ! [ -e nix-export/"$needed_path".nar.gz ]; then
|
||||
@bindir@/nix-store --export "$full_path" | @gzip@ > "$TMP_DIR"/"$needed_path".nar.gz
|
||||
@coreutils@/ln -fs "$TMP_DIR"/"$needed_path".nar.gz nix-export/"$needed_path".nar.gz
|
||||
fi;
|
||||
echo "Status: 301 Moved"
|
||||
echo "Location: nix-export/"$needed_path".nar.gz"
|
||||
echo
|
||||
else
|
||||
echo "Status: 404 No such path found"
|
||||
echo "Content-Type: text/plain"
|
||||
echo
|
||||
echo "Path not found:"
|
||||
echo "$needed_path"
|
||||
echo "checked:"
|
||||
echo "$full_path"
|
||||
fi
|
||||
|
|
@ -5,7 +5,7 @@ __ETC_PROFILE_NIX_SOURCED=1
|
|||
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
|
||||
|
||||
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
|
||||
if [ ! -z "${NIX_SSL_CERT_FILE:-}" ]; then
|
||||
if [ -n "${NIX_SSL_CERT_FILE:-}" ]; then
|
||||
: # Allow users to override the NIX_SSL_CERT_FILE
|
||||
elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
|
||||
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
|
@ -18,14 +18,14 @@ elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS
|
|||
else
|
||||
# Fall back to what is in the nix profiles, favouring whatever is defined last.
|
||||
check_nix_profiles() {
|
||||
if [ "$ZSH_VERSION" ]; then
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
# Zsh by default doesn't split words in unquoted parameter expansion.
|
||||
# Set local_options for these options to be reverted at the end of the function
|
||||
# and shwordsplit to force splitting words in $NIX_PROFILES below.
|
||||
setopt local_options shwordsplit
|
||||
fi
|
||||
for i in $NIX_PROFILES; do
|
||||
if [ -e $i/etc/ssl/certs/ca-bundle.crt ]; then
|
||||
if [ -e "$i/etc/ssl/certs/ca-bundle.crt" ]; then
|
||||
export NIX_SSL_CERT_FILE=$i/etc/ssl/certs/ca-bundle.crt
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -24,6 +24,9 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
|||
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
|
||||
fi
|
||||
|
||||
# Only use MANPATH if it is already set. In general `man` will just simply
|
||||
# pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin`
|
||||
# which is in the $PATH. For more info, run `manpath -d`.
|
||||
if [ -n "${MANPATH-}" ]; then
|
||||
export MANPATH="$NIX_LINK/share/man:$MANPATH"
|
||||
fi
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
#! @bash@
|
||||
|
||||
WORKING_DIRECTORY=$(mktemp -d "${TMPDIR:-/tmp}"/nix-reduce-build-XXXXXX);
|
||||
cd "$WORKING_DIRECTORY";
|
||||
|
||||
if test -z "$1" || test "a--help" = "a$1" ; then
|
||||
echo 'nix-reduce-build (paths or Nix expressions) -- (package sources)' >&2
|
||||
echo As in: >&2
|
||||
echo nix-reduce-build /etc/nixos/nixos -- ssh://user@somewhere.nowhere.example.org >&2
|
||||
echo nix-reduce-build /etc/nixos/nixos -- \\
|
||||
echo " " \''http://somewhere.nowhere.example.org/nix/nix-http-export.cgi?needed_path='\' >&2
|
||||
echo " store path name will be added into the end of the URL" >&2
|
||||
echo nix-reduce-build /etc/nixos/nixos -- file://home/user/nar/ >&2
|
||||
echo " that should be a directory where gzipped 'nix-store --export' ">&2
|
||||
echo " files are located (they should have .nar.gz extension)" >&2
|
||||
echo " Or all together: " >&2
|
||||
echo -e nix-reduce-build /expr.nix /e2.nix -- \\\\\\\n\
|
||||
" ssh://a@b.example.com http://n.example.com/get-nar?q= file://nar/" >&2
|
||||
echo " Also supports best-effort local builds of failing expression set:" >&2
|
||||
echo "nix-reduce-build /e.nix -- nix-daemon:// nix-self://" >&2
|
||||
echo " nix-daemon:// builds using daemon"
|
||||
echo " nix-self:// builds directly using nix-store from current installation" >&2
|
||||
echo " nix-daemon-fixed:// and nix-self-fixed:// do the same, but only for" >&2;
|
||||
echo "derivations with specified output hash (sha256, sha1 or md5)." >&2
|
||||
echo " nix-daemon-substitute:// and nix-self-substitute:// try to substitute" >&2;
|
||||
echo "maximum amount of paths" >&2;
|
||||
echo " nix-daemon-build:// and nix-self-build:// try to build (not substitute)" >&2;
|
||||
echo "maximum amount of paths" >&2;
|
||||
echo " If no package sources are specified, required paths are listed." >&2;
|
||||
exit;
|
||||
fi;
|
||||
|
||||
while ! test "$1" = "--" || test "$1" = "" ; do
|
||||
echo "$1" >> initial; >&2
|
||||
shift;
|
||||
done
|
||||
shift;
|
||||
echo Will work on $(cat initial | wc -l) targets. >&2
|
||||
|
||||
while read ; do
|
||||
case "$REPLY" in
|
||||
${NIX_STORE_DIR:-/nix/store}/*)
|
||||
echo "$REPLY" >> paths; >&2
|
||||
;;
|
||||
*)
|
||||
(
|
||||
IFS=: ;
|
||||
nix-instantiate $REPLY >> paths;
|
||||
);
|
||||
;;
|
||||
esac;
|
||||
done < initial;
|
||||
echo Proceeding $(cat paths | wc -l) paths. >&2
|
||||
|
||||
while read; do
|
||||
case "$REPLY" in
|
||||
*.drv)
|
||||
echo "$REPLY" >> derivers; >&2
|
||||
;;
|
||||
*)
|
||||
nix-store --query --deriver "$REPLY" >>derivers;
|
||||
;;
|
||||
esac;
|
||||
done < paths;
|
||||
echo Found $(cat derivers | wc -l) derivers. >&2
|
||||
|
||||
cat derivers | xargs nix-store --query -R > derivers-closure;
|
||||
echo Proceeding at most $(cat derivers-closure | wc -l) derivers. >&2
|
||||
|
||||
cat derivers-closure | egrep '[.]drv$' | xargs nix-store --query --outputs > wanted-paths;
|
||||
cat derivers-closure | egrep -v '[.]drv$' >> wanted-paths;
|
||||
echo Prepared $(cat wanted-paths | wc -l) paths to get. >&2
|
||||
|
||||
cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
|
||||
echo We need $(cat needed-paths | wc -l) paths. >&2
|
||||
|
||||
egrep '[.]drv$' derivers-closure > critical-derivers;
|
||||
|
||||
if test -z "$1" ; then
|
||||
cat needed-paths;
|
||||
fi;
|
||||
|
||||
refresh_critical_derivers() {
|
||||
echo "Finding needed derivers..." >&2;
|
||||
cat critical-derivers | while read; do
|
||||
if ! (nix-store --query --outputs "$REPLY" | xargs nix-store --check-validity &> /dev/null;); then
|
||||
echo "$REPLY";
|
||||
fi;
|
||||
done > new-critical-derivers;
|
||||
mv new-critical-derivers critical-derivers;
|
||||
echo The needed paths are realized by $(cat critical-derivers | wc -l) derivers. >&2
|
||||
}
|
||||
|
||||
build_here() {
|
||||
cat critical-derivers | while read; do
|
||||
echo "Realising $REPLY using nix-daemon" >&2
|
||||
@bindir@/nix-store -r "${REPLY}"
|
||||
done;
|
||||
}
|
||||
|
||||
try_to_substitute(){
|
||||
cat needed-paths | while read ; do
|
||||
echo "Building $REPLY using nix-daemon" >&2
|
||||
@bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}"
|
||||
done;
|
||||
}
|
||||
|
||||
for i in "$@"; do
|
||||
sshHost="${i#ssh://}";
|
||||
httpHost="${i#http://}";
|
||||
httpsHost="${i#https://}";
|
||||
filePath="${i#file:/}";
|
||||
if [ "$i" != "$sshHost" ]; then
|
||||
cat needed-paths | while read; do
|
||||
echo "Getting $REPLY and its closure over ssh" >&2
|
||||
nix-copy-closure --from "$sshHost" --gzip "$REPLY" </dev/null || true;
|
||||
done;
|
||||
elif [ "$i" != "$httpHost" ] || [ "$i" != "$httpsHost" ]; then
|
||||
cat needed-paths | while read; do
|
||||
echo "Getting $REPLY over http/https" >&2
|
||||
curl ${BAD_CERTIFICATE:+-k} -L "$i${REPLY##*/}" | gunzip | nix-store --import;
|
||||
done;
|
||||
elif [ "$i" != "$filePath" ] ; then
|
||||
cat needed-paths | while read; do
|
||||
echo "Installing $REPLY from file" >&2
|
||||
gunzip < "$filePath/${REPLY##*/}".nar.gz | nix-store --import;
|
||||
done;
|
||||
elif [ "$i" = "nix-daemon://" ] ; then
|
||||
NIX_REMOTE=daemon try_to_substitute;
|
||||
refresh_critical_derivers;
|
||||
NIX_REMOTE=daemon build_here;
|
||||
elif [ "$i" = "nix-self://" ] ; then
|
||||
NIX_REMOTE= try_to_substitute;
|
||||
refresh_critical_derivers;
|
||||
NIX_REMOTE= build_here;
|
||||
elif [ "$i" = "nix-daemon-fixed://" ] ; then
|
||||
refresh_critical_derivers;
|
||||
|
||||
cat critical-derivers | while read; do
|
||||
if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
|
||||
echo "Realising $REPLY using nix-daemon" >&2
|
||||
NIX_REMOTE=daemon @bindir@/nix-store -r "${REPLY}"
|
||||
fi;
|
||||
done;
|
||||
elif [ "$i" = "nix-self-fixed://" ] ; then
|
||||
refresh_critical_derivers;
|
||||
|
||||
cat critical-derivers | while read; do
|
||||
if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
|
||||
echo "Realising $REPLY using direct Nix build" >&2
|
||||
NIX_REMOTE= @bindir@/nix-store -r "${REPLY}"
|
||||
fi;
|
||||
done;
|
||||
elif [ "$i" = "nix-daemon-substitute://" ] ; then
|
||||
NIX_REMOTE=daemon try_to_substitute;
|
||||
elif [ "$i" = "nix-self-substitute://" ] ; then
|
||||
NIX_REMOTE= try_to_substitute;
|
||||
elif [ "$i" = "nix-daemon-build://" ] ; then
|
||||
refresh_critical_derivers;
|
||||
NIX_REMOTE=daemon build_here;
|
||||
elif [ "$i" = "nix-self-build://" ] ; then
|
||||
refresh_critical_derivers;
|
||||
NIX_REMOTE= build_here;
|
||||
fi;
|
||||
mv needed-paths wanted-paths;
|
||||
cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
|
||||
echo We still need $(cat needed-paths | wc -l) paths. >&2
|
||||
done;
|
||||
|
||||
cd /
|
||||
rm -r "$WORKING_DIRECTORY"
|
|
@ -3,7 +3,7 @@
|
|||
set -e
|
||||
|
||||
script=$(nix-build -A outputs.hydraJobs.installerScriptForGHA --no-out-link)
|
||||
installerHash=$(echo $script | cut -b12-43 -)
|
||||
installerHash=$(echo "$script" | cut -b12-43 -)
|
||||
|
||||
installerURL=https://$CACHIX_NAME.cachix.org/serve/$installerHash/install
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) {
|
||||
(import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") {
|
||||
src = ./.;
|
||||
}).shellNix
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
#include "pathlocks.hh"
|
||||
#include "globals.hh"
|
||||
#include "serialise.hh"
|
||||
#include "build-result.hh"
|
||||
#include "store-api.hh"
|
||||
#include "derivations.hh"
|
||||
#include "local-store.hh"
|
||||
#include "legacy.hh"
|
||||
#include "experimental-features.hh"
|
||||
|
||||
using namespace nix;
|
||||
using std::cin;
|
||||
|
@ -31,7 +33,7 @@ std::string escapeUri(std::string uri)
|
|||
return uri;
|
||||
}
|
||||
|
||||
static string currentLoad;
|
||||
static std::string currentLoad;
|
||||
|
||||
static AutoCloseFD openSlotLock(const Machine & m, uint64_t slot)
|
||||
{
|
||||
|
@ -96,7 +98,7 @@ static int main_build_remote(int argc, char * * argv)
|
|||
}
|
||||
|
||||
std::optional<StorePath> drvPath;
|
||||
string storeUri;
|
||||
std::string storeUri;
|
||||
|
||||
while (true) {
|
||||
|
||||
|
@ -130,11 +132,14 @@ static int main_build_remote(int argc, char * * argv)
|
|||
for (auto & m : machines) {
|
||||
debug("considering building on remote machine '%s'", m.storeUri);
|
||||
|
||||
if (m.enabled && std::find(m.systemTypes.begin(),
|
||||
m.systemTypes.end(),
|
||||
neededSystem) != m.systemTypes.end() &&
|
||||
if (m.enabled
|
||||
&& (neededSystem == "builtin"
|
||||
|| std::find(m.systemTypes.begin(),
|
||||
m.systemTypes.end(),
|
||||
neededSystem) != m.systemTypes.end()) &&
|
||||
m.allSupported(requiredFeatures) &&
|
||||
m.mandatoryMet(requiredFeatures)) {
|
||||
m.mandatoryMet(requiredFeatures))
|
||||
{
|
||||
rightType = true;
|
||||
AutoCloseFD free;
|
||||
uint64_t load = 0;
|
||||
|
@ -179,7 +184,7 @@ static int main_build_remote(int argc, char * * argv)
|
|||
else
|
||||
{
|
||||
// build the hint template.
|
||||
string errorText =
|
||||
std::string errorText =
|
||||
"Failed to find a machine for remote build!\n"
|
||||
"derivation: %s\nrequired (system, features): (%s, %s)";
|
||||
errorText += "\n%s available machines:";
|
||||
|
@ -189,7 +194,7 @@ static int main_build_remote(int argc, char * * argv)
|
|||
errorText += "\n(%s, %s, %s, %s)";
|
||||
|
||||
// add the template values.
|
||||
string drvstr;
|
||||
std::string drvstr;
|
||||
if (drvPath.has_value())
|
||||
drvstr = drvPath->to_string();
|
||||
else
|
||||
|
@ -204,7 +209,7 @@ static int main_build_remote(int argc, char * * argv)
|
|||
|
||||
for (auto & m : machines)
|
||||
error
|
||||
% concatStringsSep<vector<string>>(", ", m.systemTypes)
|
||||
% concatStringsSep<std::vector<std::string>>(", ", m.systemTypes)
|
||||
% m.maxJobs
|
||||
% concatStringsSep<StringSet>(", ", m.supportedFeatures)
|
||||
% concatStringsSep<StringSet>(", ", m.mandatoryFeatures);
|
||||
|
@ -295,7 +300,7 @@ connected:
|
|||
|
||||
std::set<Realisation> missingRealisations;
|
||||
StorePathSet missingPaths;
|
||||
if (settings.isExperimentalFeatureEnabled("ca-derivations") && !derivationHasKnownOutputPaths(drv.type())) {
|
||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations) && !derivationHasKnownOutputPaths(drv.type())) {
|
||||
for (auto & outputName : wantedOutputs) {
|
||||
auto thisOutputHash = outputHashes.at(outputName);
|
||||
auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
|
||||
|
@ -327,7 +332,7 @@ connected:
|
|||
for (auto & realisation : missingRealisations) {
|
||||
// Should hold, because if the feature isn't enabled the set
|
||||
// of missing realisations should be empty
|
||||
settings.requireExperimentalFeature("ca-derivations");
|
||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
||||
store->registerDrvOutput(realisation);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
Copyright (c) 2014 Chase Geigle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
File diff suppressed because it is too large
Load diff
|
@ -54,6 +54,36 @@ void StoreCommand::run()
|
|||
run(getStore());
|
||||
}
|
||||
|
||||
CopyCommand::CopyCommand()
|
||||
{
|
||||
addFlag({
|
||||
.longName = "from",
|
||||
.description = "URL of the source Nix store.",
|
||||
.labels = {"store-uri"},
|
||||
.handler = {&srcUri},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "to",
|
||||
.description = "URL of the destination Nix store.",
|
||||
.labels = {"store-uri"},
|
||||
.handler = {&dstUri},
|
||||
});
|
||||
}
|
||||
|
||||
ref<Store> CopyCommand::createStore()
|
||||
{
|
||||
return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri);
|
||||
}
|
||||
|
||||
ref<Store> CopyCommand::getDstStore()
|
||||
{
|
||||
if (srcUri.empty() && dstUri.empty())
|
||||
throw UsageError("you must pass '--from' and/or '--to'");
|
||||
|
||||
return dstUri.empty() ? openStore() : openStore(dstUri);
|
||||
}
|
||||
|
||||
EvalCommand::EvalCommand()
|
||||
{
|
||||
}
|
||||
|
@ -74,7 +104,15 @@ ref<Store> EvalCommand::getEvalStore()
|
|||
ref<EvalState> EvalCommand::getEvalState()
|
||||
{
|
||||
if (!evalState)
|
||||
evalState = std::make_shared<EvalState>(searchPath, getEvalStore(), getStore());
|
||||
evalState =
|
||||
#if HAVE_BOEHMGC
|
||||
std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
|
||||
searchPath, getEvalStore(), getStore())
|
||||
#else
|
||||
std::make_shared<EvalState>(
|
||||
searchPath, getEvalStore(), getStore())
|
||||
#endif
|
||||
;
|
||||
return ref<EvalState>(evalState);
|
||||
}
|
||||
|
||||
|
@ -115,7 +153,7 @@ void BuiltPathsCommand::run(ref<Store> store)
|
|||
for (auto & p : store->queryAllValidPaths())
|
||||
paths.push_back(BuiltPath::Opaque{p});
|
||||
} else {
|
||||
paths = toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
||||
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
||||
if (recursive) {
|
||||
// XXX: This only computes the store path closure, ignoring
|
||||
// intermediate realisations
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "common-eval-args.hh"
|
||||
#include "path.hh"
|
||||
#include "flake/lockfile.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
@ -43,6 +42,19 @@ private:
|
|||
std::shared_ptr<Store> _store;
|
||||
};
|
||||
|
||||
/* A command that copies something between `--from` and `--to`
|
||||
stores. */
|
||||
struct CopyCommand : virtual StoreCommand
|
||||
{
|
||||
std::string srcUri, dstUri;
|
||||
|
||||
CopyCommand();
|
||||
|
||||
ref<Store> createStore() override;
|
||||
|
||||
ref<Store> getDstStore();
|
||||
};
|
||||
|
||||
struct EvalCommand : virtual StoreCommand, MixEvalArgs
|
||||
{
|
||||
EvalCommand();
|
||||
|
@ -69,14 +81,6 @@ struct MixFlakeOptions : virtual Args, EvalCommand
|
|||
{ return {}; }
|
||||
};
|
||||
|
||||
/* How to handle derivations in commands that operate on store paths. */
|
||||
enum class OperateOn {
|
||||
/* Operate on the output path. */
|
||||
Output,
|
||||
/* Operate on the .drv path. */
|
||||
Derivation
|
||||
};
|
||||
|
||||
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||
{
|
||||
std::optional<Path> file;
|
||||
|
@ -100,19 +104,6 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
|
|||
void completeInstallable(std::string_view prefix);
|
||||
};
|
||||
|
||||
enum class Realise {
|
||||
/* Build the derivation. Postcondition: the
|
||||
derivation outputs exist. */
|
||||
Outputs,
|
||||
/* Don't build the derivation. Postcondition: the store derivation
|
||||
exists. */
|
||||
Derivation,
|
||||
/* Evaluate in dry-run mode. Postcondition: nothing. */
|
||||
// FIXME: currently unused, but could be revived if we can
|
||||
// evaluate derivations in-memory.
|
||||
Nothing
|
||||
};
|
||||
|
||||
/* A command that operates on a list of "installables", which can be
|
||||
store paths, attribute paths, Nix expressions, etc. */
|
||||
struct InstallablesCommand : virtual Args, SourceExprCommand
|
||||
|
@ -225,38 +216,6 @@ static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
|||
return RegisterCommand(std::move(name), [](){ return make_ref<T>(); });
|
||||
}
|
||||
|
||||
BuiltPaths build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store, Realise mode,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
BuildMode bMode = bmNormal);
|
||||
|
||||
std::set<StorePath> toStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables);
|
||||
|
||||
StorePath toStorePath(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
std::shared_ptr<Installable> installable);
|
||||
|
||||
std::set<StorePath> toDerivations(
|
||||
ref<Store> store,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
bool useDeriver = false);
|
||||
|
||||
BuiltPaths toBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables);
|
||||
|
||||
/* Helper function to generate args that invoke $EDITOR on
|
||||
filename:lineno. */
|
||||
Strings editorFor(const Pos & pos);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
|
@ -97,7 +98,7 @@ MixFlakeOptions::MixFlakeOptions()
|
|||
lockFlags.writeLockFile = false;
|
||||
lockFlags.inputOverrides.insert_or_assign(
|
||||
flake::parseInputPath(inputPath),
|
||||
parseFlakeRef(flakeRef, absPath(".")));
|
||||
parseFlakeRef(flakeRef, absPath("."), true));
|
||||
}}
|
||||
});
|
||||
|
||||
|
@ -158,7 +159,10 @@ SourceExprCommand::SourceExprCommand()
|
|||
|
||||
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
|
||||
{
|
||||
return {"defaultPackage." + settings.thisSystem.get()};
|
||||
return {
|
||||
"packages." + settings.thisSystem.get() + ".default",
|
||||
"defaultPackage." + settings.thisSystem.get()
|
||||
};
|
||||
}
|
||||
|
||||
Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
|
||||
|
@ -191,18 +195,21 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
|||
auto sep = prefix_.rfind('.');
|
||||
std::string searchWord;
|
||||
if (sep != std::string::npos) {
|
||||
searchWord = prefix_.substr(sep, std::string::npos);
|
||||
searchWord = prefix_.substr(sep + 1, std::string::npos);
|
||||
prefix_ = prefix_.substr(0, sep);
|
||||
} else {
|
||||
searchWord = prefix_;
|
||||
prefix_ = "";
|
||||
}
|
||||
|
||||
Value &v1(*findAlongAttrPath(*state, prefix_, *autoArgs, root).first);
|
||||
state->forceValue(v1);
|
||||
auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root);
|
||||
Value &v1(*v);
|
||||
state->forceValue(v1, pos);
|
||||
Value v2;
|
||||
state->autoCallFunction(*autoArgs, v1, v2);
|
||||
|
||||
completionType = ctAttrs;
|
||||
|
||||
if (v2.type() == nAttrs) {
|
||||
for (auto & i : *v2.attrs) {
|
||||
std::string name = i.name;
|
||||
|
@ -232,7 +239,9 @@ void completeFlakeRefWithFragment(
|
|||
prefix. */
|
||||
try {
|
||||
auto hash = prefix.find('#');
|
||||
if (hash != std::string::npos) {
|
||||
if (hash == std::string::npos) {
|
||||
completeFlakeRef(evalState->store, prefix);
|
||||
} else {
|
||||
auto fragment = prefix.substr(hash + 1);
|
||||
auto flakeRefS = std::string(prefix.substr(0, hash));
|
||||
// FIXME: do tilde expansion.
|
||||
|
@ -248,6 +257,8 @@ void completeFlakeRefWithFragment(
|
|||
flake. */
|
||||
attrPathPrefixes.push_back("");
|
||||
|
||||
completionType = ctAttrs;
|
||||
|
||||
for (auto & attrPathPrefixS : attrPathPrefixes) {
|
||||
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
|
||||
auto attrPathS = attrPathPrefixS + std::string(fragment);
|
||||
|
@ -262,9 +273,9 @@ void completeFlakeRefWithFragment(
|
|||
auto attr = root->findAlongAttrPath(attrPath);
|
||||
if (!attr) continue;
|
||||
|
||||
for (auto & attr2 : attr->getAttrs()) {
|
||||
for (auto & attr2 : (*attr)->getAttrs()) {
|
||||
if (hasPrefix(attr2, lastAttr)) {
|
||||
auto attrPath2 = attr->getAttrPath(attr2);
|
||||
auto attrPath2 = (*attr)->getAttrPath(attr2);
|
||||
/* Strip the attrpath prefix. */
|
||||
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
|
||||
completions->add(flakeRefS + "#" + concatStringsSep(".", attrPath2));
|
||||
|
@ -285,12 +296,13 @@ void completeFlakeRefWithFragment(
|
|||
} catch (Error & e) {
|
||||
warn(e.msg());
|
||||
}
|
||||
|
||||
completeFlakeRef(evalState->store, prefix);
|
||||
}
|
||||
|
||||
void completeFlakeRef(ref<Store> store, std::string_view prefix)
|
||||
{
|
||||
if (!settings.isExperimentalFeatureEnabled(Xp::Flakes))
|
||||
return;
|
||||
|
||||
if (prefix == "")
|
||||
completions->add(".");
|
||||
|
||||
|
@ -338,6 +350,18 @@ Installable::getCursor(EvalState & state)
|
|||
return cursors[0];
|
||||
}
|
||||
|
||||
static StorePath getDeriver(
|
||||
ref<Store> store,
|
||||
const Installable & i,
|
||||
const StorePath & drvPath)
|
||||
{
|
||||
auto derivers = store->queryValidDerivers(drvPath);
|
||||
if (derivers.empty())
|
||||
throw Error("'%s' does not have a known deriver", i.what());
|
||||
// FIXME: use all derivers?
|
||||
return *derivers.begin();
|
||||
}
|
||||
|
||||
struct InstallableStorePath : Installable
|
||||
{
|
||||
ref<Store> store;
|
||||
|
@ -346,7 +370,7 @@ struct InstallableStorePath : Installable
|
|||
InstallableStorePath(ref<Store> store, StorePath && storePath)
|
||||
: store(store), storePath(std::move(storePath)) { }
|
||||
|
||||
std::string what() override { return store->printStorePath(storePath); }
|
||||
std::string what() const override { return store->printStorePath(storePath); }
|
||||
|
||||
DerivedPaths toDerivedPaths() override
|
||||
{
|
||||
|
@ -367,6 +391,15 @@ struct InstallableStorePath : Installable
|
|||
}
|
||||
}
|
||||
|
||||
StorePathSet toDrvPaths(ref<Store> store) override
|
||||
{
|
||||
if (storePath.isDerivation()) {
|
||||
return {storePath};
|
||||
} else {
|
||||
return {getDeriver(store, *this, storePath)};
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<StorePath> getStorePath() override
|
||||
{
|
||||
return storePath;
|
||||
|
@ -395,6 +428,14 @@ DerivedPaths InstallableValue::toDerivedPaths()
|
|||
return res;
|
||||
}
|
||||
|
||||
StorePathSet InstallableValue::toDrvPaths(ref<Store> store)
|
||||
{
|
||||
StorePathSet res;
|
||||
for (auto & drv : toDerivations())
|
||||
res.insert(drv.drvPath);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct InstallableAttrPath : InstallableValue
|
||||
{
|
||||
SourceExprCommand & cmd;
|
||||
|
@ -405,12 +446,12 @@ struct InstallableAttrPath : InstallableValue
|
|||
: InstallableValue(state), cmd(cmd), v(allocRootValue(v)), attrPath(attrPath)
|
||||
{ }
|
||||
|
||||
std::string what() override { return attrPath; }
|
||||
std::string what() const override { return attrPath; }
|
||||
|
||||
std::pair<Value *, Pos> toValue(EvalState & state) override
|
||||
{
|
||||
auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), **v);
|
||||
state.forceValue(*vRes);
|
||||
state.forceValue(*vRes, pos);
|
||||
return {vRes, pos};
|
||||
}
|
||||
|
||||
|
@ -428,11 +469,10 @@ std::vector<InstallableValue::DerivationInfo> InstallableAttrPath::toDerivations
|
|||
|
||||
std::vector<DerivationInfo> res;
|
||||
for (auto & drvInfo : drvInfos) {
|
||||
res.push_back({
|
||||
state->store->parseStorePath(drvInfo.queryDrvPath()),
|
||||
state->store->maybeParseStorePath(drvInfo.queryOutPath()),
|
||||
drvInfo.queryOutputName()
|
||||
});
|
||||
auto drvPath = drvInfo.queryDrvPath();
|
||||
if (!drvPath)
|
||||
throw Error("'%s' is not a derivation", what());
|
||||
res.push_back({ *drvPath, drvInfo.queryOutputName() });
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -460,7 +500,7 @@ Value * InstallableFlake::getFlakeOutputs(EvalState & state, const flake::Locked
|
|||
auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
|
||||
assert(aOutputs);
|
||||
|
||||
state.forceValue(*aOutputs->value);
|
||||
state.forceValue(*aOutputs->value, [&]() { return aOutputs->value->determinePos(noPos); });
|
||||
|
||||
return aOutputs->value;
|
||||
}
|
||||
|
@ -485,7 +525,7 @@ ref<eval_cache::EvalCache> openEvalCache(
|
|||
auto vFlake = state.allocValue();
|
||||
flake::callFlake(state, *lockedFlake, *vFlake);
|
||||
|
||||
state.forceAttrs(*vFlake);
|
||||
state.forceAttrs(*vFlake, noPos);
|
||||
|
||||
auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
|
||||
assert(aOutputs);
|
||||
|
@ -508,13 +548,14 @@ InstallableFlake::InstallableFlake(
|
|||
SourceExprCommand * cmd,
|
||||
ref<EvalState> state,
|
||||
FlakeRef && flakeRef,
|
||||
Strings && attrPaths,
|
||||
Strings && prefixes,
|
||||
std::string_view fragment,
|
||||
Strings attrPaths,
|
||||
Strings prefixes,
|
||||
const flake::LockFlags & lockFlags)
|
||||
: InstallableValue(state),
|
||||
flakeRef(flakeRef),
|
||||
attrPaths(attrPaths),
|
||||
prefixes(prefixes),
|
||||
attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}),
|
||||
prefixes(fragment == "" ? Strings{} : prefixes),
|
||||
lockFlags(lockFlags)
|
||||
{
|
||||
if (cmd && cmd->getAutoArgs(*state)->size())
|
||||
|
@ -528,29 +569,37 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
|
|||
auto cache = openEvalCache(*state, lockedFlake);
|
||||
auto root = cache->getRoot();
|
||||
|
||||
Suggestions suggestions;
|
||||
|
||||
for (auto & attrPath : getActualAttrPaths()) {
|
||||
auto attr = root->findAlongAttrPath(
|
||||
debug("trying flake output attribute '%s'", attrPath);
|
||||
|
||||
auto attrOrSuggestions = root->findAlongAttrPath(
|
||||
parseAttrPath(*state, attrPath),
|
||||
true
|
||||
);
|
||||
|
||||
if (!attr) continue;
|
||||
if (!attrOrSuggestions) {
|
||||
suggestions += attrOrSuggestions.getSuggestions();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto attr = *attrOrSuggestions;
|
||||
|
||||
if (!attr->isDerivation())
|
||||
throw Error("flake output attribute '%s' is not a derivation", attrPath);
|
||||
|
||||
auto drvPath = attr->forceDerivation();
|
||||
|
||||
auto drvInfo = DerivationInfo{
|
||||
auto drvInfo = DerivationInfo {
|
||||
std::move(drvPath),
|
||||
state->store->maybeParseStorePath(attr->getAttr(state->sOutPath)->getString()),
|
||||
attr->getAttr(state->sOutputName)->getString()
|
||||
};
|
||||
|
||||
return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)};
|
||||
}
|
||||
|
||||
throw Error("flake '%s' does not provide attribute %s",
|
||||
throw Error(suggestions, "flake '%s' does not provide attribute %s",
|
||||
flakeRef, showAttrPaths(getActualAttrPaths()));
|
||||
}
|
||||
|
||||
|
@ -569,17 +618,24 @@ std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state)
|
|||
|
||||
auto emptyArgs = state.allocBindings(0);
|
||||
|
||||
Suggestions suggestions;
|
||||
|
||||
for (auto & attrPath : getActualAttrPaths()) {
|
||||
try {
|
||||
auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
|
||||
state.forceValue(*v);
|
||||
state.forceValue(*v, pos);
|
||||
return {v, pos};
|
||||
} catch (AttrPathNotFound & e) {
|
||||
suggestions += e.info().suggestions;
|
||||
}
|
||||
}
|
||||
|
||||
throw Error("flake '%s' does not provide attribute %s",
|
||||
flakeRef, showAttrPaths(getActualAttrPaths()));
|
||||
throw Error(
|
||||
suggestions,
|
||||
"flake '%s' does not provide attribute %s",
|
||||
flakeRef,
|
||||
showAttrPaths(getActualAttrPaths())
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::shared_ptr<eval_cache::AttrCursor>, std::string>>
|
||||
|
@ -594,7 +650,7 @@ InstallableFlake::getCursors(EvalState & state)
|
|||
|
||||
for (auto & attrPath : getActualAttrPaths()) {
|
||||
auto attr = root->findAlongAttrPath(parseAttrPath(state, attrPath));
|
||||
if (attr) res.push_back({attr, attrPath});
|
||||
if (attr) res.push_back({*attr, attrPath});
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -671,7 +727,8 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
|
|||
this,
|
||||
getEvalState(),
|
||||
std::move(flakeRef),
|
||||
fragment == "" ? getDefaultFlakeAttrPaths() : Strings{fragment},
|
||||
fragment,
|
||||
getDefaultFlakeAttrPaths(),
|
||||
getDefaultFlakeAttrPathPrefixes(),
|
||||
lockFlags));
|
||||
continue;
|
||||
|
@ -713,8 +770,7 @@ BuiltPaths getBuiltPaths(ref<Store> evalStore, ref<Store> store, const DerivedPa
|
|||
throw Error(
|
||||
"the derivation '%s' doesn't have an output named '%s'",
|
||||
store->printStorePath(bfd.drvPath), output);
|
||||
if (settings.isExperimentalFeatureEnabled(
|
||||
"ca-derivations")) {
|
||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
||||
auto outputId =
|
||||
DrvOutput{outputHashes.at(output), output};
|
||||
auto realisation =
|
||||
|
@ -743,7 +799,7 @@ BuiltPaths getBuiltPaths(ref<Store> evalStore, ref<Store> store, const DerivedPa
|
|||
return res;
|
||||
}
|
||||
|
||||
BuiltPaths build(
|
||||
BuiltPaths Installable::build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
|
@ -760,15 +816,36 @@ BuiltPaths build(
|
|||
pathsToBuild.insert(pathsToBuild.end(), b.begin(), b.end());
|
||||
}
|
||||
|
||||
if (mode == Realise::Nothing || mode == Realise::Derivation)
|
||||
switch (mode) {
|
||||
case Realise::Nothing:
|
||||
case Realise::Derivation:
|
||||
printMissing(store, pathsToBuild, lvlError);
|
||||
else if (mode == Realise::Outputs)
|
||||
store->buildPaths(pathsToBuild, bMode, evalStore);
|
||||
|
||||
return getBuiltPaths(evalStore, store, pathsToBuild);
|
||||
return getBuiltPaths(evalStore, store, pathsToBuild);
|
||||
case Realise::Outputs: {
|
||||
BuiltPaths res;
|
||||
for (auto & buildResult : store->buildPathsWithResults(pathsToBuild, bMode, evalStore)) {
|
||||
if (!buildResult.success())
|
||||
buildResult.rethrow();
|
||||
std::visit(overloaded {
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
std::map<std::string, StorePath> outputs;
|
||||
for (auto & path : buildResult.builtOutputs)
|
||||
outputs.emplace(path.first.outputName, path.second.outPath);
|
||||
res.push_back(BuiltPath::Built { bfd.drvPath, outputs });
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back(BuiltPath::Opaque { bo.path });
|
||||
},
|
||||
}, buildResult.path.raw());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
BuiltPaths toBuiltPaths(
|
||||
BuiltPaths Installable::toBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
|
@ -776,19 +853,19 @@ BuiltPaths toBuiltPaths(
|
|||
const std::vector<std::shared_ptr<Installable>> & installables)
|
||||
{
|
||||
if (operateOn == OperateOn::Output)
|
||||
return build(evalStore, store, mode, installables);
|
||||
return Installable::build(evalStore, store, mode, installables);
|
||||
else {
|
||||
if (mode == Realise::Nothing)
|
||||
settings.readOnlyMode = true;
|
||||
|
||||
BuiltPaths res;
|
||||
for (auto & drvPath : toDerivations(store, installables, true))
|
||||
for (auto & drvPath : Installable::toDerivations(store, installables, true))
|
||||
res.push_back(BuiltPath::Opaque{drvPath});
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
StorePathSet toStorePaths(
|
||||
StorePathSet Installable::toStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
|
@ -802,7 +879,7 @@ StorePathSet toStorePaths(
|
|||
return outPaths;
|
||||
}
|
||||
|
||||
StorePath toStorePath(
|
||||
StorePath Installable::toStorePath(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
|
@ -816,7 +893,7 @@ StorePath toStorePath(
|
|||
return *paths.begin();
|
||||
}
|
||||
|
||||
StorePathSet toDerivations(
|
||||
StorePathSet Installable::toDerivations(
|
||||
ref<Store> store,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
bool useDeriver)
|
||||
|
@ -829,11 +906,7 @@ StorePathSet toDerivations(
|
|||
[&](const DerivedPath::Opaque & bo) {
|
||||
if (!useDeriver)
|
||||
throw Error("argument '%s' did not evaluate to a derivation", i->what());
|
||||
auto derivers = store->queryValidDerivers(bo.path);
|
||||
if (derivers.empty())
|
||||
throw Error("'%s' does not have a known deriver", i->what());
|
||||
// FIXME: use all derivers?
|
||||
drvPaths.insert(*derivers.begin());
|
||||
drvPaths.insert(getDeriver(store, *i, bo.path));
|
||||
},
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
drvPaths.insert(bfd.drvPath);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "path-with-outputs.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "eval.hh"
|
||||
#include "store-api.hh"
|
||||
#include "flake/flake.hh"
|
||||
|
||||
#include <optional>
|
||||
|
@ -29,14 +30,40 @@ struct UnresolvedApp
|
|||
App resolve(ref<Store> evalStore, ref<Store> store);
|
||||
};
|
||||
|
||||
enum class Realise {
|
||||
/* Build the derivation. Postcondition: the
|
||||
derivation outputs exist. */
|
||||
Outputs,
|
||||
/* Don't build the derivation. Postcondition: the store derivation
|
||||
exists. */
|
||||
Derivation,
|
||||
/* Evaluate in dry-run mode. Postcondition: nothing. */
|
||||
// FIXME: currently unused, but could be revived if we can
|
||||
// evaluate derivations in-memory.
|
||||
Nothing
|
||||
};
|
||||
|
||||
/* How to handle derivations in commands that operate on store paths. */
|
||||
enum class OperateOn {
|
||||
/* Operate on the output path. */
|
||||
Output,
|
||||
/* Operate on the .drv path. */
|
||||
Derivation
|
||||
};
|
||||
|
||||
struct Installable
|
||||
{
|
||||
virtual ~Installable() { }
|
||||
|
||||
virtual std::string what() = 0;
|
||||
virtual std::string what() const = 0;
|
||||
|
||||
virtual DerivedPaths toDerivedPaths() = 0;
|
||||
|
||||
virtual StorePathSet toDrvPaths(ref<Store> store)
|
||||
{
|
||||
throw Error("'%s' cannot be converted to a derivation path", what());
|
||||
}
|
||||
|
||||
DerivedPath toDerivedPath();
|
||||
|
||||
UnresolvedApp toApp(EvalState & state);
|
||||
|
@ -63,6 +90,39 @@ struct Installable
|
|||
{
|
||||
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
|
||||
}
|
||||
|
||||
static BuiltPaths build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
BuildMode bMode = bmNormal);
|
||||
|
||||
static std::set<StorePath> toStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables);
|
||||
|
||||
static StorePath toStorePath(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
std::shared_ptr<Installable> installable);
|
||||
|
||||
static std::set<StorePath> toDerivations(
|
||||
ref<Store> store,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
bool useDeriver = false);
|
||||
|
||||
static BuiltPaths toBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables);
|
||||
};
|
||||
|
||||
struct InstallableValue : Installable
|
||||
|
@ -74,13 +134,14 @@ struct InstallableValue : Installable
|
|||
struct DerivationInfo
|
||||
{
|
||||
StorePath drvPath;
|
||||
std::optional<StorePath> outPath;
|
||||
std::string outputName;
|
||||
};
|
||||
|
||||
virtual std::vector<DerivationInfo> toDerivations() = 0;
|
||||
|
||||
DerivedPaths toDerivedPaths() override;
|
||||
|
||||
StorePathSet toDrvPaths(ref<Store> store) override;
|
||||
};
|
||||
|
||||
struct InstallableFlake : InstallableValue
|
||||
|
@ -95,11 +156,12 @@ struct InstallableFlake : InstallableValue
|
|||
SourceExprCommand * cmd,
|
||||
ref<EvalState> state,
|
||||
FlakeRef && flakeRef,
|
||||
Strings && attrPaths,
|
||||
Strings && prefixes,
|
||||
std::string_view fragment,
|
||||
Strings attrPaths,
|
||||
Strings prefixes,
|
||||
const flake::LockFlags & lockFlags);
|
||||
|
||||
std::string what() override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
|
||||
std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
|
||||
|
||||
std::vector<std::string> getActualAttrPaths();
|
||||
|
||||
|
@ -123,4 +185,9 @@ ref<eval_cache::EvalCache> openEvalCache(
|
|||
EvalState & state,
|
||||
std::shared_ptr<flake::LockedFlake> lockedFlake);
|
||||
|
||||
BuiltPaths getBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
const DerivedPaths & hopefullyBuiltPaths);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ libcmd_SOURCES := $(wildcard $(d)/*.cc)
|
|||
|
||||
libcmd_CXXFLAGS += -I src/libutil -I src/libstore -I src/libexpr -I src/libmain -I src/libfetchers
|
||||
|
||||
libcmd_LDFLAGS += -llowdown -pthread
|
||||
libcmd_LDFLAGS += $(LOWDOWN_LIBS) -pthread
|
||||
|
||||
libcmd_LIBS = libstore libutil libexpr libmain libfetchers
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace nix {
|
|||
static Strings parseAttrPath(std::string_view s)
|
||||
{
|
||||
Strings res;
|
||||
string cur;
|
||||
std::string cur;
|
||||
auto i = s.begin();
|
||||
while (i != s.end()) {
|
||||
if (*i == '.') {
|
||||
|
@ -41,7 +41,7 @@ std::vector<Symbol> parseAttrPath(EvalState & state, std::string_view s)
|
|||
}
|
||||
|
||||
|
||||
std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||
std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const std::string & attrPath,
|
||||
Bindings & autoArgs, Value & vIn)
|
||||
{
|
||||
Strings tokens = parseAttrPath(attrPath);
|
||||
|
@ -58,7 +58,7 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
|||
Value * vNew = state.allocValue();
|
||||
state.autoCallFunction(autoArgs, *v, *vNew);
|
||||
v = vNew;
|
||||
state.forceValue(*v);
|
||||
state.forceValue(*v, noPos);
|
||||
|
||||
/* It should evaluate to either a set or an expression,
|
||||
according to what is specified in the attrPath. */
|
||||
|
@ -74,8 +74,14 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
|||
throw Error("empty attribute name in selection path '%1%'", attrPath);
|
||||
|
||||
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
||||
if (a == v->attrs->end())
|
||||
throw AttrPathNotFound("attribute '%1%' in selection path '%2%' not found", attr, attrPath);
|
||||
if (a == v->attrs->end()) {
|
||||
std::set<std::string> attrNames;
|
||||
for (auto & attr : *v->attrs)
|
||||
attrNames.insert(attr.name);
|
||||
|
||||
auto suggestions = Suggestions::bestMatches(attrNames, attr);
|
||||
throw AttrPathNotFound(suggestions, "attribute '%1%' in selection path '%2%' not found", attr, attrPath);
|
||||
}
|
||||
v = &*a->value;
|
||||
pos = *a->pos;
|
||||
}
|
||||
|
@ -121,7 +127,7 @@ Pos findPackageFilename(EvalState & state, Value & v, std::string what)
|
|||
std::string filename(pos, 0, colon);
|
||||
unsigned int lineno;
|
||||
try {
|
||||
lineno = std::stoi(std::string(pos, colon + 1));
|
||||
lineno = std::stoi(std::string(pos, colon + 1, std::string::npos));
|
||||
} catch (std::invalid_argument & e) {
|
||||
throw ParseError("cannot parse line number '%s'", pos);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,11 @@ namespace nix {
|
|||
MakeError(AttrPathNotFound, Error);
|
||||
MakeError(NoPositionInfo, Error);
|
||||
|
||||
std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||
Bindings & autoArgs, Value & vIn);
|
||||
std::pair<Value *, Pos> findAlongAttrPath(
|
||||
EvalState & state,
|
||||
const std::string & attrPath,
|
||||
Bindings & autoArgs,
|
||||
Value & vIn);
|
||||
|
||||
/* Heuristic to find the filename and lineno or a nix value. */
|
||||
Pos findPackageFilename(EvalState & state, Value & v, std::string what);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue