Merge branch 'staging' into ios-13
This commit is contained in:
commit
86d8c55470
|
@ -43,15 +43,50 @@ indent_style = space
|
||||||
# Disable file types or individual files
|
# Disable file types or individual files
|
||||||
# some of these files may be auto-generated and/or require significant changes
|
# some of these files may be auto-generated and/or require significant changes
|
||||||
|
|
||||||
|
[*.{c,h}]
|
||||||
|
insert_final_newline = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[*.{key,ovpn}]
|
||||||
|
insert_final_newline = unset
|
||||||
|
end_of_line = unset
|
||||||
|
|
||||||
[*.lock]
|
[*.lock]
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
||||||
|
[deps.nix]
|
||||||
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[eggs.nix]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
[gemset.nix]
|
[gemset.nix]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[node-{composition,packages}.nix]
|
||||||
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[nixos/modules/services/networking/ircd-hybrid/*.{conf,in}]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[nixos/tests/systemd-networkd-vrf.nix]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
[pkgs/applications/editors/emacs-modes/recipes-archive-melpa.json]
|
[pkgs/applications/editors/emacs-modes/recipes-archive-melpa.json]
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
||||||
|
[pkgs/build-support/dotnetenv/Wrapper/**]
|
||||||
|
end_of_line = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[pkgs/build-support/upstream-updater/**]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[pkgs/development/compilers/elm/registry.dat]
|
||||||
|
end_of_line = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
|
||||||
[pkgs/development/lisp-modules/quicklisp-to-nix.nix]
|
[pkgs/development/lisp-modules/quicklisp-to-nix.nix]
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
||||||
|
@ -70,5 +105,8 @@ insert_final_newline = unset
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
|
[pkgs/top-level/emscripten-packages.nix]
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
|
||||||
[pkgs/top-level/perl-packages.nix]
|
[pkgs/top-level/perl-packages.nix]
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
# This file
|
# This file
|
||||||
/.github/CODEOWNERS @edolstra
|
/.github/CODEOWNERS @edolstra
|
||||||
|
|
||||||
|
# GitHub actions
|
||||||
|
/.github/workflows @Mic92 @zowoq
|
||||||
|
|
||||||
|
# EditorConfig
|
||||||
|
/.editorconfig @Mic92 @zowoq
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
/lib @edolstra @nbp @infinisil
|
/lib @edolstra @nbp @infinisil
|
||||||
/lib/systems @nbp @ericson2314 @matthewbauer
|
/lib/systems @nbp @ericson2314 @matthewbauer
|
||||||
|
@ -189,10 +195,16 @@
|
||||||
/pkgs/top-level/php-packages.nix @NixOS/php
|
/pkgs/top-level/php-packages.nix @NixOS/php
|
||||||
|
|
||||||
# Podman, CRI-O modules and related
|
# Podman, CRI-O modules and related
|
||||||
/nixos/modules/virtualisation/containers.nix @NixOS/podman
|
/nixos/modules/virtualisation/containers.nix @NixOS/podman @zowoq
|
||||||
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman
|
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman @zowoq
|
||||||
/nixos/modules/virtualisation/podman.nix @NixOS/podman
|
/nixos/modules/virtualisation/podman.nix @NixOS/podman @zowoq
|
||||||
/nixos/tests/podman.nix @NixOS/podman
|
/nixos/tests/cri-o.nix @NixOS/podman @zowoq
|
||||||
|
/nixos/tests/podman.nix @NixOS/podman @zowoq
|
||||||
|
|
||||||
# Blockchains
|
# Blockchains
|
||||||
/pkgs/applications/blockchains @mmahut
|
/pkgs/applications/blockchains @mmahut
|
||||||
|
|
||||||
|
# Go
|
||||||
|
/pkgs/development/compilers/go @kalbasit @Mic92 @zowoq
|
||||||
|
/pkgs/development/go-modules @kalbasit @Mic92 @zowoq
|
||||||
|
/pkgs/development/go-packages @kalbasit @Mic92 @zowoq
|
||||||
|
|
|
@ -9,17 +9,33 @@ exemptLabels:
|
||||||
# Label to use when marking an issue as stale
|
# Label to use when marking an issue as stale
|
||||||
staleLabel: "2.status: stale"
|
staleLabel: "2.status: stale"
|
||||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||||
markComment: |
|
pulls:
|
||||||
Thank you for your contributions.
|
markComment: |
|
||||||
|
Hello, I'm a bot and I thank you in the name of the community for your contributions.
|
||||||
|
|
||||||
This has been automatically marked as stale because it has had no activity for 180 days.
|
Nixpkgs is a busy repository, and unfortunately sometimes PRs get left behind for too long. Nevertheless, we'd like to help committers reach the PRs that are still important. This PR has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.
|
||||||
|
|
||||||
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
|
If this is still important to you and you'd like to remove the stale label, we ask that you leave a comment. Your comment can be as simple as "still important to me". But there's a bit more you can do:
|
||||||
|
|
||||||
Here are suggestions that might help resolve this more quickly:
|
If you received an approval by an unprivileged maintainer and you are just waiting for a merge, you can @ mention someone with merge permissions and ask them to help. You might be able to find someone relevant by using [Git blame](https://git-scm.com/docs/git-blame) on the relevant files, or via [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file). You can see if someone's a member of the [nixpkgs-committers](https://github.com/orgs/NixOS/teams/nixpkgs-committers) team, by hovering with the mouse over their username on the web interface, or by searching them directly on [the list](https://github.com/orgs/NixOS/teams/nixpkgs-committers).
|
||||||
|
|
||||||
|
If your PR wasn't reviewed at all, it might help to find someone who's perhaps a user of the package or module you are changing, or alternatively, ask once more for a review by the maintainer of the package/module this is about. If you don't know any, you can use [Git blame](https://git-scm.com/docs/git-blame) on the relevant files, or [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file) to find someone who touched the relevant files in the past.
|
||||||
|
|
||||||
|
If your PR has had reviews and nevertheless got stale, make sure you've responded to all of the reviewer's requests / questions. Usually when PR authors show responsibility and dedication, reviewers (privileged or not) show dedication as well. If you've pushed a change, it's possible the reviewer wasn't notified about your push via email, so you can always [officially request them for a review](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review), or just @ mention them and say you've addressed their comments.
|
||||||
|
|
||||||
|
Lastly, you can always ask for help at [our Discourse Forum](https://discourse.nixos.org/), or more specifically, [at this thread](https://discourse.nixos.org/t/prs-in-distress/3604) or at [#nixos' IRC channel](https://webchat.freenode.net/#nixos).
|
||||||
|
|
||||||
|
issues:
|
||||||
|
markComment: |
|
||||||
|
Hello, I'm a bot and I thank you in the name of the community for opening this issue.
|
||||||
|
|
||||||
|
To help our human contributors focus on the most-relevant reports, I check up on old issues to see if they're still relevant. This issue has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.
|
||||||
|
|
||||||
|
The community would appreciate your effort in checking if the issue is still valid. If it isn't, please close it.
|
||||||
|
|
||||||
|
If the issue persists, and you'd like to remove the stale label, you simply need to leave a comment. Your comment can be as simple as "still important to me". If you'd like it to get more attention, you can ask for help by searching for maintainers and people that previously touched related code and @ mention them in a comment. You can use [Git blame](https://git-scm.com/docs/git-blame) or [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file) on the relevant files to find them.
|
||||||
|
|
||||||
|
Lastly, you can always ask for help at [our Discourse Forum](https://discourse.nixos.org/) or at [#nixos' IRC channel](https://webchat.freenode.net/#nixos).
|
||||||
|
|
||||||
1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
|
|
||||||
2. Ask on the [NixOS Discourse](https://discourse.nixos.org/).
|
|
||||||
3. Ask on the [#nixos channel](irc://irc.freenode.net/#nixos) on [irc.freenode.net](https://freenode.net).
|
|
||||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||||
closeComment: false
|
closeComment: false
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
name: "Checking EditorConfig"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: technote-space/get-diff-action@v3.1.0
|
||||||
|
- name: Fetch editorconfig-checker
|
||||||
|
if: env.GIT_DIFF
|
||||||
|
env:
|
||||||
|
ECC_VERSION: "2.1.0"
|
||||||
|
ECC_URL: "https://github.com/editorconfig-checker/editorconfig-checker/releases/download"
|
||||||
|
run: |
|
||||||
|
curl -sSf -O -L -C - "$ECC_URL/$ECC_VERSION/ec-linux-amd64.tar.gz" && \
|
||||||
|
tar xzf ec-linux-amd64.tar.gz && \
|
||||||
|
mv ./bin/ec-linux-amd64 ./bin/editorconfig-checker
|
||||||
|
- name: Checking EditorConfig
|
||||||
|
if: env.GIT_DIFF
|
||||||
|
run: |
|
||||||
|
./bin/editorconfig-checker -disable-indentation \
|
||||||
|
${{ env.GIT_DIFF }}
|
|
@ -0,0 +1,21 @@
|
||||||
|
name: "clear pending status"
|
||||||
|
|
||||||
|
on:
|
||||||
|
check_suite:
|
||||||
|
types: [ completed ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
action:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: clear pending status
|
||||||
|
if: github.repository_owner == 'NixOS' && github.event.check_suite.app.name == 'OfBorg'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-d '{"state": "success", "target_url": " ", "description": " ", "context": "Wait for ofborg"}' \
|
||||||
|
"https://api.github.com/repos/NixOS/nixpkgs/statuses/${{ github.event.check_suite.head_sha }}"
|
|
@ -0,0 +1,20 @@
|
||||||
|
name: "set pending status"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
action:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: set pending status
|
||||||
|
if: github.repository_owner == 'NixOS'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-d '{"state": "failure", "target_url": " ", "description": "This failed status will be cleared when ofborg finishes eval.", "context": "Wait for ofborg"}' \
|
||||||
|
"https://api.github.com/repos/NixOS/nixpkgs/statuses/${{ github.event.pull_request.head.sha }}"
|
|
@ -12,6 +12,7 @@ result-*
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
|
__pycache__
|
||||||
|
|
||||||
/pkgs/development/libraries/qt-5/*/tmp/
|
/pkgs/development/libraries/qt-5/*/tmp/
|
||||||
/pkgs/desktops/kde-5/*/tmp/
|
/pkgs/desktops/kde-5/*/tmp/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
MD_TARGETS=$(addsuffix .xml, $(basename $(wildcard ./*.md ./**/*.md)))
|
MD_TARGETS=$(addsuffix .xml, $(basename $(shell find . -type f -regex '.*\.md$$')))
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: validate format out/html/index.html out/epub/manual.epub
|
all: validate format out/html/index.html out/epub/manual.epub
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Cataclysm: Dark Days Ahead
|
||||||
|
|
||||||
|
## How to install Cataclysm DDA
|
||||||
|
|
||||||
|
To install the latest stable release of Cataclysm DDA to your profile, execute
|
||||||
|
`nix-env -f "<nixpkgs>" -iA cataclysm-dda`. For the curses build (build
|
||||||
|
without tiles), install `cataclysmDDA.stable.curses`. Note: `cataclysm-dda` is
|
||||||
|
an alias to `cataclysmDDA.stable.tiles`.
|
||||||
|
|
||||||
|
If you like access to a development build of your favorite git revision,
|
||||||
|
override `cataclysm-dda-git` (or `cataclysmDDA.git.curses` if you like curses
|
||||||
|
build):
|
||||||
|
|
||||||
|
```nix
|
||||||
|
cataclysm-dda-git.override {
|
||||||
|
version = "YYYY-MM-DD";
|
||||||
|
rev = "YOUR_FAVORITE_REVISION";
|
||||||
|
sha256 = "CHECKSUM_OF_THE_REVISION";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The sha256 checksum can be obtained by
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix-prefetch-url --unpack "https://github.com/CleverRaven/Cataclysm-DDA/archive/${YOUR_FAVORITE_REVISION}.tar.gz"
|
||||||
|
```
|
||||||
|
|
||||||
|
The default configuration directory is `~/.cataclysm-dda`. If you prefer
|
||||||
|
`$XDG_CONFIG_HOME/cataclysm-dda`, override the derivation:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
cataclysm-dda.override {
|
||||||
|
useXdgDir = true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customizing with mods
|
||||||
|
|
||||||
|
To install Cataclysm DDA with mods of your choice, you can use `withMods`
|
||||||
|
attribute:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
cataclysm-dda.withMods (mods: with mods; [
|
||||||
|
tileset.UndeadPeople
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
All mods, soundpacks, and tilesets available in nixpkgs are found in
|
||||||
|
`cataclysmDDA.pkgs`.
|
||||||
|
|
||||||
|
Here is an example to modify existing mods and/or add more mods not available
|
||||||
|
in nixpkgs:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
customMods = self: super: lib.recursiveUpdate super {
|
||||||
|
# Modify existing mod
|
||||||
|
tileset.UndeadPeople = super.tileset.UndeadPeople.overrideAttrs (old: {
|
||||||
|
# If you like to apply a patch to the tileset for example
|
||||||
|
patches = [ ./path/to/your.patch ];
|
||||||
|
});
|
||||||
|
|
||||||
|
# Add another mod
|
||||||
|
mod.Awesome = cataclysmDDA.buildMod {
|
||||||
|
modName = "Awesome";
|
||||||
|
version = "0.x";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Someone";
|
||||||
|
repo = "AwesomeMod";
|
||||||
|
rev = "...";
|
||||||
|
sha256 = "...";
|
||||||
|
};
|
||||||
|
# Path to be installed in the unpacked source (default: ".")
|
||||||
|
modRoot = "contents/under/this/path/will/be/installed";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add another soundpack
|
||||||
|
soundpack.Fantastic = cataclysmDDA.buildSoundPack {
|
||||||
|
# ditto
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add another tileset
|
||||||
|
tileset.SuperDuper = cataclysmDDA.buildTileSet {
|
||||||
|
# ditto
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
cataclysm-dda.withMods (mods: with mods.extend customMods; [
|
||||||
|
tileset.UndeadPeople
|
||||||
|
mod.Awesome
|
||||||
|
soundpack.Fantastic
|
||||||
|
tileset.SuperDuper
|
||||||
|
])
|
||||||
|
```
|
|
@ -4,34 +4,36 @@
|
||||||
<title>Citrix Workspace</title>
|
<title>Citrix Workspace</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<note>
|
The <link xlink:href="https://www.citrix.com/products/workspace-app/">Citrix Workspace App</link> is a remote desktop viewer which provides access to <link xlink:href="https://www.citrix.com/products/xenapp-xendesktop/">XenDesktop</link> installations.
|
||||||
<para>
|
|
||||||
Please note that the <literal>citrix_receiver</literal> package has been deprecated since its development was <link xlink:href="https://docs.citrix.com/en-us/citrix-workspace-app.html">discontinued by upstream</link> and has been replaced by <link xlink:href="https://www.citrix.com/products/workspace-app/">the citrix workspace app</link>.
|
|
||||||
</para>
|
|
||||||
</note>
|
|
||||||
<link xlink:href="https://www.citrix.com/products/receiver/">Citrix Receiver</link> and <link xlink:href="https://www.citrix.com/products/workspace-app/">Citrix Workspace App</link> are a remote desktop viewers which provide access to <link xlink:href="https://www.citrix.com/products/xenapp-xendesktop/">XenDesktop</link> installations.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section xml:id="sec-citrix-base">
|
<section xml:id="sec-citrix-base">
|
||||||
<title>Basic usage</title>
|
<title>Basic usage</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The tarball archive needs to be downloaded manually as the license agreements of the vendor for <link xlink:href="https://www.citrix.com/downloads/citrix-receiver/">Citrix Receiver</link> or <link xlink:href="https://www.citrix.de/downloads/workspace-app/linux/workspace-app-for-linux-latest.html">Citrix Workspace</link> need to be accepted first. Then run <command>nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz</command>. With the archive available in the store the package can be built and installed with Nix.
|
The tarball archive needs to be downloaded manually as the license agreements of the vendor for <link xlink:href="https://www.citrix.de/downloads/workspace-app/linux/workspace-app-for-linux-latest.html">Citrix Workspace</link> needs to be accepted first. Then run <command>nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz</command>. With the archive available in the store the package can be built and installed with Nix.
|
||||||
</para>
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
<warning>
|
<section xml:id="sec-citrix-selfservice">
|
||||||
<title>Caution with <command>nix-shell</command> installs</title>
|
<title>Citrix Selfservice</title>
|
||||||
<para>
|
<para>
|
||||||
It's recommended to install <literal>Citrix Receiver</literal> and/or <literal>Citrix Workspace</literal> using <literal>nix-env -i</literal> or globally to ensure that the <literal>.desktop</literal> files are installed properly into <literal>$XDG_CONFIG_DIRS</literal>. Otherwise it won't be possible to open <literal>.ica</literal> files automatically from the browser to start a Citrix connection.
|
The <link xlink:href="https://support.citrix.com/article/CTX200337">selfservice</link> is an application managing Citrix desktops and applications. Please note that this feature only works with at least <package>citrix_workspace_20_06_0</package> and later versions.
|
||||||
</para>
|
</para>
|
||||||
</warning>
|
<para>
|
||||||
|
In order to set this up, you first have to <link xlink:href="https://its.uiowa.edu/support/article/102186">download the <literal>.cr</literal> file from the Netscaler Gateway</link>. After that you can configure the <command>selfservice</command> like this:
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>storebrowse -C ~/Downloads/receiverconfig.cr
|
||||||
|
<prompt>$ </prompt>selfservice
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="sec-citrix-custom-certs">
|
<section xml:id="sec-citrix-custom-certs">
|
||||||
<title>Custom certificates</title>
|
<title>Custom certificates</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <literal>Citrix Workspace App</literal> in <literal>nixpkgs</literal> trust several certificates <link xlink:href="https://curl.haxx.se/docs/caextract.html">from the Mozilla database</link> by default. However several companies using Citrix might require their own corporate certificate. On distros with imperative packaging these certs can be stored easily in <link xlink:href="https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/"><literal>$ICAROOT</literal></link>, however this directory is a store path in <literal>nixpkgs</literal>. In order to work around this issue the package provides a simple mechanism to add custom certificates without rebuilding the entire package using <literal>symlinkJoin</literal>:
|
The <literal>Citrix Workspace App</literal> in <literal>nixpkgs</literal> trusts several certificates <link xlink:href="https://curl.haxx.se/docs/caextract.html">from the Mozilla database</link> by default. However several companies using Citrix might require their own corporate certificate. On distros with imperative packaging these certs can be stored easily in <link xlink:href="https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/"><literal>$ICAROOT</literal></link>, however this directory is a store path in <literal>nixpkgs</literal>. In order to work around this issue the package provides a simple mechanism to add custom certificates without rebuilding the entire package using <literal>symlinkJoin</literal>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[with import <nixpkgs> { config.allowUnfree = true; };
|
<![CDATA[with import <nixpkgs> { config.allowUnfree = true; };
|
||||||
let extraCerts = [ ./custom-cert-1.pem ./custom-cert-2.pem /* ... */ ]; in
|
let extraCerts = [ ./custom-cert-1.pem ./custom-cert-2.pem /* ... */ ]; in
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<xi:include href="opengl.xml" />
|
<xi:include href="opengl.xml" />
|
||||||
<xi:include href="shell-helpers.xml" />
|
<xi:include href="shell-helpers.xml" />
|
||||||
<xi:include href="steam.xml" />
|
<xi:include href="steam.xml" />
|
||||||
|
<xi:include href="cataclysm-dda.section.xml" />
|
||||||
<xi:include href="urxvt.xml" />
|
<xi:include href="urxvt.xml" />
|
||||||
<xi:include href="weechat.xml" />
|
<xi:include href="weechat.xml" />
|
||||||
<xi:include href="xorg.xml" />
|
<xi:include href="xorg.xml" />
|
||||||
|
|
|
@ -45,13 +45,7 @@
|
||||||
<title>How to play</title>
|
<title>How to play</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
For 64-bit systems it's important to have
|
Use <programlisting>programs.steam.enable = true;</programlisting> if you want to add steam to systemPackages and also enable a few workarrounds aswell as Steam controller support or other Steam supported controllers such as the DualShock 4 or Nintendo Switch Pr.
|
||||||
<programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
|
|
||||||
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
|
|
||||||
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
|
|
||||||
if you are using PulseAudio - this will enable 32bit ALSA apps integration. To use the Steam controller or other Steam supported controllers such as the DualShock 4 or Nintendo Switch Pro, you need to add
|
|
||||||
<programlisting>hardware.steam-hardware.enable = true;</programlisting>
|
|
||||||
to your configuration.
|
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ map (p: p.name) pkgs.rxvt-unicode.plugins
|
||||||
In addition to <literal>plugins</literal> the options
|
In addition to <literal>plugins</literal> the options
|
||||||
<literal>extraDeps</literal> and <literal>perlDeps</literal> can be used
|
<literal>extraDeps</literal> and <literal>perlDeps</literal> can be used
|
||||||
to install extra packages.
|
to install extra packages.
|
||||||
<literal>extraDeps</literal> can be used, for example, to provide
|
<literal>extraDeps</literal> can be used, for example, to provide
|
||||||
<literal>xsel</literal> (a clipboard manager) to the clipboard plugin,
|
<literal>xsel</literal> (a clipboard manager) to the clipboard plugin,
|
||||||
without installing it globally:
|
without installing it globally:
|
||||||
<programlisting>rxvt-unicode.override { configure = { availablePlugins, ... }: {
|
<programlisting>rxvt-unicode.override { configure = { availablePlugins, ... }: {
|
||||||
|
|
|
@ -191,6 +191,8 @@ androidenv.emulateApp {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Additional flags may be applied to the Android SDK's emulator through the runtime environment variable `$NIX_ANDROID_EMULATOR_FLAGS`.
|
||||||
|
|
||||||
It is also possible to specify an APK to deploy inside the emulator
|
It is also possible to specify an APK to deploy inside the emulator
|
||||||
and the package and activity names to launch it:
|
and the package and activity names to launch it:
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
<title>How to Install BEAM Packages</title>
|
<title>How to Install BEAM Packages</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
BEAM builders are not registered at the top level, simply because they are not relevant to the vast majority of Nix users.
|
BEAM builders are not registered at the top level, simply because they are not relevant to the vast majority of Nix users.
|
||||||
To install any of those builders into your profile, refer to them by their attribute path <literal>beamPackages.rebar3</literal>:
|
To install any of those builders into your profile, refer to them by their attribute path <literal>beamPackages.rebar3</literal>:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,11 @@ Modes of use of `emscripten`:
|
||||||
* **Declarative usage**:
|
* **Declarative usage**:
|
||||||
|
|
||||||
This mode is far more power full since this makes use of `nix` for dependency management of emscripten libraries and targets by using the `mkDerivation` which is implemented by `pkgs.emscriptenStdenv` and `pkgs.buildEmscriptenPackage`. The source for the packages is in `pkgs/top-level/emscripten-packages.nix` and the abstraction behind it in `pkgs/development/em-modules/generic/default.nix`.
|
This mode is far more power full since this makes use of `nix` for dependency management of emscripten libraries and targets by using the `mkDerivation` which is implemented by `pkgs.emscriptenStdenv` and `pkgs.buildEmscriptenPackage`. The source for the packages is in `pkgs/top-level/emscripten-packages.nix` and the abstraction behind it in `pkgs/development/em-modules/generic/default.nix`.
|
||||||
* build and install all packages:
|
* build and install all packages:
|
||||||
* `nix-env -iA emscriptenPackages`
|
* `nix-env -iA emscriptenPackages`
|
||||||
|
|
||||||
* dev-shell for zlib implementation hacking:
|
* dev-shell for zlib implementation hacking:
|
||||||
* `nix-shell -A emscriptenPackages.zlib`
|
* `nix-shell -A emscriptenPackages.zlib`
|
||||||
|
|
||||||
|
|
||||||
## Imperative usage
|
## Imperative usage
|
||||||
|
@ -90,7 +90,7 @@ See the `zlib` example:
|
||||||
libz.so.${old.version} -I . -o example.js
|
libz.so.${old.version} -I . -o example.js
|
||||||
|
|
||||||
echo "Using node to execute the test"
|
echo "Using node to execute the test"
|
||||||
${pkgs.nodejs}/bin/node ./example.js
|
${pkgs.nodejs}/bin/node ./example.js
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
|
@ -112,7 +112,7 @@ See the `zlib` example:
|
||||||
|
|
||||||
### Usage 2: pkgs.buildEmscriptenPackage
|
### Usage 2: pkgs.buildEmscriptenPackage
|
||||||
|
|
||||||
This `xmlmirror` example features a emscriptenPackage which is defined completely from this context and no `pkgs.zlib.override` is used.
|
This `xmlmirror` example features a emscriptenPackage which is defined completely from this context and no `pkgs.zlib.override` is used.
|
||||||
|
|
||||||
xmlmirror = pkgs.buildEmscriptenPackage rec {
|
xmlmirror = pkgs.buildEmscriptenPackage rec {
|
||||||
name = "xmlmirror";
|
name = "xmlmirror";
|
||||||
|
@ -163,7 +163,7 @@ This `xmlmirror` example features a emscriptenPackage which is defined completel
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
### Declarative debugging
|
### Declarative debugging
|
||||||
|
|
||||||
|
@ -182,4 +182,3 @@ Use `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz` and from
|
||||||
Using this toolchain makes it easy to leverage `nix` from NixOS, MacOSX or even Windows (WSL+ubuntu+nix). This toolchain is reproducible, behaves like the rest of the packages from nixpkgs and contains a set of well working examples to learn and adapt from.
|
Using this toolchain makes it easy to leverage `nix` from NixOS, MacOSX or even Windows (WSL+ubuntu+nix). This toolchain is reproducible, behaves like the rest of the packages from nixpkgs and contains a set of well working examples to learn and adapt from.
|
||||||
|
|
||||||
If in trouble, ask the maintainers.
|
If in trouble, ask the maintainers.
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,10 @@ pet = buildGoModule rec {
|
||||||
|
|
||||||
subPackages = [ "." ]; <co xml:id='ex-buildGoModule-2' />
|
subPackages = [ "." ]; <co xml:id='ex-buildGoModule-2' />
|
||||||
|
|
||||||
|
deleteVendor = true; <co xml:id='ex-buildGoModule-3' />
|
||||||
|
|
||||||
|
runVend = true; <co xml:id='ex-buildGoModule-4' />
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
description = "Simple command-line snippet manager, written in Go";
|
description = "Simple command-line snippet manager, written in Go";
|
||||||
homepage = "https://github.com/knqyf263/pet";
|
homepage = "https://github.com/knqyf263/pet";
|
||||||
|
@ -64,6 +68,16 @@ pet = buildGoModule rec {
|
||||||
<varname>subPackages</varname> limits the builder from building child packages that have not been listed. If <varname>subPackages</varname> is not specified, all child packages will be built.
|
<varname>subPackages</varname> limits the builder from building child packages that have not been listed. If <varname>subPackages</varname> is not specified, all child packages will be built.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
<callout arearefs='ex-buildGoModule-3'>
|
||||||
|
<para>
|
||||||
|
<varname>deleteVendor</varname> removes the pre-existing vendor directory and fetches the dependencies. This should only be used if the dependencies included in the vendor folder are broken or incomplete.
|
||||||
|
</para>
|
||||||
|
</callout>
|
||||||
|
<callout arearefs='ex-buildGoModule-4'>
|
||||||
|
<para>
|
||||||
|
<varname>runVend</varname> runs the vend command to generate the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build.
|
||||||
|
</para>
|
||||||
|
</callout>
|
||||||
</calloutlist>
|
</calloutlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -72,7 +86,7 @@ pet = buildGoModule rec {
|
||||||
|
|
||||||
When `null` is used as a value, rather than fetching the dependencies
|
When `null` is used as a value, rather than fetching the dependencies
|
||||||
and vendoring them, we use the vendoring included within the source repo.
|
and vendoring them, we use the vendoring included within the source repo.
|
||||||
If you'd like to not have to update this field on dependency changes,
|
If you'd like to not have to update this field on dependency changes,
|
||||||
run `go mod vendor` in your source repo and set 'vendorSha256 = null;'
|
run `go mod vendor` in your source repo and set 'vendorSha256 = null;'
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -25,12 +25,13 @@ build system it uses. Here are some examples:
|
||||||
|
|
||||||
After you have identified the correct system, you need to override your package
|
After you have identified the correct system, you need to override your package
|
||||||
expression while adding in build system as a build input. For example, `dat`
|
expression while adding in build system as a build input. For example, `dat`
|
||||||
requires `node-gyp-build`, so we override its expression in `default.nix`:
|
requires `node-gyp-build`, so [we override](https://github.com/NixOS/nixpkgs/blob/32f5e5da4a1b3f0595527f5195ac3a91451e9b56/pkgs/development/node-packages/default.nix#L37-L40) its expression in [`default.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/node-packages/default.nix):
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
dat = nodePackages.dat.override (oldAttrs: {
|
dat = super.dat.override {
|
||||||
buildInputs = oldAttrs.buildInputs ++ [ nodePackages.node-gyp-build ];
|
buildInputs = [ self.node-gyp-build pkgs.libtool pkgs.autoconf pkgs.automake ];
|
||||||
});
|
meta.broken = since "12";
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
To add a package from NPM to nixpkgs:
|
To add a package from NPM to nixpkgs:
|
||||||
|
|
|
@ -3,159 +3,193 @@
|
||||||
xml:id="sec-language-perl">
|
xml:id="sec-language-perl">
|
||||||
<title>Perl</title>
|
<title>Perl</title>
|
||||||
|
|
||||||
<para>
|
<section xml:id="ssec-perl-running">
|
||||||
Nixpkgs provides a function <varname>buildPerlPackage</varname>, a generic package builder function for any Perl package that has a standard <varname>Makefile.PL</varname>. It’s implemented in <link
|
<title>Running perl programs on the shell</title>
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic"><filename>pkgs/development/perl-modules/generic</filename></link>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Perl packages from CPAN are defined in <link
|
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/top-level/perl-packages.nix</filename></link>, rather than <filename>pkgs/all-packages.nix</filename>. Most Perl packages are so straight-forward to build that they are defined here directly, rather than having a separate function for each package called from <filename>perl-packages.nix</filename>. However, more complicated packages should be put in a separate file, typically in <filename>pkgs/development/perl-modules</filename>. Here is an example of the former:
|
|
||||||
<programlisting>
|
|
||||||
ClassC3 = buildPerlPackage rec {
|
|
||||||
name = "Class-C3-0.21";
|
|
||||||
src = fetchurl {
|
|
||||||
url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
|
|
||||||
sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
Note the use of <literal>mirror://cpan/</literal>, and the <literal>${name}</literal> in the URL definition to ensure that the name attribute is consistent with the source that we’re actually downloading. Perl packages are made available in <filename>all-packages.nix</filename> through the variable <varname>perlPackages</varname>. For instance, if you have a package that needs <varname>ClassC3</varname>, you would typically write
|
|
||||||
<programlisting>
|
|
||||||
foo = import ../path/to/foo.nix {
|
|
||||||
inherit stdenv fetchurl ...;
|
|
||||||
inherit (perlPackages) ClassC3;
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
in <filename>all-packages.nix</filename>. You can test building a Perl package as follows:
|
|
||||||
<screen>
|
|
||||||
<prompt>$ </prompt>nix-build -A perlPackages.ClassC3
|
|
||||||
</screen>
|
|
||||||
<varname>buildPerlPackage</varname> adds <literal>perl-</literal> to the start of the name attribute, so the package above is actually called <literal>perl-Class-C3-0.21</literal>. So to install it, you can say:
|
|
||||||
<screen>
|
|
||||||
<prompt>$ </prompt>nix-env -i perl-Class-C3
|
|
||||||
</screen>
|
|
||||||
(Of course you can also install using the attribute name: <literal>nix-env -i -A perlPackages.ClassC3</literal>.)
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
So what does <varname>buildPerlPackage</varname> do? It does the following:
|
|
||||||
<orderedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
In the configure phase, it calls <literal>perl Makefile.PL</literal> to generate a Makefile. You can set the variable <varname>makeMakerFlags</varname> to pass flags to <filename>Makefile.PL</filename>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
It adds the contents of the <envar>PERL5LIB</envar> environment variable to <literal>#! .../bin/perl</literal> line of Perl scripts as <literal>-I<replaceable>dir</replaceable></literal> flags. This ensures that a script can find its dependencies. (This can cause this shebang line to become too long for Darwin to handle; see the note below.)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
In the fixup phase, it writes the propagated build inputs (<varname>propagatedBuildInputs</varname>) to the file <filename>$out/nix-support/propagated-user-env-packages</filename>. <command>nix-env</command> recursively installs all packages listed in this file when you install a package that has it. This ensures that a Perl package can find its dependencies.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<varname>buildPerlPackage</varname> is built on top of <varname>stdenv</varname>, so everything can be customised in the usual way. For instance, the <literal>BerkeleyDB</literal> module has a <varname>preConfigure</varname> hook to generate a configuration file used by <filename>Makefile.PL</filename>:
|
|
||||||
<programlisting>
|
|
||||||
{ buildPerlPackage, fetchurl, db }:
|
|
||||||
|
|
||||||
buildPerlPackage rec {
|
|
||||||
name = "BerkeleyDB-0.36";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
|
|
||||||
sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
|
|
||||||
};
|
|
||||||
|
|
||||||
preConfigure = ''
|
|
||||||
echo "LIB = ${db.out}/lib" > config.in
|
|
||||||
echo "INCLUDE = ${db.dev}/include" >> config.in
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Dependencies on other Perl packages can be specified in the <varname>buildInputs</varname> and <varname>propagatedBuildInputs</varname> attributes. If something is exclusively a build-time dependency, use <varname>buildInputs</varname>; if it’s (also) a runtime dependency, use <varname>propagatedBuildInputs</varname>. For instance, this builds a Perl module that has runtime dependencies on a bunch of other modules:
|
|
||||||
<programlisting>
|
|
||||||
ClassC3Componentised = buildPerlPackage rec {
|
|
||||||
name = "Class-C3-Componentised-1.0004";
|
|
||||||
src = fetchurl {
|
|
||||||
url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
|
|
||||||
sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
|
|
||||||
};
|
|
||||||
propagatedBuildInputs = [
|
|
||||||
ClassC3 ClassInspector TestException MROCompat
|
|
||||||
];
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
On Darwin, if a script has too many <literal>-I<replaceable>dir</replaceable></literal> flags in its first line (its “shebang line”), it will not run. This can be worked around by calling the <literal>shortenPerlShebang</literal> function from the <literal>postInstall</literal> phase:
|
|
||||||
<programlisting>
|
|
||||||
{ stdenv, buildPerlPackage, fetchurl, shortenPerlShebang }:
|
|
||||||
|
|
||||||
ImageExifTool = buildPerlPackage {
|
|
||||||
pname = "Image-ExifTool";
|
|
||||||
version = "11.50";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz";
|
|
||||||
sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3";
|
|
||||||
};
|
|
||||||
|
|
||||||
buildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang;
|
|
||||||
postInstall = stdenv.lib.optional stdenv.isDarwin ''
|
|
||||||
shortenPerlShebang $out/bin/exiftool
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
This will remove the <literal>-I</literal> flags from the shebang line, rewrite them in the <literal>use lib</literal> form, and put them on the next line instead. This function can be given any number of Perl scripts as arguments; it will modify them in-place.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<section xml:id="ssec-generation-from-CPAN">
|
|
||||||
<title>Generation from CPAN</title>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Nix expressions for Perl packages can be generated (almost) automatically from CPAN. This is done by the program <command>nix-generate-from-cpan</command>, which can be installed as follows:
|
When executing a Perl script, it is possible you get an error such as <literal>./myscript.pl: bad interpreter: /usr/bin/perl: no such file or directory</literal>. This happens when the script expects Perl to be installed at <filename>/usr/bin/perl</filename>, which is not the case when using Perl from nixpkgs. You can fix the script by changing the first line to:
|
||||||
|
<programlisting>
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
</programlisting>
|
||||||
|
to take the Perl installation from the <literal>PATH</literal> environment variable, or invoke Perl directly with:
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>perl ./myscript.pl
|
||||||
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<screen>
|
<para>
|
||||||
<prompt>$ </prompt>nix-env -i nix-generate-from-cpan
|
When the script is using a Perl library that is not installed globally, you might get an error such as <literal>Can't locate DB_File.pm in @INC (you may need to install the DB_File module)</literal>. In that case, you can use <command>nix-shell</command> to start an ad-hoc shell with that library installed, for instance:
|
||||||
</screen>
|
<screen>
|
||||||
|
<prompt>$ </prompt>nix-shell -p perl perlPackages.DBFile --run ./myscript.pl
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This program takes a Perl module name, looks it up on CPAN, fetches and unpacks the corresponding package, and prints a Nix expression on standard output. For example:
|
If you are always using the script in places where <command>nix-shell</command> is available, you can embed the <command>nix-shell</command> invocation in the shebang like this:
|
||||||
<screen>
|
<programlisting>
|
||||||
<prompt>$ </prompt>nix-generate-from-cpan XML::Simple
|
#!/usr/bin/env nix-shell
|
||||||
XMLSimple = buildPerlPackage rec {
|
#! nix-shell -i perl -p perl perlPackages.DBFile
|
||||||
name = "XML-Simple-2.22";
|
</programlisting>
|
||||||
src = fetchurl {
|
|
||||||
url = "mirror://cpan/authors/id/G/GR/GRANTM/${name}.tar.gz";
|
|
||||||
sha256 = "b9450ef22ea9644ae5d6ada086dc4300fa105be050a2030ebd4efd28c198eb49";
|
|
||||||
};
|
|
||||||
propagatedBuildInputs = [ XMLNamespaceSupport XMLSAX XMLSAXExpat ];
|
|
||||||
meta = {
|
|
||||||
description = "An API for simple XML files";
|
|
||||||
license = with stdenv.lib.licenses; [ artistic1 gpl1Plus ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
</screen>
|
|
||||||
The output can be pasted into <filename>pkgs/top-level/perl-packages.nix</filename> or wherever else you need it.
|
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="ssec-perl-cross-compilation">
|
<section xml:id="ssec-perl-packaging">
|
||||||
<title>Cross-compiling modules</title>
|
<title>Packaging Perl programs</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Nixpkgs has experimental support for cross-compiling Perl modules. In many cases, it will just work out of the box, even for modules with native extensions. Sometimes, however, the Makefile.PL for a module may (indirectly) import a native module. In that case, you will need to make a stub for that module that will satisfy the Makefile.PL and install it into <filename>lib/perl5/site_perl/cross_perl/${perl.version}</filename>. See the <varname>postInstall</varname> for <varname>DBI</varname> for an example.
|
Nixpkgs provides a function <varname>buildPerlPackage</varname>, a generic package builder function for any Perl package that has a standard <varname>Makefile.PL</varname>. It’s implemented in <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic"><filename>pkgs/development/perl-modules/generic</filename></link>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Perl packages from CPAN are defined in <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/top-level/perl-packages.nix</filename></link>, rather than <filename>pkgs/all-packages.nix</filename>. Most Perl packages are so straight-forward to build that they are defined here directly, rather than having a separate function for each package called from <filename>perl-packages.nix</filename>. However, more complicated packages should be put in a separate file, typically in <filename>pkgs/development/perl-modules</filename>. Here is an example of the former:
|
||||||
|
<programlisting>
|
||||||
|
ClassC3 = buildPerlPackage rec {
|
||||||
|
name = "Class-C3-0.21";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
|
||||||
|
sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
Note the use of <literal>mirror://cpan/</literal>, and the <literal>${name}</literal> in the URL definition to ensure that the name attribute is consistent with the source that we’re actually downloading. Perl packages are made available in <filename>all-packages.nix</filename> through the variable <varname>perlPackages</varname>. For instance, if you have a package that needs <varname>ClassC3</varname>, you would typically write
|
||||||
|
<programlisting>
|
||||||
|
foo = import ../path/to/foo.nix {
|
||||||
|
inherit stdenv fetchurl ...;
|
||||||
|
inherit (perlPackages) ClassC3;
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
in <filename>all-packages.nix</filename>. You can test building a Perl package as follows:
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>nix-build -A perlPackages.ClassC3
|
||||||
|
</screen>
|
||||||
|
<varname>buildPerlPackage</varname> adds <literal>perl-</literal> to the start of the name attribute, so the package above is actually called <literal>perl-Class-C3-0.21</literal>. So to install it, you can say:
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>nix-env -i perl-Class-C3
|
||||||
|
</screen>
|
||||||
|
(Of course you can also install using the attribute name: <literal>nix-env -i -A perlPackages.ClassC3</literal>.)
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
So what does <varname>buildPerlPackage</varname> do? It does the following:
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
In the configure phase, it calls <literal>perl Makefile.PL</literal> to generate a Makefile. You can set the variable <varname>makeMakerFlags</varname> to pass flags to <filename>Makefile.PL</filename>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
It adds the contents of the <envar>PERL5LIB</envar> environment variable to <literal>#! .../bin/perl</literal> line of Perl scripts as <literal>-I<replaceable>dir</replaceable></literal> flags. This ensures that a script can find its dependencies. (This can cause this shebang line to become too long for Darwin to handle; see the note below.)
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
In the fixup phase, it writes the propagated build inputs (<varname>propagatedBuildInputs</varname>) to the file <filename>$out/nix-support/propagated-user-env-packages</filename>. <command>nix-env</command> recursively installs all packages listed in this file when you install a package that has it. This ensures that a Perl package can find its dependencies.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<varname>buildPerlPackage</varname> is built on top of <varname>stdenv</varname>, so everything can be customised in the usual way. For instance, the <literal>BerkeleyDB</literal> module has a <varname>preConfigure</varname> hook to generate a configuration file used by <filename>Makefile.PL</filename>:
|
||||||
|
<programlisting>
|
||||||
|
{ buildPerlPackage, fetchurl, db }:
|
||||||
|
|
||||||
|
buildPerlPackage rec {
|
||||||
|
name = "BerkeleyDB-0.36";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
|
||||||
|
sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
|
||||||
|
};
|
||||||
|
|
||||||
|
preConfigure = ''
|
||||||
|
echo "LIB = ${db.out}/lib" > config.in
|
||||||
|
echo "INCLUDE = ${db.dev}/include" >> config.in
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Dependencies on other Perl packages can be specified in the <varname>buildInputs</varname> and <varname>propagatedBuildInputs</varname> attributes. If something is exclusively a build-time dependency, use <varname>buildInputs</varname>; if it’s (also) a runtime dependency, use <varname>propagatedBuildInputs</varname>. For instance, this builds a Perl module that has runtime dependencies on a bunch of other modules:
|
||||||
|
<programlisting>
|
||||||
|
ClassC3Componentised = buildPerlPackage rec {
|
||||||
|
name = "Class-C3-Componentised-1.0004";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
|
||||||
|
sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
|
||||||
|
};
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
ClassC3 ClassInspector TestException MROCompat
|
||||||
|
];
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
On Darwin, if a script has too many <literal>-I<replaceable>dir</replaceable></literal> flags in its first line (its “shebang line”), it will not run. This can be worked around by calling the <literal>shortenPerlShebang</literal> function from the <literal>postInstall</literal> phase:
|
||||||
|
<programlisting>
|
||||||
|
{ stdenv, buildPerlPackage, fetchurl, shortenPerlShebang }:
|
||||||
|
|
||||||
|
ImageExifTool = buildPerlPackage {
|
||||||
|
pname = "Image-ExifTool";
|
||||||
|
version = "11.50";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz";
|
||||||
|
sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang;
|
||||||
|
postInstall = stdenv.lib.optional stdenv.isDarwin ''
|
||||||
|
shortenPerlShebang $out/bin/exiftool
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
This will remove the <literal>-I</literal> flags from the shebang line, rewrite them in the <literal>use lib</literal> form, and put them on the next line instead. This function can be given any number of Perl scripts as arguments; it will modify them in-place.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="ssec-generation-from-CPAN">
|
||||||
|
<title>Generation from CPAN</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Nix expressions for Perl packages can be generated (almost) automatically from CPAN. This is done by the program <command>nix-generate-from-cpan</command>, which can be installed as follows:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>nix-env -i nix-generate-from-cpan
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This program takes a Perl module name, looks it up on CPAN, fetches and unpacks the corresponding package, and prints a Nix expression on standard output. For example:
|
||||||
|
<screen>
|
||||||
|
<prompt>$ </prompt>nix-generate-from-cpan XML::Simple
|
||||||
|
XMLSimple = buildPerlPackage rec {
|
||||||
|
name = "XML-Simple-2.22";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "mirror://cpan/authors/id/G/GR/GRANTM/${name}.tar.gz";
|
||||||
|
sha256 = "b9450ef22ea9644ae5d6ada086dc4300fa105be050a2030ebd4efd28c198eb49";
|
||||||
|
};
|
||||||
|
propagatedBuildInputs = [ XMLNamespaceSupport XMLSAX XMLSAXExpat ];
|
||||||
|
meta = {
|
||||||
|
description = "An API for simple XML files";
|
||||||
|
license = with stdenv.lib.licenses; [ artistic1 gpl1Plus ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</screen>
|
||||||
|
The output can be pasted into <filename>pkgs/top-level/perl-packages.nix</filename> or wherever else you need it.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="ssec-perl-cross-compilation">
|
||||||
|
<title>Cross-compiling modules</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Nixpkgs has experimental support for cross-compiling Perl modules. In many cases, it will just work out of the box, even for modules with native extensions. Sometimes, however, the Makefile.PL for a module may (indirectly) import a native module. In that case, you will need to make a stub for that module that will satisfy the Makefile.PL and install it into <filename>lib/perl5/site_perl/cross_perl/${perl.version}</filename>. See the <varname>postInstall</varname> for <varname>DBI</varname> for an example.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -538,8 +538,123 @@ buildPythonPackage rec {
|
||||||
```
|
```
|
||||||
Note also the line `doCheck = false;`, we explicitly disabled running the test-suite.
|
Note also the line `doCheck = false;`, we explicitly disabled running the test-suite.
|
||||||
|
|
||||||
|
#### Testing Python Packages
|
||||||
|
|
||||||
#### Develop local package
|
It is highly encouraged to have testing as part of the package build. This
|
||||||
|
helps to avoid situations where the package was able to build and install,
|
||||||
|
but is not usable at runtime. Currently, all packages will use the `test`
|
||||||
|
command provided by the setup.py (i.e. `python setup.py test`). However,
|
||||||
|
this is currently deprecated https://github.com/pypa/setuptools/pull/1878
|
||||||
|
and your package should provide its own checkPhase.
|
||||||
|
|
||||||
|
*NOTE:* The `checkPhase` for python maps to the `installCheckPhase` on a
|
||||||
|
normal derivation. This is due to many python packages not behaving well
|
||||||
|
to the pre-installed version of the package. Version info, and natively
|
||||||
|
compiled extensions generally only exist in the install directory, and
|
||||||
|
thus can cause issues when a test suite asserts on that behavior.
|
||||||
|
|
||||||
|
*NOTE:* Tests should only be disabled if they don't agree with nix
|
||||||
|
(e.g. external dependencies, network access, flakey tests), however,
|
||||||
|
as many tests should be enabled as possible. Failing tests can still be
|
||||||
|
a good indication that the package is not in a valid state.
|
||||||
|
|
||||||
|
#### Using pytest
|
||||||
|
|
||||||
|
Pytest is the most common test runner for python repositories. A trivial
|
||||||
|
test run would be:
|
||||||
|
```
|
||||||
|
checkInputs = [ pytest ];
|
||||||
|
checkPhase = "pytest";
|
||||||
|
```
|
||||||
|
|
||||||
|
However, many repositories' test suites do not translate well to nix's build
|
||||||
|
sandbox, and will generally need many tests to be disabled.
|
||||||
|
|
||||||
|
To filter tests using pytest, one can do the following:
|
||||||
|
```
|
||||||
|
checkInputs = [ pytest ];
|
||||||
|
# avoid tests which need additional data or touch network
|
||||||
|
checkPhase = ''
|
||||||
|
pytest tests/ --ignore=tests/integration -k 'not download and not update'
|
||||||
|
'';
|
||||||
|
```
|
||||||
|
|
||||||
|
`--ignore` will tell pytest to ignore that file or directory from being
|
||||||
|
collected as part of a test run. This is useful is a file uses a package
|
||||||
|
which is not available in nixpkgs, thus skipping that test file is much
|
||||||
|
easier than having to create a new package.
|
||||||
|
|
||||||
|
`-k` is used to define a predicate for test names. In this example, we are
|
||||||
|
filtering out tests which contain `download` or `update` in their test case name.
|
||||||
|
Only one `-k` argument is allows, and thus a long predicate should be concatenated
|
||||||
|
with "\" and wrapped to the next line.
|
||||||
|
|
||||||
|
*NOTE:* In pytest==6.0.1, the use of "\" to continue a line (e.g. `-k 'not download \'`) has
|
||||||
|
been removed, in this case, it's recommended to use `pytestCheckHook`.
|
||||||
|
|
||||||
|
#### Using pytestCheckHook
|
||||||
|
|
||||||
|
`pytestCheckHook` is a convenient hook which will substitute the setuptools
|
||||||
|
`test` command for a checkPhase which runs `pytest`. This is also beneficial
|
||||||
|
when a package may need many items disabled to run the test suite.
|
||||||
|
|
||||||
|
Using the example above, the analagous pytestCheckHook usage would be:
|
||||||
|
```
|
||||||
|
checkInputs = [ pytestCheckHook ];
|
||||||
|
|
||||||
|
# requires additional data
|
||||||
|
pytestFlagsArray = [ "tests/" "--ignore=tests/integration" ];
|
||||||
|
|
||||||
|
disabledTests = [
|
||||||
|
# touches network
|
||||||
|
"download"
|
||||||
|
"update"
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
This is expecially useful when tests need to be conditionallydisabled,
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```
|
||||||
|
disabledTests = [
|
||||||
|
# touches network
|
||||||
|
"download"
|
||||||
|
"update"
|
||||||
|
] ++ lib.optionals (pythonAtLeast "3.8") [
|
||||||
|
# broken due to python3.8 async changes
|
||||||
|
"async"
|
||||||
|
] ++ lib.optionals stdenv.isDarwin [
|
||||||
|
# can fail when building with other packages
|
||||||
|
"socket"
|
||||||
|
];
|
||||||
|
```
|
||||||
|
Trying to concatenate the related strings to disable tests in a regular checkPhase
|
||||||
|
would be much harder to read. This also enables us to comment on why specific tests
|
||||||
|
are disabled.
|
||||||
|
|
||||||
|
#### Using pythonImportsCheck
|
||||||
|
|
||||||
|
Although unit tests are highly prefered to valid correctness of a package. Not
|
||||||
|
all packages have test suites that can be ran easily, and some have none at all.
|
||||||
|
To help ensure the package still works, `pythonImportsCheck` can attempt to import
|
||||||
|
the listed modules.
|
||||||
|
|
||||||
|
```
|
||||||
|
pythonImportsCheck = [ "requests" "urllib" ];
|
||||||
|
```
|
||||||
|
roughly translates to:
|
||||||
|
```
|
||||||
|
postCheck = ''
|
||||||
|
PYTHONPATH=$out/${python.sitePackages}:$PYTHONPATH
|
||||||
|
python -c "import requests; import urllib"
|
||||||
|
'';
|
||||||
|
```
|
||||||
|
However, this is done in it's own phase, and not dependent on whether `doCheck = true;`
|
||||||
|
|
||||||
|
This can also be useful in verifying that the package doesn't assume commonly
|
||||||
|
present packages (e.g. `setuptools`)
|
||||||
|
|
||||||
|
### Develop local package
|
||||||
|
|
||||||
As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
|
As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
|
||||||
(`python setup.py develop`); instead of installing the package this command
|
(`python setup.py develop`); instead of installing the package this command
|
||||||
|
@ -640,8 +755,8 @@ and in this case the `python38` interpreter is automatically used.
|
||||||
|
|
||||||
### Interpreters
|
### Interpreters
|
||||||
|
|
||||||
Versions 2.7, 3.5, 3.6, 3.7 and 3.8 of the CPython interpreter are available as
|
Versions 2.7, 3.6, 3.7 and 3.8 of the CPython interpreter are available as
|
||||||
respectively `python27`, `python35`, `python36`, `python37` and `python38`. The
|
respectively `python27`, `python36`, `python37` and `python38`. The
|
||||||
aliases `python2` and `python3` correspond to respectively `python27` and
|
aliases `python2` and `python3` correspond to respectively `python27` and
|
||||||
`python38`. The default interpreter, `python`, maps to `python2`. The PyPy
|
`python38`. The default interpreter, `python`, maps to `python2`. The PyPy
|
||||||
interpreters compatible with Python 2.7 and 3 are available as `pypy27` and
|
interpreters compatible with Python 2.7 and 3 are available as `pypy27` and
|
||||||
|
@ -689,15 +804,16 @@ attribute set is created for each available Python interpreter. The available
|
||||||
sets are
|
sets are
|
||||||
|
|
||||||
* `pkgs.python27Packages`
|
* `pkgs.python27Packages`
|
||||||
* `pkgs.python35Packages`
|
|
||||||
* `pkgs.python36Packages`
|
* `pkgs.python36Packages`
|
||||||
* `pkgs.python37Packages`
|
* `pkgs.python37Packages`
|
||||||
|
* `pkgs.python38Packages`
|
||||||
|
* `pkgs.python39Packages`
|
||||||
* `pkgs.pypyPackages`
|
* `pkgs.pypyPackages`
|
||||||
|
|
||||||
and the aliases
|
and the aliases
|
||||||
|
|
||||||
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
|
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
|
||||||
* `pkgs.python3Packages` pointing to `pkgs.python37Packages`
|
* `pkgs.python3Packages` pointing to `pkgs.python38Packages`
|
||||||
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
|
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
|
||||||
|
|
||||||
#### `buildPythonPackage` function
|
#### `buildPythonPackage` function
|
||||||
|
@ -1016,7 +1132,7 @@ are used in `buildPythonPackage`.
|
||||||
- `pipBuildHook` to build a wheel using `pip` and PEP 517. Note a build system
|
- `pipBuildHook` to build a wheel using `pip` and PEP 517. Note a build system
|
||||||
(e.g. `setuptools` or `flit`) should still be added as `nativeBuildInput`.
|
(e.g. `setuptools` or `flit`) should still be added as `nativeBuildInput`.
|
||||||
- `pipInstallHook` to install wheels.
|
- `pipInstallHook` to install wheels.
|
||||||
- `pytestCheckHook` to run tests with `pytest`.
|
- `pytestCheckHook` to run tests with `pytest`. See [example usage](#using-pytestcheckhook).
|
||||||
- `pythonCatchConflictsHook` to check whether a Python package is not already existing.
|
- `pythonCatchConflictsHook` to check whether a Python package is not already existing.
|
||||||
- `pythonImportsCheckHook` to check whether importing the listed modules works.
|
- `pythonImportsCheckHook` to check whether importing the listed modules works.
|
||||||
- `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder.
|
- `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder.
|
||||||
|
|
|
@ -43,7 +43,6 @@ rustPlatform.buildRustPackage rec {
|
||||||
homepage = "https://github.com/BurntSushi/ripgrep";
|
homepage = "https://github.com/BurntSushi/ripgrep";
|
||||||
license = licenses.unlicense;
|
license = licenses.unlicense;
|
||||||
maintainers = [ maintainers.tailhook ];
|
maintainers = [ maintainers.tailhook ];
|
||||||
platforms = platforms.all;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -79,7 +78,7 @@ pkgs.rustPlatform.buildRustPackage {
|
||||||
|
|
||||||
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
|
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
|
||||||
`cargo test` on the package to build. To make sure that we don't compile the
|
`cargo test` on the package to build. To make sure that we don't compile the
|
||||||
sources twice and to actually test the artifacts that will be used at runtime,
|
sources twice and to actually test the artifacts that will be used at runtime,
|
||||||
the tests will be ran in the `release` mode by default.
|
the tests will be ran in the `release` mode by default.
|
||||||
|
|
||||||
However, in some cases the test-suite of a package doesn't work properly in the
|
However, in some cases the test-suite of a package doesn't work properly in the
|
||||||
|
|
|
@ -263,6 +263,8 @@ Sometimes plugins require an override that must be changed when the plugin is up
|
||||||
|
|
||||||
To add a new plugin, run `./update.py --add "[owner]/[name]"`. **NOTE**: This script automatically commits to your git repository. Be sure to check out a fresh branch before running.
|
To add a new plugin, run `./update.py --add "[owner]/[name]"`. **NOTE**: This script automatically commits to your git repository. Be sure to check out a fresh branch before running.
|
||||||
|
|
||||||
|
Finally, there are some plugins that are also packaged in nodePackages because they have Javascript-related build steps, such as running webpack. Those plugins are not listed in `vim-plugin-names` or managed by `update.py` at all, and are included separately in `overrides.nix`. Currently, all these plugins are related to the `coc.nvim` ecosystem of Language Server Protocol integration with vim/neovim.
|
||||||
|
|
||||||
## Important repositories
|
## Important repositories
|
||||||
|
|
||||||
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository
|
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository
|
||||||
|
|
|
@ -220,7 +220,7 @@ fi
|
||||||
|
|
||||||
preConfigure=preConfigure
|
preConfigure=preConfigure
|
||||||
preConfigure() {
|
preConfigure() {
|
||||||
|
|
||||||
# Determine the frontends to build.
|
# Determine the frontends to build.
|
||||||
langs="c"
|
langs="c"
|
||||||
if test -n "$langCC"; then
|
if test -n "$langCC"; then
|
||||||
|
@ -262,7 +262,7 @@ postInstall() {
|
||||||
|
|
||||||
#if test -z "$profiledCompiler"; then
|
#if test -z "$profiledCompiler"; then
|
||||||
#makeFlags="bootstrap"
|
#makeFlags="bootstrap"
|
||||||
#else
|
#else
|
||||||
#makeFlags="profiledbootstrap"
|
#makeFlags="profiledbootstrap"
|
||||||
#fi
|
#fi
|
||||||
|
|
||||||
|
|
|
@ -155,17 +155,17 @@ hello-2.3 A program that produces a familiar, friendly greeting
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Single license referenced by attribute (preferred) <literal>stdenv.lib.licenses.gpl3</literal>.
|
Single license referenced by attribute (preferred) <literal>stdenv.lib.licenses.gpl3Only</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Single license referenced by its attribute shortName (frowned upon) <literal>"gpl3"</literal>.
|
Single license referenced by its attribute shortName (frowned upon) <literal>"gpl3Only"</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Single license referenced by its attribute spdxId (frowned upon) <literal>"GPL-3.0"</literal>.
|
Single license referenced by its attribute spdxId (frowned upon) <literal>"GPL-3.0-only"</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -22,39 +22,69 @@
|
||||||
The reduction effects could be instead achieved by building the parts in completely separate derivations. That would often additionally reduce build-time closures, but it tends to be much harder to write such derivations, as build systems typically assume all parts are being built at once. This compromise approach of single source package producing multiple binary packages is also utilized often by rpm and deb.
|
The reduction effects could be instead achieved by building the parts in completely separate derivations. That would often additionally reduce build-time closures, but it tends to be much harder to write such derivations, as build systems typically assume all parts are being built at once. This compromise approach of single source package producing multiple binary packages is also utilized often by rpm and deb.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A number of attributes can be used to work with a derivation with multiple outputs. The attribute <varname>outputs</varname> is a list of strings, which are the names of the outputs. For each of these names, an identically named attribute is created, corresponding to that output. The attribute <varname>meta.outputsToInstall</varname> is used to determine the default set of outputs to install when using the derivation name unqualified.
|
||||||
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="sec-multiple-outputs-installing">
|
<section xml:id="sec-multiple-outputs-installing">
|
||||||
<title>Installing a split package</title>
|
<title>Installing a split package</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When installing a package via <varname>systemPackages</varname> or <command>nix-env</command> you have several options:
|
When installing a package with multiple outputs, the package's <varname>meta.outputsToInstall</varname> attribute determines which outputs are actually installed. <varname>meta.outputsToInstall</varname> is a list whose <link xlink:href="https://github.com/NixOS/nixpkgs/blob/f1680774340d5443a1409c3421ced84ac1163ba9/pkgs/stdenv/generic/make-derivation.nix#L310-L320">default installs binaries and the associated man pages</link>. The following sections describe ways to install different outputs.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<section xml:id="sec-multiple-outputs-installing-nixos">
|
||||||
<listitem>
|
<title>Selecting outputs to install via NixOS</title>
|
||||||
<para>
|
|
||||||
You can install particular outputs explicitly, as each is available in the Nix language as an attribute of the package. The <varname>outputs</varname> attribute contains a list of output names.
|
<para>
|
||||||
</para>
|
NixOS provides two ways to select the outputs to install for packages listed in <varname>environment.systemPackages</varname>:
|
||||||
</listitem>
|
</para>
|
||||||
<listitem>
|
|
||||||
<para>
|
<itemizedlist>
|
||||||
You can let it use the default outputs. These are handled by <varname>meta.outputsToInstall</varname> attribute that contains a list of output names.
|
<listitem>
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
TODO: more about tweaking the attribute, etc.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
NixOS provides configuration option <varname>environment.extraOutputsToInstall</varname> that allows adding extra outputs of <varname>environment.systemPackages</varname> atop the default ones. It's mainly meant for documentation and debug symbols, and it's also modified by specific options.
|
|
||||||
</para>
|
|
||||||
<note>
|
|
||||||
<para>
|
<para>
|
||||||
At this moment there is no similar configurability for packages installed by <command>nix-env</command>. You can still use approach from <xref linkend="sec-modify-via-packageOverrides" /> to override <varname>meta.outputsToInstall</varname> attributes, but that's a rather inconvenient way.
|
The configuration option <varname>environment.extraOutputsToInstall</varname> is appended to each package's <varname>meta.outputsToInstall</varname> attribute to determine the outputs to install. It can for example be used to install <literal>info</literal> documentation or debug symbols for all packages.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</listitem>
|
||||||
</listitem>
|
<listitem>
|
||||||
</itemizedlist>
|
<para>
|
||||||
|
The outputs can be listed as packages in <varname>environment.systemPackages</varname>. For example, the <literal>"out"</literal> and <literal>"info"</literal> outputs for the <varname>coreutils</varname> package can be installed by including <varname>coreutils</varname> and <varname>coreutils.info</varname> in <varname>environment.systemPackages</varname>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-multiple-outputs-installing-nix-env">
|
||||||
|
<title>Selecting outputs to install via <command>nix-env</command></title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>nix-env</command> lacks an easy way to select the outputs to install. When installing a package, <command>nix-env</command> always installs the outputs listed in <varname>meta.outputsToInstall</varname>, even when the user explicitly selects an output.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<warning>
|
||||||
|
<para>
|
||||||
|
<command>nix-env</command> silenty disregards the outputs selected by the user, and instead installs the outputs from <varname>meta.outputsToInstall</varname>. For example,
|
||||||
|
</para>
|
||||||
|
<programlisting>$ nix-env -iA nixpkgs.coreutils.info</programlisting>
|
||||||
|
<para>
|
||||||
|
installs the <literal>"out"</literal> output (<varname>coreutils.meta.outputsToInstall</varname> is <literal>[ "out" ]</literal>) instead of the requested <literal>"info"</literal>.
|
||||||
|
</para>
|
||||||
|
</warning>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The only recourse to select an output with <command>nix-env</command> is to override the package's <varname>meta.outputsToInstall</varname>, using the functions described in <xref linkend="chap-overrides" />. For example, the following overlay adds the <literal>"info"</literal> output for the <varname>coreutils</varname> package:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>self: super:
|
||||||
|
{
|
||||||
|
coreutils = super.coreutils.overrideAttrs (oldAttrs: {
|
||||||
|
meta = oldAttrs.meta // { outputsToInstall = oldAttrs.meta.outputsToInstall or [ "out" ] ++ [ "info" ]; };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="sec-multiple-outputs-using-split-packages">
|
<section xml:id="sec-multiple-outputs-using-split-packages">
|
||||||
<title>Using a split package</title>
|
<title>Using a split package</title>
|
||||||
|
|
|
@ -254,7 +254,7 @@ let f(h, h + 1, i) = i + h
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables specifying dependencies</title>
|
<title>Variables specifying dependencies</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsBuildBuild">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsBuildBuild</varname>
|
<varname>depsBuildBuild</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -267,7 +267,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-nativeBuildInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>nativeBuildInputs</varname>
|
<varname>nativeBuildInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -280,7 +280,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsBuildTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsBuildTarget</varname>
|
<varname>depsBuildTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -296,7 +296,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsHostHost">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsHostHost</varname>
|
<varname>depsHostHost</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -306,7 +306,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-buildInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>buildInputs</varname>
|
<varname>buildInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -319,7 +319,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsTargetTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsTargetTarget</varname>
|
<varname>depsTargetTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -329,7 +329,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsBuildBuildPropagated">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsBuildBuildPropagated</varname>
|
<varname>depsBuildBuildPropagated</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -339,7 +339,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-propagatedNativeBuildInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>propagatedNativeBuildInputs</varname>
|
<varname>propagatedNativeBuildInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -349,7 +349,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsBuildTargetPropagated">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsBuildTargetPropagated</varname>
|
<varname>depsBuildTargetPropagated</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -359,7 +359,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsHostHostPropagated">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsHostHostPropagated</varname>
|
<varname>depsHostHostPropagated</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -369,7 +369,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-propagatedBuildInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>propagatedBuildInputs</varname>
|
<varname>propagatedBuildInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -379,7 +379,7 @@ let f(h, h + 1, i) = i + h
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-depsTargetTargetPropagated">
|
||||||
<term>
|
<term>
|
||||||
<varname>depsTargetTargetPropagated</varname>
|
<varname>depsTargetTargetPropagated</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -396,7 +396,7 @@ let f(h, h + 1, i) = i + h
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables affecting <literal>stdenv</literal> initialisation</title>
|
<title>Variables affecting <literal>stdenv</literal> initialisation</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-NIX_DEBUG">
|
||||||
<term>
|
<term>
|
||||||
<varname>NIX_DEBUG</varname>
|
<varname>NIX_DEBUG</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -410,7 +410,7 @@ let f(h, h + 1, i) = i + h
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Attributes affecting build properties</title>
|
<title>Attributes affecting build properties</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-enableParallelBuilding">
|
||||||
<term>
|
<term>
|
||||||
<varname>enableParallelBuilding</varname>
|
<varname>enableParallelBuilding</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -427,7 +427,7 @@ let f(h, h + 1, i) = i + h
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Special variables</title>
|
<title>Special variables</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-passthru">
|
||||||
<term>
|
<term>
|
||||||
<varname>passthru</varname>
|
<varname>passthru</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -504,7 +504,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
There are a number of variables that control what phases are executed and in what order:
|
There are a number of variables that control what phases are executed and in what order:
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables affecting phase control</title>
|
<title>Variables affecting phase control</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-phases">
|
||||||
<term>
|
<term>
|
||||||
<varname>phases</varname>
|
<varname>phases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -517,7 +517,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-prePhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>prePhases</varname>
|
<varname>prePhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -527,7 +527,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preConfigurePhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>preConfigurePhases</varname>
|
<varname>preConfigurePhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -537,7 +537,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preBuildPhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>preBuildPhases</varname>
|
<varname>preBuildPhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -547,7 +547,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preInstallPhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>preInstallPhases</varname>
|
<varname>preInstallPhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -557,7 +557,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preFixupPhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>preFixupPhases</varname>
|
<varname>preFixupPhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -567,7 +567,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preDistPhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>preDistPhases</varname>
|
<varname>preDistPhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -577,7 +577,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postPhases">
|
||||||
<term>
|
<term>
|
||||||
<varname>postPhases</varname>
|
<varname>postPhases</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -635,7 +635,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the unpack phase</title>
|
<title>Variables controlling the unpack phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-src">
|
||||||
<term>
|
<term>
|
||||||
<varname>srcs</varname> / <varname>src</varname>
|
<varname>srcs</varname> / <varname>src</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -645,7 +645,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-sourceRoot">
|
||||||
<term>
|
<term>
|
||||||
<varname>sourceRoot</varname>
|
<varname>sourceRoot</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -655,7 +655,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-setSourceRoot">
|
||||||
<term>
|
<term>
|
||||||
<varname>setSourceRoot</varname>
|
<varname>setSourceRoot</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -665,7 +665,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preUnpack">
|
||||||
<term>
|
<term>
|
||||||
<varname>preUnpack</varname>
|
<varname>preUnpack</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -675,7 +675,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postUnpack">
|
||||||
<term>
|
<term>
|
||||||
<varname>postUnpack</varname>
|
<varname>postUnpack</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -685,7 +685,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontUnpack">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontUnpack</varname>
|
<varname>dontUnpack</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -695,7 +695,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontMakeSourcesWritable">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontMakeSourcesWritable</varname>
|
<varname>dontMakeSourcesWritable</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -705,7 +705,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-unpackCmd">
|
||||||
<term>
|
<term>
|
||||||
<varname>unpackCmd</varname>
|
<varname>unpackCmd</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -727,7 +727,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the patch phase</title>
|
<title>Variables controlling the patch phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontPatch">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontPatch</varname>
|
<varname>dontPatch</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -737,7 +737,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-patches">
|
||||||
<term>
|
<term>
|
||||||
<varname>patches</varname>
|
<varname>patches</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -747,7 +747,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-patchFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>patchFlags</varname>
|
<varname>patchFlags</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -757,7 +757,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-prePatch">
|
||||||
<term>
|
<term>
|
||||||
<varname>prePatch</varname>
|
<varname>prePatch</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -767,7 +767,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postPatch">
|
||||||
<term>
|
<term>
|
||||||
<varname>postPatch</varname>
|
<varname>postPatch</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -789,7 +789,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the configure phase</title>
|
<title>Variables controlling the configure phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-configureScript">
|
||||||
<term>
|
<term>
|
||||||
<varname>configureScript</varname>
|
<varname>configureScript</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -799,7 +799,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-configureFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>configureFlags</varname>
|
<varname>configureFlags</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -809,7 +809,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontConfigure">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontConfigure</varname>
|
<varname>dontConfigure</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -819,7 +819,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-configureFlagsArray">
|
||||||
<term>
|
<term>
|
||||||
<varname>configureFlagsArray</varname>
|
<varname>configureFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -829,7 +829,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontAddPrefix">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontAddPrefix</varname>
|
<varname>dontAddPrefix</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -839,7 +839,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-prefix">
|
||||||
<term>
|
<term>
|
||||||
<varname>prefix</varname>
|
<varname>prefix</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -849,7 +849,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-prefixKey">
|
||||||
<term>
|
<term>
|
||||||
<varname>prefixKey</varname>
|
<varname>prefixKey</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -859,7 +859,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontAddDisableDepTrack">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontAddDisableDepTrack</varname>
|
<varname>dontAddDisableDepTrack</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -869,7 +869,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontFixLibtool">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontFixLibtool</varname>
|
<varname>dontFixLibtool</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -885,7 +885,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontDisableStatic">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontDisableStatic</varname>
|
<varname>dontDisableStatic</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -898,7 +898,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-configurePlatforms">
|
||||||
<term>
|
<term>
|
||||||
<varname>configurePlatforms</varname>
|
<varname>configurePlatforms</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -913,7 +913,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preConfigure">
|
||||||
<term>
|
<term>
|
||||||
<varname>preConfigure</varname>
|
<varname>preConfigure</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -923,7 +923,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postConfigure">
|
||||||
<term>
|
<term>
|
||||||
<varname>postConfigure</varname>
|
<varname>postConfigure</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -945,7 +945,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the build phase</title>
|
<title>Variables controlling the build phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontBuild">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontBuild</varname>
|
<varname>dontBuild</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -955,7 +955,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-makefile">
|
||||||
<term>
|
<term>
|
||||||
<varname>makefile</varname>
|
<varname>makefile</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -965,7 +965,7 @@ passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-makeFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>makeFlags</varname>
|
<varname>makeFlags</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -983,7 +983,7 @@ makeFlags = [ "PREFIX=$(out)" ];
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-makeFlagsArray">
|
||||||
<term>
|
<term>
|
||||||
<varname>makeFlagsArray</varname>
|
<varname>makeFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -999,7 +999,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-buildFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>buildFlags</varname> / <varname>buildFlagsArray</varname>
|
<varname>buildFlags</varname> / <varname>buildFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1009,7 +1009,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preBuild">
|
||||||
<term>
|
<term>
|
||||||
<varname>preBuild</varname>
|
<varname>preBuild</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1019,7 +1019,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postBuild">
|
||||||
<term>
|
<term>
|
||||||
<varname>postBuild</varname>
|
<varname>postBuild</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1049,7 +1049,7 @@ preBuild = ''
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the check phase</title>
|
<title>Variables controlling the check phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-doCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>doCheck</varname>
|
<varname>doCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1067,11 +1067,11 @@ preBuild = ''
|
||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
See the build phase for details.
|
See the <link xlink:href="#var-stdenv-makeFlags">build phase</link> for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-checkTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>checkTarget</varname>
|
<varname>checkTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1081,7 +1081,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-checkFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>checkFlags</varname> / <varname>checkFlagsArray</varname>
|
<varname>checkFlags</varname> / <varname>checkFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1091,7 +1091,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-checkInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>checkInputs</varname>
|
<varname>checkInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1101,7 +1101,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>preCheck</varname>
|
<varname>preCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1111,7 +1111,7 @@ preBuild = ''
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>postCheck</varname>
|
<varname>postCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1133,7 +1133,7 @@ preBuild = ''
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the install phase</title>
|
<title>Variables controlling the install phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontInstall">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontInstall</varname>
|
<varname>dontInstall</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1149,11 +1149,11 @@ preBuild = ''
|
||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
See the build phase for details.
|
See the <link xlink:href="#var-stdenv-makeFlags">build phase</link> for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-installTargets">
|
||||||
<term>
|
<term>
|
||||||
<varname>installTargets</varname>
|
<varname>installTargets</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1165,7 +1165,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-installFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>installFlags</varname> / <varname>installFlagsArray</varname>
|
<varname>installFlags</varname> / <varname>installFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1175,7 +1175,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preInstall">
|
||||||
<term>
|
<term>
|
||||||
<varname>preInstall</varname>
|
<varname>preInstall</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1185,7 +1185,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postInstall">
|
||||||
<term>
|
<term>
|
||||||
<varname>postInstall</varname>
|
<varname>postInstall</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1229,7 +1229,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the fixup phase</title>
|
<title>Variables controlling the fixup phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontFixup">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontFixup</varname>
|
<varname>dontFixup</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1239,7 +1239,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontStrip">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontStrip</varname>
|
<varname>dontStrip</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1249,7 +1249,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontStripHost">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontStripHost</varname>
|
<varname>dontStripHost</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1259,7 +1259,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontStripTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontStripTarget</varname>
|
<varname>dontStripTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1269,7 +1269,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontMoveSbin">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontMoveSbin</varname>
|
<varname>dontMoveSbin</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1279,7 +1279,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-stripAllList">
|
||||||
<term>
|
<term>
|
||||||
<varname>stripAllList</varname>
|
<varname>stripAllList</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1289,7 +1289,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-stripAllFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>stripAllFlags</varname>
|
<varname>stripAllFlags</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1299,7 +1299,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-stripDebugList">
|
||||||
<term>
|
<term>
|
||||||
<varname>stripDebugList</varname>
|
<varname>stripDebugList</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1309,7 +1309,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-stripDebugFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>stripDebugFlags</varname>
|
<varname>stripDebugFlags</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1319,7 +1319,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontPatchELF">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontPatchELF</varname>
|
<varname>dontPatchELF</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1329,7 +1329,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontPatchShebangs">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontPatchShebangs</varname>
|
<varname>dontPatchShebangs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1339,7 +1339,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontPruneLibtoolFiles">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontPruneLibtoolFiles</varname>
|
<varname>dontPruneLibtoolFiles</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1349,7 +1349,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-forceShare">
|
||||||
<term>
|
<term>
|
||||||
<varname>forceShare</varname>
|
<varname>forceShare</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1359,7 +1359,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-setupHook">
|
||||||
<term>
|
<term>
|
||||||
<varname>setupHook</varname>
|
<varname>setupHook</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1370,7 +1370,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preFixup">
|
||||||
<term>
|
<term>
|
||||||
<varname>preFixup</varname>
|
<varname>preFixup</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1380,7 +1380,7 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postFixup">
|
||||||
<term>
|
<term>
|
||||||
<varname>postFixup</varname>
|
<varname>postFixup</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1419,7 +1419,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the installCheck phase</title>
|
<title>Variables controlling the installCheck phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-doInstallCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>doInstallCheck</varname>
|
<varname>doInstallCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1431,7 +1431,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-installCheckTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>installCheckTarget</varname>
|
<varname>installCheckTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1441,7 +1441,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-installCheckFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>installCheckFlags</varname> / <varname>installCheckFlagsArray</varname>
|
<varname>installCheckFlags</varname> / <varname>installCheckFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1451,7 +1451,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-installCheckInputs">
|
||||||
<term>
|
<term>
|
||||||
<varname>installCheckInputs</varname>
|
<varname>installCheckInputs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1461,7 +1461,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preInstallCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>preInstallCheck</varname>
|
<varname>preInstallCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1471,7 +1471,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postInstallCheck">
|
||||||
<term>
|
<term>
|
||||||
<varname>postInstallCheck</varname>
|
<varname>postInstallCheck</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1493,7 +1493,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Variables controlling the distribution phase</title>
|
<title>Variables controlling the distribution phase</title>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-distTarget">
|
||||||
<term>
|
<term>
|
||||||
<varname>distTarget</varname>
|
<varname>distTarget</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1503,7 +1503,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-distFlags">
|
||||||
<term>
|
<term>
|
||||||
<varname>distFlags</varname> / <varname>distFlagsArray</varname>
|
<varname>distFlags</varname> / <varname>distFlagsArray</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1513,7 +1513,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-tarballs">
|
||||||
<term>
|
<term>
|
||||||
<varname>tarballs</varname>
|
<varname>tarballs</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1523,7 +1523,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-dontCopyDist">
|
||||||
<term>
|
<term>
|
||||||
<varname>dontCopyDist</varname>
|
<varname>dontCopyDist</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1533,7 +1533,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-preDist">
|
||||||
<term>
|
<term>
|
||||||
<varname>preDist</varname>
|
<varname>preDist</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -1543,7 +1543,7 @@ set debug-file-directory ~/.nix-profile/lib/debug
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry xml:id="var-stdenv-postDist">
|
||||||
<term>
|
<term>
|
||||||
<varname>postDist</varname>
|
<varname>postDist</varname>
|
||||||
</term>
|
</term>
|
||||||
|
@ -2018,6 +2018,9 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||||
<para>
|
<para>
|
||||||
In certain situations you may want to run the main command (<command>autoPatchelf</command>) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the <varname>dontAutoPatchelf</varname> environment variable to a non-empty value.
|
In certain situations you may want to run the main command (<command>autoPatchelf</command>) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the <varname>dontAutoPatchelf</varname> environment variable to a non-empty value.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
By default <command>autoPatchelf</command> will fail as soon as any ELF file requires a dependency which cannot be resolved via the given build inputs. In some situations you might prefer to just leave missing dependencies unpatched and continue to patch the rest. This can be achieved by setting the <envar>autoPatchelfIgnoreMissingDeps</envar> environment variable to a non-empty value.
|
||||||
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The <command>autoPatchelf</command> command also recognizes a <parameter class="command">--no-recurse</parameter> command line flag, which prevents it from recursing into subdirectories.
|
The <command>autoPatchelf</command> command also recognizes a <parameter class="command">--no-recurse</parameter> command line flag, which prevents it from recursing into subdirectories.
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -162,10 +162,10 @@
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The following example configuration blacklists the <literal>gpl3</literal> and <literal>agpl3</literal> licenses:
|
The following example configuration blacklists the <literal>gpl3Only</literal> and <literal>agpl3Only</literal> licenses:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
blacklistedLicenses = with stdenv.lib.licenses; [ agpl3 gpl3 ];
|
blacklistedLicenses = with stdenv.lib.licenses; [ agpl3Only gpl3Only ];
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -178,26 +178,40 @@ self: super:
|
||||||
<para>
|
<para>
|
||||||
<link
|
<link
|
||||||
xlink:href="https://software.intel.com/en-us/mkl">Intel
|
xlink:href="https://software.intel.com/en-us/mkl">Intel
|
||||||
MKL</link> (only works on x86 architecture, unfree)
|
MKL</link> (only works on the x86_64 architecture, unfree)
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The Nixpkgs attribute is <literal>mkl</literal>.
|
The Nixpkgs attribute is <literal>mkl</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link
|
||||||
|
xlink:href="https://developer.amd.com/amd-aocl/blas-library/">AMD
|
||||||
|
BLIS/LIBFLAME</link> (optimized for modern AMD x86_64 CPUs)
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The AMD BLIS library, with attribute <literal>amd-blis</literal>,
|
||||||
|
provides a BLAS implementation. The complementary AMD LIBFLAME
|
||||||
|
library, with attribute <literal>amd-libflame</literal>, provides
|
||||||
|
a LAPACK implementation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
<para>
|
<para>
|
||||||
Introduced in <link
|
Introduced in <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/pull/83888">PR
|
xlink:href="https://github.com/NixOS/nixpkgs/pull/83888">PR
|
||||||
#83888</link>, we are able to override the ‘blas’ and ‘lapack’
|
#83888</link>, we are able to override the <literal>blas</literal>
|
||||||
packages to use different implementations, through the
|
and <literal>lapack</literal> packages to use different implementations,
|
||||||
‘blasProvider’ and ‘lapackProvider’ argument. This can be used
|
through the <literal>blasProvider</literal> and
|
||||||
|
<literal>lapackProvider</literal> argument. This can be used
|
||||||
to select a different provider. BLAS providers will have
|
to select a different provider. BLAS providers will have
|
||||||
symlinks in <literal>$out/lib/libblas.so.3</literal> and
|
symlinks in <literal>$out/lib/libblas.so.3</literal> and
|
||||||
<literal>$out/lib/libcblas.so.3</literal> to their respective
|
<literal>$out/lib/libcblas.so.3</literal> to their respective
|
||||||
BLAS libraries. Likewise, LAPACK providers will have symlinks
|
BLAS libraries. Likewise, LAPACK providers will have symlinks
|
||||||
in <literal>$out/lib/liblapack.so.3</literal> and
|
in <literal>$out/lib/liblapack.so.3</literal> and
|
||||||
<literal>$out/lib/liblapacke.so.3</literal> to their respective
|
<literal>$out/lib/liblapacke.so.3</literal> to their respective
|
||||||
LAPCK libraries. For example, Intel MKL is both a BLAS and
|
LAPACK libraries. For example, Intel MKL is both a BLAS and
|
||||||
LAPACK provider. An overlay can be created to use Intel MKL
|
LAPACK provider. An overlay can be created to use Intel MKL
|
||||||
that looks like:
|
that looks like:
|
||||||
</para>
|
</para>
|
||||||
|
@ -216,8 +230,9 @@ self: super:
|
||||||
<para>
|
<para>
|
||||||
This overlay uses Intel’s MKL library for both BLAS and LAPACK
|
This overlay uses Intel’s MKL library for both BLAS and LAPACK
|
||||||
interfaces. Note that the same can be accomplished at runtime
|
interfaces. Note that the same can be accomplished at runtime
|
||||||
using <literal>LD_LIBRARY_PATH</literal> of libblas.so.3 and
|
using <literal>LD_LIBRARY_PATH</literal> of
|
||||||
liblapack.so.3. For instance:
|
<literal>libblas.so.3</literal> and
|
||||||
|
<literal>liblapack.so.3</literal>. For instance:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ LD_LIBRARY_PATH=$(nix-build -A mkl)/lib:$LD_LIBRARY_PATH nix-shell -p octave --run octave
|
$ LD_LIBRARY_PATH=$(nix-build -A mkl)/lib:$LD_LIBRARY_PATH nix-shell -p octave --run octave
|
||||||
|
|
17
flake.nix
17
flake.nix
|
@ -12,23 +12,30 @@
|
||||||
|
|
||||||
lib = import ./lib;
|
lib = import ./lib;
|
||||||
|
|
||||||
systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" ];
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"i686-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"aarch64-linux"
|
||||||
|
"armv6l-linux"
|
||||||
|
"armv7l-linux"
|
||||||
|
];
|
||||||
|
|
||||||
forAllSystems = f: lib.genAttrs systems (system: f system);
|
forAllSystems = f: lib.genAttrs systems (system: f system);
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
lib = lib // {
|
lib = lib.extend (final: prev: {
|
||||||
nixosSystem = { modules, ... } @ args:
|
nixosSystem = { modules, ... } @ args:
|
||||||
import ./nixos/lib/eval-config.nix (args // {
|
import ./nixos/lib/eval-config.nix (args // {
|
||||||
modules = modules ++
|
modules = modules ++
|
||||||
[ { system.nixos.versionSuffix =
|
[ { system.nixos.versionSuffix =
|
||||||
".${lib.substring 0 8 (self.lastModifiedDate or self.lastModified)}.${self.shortRev or "dirty"}";
|
".${final.substring 0 8 (self.lastModifiedDate or self.lastModified)}.${self.shortRev or "dirty"}";
|
||||||
system.nixos.revision = lib.mkIf (self ? rev) self.rev;
|
system.nixos.revision = final.mkIf (self ? rev) self.rev;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
checks.x86_64-linux.tarball = jobs.tarball;
|
checks.x86_64-linux.tarball = jobs.tarball;
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ let
|
||||||
inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor
|
inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor
|
||||||
bitNot boolToString mergeAttrs flip mapNullable inNixShell min max
|
bitNot boolToString mergeAttrs flip mapNullable inNixShell min max
|
||||||
importJSON warn info showWarnings nixpkgsVersion version mod compare
|
importJSON warn info showWarnings nixpkgsVersion version mod compare
|
||||||
splitByAndCompare functionArgs setFunctionArgs isFunction;
|
splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits;
|
||||||
inherit (fixedPoints) fix fix' converge extends composeExtensions
|
inherit (fixedPoints) fix fix' converge extends composeExtensions
|
||||||
makeExtensible makeExtensibleWithCustomName;
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||||
|
|
|
@ -48,8 +48,10 @@ rec {
|
||||||
else if isAttrs v then err "attrsets" v
|
else if isAttrs v then err "attrsets" v
|
||||||
# functions can’t be printed of course
|
# functions can’t be printed of course
|
||||||
else if isFunction v then err "functions" v
|
else if isFunction v then err "functions" v
|
||||||
# let’s not talk about floats. There is no sensible `toString` for them.
|
# Floats currently can't be converted to precise strings,
|
||||||
else if isFloat v then err "floats" v
|
# condition warning on nix version once this isn't a problem anymore
|
||||||
|
# See https://github.com/NixOS/nix/pull/3480
|
||||||
|
else if isFloat v then libStr.floatToString v
|
||||||
else err "this value is" (toString v);
|
else err "this value is" (toString v);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "Academic Free License v3.0";
|
fullName = "Academic Free License v3.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
agpl3 = spdx {
|
agpl3Only = spdx {
|
||||||
spdxId = "AGPL-3.0-only";
|
spdxId = "AGPL-3.0-only";
|
||||||
fullName = "GNU Affero General Public License v3.0 only";
|
fullName = "GNU Affero General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
@ -85,6 +85,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = ''Beerware License'';
|
fullName = ''Beerware License'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
blueOak100 = spdx {
|
||||||
|
spdxId = "BlueOak-1.0.0";
|
||||||
|
fullName = "Blue Oak Model License 1.0.0";
|
||||||
|
};
|
||||||
|
|
||||||
bsd0 = spdx {
|
bsd0 = spdx {
|
||||||
spdxId = "0BSD";
|
spdxId = "0BSD";
|
||||||
fullName = "BSD Zero Clause License";
|
fullName = "BSD Zero Clause License";
|
||||||
|
@ -110,6 +115,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bsdProtection = spdx {
|
||||||
|
spdxId = "BSD-Protection";
|
||||||
|
fullName = "BSD Protection License";
|
||||||
|
};
|
||||||
|
|
||||||
bsl11 = {
|
bsl11 = {
|
||||||
fullName = "Business Source License 1.1";
|
fullName = "Business Source License 1.1";
|
||||||
url = "https://mariadb.com/bsl11";
|
url = "https://mariadb.com/bsl11";
|
||||||
|
@ -281,12 +291,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "European Union Public License 1.2";
|
fullName = "European Union Public License 1.2";
|
||||||
};
|
};
|
||||||
|
|
||||||
fdl11 = spdx {
|
fdl11Only = spdx {
|
||||||
spdxId = "GFDL-1.1-only";
|
spdxId = "GFDL-1.1-only";
|
||||||
fullName = "GNU Free Documentation License v1.1 only";
|
fullName = "GNU Free Documentation License v1.1 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
fdl12 = spdx {
|
fdl12Only = spdx {
|
||||||
spdxId = "GFDL-1.2-only";
|
spdxId = "GFDL-1.2-only";
|
||||||
fullName = "GNU Free Documentation License v1.2 only";
|
fullName = "GNU Free Documentation License v1.2 only";
|
||||||
};
|
};
|
||||||
|
@ -296,7 +306,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "GNU Free Documentation License v1.2 or later";
|
fullName = "GNU Free Documentation License v1.2 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
fdl13 = spdx {
|
fdl13Only = spdx {
|
||||||
spdxId = "GFDL-1.3-only";
|
spdxId = "GFDL-1.3-only";
|
||||||
fullName = "GNU Free Documentation License v1.3 only";
|
fullName = "GNU Free Documentation License v1.3 only";
|
||||||
};
|
};
|
||||||
|
@ -327,7 +337,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
free = false;
|
free = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl1 = spdx {
|
gpl1Only = spdx {
|
||||||
spdxId = "GPL-1.0-only";
|
spdxId = "GPL-1.0-only";
|
||||||
fullName = "GNU General Public License v1.0 only";
|
fullName = "GNU General Public License v1.0 only";
|
||||||
};
|
};
|
||||||
|
@ -337,7 +347,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "GNU General Public License v1.0 or later";
|
fullName = "GNU General Public License v1.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl2 = spdx {
|
gpl2Only = spdx {
|
||||||
spdxId = "GPL-2.0-only";
|
spdxId = "GPL-2.0-only";
|
||||||
fullName = "GNU General Public License v2.0 only";
|
fullName = "GNU General Public License v2.0 only";
|
||||||
};
|
};
|
||||||
|
@ -362,7 +372,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "GNU General Public License v2.0 or later";
|
fullName = "GNU General Public License v2.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl3 = spdx {
|
gpl3Only = spdx {
|
||||||
spdxId = "GPL-3.0-only";
|
spdxId = "GPL-3.0-only";
|
||||||
fullName = "GNU General Public License v3.0 only";
|
fullName = "GNU General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
@ -426,6 +436,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Proprietary binaries; free to redistribute without modification.
|
# Proprietary binaries; free to redistribute without modification.
|
||||||
|
databricks = {
|
||||||
|
fullName = "Databricks Proprietary License";
|
||||||
|
url = "https://pypi.org/project/databricks-connect";
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
issl = {
|
issl = {
|
||||||
fullName = "Intel Simplified Software License";
|
fullName = "Intel Simplified Software License";
|
||||||
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
||||||
|
@ -437,7 +453,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "JasPer License";
|
fullName = "JasPer License";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl2 = spdx {
|
lgpl2Only = spdx {
|
||||||
spdxId = "LGPL-2.0-only";
|
spdxId = "LGPL-2.0-only";
|
||||||
fullName = "GNU Library General Public License v2 only";
|
fullName = "GNU Library General Public License v2 only";
|
||||||
};
|
};
|
||||||
|
@ -447,7 +463,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "GNU Library General Public License v2 or later";
|
fullName = "GNU Library General Public License v2 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl21 = spdx {
|
lgpl21Only = spdx {
|
||||||
spdxId = "LGPL-2.1-only";
|
spdxId = "LGPL-2.1-only";
|
||||||
fullName = "GNU Lesser General Public License v2.1 only";
|
fullName = "GNU Lesser General Public License v2.1 only";
|
||||||
};
|
};
|
||||||
|
@ -457,7 +473,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
fullName = "GNU Lesser General Public License v2.1 or later";
|
fullName = "GNU Lesser General Public License v2.1 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl3 = spdx {
|
lgpl3Only = spdx {
|
||||||
spdxId = "LGPL-3.0-only";
|
spdxId = "LGPL-3.0-only";
|
||||||
fullName = "GNU Lesser General Public License v3.0 only";
|
fullName = "GNU Lesser General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
@ -782,4 +798,16 @@ lib.mapAttrs (n: v: v // { shortName = n; }) {
|
||||||
spdxId = "ZPL-2.1";
|
spdxId = "ZPL-2.1";
|
||||||
fullName = "Zope Public License 2.1";
|
fullName = "Zope Public License 2.1";
|
||||||
};
|
};
|
||||||
|
} // {
|
||||||
|
# TODO: remove legacy aliases
|
||||||
|
agpl3 = lib.licenses.agpl3Only;
|
||||||
|
fdl11 = lib.licenses.fdl11Only;
|
||||||
|
fdl12 = lib.licenses.fdl12Only;
|
||||||
|
fdl13 = lib.licenses.fdl13Only;
|
||||||
|
gpl1 = lib.licenses.gpl1Only;
|
||||||
|
gpl2 = lib.licenses.gpl2Only;
|
||||||
|
gpl3 = lib.licenses.gpl3Only;
|
||||||
|
lgpl2 = lib.licenses.lgpl2Only;
|
||||||
|
lgpl21 = lib.licenses.lgpl21Only;
|
||||||
|
lgpl3 = lib.licenses.lgpl3Only;
|
||||||
}
|
}
|
||||||
|
|
161
lib/modules.nix
161
lib/modules.nix
|
@ -58,6 +58,23 @@ rec {
|
||||||
default = check;
|
default = check;
|
||||||
description = "Whether to check whether all option definitions have matching declarations.";
|
description = "Whether to check whether all option definitions have matching declarations.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_module.freeformType = mkOption {
|
||||||
|
# Disallow merging for now, but could be implemented nicely with a `types.optionType`
|
||||||
|
type = types.nullOr (types.uniq types.attrs);
|
||||||
|
internal = true;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
If set, merge all definitions that don't have an associated option
|
||||||
|
together using this type. The result then gets combined with the
|
||||||
|
values of all declared options to produce the final <literal>
|
||||||
|
config</literal> value.
|
||||||
|
|
||||||
|
If this is <literal>null</literal>, definitions without an option
|
||||||
|
will throw an error unless <option>_module.check</option> is
|
||||||
|
turned off.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
@ -65,35 +82,55 @@ rec {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
collected = collectModules
|
merged =
|
||||||
(specialArgs.modulesPath or "")
|
let collected = collectModules
|
||||||
(modules ++ [ internalModule ])
|
(specialArgs.modulesPath or "")
|
||||||
({ inherit config options lib; } // specialArgs);
|
(modules ++ [ internalModule ])
|
||||||
|
({ inherit lib options config; } // specialArgs);
|
||||||
|
in mergeModules prefix (reverseList collected);
|
||||||
|
|
||||||
options = mergeModules prefix (reverseList collected);
|
options = merged.matchedOptions;
|
||||||
|
|
||||||
# Traverse options and extract the option values into the final
|
config =
|
||||||
# config set. At the same time, check whether all option
|
let
|
||||||
# definitions have matching declarations.
|
|
||||||
# !!! _module.check's value can't depend on any other config values
|
# For definitions that have an associated option
|
||||||
# without an infinite recursion. One way around this is to make the
|
declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
|
||||||
# 'config' passed around to the modules be unconditionally unchecked,
|
|
||||||
# and only do the check in 'result'.
|
# If freeformType is set, this is for definitions that don't have an associated option
|
||||||
config = yieldConfig prefix options;
|
freeformConfig =
|
||||||
yieldConfig = prefix: set:
|
let
|
||||||
let res = removeAttrs (mapAttrs (n: v:
|
defs = map (def: {
|
||||||
if isOption v then v.value
|
file = def.file;
|
||||||
else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"];
|
value = setAttrByPath def.prefix def.value;
|
||||||
in
|
}) merged.unmatchedDefns;
|
||||||
if options._module.check.value && set ? _definedNames then
|
in if defs == [] then {}
|
||||||
foldl' (res: m:
|
else declaredConfig._module.freeformType.merge prefix defs;
|
||||||
foldl' (res: name:
|
|
||||||
if set ? ${name} then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.")
|
in if declaredConfig._module.freeformType == null then declaredConfig
|
||||||
res m.names)
|
# Because all definitions that had an associated option ended in
|
||||||
res set._definedNames
|
# declaredConfig, freeformConfig can only contain the non-option
|
||||||
else
|
# paths, meaning recursiveUpdate will never override any value
|
||||||
res;
|
else recursiveUpdate freeformConfig declaredConfig;
|
||||||
result = {
|
|
||||||
|
checkUnmatched =
|
||||||
|
if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
|
||||||
|
let
|
||||||
|
firstDef = head merged.unmatchedDefns;
|
||||||
|
baseMsg = "The option `${showOption (prefix ++ firstDef.prefix)}' defined in `${firstDef.file}' does not exist.";
|
||||||
|
in
|
||||||
|
if attrNames options == [ "_module" ]
|
||||||
|
then throw ''
|
||||||
|
${baseMsg}
|
||||||
|
|
||||||
|
However there are no options defined in `${showOption prefix}'. Are you sure you've
|
||||||
|
declared your options properly? This can happen if you e.g. declared your options in `types.submodule'
|
||||||
|
under `config' rather than `options'.
|
||||||
|
''
|
||||||
|
else throw baseMsg
|
||||||
|
else null;
|
||||||
|
|
||||||
|
result = builtins.seq checkUnmatched {
|
||||||
inherit options;
|
inherit options;
|
||||||
config = removeAttrs config [ "_module" ];
|
config = removeAttrs config [ "_module" ];
|
||||||
inherit (config) _module;
|
inherit (config) _module;
|
||||||
|
@ -174,12 +211,16 @@ rec {
|
||||||
/* Massage a module into canonical form, that is, a set consisting
|
/* Massage a module into canonical form, that is, a set consisting
|
||||||
of ‘options’, ‘config’ and ‘imports’ attributes. */
|
of ‘options’, ‘config’ and ‘imports’ attributes. */
|
||||||
unifyModuleSyntax = file: key: m:
|
unifyModuleSyntax = file: key: m:
|
||||||
let addMeta = config: if m ? meta
|
let
|
||||||
then mkMerge [ config { meta = m.meta; } ]
|
addMeta = config: if m ? meta
|
||||||
else config;
|
then mkMerge [ config { meta = m.meta; } ]
|
||||||
|
else config;
|
||||||
|
addFreeformType = config: if m ? freeformType
|
||||||
|
then mkMerge [ config { _module.freeformType = m.freeformType; } ]
|
||||||
|
else config;
|
||||||
in
|
in
|
||||||
if m ? config || m ? options then
|
if m ? config || m ? options then
|
||||||
let badAttrs = removeAttrs m ["_file" "key" "disabledModules" "imports" "options" "config" "meta"]; in
|
let badAttrs = removeAttrs m ["_file" "key" "disabledModules" "imports" "options" "config" "meta" "freeformType"]; in
|
||||||
if badAttrs != {} then
|
if badAttrs != {} then
|
||||||
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'. This is caused by introducing a top-level `config' or `options' attribute. Add configuration attributes immediately on the top level instead, or move all of them (namely: ${toString (attrNames badAttrs)}) into the explicit `config' attribute."
|
throw "Module `${key}' has an unsupported attribute `${head (attrNames badAttrs)}'. This is caused by introducing a top-level `config' or `options' attribute. Add configuration attributes immediately on the top level instead, or move all of them (namely: ${toString (attrNames badAttrs)}) into the explicit `config' attribute."
|
||||||
else
|
else
|
||||||
|
@ -188,7 +229,7 @@ rec {
|
||||||
disabledModules = m.disabledModules or [];
|
disabledModules = m.disabledModules or [];
|
||||||
imports = m.imports or [];
|
imports = m.imports or [];
|
||||||
options = m.options or {};
|
options = m.options or {};
|
||||||
config = addMeta (m.config or {});
|
config = addFreeformType (addMeta (m.config or {}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ _file = m._file or file;
|
{ _file = m._file or file;
|
||||||
|
@ -196,7 +237,7 @@ rec {
|
||||||
disabledModules = m.disabledModules or [];
|
disabledModules = m.disabledModules or [];
|
||||||
imports = m.require or [] ++ m.imports or [];
|
imports = m.require or [] ++ m.imports or [];
|
||||||
options = {};
|
options = {};
|
||||||
config = addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports"]);
|
config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"]));
|
||||||
};
|
};
|
||||||
|
|
||||||
applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
|
applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
|
||||||
|
@ -233,7 +274,23 @@ rec {
|
||||||
declarations in all modules, combining them into a single set.
|
declarations in all modules, combining them into a single set.
|
||||||
At the same time, for each option declaration, it will merge the
|
At the same time, for each option declaration, it will merge the
|
||||||
corresponding option definitions in all machines, returning them
|
corresponding option definitions in all machines, returning them
|
||||||
in the ‘value’ attribute of each option. */
|
in the ‘value’ attribute of each option.
|
||||||
|
|
||||||
|
This returns a set like
|
||||||
|
{
|
||||||
|
# A recursive set of options along with their final values
|
||||||
|
matchedOptions = {
|
||||||
|
foo = { _type = "option"; value = "option value of foo"; ... };
|
||||||
|
bar.baz = { _type = "option"; value = "option value of bar.baz"; ... };
|
||||||
|
...
|
||||||
|
};
|
||||||
|
# A list of definitions that weren't matched by any option
|
||||||
|
unmatchedDefns = [
|
||||||
|
{ file = "file.nix"; prefix = [ "qux" ]; value = "qux"; }
|
||||||
|
...
|
||||||
|
];
|
||||||
|
}
|
||||||
|
*/
|
||||||
mergeModules = prefix: modules:
|
mergeModules = prefix: modules:
|
||||||
mergeModules' prefix modules
|
mergeModules' prefix modules
|
||||||
(concatMap (m: map (config: { file = m._file; inherit config; }) (pushDownProperties m.config)) modules);
|
(concatMap (m: map (config: { file = m._file; inherit config; }) (pushDownProperties m.config)) modules);
|
||||||
|
@ -280,9 +337,9 @@ rec {
|
||||||
defnsByName' = byName "config" (module: value:
|
defnsByName' = byName "config" (module: value:
|
||||||
[{ inherit (module) file; inherit value; }]
|
[{ inherit (module) file; inherit value; }]
|
||||||
) configs;
|
) configs;
|
||||||
in
|
|
||||||
(flip mapAttrs declsByName (name: decls:
|
resultsByName = flip mapAttrs declsByName (name: decls:
|
||||||
# We're descending into attribute ‘name’.
|
# We're descending into attribute ‘name’.
|
||||||
let
|
let
|
||||||
loc = prefix ++ [name];
|
loc = prefix ++ [name];
|
||||||
defns = defnsByName.${name} or [];
|
defns = defnsByName.${name} or [];
|
||||||
|
@ -291,7 +348,10 @@ rec {
|
||||||
in
|
in
|
||||||
if nrOptions == length decls then
|
if nrOptions == length decls then
|
||||||
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
|
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
|
||||||
in evalOptionValue loc opt defns'
|
in {
|
||||||
|
matchedOptions = evalOptionValue loc opt defns';
|
||||||
|
unmatchedDefns = [];
|
||||||
|
}
|
||||||
else if nrOptions != 0 then
|
else if nrOptions != 0 then
|
||||||
let
|
let
|
||||||
firstOption = findFirst (m: isOption m.options) "" decls;
|
firstOption = findFirst (m: isOption m.options) "" decls;
|
||||||
|
@ -299,9 +359,27 @@ rec {
|
||||||
in
|
in
|
||||||
throw "The option `${showOption loc}' in `${firstOption._file}' is a prefix of options in `${firstNonOption._file}'."
|
throw "The option `${showOption loc}' in `${firstOption._file}' is a prefix of options in `${firstNonOption._file}'."
|
||||||
else
|
else
|
||||||
mergeModules' loc decls defns
|
mergeModules' loc decls defns);
|
||||||
))
|
|
||||||
// { _definedNames = map (m: { inherit (m) file; names = attrNames m.config; }) configs; };
|
matchedOptions = mapAttrs (n: v: v.matchedOptions) resultsByName;
|
||||||
|
|
||||||
|
# an attrset 'name' => list of unmatched definitions for 'name'
|
||||||
|
unmatchedDefnsByName =
|
||||||
|
# Propagate all unmatched definitions from nested option sets
|
||||||
|
mapAttrs (n: v: v.unmatchedDefns) resultsByName
|
||||||
|
# Plus the definitions for the current prefix that don't have a matching option
|
||||||
|
// removeAttrs defnsByName' (attrNames matchedOptions);
|
||||||
|
in {
|
||||||
|
inherit matchedOptions;
|
||||||
|
|
||||||
|
# Transforms unmatchedDefnsByName into a list of definitions
|
||||||
|
unmatchedDefns = concatLists (mapAttrsToList (name: defs:
|
||||||
|
map (def: def // {
|
||||||
|
# Set this so we know when the definition first left unmatched territory
|
||||||
|
prefix = [name] ++ (def.prefix or []);
|
||||||
|
}) defs
|
||||||
|
) unmatchedDefnsByName);
|
||||||
|
};
|
||||||
|
|
||||||
/* Merge multiple option declarations into a single declaration. In
|
/* Merge multiple option declarations into a single declaration. In
|
||||||
general, there should be only one declaration of each option.
|
general, there should be only one declaration of each option.
|
||||||
|
@ -535,7 +613,6 @@ rec {
|
||||||
if tp.name == "option set" || tp.name == "submodule" then
|
if tp.name == "option set" || tp.name == "submodule" then
|
||||||
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
|
||||||
else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
|
else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
|
||||||
else if optionSetIn "loaOf" then types.loaOf (types.submodule options)
|
|
||||||
else if optionSetIn "listOf" then types.listOf (types.submodule options)
|
else if optionSetIn "listOf" then types.listOf (types.submodule options)
|
||||||
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
|
else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
|
||||||
else tp;
|
else tp;
|
||||||
|
|
|
@ -145,10 +145,14 @@ rec {
|
||||||
# packed-refs file, so we have to grep through it:
|
# packed-refs file, so we have to grep through it:
|
||||||
then
|
then
|
||||||
let fileContent = readFile packedRefsName;
|
let fileContent = readFile packedRefsName;
|
||||||
matchRef = match (".*\n([^\n ]*) " + file + "\n.*") fileContent;
|
matchRef = builtins.match "([a-z0-9]+) ${file}";
|
||||||
in if matchRef == null
|
isRef = s: builtins.isString s && (matchRef s) != null;
|
||||||
|
# there is a bug in libstdc++ leading to stackoverflow for long strings:
|
||||||
|
# https://github.com/NixOS/nix/issues/2147#issuecomment-659868795
|
||||||
|
refs = builtins.filter isRef (builtins.split "\n" fileContent);
|
||||||
|
in if refs == []
|
||||||
then throw ("Could not find " + file + " in " + packedRefsName)
|
then throw ("Could not find " + file + " in " + packedRefsName)
|
||||||
else lib.head matchRef
|
else lib.head (matchRef (lib.head refs))
|
||||||
|
|
||||||
else throw ("Not a .git directory: " + path);
|
else throw ("Not a .git directory: " + path);
|
||||||
in readCommitFromFile "HEAD";
|
in readCommitFromFile "HEAD";
|
||||||
|
|
|
@ -612,6 +612,22 @@ rec {
|
||||||
*/
|
*/
|
||||||
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
||||||
|
|
||||||
|
/* Convert a float to a string, but emit a warning when precision is lost
|
||||||
|
during the conversion
|
||||||
|
|
||||||
|
Example:
|
||||||
|
floatToString 0.000001
|
||||||
|
=> "0.000001"
|
||||||
|
floatToString 0.0000001
|
||||||
|
=> trace: warning: Imprecise conversion from float to string 0.000000
|
||||||
|
"0.000000"
|
||||||
|
*/
|
||||||
|
floatToString = float: let
|
||||||
|
result = toString float;
|
||||||
|
precise = float == builtins.fromJSON result;
|
||||||
|
in if precise then result
|
||||||
|
else lib.warn "Imprecise conversion from float to string ${result}" result;
|
||||||
|
|
||||||
/* Check whether a value can be coerced to a string */
|
/* Check whether a value can be coerced to a string */
|
||||||
isCoercibleToString = x:
|
isCoercibleToString = x:
|
||||||
builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
||||||
|
@ -673,14 +689,15 @@ rec {
|
||||||
"/prefix/nix-profiles-library-paths.patch"
|
"/prefix/nix-profiles-library-paths.patch"
|
||||||
"/prefix/compose-search-path.patch" ]
|
"/prefix/compose-search-path.patch" ]
|
||||||
*/
|
*/
|
||||||
readPathsFromFile = rootPath: file:
|
readPathsFromFile = lib.warn "lib.readPathsFromFile is deprecated, use a list instead"
|
||||||
let
|
(rootPath: file:
|
||||||
lines = lib.splitString "\n" (builtins.readFile file);
|
let
|
||||||
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
lines = lib.splitString "\n" (builtins.readFile file);
|
||||||
relativePaths = removeComments lines;
|
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
||||||
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
relativePaths = removeComments lines;
|
||||||
in
|
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
||||||
absolutePaths;
|
in
|
||||||
|
absolutePaths);
|
||||||
|
|
||||||
/* Read the contents of a file removing the trailing \n
|
/* Read the contents of a file removing the trailing \n
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# platform.gcc.arch to its features (as in /proc/cpuinfo)
|
||||||
|
features = {
|
||||||
|
default = [ ];
|
||||||
|
# x86_64 Intel
|
||||||
|
westmere = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" ];
|
||||||
|
sandybridge = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
ivybridge = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
haswell = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
broadwell = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
skylake = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "fma" ];
|
||||||
|
skylake-avx512 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" "avx2" "avx512" "fma" ];
|
||||||
|
# x86_64 AMD
|
||||||
|
btver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" ];
|
||||||
|
btver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "aes" "avx" ];
|
||||||
|
bdver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver3 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "fma" "fma4" ];
|
||||||
|
bdver4 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" "fma4" ];
|
||||||
|
znver1 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" ];
|
||||||
|
znver2 = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "fma" ];
|
||||||
|
# other
|
||||||
|
armv5te = [ ];
|
||||||
|
armv6 = [ ];
|
||||||
|
armv7-a = [ ];
|
||||||
|
armv8-a = [ ];
|
||||||
|
mips32 = [ ];
|
||||||
|
loongson2f = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# a superior CPU has all the features of an inferior and is able to build and test code for it
|
||||||
|
inferiors = {
|
||||||
|
# x86_64 Intel
|
||||||
|
default = [ ];
|
||||||
|
westmere = [ ];
|
||||||
|
sandybridge = [ "westmere" ] ++ inferiors.westmere;
|
||||||
|
ivybridge = [ "sandybridge" ] ++ inferiors.sandybridge;
|
||||||
|
haswell = [ "ivybridge" ] ++ inferiors.ivybridge;
|
||||||
|
broadwell = [ "haswell" ] ++ inferiors.haswell;
|
||||||
|
skylake = [ "broadwell" ] ++ inferiors.broadwell;
|
||||||
|
skylake-avx512 = [ "skylake" ] ++ inferiors.skylake;
|
||||||
|
# x86_64 AMD
|
||||||
|
btver1 = [ ];
|
||||||
|
btver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver1 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver3 = [ ]; # TODO: fill this (need testing)
|
||||||
|
bdver4 = [ ]; # TODO: fill this (need testing)
|
||||||
|
znver1 = [ ]; # TODO: fill this (need testing)
|
||||||
|
znver2 = [ ]; # TODO: fill this (need testing)
|
||||||
|
# other
|
||||||
|
armv5te = [ ];
|
||||||
|
armv6 = [ ];
|
||||||
|
armv7-a = [ ];
|
||||||
|
armv8-a = [ ];
|
||||||
|
mips32 = [ ];
|
||||||
|
loongson2f = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
predicates = let
|
||||||
|
featureSupport = feature: x: builtins.elem feature features.${x};
|
||||||
|
in {
|
||||||
|
sse3Support = featureSupport "sse3";
|
||||||
|
ssse3Support = featureSupport "ssse3";
|
||||||
|
sse4_1Support = featureSupport "sse4_1";
|
||||||
|
sse4_2Support = featureSupport "sse4_2";
|
||||||
|
sse4_aSupport = featureSupport "sse4a";
|
||||||
|
avxSupport = featureSupport "avx";
|
||||||
|
avx2Support = featureSupport "avx2";
|
||||||
|
avx512Support = featureSupport "avx512";
|
||||||
|
aesSupport = featureSupport "aes";
|
||||||
|
fmaSupport = featureSupport "fma";
|
||||||
|
fma4Support = featureSupport "fma4";
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ rec {
|
||||||
inspect = import ./inspect.nix { inherit lib; };
|
inspect = import ./inspect.nix { inherit lib; };
|
||||||
platforms = import ./platforms.nix { inherit lib; };
|
platforms = import ./platforms.nix { inherit lib; };
|
||||||
examples = import ./examples.nix { inherit lib; };
|
examples = import ./examples.nix { inherit lib; };
|
||||||
|
architectures = import ./architectures.nix { inherit lib; };
|
||||||
|
|
||||||
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
||||||
# necessary.
|
# necessary.
|
||||||
|
@ -32,6 +33,7 @@ rec {
|
||||||
/**/ if final.isDarwin then "libSystem"
|
/**/ if final.isDarwin then "libSystem"
|
||||||
else if final.isMinGW then "msvcrt"
|
else if final.isMinGW then "msvcrt"
|
||||||
else if final.isWasi then "wasilibc"
|
else if final.isWasi then "wasilibc"
|
||||||
|
else if final.isRedox then "relibc"
|
||||||
else if final.isMusl then "musl"
|
else if final.isMusl then "musl"
|
||||||
else if final.isUClibc then "uclibc"
|
else if final.isUClibc then "uclibc"
|
||||||
else if final.isAndroid then "bionic"
|
else if final.isAndroid then "bionic"
|
||||||
|
@ -65,6 +67,7 @@ rec {
|
||||||
freebsd = "FreeBSD";
|
freebsd = "FreeBSD";
|
||||||
openbsd = "OpenBSD";
|
openbsd = "OpenBSD";
|
||||||
wasi = "Wasi";
|
wasi = "Wasi";
|
||||||
|
redox = "Redox";
|
||||||
genode = "Genode";
|
genode = "Genode";
|
||||||
}.${final.parsed.kernel.name} or null;
|
}.${final.parsed.kernel.name} or null;
|
||||||
|
|
||||||
|
@ -74,6 +77,7 @@ rec {
|
||||||
# uname -r
|
# uname -r
|
||||||
release = null;
|
release = null;
|
||||||
};
|
};
|
||||||
|
isStatic = final.isWasm || final.isRedox;
|
||||||
|
|
||||||
kernelArch =
|
kernelArch =
|
||||||
if final.isAarch32 then "arm"
|
if final.isAarch32 then "arm"
|
||||||
|
@ -123,6 +127,7 @@ rec {
|
||||||
else throw "Don't know how to run ${final.config} executables.";
|
else throw "Don't know how to run ${final.config} executables.";
|
||||||
|
|
||||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
|
// mapAttrs (n: v: v final.platform.gcc.arch or "default") architectures.predicates
|
||||||
// args;
|
// args;
|
||||||
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||||
assert lib.foldl
|
assert lib.foldl
|
||||||
|
|
|
@ -22,6 +22,8 @@ let
|
||||||
|
|
||||||
"wasm64-wasi" "wasm32-wasi"
|
"wasm64-wasi" "wasm32-wasi"
|
||||||
|
|
||||||
|
"x86_64-redox"
|
||||||
|
|
||||||
"powerpc64le-linux"
|
"powerpc64le-linux"
|
||||||
|
|
||||||
"riscv32-linux" "riscv64-linux"
|
"riscv32-linux" "riscv64-linux"
|
||||||
|
@ -36,7 +38,7 @@ let
|
||||||
|
|
||||||
"js-ghcjs"
|
"js-ghcjs"
|
||||||
|
|
||||||
"aarch64-genode" "x86_64-genode"
|
"aarch64-genode" "i686-genode" "x86_64-genode"
|
||||||
];
|
];
|
||||||
|
|
||||||
allParsed = map parse.mkSystemFromString all;
|
allParsed = map parse.mkSystemFromString all;
|
||||||
|
@ -69,6 +71,7 @@ in {
|
||||||
openbsd = filterDoubles predicates.isOpenBSD;
|
openbsd = filterDoubles predicates.isOpenBSD;
|
||||||
unix = filterDoubles predicates.isUnix;
|
unix = filterDoubles predicates.isUnix;
|
||||||
wasi = filterDoubles predicates.isWasi;
|
wasi = filterDoubles predicates.isWasi;
|
||||||
|
redox = filterDoubles predicates.isRedox;
|
||||||
windows = filterDoubles predicates.isWindows;
|
windows = filterDoubles predicates.isWindows;
|
||||||
genode = filterDoubles predicates.isGenode;
|
genode = filterDoubles predicates.isGenode;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ rec {
|
||||||
|
|
||||||
armv7a-android-prebuilt = {
|
armv7a-android-prebuilt = {
|
||||||
config = "armv7a-unknown-linux-androideabi";
|
config = "armv7a-unknown-linux-androideabi";
|
||||||
sdkVer = "24";
|
sdkVer = "29";
|
||||||
ndkVer = "18b";
|
ndkVer = "18b";
|
||||||
platform = platforms.armv7a-android;
|
platform = platforms.armv7a-android;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
|
@ -54,7 +54,7 @@ rec {
|
||||||
|
|
||||||
aarch64-android-prebuilt = {
|
aarch64-android-prebuilt = {
|
||||||
config = "aarch64-unknown-linux-android";
|
config = "aarch64-unknown-linux-android";
|
||||||
sdkVer = "24";
|
sdkVer = "29";
|
||||||
ndkVer = "18b";
|
ndkVer = "18b";
|
||||||
platform = platforms.aarch64-multiplatform;
|
platform = platforms.aarch64-multiplatform;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
|
@ -163,6 +163,15 @@ rec {
|
||||||
libc = "newlib";
|
libc = "newlib";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Redox
|
||||||
|
#
|
||||||
|
|
||||||
|
x86_64-unknown-redox = {
|
||||||
|
config = "x86_64-unknown-redox";
|
||||||
|
libc = "relibc";
|
||||||
|
};
|
||||||
|
|
||||||
#
|
#
|
||||||
# Darwin
|
# Darwin
|
||||||
#
|
#
|
||||||
|
|
|
@ -33,7 +33,7 @@ rec {
|
||||||
|
|
||||||
isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
||||||
isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
|
isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
|
||||||
isUnix = [ isBSD isDarwin isLinux isSunOS isCygwin ];
|
isUnix = [ isBSD isDarwin isLinux isSunOS isCygwin isRedox ];
|
||||||
|
|
||||||
isMacOS = { kernel = kernels.macos; };
|
isMacOS = { kernel = kernels.macos; };
|
||||||
isiOS = { kernel = kernels.ios; };
|
isiOS = { kernel = kernels.ios; };
|
||||||
|
@ -46,6 +46,7 @@ rec {
|
||||||
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
||||||
isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
||||||
isWasi = { kernel = kernels.wasi; };
|
isWasi = { kernel = kernels.wasi; };
|
||||||
|
isRedox = { kernel = kernels.redox; };
|
||||||
isGhcjs = { kernel = kernels.ghcjs; };
|
isGhcjs = { kernel = kernels.ghcjs; };
|
||||||
isGenode = { kernel = kernels.genode; };
|
isGenode = { kernel = kernels.genode; };
|
||||||
isNone = { kernel = kernels.none; };
|
isNone = { kernel = kernels.none; };
|
||||||
|
|
|
@ -277,6 +277,7 @@ rec {
|
||||||
openbsd = { execFormat = elf; families = { inherit bsd; }; };
|
openbsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||||
solaris = { execFormat = elf; families = { }; };
|
solaris = { execFormat = elf; families = { }; };
|
||||||
wasi = { execFormat = wasm; families = { }; };
|
wasi = { execFormat = wasm; families = { }; };
|
||||||
|
redox = { execFormat = elf; families = { }; };
|
||||||
windows = { execFormat = pe; families = { }; };
|
windows = { execFormat = pe; families = { }; };
|
||||||
ghcjs = { execFormat = unknown; families = { }; };
|
ghcjs = { execFormat = unknown; families = { }; };
|
||||||
genode = { execFormat = elf; families = { }; };
|
genode = { execFormat = elf; families = { }; };
|
||||||
|
@ -390,6 +391,8 @@ rec {
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; }
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; }
|
||||||
else if (elemAt l 2 == "wasi")
|
else if (elemAt l 2 == "wasi")
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi"; }
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi"; }
|
||||||
|
else if (elemAt l 2 == "redox")
|
||||||
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "redox"; }
|
||||||
else if hasPrefix "netbsd" (elemAt l 2)
|
else if hasPrefix "netbsd" (elemAt l 2)
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
|
||||||
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
|
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
|
||||||
|
|
|
@ -102,6 +102,16 @@ runTests {
|
||||||
expected = 9;
|
expected = 9;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testToHexString = {
|
||||||
|
expr = toHexString 250;
|
||||||
|
expected = "FA";
|
||||||
|
};
|
||||||
|
|
||||||
|
testToBaseDigits = {
|
||||||
|
expr = toBaseDigits 2 6;
|
||||||
|
expected = [ 1 1 0 ];
|
||||||
|
};
|
||||||
|
|
||||||
# STRINGS
|
# STRINGS
|
||||||
|
|
||||||
testConcatMapStrings = {
|
testConcatMapStrings = {
|
||||||
|
|
|
@ -210,6 +210,29 @@ checkConfigOutput "empty" config.value.foo ./declare-lazyAttrsOf.nix ./attrsOf-c
|
||||||
checkConfigError 'The option value .* in .* is not of type .*' \
|
checkConfigError 'The option value .* in .* is not of type .*' \
|
||||||
config.value ./declare-int-unsigned-value.nix ./define-value-list.nix ./define-value-int-positive.nix
|
config.value ./declare-int-unsigned-value.nix ./define-value-list.nix ./define-value-int-positive.nix
|
||||||
|
|
||||||
|
## Freeform modules
|
||||||
|
# Assigning without a declared option should work
|
||||||
|
checkConfigOutput 24 config.value ./freeform-attrsOf.nix ./define-value-string.nix
|
||||||
|
# No freeform assigments shouldn't make it error
|
||||||
|
checkConfigOutput '{ }' config ./freeform-attrsOf.nix
|
||||||
|
# but only if the type matches
|
||||||
|
checkConfigError 'The option value .* in .* is not of type .*' config.value ./freeform-attrsOf.nix ./define-value-list.nix
|
||||||
|
# and properties should be applied
|
||||||
|
checkConfigOutput yes config.value ./freeform-attrsOf.nix ./define-value-string-properties.nix
|
||||||
|
# Options should still be declarable, and be able to have a type that doesn't match the freeform type
|
||||||
|
checkConfigOutput false config.enable ./freeform-attrsOf.nix ./define-value-string.nix ./declare-enable.nix
|
||||||
|
checkConfigOutput 24 config.value ./freeform-attrsOf.nix ./define-value-string.nix ./declare-enable.nix
|
||||||
|
# and this should work too with nested values
|
||||||
|
checkConfigOutput false config.nest.foo ./freeform-attrsOf.nix ./freeform-nested.nix
|
||||||
|
checkConfigOutput bar config.nest.bar ./freeform-attrsOf.nix ./freeform-nested.nix
|
||||||
|
# Check whether a declared option can depend on an freeform-typed one
|
||||||
|
checkConfigOutput null config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix
|
||||||
|
checkConfigOutput 24 config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix ./define-value-string.nix
|
||||||
|
# Check whether an freeform-typed value can depend on a declared option, this can only work with lazyAttrsOf
|
||||||
|
checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
|
||||||
|
checkConfigError 'The option .* is used but not defined' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
|
||||||
|
checkConfigOutput 24 config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
====== module tests ======
|
====== module tests ======
|
||||||
$pass Pass
|
$pass Pass
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Always defined, but the value depends on the presence of an option.
|
# Always defined, but the value depends on the presence of an option.
|
||||||
config = {
|
config = {
|
||||||
value = if options ? enable then 360 else 7;
|
value = if options ? enable then 360 else 7;
|
||||||
}
|
}
|
||||||
# Only define if possible.
|
# Only define if possible.
|
||||||
// lib.optionalAttrs (options ? enable) {
|
// lib.optionalAttrs (options ? enable) {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
|
||||||
|
imports = [{
|
||||||
|
value = lib.mkDefault "def";
|
||||||
|
}];
|
||||||
|
|
||||||
|
value = lib.mkMerge [
|
||||||
|
(lib.mkIf false "nope")
|
||||||
|
"yes"
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
freeformType = with lib.types; attrsOf (either str (attrsOf str));
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
freeformType = with lib.types; lazyAttrsOf (either str (lazyAttrsOf str));
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
options.nest.foo = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
config.nest.bar = "bar";
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{ lib, config, ... }: {
|
||||||
|
options.foo = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.foo = lib.mkIf (config ? value) config.value;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{ lib, config, ... }: {
|
||||||
|
options.value = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.foo = lib.mkIf (config.value != null) config.value;
|
||||||
|
}
|
|
@ -17,7 +17,6 @@ pkgs.runCommandNoCC "nixpkgs-lib-tests" {
|
||||||
export TEST_ROOT=$(pwd)/test-tmp
|
export TEST_ROOT=$(pwd)/test-tmp
|
||||||
export NIX_BUILD_HOOK=
|
export NIX_BUILD_HOOK=
|
||||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||||
export NIX_DB_DIR=$TEST_ROOT/db
|
|
||||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||||
|
|
|
@ -12,22 +12,23 @@ let
|
||||||
expected = lib.sort lib.lessThan y;
|
expected = lib.sort lib.lessThan y;
|
||||||
};
|
};
|
||||||
in with lib.systems.doubles; lib.runTests {
|
in with lib.systems.doubles; lib.runTests {
|
||||||
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows ++ embedded ++ js ++ genode);
|
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows ++ embedded ++ js ++ genode ++ redox);
|
||||||
|
|
||||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-none" "armv7a-linux" "armv7l-linux" "arm-none" "armv7a-darwin" ];
|
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-none" "armv7a-linux" "armv7l-linux" "arm-none" "armv7a-darwin" ];
|
||||||
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
|
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
|
||||||
testmips = mseteq mips [ "mipsel-linux" ];
|
testmips = mseteq mips [ "mipsel-linux" ];
|
||||||
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
|
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
|
||||||
|
|
||||||
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];
|
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];
|
||||||
testdarwin = mseteq darwin [ "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" ];
|
testdarwin = mseteq darwin [ "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" ];
|
||||||
testfreebsd = mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ];
|
testfreebsd = mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ];
|
||||||
testgenode = mseteq genode [ "aarch64-genode" "x86_64-genode" ];
|
testgenode = mseteq genode [ "aarch64-genode" "i686-genode" "x86_64-genode" ];
|
||||||
|
testredox = mseteq redox [ "x86_64-redox" ];
|
||||||
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
||||||
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
||||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64le-linux" ];
|
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64le-linux" ];
|
||||||
testnetbsd = mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ];
|
testnetbsd = mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ];
|
||||||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||||
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin);
|
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin ++ redox);
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,4 +332,55 @@ rec {
|
||||||
*/
|
*/
|
||||||
isFunction = f: builtins.isFunction f ||
|
isFunction = f: builtins.isFunction f ||
|
||||||
(f ? __functor && isFunction (f.__functor f));
|
(f ? __functor && isFunction (f.__functor f));
|
||||||
|
|
||||||
|
/* Convert the given positive integer to a string of its hexadecimal
|
||||||
|
representation. For example:
|
||||||
|
|
||||||
|
toHexString 0 => "0"
|
||||||
|
|
||||||
|
toHexString 16 => "10"
|
||||||
|
|
||||||
|
toHexString 250 => "FA"
|
||||||
|
*/
|
||||||
|
toHexString = i:
|
||||||
|
let
|
||||||
|
toHexDigit = d:
|
||||||
|
if d < 10
|
||||||
|
then toString d
|
||||||
|
else
|
||||||
|
{
|
||||||
|
"10" = "A";
|
||||||
|
"11" = "B";
|
||||||
|
"12" = "C";
|
||||||
|
"13" = "D";
|
||||||
|
"14" = "E";
|
||||||
|
"15" = "F";
|
||||||
|
}.${toString d};
|
||||||
|
in
|
||||||
|
lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
|
||||||
|
|
||||||
|
/* `toBaseDigits base i` converts the positive integer i to a list of its
|
||||||
|
digits in the given base. For example:
|
||||||
|
|
||||||
|
toBaseDigits 10 123 => [ 1 2 3 ]
|
||||||
|
|
||||||
|
toBaseDigits 2 6 => [ 1 1 0 ]
|
||||||
|
|
||||||
|
toBaseDigits 16 250 => [ 15 10 ]
|
||||||
|
*/
|
||||||
|
toBaseDigits = base: i:
|
||||||
|
let
|
||||||
|
go = i:
|
||||||
|
if i < base
|
||||||
|
then [i]
|
||||||
|
else
|
||||||
|
let
|
||||||
|
r = i - ((i / base) * base);
|
||||||
|
q = (i - r) / base;
|
||||||
|
in
|
||||||
|
[r] ++ go q;
|
||||||
|
in
|
||||||
|
assert (base >= 2);
|
||||||
|
assert (i >= 0);
|
||||||
|
lib.reverseList (go i);
|
||||||
}
|
}
|
||||||
|
|
123
lib/types.nix
123
lib/types.nix
|
@ -252,8 +252,8 @@ rec {
|
||||||
merge = mergeEqualOption;
|
merge = mergeEqualOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
# drop this in the future:
|
# TODO: drop this in the future:
|
||||||
list = builtins.trace "`types.list` is deprecated; use `types.listOf` instead" types.listOf;
|
list = builtins.trace "`types.list` has been removed; please use `types.listOf` instead" types.listOf;
|
||||||
|
|
||||||
listOf = elemType: mkOptionType rec {
|
listOf = elemType: mkOptionType rec {
|
||||||
name = "listOf";
|
name = "listOf";
|
||||||
|
@ -326,110 +326,15 @@ rec {
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
# List or attribute set of ...
|
# TODO: drop this in the future:
|
||||||
loaOf = elemType:
|
loaOf =
|
||||||
let
|
let msg =
|
||||||
convertAllLists = loc: defs:
|
''
|
||||||
let
|
`types.loaOf` has been removed and mixing lists with attribute values
|
||||||
padWidth = stringLength (toString (length defs));
|
is no longer possible; please use `types.attrsOf` instead.
|
||||||
unnamedPrefix = i: "unnamed-" + fixedWidthNumber padWidth i + ".";
|
See https://github.com/NixOS/nixpkgs/issues/1800 for the motivation.
|
||||||
in
|
'';
|
||||||
imap1 (i: convertIfList loc (unnamedPrefix i)) defs;
|
in builtins.trace msg types.attrsOf;
|
||||||
convertIfList = loc: unnamedPrefix: def:
|
|
||||||
if isList def.value then
|
|
||||||
let
|
|
||||||
padWidth = stringLength (toString (length def.value));
|
|
||||||
unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i;
|
|
||||||
anyString = placeholder "name";
|
|
||||||
nameAttrs = [
|
|
||||||
{ path = [ "environment" "etc" ];
|
|
||||||
name = "target";
|
|
||||||
}
|
|
||||||
{ path = [ "containers" anyString "bindMounts" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "programs" "ssh" "knownHosts" ];
|
|
||||||
# hostNames is actually a list so we would need to handle it only when singleton
|
|
||||||
name = "hostNames";
|
|
||||||
}
|
|
||||||
{ path = [ "fileSystems" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "boot" "specialFileSystems" ];
|
|
||||||
name = "mountPoint";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "znapzend" "zetup" ];
|
|
||||||
name = "dataset";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "znapzend" "zetup" anyString "destinations" ];
|
|
||||||
name = "label";
|
|
||||||
}
|
|
||||||
{ path = [ "services" "geoclue2" "appConfig" ];
|
|
||||||
name = "desktopID";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
matched = let
|
|
||||||
equals = a: b: b == anyString || a == b;
|
|
||||||
fallback = { name = "name"; };
|
|
||||||
in findFirst ({ path, ... }: all (v: v == true) (zipListsWith equals loc path)) fallback nameAttrs;
|
|
||||||
nameAttr = matched.name;
|
|
||||||
nameValueOld = value:
|
|
||||||
if isList value then
|
|
||||||
if length value > 0 then
|
|
||||||
"[ " + concatMapStringsSep " " escapeNixString value + " ]"
|
|
||||||
else
|
|
||||||
"[ ]"
|
|
||||||
else
|
|
||||||
escapeNixString value;
|
|
||||||
nameValueNew = value: unnamed:
|
|
||||||
if isList value then
|
|
||||||
if length value > 0 then
|
|
||||||
head value
|
|
||||||
else
|
|
||||||
unnamed
|
|
||||||
else
|
|
||||||
value;
|
|
||||||
res =
|
|
||||||
{ inherit (def) file;
|
|
||||||
value = listToAttrs (
|
|
||||||
imap1 (elemIdx: elem:
|
|
||||||
{ name = nameValueNew (elem.${nameAttr} or (unnamed elemIdx)) (unnamed elemIdx);
|
|
||||||
value = elem;
|
|
||||||
}) def.value);
|
|
||||||
};
|
|
||||||
option = concatStringsSep "." loc;
|
|
||||||
sample = take 3 def.value;
|
|
||||||
more = lib.optionalString (length def.value > 3) "... ";
|
|
||||||
list = concatMapStrings (x: ''{ ${nameAttr} = ${nameValueOld (x.${nameAttr} or "unnamed")}; ...} '') sample;
|
|
||||||
set = concatMapStrings (x: ''${nameValueNew (x.${nameAttr} or "unnamed") "unnamed"} = {...}; '') sample;
|
|
||||||
msg = ''
|
|
||||||
In file ${def.file}
|
|
||||||
a list is being assigned to the option config.${option}.
|
|
||||||
This will soon be an error as type loaOf is deprecated.
|
|
||||||
See https://github.com/NixOS/nixpkgs/pull/63103 for more information.
|
|
||||||
Do
|
|
||||||
${option} =
|
|
||||||
{ ${set}${more}}
|
|
||||||
instead of
|
|
||||||
${option} =
|
|
||||||
[ ${list}${more}]
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
lib.warn msg res
|
|
||||||
else
|
|
||||||
def;
|
|
||||||
attrOnly = attrsOf elemType;
|
|
||||||
in mkOptionType rec {
|
|
||||||
name = "loaOf";
|
|
||||||
description = "list or attribute set of ${elemType.description}s";
|
|
||||||
check = x: isList x || isAttrs x;
|
|
||||||
merge = loc: defs: attrOnly.merge loc (convertAllLists loc defs);
|
|
||||||
emptyValue = { value = {}; };
|
|
||||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
|
|
||||||
getSubModules = elemType.getSubModules;
|
|
||||||
substSubModules = m: loaOf (elemType.substSubModules m);
|
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
|
||||||
};
|
|
||||||
|
|
||||||
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
||||||
uniq = elemType: mkOptionType rec {
|
uniq = elemType: mkOptionType rec {
|
||||||
|
@ -486,9 +391,15 @@ rec {
|
||||||
else value
|
else value
|
||||||
) defs;
|
) defs;
|
||||||
|
|
||||||
|
freeformType = (evalModules {
|
||||||
|
inherit modules specialArgs;
|
||||||
|
args.name = "‹name›";
|
||||||
|
})._module.freeformType;
|
||||||
|
|
||||||
in
|
in
|
||||||
mkOptionType rec {
|
mkOptionType rec {
|
||||||
name = "submodule";
|
name = "submodule";
|
||||||
|
description = freeformType.description or name;
|
||||||
check = x: isAttrs x || isFunction x || path.check x;
|
check = x: isAttrs x || isFunction x || path.check x;
|
||||||
merge = loc: defs:
|
merge = loc: defs:
|
||||||
(evalModules {
|
(evalModules {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,10 @@ lua-cmsgpack,,,,,
|
||||||
lua-iconv,,,,,
|
lua-iconv,,,,,
|
||||||
lua-lsp,,http://luarocks.org/dev,,,
|
lua-lsp,,http://luarocks.org/dev,,,
|
||||||
lua-messagepack,,,,,
|
lua-messagepack,,,,,
|
||||||
|
lua-resty-http,,,,,
|
||||||
|
lua-resty-jwt,,,,,
|
||||||
|
lua-resty-openidc,,,,,
|
||||||
|
lua-resty-session,,,,,
|
||||||
lua-term,,,,,
|
lua-term,,,,,
|
||||||
lua-toml,,,,,
|
lua-toml,,,,,
|
||||||
lua-zlib,,,,,koral
|
lua-zlib,,,,,koral
|
||||||
|
@ -79,5 +83,4 @@ say,,,,,
|
||||||
std__debug,std._debug,,,,
|
std__debug,std._debug,,,,
|
||||||
std_normalize,std.normalize,,,,
|
std_normalize,std.normalize,,,,
|
||||||
stdlib,,,,,vyp
|
stdlib,,,,,vyp
|
||||||
pulseaudio,,,,,doronbehar
|
|
||||||
vstruct,,,,,
|
vstruct,,,,,
|
||||||
|
|
|
|
@ -60,7 +60,7 @@ nixexpr() {
|
||||||
"darwin-tested" "unstable" "stdenvBootstrapTools"
|
"darwin-tested" "unstable" "stdenvBootstrapTools"
|
||||||
"moduleSystem" "lib-tests" # these just confuse the output
|
"moduleSystem" "lib-tests" # these just confuse the output
|
||||||
];
|
];
|
||||||
|
|
||||||
in
|
in
|
||||||
tweak (builtins.removeAttrs hydraJobs blacklist)
|
tweak (builtins.removeAttrs hydraJobs blacklist)
|
||||||
EONIX
|
EONIX
|
||||||
|
@ -124,4 +124,3 @@ if [ -n "$optPrint" ]; then
|
||||||
echo
|
echo
|
||||||
cat "$newlist"
|
cat "$newlist"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,13 @@
|
||||||
# TODO: add assert statements
|
# TODO: add assert statements
|
||||||
|
|
||||||
let
|
let
|
||||||
pkgs = import ./../../default.nix (if include-overlays then { } else { overlays = []; });
|
pkgs = import ./../../default.nix (
|
||||||
|
if include-overlays == false then
|
||||||
|
{ overlays = []; }
|
||||||
|
else if include-overlays == true then
|
||||||
|
{ } # Let Nixpkgs include overlays impurely.
|
||||||
|
else { overlays = include-overlays; }
|
||||||
|
);
|
||||||
|
|
||||||
inherit (pkgs) lib;
|
inherit (pkgs) lib;
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,21 @@ with lib.maintainers; {
|
||||||
hedning
|
hedning
|
||||||
jtojnar
|
jtojnar
|
||||||
worldofpeace
|
worldofpeace
|
||||||
|
dasj19
|
||||||
];
|
];
|
||||||
scope = "Maintain GNOME desktop environment and platform.";
|
scope = "Maintain GNOME desktop environment and platform.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
jitsi = {
|
||||||
|
members = [
|
||||||
|
mmilata
|
||||||
|
petabyteboy
|
||||||
|
prusnak
|
||||||
|
ryantm
|
||||||
|
];
|
||||||
|
scope = "Maintain Jitsi.";
|
||||||
|
};
|
||||||
|
|
||||||
matrix = {
|
matrix = {
|
||||||
members = [
|
members = [
|
||||||
ma27
|
ma27
|
||||||
|
|
|
@ -58,9 +58,9 @@
|
||||||
Like <literal>boot.debug1</literal> or
|
Like <literal>boot.debug1</literal> or
|
||||||
<literal>boot.debug1devices</literal>, but runs stage1 until all
|
<literal>boot.debug1devices</literal>, but runs stage1 until all
|
||||||
filesystems that are mounted during initrd are mounted (see
|
filesystems that are mounted during initrd are mounted (see
|
||||||
<option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
|
<option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
|
||||||
). As a motivating example, this could be useful if you've forgotten to set
|
). As a motivating example, this could be useful if you've forgotten to set
|
||||||
<option><link linkend="opt-fileSystems._name__.neededForBoot">neededForBoot</link></option>
|
<option><link linkend="opt-fileSystems._name_.neededForBoot">neededForBoot</link></option>
|
||||||
on a file system.
|
on a file system.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<screen>
|
<screen>
|
||||||
# nixos-container create foo --config '
|
# nixos-container create foo --config '
|
||||||
<xref linkend="opt-services.openssh.enable"/> = true;
|
<xref linkend="opt-services.openssh.enable"/> = true;
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.root.openssh.authorizedKeys.keys</link> = ["ssh-dss AAAAB3N…"];
|
||||||
'
|
'
|
||||||
</screen>
|
</screen>
|
||||||
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
|
By default the next free address in the <literal>10.233.0.0/16</literal> subnet will be chosen
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<xi:include href="user-mgmt.xml" />
|
<xi:include href="user-mgmt.xml" />
|
||||||
<xi:include href="file-systems.xml" />
|
<xi:include href="file-systems.xml" />
|
||||||
<xi:include href="x-windows.xml" />
|
<xi:include href="x-windows.xml" />
|
||||||
|
<xi:include href="gpu-accel.xml" />
|
||||||
<xi:include href="xfce.xml" />
|
<xi:include href="xfce.xml" />
|
||||||
<xi:include href="networking.xml" />
|
<xi:include href="networking.xml" />
|
||||||
<xi:include href="linux-kernel.xml" />
|
<xi:include href="linux-kernel.xml" />
|
||||||
|
|
|
@ -23,12 +23,12 @@
|
||||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html">systemd-fstab-generator</link>.
|
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html">systemd-fstab-generator</link>.
|
||||||
The filesystem will be mounted automatically unless
|
The filesystem will be mounted automatically unless
|
||||||
<literal>"noauto"</literal> is present in <link
|
<literal>"noauto"</literal> is present in <link
|
||||||
linkend="opt-fileSystems._name__.options">options</link>.
|
linkend="opt-fileSystems._name_.options">options</link>.
|
||||||
<literal>"noauto"</literal> filesystems can be mounted explicitly using
|
<literal>"noauto"</literal> filesystems can be mounted explicitly using
|
||||||
<command>systemctl</command> e.g. <command>systemctl start
|
<command>systemctl</command> e.g. <command>systemctl start
|
||||||
data.mount</command>.
|
data.mount</command>.
|
||||||
Mount points are created automatically if they don’t already exist. For
|
Mount points are created automatically if they don’t already exist. For
|
||||||
<option><link linkend="opt-fileSystems._name__.device">device</link></option>,
|
<option><link linkend="opt-fileSystems._name_.device">device</link></option>,
|
||||||
it’s best to use the topology-independent device aliases in
|
it’s best to use the topology-independent device aliases in
|
||||||
<filename>/dev/disk/by-label</filename> and
|
<filename>/dev/disk/by-label</filename> and
|
||||||
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
|
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
You can usually omit the file system type
|
You can usually omit the file system type
|
||||||
(<option><link linkend="opt-fileSystems._name__.fsType">fsType</link></option>),
|
(<option><link linkend="opt-fileSystems._name_.fsType">fsType</link></option>),
|
||||||
since <command>mount</command> can usually detect the type and load the
|
since <command>mount</command> can usually detect the type and load the
|
||||||
necessary kernel module automatically. However, if the file system is needed
|
necessary kernel module automatically. However, if the file system is needed
|
||||||
at early boot (in the initial ramdisk) and is not <literal>ext2</literal>,
|
at early boot (in the initial ramdisk) and is not <literal>ext2</literal>,
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
System startup will fail if any of the filesystems fails to mount, dropping
|
System startup will fail if any of the filesystems fails to mount, dropping
|
||||||
you to the emergency shell. You can make a mount asynchronous and
|
you to the emergency shell. You can make a mount asynchronous and
|
||||||
non-critical by adding
|
non-critical by adding
|
||||||
<literal><link linkend="opt-fileSystems._name__.options">options</link> = [
|
<literal><link linkend="opt-fileSystems._name_.options">options</link> = [
|
||||||
"nofail" ];</literal>.
|
"nofail" ];</literal>.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-gpu-accel">
|
||||||
|
<title>GPU acceleration</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
NixOS provides various APIs that benefit from GPU hardware
|
||||||
|
acceleration, such as VA-API and VDPAU for video playback; OpenGL and
|
||||||
|
Vulkan for 3D graphics; and OpenCL for general-purpose computing.
|
||||||
|
This chapter describes how to set up GPU hardware acceleration (as far
|
||||||
|
as this is not done automatically) and how to verify that hardware
|
||||||
|
acceleration is indeed used.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Most of the aforementioned APIs are agnostic with regards to which
|
||||||
|
display server is used. Consequently, these instructions should apply
|
||||||
|
both to the X Window System and Wayland compositors.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-opencl">
|
||||||
|
<title>OpenCL</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://en.wikipedia.org/wiki/OpenCL">OpenCL</link> is a
|
||||||
|
general compute API. It is used by various applications such as
|
||||||
|
Blender and Darktable to accelerate certain operations.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
OpenCL applications load drivers through the <emphasis>Installable Client
|
||||||
|
Driver</emphasis> (ICD) mechanism. In this mechanism, an ICD file
|
||||||
|
specifies the path to the OpenCL driver for a particular GPU family.
|
||||||
|
In NixOS, there are two ways to make ICD files visible to the ICD
|
||||||
|
loader. The first is through the <varname>OCL_ICD_VENDORS</varname>
|
||||||
|
environment variable. This variable can contain a directory which
|
||||||
|
is scanned by the ICL loader for ICD files. For example:
|
||||||
|
|
||||||
|
<screen><prompt>$</prompt> export \
|
||||||
|
OCL_ICD_VENDORS=`nix-build '<nixpkgs>' --no-out-link -A rocm-opencl-icd`/etc/OpenCL/vendors/</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The second mechanism is to add the OpenCL driver package to
|
||||||
|
<xref linkend="opt-hardware.opengl.extraPackages"/>. This links the
|
||||||
|
ICD file under <filename>/run/opengl-driver</filename>, where it will
|
||||||
|
be visible to the ICD loader.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The proper installation of OpenCL drivers can be verified through
|
||||||
|
the <command>clinfo</command> command of the <package>clinfo</package>
|
||||||
|
package. This command will report the number of hardware devices
|
||||||
|
that is found and give detailed information for each device:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen><prompt>$</prompt> clinfo | head -n3
|
||||||
|
Number of platforms 1
|
||||||
|
Platform Name AMD Accelerated Parallel Processing
|
||||||
|
Platform Vendor Advanced Micro Devices, Inc.</screen>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-opencl-amd">
|
||||||
|
<title>AMD</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Modern AMD <link
|
||||||
|
xlink:href="https://en.wikipedia.org/wiki/Graphics_Core_Next">Graphics
|
||||||
|
Core Next</link> (GCN) GPUs are supported through the
|
||||||
|
<package>rocm-opencl-icd</package> package. Adding this package to
|
||||||
|
<xref linkend="opt-hardware.opengl.extraPackages"/> enables OpenCL
|
||||||
|
support:
|
||||||
|
|
||||||
|
<programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
|
||||||
|
rocm-opencl-icd
|
||||||
|
];</programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-opencl-intel">
|
||||||
|
<title>Intel</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<link
|
||||||
|
xlink:href="https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen8">Intel
|
||||||
|
Gen8 and later GPUs</link> are supported by the Intel NEO OpenCL
|
||||||
|
runtime that is provided by the
|
||||||
|
<package>intel-compute-runtime</package> package. For Gen7 GPUs,
|
||||||
|
the deprecated Beignet runtime can be used, which is provided
|
||||||
|
by the <package>beignet</package> package. The proprietary Intel
|
||||||
|
OpenCL runtime, in the <package>intel-ocl</package> package, is
|
||||||
|
an alternative for Gen7 GPUs.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <package>intel-compute-runtime</package>, <package>beignet</package>,
|
||||||
|
or <package>intel-ocl</package> package can be added to
|
||||||
|
<xref linkend="opt-hardware.opengl.extraPackages"/> to enable OpenCL
|
||||||
|
support. For example, for Gen8 and later GPUs, the following
|
||||||
|
configuration can be used:
|
||||||
|
|
||||||
|
<programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
|
||||||
|
intel-compute-runtime
|
||||||
|
];</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-vulkan">
|
||||||
|
<title>Vulkan</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://en.wikipedia.org/wiki/Vulkan_(API)">Vulkan</link> is a
|
||||||
|
graphics and compute API for GPUs. It is used directly by games or indirectly though
|
||||||
|
compatibility layers like <link xlink:href="https://github.com/doitsujin/dxvk/wiki">DXVK</link>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By default, if <xref linkend="opt-hardware.opengl.driSupport"/> is enabled,
|
||||||
|
<package>mesa</package> is installed and provides Vulkan for supported hardware.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Similar to OpenCL, Vulkan drivers are loaded through the <emphasis>Installable Client
|
||||||
|
Driver</emphasis> (ICD) mechanism. ICD files for Vulkan are JSON files that specify
|
||||||
|
the path to the driver library and the supported Vulkan version. All successfully
|
||||||
|
loaded drivers are exposed to the application as different GPUs.
|
||||||
|
In NixOS, there are two ways to make ICD files visible to Vulkan applications: an
|
||||||
|
environment variable and a module option.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The first option is through the <varname>VK_ICD_FILENAMES</varname>
|
||||||
|
environment variable. This variable can contain multiple JSON files, separated by
|
||||||
|
<literal>:</literal>. For example:
|
||||||
|
|
||||||
|
<screen><prompt>$</prompt> export \
|
||||||
|
VK_ICD_FILENAMES=`nix-build '<nixpkgs>' --no-out-link -A amdvlk`/share/vulkan/icd.d/amd_icd64.json</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The second mechanism is to add the Vulkan driver package to
|
||||||
|
<xref linkend="opt-hardware.opengl.extraPackages"/>. This links the
|
||||||
|
ICD file under <filename>/run/opengl-driver</filename>, where it will
|
||||||
|
be visible to the ICD loader.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The proper installation of Vulkan drivers can be verified through
|
||||||
|
the <command>vulkaninfo</command> command of the <package>vulkan-tools</package>
|
||||||
|
package. This command will report the hardware devices and drivers found,
|
||||||
|
in this example output amdvlk and radv:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen><prompt>$</prompt> vulkaninfo | grep GPU
|
||||||
|
GPU id : 0 (Unknown AMD GPU)
|
||||||
|
GPU id : 1 (AMD RADV NAVI10 (LLVM 9.0.1))
|
||||||
|
...
|
||||||
|
GPU0:
|
||||||
|
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||||
|
deviceName = Unknown AMD GPU
|
||||||
|
GPU1:
|
||||||
|
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A simple graphical application that uses Vulkan is <command>vkcube</command>
|
||||||
|
from the <package>vulkan-tools</package> package.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-vulkan-amd">
|
||||||
|
<title>AMD</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Modern AMD <link
|
||||||
|
xlink:href="https://en.wikipedia.org/wiki/Graphics_Core_Next">Graphics
|
||||||
|
Core Next</link> (GCN) GPUs are supported through either radv, which is
|
||||||
|
part of <package>mesa</package>, or the <package>amdvlk</package> package.
|
||||||
|
Adding the <package>amdvlk</package> package to
|
||||||
|
<xref linkend="opt-hardware.opengl.extraPackages"/> makes both drivers
|
||||||
|
available for applications and lets them choose. A specific driver can
|
||||||
|
be forced as follows:
|
||||||
|
|
||||||
|
<programlisting><xref linkend="opt-hardware.opengl.extraPackages"/> = [
|
||||||
|
<package>amdvlk</package>
|
||||||
|
];
|
||||||
|
|
||||||
|
# For amdvlk
|
||||||
|
<xref linkend="opt-environment.variables"/>.VK_ICD_FILENAMES =
|
||||||
|
"/run/opengl-driver/share/vulkan/icd.d/amd_icd64.json";
|
||||||
|
# For radv
|
||||||
|
<xref linkend="opt-environment.variables"/>.VK_ICD_FILENAMES =
|
||||||
|
"/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json";
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-common-issues">
|
||||||
|
<title>Common issues</title>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-common-issues-permissions">
|
||||||
|
<title>User permissions</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Except where noted explicitly, it should not be necessary to
|
||||||
|
adjust user permissions to use these acceleration APIs. In the default
|
||||||
|
configuration, GPU devices have world-read/write permissions
|
||||||
|
(<filename>/dev/dri/renderD*</filename>) or are tagged as
|
||||||
|
<code>uaccess</code> (<filename>/dev/dri/card*</filename>). The
|
||||||
|
access control lists of devices with the <varname>uaccess</varname>
|
||||||
|
tag will be updated automatically when a user logs in through
|
||||||
|
<command>systemd-logind</command>. For example, if the user
|
||||||
|
<emphasis>jane</emphasis> is logged in, the access control list
|
||||||
|
should look as follows:
|
||||||
|
|
||||||
|
<screen><prompt>$</prompt> getfacl /dev/dri/card0
|
||||||
|
# file: dev/dri/card0
|
||||||
|
# owner: root
|
||||||
|
# group: video
|
||||||
|
user::rw-
|
||||||
|
user:jane:rw-
|
||||||
|
group::rw-
|
||||||
|
mask::rw-
|
||||||
|
other::---</screen>
|
||||||
|
|
||||||
|
If you disabled (this functionality of) <command>systemd-logind</command>,
|
||||||
|
you may need to add the user to the <code>video</code> group and
|
||||||
|
log in again.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-gpu-accel-common-issues-mixing-nixpkgs">
|
||||||
|
<title>Mixing different versions of nixpkgs</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <emphasis>Installable Client Driver</emphasis> (ICD)
|
||||||
|
mechanism used by OpenCL and Vulkan loads runtimes into its address
|
||||||
|
space using <code>dlopen</code>. Mixing an ICD loader mechanism and
|
||||||
|
runtimes from different version of nixpkgs may not work. For example,
|
||||||
|
if the ICD loader uses an older version of <package>glibc</package>
|
||||||
|
than the runtime, the runtime may not be loadable due to
|
||||||
|
missing symbols. Unfortunately, the loader will generally be quiet
|
||||||
|
about such issues.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If you suspect that you are running into library version mismatches
|
||||||
|
between an ICL loader and a runtime, you could run an application with
|
||||||
|
the <code>LD_DEBUG</code> variable set to get more diagnostic
|
||||||
|
information. For example, OpenCL can be tested with
|
||||||
|
<code>LD_DEBUG=files clinfo</code>, which should report missing
|
||||||
|
symbols.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</chapter>
|
|
@ -10,7 +10,7 @@
|
||||||
automatically configure network interfaces. However, you can configure an
|
automatically configure network interfaces. However, you can configure an
|
||||||
interface manually as follows:
|
interface manually as follows:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-networking.interfaces._name__.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
|
<link linkend="opt-networking.interfaces._name_.ipv4.addresses">networking.interfaces.eth0.ipv4.addresses</link> = [ {
|
||||||
address = "192.168.1.2";
|
address = "192.168.1.2";
|
||||||
prefixLength = 24;
|
prefixLength = 24;
|
||||||
} ];
|
} ];
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
As with IPv4 networking interfaces are automatically configured via DHCPv6.
|
As with IPv4 networking interfaces are automatically configured via DHCPv6.
|
||||||
You can configure an interface manually:
|
You can configure an interface manually:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-networking.interfaces._name__.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
|
<link linkend="opt-networking.interfaces._name_.ipv6.addresses">networking.interfaces.eth0.ipv6.addresses</link> = [ {
|
||||||
address = "fe00:aa:bb:cc::2";
|
address = "fe00:aa:bb:cc::2";
|
||||||
prefixLength = 64;
|
prefixLength = 64;
|
||||||
} ];
|
} ];
|
||||||
|
|
|
@ -30,7 +30,7 @@ Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
|
||||||
<filename>/</filename>, add the following to
|
<filename>/</filename>, add the following to
|
||||||
<filename>configuration.nix</filename>:
|
<filename>configuration.nix</filename>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
<link linkend="opt-boot.initrd.luks.devices._name_.device">boot.initrd.luks.devices.crypted.device</link> = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
|
||||||
<xref linkend="opt-fileSystems"/>."/".device = "/dev/mapper/crypted";
|
<xref linkend="opt-fileSystems"/>."/".device = "/dev/mapper/crypted";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Should grub be used as bootloader, and <filename>/boot</filename> is located
|
Should grub be used as bootloader, and <filename>/boot</filename> is located
|
||||||
|
@ -60,13 +60,13 @@ Added to key to device /dev/sda2, slot: 2
|
||||||
To ensure that this file system is decrypted using the FIDO2 compatible key, add the following to <filename>configuration.nix</filename>:
|
To ensure that this file system is decrypted using the FIDO2 compatible key, add the following to <filename>configuration.nix</filename>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.fido2Support">boot.initrd.luks.fido2Support</link> = true;
|
<link linkend="opt-boot.initrd.luks.fido2Support">boot.initrd.luks.fido2Support</link> = true;
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
|
<link linkend="opt-boot.initrd.luks.devices._name_.fido2.credential">boot.initrd.luks.devices."/dev/sda2".fido2.credential</link> = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
You can also use the FIDO2 passwordless setup, but for security reasons, you might want to enable it only when your device is PIN protected, such as <link xlink:href="https://trezor.io/">Trezor</link>.
|
You can also use the FIDO2 passwordless setup, but for security reasons, you might want to enable it only when your device is PIN protected, such as <link xlink:href="https://trezor.io/">Trezor</link>.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-boot.initrd.luks.devices._name__.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
|
<link linkend="opt-boot.initrd.luks.devices._name_.fido2.passwordLess">boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess</link> = true;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
All users that should have permission to change network settings must belong
|
All users that should have permission to change network settings must belong
|
||||||
to the <code>networkmanager</code> group:
|
to the <code>networkmanager</code> group:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
|
<link linkend="opt-users.users._name_.extraGroups">users.users.alice.extraGroups</link> = [ "networkmanager" ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
This profile just enables a <systemitem class="username">demo</systemitem>
|
This profile just enables a <systemitem class="username">demo</systemitem>
|
||||||
user, with password <literal>demo</literal>, uid <literal>1000</literal>,
|
user, with password <literal>demo</literal>, uid <literal>1000</literal>,
|
||||||
<systemitem class="groupname">wheel</systemitem> group and
|
<systemitem class="groupname">wheel</systemitem> group and
|
||||||
<link linkend="opt-services.xserver.displayManager.sddm.autoLogin"> autologin
|
<link linkend="opt-services.xserver.displayManager.autoLogin">autologin in the SDDM display manager</link>.
|
||||||
in the SDDM display manager</link>.
|
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
follows:
|
follows:
|
||||||
<!-- FIXME: this might not work if the user is unmanaged. -->
|
<!-- FIXME: this might not work if the user is unmanaged. -->
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">users.users.alice.openssh.authorizedKeys.keys</link> =
|
||||||
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
that a user account named <literal>alice</literal> shall exist:
|
that a user account named <literal>alice</literal> shall exist:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<xref linkend="opt-users.users"/>.alice = {
|
<xref linkend="opt-users.users"/>.alice = {
|
||||||
<link linkend="opt-users.users._name__.isNormalUser">isNormalUser</link> = true;
|
<link linkend="opt-users.users._name_.isNormalUser">isNormalUser</link> = true;
|
||||||
<link linkend="opt-users.users._name__.home">home</link> = "/home/alice";
|
<link linkend="opt-users.users._name_.home">home</link> = "/home/alice";
|
||||||
<link linkend="opt-users.users._name__.description">description</link> = "Alice Foobar";
|
<link linkend="opt-users.users._name_.description">description</link> = "Alice Foobar";
|
||||||
<link linkend="opt-users.users._name__.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
|
<link linkend="opt-users.users._name_.extraGroups">extraGroups</link> = [ "wheel" "networkmanager" ];
|
||||||
<link linkend="opt-users.users._name__.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
<link linkend="opt-users.users._name_.openssh.authorizedKeys.keys">openssh.authorizedKeys.keys</link> = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Note that <literal>alice</literal> is a member of the
|
Note that <literal>alice</literal> is a member of the
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
account will cease to exist. Also, imperative commands for managing users and
|
account will cease to exist. Also, imperative commands for managing users and
|
||||||
groups, such as useradd, are no longer available. Passwords may still be
|
groups, such as useradd, are no longer available. Passwords may still be
|
||||||
assigned by setting the user's
|
assigned by setting the user's
|
||||||
<link linkend="opt-users.users._name__.hashedPassword">hashedPassword</link>
|
<link linkend="opt-users.users._name_.hashedPassword">hashedPassword</link>
|
||||||
option. A hashed password can be generated using <command>mkpasswd -m
|
option. A hashed password can be generated using <command>mkpasswd -m
|
||||||
sha-512</command> after installing the <literal>mkpasswd</literal> package.
|
sha-512</command> after installing the <literal>mkpasswd</literal> package.
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -90,10 +90,9 @@
|
||||||
using lightdm for a user <literal>alice</literal>:
|
using lightdm for a user <literal>alice</literal>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
|
<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
|
||||||
<xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin.enable"/> = true;
|
<xref linkend="opt-services.xserver.displayManager.autoLogin.enable"/> = true;
|
||||||
<xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin.user"/> = "alice";
|
<xref linkend="opt-services.xserver.displayManager.autoLogin.user"/> = "alice";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The options are named identically for all other display managers.
|
|
||||||
</para>
|
</para>
|
||||||
</simplesect>
|
</simplesect>
|
||||||
<simplesect xml:id="sec-x11--graphics-cards-intel">
|
<simplesect xml:id="sec-x11--graphics-cards-intel">
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-freeform-modules">
|
||||||
|
<title>Freeform modules</title>
|
||||||
|
<para>
|
||||||
|
Freeform modules allow you to define values for option paths that have not been declared explicitly. This can be used to add attribute-specific types to what would otherwise have to be <literal>attrsOf</literal> options in order to accept all attribute names.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This feature can be enabled by using the attribute <literal>freeformType</literal> to define a freeform type. By doing this, all assignments without an associated option will be merged using the freeform type and combined into the resulting <literal>config</literal> set. Since this feature nullifies name checking for entire option trees, it is only recommended for use in submodules.
|
||||||
|
</para>
|
||||||
|
<example xml:id="ex-freeform-module">
|
||||||
|
<title>Freeform submodule</title>
|
||||||
|
<para>
|
||||||
|
The following shows a submodule assigning a freeform type that allows arbitrary attributes with <literal>str</literal> values below <literal>settings</literal>, but also declares an option for the <literal>settings.port</literal> attribute to have it type-checked and assign a default value. See <xref linkend="ex-settings-typed-attrs"/> for a more complete example.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
{ lib, config, ... }: {
|
||||||
|
|
||||||
|
options.settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
|
||||||
|
freeformType = with lib.types; attrsOf str;
|
||||||
|
|
||||||
|
# We want this attribute to be checked for the correct type
|
||||||
|
options.port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
# Declaring the option also allows defining a default value
|
||||||
|
default = 8080;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
And the following shows what such a module then allows
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
{
|
||||||
|
# Not a declared option, but the freeform type allows this
|
||||||
|
settings.logLevel = "debug";
|
||||||
|
|
||||||
|
# Not allowed because the the freeform type only allows strings
|
||||||
|
# settings.enable = true;
|
||||||
|
|
||||||
|
# Allowed because there is a port option declared
|
||||||
|
settings.port = 80;
|
||||||
|
|
||||||
|
# Not allowed because the port option doesn't allow strings
|
||||||
|
# settings.port = "443";
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Freeform attributes cannot depend on other attributes of the same set without infinite recursion:
|
||||||
|
<programlisting>
|
||||||
|
{
|
||||||
|
# This throws infinite recursion encountered
|
||||||
|
settings.logLevel = lib.mkIf (config.settings.port == 80) "debug";
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
To prevent this, declare options for all attributes that need to depend on others. For above example this means to declare <literal>logLevel</literal> to be an option.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</section>
|
|
@ -385,17 +385,6 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.loaOf</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An attribute set or a list of <replaceable>t</replaceable> type. Multiple
|
|
||||||
definitions are merged according to the value.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<varname>types.nullOr</varname> <replaceable>t</replaceable>
|
<varname>types.nullOr</varname> <replaceable>t</replaceable>
|
||||||
|
|
|
@ -8,24 +8,26 @@
|
||||||
<title>Release process</title>
|
<title>Release process</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Going through an example of releasing NixOS 17.09:
|
Going through an example of releasing NixOS 19.09:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section xml:id="one-month-before-the-beta">
|
<section xml:id="one-month-before-the-beta">
|
||||||
<title>One month before the beta</title>
|
<title>One month before the beta</title>
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Send an email to the nix-devel mailinglist as a warning about upcoming
|
Create an announcement on <link xlink:href="https://discourse.nixos.org">Discourse</link> as a warning about upcoming beta <quote>feature freeze</quote> in a month. <link xlink:href="https://discourse.nixos.org/t/nixos-19-09-feature-freeze/3707">See this post as an example</link>.
|
||||||
beta "feature freeze" in a month.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Discuss with Eelco Dolstra and the community (via IRC, ML) about what
|
Discuss with Eelco Dolstra and the community (via IRC, ML) about what will reach the deadline. Any issue or Pull Request targeting the release should be included in the release milestone.
|
||||||
will reach the deadline. Any issue or Pull Request targeting the release
|
</para>
|
||||||
should be included in the release milestone.
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Remove attributes that we know we will not be able to support, especially if there is a stable alternative. E.g. Check that our Linux kernels’ <link xlink:href="https://www.kernel.org/category/releases.html">projected end-of-life</link> are after our release projected end-of-life.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
@ -34,113 +36,113 @@
|
||||||
<section xml:id="at-beta-release-time">
|
<section xml:id="at-beta-release-time">
|
||||||
<title>At beta release time</title>
|
<title>At beta release time</title>
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create
|
From the master branch run:
|
||||||
an issue for tracking Zero Hydra Failures progress. ZHF is an effort to
|
</para>
|
||||||
get build failures down to zero.</link>
|
<programlisting>
|
||||||
|
git checkout -b release-19.09
|
||||||
|
</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/10e61bf5be57736035ec7a804cb0bf3d083bf2cf#diff-9c798092bac0caeb5c52d509be0ca263R69">Bump the <literal>system.defaultChannel</literal> attribute in <literal>nixos/modules/misc/version.nix</literal></link>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>git tag -a -s -m "Release 17.09-beta" 17.09-beta
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/10e61bf5be57736035ec7a804cb0bf3d083bf2cf#diff-831e8d9748240fb23e6734fdc2a6d16eR15">Update <literal>versionSuffix</literal> in <literal>nixos/release.nix</literal></link>
|
||||||
&& git push origin 17.09-beta</literal>
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To get the commit count, use the following command:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
git rev-list --count release-19.09
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
From the master branch run <literal>git checkout -b
|
Edit changelog at <literal>nixos/doc/manual/release-notes/rl-1909.xml</literal>.
|
||||||
release-17.09</literal>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
<itemizedlist>
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixos-org-configurations/pull/18">
|
|
||||||
Make sure a channel is created at https://nixos.org/channels/. </link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/compare/bdf161ed8d21...6b63c4616790">
|
|
||||||
Bump the <literal>system.defaultChannel</literal> attribute in
|
|
||||||
<literal>nixos/modules/misc/version.nix</literal> </link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/d6b08acd1ccac0d9d502c4b635e00b04d3387f06">
|
|
||||||
Update <literal>versionSuffix</literal> in
|
|
||||||
<literal>nixos/release.nix</literal></link>, use
|
|
||||||
<literal>git rev-list --count 17.09-beta</literal>
|
|
||||||
to get the commit count.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>echo -n "18.03" > .version</literal> on master.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/b8a4095003e27659092892a4708bb3698231a842">
|
|
||||||
Pick a new name for the unstable branch. </link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Create a new release notes file for the upcoming release + 1, in this
|
|
||||||
case <literal>rl-1803.xml</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Create two Hydra jobsets: release-17.09 and release-17.09-small with
|
|
||||||
<literal>stableBranch</literal> set to false.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Remove attributes that we know we will not be able to support,
|
|
||||||
especially if there is a stable alternative. E.g. Check that our
|
|
||||||
Linux kernels'
|
|
||||||
<link xlink:href="https://www.kernel.org/category/releases.html">
|
|
||||||
projected end-of-life</link> are after our release projected
|
|
||||||
end-of-life
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Edit changelog at
|
|
||||||
<literal>nixos/doc/manual/release-notes/rl-1709.xml</literal> (double
|
|
||||||
check desktop versions are noted)
|
|
||||||
</para>
|
|
||||||
<itemizedlist spacing="compact">
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Get all new NixOS modules <literal>git diff
|
Get all new NixOS modules:
|
||||||
release-17.03..release-17.09 nixos/modules/module-list.nix|grep
|
|
||||||
^+</literal>
|
|
||||||
</para>
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
git diff release-19.03..release-19.09 nixos/modules/module-list.nix | grep ^+
|
||||||
|
</programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Note systemd, kernel, glibc and Nix upgrades.
|
Note systemd, kernel, glibc, desktop environment, and Nix upgrades.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Tag the release:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
git tag --annotate --message="Release 19.09-beta" 19.09-beta
|
||||||
|
git push upstream 19.09-beta
|
||||||
|
</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-2bc0e46110b507d6d5a344264ef15adaR1">On the <literal>master</literal> branch, increment the <literal>.version</literal> file</link>
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
echo -n "20.03" > .version
|
||||||
|
</programlisting>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-03f3d41b68f62079c55001f1a1c55c1dR137">Update <literal>codeName</literal> in <literal>lib/trivial.nix</literal></link> This will be the name for the next release.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/01268fda85b7eee4e462c873d8654f975067731f#diff-e7ee5ff686cdcc513ca089d6e5682587R11">Create a new release notes file for the upcoming release + 1</link>, in our case this is <literal>rl-2003.xml</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Contact the infrastructure team to create the necessary Hydra Jobsets.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-org-configurations/blob/master/channels.nix">Create a channel at https://nixos.org/channels by creating a PR to nixos-org-configurations, changing <literal>channels.nix</literal></link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Get all Hydra jobsets for the release to have their first evaluation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create an issue for tracking Zero Hydra Failures progress. ZHF is an effort to get build failures down to zero.</link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="during-beta">
|
<section xml:id="during-beta">
|
||||||
<title>During Beta</title>
|
<title>During Beta</title>
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Monitor the master branch for bugfixes and minor updates and cherry-pick
|
Monitor the master branch for bugfixes and minor updates and cherry-pick them to the release branch.
|
||||||
them to the release branch.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
@ -149,7 +151,7 @@
|
||||||
<section xml:id="before-the-final-release">
|
<section xml:id="before-the-final-release">
|
||||||
<title>Before the final release</title>
|
<title>Before the final release</title>
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Re-check that the release notes are complete.
|
Re-check that the release notes are complete.
|
||||||
|
@ -157,21 +159,17 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Release Nix (currently only Eelco Dolstra can do that).
|
Release Nix (currently only Eelco Dolstra can do that). <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/tools/nix-fallback-paths.nix">Make sure fallback is updated.</link>
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/tools/nix-fallback-paths.nix">
|
|
||||||
Make sure fallback is updated. </link>
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/40fd9ae3ac8048758abdcfc7d28a78b5f22fe97e">
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/40fd9ae3ac8048758abdcfc7d28a78b5f22fe97e">Update README.md with new stable NixOS version information.</link>
|
||||||
Update README.md with new stable NixOS version information. </link>
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Change <literal>stableBranch</literal> to <literal>true</literal> in Hydra and wait for
|
Change <literal>stableBranch</literal> to <literal>true</literal> in Hydra and wait for the channel to update.
|
||||||
the channel to update.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
@ -180,76 +178,143 @@
|
||||||
<section xml:id="at-final-release-time">
|
<section xml:id="at-final-release-time">
|
||||||
<title>At final release time</title>
|
<title>At final release time</title>
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>git tag -s -a -m "Release 15.09" 15.09</literal>
|
Update <xref linkend="sec-upgrading" /> section of the manual to match new stable release version.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Update "Chapter 4. Upgrading NixOS" section of the manual to match
|
Update <literal>rl-1909.xml</literal> with the release date.
|
||||||
new stable release version.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Update the
|
Tag the final release
|
||||||
<link xlink:href="https://github.com/NixOS/nixos-homepage/commit/2a37975d5a617ecdfca94696242b6f32ffcba9f1"><code>NIXOS_SERIES</code></link>
|
|
||||||
in the
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixos-homepage">nixos-homepage</link>
|
|
||||||
repository.
|
|
||||||
</para>
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
git tag --annotate --message="Release 19.09" 19.09
|
||||||
|
git push upstream 19.09
|
||||||
|
</programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Get number of commits for the release: <literal>git log
|
Update <link xlink:href="https://github.com/NixOS/nixos-homepage">nixos-homepage</link> for the release.
|
||||||
release-14.04..release-14.12 --format=%an|wc -l</literal>
|
|
||||||
</para>
|
</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/Makefile#L1">Update <literal>NIXOS_SERIES</literal> in the <literal>Makefile</literal></link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/nixos-release.tt#L1">Update <literal>nixos-release.tt</literal> with the new NixOS version</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/blob/47ac3571c4d71e841fd4e6c6e1872e762b9c4942/flake.nix#L10">Update the <literal>flake.nix</literal> input <literal>released-nixpkgs</literal> to 19.09</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Run <literal>./update.sh</literal> (this updates flake.lock to updated channel).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/blob/a5626c71c03a2dd69086564e56f1a230a2bb177a/logo/nixos-logo-19.09-loris-lores.png">Add a compressed version of the NixOS logo for 19.09</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-homepage/commit/a5626c71c03a2dd69086564e56f1a230a2bb177a#diff-9cdc6434d3e4fd93a6e5bb0a531a7c71R5">Compose a news item for the website RSS feed</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Commits by contributor: <literal>git log release-14.04..release-14.12
|
Create a new topic on <link xlink:href="https://discourse.nixos.org/">the Discourse instance</link> to announce the release.
|
||||||
--format=%an|sort|uniq -c|sort -rn</literal>
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You should include the following information:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Number of commits for the release:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
bash git log release-19.03..release-19.09 --format=%an | wc -l
|
||||||
|
</programlisting>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Create a new topic on <link xlink:href="https://discourse.nixos.org/">the
|
Commits by contributor:
|
||||||
Discourse instance</link> to announce the release with the above information.
|
|
||||||
Best to check how previous email was formulated to see what needs to be
|
|
||||||
included.
|
|
||||||
</para>
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
git shortlog --summary --numbered release-19.03..release-19.09
|
||||||
|
</programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Best to check how the previous post was formulated to see what needs to be included.
|
||||||
|
</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="release-managers">
|
<section xml:id="release-management-team">
|
||||||
<title>Release Management Team</title>
|
<title>Release Management Team</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
For each release there are two release managers. After each release the
|
For each release there are two release managers. After each release the release manager having managed two releases steps down and the release management team of the last release appoints a new release manager.
|
||||||
release manager having managed two releases steps down and the release
|
|
||||||
management team of the last release appoints a new release manager.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This makes sure a release management team always consists of one release
|
This makes sure a release management team always consists of one release manager who already has managed one release and one release manager being introduced to their role, making it easier to pass on knowledge and experience.
|
||||||
manager who already has managed one release and one release manager being
|
|
||||||
introduced to their role, making it easier to pass on knowledge and
|
|
||||||
experience.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Release managers for the current NixOS release are tracked by GitHub team
|
Release managers for the current NixOS release are tracked by GitHub team <link xlink:href="https://github.com/orgs/NixOS/teams/nixos-release-managers/members"><literal>@NixOS/nixos-release-managers</literal></link>.
|
||||||
<link xlink:href="https://github.com/orgs/NixOS/teams/nixos-release-managers/members"><literal>@NixOS/nixos-release-managers</literal></link>.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A release manager's role and responsibilities are:
|
A release manager’s role and responsibilities are:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>manage the release process</para></listitem>
|
<listitem>
|
||||||
<listitem><para>start discussions about features and changes for a given release</para></listitem>
|
<para>
|
||||||
<listitem><para>create a roadmap</para></listitem>
|
manage the release process
|
||||||
<listitem><para>release in cooperation with Eelco Dolstra</para></listitem>
|
</para>
|
||||||
<listitem><para>decide which bug fixes, features, etc... get backported after a release</para></listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
start discussions about features and changes for a given release
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
create a roadmap
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
release in cooperation with Eelco Dolstra
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
decide which bug fixes, features, etc… get backported after a release
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="release-schedule">
|
<section xml:id="release-schedule">
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-settings-options">
|
||||||
|
<title>Options for Program Settings</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Many programs have configuration files where program-specific settings can be declared. File formats can be separated into two categories:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Nix-representable ones: These can trivially be mapped to a subset of Nix syntax. E.g. JSON is an example, since its values like <literal>{"foo":{"bar":10}}</literal> can be mapped directly to Nix: <literal>{ foo = { bar = 10; }; }</literal>. Other examples are INI, YAML and TOML. The following section explains the convention for these settings.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Non-nix-representable ones: These can't be trivially mapped to a subset of Nix syntax. Most generic programming languages are in this group, e.g. bash, since the statement <literal>if true; then echo hi; fi</literal> doesn't have a trivial representation in Nix.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Currently there are no fixed conventions for these, but it is common to have a <literal>configFile</literal> option for setting the configuration file path directly. The default value of <literal>configFile</literal> can be an auto-generated file, with convenient options for controlling the contents. For example an option of type <literal>attrsOf str</literal> can be used for representing environment variables which generates a section like <literal>export FOO="foo"</literal>. Often it can also be useful to also include an <literal>extraConfig</literal> option of type <literal>lines</literal> to allow arbitrary text after the autogenerated part of the file.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
<section xml:id="sec-settings-nix-representable">
|
||||||
|
<title>Nix-representable Formats (JSON, YAML, TOML, INI, ...)</title>
|
||||||
|
<para>
|
||||||
|
By convention, formats like this are handled with a generic <literal>settings</literal> option, representing the full program configuration as a Nix value. The type of this option should represent the format. The most common formats have a predefined type and string generator already declared under <literal>pkgs.formats</literal>:
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>pkgs.formats.json</varname> { }
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A function taking an empty attribute set (for future extensibility) and returning a set with JSON-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>pkgs.formats.yaml</varname> { }
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A function taking an empty attribute set (for future extensibility) and returning a set with YAML-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>pkgs.formats.ini</varname> { <replaceable>listsAsDuplicateKeys</replaceable> ? false, ... }
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A function taking an attribute set with values
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>listsAsDuplicateKeys</varname>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A boolean for controlling whether list values can be used to represent duplicate INI keys
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
It returns a set with INI-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>pkgs.formats.toml</varname> { }
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A function taking an empty attribute set (for future extensibility) and returning a set with TOML-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
<para xml:id="pkgs-formats-result">
|
||||||
|
These functions all return an attribute set with these values:
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>type</varname>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A module system type representing a value of the format
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>generate</varname> <replaceable>filename</replaceable> <replaceable>jsonValue</replaceable>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A function that can render a value of the format to a file. Returns a file path.
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
This function puts the value contents in the Nix store. So this should be avoided for secrets.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
<example xml:id="ex-settings-nix-representable">
|
||||||
|
<title>Module with conventional <literal>settings</literal> option</title>
|
||||||
|
<para>
|
||||||
|
The following shows a module for an example program that uses a JSON configuration file. It demonstrates how above values can be used, along with some other related best practices. See the comments for explanations.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
{ options, config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.services.foo;
|
||||||
|
# Define the settings format used for this program
|
||||||
|
settingsFormat = pkgs.formats.json {};
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.foo = {
|
||||||
|
enable = lib.mkEnableOption "foo service";
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
# Setting this type allows for correct merging behavior
|
||||||
|
type = settingsFormat.type;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Configuration for foo, see
|
||||||
|
<link xlink:href="https://example.com/docs/foo"/>
|
||||||
|
for supported settings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# We can assign some default settings here to make the service work by just
|
||||||
|
# enabling it. We use `mkDefault` for values that can be changed without
|
||||||
|
# problems
|
||||||
|
services.foo.settings = {
|
||||||
|
# Fails at runtime without any value set
|
||||||
|
log_level = lib.mkDefault "WARN";
|
||||||
|
|
||||||
|
# We assume systemd's `StateDirectory` is used, so we require this value,
|
||||||
|
# therefore no mkDefault
|
||||||
|
data_path = "/var/lib/foo";
|
||||||
|
|
||||||
|
# Since we use this to create a user we need to know the default value at
|
||||||
|
# eval time
|
||||||
|
user = lib.mkDefault "foo";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."foo.json".source =
|
||||||
|
# The formats generator function takes a filename and the Nix value
|
||||||
|
# representing the format value and produces a filepath with that value
|
||||||
|
# rendered in the format
|
||||||
|
settingsFormat.generate "foo-config.json" cfg.settings;
|
||||||
|
|
||||||
|
# We know that the `user` attribute exists because we set a default value
|
||||||
|
# for it above, allowing us to use it without worries here
|
||||||
|
users.users.${cfg.settings.user} = {};
|
||||||
|
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
<section xml:id="sec-settings-attrs-options">
|
||||||
|
<title>Option declarations for attributes</title>
|
||||||
|
<para>
|
||||||
|
Some <literal>settings</literal> attributes may deserve some extra care. They may need a different type, default or merging behavior, or they are essential options that should show their documentation in the manual. This can be done using <xref linkend='sec-freeform-modules'/>.
|
||||||
|
<example xml:id="ex-settings-typed-attrs">
|
||||||
|
<title>Declaring a type-checked <literal>settings</literal> attribute</title>
|
||||||
|
<para>
|
||||||
|
We extend above example using freeform modules to declare an option for the port, which will enforce it to be a valid integer and make it show up in the manual.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
# Declare an option for the port such that the type is checked and this option
|
||||||
|
# is shown in the manual.
|
||||||
|
options.port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 8080;
|
||||||
|
description = ''
|
||||||
|
Which port this service should listen on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Configuration for Foo, see
|
||||||
|
<link xlink:href="https://example.com/docs/foo"/>
|
||||||
|
for supported values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
|
@ -183,4 +183,6 @@ in {
|
||||||
<xi:include href="meta-attributes.xml" />
|
<xi:include href="meta-attributes.xml" />
|
||||||
<xi:include href="importing-modules.xml" />
|
<xi:include href="importing-modules.xml" />
|
||||||
<xi:include href="replace-modules.xml" />
|
<xi:include href="replace-modules.xml" />
|
||||||
|
<xi:include href="freeform-modules.xml" />
|
||||||
|
<xi:include href="settings-options.xml" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -216,12 +216,12 @@ start_all()
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<methodname>send_keys</methodname>
|
<methodname>send_key</methodname>
|
||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Simulate pressing keys on the virtual keyboard, e.g.,
|
Simulate pressing keys on the virtual keyboard, e.g.,
|
||||||
<literal>send_keys("ctrl-alt-delete")</literal>.
|
<literal>send_key("ctrl-alt-delete")</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -232,7 +232,7 @@ start_all()
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Simulate typing a sequence of characters on the virtual keyboard, e.g.,
|
Simulate typing a sequence of characters on the virtual keyboard, e.g.,
|
||||||
<literal>send_keys("foobar\n")</literal> will type the string
|
<literal>send_chars("foobar\n")</literal> will type the string
|
||||||
<literal>foobar</literal> followed by the Enter key.
|
<literal>foobar</literal> followed by the Enter key.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -390,7 +390,7 @@ start_all()
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Copies a file from host to machine, e.g.,
|
Copies a file from host to machine, e.g.,
|
||||||
<literal>copy_file_from_host("myfile", "/etc/my/important/file")</literal>.
|
<literal>copy_from_host("myfile", "/etc/my/important/file")</literal>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The first argument is the file on the host. The file needs to be
|
The first argument is the file on the host. The file needs to be
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
<literal>mutableUsers = false</literal>. Another way is to temporarily add
|
<literal>mutableUsers = false</literal>. Another way is to temporarily add
|
||||||
the following to your configuration:
|
the following to your configuration:
|
||||||
<screen>
|
<screen>
|
||||||
<link linkend="opt-users.users._name__.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
|
<link linkend="opt-users.users._name_.initialHashedPassword">users.users.your-user.initialHashedPassword</link> = "test";
|
||||||
</screen>
|
</screen>
|
||||||
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
|
<emphasis>Important:</emphasis> delete the $hostname.qcow2 file if you have
|
||||||
started the virtual machine at least once without the right users, otherwise
|
started the virtual machine at least once without the right users, otherwise
|
||||||
|
|
|
@ -211,7 +211,7 @@ nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
|
||||||
use <literal>sudo</literal>)
|
use <literal>sudo</literal>)
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link linkend="opt-users.users._name__.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
|
<link linkend="opt-users.users._name_.initialHashedPassword">users.users.root.initialHashedPassword</link> = "";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
nix-build -A netboot nixos/release.nix
|
nix-build -A netboot.x86_64-linux nixos/release.nix
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Click on Settings / Display / Screen and select VBoxVGA as Graphics Controller
|
Click on Settings / Display / Screen and select VMSVGA as Graphics Controller
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If the text is too small to be legible, try <command>setfont ter-132n</command>
|
If the text is too small to be legible, try <command>setfont ter-v32n</command>
|
||||||
to increase the font size.
|
to increase the font size.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -550,7 +550,7 @@ Retype new UNIX password: ***</screen>
|
||||||
# Note: setting fileSystems is generally not
|
# Note: setting fileSystems is generally not
|
||||||
# necessary, since nixos-generate-config figures them out
|
# necessary, since nixos-generate-config figures them out
|
||||||
# automatically in hardware-configuration.nix.
|
# automatically in hardware-configuration.nix.
|
||||||
#<link linkend="opt-fileSystems._name__.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
|
#<link linkend="opt-fileSystems._name_.device">fileSystems."/".device</link> = "/dev/disk/by-label/nixos";
|
||||||
|
|
||||||
# Enable the OpenSSH server.
|
# Enable the OpenSSH server.
|
||||||
services.sshd.enable = true;
|
services.sshd.enable = true;
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>nixos-build-vms</command>
|
<command>nixos-build-vms</command>
|
||||||
<arg>
|
<arg>
|
||||||
<option>--show-trace</option>
|
<option>--show-trace</option>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<option>--no-out-link</option>
|
<option>--no-out-link</option>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<option>--help</option>
|
<option>--help</option>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
|
@ -13,21 +13,21 @@
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>nixos-enter</command>
|
<command>nixos-enter</command>
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>--root</option>
|
<option>--root</option>
|
||||||
</arg>
|
</arg>
|
||||||
<replaceable>root</replaceable>
|
<replaceable>root</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>--system</option>
|
<option>--system</option>
|
||||||
</arg>
|
</arg>
|
||||||
<replaceable>system</replaceable>
|
<replaceable>system</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>-c</option>
|
<option>-c</option>
|
||||||
|
@ -40,13 +40,13 @@
|
||||||
<option>--silent</option>
|
<option>--silent</option>
|
||||||
</arg>
|
</arg>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>--help</option>
|
<option>--help</option>
|
||||||
</arg>
|
</arg>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>--</option>
|
<option>--</option>
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
<filename>/mnt</filename>:
|
<filename>/mnt</filename>:
|
||||||
</para>
|
</para>
|
||||||
<screen>
|
<screen>
|
||||||
# nixos-enter /mnt
|
# nixos-enter --root /mnt
|
||||||
</screen>
|
</screen>
|
||||||
<para>
|
<para>
|
||||||
Run a shell command:
|
Run a shell command:
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
<replaceable>path</replaceable>
|
<replaceable>path</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<option>--flake</option> <replaceable>flake-uri</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'>
|
<arg choice='plain'>
|
||||||
<option>--channel</option>
|
<option>--channel</option>
|
||||||
|
@ -199,6 +203,18 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--flake</option> <replaceable>flake-uri</replaceable>#<replaceable>name</replaceable>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Build the NixOS system from the specified flake.
|
||||||
|
The flake must contain an output named
|
||||||
|
<literal>nixosConfigurations.<replaceable>name</replaceable></literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>--channel</option>
|
<option>--channel</option>
|
||||||
|
|
|
@ -315,7 +315,7 @@
|
||||||
switch</command>), because the hardware and boot loader configuration in
|
switch</command>), because the hardware and boot loader configuration in
|
||||||
the VM are different. The boot loader is installed on an automatically
|
the VM are different. The boot loader is installed on an automatically
|
||||||
generated virtual disk containing a <filename>/boot</filename>
|
generated virtual disk containing a <filename>/boot</filename>
|
||||||
partition, which is mounted read-only in the VM.
|
partition.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -521,7 +521,7 @@
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>--flake</option> <replaceable>flake-uri</replaceable>[<replaceable>name</replaceable>]
|
<option>--flake</option> <replaceable>flake-uri</replaceable><optional>#<replaceable>name</replaceable></optional>
|
||||||
</term>
|
</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -792,11 +792,11 @@ users.users.me =
|
||||||
The <option>services.xserver.displayManager.auto</option> module has been removed.
|
The <option>services.xserver.displayManager.auto</option> module has been removed.
|
||||||
It was only intended for use in internal NixOS tests, and gave the false impression
|
It was only intended for use in internal NixOS tests, and gave the false impression
|
||||||
of it being a special display manager when it's actually LightDM.
|
of it being a special display manager when it's actually LightDM.
|
||||||
Please use the <xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin"/> options instead,
|
Please use the <option>services.xserver.displayManager.lightdm.autoLogin</option> options instead,
|
||||||
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
|
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
|
||||||
because it permitted root auto-login you can override the lightdm-autologin pam module like:
|
because it permitted root auto-login you can override the lightdm-autologin pam module like:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<link xlink:href="#opt-security.pam.services._name__.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
|
<link xlink:href="#opt-security.pam.services._name_.text">security.pam.services.lightdm-autologin.text</link> = lib.mkForce ''
|
||||||
auth requisite pam_nologin.so
|
auth requisite pam_nologin.so
|
||||||
auth required pam_succeed_if.so quiet
|
auth required pam_succeed_if.so quiet
|
||||||
auth required pam_permit.so
|
auth required pam_permit.so
|
||||||
|
|
|
@ -42,6 +42,11 @@
|
||||||
PHP now defaults to PHP 7.4, updated from 7.3.
|
PHP now defaults to PHP 7.4, updated from 7.3.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
PHP 7.2 is no longer supported due to upstream not supporting this version for the entire lifecycle of the 20.09 release.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Python 3 now defaults to Python 3.8 instead of 3.7.
|
Python 3 now defaults to Python 3.8 instead of 3.7.
|
||||||
|
@ -109,16 +114,106 @@ systemd.services.mysql.serviceConfig.ProtectHome = lib.mkForce "read-only";
|
||||||
systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
The MySQL service no longer runs its <literal>systemd</literal> service startup script as <literal>root</literal> anymore. A dedicated non <literal>root</literal>
|
||||||
|
super user account is required for operation. This means users with an existing MySQL or MariaDB database server are required to run the following SQL statements
|
||||||
|
as a super admin user before upgrading:
|
||||||
|
<programlisting>
|
||||||
|
CREATE USER IF NOT EXISTS 'mysql'@'localhost' identified with unix_socket;
|
||||||
|
GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;
|
||||||
|
</programlisting>
|
||||||
|
If you use MySQL instead of MariaDB please replace <literal>unix_socket</literal> with <literal>auth_socket</literal>. If you have changed the value of <xref linkend="opt-services.mysql.user"/>
|
||||||
|
from the default of <literal>mysql</literal> to a different user please change <literal>'mysql'@'localhost'</literal> to the corresponding user instead.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Two new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link>
|
The new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link>
|
||||||
has been added to automatically generate the <literal>man-db</literal> caches, which are needed by utilities
|
has been added to automatically generate the <literal>man-db</literal> caches, which are needed by utilities
|
||||||
like <command>whatis</command> and <command>apropos</command>. The caches are generated during the build of
|
like <command>whatis</command> and <command>apropos</command>. The caches are generated during the build of
|
||||||
the NixOS configuration: since this can be expensive when a large number of packages are installed, the
|
the NixOS configuration: since this can be expensive when a large number of packages are installed, the
|
||||||
feature is disabled by default.
|
feature is disabled by default.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<varname>services.postfix.sslCACert</varname> was replaced by <varname>services.postfix.tlsTrustedAuthorities</varname> which now defaults to system certificate authorities.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Subordinate GID and UID mappings are now set up automatically for all normal users.
|
||||||
|
This will make container tools like Podman work as non-root users out of the box.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The various documented workarounds to use steam have been converted to a module. <varname>programs.steam.enable</varname> enables steam, controller support and the workarounds.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Support for built-in LCDs in various pieces of Logitech hardware (keyboards and USB speakers). <varname>hardware.logitech.lcd.enable</varname> enables support for all hardware supported by the g15daemon project.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Zabbix now defaults to 5.0, updated from 4.4. Please carefully read through
|
||||||
|
<link xlink:href="https://www.zabbix.com/documentation/current/manual/installation/upgrade/sources">the upgrade guide</link>
|
||||||
|
and apply any changes required. Be sure to take special note of the section on
|
||||||
|
<link xlink:href="https://www.zabbix.com/documentation/current/manual/installation/upgrade_notes_500#enabling_extended_range_of_numeric_float_values">enabling extended range of numeric (float) values</link>
|
||||||
|
as you will need to apply this database migration manually.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If you are using Zabbix Server with a MySQL or MariaDB database you should note that using a character set of <literal>utf8</literal> and a collate of <literal>utf8_bin</literal> has become mandatory with
|
||||||
|
this release. See the upstream <link xlink:href="https://support.zabbix.com/browse/ZBX-17357">issue</link> for further discussion. Before upgrading you should check the character set and collation used by
|
||||||
|
your database and ensure they are correct:
|
||||||
|
<programlisting>
|
||||||
|
SELECT
|
||||||
|
default_character_set_name,
|
||||||
|
default_collation_name
|
||||||
|
FROM
|
||||||
|
information_schema.schemata
|
||||||
|
WHERE
|
||||||
|
schema_name = 'zabbix';
|
||||||
|
</programlisting>
|
||||||
|
If these values are not correct you should take a backup of your database and convert the character set and collation as required. Here is an
|
||||||
|
<link xlink:href="https://www.zabbix.com/forum/zabbix-help/396573-reinstall-after-upgrade?p=396891#post396891">example</link> of how to do so, taken from
|
||||||
|
the Zabbix forums:
|
||||||
|
<programlisting>
|
||||||
|
ALTER DATABASE `zabbix` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
-- the following will produce a list of SQL commands you should subsequently execute
|
||||||
|
SELECT CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;") AS ExecuteTheString
|
||||||
|
FROM information_schema.`COLUMNS`
|
||||||
|
WHERE table_schema = "zabbix" AND COLLATION_NAME = "utf8_general_ci";
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The NixOS module system now supports freeform modules as a mix between <literal>types.attrsOf</literal> and <literal>types.submodule</literal>. These allow you to explicitly declare a subset of options while still permitting definitions without an associated option. See <xref linkend='sec-freeform-modules'/> for how to use them.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The GRUB module gained support for basic password protection, which
|
||||||
|
allows to restrict non-default entries in the boot menu to one or more
|
||||||
|
users. The users and passwords are defined via the option
|
||||||
|
<option>boot.loader.grub.users</option>.
|
||||||
|
Note: Password support is only avaiable in GRUB version 2.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Following its deprecation in 20.03, the Perl NixOS test driver has been removed.
|
||||||
|
All remaining tests have been ported to the Python test framework.
|
||||||
|
Code outside nixpkgs using <filename>make-test.nix</filename> or
|
||||||
|
<filename>testing.nix</filename> needs to be ported to
|
||||||
|
<filename>make-test-python.nix</filename> and
|
||||||
|
<filename>testing-python.nix</filename> respectively.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -138,6 +233,11 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
<para>
|
<para>
|
||||||
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
|
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://hercules-ci.com">Hercules CI</link> Agent is a specialized build agent for projects built with Nix. See the <link xlink:href="https://nixos.org/nixos/options.html#services.hercules-ci-agent">options</link> and <link xlink:href="https://docs.hercules-ci.com/hercules-ci/getting-started/#deploy-agent">setup</link>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
@ -162,12 +262,10 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
in the source tree for downloaded modules instead of using go's <link
|
in the source tree for downloaded modules instead of using go's <link
|
||||||
xlink:href="https://golang.org/cmd/go/#hdr-Module_proxy_protocol">module
|
xlink:href="https://golang.org/cmd/go/#hdr-Module_proxy_protocol">module
|
||||||
proxy protocol</link>. This storage format is simpler and therefore less
|
proxy protocol</link>. This storage format is simpler and therefore less
|
||||||
likekly to break with future versions of go. As a result
|
likely to break with future versions of go. As a result
|
||||||
<literal>buildGoModule</literal> switched from
|
<literal>buildGoModule</literal> switched from
|
||||||
<literal>modSha256</literal> to the <literal>vendorSha256</literal>
|
<literal>modSha256</literal> to the <literal>vendorSha256</literal>
|
||||||
attribute to pin fetched version data. <literal>buildGoModule</literal>
|
attribute to pin fetched version data.
|
||||||
still accepts <literal>modSha256</literal> with a warning, but support will
|
|
||||||
be removed in the next release.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -176,7 +274,7 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
<link xlink:href="https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/">deprecated in Grafana</link>
|
<link xlink:href="https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/">deprecated in Grafana</link>
|
||||||
and the <package>phantomjs</package> project is
|
and the <package>phantomjs</package> project is
|
||||||
<link xlink:href="https://github.com/ariya/phantomjs/issues/15344#issue-302015362">currently unmaintained</link>.
|
<link xlink:href="https://github.com/ariya/phantomjs/issues/15344#issue-302015362">currently unmaintained</link>.
|
||||||
It can still be enabled by providing <literal>phantomJsSupport = true</literal> to the package instanciation:
|
It can still be enabled by providing <literal>phantomJsSupport = true</literal> to the package instantiation:
|
||||||
<programlisting>{
|
<programlisting>{
|
||||||
services.grafana.package = pkgs.grafana.overrideAttrs (oldAttrs: rec {
|
services.grafana.package = pkgs.grafana.overrideAttrs (oldAttrs: rec {
|
||||||
phantomJsSupport = false;
|
phantomJsSupport = false;
|
||||||
|
@ -188,7 +286,7 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
<para>
|
<para>
|
||||||
The <link linkend="opt-services.supybot.enable">supybot</link> module now uses <literal>/var/lib/supybot</literal>
|
The <link linkend="opt-services.supybot.enable">supybot</link> module now uses <literal>/var/lib/supybot</literal>
|
||||||
as its default <link linkend="opt-services.supybot.stateDir">stateDir</link> path if <literal>stateVersion</literal>
|
as its default <link linkend="opt-services.supybot.stateDir">stateDir</link> path if <literal>stateVersion</literal>
|
||||||
is 20.09 or higher. It also enables number of
|
is 20.09 or higher. It also enables a number of
|
||||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing">systemd sandboxing options</link>
|
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing">systemd sandboxing options</link>
|
||||||
which may possibly interfere with some plugins. If this is the case you can disable the options through attributes in
|
which may possibly interfere with some plugins. If this is the case you can disable the options through attributes in
|
||||||
<option>systemd.services.supybot.serviceConfig</option>.
|
<option>systemd.services.supybot.serviceConfig</option>.
|
||||||
|
@ -296,6 +394,20 @@ php.override {
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The ACME module has been overhauled for simplicity and maintainability.
|
||||||
|
Cert generation now implicitly uses the <literal>acme</literal>
|
||||||
|
user, and the <literal>security.acme.certs._name_.user</literal> option
|
||||||
|
has been removed. Instead, certificate access from other services is now
|
||||||
|
managed through group permissions. The module no longer runs lego
|
||||||
|
twice under certain conditions, and will correctly renew certificates if
|
||||||
|
their configuration is changed. Services which reload nginx and httpd after
|
||||||
|
certificate renewal are now properly configured too so you no longer have
|
||||||
|
to do this manually if you are using HTTPS enabled virtual hosts. A mechanism
|
||||||
|
for regenerating certs on demand has also been added and documented.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Gollum received a major update to version 5.x and you may have to change
|
Gollum received a major update to version 5.x and you may have to change
|
||||||
|
@ -502,6 +614,46 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
In the <literal>resilio</literal> module, <xref linkend="opt-services.resilio.httpListenAddr"/> has been changed to listen to <literal>[::1]</literal> instead of <literal>0.0.0.0</literal>.
|
In the <literal>resilio</literal> module, <xref linkend="opt-services.resilio.httpListenAddr"/> has been changed to listen to <literal>[::1]</literal> instead of <literal>0.0.0.0</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Users of <link xlink:href="http://openafs.org">OpenAFS 1.6</link> must
|
||||||
|
upgrade their services to OpenAFS 1.8! In this release, the OpenAFS package
|
||||||
|
version 1.6.24 is marked broken but can be used during transition to
|
||||||
|
OpenAFS 1.8.x. Use the options
|
||||||
|
<option>services.openafsClient.packages.module</option>,
|
||||||
|
<option>services.openafsClient.packages.programs</option> and
|
||||||
|
<option>services.openafsServer.package</option> to select a different
|
||||||
|
OpenAFS package. OpenAFS 1.6 will be removed in the next release. The
|
||||||
|
package <literal>openafs</literal> and the service options will then
|
||||||
|
silently point to the OpenAFS 1.8 release.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
See also the OpenAFS <link
|
||||||
|
xlink:href="http://docs.openafs.org/AdminGuide/index.html">Administrator
|
||||||
|
Guide</link> for instructions. Beware of the following when updating
|
||||||
|
servers:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The storage format of the server key has changed and the key must be converted before running the new release.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When updating multiple database servers, turn off the database servers
|
||||||
|
from the highest IP down to the lowest with resting periods in
|
||||||
|
between. Start up in reverse order. Do not concurrently run database
|
||||||
|
servers working with different OpenAFS releases!
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Update servers first, then clients.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -514,6 +666,136 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
automatically if <literal>stateVersion</literal> is 20.09 or higher.
|
automatically if <literal>stateVersion</literal> is 20.09 or higher.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>udpt</literal> experienced a complete rewrite from C++ to rust. The configuration format changed from ini to toml.
|
||||||
|
The new configuration documentation can be found at
|
||||||
|
<link xlink:href="https://naim94a.github.io/udpt/config.html">the official website</link> and example
|
||||||
|
configuration is packaged in <literal>${udpt}/share/udpt/udpt.toml</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
We now have a unified <xref linkend="opt-services.xserver.displayManager.autoLogin"/> option interface
|
||||||
|
to be used for every display-manager in NixOS.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>bitcoind</literal> module has changed to multi-instance, using submodules.
|
||||||
|
Therefore, it is now mandatory to name each instance.
|
||||||
|
To use this new multi-instance config with an existing bitcoind data directory and user,
|
||||||
|
you have to adjust the original config, e.g.:
|
||||||
|
<programlisting>
|
||||||
|
services.bitcoind = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = "...";
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
To something similar:
|
||||||
|
<programlisting>
|
||||||
|
services.bitcoind.mainnet = {
|
||||||
|
enable = true;
|
||||||
|
dataDir = "/var/lib/bitcoind";
|
||||||
|
user = "bitcoin";
|
||||||
|
extraConfig = "...";
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
The key settings are:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>dataDir</literal> - to continue using the same data directory.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>user</literal> - to continue using the same user so that bitcoind maintains access to its files.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Graylog introduced a change in the LDAP server certificate validation behaviour for version 3.3.3 which might break existing setups.
|
||||||
|
When updating Graylog from a version before 3.3.3 make sure to check the Graylog <link xlink:href="https://www.graylog.org/post/announcing-graylog-v3-3-3">release info</link> for information on how to avoid the issue.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>dokuwiki</literal> module has changed to multi-instance, using submodules.
|
||||||
|
Therefore, it is now mandatory to name each instance. Moreover, forcing SSL by default has been dropped, so
|
||||||
|
<literal>nginx.forceSSL</literal> and <literal>nginx.enableACME</literal> are no longer set to <literal>true</literal>.
|
||||||
|
To continue using your service with the original SSL settings, you have to adjust the original config, e.g.:
|
||||||
|
<programlisting>
|
||||||
|
services.dokuwiki = {
|
||||||
|
enable = true;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
To something similar:
|
||||||
|
<programlisting>
|
||||||
|
services.dokuwiki."mywiki" = {
|
||||||
|
enable = true;
|
||||||
|
nginx = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
};
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
The base package has also been upgraded to the 2020-07-29 "Hogfather" release. Plugins might be incompatible or require upgrading.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <xref linkend="opt-services.postgresql.dataDir"/> option is now set to <literal>"/var/lib/postgresql/${cfg.package.psqlSchema}"</literal> regardless of your
|
||||||
|
<xref linkend="opt-system.stateVersion"/>. Users with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below
|
||||||
|
should double check what the value of their <xref linkend="opt-services.postgresql.dataDir"/> option is (<literal>/var/db/postgresql</literal>) and then explicitly
|
||||||
|
set this value to maintain compatibility:
|
||||||
|
<programlisting>
|
||||||
|
services.postgresql.dataDir = "/var/db/postgresql";
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The postgresql module now expects there to be a database super user account called <literal>postgres</literal> regardless of your <xref linkend="opt-system.stateVersion"/>. Users
|
||||||
|
with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below should run the following SQL statements as a
|
||||||
|
database super admin user before upgrading:
|
||||||
|
<programlisting>
|
||||||
|
CREATE ROLE postgres LOGIN SUPERUSER;
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The USBGuard module now removes options and instead hardcodes values for <literal>IPCAccessControlFiles</literal>, <literal>ruleFiles</literal>, and <literal>auditFilePath</literal>. Audit logs can be found in the journal.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The NixOS module system now evaluates option definitions more strictly, allowing it to detect a larger set of problems.
|
||||||
|
As a result, what previously evaluated may not do so anymore.
|
||||||
|
See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/82743#issuecomment-674520472">the PR that changed this</link> for more info.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
For NixOS configuration options, the type <literal>loaOf</literal>, after
|
||||||
|
its initial deprecation in release 20.03, has been removed. In NixOS and
|
||||||
|
Nixpkgs options using this type have been converted to <literal>attrsOf</literal>.
|
||||||
|
For more information on this change have look at these links:
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/1800">issue #1800</link>,
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/63103">PR #63103</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>config.systemd.services.${name}.path</literal> now returns a list of paths instead of a colon-separated string.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -549,6 +831,11 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
The default output of <literal>buildGoPackage</literal> is now <literal>$out</literal> instead of <literal>$bin</literal>.
|
The default output of <literal>buildGoPackage</literal> is now <literal>$out</literal> instead of <literal>$bin</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>buildGoModule</literal> <literal>doCheck</literal> now defaults to <literal>true</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Packages built using <literal>buildRustPackage</literal> now use <literal>release</literal>
|
Packages built using <literal>buildRustPackage</literal> now use <literal>release</literal>
|
||||||
|
@ -606,6 +893,37 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
was removed, as udev gained native support to handle FIDO security tokens.
|
was removed, as udev gained native support to handle FIDO security tokens.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>services.transmission</literal> module
|
||||||
|
was enhanced with the new options:
|
||||||
|
<xref linkend="opt-services.transmission.credentialsFile"/>,
|
||||||
|
<xref linkend="opt-services.transmission.openFirewall"/>,
|
||||||
|
and <xref linkend="opt-services.transmission.performanceNetParameters"/>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
<literal>transmission-daemon</literal> is now started with additional systemd sandbox/hardening options for better security.
|
||||||
|
Please <link xlink:href="https://github.com/NixOS/nixpkgs/issues">report</link>
|
||||||
|
any use case where this is not working well.
|
||||||
|
In particular, the <literal>RootDirectory</literal> option newly set
|
||||||
|
forbids uploading or downloading a torrent outside of the default directory
|
||||||
|
configured at <link linkend="opt-services.transmission.settings">settings.download-dir</link>.
|
||||||
|
If you really need Transmission to access other directories,
|
||||||
|
you must include those directories into the <literal>BindPaths</literal> of the service:
|
||||||
|
<programlisting>
|
||||||
|
systemd.services.transmission.serviceConfig.BindPaths = [ "/path/to/alternative/download-dir" ];
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Also, connection to the RPC (Remote Procedure Call) of <literal>transmission-daemon</literal>
|
||||||
|
is now only available on the local network interface by default.
|
||||||
|
Use:
|
||||||
|
<programlisting>
|
||||||
|
services.transmission.settings.rpc-bind-address = "0.0.0.0";
|
||||||
|
</programlisting>
|
||||||
|
to get the previous behavior of listening on all network interfaces.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
|
With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
|
||||||
|
@ -682,6 +1000,85 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
behaviour and keep the same VM state between different test runs.
|
behaviour and keep the same VM state between different test runs.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <link linkend="opt-nix.buildMachines">nix.buildMachines</link> option is now type-checked.
|
||||||
|
There are no functional changes, however this may require updating some configurations to use correct types for all attributes.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>fontconfig</literal> module stopped generating fontconfig 2.10.x config and cache.
|
||||||
|
Fontconfig 2.10.x was removed from Nixpkgs - it hasn't been used in any nixpkgs package anymore.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Nginx module <literal>nginxModules.fastcgi-cache-purge</literal> renamed to official name <literal>nginxModules.cache-purge</literal>.
|
||||||
|
Nginx module <literal>nginxModules.ngx_aws_auth</literal> renamed to official name <literal>nginxModules.aws-auth</literal>.
|
||||||
|
The packages <package>perl</package>, <package>rsync</package> and <package>strace</package> were removed from <option>systemPackages</option>. If you need them, install them again with <code><xref linkend="opt-environment.systemPackages"/> = with pkgs; [ perl rsync strace ];</code> in your <filename>configuration.nix</filename>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>undervolt</literal> option no longer needs to apply its
|
||||||
|
settings every 30s. If they still become undone, open an issue and restore
|
||||||
|
the previous behaviour using <literal>undervolt.useTimer</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Agda has been heavily reworked.
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>agda.mkDerivation</literal> has been heavily changed and
|
||||||
|
is now located at <package>agdaPackages.mkDerivation</package>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
New top-level packages <package>agda</package> and
|
||||||
|
<literal>agda.withPackages</literal> have been added, the second
|
||||||
|
of which sets up agda with access to chosen libraries.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
All agda libraries now live under
|
||||||
|
<literal>agdaPackages</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Many broken libraries have been removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
See the <link
|
||||||
|
xlink:href="https://nixos.org/nixpkgs/manual/#agda">new
|
||||||
|
documentation</link> for more information.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>deepin</literal> package set has been removed from
|
||||||
|
nixpkgs. It was a work in progress to package the
|
||||||
|
<link xlink:href="https://www.deepin.org/en/dde/">Deepin Desktop Environment (DDE)</link>,
|
||||||
|
including libraries, tools and applications, and it was still
|
||||||
|
missing a service to lauch the desktop environment. It has shown
|
||||||
|
to no longer be a feasible goal due to reasons discussed in
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/94870">issue #94870</link>.
|
||||||
|
The package <literal>netease-cloud-music</literal> has also been
|
||||||
|
removed, as it depends on libraries from deepin.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>opendkim</literal> module now uses systemd sandboxing features
|
||||||
|
to limit the exposure of the system towards the opendkim service.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
check ? true
|
check ? true
|
||||||
, prefix ? []
|
, prefix ? []
|
||||||
, lib ? import ../../lib
|
, lib ? import ../../lib
|
||||||
|
, extraModules ? let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
|
||||||
|
in if e == "" then [] else [(import e)]
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let extraArgs_ = extraArgs; pkgs_ = pkgs;
|
let extraArgs_ = extraArgs; pkgs_ = pkgs;
|
||||||
extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
|
|
||||||
in if e == "" then [] else [(import e)];
|
|
||||||
in
|
in
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
|
@ -5,21 +5,32 @@
|
||||||
config
|
config
|
||||||
|
|
||||||
, # The size of the disk, in megabytes.
|
, # The size of the disk, in megabytes.
|
||||||
diskSize
|
# if "auto" size is calculated based on the contents copied to it and
|
||||||
|
# additionalSpace is taken into account.
|
||||||
|
diskSize ? "auto"
|
||||||
|
|
||||||
# The files and directories to be placed in the target file system.
|
, # additional disk space to be added to the image if diskSize "auto"
|
||||||
|
# is used
|
||||||
|
additionalSpace ? "512M"
|
||||||
|
|
||||||
|
, # size of the boot partition, is only used if partitionTableType is
|
||||||
|
# either "efi" or "hybrid"
|
||||||
|
bootSize ? "256M"
|
||||||
|
|
||||||
|
, # The files and directories to be placed in the target file system.
|
||||||
# This is a list of attribute sets {source, target} where `source'
|
# This is a list of attribute sets {source, target} where `source'
|
||||||
# is the file system object (regular file or directory) to be
|
# is the file system object (regular file or directory) to be
|
||||||
# grafted in the file system at path `target'.
|
# grafted in the file system at path `target'.
|
||||||
, contents ? []
|
contents ? []
|
||||||
|
|
||||||
, # Type of partition table to use; either "legacy", "efi", or "none".
|
, # Type of partition table to use; either "legacy", "efi", or "none".
|
||||||
# For "efi" images, the GPT partition table is used and a mandatory ESP
|
# For "efi" images, the GPT partition table is used and a mandatory ESP
|
||||||
# partition of reasonable size is created in addition to the root partition.
|
# partition of reasonable size is created in addition to the root partition.
|
||||||
# If `installBootLoader` is true, GRUB will be installed in EFI mode.
|
|
||||||
# For "legacy", the msdos partition table is used and a single large root
|
# For "legacy", the msdos partition table is used and a single large root
|
||||||
# partition is created. If `installBootLoader` is true, GRUB will be
|
# partition is created.
|
||||||
# installed in legacy mode.
|
# For "hybrid", the GPT partition table is used and a mandatory ESP
|
||||||
|
# partition of reasonable size is created in addition to the root partition.
|
||||||
|
# Also a legacy MBR will be present.
|
||||||
# For "none", no partition table is created. Enabling `installBootLoader`
|
# For "none", no partition table is created. Enabling `installBootLoader`
|
||||||
# most likely fails as GRUB will probably refuse to install.
|
# most likely fails as GRUB will probably refuse to install.
|
||||||
partitionTableType ? "legacy"
|
partitionTableType ? "legacy"
|
||||||
|
@ -43,7 +54,7 @@
|
||||||
format ? "raw"
|
format ? "raw"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
assert partitionTableType == "legacy" || partitionTableType == "efi" || partitionTableType == "none";
|
assert partitionTableType == "legacy" || partitionTableType == "efi" || partitionTableType == "hybrid" || partitionTableType == "none";
|
||||||
# We use -E offset=X below, which is only supported by e2fsprogs
|
# We use -E offset=X below, which is only supported by e2fsprogs
|
||||||
assert partitionTableType != "none" -> fsType == "ext4";
|
assert partitionTableType != "none" -> fsType == "ext4";
|
||||||
|
|
||||||
|
@ -60,11 +71,12 @@ let format' = format; in let
|
||||||
vdi = "vdi";
|
vdi = "vdi";
|
||||||
vpc = "vhd";
|
vpc = "vhd";
|
||||||
raw = "img";
|
raw = "img";
|
||||||
}.${format};
|
}.${format} or format;
|
||||||
|
|
||||||
rootPartition = { # switch-case
|
rootPartition = { # switch-case
|
||||||
legacy = "1";
|
legacy = "1";
|
||||||
efi = "2";
|
efi = "2";
|
||||||
|
hybrid = "3";
|
||||||
}.${partitionTableType};
|
}.${partitionTableType};
|
||||||
|
|
||||||
partitionDiskScript = { # switch-case
|
partitionDiskScript = { # switch-case
|
||||||
|
@ -76,9 +88,18 @@ let format' = format; in let
|
||||||
efi = ''
|
efi = ''
|
||||||
parted --script $diskImage -- \
|
parted --script $diskImage -- \
|
||||||
mklabel gpt \
|
mklabel gpt \
|
||||||
mkpart ESP fat32 8MiB 256MiB \
|
mkpart ESP fat32 8MiB ${bootSize} \
|
||||||
set 1 boot on \
|
set 1 boot on \
|
||||||
mkpart primary ext4 256MiB -1
|
mkpart primary ext4 ${bootSize} -1
|
||||||
|
'';
|
||||||
|
hybrid = ''
|
||||||
|
parted --script $diskImage -- \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart ESP fat32 8MiB ${bootSize} \
|
||||||
|
set 1 boot on \
|
||||||
|
mkpart no-fs 0 1024KiB \
|
||||||
|
set 2 bios_grub on \
|
||||||
|
mkpart primary ext4 ${bootSize} -1
|
||||||
'';
|
'';
|
||||||
none = "";
|
none = "";
|
||||||
}.${partitionTableType};
|
}.${partitionTableType};
|
||||||
|
@ -129,19 +150,6 @@ let format' = format; in let
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir $out
|
mkdir $out
|
||||||
diskImage=nixos.raw
|
|
||||||
truncate -s ${toString diskSize}M $diskImage
|
|
||||||
|
|
||||||
${partitionDiskScript}
|
|
||||||
|
|
||||||
${if partitionTableType != "none" then ''
|
|
||||||
# Get start & length of the root partition in sectors to $START and $SECTORS.
|
|
||||||
eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
|
|
||||||
|
|
||||||
mkfs.${fsType} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
|
||||||
'' else ''
|
|
||||||
mkfs.${fsType} -F -L ${label} $diskImage
|
|
||||||
''}
|
|
||||||
|
|
||||||
root="$PWD/root"
|
root="$PWD/root"
|
||||||
mkdir -p $root
|
mkdir -p $root
|
||||||
|
@ -181,10 +189,36 @@ let format' = format; in let
|
||||||
export NIX_STATE_DIR=$TMPDIR/state
|
export NIX_STATE_DIR=$TMPDIR/state
|
||||||
nix-store --load-db < ${closureInfo}/registration
|
nix-store --load-db < ${closureInfo}/registration
|
||||||
|
|
||||||
|
chmod 755 "$TMPDIR"
|
||||||
echo "running nixos-install..."
|
echo "running nixos-install..."
|
||||||
nixos-install --root $root --no-bootloader --no-root-passwd \
|
nixos-install --root $root --no-bootloader --no-root-passwd \
|
||||||
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
||||||
|
|
||||||
|
diskImage=nixos.raw
|
||||||
|
|
||||||
|
${if diskSize == "auto" then ''
|
||||||
|
${if partitionTableType == "efi" || partitionTableType == "hybrid" then ''
|
||||||
|
additionalSpace=$(( ($(numfmt --from=iec '${additionalSpace}') + $(numfmt --from=iec '${bootSize}')) / 1000 ))
|
||||||
|
'' else ''
|
||||||
|
additionalSpace=$(( $(numfmt --from=iec '${additionalSpace}') / 1000 ))
|
||||||
|
''}
|
||||||
|
diskSize=$(( $(set -- $(du -d0 $root); echo "$1") + $additionalSpace ))
|
||||||
|
truncate -s "$diskSize"K $diskImage
|
||||||
|
'' else ''
|
||||||
|
truncate -s ${toString diskSize}M $diskImage
|
||||||
|
''}
|
||||||
|
|
||||||
|
${partitionDiskScript}
|
||||||
|
|
||||||
|
${if partitionTableType != "none" then ''
|
||||||
|
# Get start & length of the root partition in sectors to $START and $SECTORS.
|
||||||
|
eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
|
||||||
|
|
||||||
|
mkfs.${fsType} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||||
|
'' else ''
|
||||||
|
mkfs.${fsType} -F -L ${label} $diskImage
|
||||||
|
''}
|
||||||
|
|
||||||
echo "copying staging root to image..."
|
echo "copying staging root to image..."
|
||||||
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
|
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
|
||||||
'';
|
'';
|
||||||
|
@ -218,7 +252,7 @@ in pkgs.vmTools.runInLinuxVM (
|
||||||
|
|
||||||
# Create the ESP and mount it. Unlike e2fsprogs, mkfs.vfat doesn't support an
|
# Create the ESP and mount it. Unlike e2fsprogs, mkfs.vfat doesn't support an
|
||||||
# '-E offset=X' option, so we can't do this outside the VM.
|
# '-E offset=X' option, so we can't do this outside the VM.
|
||||||
${optionalString (partitionTableType == "efi") ''
|
${optionalString (partitionTableType == "efi" || partitionTableType == "hybrid") ''
|
||||||
mkdir -p /mnt/boot
|
mkdir -p /mnt/boot
|
||||||
mkfs.vfat -n ESP /dev/vda1
|
mkfs.vfat -n ESP /dev/vda1
|
||||||
mount /dev/vda1 /mnt/boot
|
mount /dev/vda1 /mnt/boot
|
||||||
|
|
|
@ -46,7 +46,10 @@ pkgs.stdenv.mkDerivation {
|
||||||
(
|
(
|
||||||
GLOBIGNORE=".:.."
|
GLOBIGNORE=".:.."
|
||||||
shopt -u dotglob
|
shopt -u dotglob
|
||||||
cp -a --reflink=auto ./files/* -t ./rootImage/
|
|
||||||
|
for f in ./files/*; do
|
||||||
|
cp -a --reflink=auto -t ./rootImage/ "$f"
|
||||||
|
done
|
||||||
)
|
)
|
||||||
|
|
||||||
# Also include a manifest of the closures in a format suitable for nix-store --load-db
|
# Also include a manifest of the closures in a format suitable for nix-store --load-db
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ stdenv, closureInfo, xorriso, syslinux
|
{ stdenv, closureInfo, xorriso, syslinux, libossp_uuid
|
||||||
|
|
||||||
, # The file name of the resulting ISO image.
|
, # The file name of the resulting ISO image.
|
||||||
isoName ? "cd.iso"
|
isoName ? "cd.iso"
|
||||||
|
@ -48,7 +48,7 @@ assert usbBootable -> isohybridMbrImage != "";
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = isoName;
|
name = isoName;
|
||||||
builder = ./make-iso9660-image.sh;
|
builder = ./make-iso9660-image.sh;
|
||||||
buildInputs = [ xorriso syslinux zstd ];
|
buildInputs = [ xorriso syslinux zstd libossp_uuid ];
|
||||||
|
|
||||||
inherit isoName bootable bootImage compressImage volumeID efiBootImage efiBootable isohybridMbrImage usbBootable;
|
inherit isoName bootable bootImage compressImage volumeID efiBootImage efiBootable isohybridMbrImage usbBootable;
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,12 @@ done
|
||||||
|
|
||||||
mkdir -p $out/iso
|
mkdir -p $out/iso
|
||||||
|
|
||||||
|
# daed2280-b91e-42c0-aed6-82c825ca41f3 is an arbitrary namespace, to prevent
|
||||||
|
# independent applications from generating the same UUID for the same value.
|
||||||
|
# (the chance of that being problematic seem pretty slim here, but that's how
|
||||||
|
# version-5 UUID's work)
|
||||||
xorriso="xorriso
|
xorriso="xorriso
|
||||||
|
-boot_image any gpt_disk_guid=$(uuid -v 5 daed2280-b91e-42c0-aed6-82c825ca41f3 $out | tr -d -)
|
||||||
-as mkisofs
|
-as mkisofs
|
||||||
-iso-level 3
|
-iso-level 3
|
||||||
-volid ${volumeID}
|
-volid ${volumeID}
|
||||||
|
@ -118,15 +123,6 @@ xorriso="xorriso
|
||||||
|
|
||||||
$xorriso -output $out/iso/$isoName
|
$xorriso -output $out/iso/$isoName
|
||||||
|
|
||||||
if test -n "$usbBootable"; then
|
|
||||||
echo "Making image hybrid..."
|
|
||||||
if test -n "$efiBootable"; then
|
|
||||||
isohybrid --uefi $out/iso/$isoName
|
|
||||||
else
|
|
||||||
isohybrid $out/iso/$isoName
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -n "$compressImage"; then
|
if test -n "$compressImage"; then
|
||||||
echo "Compressing image..."
|
echo "Compressing image..."
|
||||||
zstd -T$NIX_BUILD_CORES --rm $out/iso/$isoName
|
zstd -T$NIX_BUILD_CORES --rm $out/iso/$isoName
|
||||||
|
|
|
@ -36,7 +36,7 @@ let
|
||||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
||||||
// lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != []) { relatedPackages = genRelatedPackages opt.relatedPackages; }
|
// lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != []) { relatedPackages = genRelatedPackages opt.relatedPackages opt.name; }
|
||||||
);
|
);
|
||||||
|
|
||||||
# Generate DocBook documentation for a list of packages. This is
|
# Generate DocBook documentation for a list of packages. This is
|
||||||
|
@ -48,7 +48,7 @@ let
|
||||||
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
||||||
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
||||||
# (either of `name`, `path` is required, the rest are optional).
|
# (either of `name`, `path` is required, the rest are optional).
|
||||||
genRelatedPackages = packages:
|
genRelatedPackages = packages: optName:
|
||||||
let
|
let
|
||||||
unpack = p: if lib.isString p then { name = p; }
|
unpack = p: if lib.isString p then { name = p; }
|
||||||
else if lib.isList p then { path = p; }
|
else if lib.isList p then { path = p; }
|
||||||
|
@ -58,7 +58,7 @@ let
|
||||||
title = args.title or null;
|
title = args.title or null;
|
||||||
name = args.name or (lib.concatStringsSep "." args.path);
|
name = args.name or (lib.concatStringsSep "." args.path);
|
||||||
path = args.path or [ args.name ];
|
path = args.path or [ args.name ];
|
||||||
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
|
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}' found while evaluating `relatedPackages' of option `${optName}'") pkgs);
|
||||||
in "<listitem>"
|
in "<listitem>"
|
||||||
+ "<para><literal>${lib.optionalString (title != null) "${title} aka "}pkgs.${name} (${package.meta.name})</literal>"
|
+ "<para><literal>${lib.optionalString (title != null) "${title} aka "}pkgs.${name} (${package.meta.name})</literal>"
|
||||||
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<title>Configuration Options</title>
|
<title>Configuration Options</title>
|
||||||
<variablelist xml:id="configuration-variable-list">
|
<variablelist xml:id="configuration-variable-list">
|
||||||
<xsl:for-each select="attrs">
|
<xsl:for-each select="attrs">
|
||||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'))" />
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term xlink:href="#{$id}">
|
<term xlink:href="#{$id}">
|
||||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
||||||
|
|
|
@ -2,13 +2,18 @@
|
||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
let
|
let
|
||||||
zeroPad = n: if n < 10 then "0${toString n}" else toString n;
|
zeroPad = n:
|
||||||
|
pkgs.lib.optionalString (n < 16) "0" +
|
||||||
|
(if n > 255
|
||||||
|
then throw "Can't have more than 255 nets or nodes!"
|
||||||
|
else pkgs.lib.toHexString n);
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
rec {
|
||||||
|
qemuNicMac = net: machine: "52:54:00:12:${zeroPad net}:${zeroPad machine}";
|
||||||
|
|
||||||
qemuNICFlags = nic: net: machine:
|
qemuNICFlags = nic: net: machine:
|
||||||
[ "-device virtio-net-pci,netdev=vlan${toString nic},mac=52:54:00:12:${zeroPad net}:${zeroPad machine}"
|
[ "-device virtio-net-pci,netdev=vlan${toString nic},mac=${qemuNicMac net machine}"
|
||||||
"-netdev vde,id=vlan${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}"
|
"-netdev vde,id=vlan${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -17,9 +22,9 @@ in
|
||||||
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
||||||
|
|
||||||
qemuBinary = qemuPkg: {
|
qemuBinary = qemuPkg: {
|
||||||
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu host";
|
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||||
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
|
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
|
||||||
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
|
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
|
||||||
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu host";
|
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||||
}.${pkgs.stdenv.hostPlatform.system} or "${qemuPkg}/bin/qemu-kvm";
|
}.${pkgs.stdenv.hostPlatform.system} or "${qemuPkg}/bin/qemu-kvm";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package Logger;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Thread::Queue;
|
|
||||||
use XML::Writer;
|
|
||||||
use Encode qw(decode encode);
|
|
||||||
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my ($class) = @_;
|
|
||||||
|
|
||||||
my $logFile = defined $ENV{LOGFILE} ? "$ENV{LOGFILE}" : "/dev/null";
|
|
||||||
my $log = new XML::Writer(OUTPUT => new IO::File(">$logFile"));
|
|
||||||
|
|
||||||
my $self = {
|
|
||||||
log => $log,
|
|
||||||
logQueue => Thread::Queue->new()
|
|
||||||
};
|
|
||||||
|
|
||||||
$self->{log}->startTag("logfile");
|
|
||||||
|
|
||||||
bless $self, $class;
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub close {
|
|
||||||
my ($self) = @_;
|
|
||||||
$self->{log}->endTag("logfile");
|
|
||||||
$self->{log}->end;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub drainLogQueue {
|
|
||||||
my ($self) = @_;
|
|
||||||
while (defined (my $item = $self->{logQueue}->dequeue_nb())) {
|
|
||||||
$self->{log}->dataElement("line", sanitise($item->{msg}), 'machine' => $item->{machine}, 'type' => 'serial');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub maybePrefix {
|
|
||||||
my ($msg, $attrs) = @_;
|
|
||||||
$msg = $attrs->{machine} . ": " . $msg if defined $attrs->{machine};
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub nest {
|
|
||||||
my ($self, $msg, $coderef, $attrs) = @_;
|
|
||||||
print STDERR maybePrefix("$msg\n", $attrs);
|
|
||||||
$self->{log}->startTag("nest");
|
|
||||||
$self->{log}->dataElement("head", $msg, %{$attrs});
|
|
||||||
my $now = clock_gettime(CLOCK_MONOTONIC);
|
|
||||||
$self->drainLogQueue();
|
|
||||||
eval { &$coderef };
|
|
||||||
my $res = $@;
|
|
||||||
$self->drainLogQueue();
|
|
||||||
$self->log(sprintf("(%.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
|
|
||||||
$self->{log}->endTag("nest");
|
|
||||||
die $@ if $@;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sanitise {
|
|
||||||
my ($s) = @_;
|
|
||||||
$s =~ s/[[:cntrl:]\xff]//g;
|
|
||||||
$s = decode('UTF-8', $s, Encode::FB_DEFAULT);
|
|
||||||
return encode('UTF-8', $s, Encode::FB_CROAK);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub log {
|
|
||||||
my ($self, $msg, $attrs) = @_;
|
|
||||||
chomp $msg;
|
|
||||||
print STDERR maybePrefix("$msg\n", $attrs);
|
|
||||||
$self->drainLogQueue();
|
|
||||||
$self->{log}->dataElement("line", $msg, %{$attrs});
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
|
|
@ -1,734 +0,0 @@
|
||||||
package Machine;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use threads;
|
|
||||||
use Socket;
|
|
||||||
use IO::Handle;
|
|
||||||
use POSIX qw(dup2);
|
|
||||||
use FileHandle;
|
|
||||||
use Cwd;
|
|
||||||
use File::Basename;
|
|
||||||
use File::Path qw(make_path);
|
|
||||||
use File::Slurp;
|
|
||||||
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
|
|
||||||
|
|
||||||
|
|
||||||
my $showGraphics = defined $ENV{'DISPLAY'};
|
|
||||||
|
|
||||||
my $sharedDir;
|
|
||||||
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my ($class, $args) = @_;
|
|
||||||
|
|
||||||
my $startCommand = $args->{startCommand};
|
|
||||||
|
|
||||||
my $name = $args->{name};
|
|
||||||
if (!$name) {
|
|
||||||
$startCommand =~ /run-(.*)-vm$/ if defined $startCommand;
|
|
||||||
$name = $1 || "machine";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$startCommand) {
|
|
||||||
# !!! merge with qemu-vm.nix.
|
|
||||||
my $netBackend = "-netdev user,id=net0";
|
|
||||||
my $netFrontend = "-device virtio-net-pci,netdev=net0";
|
|
||||||
|
|
||||||
$netBackend .= "," . $args->{netBackendArgs}
|
|
||||||
if defined $args->{netBackendArgs};
|
|
||||||
|
|
||||||
$netFrontend .= "," . $args->{netFrontendArgs}
|
|
||||||
if defined $args->{netFrontendArgs};
|
|
||||||
|
|
||||||
$startCommand =
|
|
||||||
"qemu-kvm -m 384 $netBackend $netFrontend \$QEMU_OPTS ";
|
|
||||||
|
|
||||||
if (defined $args->{hda}) {
|
|
||||||
if ($args->{hdaInterface} eq "scsi") {
|
|
||||||
$startCommand .= "-drive id=hda,file="
|
|
||||||
. Cwd::abs_path($args->{hda})
|
|
||||||
. ",werror=report,if=none "
|
|
||||||
. "-device scsi-hd,drive=hda ";
|
|
||||||
} else {
|
|
||||||
$startCommand .= "-drive file=" . Cwd::abs_path($args->{hda})
|
|
||||||
. ",if=" . $args->{hdaInterface}
|
|
||||||
. ",werror=report ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$startCommand .= "-cdrom $args->{cdrom} "
|
|
||||||
if defined $args->{cdrom};
|
|
||||||
$startCommand .= "-device piix3-usb-uhci -drive id=usbdisk,file=$args->{usb},if=none,readonly -device usb-storage,drive=usbdisk "
|
|
||||||
if defined $args->{usb};
|
|
||||||
$startCommand .= "-bios $args->{bios} "
|
|
||||||
if defined $args->{bios};
|
|
||||||
$startCommand .= $args->{qemuFlags} || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $tmpDir = $ENV{'TMPDIR'} || "/tmp";
|
|
||||||
unless (defined $sharedDir) {
|
|
||||||
$sharedDir = $tmpDir . "/xchg-shared";
|
|
||||||
make_path($sharedDir, { mode => 0700, owner => $< });
|
|
||||||
}
|
|
||||||
|
|
||||||
my $allowReboot = 0;
|
|
||||||
$allowReboot = $args->{allowReboot} if defined $args->{allowReboot};
|
|
||||||
|
|
||||||
my $self = {
|
|
||||||
startCommand => $startCommand,
|
|
||||||
name => $name,
|
|
||||||
allowReboot => $allowReboot,
|
|
||||||
booted => 0,
|
|
||||||
pid => 0,
|
|
||||||
connected => 0,
|
|
||||||
socket => undef,
|
|
||||||
stateDir => "$tmpDir/vm-state-$name",
|
|
||||||
monitor => undef,
|
|
||||||
log => $args->{log},
|
|
||||||
redirectSerial => $args->{redirectSerial} // 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
mkdir $self->{stateDir}, 0700;
|
|
||||||
|
|
||||||
bless $self, $class;
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub log {
|
|
||||||
my ($self, $msg) = @_;
|
|
||||||
$self->{log}->log($msg, { machine => $self->{name} });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub nest {
|
|
||||||
my ($self, $msg, $coderef, $attrs) = @_;
|
|
||||||
$self->{log}->nest($msg, $coderef, { %{$attrs || {}}, machine => $self->{name} });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub name {
|
|
||||||
my ($self) = @_;
|
|
||||||
return $self->{name};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub stateDir {
|
|
||||||
my ($self) = @_;
|
|
||||||
return $self->{stateDir};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub start {
|
|
||||||
my ($self) = @_;
|
|
||||||
return if $self->{booted};
|
|
||||||
|
|
||||||
$self->log("starting vm");
|
|
||||||
|
|
||||||
# Create a socket pair for the serial line input/output of the VM.
|
|
||||||
my ($serialP, $serialC);
|
|
||||||
socketpair($serialP, $serialC, PF_UNIX, SOCK_STREAM, 0) or die;
|
|
||||||
|
|
||||||
# Create a Unix domain socket to which QEMU's monitor will connect.
|
|
||||||
my $monitorPath = $self->{stateDir} . "/monitor";
|
|
||||||
unlink $monitorPath;
|
|
||||||
my $monitorS;
|
|
||||||
socket($monitorS, PF_UNIX, SOCK_STREAM, 0) or die;
|
|
||||||
bind($monitorS, sockaddr_un($monitorPath)) or die "cannot bind monitor socket: $!";
|
|
||||||
listen($monitorS, 1) or die;
|
|
||||||
|
|
||||||
# Create a Unix domain socket to which the root shell in the guest will connect.
|
|
||||||
my $shellPath = $self->{stateDir} . "/shell";
|
|
||||||
unlink $shellPath;
|
|
||||||
my $shellS;
|
|
||||||
socket($shellS, PF_UNIX, SOCK_STREAM, 0) or die;
|
|
||||||
bind($shellS, sockaddr_un($shellPath)) or die "cannot bind shell socket: $!";
|
|
||||||
listen($shellS, 1) or die;
|
|
||||||
|
|
||||||
# Start the VM.
|
|
||||||
my $pid = fork();
|
|
||||||
die if $pid == -1;
|
|
||||||
|
|
||||||
if ($pid == 0) {
|
|
||||||
close $serialP;
|
|
||||||
close $monitorS;
|
|
||||||
close $shellS;
|
|
||||||
if ($self->{redirectSerial}) {
|
|
||||||
open NUL, "</dev/null" or die;
|
|
||||||
dup2(fileno(NUL), fileno(STDIN));
|
|
||||||
dup2(fileno($serialC), fileno(STDOUT));
|
|
||||||
dup2(fileno($serialC), fileno(STDERR));
|
|
||||||
}
|
|
||||||
$ENV{TMPDIR} = $self->{stateDir};
|
|
||||||
$ENV{SHARED_DIR} = $sharedDir;
|
|
||||||
$ENV{USE_TMPDIR} = 1;
|
|
||||||
$ENV{QEMU_OPTS} =
|
|
||||||
($self->{allowReboot} ? "" : "-no-reboot ") .
|
|
||||||
"-monitor unix:./monitor -chardev socket,id=shell,path=./shell " .
|
|
||||||
"-device virtio-serial -device virtconsole,chardev=shell " .
|
|
||||||
"-device virtio-rng-pci " .
|
|
||||||
($showGraphics ? "-serial stdio" : "-nographic") . " " . ($ENV{QEMU_OPTS} || "");
|
|
||||||
chdir $self->{stateDir} or die;
|
|
||||||
exec $self->{startCommand};
|
|
||||||
die "running VM script: $!";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process serial line output.
|
|
||||||
close $serialC;
|
|
||||||
|
|
||||||
threads->create(\&processSerialOutput, $self, $serialP)->detach;
|
|
||||||
|
|
||||||
sub processSerialOutput {
|
|
||||||
my ($self, $serialP) = @_;
|
|
||||||
while (<$serialP>) {
|
|
||||||
chomp;
|
|
||||||
s/\r$//;
|
|
||||||
print STDERR $self->{name}, "# $_\n";
|
|
||||||
$self->{log}->{logQueue}->enqueue({msg => $_, machine => $self->{name}}); # !!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eval {
|
|
||||||
local $SIG{CHLD} = sub { die "QEMU died prematurely\n"; };
|
|
||||||
|
|
||||||
# Wait until QEMU connects to the monitor.
|
|
||||||
accept($self->{monitor}, $monitorS) or die;
|
|
||||||
|
|
||||||
# Wait until QEMU connects to the root shell socket. QEMU
|
|
||||||
# does so immediately; this doesn't mean that the root shell
|
|
||||||
# has connected yet inside the guest.
|
|
||||||
accept($self->{socket}, $shellS) or die;
|
|
||||||
$self->{socket}->autoflush(1);
|
|
||||||
};
|
|
||||||
die "$@" if $@;
|
|
||||||
|
|
||||||
$self->waitForMonitorPrompt;
|
|
||||||
|
|
||||||
$self->log("QEMU running (pid $pid)");
|
|
||||||
|
|
||||||
$self->{pid} = $pid;
|
|
||||||
$self->{booted} = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Send a command to the monitor and wait for it to finish. TODO: QEMU
|
|
||||||
# also has a JSON-based monitor interface now, but it doesn't support
|
|
||||||
# all commands yet. We should use it once it does.
|
|
||||||
sub sendMonitorCommand {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
$self->log("sending monitor command: $command");
|
|
||||||
syswrite $self->{monitor}, "$command\n";
|
|
||||||
return $self->waitForMonitorPrompt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until the monitor sends "(qemu) ".
|
|
||||||
sub waitForMonitorPrompt {
|
|
||||||
my ($self) = @_;
|
|
||||||
my $res = "";
|
|
||||||
my $s;
|
|
||||||
while (sysread($self->{monitor}, $s, 1024)) {
|
|
||||||
$res .= $s;
|
|
||||||
last if $res =~ s/\(qemu\) $//;
|
|
||||||
}
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Call the given code reference repeatedly, with 1 second intervals,
|
|
||||||
# until it returns 1 or a timeout is reached.
|
|
||||||
sub retry {
|
|
||||||
my ($coderef) = @_;
|
|
||||||
my $n;
|
|
||||||
for ($n = 899; $n >=0; $n--) {
|
|
||||||
return if &$coderef($n);
|
|
||||||
sleep 1;
|
|
||||||
}
|
|
||||||
die "action timed out after $n seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub connect {
|
|
||||||
my ($self) = @_;
|
|
||||||
return if $self->{connected};
|
|
||||||
|
|
||||||
$self->nest("waiting for the VM to finish booting", sub {
|
|
||||||
|
|
||||||
$self->start;
|
|
||||||
|
|
||||||
my $now = clock_gettime(CLOCK_MONOTONIC);
|
|
||||||
local $SIG{ALRM} = sub { die "timed out waiting for the VM to connect\n"; };
|
|
||||||
alarm 600;
|
|
||||||
readline $self->{socket} or die "the VM quit before connecting\n";
|
|
||||||
alarm 0;
|
|
||||||
|
|
||||||
$self->log("connected to guest root shell");
|
|
||||||
# We're interested in tracking how close we are to `alarm`.
|
|
||||||
$self->log(sprintf("(connecting took %.2f seconds)", clock_gettime(CLOCK_MONOTONIC) - $now));
|
|
||||||
$self->{connected} = 1;
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub waitForShutdown {
|
|
||||||
my ($self) = @_;
|
|
||||||
return unless $self->{booted};
|
|
||||||
|
|
||||||
$self->nest("waiting for the VM to power off", sub {
|
|
||||||
waitpid $self->{pid}, 0;
|
|
||||||
$self->{pid} = 0;
|
|
||||||
$self->{booted} = 0;
|
|
||||||
$self->{connected} = 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub isUp {
|
|
||||||
my ($self) = @_;
|
|
||||||
return $self->{booted} && $self->{connected};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub execute_ {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
|
|
||||||
$self->connect;
|
|
||||||
|
|
||||||
print { $self->{socket} } ("( $command ); echo '|!=EOF' \$?\n");
|
|
||||||
|
|
||||||
my $out = "";
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
my $line = readline($self->{socket});
|
|
||||||
die "connection to VM lost unexpectedly" unless defined $line;
|
|
||||||
#$self->log("got line: $line");
|
|
||||||
if ($line =~ /^(.*)\|\!\=EOF\s+(\d+)$/) {
|
|
||||||
$out .= $1;
|
|
||||||
$self->log("exit status $2");
|
|
||||||
return ($2, $out);
|
|
||||||
}
|
|
||||||
$out .= $line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub execute {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
my @res;
|
|
||||||
$self->nest("running command: $command", sub {
|
|
||||||
@res = $self->execute_($command);
|
|
||||||
});
|
|
||||||
return @res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub succeed {
|
|
||||||
my ($self, @commands) = @_;
|
|
||||||
|
|
||||||
my $res;
|
|
||||||
foreach my $command (@commands) {
|
|
||||||
$self->nest("must succeed: $command", sub {
|
|
||||||
my ($status, $out) = $self->execute_($command);
|
|
||||||
if ($status != 0) {
|
|
||||||
$self->log("output: $out");
|
|
||||||
die "command `$command' did not succeed (exit code $status)\n";
|
|
||||||
}
|
|
||||||
$res .= $out;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub mustSucceed {
|
|
||||||
succeed @_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub waitUntilSucceeds {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
$self->nest("waiting for success: $command", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute($command);
|
|
||||||
return 1 if $status == 0;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub waitUntilFails {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
$self->nest("waiting for failure: $command", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute($command);
|
|
||||||
return 1 if $status != 0;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub fail {
|
|
||||||
my ($self, $command) = @_;
|
|
||||||
$self->nest("must fail: $command", sub {
|
|
||||||
my ($status, $out) = $self->execute_($command);
|
|
||||||
die "command `$command' unexpectedly succeeded"
|
|
||||||
if $status == 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub mustFail {
|
|
||||||
fail @_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub getUnitInfo {
|
|
||||||
my ($self, $unit, $user) = @_;
|
|
||||||
my ($status, $lines) = $self->systemctl("--no-pager show \"$unit\"", $user);
|
|
||||||
return undef if $status != 0;
|
|
||||||
my $info = {};
|
|
||||||
foreach my $line (split '\n', $lines) {
|
|
||||||
$line =~ /^([^=]+)=(.*)$/ or next;
|
|
||||||
$info->{$1} = $2;
|
|
||||||
}
|
|
||||||
return $info;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub systemctl {
|
|
||||||
my ($self, $q, $user) = @_;
|
|
||||||
if ($user) {
|
|
||||||
$q =~ s/'/\\'/g;
|
|
||||||
return $self->execute("su -l $user -c \$'XDG_RUNTIME_DIR=/run/user/`id -u` systemctl --user $q'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return $self->execute("systemctl $q");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fail if the given systemd unit is not in the "active" state.
|
|
||||||
sub requireActiveUnit {
|
|
||||||
my ($self, $unit) = @_;
|
|
||||||
$self->nest("checking if unit ‘$unit’ has reached state 'active'", sub {
|
|
||||||
my $info = $self->getUnitInfo($unit);
|
|
||||||
my $state = $info->{ActiveState};
|
|
||||||
if ($state ne "active") {
|
|
||||||
die "Expected unit ‘$unit’ to to be in state 'active' but it is in state ‘$state’\n";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wait for a systemd unit to reach the "active" state.
|
|
||||||
sub waitForUnit {
|
|
||||||
my ($self, $unit, $user) = @_;
|
|
||||||
$self->nest("waiting for unit ‘$unit’", sub {
|
|
||||||
retry sub {
|
|
||||||
my $info = $self->getUnitInfo($unit, $user);
|
|
||||||
my $state = $info->{ActiveState};
|
|
||||||
die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed";
|
|
||||||
if ($state eq "inactive") {
|
|
||||||
# If there are no pending jobs, then assume this unit
|
|
||||||
# will never reach active state.
|
|
||||||
my ($status, $jobs) = $self->systemctl("list-jobs --full 2>&1", $user);
|
|
||||||
if ($jobs =~ /No jobs/) { # FIXME: fragile
|
|
||||||
# Handle the case where the unit may have started
|
|
||||||
# between the previous getUnitInfo() and
|
|
||||||
# list-jobs.
|
|
||||||
my $info2 = $self->getUnitInfo($unit);
|
|
||||||
die "unit ‘$unit’ is inactive and there are no pending jobs\n"
|
|
||||||
if $info2->{ActiveState} eq $state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1 if $state eq "active";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub waitForJob {
|
|
||||||
my ($self, $jobName) = @_;
|
|
||||||
return $self->waitForUnit($jobName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until the specified file exists.
|
|
||||||
sub waitForFile {
|
|
||||||
my ($self, $fileName) = @_;
|
|
||||||
$self->nest("waiting for file ‘$fileName’", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute("test -e $fileName");
|
|
||||||
return 1 if $status == 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sub startJob {
|
|
||||||
my ($self, $jobName, $user) = @_;
|
|
||||||
$self->systemctl("start $jobName", $user);
|
|
||||||
# FIXME: check result
|
|
||||||
}
|
|
||||||
|
|
||||||
sub stopJob {
|
|
||||||
my ($self, $jobName, $user) = @_;
|
|
||||||
$self->systemctl("stop $jobName", $user);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until the machine is listening on the given TCP port.
|
|
||||||
sub waitForOpenPort {
|
|
||||||
my ($self, $port) = @_;
|
|
||||||
$self->nest("waiting for TCP port $port", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute("nc -z localhost $port");
|
|
||||||
return 1 if $status == 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until the machine is not listening on the given TCP port.
|
|
||||||
sub waitForClosedPort {
|
|
||||||
my ($self, $port) = @_;
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute("nc -z localhost $port");
|
|
||||||
return 1 if $status != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub shutdown {
|
|
||||||
my ($self) = @_;
|
|
||||||
return unless $self->{booted};
|
|
||||||
|
|
||||||
print { $self->{socket} } ("poweroff\n");
|
|
||||||
|
|
||||||
$self->waitForShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub crash {
|
|
||||||
my ($self) = @_;
|
|
||||||
return unless $self->{booted};
|
|
||||||
|
|
||||||
$self->log("forced crash");
|
|
||||||
|
|
||||||
$self->sendMonitorCommand("quit");
|
|
||||||
|
|
||||||
$self->waitForShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Make the machine unreachable by shutting down eth1 (the multicast
|
|
||||||
# interface used to talk to the other VMs). We keep eth0 up so that
|
|
||||||
# the test driver can continue to talk to the machine.
|
|
||||||
sub block {
|
|
||||||
my ($self) = @_;
|
|
||||||
$self->sendMonitorCommand("set_link virtio-net-pci.1 off");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Make the machine reachable.
|
|
||||||
sub unblock {
|
|
||||||
my ($self) = @_;
|
|
||||||
$self->sendMonitorCommand("set_link virtio-net-pci.1 on");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Take a screenshot of the X server on :0.0.
|
|
||||||
sub screenshot {
|
|
||||||
my ($self, $filename) = @_;
|
|
||||||
my $dir = $ENV{'out'} || Cwd::abs_path(".");
|
|
||||||
$filename = "$dir/${filename}.png" if $filename =~ /^\w+$/;
|
|
||||||
my $tmp = "${filename}.ppm";
|
|
||||||
my $name = basename($filename);
|
|
||||||
$self->nest("making screenshot ‘$name’", sub {
|
|
||||||
$self->sendMonitorCommand("screendump $tmp");
|
|
||||||
system("pnmtopng $tmp > ${filename}") == 0
|
|
||||||
or die "cannot convert screenshot";
|
|
||||||
unlink $tmp;
|
|
||||||
}, { image => $name } );
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the text of TTY<n>
|
|
||||||
sub getTTYText {
|
|
||||||
my ($self, $tty) = @_;
|
|
||||||
|
|
||||||
my ($status, $out) = $self->execute("fold -w\$(stty -F /dev/tty${tty} size | awk '{print \$2}') /dev/vcs${tty}");
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wait until TTY<n>'s text matches a particular regular expression
|
|
||||||
sub waitUntilTTYMatches {
|
|
||||||
my ($self, $tty, $regexp) = @_;
|
|
||||||
|
|
||||||
$self->nest("waiting for $regexp to appear on tty $tty", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($retries_remaining) = @_;
|
|
||||||
if ($retries_remaining == 0) {
|
|
||||||
$self->log("Last chance to match /$regexp/ on TTY$tty, which currently contains:");
|
|
||||||
$self->log($self->getTTYText($tty));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1 if $self->getTTYText($tty) =~ /$regexp/;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
# Debugging: Dump the contents of the TTY<n>
|
|
||||||
sub dumpTTYContents {
|
|
||||||
my ($self, $tty) = @_;
|
|
||||||
|
|
||||||
$self->execute("fold -w 80 /dev/vcs${tty} | systemd-cat");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Take a screenshot and return the result as text using optical character
|
|
||||||
# recognition.
|
|
||||||
sub getScreenText {
|
|
||||||
my ($self) = @_;
|
|
||||||
|
|
||||||
system("command -v tesseract &> /dev/null") == 0
|
|
||||||
or die "getScreenText used but enableOCR is false";
|
|
||||||
|
|
||||||
my $text;
|
|
||||||
$self->nest("performing optical character recognition", sub {
|
|
||||||
my $tmpbase = Cwd::abs_path(".")."/ocr";
|
|
||||||
my $tmpin = $tmpbase."in.ppm";
|
|
||||||
|
|
||||||
$self->sendMonitorCommand("screendump $tmpin");
|
|
||||||
|
|
||||||
my $magickArgs = "-filter Catrom -density 72 -resample 300 "
|
|
||||||
. "-contrast -normalize -despeckle -type grayscale "
|
|
||||||
. "-sharpen 1 -posterize 3 -negate -gamma 100 "
|
|
||||||
. "-blur 1x65535";
|
|
||||||
my $tessArgs = "-c debug_file=/dev/null --psm 11 --oem 2";
|
|
||||||
|
|
||||||
$text = `convert $magickArgs $tmpin tiff:- | tesseract - - $tessArgs`;
|
|
||||||
my $status = $? >> 8;
|
|
||||||
unlink $tmpin;
|
|
||||||
|
|
||||||
die "OCR failed with exit code $status" if $status != 0;
|
|
||||||
});
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until a specific regexp matches the textual contents of the screen.
|
|
||||||
sub waitForText {
|
|
||||||
my ($self, $regexp) = @_;
|
|
||||||
$self->nest("waiting for $regexp to appear on the screen", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($retries_remaining) = @_;
|
|
||||||
if ($retries_remaining == 0) {
|
|
||||||
$self->log("Last chance to match /$regexp/ on the screen, which currently contains:");
|
|
||||||
$self->log($self->getScreenText);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1 if $self->getScreenText =~ /$regexp/;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until it is possible to connect to the X server. Note that
|
|
||||||
# testing the existence of /tmp/.X11-unix/X0 is insufficient.
|
|
||||||
sub waitForX {
|
|
||||||
my ($self, $regexp) = @_;
|
|
||||||
$self->nest("waiting for the X11 server", sub {
|
|
||||||
retry sub {
|
|
||||||
my ($status, $out) = $self->execute("journalctl -b SYSLOG_IDENTIFIER=systemd | grep 'Reached target Current graphical'");
|
|
||||||
return 0 if $status != 0;
|
|
||||||
($status, $out) = $self->execute("[ -e /tmp/.X11-unix/X0 ]");
|
|
||||||
return 1 if $status == 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub getWindowNames {
|
|
||||||
my ($self) = @_;
|
|
||||||
my $res = $self->mustSucceed(
|
|
||||||
q{xwininfo -root -tree | sed 's/.*0x[0-9a-f]* \"\([^\"]*\)\".*/\1/; t; d'});
|
|
||||||
return split /\n/, $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub waitForWindow {
|
|
||||||
my ($self, $regexp) = @_;
|
|
||||||
$self->nest("waiting for a window to appear", sub {
|
|
||||||
retry sub {
|
|
||||||
my @names = $self->getWindowNames;
|
|
||||||
|
|
||||||
my ($retries_remaining) = @_;
|
|
||||||
if ($retries_remaining == 0) {
|
|
||||||
$self->log("Last chance to match /$regexp/ on the the window list, which currently contains:");
|
|
||||||
$self->log(join(", ", @names));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $n (@names) {
|
|
||||||
return 1 if $n =~ /$regexp/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub copyFileFromHost {
|
|
||||||
my ($self, $from, $to) = @_;
|
|
||||||
my $s = `cat $from` or die;
|
|
||||||
$s =~ s/'/'\\''/g;
|
|
||||||
$self->mustSucceed("echo '$s' > $to");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my %charToKey = (
|
|
||||||
'A' => "shift-a", 'N' => "shift-n", '-' => "0x0C", '_' => "shift-0x0C", '!' => "shift-0x02",
|
|
||||||
'B' => "shift-b", 'O' => "shift-o", '=' => "0x0D", '+' => "shift-0x0D", '@' => "shift-0x03",
|
|
||||||
'C' => "shift-c", 'P' => "shift-p", '[' => "0x1A", '{' => "shift-0x1A", '#' => "shift-0x04",
|
|
||||||
'D' => "shift-d", 'Q' => "shift-q", ']' => "0x1B", '}' => "shift-0x1B", '$' => "shift-0x05",
|
|
||||||
'E' => "shift-e", 'R' => "shift-r", ';' => "0x27", ':' => "shift-0x27", '%' => "shift-0x06",
|
|
||||||
'F' => "shift-f", 'S' => "shift-s", '\'' => "0x28", '"' => "shift-0x28", '^' => "shift-0x07",
|
|
||||||
'G' => "shift-g", 'T' => "shift-t", '`' => "0x29", '~' => "shift-0x29", '&' => "shift-0x08",
|
|
||||||
'H' => "shift-h", 'U' => "shift-u", '\\' => "0x2B", '|' => "shift-0x2B", '*' => "shift-0x09",
|
|
||||||
'I' => "shift-i", 'V' => "shift-v", ',' => "0x33", '<' => "shift-0x33", '(' => "shift-0x0A",
|
|
||||||
'J' => "shift-j", 'W' => "shift-w", '.' => "0x34", '>' => "shift-0x34", ')' => "shift-0x0B",
|
|
||||||
'K' => "shift-k", 'X' => "shift-x", '/' => "0x35", '?' => "shift-0x35",
|
|
||||||
'L' => "shift-l", 'Y' => "shift-y", ' ' => "spc",
|
|
||||||
'M' => "shift-m", 'Z' => "shift-z", "\n" => "ret",
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
sub sendKeys {
|
|
||||||
my ($self, @keys) = @_;
|
|
||||||
foreach my $key (@keys) {
|
|
||||||
$key = $charToKey{$key} if exists $charToKey{$key};
|
|
||||||
$self->sendMonitorCommand("sendkey $key");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub sendChars {
|
|
||||||
my ($self, $chars) = @_;
|
|
||||||
$self->nest("sending keys ‘$chars’", sub {
|
|
||||||
$self->sendKeys(split //, $chars);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Sleep N seconds (in virtual guest time, not real time).
|
|
||||||
sub sleep {
|
|
||||||
my ($self, $time) = @_;
|
|
||||||
$self->succeed("sleep $time");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Forward a TCP port on the host to a TCP port on the guest. Useful
|
|
||||||
# during interactive testing.
|
|
||||||
sub forwardPort {
|
|
||||||
my ($self, $hostPort, $guestPort) = @_;
|
|
||||||
$hostPort = 8080 unless defined $hostPort;
|
|
||||||
$guestPort = 80 unless defined $guestPort;
|
|
||||||
$self->sendMonitorCommand("hostfwd_add tcp::$hostPort-:$guestPort");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
1;
|
|
|
@ -1,191 +0,0 @@
|
||||||
#! /somewhere/perl -w
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Machine;
|
|
||||||
use Term::ReadLine;
|
|
||||||
use IO::File;
|
|
||||||
use IO::Pty;
|
|
||||||
use Logger;
|
|
||||||
use Cwd;
|
|
||||||
use POSIX qw(_exit dup2);
|
|
||||||
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
|
|
||||||
|
|
||||||
$SIG{PIPE} = 'IGNORE'; # because Unix domain sockets may die unexpectedly
|
|
||||||
|
|
||||||
STDERR->autoflush(1);
|
|
||||||
|
|
||||||
my $log = new Logger;
|
|
||||||
|
|
||||||
|
|
||||||
# Start vde_switch for each network required by the test.
|
|
||||||
my %vlans;
|
|
||||||
foreach my $vlan (split / /, $ENV{VLANS} || "") {
|
|
||||||
next if defined $vlans{$vlan};
|
|
||||||
# Start vde_switch as a child process. We don't run it in daemon
|
|
||||||
# mode because we want the child process to be cleaned up when we
|
|
||||||
# die. Since we have to make sure that the control socket is
|
|
||||||
# ready, we send a dummy command to vde_switch (via stdin) and
|
|
||||||
# wait for a reply. Note that vde_switch requires stdin to be a
|
|
||||||
# TTY, so we create one.
|
|
||||||
$log->log("starting VDE switch for network $vlan");
|
|
||||||
my $socket = Cwd::abs_path "./vde$vlan.ctl";
|
|
||||||
my $pty = new IO::Pty;
|
|
||||||
my ($stdoutR, $stdoutW); pipe $stdoutR, $stdoutW;
|
|
||||||
my $pid = fork(); die "cannot fork" unless defined $pid;
|
|
||||||
if ($pid == 0) {
|
|
||||||
dup2(fileno($pty->slave), 0);
|
|
||||||
dup2(fileno($stdoutW), 1);
|
|
||||||
exec "vde_switch -s $socket --dirmode 0700" or _exit(1);
|
|
||||||
}
|
|
||||||
close $stdoutW;
|
|
||||||
print $pty "version\n";
|
|
||||||
readline $stdoutR or die "cannot start vde_switch";
|
|
||||||
$ENV{"QEMU_VDE_SOCKET_$vlan"} = $socket;
|
|
||||||
$vlans{$vlan} = $pty;
|
|
||||||
die unless -e "$socket/ctl";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my %vms;
|
|
||||||
my $context = "";
|
|
||||||
|
|
||||||
sub createMachine {
|
|
||||||
my ($args) = @_;
|
|
||||||
my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"});
|
|
||||||
$vms{$vm->name} = $vm;
|
|
||||||
$context .= "my \$" . $vm->name . " = \$vms{'" . $vm->name . "'}; ";
|
|
||||||
return $vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $vmScript (@ARGV) {
|
|
||||||
my $vm = createMachine({startCommand => $vmScript});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub startAll {
|
|
||||||
$log->nest("starting all VMs", sub {
|
|
||||||
$_->start foreach values %vms;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Wait until all VMs have terminated.
|
|
||||||
sub joinAll {
|
|
||||||
$log->nest("waiting for all VMs to finish", sub {
|
|
||||||
$_->waitForShutdown foreach values %vms;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# In interactive tests, this allows the non-interactive test script to
|
|
||||||
# be executed conveniently.
|
|
||||||
sub testScript {
|
|
||||||
eval "$context $ENV{testScript};\n";
|
|
||||||
warn $@ if $@;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my $nrTests = 0;
|
|
||||||
my $nrSucceeded = 0;
|
|
||||||
|
|
||||||
|
|
||||||
sub subtest {
|
|
||||||
my ($name, $coderef) = @_;
|
|
||||||
$log->nest("subtest: $name", sub {
|
|
||||||
$nrTests++;
|
|
||||||
eval { &$coderef };
|
|
||||||
if ($@) {
|
|
||||||
$log->log("error: $@", { error => 1 });
|
|
||||||
} else {
|
|
||||||
$nrSucceeded++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub runTests {
|
|
||||||
if (defined $ENV{tests}) {
|
|
||||||
$log->nest("running the VM test script", sub {
|
|
||||||
eval "$context $ENV{tests}";
|
|
||||||
if ($@) {
|
|
||||||
$log->log("error: $@", { error => 1 });
|
|
||||||
die $@;
|
|
||||||
}
|
|
||||||
}, { expanded => 1 });
|
|
||||||
} else {
|
|
||||||
my $term = Term::ReadLine->new('nixos-vm-test');
|
|
||||||
$term->ReadHistory;
|
|
||||||
while (defined ($_ = $term->readline("> "))) {
|
|
||||||
eval "$context $_\n";
|
|
||||||
warn $@ if $@;
|
|
||||||
}
|
|
||||||
$term->WriteHistory;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy the kernel coverage data for each machine, if the kernel
|
|
||||||
# has been compiled with coverage instrumentation.
|
|
||||||
$log->nest("collecting coverage data", sub {
|
|
||||||
foreach my $vm (values %vms) {
|
|
||||||
my $gcovDir = "/sys/kernel/debug/gcov";
|
|
||||||
|
|
||||||
next unless $vm->isUp();
|
|
||||||
|
|
||||||
my ($status, $out) = $vm->execute("test -e $gcovDir");
|
|
||||||
next if $status != 0;
|
|
||||||
|
|
||||||
# Figure out where to put the *.gcda files so that the
|
|
||||||
# report generator can find the corresponding kernel
|
|
||||||
# sources.
|
|
||||||
my $kernelDir = $vm->mustSucceed("echo \$(dirname \$(readlink -f /run/current-system/kernel))/.build/linux-*");
|
|
||||||
chomp $kernelDir;
|
|
||||||
my $coverageDir = "/tmp/xchg/coverage-data/$kernelDir";
|
|
||||||
|
|
||||||
# Copy all the *.gcda files.
|
|
||||||
$vm->execute("for d in $gcovDir/nix/store/*/.build/linux-*; do for i in \$(cd \$d && find -name '*.gcda'); do echo \$i; mkdir -p $coverageDir/\$(dirname \$i); cp -v \$d/\$i $coverageDir/\$i; done; done");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$log->nest("syncing", sub {
|
|
||||||
foreach my $vm (values %vms) {
|
|
||||||
next unless $vm->isUp();
|
|
||||||
$vm->execute("sync");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($nrTests != 0) {
|
|
||||||
$log->log("$nrSucceeded out of $nrTests tests succeeded",
|
|
||||||
($nrSucceeded < $nrTests ? { error => 1 } : { }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Create an empty raw virtual disk with the given name and size (in
|
|
||||||
# MiB).
|
|
||||||
sub createDisk {
|
|
||||||
my ($name, $size) = @_;
|
|
||||||
system("qemu-img create -f raw $name ${size}M") == 0
|
|
||||||
or die "cannot create image of size $size";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
END {
|
|
||||||
$log->nest("cleaning up", sub {
|
|
||||||
foreach my $vm (values %vms) {
|
|
||||||
if ($vm->{pid}) {
|
|
||||||
$log->log("killing " . $vm->{name} . " (pid " . $vm->{pid} . ")");
|
|
||||||
kill 9, $vm->{pid};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$log->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
my $now1 = clock_gettime(CLOCK_MONOTONIC);
|
|
||||||
|
|
||||||
runTests;
|
|
||||||
|
|
||||||
my $now2 = clock_gettime(CLOCK_MONOTONIC);
|
|
||||||
|
|
||||||
printf STDERR "test script finished in %.2fs\n", $now2 - $now1;
|
|
||||||
|
|
||||||
exit ($nrSucceeded < $nrTests ? 1 : 0);
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue