Merge remote-tracking branch 'nixos/master'
This commit is contained in:
commit
2b9c7b4268
16
.github/CONTRIBUTING.md
vendored
16
.github/CONTRIBUTING.md
vendored
@ -14,14 +14,22 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
||||
|
||||
* Format the commits in the following way:
|
||||
|
||||
`(pkg-name | service-name): (from -> to | init at version | refactor | etc)`
|
||||
```
|
||||
(pkg-name | service-name): (from -> to | init at version | refactor | etc)
|
||||
|
||||
(Motivation for change. Additional information.)
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
* nginx: init at 2.0.1
|
||||
* firefox: 3.0 -> 3.1.1
|
||||
* hydra service: add bazBaz option
|
||||
|
||||
Dual baz behavior is needed to do foo.
|
||||
* nginx service: refactor config generation
|
||||
|
||||
The old config generation system used impure shell scripts and could break in specific circumstances (see #1234).
|
||||
|
||||
* `meta.description` should:
|
||||
* Be capitalized
|
||||
@ -30,6 +38,12 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
||||
|
||||
See the nixpkgs manual for more details on how to [Submit changes to nixpkgs](https://nixos.org/nixpkgs/manual/#chap-submitting-changes).
|
||||
|
||||
## Writing good commit messages
|
||||
|
||||
In addition to writing properly formatted commit messages, it's important to include relevant information so other developers can later understand *why* a change was made. While this information usually can be found by digging code, mailing list archives, pull request discussions or upstream changes, it may require a lot of work.
|
||||
|
||||
For package version upgrades and such a one-line commit message is usually sufficient.
|
||||
|
||||
## Reviewing contributions
|
||||
|
||||
See the nixpkgs manual for more details on how to [Review contributions](https://nixos.org/nixpkgs/manual/#sec-reviewing-contributions).
|
||||
|
@ -623,7 +623,7 @@ evaluate correctly.</para>
|
||||
from bad to good:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Uses <literal>git://</literal> which won't be proxied.
|
||||
<para>Bad: Uses <literal>git://</literal> which won't be proxied.
|
||||
<programlisting>
|
||||
src = fetchgit {
|
||||
url = "git://github.com/NixOS/nix.git";
|
||||
@ -634,7 +634,7 @@ src = fetchgit {
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>This is ok, but an archive fetch will still be faster.
|
||||
<para>Better: This is ok, but an archive fetch will still be faster.
|
||||
<programlisting>
|
||||
src = fetchgit {
|
||||
url = "https://github.com/NixOS/nix.git";
|
||||
@ -645,7 +645,7 @@ src = fetchgit {
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Fetches a snapshot archive and you get the rev you want.
|
||||
<para>Best: Fetches a snapshot archive and you get the rev you want.
|
||||
<programlisting>
|
||||
src = fetchFromGitHub {
|
||||
owner = "NixOS";
|
||||
|
@ -2,12 +2,12 @@
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="chap-packageconfig">
|
||||
|
||||
<title><filename>~/.nixpkgs/config.nix</filename>: global configuration</title>
|
||||
<title>Global configuration</title>
|
||||
|
||||
<para>Nix packages can be configured to allow or deny certain options.</para>
|
||||
|
||||
<para>To apply the configuration edit
|
||||
<filename>~/.nixpkgs/config.nix</filename> and set it like
|
||||
<filename>~/.config/nixpkgs/config.nix</filename> and set it like
|
||||
|
||||
<programlisting>
|
||||
{
|
||||
@ -89,7 +89,7 @@ packages via <literal>packageOverrides</literal></title>
|
||||
|
||||
<para>You can define a function called
|
||||
<varname>packageOverrides</varname> in your local
|
||||
<filename>~/.nixpkgs/config.nix</filename> to overide nix packages. It
|
||||
<filename>~/.config/nixpkgs/config.nix</filename> to overide nix packages. It
|
||||
must be a function that takes pkgs as an argument and return modified
|
||||
set of packages.
|
||||
|
||||
|
168
doc/cross-compilation.xml
Normal file
168
doc/cross-compilation.xml
Normal file
@ -0,0 +1,168 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="chap-cross">
|
||||
|
||||
<title>Cross-compilation</title>
|
||||
|
||||
<section xml:id="sec-cross-intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
"Cross-compilation" means compiling a program on one machine for another type of machine.
|
||||
For example, a typical use of cross compilation is to compile programs for embedded devices.
|
||||
These devices often don't have the computing power and memory to compile their own programs.
|
||||
One might think that cross-compilation is a fairly niche concern, but there are advantages to being rigorous about distinguishing build-time vs run-time environments even when one is developing and deploying on the same machine.
|
||||
Nixpkgs is increasingly adopting this opinion in that packages should be written with cross-compilation in mind, and nixpkgs should evaluate in a similar way (by minimizing cross-compilation-specific special cases) whether or not one is cross-compiling.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This chapter will be organized in three parts.
|
||||
First, it will describe the basics of how to package software in a way that supports cross-compilation.
|
||||
Second, it will describe how to use Nixpkgs when cross-compiling.
|
||||
Third, it will describe the internal infrastructure supporting cross-compilation.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<!--============================================================-->
|
||||
|
||||
<section xml:id="sec-cross-packaging">
|
||||
<title>Packaging in a cross-friendly manner</title>
|
||||
|
||||
<section>
|
||||
<title>Platform parameters</title>
|
||||
<para>
|
||||
The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>cross</wordasword>, are historically the result of much confusion.
|
||||
<link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html" /> clears this up somewhat but there is more to be said.
|
||||
An important advice to get out the way is, unless you are packaging a compiler or other build tool, just worry about the build and host platforms.
|
||||
Dealing with just two platforms usually better matches people's preconceptions, and in this case is completely correct.
|
||||
</para>
|
||||
<para>
|
||||
In Nixpkgs, these three platforms are defined as attribute sets under the names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and <literal>targetPlatform</literal>.
|
||||
All are guaranteed to contain at least a <varname>platform</varname> field, which contains detailed information on the platform.
|
||||
All three are always defined at the top level, so one can get at them just like a dependency in a function that is imported with <literal>callPackage</literal>:
|
||||
<programlisting>{ stdenv, buildPlatform, hostPlatform, fooDep, barDep, .. }: ...</programlisting>
|
||||
</para>
|
||||
<warning><para>
|
||||
These platforms should all have the same structure in all scenarios, but that is currently not the case.
|
||||
When not cross-compiling, they will each contain a <literal>system</literal> field with a short 2-part, hyphen-separated summering string name for the platform.
|
||||
But, when when cross compiling, <literal>hostPlatform</literal> and <literal>targetPlatform</literal> may instead contain <literal>config</literal> with a fuller 3- or 4-part string in the manner of LLVM.
|
||||
We should have all 3 platforms always contain both, and maybe give <literal>config</literal> a better name while we are at it.
|
||||
</para></warning>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>buildPlatform</varname></term>
|
||||
<listitem><para>
|
||||
The "build platform" is the platform on which a package is built.
|
||||
Once someone has a built package, or pre-built binary package, the build platform should not matter and be safe to ignore.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>hostPlatform</varname></term>
|
||||
<listitem><para>
|
||||
The "host platform" is the platform on which a package is run.
|
||||
This is the simplest platform to understand, but also the one with the worst name.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>targetPlatform</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The "target platform" is black sheep.
|
||||
The other two intrinsically apply to all compiled software—or any build process with a notion of "build-time" followed by "run-time".
|
||||
The target platform only applies to programming tools, and even then only is a good for for some of them.
|
||||
Briefly, GCC, Binutils, GHC, and certain other tools are written in such a way such that a single build can only compiler code for a single platform.
|
||||
Thus, when building them, one must think ahead about what platforms they wish to use the tool to produce machine code for, and build binaries for each.
|
||||
</para>
|
||||
<para>
|
||||
There is no fundamental need to think about the target ahead of time like this.
|
||||
LLVM, for example, was designed from the beginning with cross-compilation in mind, and so a normal LLVM binary will support every architecture that LLVM supports.
|
||||
If the tool supports modular or pluggable backends, one might imagine specifying a <emphasis>set</emphasis> of target platforms / backends one wishes to support, rather than a single one.
|
||||
</para>
|
||||
<para>
|
||||
The biggest reason for mess, if there is one, is that many compilers have the bad habit a build process that builds the compiler and standard library/runtime together.
|
||||
Then the specifying target platform is essential, because it determines the host platform of the standard library/runtime.
|
||||
Nixpkgs tries to avoid this where possible too, but still, because the concept of a target platform is so ingrained now in Autoconf and other tools, it is best to support it as is.
|
||||
Tools like LLVM that don't need up-front target platforms can safely ignore it like normal packages, and it will do no harm.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<note><para>
|
||||
If you dig around nixpkgs, you may notice there is also <varname>stdenv.cross</varname>.
|
||||
This field defined as <varname>hostPlatform</varname> when the host and build platforms differ, but otherwise not defined at all.
|
||||
This field is obsolete and will soon disappear—please do not use it.
|
||||
</para></note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Specifying Dependencies</title>
|
||||
<para>
|
||||
As mentioned in the introduction to this chapter, one can think about a build time vs run time distinction whether cross-compiling or not.
|
||||
In the case of cross-compilation, this corresponds with whether a derivation running on the native or foreign platform is produced.
|
||||
An interesting thing to think about is how this corresponds with the three Autoconf platforms.
|
||||
In the run-time case, the depending and depended-on package simply have matching build, host, and target platforms.
|
||||
But in the build-time case, one can imagine "sliding" the platforms one over.
|
||||
The depended-on package's host and target platforms (respectively) become the depending package's build and host platforms.
|
||||
This is the most important guiding principle behind cross-compilation with Nixpkgs, and will be called the <wordasword>sliding window principle</wordasword>.
|
||||
In this manner, given the 3 platforms for one package, we can determine the three platforms for all its transitive dependencies.
|
||||
</para>
|
||||
<para>
|
||||
Some examples will probably make this clearer.
|
||||
If a package is being built with a <literal>(build, host, target)</literal> platform triple of <literal>(foo, bar, bar)</literal>, then its build-time dependencies would have a triple of <literal>(foo, foo, bar)</literal>, and <emphasis>those packages'</emphasis> build-time dependencies would have triple of <literal>(foo, foo, foo)</literal>.
|
||||
In other words, it should take two "rounds" of following build-time dependency edges before one reaches a fixed point where, by the sliding window principle, the platform triple no longer changes.
|
||||
Indeed, this happens with cross compilation, where only rounds of native dependencies starting with the second necessarily coincide with native packages.
|
||||
</para>
|
||||
<note><para>
|
||||
The depending package's target platform is unconstrained by the sliding window principle, which makes sense in that one can in principle build cross compilers targeting arbitrary platforms.
|
||||
</para></note>
|
||||
<para>
|
||||
How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set.
|
||||
For example, <varname>buildPackages.gcc</varname> should be used at build time, while <varname>gcc</varname> should be used at run time.
|
||||
Now, for most of Nixpkgs's history, there was no <varname>buildPackages</varname>, and most packages have not been refactored to use it explicitly.
|
||||
Instead, one can use the four attributes used for specifying dependencies as documented in <link linkend="ssec-stdenv-attributes" />.
|
||||
We "splice" together the run-time and build-time package sets with <varname>callPackage</varname>, and then <varname>mkDerivation</varname> for each of four attributes pulls the right derivation out.
|
||||
This splicing can be skipped when not cross compiling as the package sets are the same, but is a bit slow for cross compiling.
|
||||
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
||||
For now, feel free to use either method.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<!--============================================================-->
|
||||
|
||||
<section xml:id="sec-cross-usage">
|
||||
<title>Cross-building packages</title>
|
||||
<note><para>
|
||||
More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
|
||||
</para></note>
|
||||
<para>
|
||||
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, and, optionally, <varname>crossSystem</varname> to nixpkgs:
|
||||
<literal>import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }</literal>.
|
||||
<varname>system</varname> and <varname>platform</varname> together determine the system on which packages are built, and <varname>crossSystem</varname> specifies the platform on which packages are ultimately intended to run, if it is different.
|
||||
This still works, but with more recent changes, one can alternatively pass <varname>localSystem</varname>, containing <varname>system</varname> and <varname>platform</varname>, for symmetry.
|
||||
</para>
|
||||
<para>
|
||||
One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual).
|
||||
Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:
|
||||
While the granularity of having 3 platforms is necessary to properly *build* packages, it is overkill for specifying the user's *intent* when making a build plan or package set.
|
||||
A simple "build vs deploy" dichotomy is adequate: the sliding window principle described in the previous section shows how to interpolate between the these two "end points" to get the 3 platform triple for each bootstrapping stage.
|
||||
That means for any package a given package set, even those not bound on the top level but only reachable via dependencies or <varname>buildPackages</varname>, the three platforms will be defined as one of <varname>localSystem</varname> or <varname>crossSystem</varname>, with the former replacing the latter as one traverses build-time dependencies.
|
||||
A last simple difference then is <varname>crossSystem</varname> should be null when one doesn't want to cross-compile, while the <varname>*Platform</varname>s are always non-null.
|
||||
<varname>localSystem</varname> is always non-null.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<!--============================================================-->
|
||||
|
||||
<section xml:id="sec-cross-infra">
|
||||
<title>Cross-compilation infrastructure</title>
|
||||
<para>To be written.</para>
|
||||
<note><para>
|
||||
If one explores nixpkgs, they will see derivations with names like <literal>gccCross</literal>.
|
||||
Such <literal>*Cross</literal> derivations is a holdover from before we properly distinguished between the host and target platforms
|
||||
—the derivation with "Cross" in the name covered the <literal>build = host != target</literal> case, while the other covered the <literal>host = target</literal>, with build platform the same or not based on whether one was using its <literal>.nativeDrv</literal> or <literal>.crossDrv</literal>.
|
||||
This ugliness will disappear soon.
|
||||
</para></note>
|
||||
</section>
|
||||
|
||||
</chapter>
|
@ -68,6 +68,10 @@ pkgs.stdenv.mkDerivation {
|
||||
inputFile = ../pkgs/development/r-modules/README.md;
|
||||
outputFile = "languages-frameworks/r.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./languages-frameworks/vim.md;
|
||||
outputFile = "./languages-frameworks/vim.xml";
|
||||
}
|
||||
+ ''
|
||||
echo ${lib.nixpkgsVersion} > .version
|
||||
|
||||
|
@ -119,7 +119,7 @@
|
||||
evaluation-per-function application incurs a performance penalty,
|
||||
which can become a problem if many overrides are used.
|
||||
It is only intended for ad-hoc customisation, such as in
|
||||
<filename>~/.nixpkgs/config.nix</filename>.
|
||||
<filename>~/.config/nixpkgs/config.nix</filename>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
|
@ -195,7 +195,7 @@ its normal core packages:
|
||||
mtl-2.2.1
|
||||
|
||||
This function allows users to define their own development environment by means
|
||||
of an override. After adding the following snippet to `~/.nixpkgs/config.nix`,
|
||||
of an override. After adding the following snippet to `~/.config/nixpkgs/config.nix`,
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
@ -522,7 +522,7 @@ file with `cabal2nix`:
|
||||
$ cd ~/src/foo && cabal2nix . >default.nix
|
||||
$ cd ~/src/bar && cabal2nix . >default.nix
|
||||
|
||||
Then edit your `~/.nixpkgs/config.nix` file to register those builds in the
|
||||
Then edit your `~/.config/nixpkgs/config.nix` file to register those builds in the
|
||||
default Haskell package set:
|
||||
|
||||
{
|
||||
@ -554,7 +554,7 @@ Every Haskell package set takes a function called `overrides` that you can use
|
||||
to manipulate the package as much as you please. One useful application of this
|
||||
feature is to replace the default `mkDerivation` function with one that enables
|
||||
library profiling for all packages. To accomplish that, add configure the
|
||||
following snippet in your `~/.nixpkgs/config.nix` file:
|
||||
following snippet in your `~/.config/nixpkgs/config.nix` file:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
@ -583,7 +583,7 @@ The first step is to generate Nix build instructions with `cabal2nix`:
|
||||
|
||||
$ cabal2nix cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||
|
||||
Then add the override in `~/.nixpkgs/config.nix`:
|
||||
Then add the override in `~/.config/nixpkgs/config.nix`:
|
||||
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in
|
||||
@ -793,6 +793,64 @@ It's important to realize, however, that most system libraries in Nix are built
|
||||
as shared libraries only, i.e. there is just no static library available that
|
||||
Cabal could link!
|
||||
|
||||
### Building GHC with integer-simple
|
||||
|
||||
By default GHC implements the Integer type using the
|
||||
[GNU Multiple Precision Arithmetic (GMP) library](https://gmplib.org/).
|
||||
The implementation can be found in the
|
||||
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
||||
|
||||
A potential problem with this is that GMP is licensed under the
|
||||
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
|
||||
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
|
||||
you may distribute a program that is designed to be compiled and dynamically
|
||||
linked with the library under the terms of your choice (i.e., commercially) but
|
||||
if your program incorporates portions of the library, if it is linked
|
||||
statically, then your program is a "derivative"--a "work based on the
|
||||
library"--and according to paragraph 2, section c, you "must cause the whole of
|
||||
the work to be licensed" under the terms of the LGPL (including for free).
|
||||
|
||||
The LGPL licensing for GMP is a problem for the overall licensing of binary
|
||||
programs compiled with GHC because most distributions (and builds) of GHC use
|
||||
static libraries. (Dynamic libraries are currently distributed only for OS X.)
|
||||
The LGPL licensing situation may be worse: even though
|
||||
[The Glasgow Haskell Compiler License](https://www.haskell.org/ghc/license)
|
||||
is essentially a "free software" license (BSD3), according to
|
||||
paragraph 2 of the LGPL, GHC must be distributed under the terms of the LGPL!
|
||||
|
||||
To work around these problems GHC can be build with a slower but LGPL-free
|
||||
alternative implemention for Integer called
|
||||
[integer-simple](http://hackage.haskell.org/package/integer-simple).
|
||||
|
||||
To get a GHC compiler build with `integer-simple` instead of `integer-gmp` use
|
||||
the attribute: `pkgs.haskell.compiler.integer-simple."${ghcVersion}"`.
|
||||
For example:
|
||||
|
||||
$ nix-build -E '(import <nixpkgs> {}).pkgs.haskell.compiler.integer-simple.ghc802'
|
||||
...
|
||||
$ result/bin/ghc-pkg list | grep integer
|
||||
integer-simple-0.1.1.1
|
||||
|
||||
The following command displays the complete list of GHC compilers build with `integer-simple`:
|
||||
|
||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler.integer-simple
|
||||
haskell.compiler.integer-simple.ghc7102 ghc-7.10.2
|
||||
haskell.compiler.integer-simple.ghc7103 ghc-7.10.3
|
||||
haskell.compiler.integer-simple.ghc722 ghc-7.2.2
|
||||
haskell.compiler.integer-simple.ghc742 ghc-7.4.2
|
||||
haskell.compiler.integer-simple.ghc763 ghc-7.6.3
|
||||
haskell.compiler.integer-simple.ghc783 ghc-7.8.3
|
||||
haskell.compiler.integer-simple.ghc784 ghc-7.8.4
|
||||
haskell.compiler.integer-simple.ghc801 ghc-8.0.1
|
||||
haskell.compiler.integer-simple.ghc802 ghc-8.0.2
|
||||
haskell.compiler.integer-simple.ghcHEAD ghc-8.1.20170106
|
||||
|
||||
To get a package set supporting `integer-simple` use the attribute:
|
||||
`pkgs.haskell.packages.integer-simple."${ghcVersion}"`. For example
|
||||
use the following to get the `scientific` package build with `integer-simple`:
|
||||
|
||||
$ nix-build -A pkgs.haskell.packages.integer-simple.ghc802.scientific
|
||||
|
||||
|
||||
## Other resources
|
||||
|
||||
|
@ -28,6 +28,7 @@ such as Perl or Haskell. These are described in this chapter.</para>
|
||||
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
|
||||
<xi:include href="ruby.xml" />
|
||||
<xi:include href="texlive.xml" />
|
||||
<xi:include href="vim.xml" />
|
||||
|
||||
|
||||
</chapter>
|
||||
|
@ -781,7 +781,7 @@ If you get the following error:
|
||||
could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc':
|
||||
Permission denied
|
||||
|
||||
This is a [known bug](https://bitbucket.org/pypa/setuptools/issue/130/install_data-doesnt-respect-prefix) in setuptools.
|
||||
This is a [known bug](https://github.com/pypa/setuptools/issues/130) in setuptools.
|
||||
Setuptools `install_data` does not respect `--prefix`. An example of such package using the feature is `pkgs/tools/X11/xpra/default.nix`.
|
||||
As workaround install it as an extra `preInstall` step:
|
||||
|
||||
|
102
doc/languages-frameworks/vim.md
Normal file
102
doc/languages-frameworks/vim.md
Normal file
@ -0,0 +1,102 @@
|
||||
---
|
||||
title: User's Guide for Vim in Nixpkgs
|
||||
author: Marc Weber
|
||||
date: 2016-06-25
|
||||
---
|
||||
# User's Guide to Vim Plugins/Addons/Bundles/Scripts in Nixpkgs
|
||||
|
||||
You'll get a vim(-your-suffix) in PATH also loading the plugins you want.
|
||||
Loading can be deferred; see examples.
|
||||
|
||||
VAM (=vim-addon-manager) and Pathogen plugin managers are supported.
|
||||
Vundle, NeoBundle could be your turn.
|
||||
|
||||
## dependencies by Vim plugins
|
||||
|
||||
VAM introduced .json files supporting dependencies without versioning
|
||||
assuming that "using latest version" is ok most of the time.
|
||||
|
||||
## HOWTO
|
||||
|
||||
First create a vim-scripts file having one plugin name per line. Example:
|
||||
|
||||
"tlib"
|
||||
{'name': 'vim-addon-sql'}
|
||||
{'filetype_regex': '\%(vim)$', 'names': ['reload', 'vim-dev-plugin']}
|
||||
|
||||
Such vim-scripts file can be read by VAM as well like this:
|
||||
|
||||
call vam#Scripts(expand('~/.vim-scripts'), {})
|
||||
|
||||
Create a default.nix file:
|
||||
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||
nixpkgs.vim_configurable.customize { name = "vim"; vimrcConfig.vam.pluginDictionaries = [ "vim-addon-vim2nix" ]; }
|
||||
|
||||
Create a generate.vim file:
|
||||
|
||||
ActivateAddons vim-addon-vim2nix
|
||||
let vim_scripts = "vim-scripts"
|
||||
call nix#ExportPluginsForNix({
|
||||
\ 'path_to_nixpkgs': eval('{"'.substitute(substitute(substitute($NIX_PATH, ':', ',', 'g'), '=',':', 'g'), '\([:,]\)', '"\1"',"g").'"}')["nixpkgs"],
|
||||
\ 'cache_file': '/tmp/vim2nix-cache',
|
||||
\ 'try_catch': 0,
|
||||
\ 'plugin_dictionaries': ["vim-addon-manager"]+map(readfile(vim_scripts), 'eval(v:val)')
|
||||
\ })
|
||||
|
||||
Then run
|
||||
|
||||
nix-shell -p vimUtils.vim_with_vim2nix --command "vim -c 'source generate.vim'"
|
||||
|
||||
You should get a Vim buffer with the nix derivations (output1) and vam.pluginDictionaries (output2).
|
||||
You can add your vim to your system's configuration file like this and start it by "vim-my":
|
||||
|
||||
my-vim =
|
||||
let plugins = let inherit (vimUtils) buildVimPluginFrom2Nix; in {
|
||||
copy paste output1 here
|
||||
}; in vim_configurable.customize {
|
||||
name = "vim-my";
|
||||
|
||||
vimrcConfig.vam.knownPlugins = plugins; # optional
|
||||
vimrcConfig.vam.pluginDictionaries = [
|
||||
copy paste output2 here
|
||||
];
|
||||
|
||||
# Pathogen would be
|
||||
# vimrcConfig.pathogen.knownPlugins = plugins; # plugins
|
||||
# vimrcConfig.pathogen.pluginNames = ["tlib"];
|
||||
};
|
||||
|
||||
|
||||
Sample output1:
|
||||
|
||||
"reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation
|
||||
name = "reload";
|
||||
src = fetchgit {
|
||||
url = "git://github.com/xolox/vim-reload";
|
||||
rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1";
|
||||
sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh";
|
||||
};
|
||||
dependencies = ["nim-misc"];
|
||||
|
||||
};
|
||||
[...]
|
||||
|
||||
Sample output2:
|
||||
|
||||
[
|
||||
''vim-addon-manager''
|
||||
''tlib''
|
||||
{ "name" = ''vim-addon-sql''; }
|
||||
{ "filetype_regex" = ''\%(vim)$$''; "names" = [ ''reload'' ''vim-dev-plugin'' ]; }
|
||||
]
|
||||
|
||||
|
||||
## Important repositories
|
||||
|
||||
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository
|
||||
from VAM plugin manager meant to be used by others as well used by
|
||||
|
||||
- [vim2nix](http://github.com/MarcWeber/vim-addon-vim2nix) which generates the
|
||||
.nix code
|
||||
|
@ -13,6 +13,7 @@
|
||||
<xi:include href="quick-start.xml" />
|
||||
<xi:include href="stdenv.xml" />
|
||||
<xi:include href="multiple-output.xml" />
|
||||
<xi:include href="cross-compilation.xml" />
|
||||
<xi:include href="configuration.xml" />
|
||||
<xi:include href="functions.xml" />
|
||||
<xi:include href="meta.xml" />
|
||||
|
@ -61,7 +61,7 @@ stdenv.mkDerivation {
|
||||
builder = ./builder.sh;
|
||||
src = fetchurl {
|
||||
url = http://ftp.nluug.nl/gnu/binutils/binutils-2.16.1.tar.bz2;
|
||||
md5 = "6a9d529efb285071dad10e1f3d2b2967";
|
||||
sha256 = "1ian3kwh2vg6hr3ymrv48s04gijs539vzrq62xr76bxbhbwnz2np";
|
||||
};
|
||||
inherit noSysDirs;
|
||||
configureFlags = "--target=arm-linux";
|
||||
@ -81,11 +81,11 @@ Step 2: build kernel headers for the target architecture
|
||||
assert stdenv.system == "i686-linux";
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "linux-headers-2.6.13.4-arm";
|
||||
name = "linux-headers-2.6.13.1-arm";
|
||||
builder = ./builder.sh;
|
||||
src = fetchurl {
|
||||
url = http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.13.4.tar.bz2;
|
||||
md5 = "94768d7eef90a9d8174639b2a7d3f58d";
|
||||
url = http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.13.1.tar.bz2;
|
||||
sha256 = "12qxmc827fjhaz53kjy7vyrzsaqcg78amiqsb3qm20z26w705lma";
|
||||
};
|
||||
}
|
||||
---
|
||||
@ -152,9 +152,7 @@ stdenv.mkDerivation {
|
||||
builder = ./builder.sh;
|
||||
src = fetchurl {
|
||||
url = ftp://ftp.nluug.nl/pub/gnu/gcc/gcc-4.0.2/gcc-core-4.0.2.tar.bz2;
|
||||
md5 = "f7781398ada62ba255486673e6274b26";
|
||||
#url = ftp://ftp.nluug.nl/pub/gnu/gcc/gcc-4.0.2/gcc-4.0.2.tar.bz2;
|
||||
#md5 = "a659b8388cac9db2b13e056e574ceeb0";
|
||||
sha256 = "02fxh0asflm8825w23l2jq1wvs7hbnam0jayrivg7zdv2ifnc0rc";
|
||||
};
|
||||
# !!! apply only if noSysDirs is set
|
||||
patches = [./no-sys-dirs.patch ./gcc-inhibit.patch];
|
||||
|
@ -28,8 +28,8 @@ first one present is considered, and all the rest are ignored:
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>In the directory pointed by the environment variable
|
||||
<varname>NIXPKGS_OVERLAYS</varname>.</para>
|
||||
<para>In the directory pointed to by the Nix search path entry
|
||||
<literal><nixpkgs-overlays></literal>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
@ -278,7 +278,7 @@ packageOverrides = pkgs: {
|
||||
</screen>
|
||||
|
||||
to your Nixpkgs configuration
|
||||
(<filename>~/.nixpkgs/config.nix</filename>) and install it by
|
||||
(<filename>~/.config/nixpkgs/config.nix</filename>) and install it by
|
||||
running <command>nix-env -f '<nixpkgs>' -iA
|
||||
myEclipse</command> and afterward run Eclipse as usual. It is
|
||||
possible to find out which plugins are available for installation
|
||||
|
132
doc/stdenv.xml
132
doc/stdenv.xml
@ -194,33 +194,52 @@ genericBuild
|
||||
tools.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<variablelist>
|
||||
<title>Variables specifying dependencies</title>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>nativeBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
A list of dependencies used by the new derivation at <emphasis>build</emphasis>-time.
|
||||
I.e. these dependencies should not make it into the package's runtime-closure, though this is currently not checked.
|
||||
For each dependency <replaceable>dir</replaceable>, the directory <filename><replaceable>dir</replaceable>/bin</filename>, if it exists, is added to the <envar>PATH</envar> environment variable.
|
||||
Other environment variables are also set up via a pluggable mechanism.
|
||||
For instance, if <varname>buildInputs</varname> contains Perl, then the <filename>lib/site_perl</filename> subdirectory of each input is added to the <envar>PERL5LIB</envar> environment variable.
|
||||
See <xref linkend="ssec-setup-hooks"/> for details.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>buildInputs</varname></term>
|
||||
<listitem><para>A list of dependencies used by
|
||||
<literal>stdenv</literal> to set up the environment for the build.
|
||||
For each dependency <replaceable>dir</replaceable>, the directory
|
||||
<filename><replaceable>dir</replaceable>/bin</filename>, if it
|
||||
exists, is added to the <envar>PATH</envar> environment variable.
|
||||
Other environment variables are also set up via a pluggable
|
||||
mechanism. For instance, if <varname>buildInputs</varname>
|
||||
contains Perl, then the <filename>lib/site_perl</filename>
|
||||
subdirectory of each input is added to the <envar>PERL5LIB</envar>
|
||||
environment variable. See <xref linkend="ssec-setup-hooks"/> for
|
||||
details.</para></listitem>
|
||||
<listitem><para>
|
||||
A list of dependencies used by the new derivation at <emphasis>run</emphasis>-time.
|
||||
Currently, the build-time environment is modified in the exact same way as with <varname>nativeBuildInputs</varname>.
|
||||
This is problematic in that when cross-compiling, foreign executables can clobber native ones on the <envar>PATH</envar>.
|
||||
Even more confusing is static-linking.
|
||||
A statically-linked library should be listed here because ultimately that generated machine code will be used at run-time, even though a derivation containing the object files or static archives will only be used at build-time.
|
||||
A less confusing solution to this would be nice.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedNativeBuildInputs</varname></term>
|
||||
<listitem><para>
|
||||
Like <varname>nativeBuildInputs</varname>, but these dependencies are <emphasis>propagated</emphasis>:
|
||||
that is, the dependencies listed here are added to the <varname>nativeBuildInputs</varname> of any package that uses <emphasis>this</emphasis> package as a dependency.
|
||||
So if package Y has <literal>propagatedBuildInputs = [X]</literal>, and package Z has <literal>buildInputs = [Y]</literal>, then package X will appear in Z’s build environment automatically.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>propagatedBuildInputs</varname></term>
|
||||
<listitem><para>Like <varname>buildInputs</varname>, but these
|
||||
dependencies are <emphasis>propagated</emphasis>: that is, the
|
||||
dependencies listed here are added to the
|
||||
<varname>buildInputs</varname> of any package that uses
|
||||
<emphasis>this</emphasis> package as a dependency. So if package
|
||||
Y has <literal>propagatedBuildInputs = [X]</literal>, and package
|
||||
Z has <literal>buildInputs = [Y]</literal>, then package X will
|
||||
appear in Z’s build environment automatically.</para></listitem>
|
||||
<listitem><para>
|
||||
Like <varname>buildInputs</varname>, but propagated just like <varname>propagatedNativeBuildInputs</varname>.
|
||||
This inherits <varname>buildInputs</varname>'s flaws of clobbering native executables when cross-compiling and being confusing for static linking.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
</variablelist>
|
||||
|
||||
@ -322,7 +341,7 @@ executed and in what order:
|
||||
$preInstallPhases installPhase fixupPhase $preDistPhases
|
||||
distPhase $postPhases</literal>.
|
||||
</para>
|
||||
|
||||
|
||||
<para>Usually, if you just want to add a few phases, it’s more
|
||||
convenient to set one of the variables below (such as
|
||||
<varname>preInstallPhases</varname>), as you then don’t specify
|
||||
@ -706,7 +725,7 @@ makeFlagsArray=(CFLAGS="-O0 -g" LDFLAGS="-lfoo -lbar")
|
||||
</variablelist>
|
||||
|
||||
|
||||
<para>
|
||||
<para>
|
||||
You can set flags for <command>make</command> through the
|
||||
<varname>makeFlags</varname> variable.</para>
|
||||
|
||||
@ -773,7 +792,7 @@ doCheck = true;</programlisting>
|
||||
|
||||
</variablelist>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
@ -840,12 +859,12 @@ install phase. The default <function>fixupPhase</function> does the
|
||||
following:
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
|
||||
<listitem><para>It moves the <filename>man/</filename>,
|
||||
<filename>doc/</filename> and <filename>info/</filename>
|
||||
subdirectories of <envar>$out</envar> to
|
||||
<filename>share/</filename>.</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>It strips libraries and executables of debug
|
||||
information.</para></listitem>
|
||||
|
||||
@ -1091,13 +1110,41 @@ functions.</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
|
||||
<varlistentry xml:id='fun-makeWrapper'>
|
||||
<term><function>makeWrapper</function>
|
||||
<replaceable>executable</replaceable>
|
||||
<replaceable>wrapperfile</replaceable>
|
||||
<replaceable>args</replaceable></term>
|
||||
<listitem><para>Constructs a wrapper for a program with various
|
||||
possible arguments. For example:
|
||||
|
||||
<programlisting>
|
||||
# adds `FOOBAR=baz` to `$out/bin/foo`’s environment
|
||||
makeWrapper $out/bin/foo $wrapperfile --set FOOBAR baz
|
||||
|
||||
# prefixes the binary paths of `hello` and `git`
|
||||
# Be advised that paths often should be patched in directly
|
||||
# (via string replacements or in `configurePhase`).
|
||||
makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello git ]}
|
||||
</programlisting>
|
||||
|
||||
There’s many more kinds of arguments, they are documented in
|
||||
<literal>nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh</literal>.</para>
|
||||
|
||||
<para><literal>wrapProgram</literal> is a convenience function you probably
|
||||
want to use most of the time.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='fun-substitute'>
|
||||
<term><function>substitute</function>
|
||||
<replaceable>infile</replaceable>
|
||||
<replaceable>outfile</replaceable>
|
||||
<replaceable>subs</replaceable></term>
|
||||
|
||||
|
||||
<listitem>
|
||||
<para>Performs string substitution on the contents of
|
||||
<replaceable>infile</replaceable>, writing the result to
|
||||
@ -1125,7 +1172,7 @@ functions.</para>
|
||||
<literal>@<replaceable>...</replaceable>@</literal> in the
|
||||
template as placeholders.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--subst-var-by</option>
|
||||
<replaceable>varName</replaceable>
|
||||
@ -1134,7 +1181,7 @@ functions.</para>
|
||||
<literal>@<replaceable>varName</replaceable>@</literal> by
|
||||
the string <replaceable>s</replaceable>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
@ -1162,7 +1209,7 @@ substitute ./foo.in ./foo.out \
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
<varlistentry xml:id='fun-substituteInPlace'>
|
||||
<term><function>substituteInPlace</function>
|
||||
@ -1173,7 +1220,7 @@ substitute ./foo.in ./foo.out \
|
||||
<replaceable>file</replaceable>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
<varlistentry xml:id='fun-substituteAll'>
|
||||
<term><function>substituteAll</function>
|
||||
<replaceable>infile</replaceable>
|
||||
@ -1233,7 +1280,7 @@ echo @foo@
|
||||
<listitem><para>Strips the directory and hash part of a store
|
||||
path, outputting the name part to <literal>stdout</literal>.
|
||||
For example:
|
||||
|
||||
|
||||
<programlisting>
|
||||
# prints coreutils-8.24
|
||||
stripHash "/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
@ -1241,7 +1288,7 @@ stripHash "/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
|
||||
If you wish to store the result in another variable, then the
|
||||
following idiom may be useful:
|
||||
|
||||
|
||||
<programlisting>
|
||||
name="/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
|
||||
someVar=$(stripHash $name)
|
||||
@ -1249,8 +1296,24 @@ someVar=$(stripHash $name)
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
<varlistentry xml:id='fun-wrapProgram'>
|
||||
<term><function>wrapProgram</function>
|
||||
<replaceable>executable</replaceable>
|
||||
<replaceable>makeWrapperArgs</replaceable></term>
|
||||
<listitem><para>Convenience function for <literal>makeWrapper</literal>
|
||||
that automatically creates a sane wrapper file
|
||||
|
||||
It takes all the same arguments as <literal>makeWrapper</literal>,
|
||||
except for <literal>--argv0</literal>.</para>
|
||||
|
||||
<para>It cannot be applied multiple times, since it will overwrite the wrapper
|
||||
file.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
@ -1607,4 +1670,3 @@ Arch Wiki</link>.
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
@ -15,10 +15,10 @@ rec {
|
||||
the original derivation attributes.
|
||||
|
||||
`overrideDerivation' allows certain "ad-hoc" customisation
|
||||
scenarios (e.g. in ~/.nixpkgs/config.nix). For instance, if you
|
||||
want to "patch" the derivation returned by a package function in
|
||||
Nixpkgs to build another version than what the function itself
|
||||
provides, you can do something like this:
|
||||
scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
|
||||
if you want to "patch" the derivation returned by a package
|
||||
function in Nixpkgs to build another version than what the
|
||||
function itself provides, you can do something like this:
|
||||
|
||||
mySed = overrideDerivation pkgs.gnused (oldAttrs: {
|
||||
name = "sed-4.2.2-pre";
|
||||
@ -106,11 +106,9 @@ rec {
|
||||
let
|
||||
f = if builtins.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
||||
finalArgs = auto // args;
|
||||
pkgs = f finalArgs;
|
||||
mkAttrOverridable = name: pkg: pkg // {
|
||||
override = newArgs: mkAttrOverridable name (f (finalArgs // newArgs)).${name};
|
||||
};
|
||||
origArgs = auto // args;
|
||||
pkgs = f origArgs;
|
||||
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||
in lib.mapAttrs mkAttrOverridable pkgs;
|
||||
|
||||
|
||||
|
@ -191,6 +191,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
free = false;
|
||||
};
|
||||
|
||||
eupl11 = spdx {
|
||||
spdxId = "EUPL-1.1";
|
||||
fullname = "European Union Public License 1.1";
|
||||
};
|
||||
|
||||
fdl12 = spdx {
|
||||
spdxId = "GFDL-1.2";
|
||||
fullName = "GNU Free Documentation License v1.2";
|
||||
@ -374,6 +379,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Mozilla Public License 2.0";
|
||||
};
|
||||
|
||||
mspl = spdx {
|
||||
spdxId = "MS-PL";
|
||||
fullName = "Microsoft Public License";
|
||||
};
|
||||
|
||||
msrla = {
|
||||
fullName = "Microsoft Research License Agreement";
|
||||
url = "http://research.microsoft.com/en-us/projects/pex/msr-la.txt";
|
||||
|
@ -20,6 +20,7 @@
|
||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
||||
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
|
||||
aflatter = "Alexander Flatter <flatter@fastmail.fm>";
|
||||
afldcr = "James Alexander Feldman-Crough <alex@fldcr.com>";
|
||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
||||
afranchuk = "Alex Franchuk <alex.franchuk@gmail.com>";
|
||||
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
|
||||
@ -81,11 +82,13 @@
|
||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
||||
canndrew = "Andrew Cann <shum@canndrew.org>";
|
||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
||||
chattered = "Phil Scott <me@philscotted.com>";
|
||||
changlinli = "Changlin Li <mail@changlinli.com>";
|
||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||
@ -111,6 +114,7 @@
|
||||
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
||||
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
||||
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
||||
dancek = "Hannu Hartikainen <hannu.hartikainen@gmail.com>";
|
||||
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
|
||||
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
||||
davidak = "David Kleuker <post@davidak.de>";
|
||||
@ -138,6 +142,7 @@
|
||||
dtzWill = "Will Dietz <nix@wdtz.org>";
|
||||
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
||||
ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
|
||||
edanaher = "Evan Danaher <nixos@edanaher.net>";
|
||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
||||
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
||||
@ -227,6 +232,7 @@
|
||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
||||
jonafato = "Jon Banafato <jon@jonafato.com>";
|
||||
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
||||
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
||||
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
||||
@ -244,6 +250,7 @@
|
||||
koral = "Koral <koral@mailoo.org>";
|
||||
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
|
||||
kragniz = "Louis Taylor <louis@kragniz.eu>";
|
||||
kristoff3r = "Kristoffer Søholm <k.soeholm@gmail.com>";
|
||||
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
||||
lassulus = "Lassulus <lassulus@gmail.com>";
|
||||
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
||||
@ -270,6 +277,7 @@
|
||||
luispedro = "Luis Pedro Coelho <luis@luispedro.org>";
|
||||
lukego = "Luke Gorrie <luke@snabb.co>";
|
||||
lw = "Sergey Sofeychuk <lw@fmap.me>";
|
||||
ma27 = "Maximilian Bosch <maximilian@mbosch.me>";
|
||||
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
||||
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
|
||||
mahe = "Matthias Herrmann <matthias.mh.herrmann@gmail.com>";
|
||||
@ -290,12 +298,14 @@
|
||||
mbbx6spp = "Susan Potter <me@susanpotter.net>";
|
||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
||||
mbrgm = "Marius Bergmann <marius@yeai.de>";
|
||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
||||
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
||||
mguentner = "Maximilian Güntner <code@klandest.in>";
|
||||
mic92 = "Jörg Thalheim <joerg@higgsboson.tk>";
|
||||
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
||||
michalrus = "Michal Rus <m@michalrus.com>";
|
||||
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
||||
@ -329,6 +339,7 @@
|
||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
||||
nckx = "Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>";
|
||||
ndowens = "Nathan Owens <ndowens04@gmail.com>";
|
||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
||||
nhooyr = "Anmol Sethi <anmol@aubble.com>";
|
||||
@ -336,6 +347,7 @@
|
||||
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
||||
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
||||
nixy = "Andrew R. M. <andrewmiller237@gmail.com>";
|
||||
nocoolnametom = "Tom Doggett <nocoolnametom@gmail.com>";
|
||||
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
||||
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
||||
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
||||
@ -349,12 +361,14 @@
|
||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
||||
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
||||
orivej = "Orivej Desh <orivej@gmx.fr>";
|
||||
osener = "Ozan Sener <ozan@ozansener.com>";
|
||||
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
|
||||
oxij = "Jan Malakhovski <oxij@oxij.org>";
|
||||
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
||||
paperdigits = "Mica Semrick <mica@silentumbrella.com>";
|
||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
||||
periklis = "theopompos@gmail.com";
|
||||
@ -375,6 +389,7 @@
|
||||
pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
|
||||
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
|
||||
polyrod = "Maurizio Di Pietro <dc1mdp@gmail.com>";
|
||||
pradeepchhetri = "Pradeep Chhetri <pradeep.chhetri89@gmail.com>";
|
||||
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
|
||||
primeos = "Michael Weiss <dev.primeos@gmail.com>";
|
||||
profpatsch = "Profpatsch <mail@profpatsch.de>";
|
||||
@ -411,8 +426,10 @@
|
||||
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
||||
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
||||
rongcuid = "Rongcui Dong <rongcuid@outlook.com>";
|
||||
ronny = "Ronny Pfannschmidt <nixos@ronnypfannschmidt.de>";
|
||||
rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
|
||||
rtreffer = "Rene Treffer <treffer+nixos@measite.de>";
|
||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
||||
@ -453,6 +470,7 @@
|
||||
SShrike = "Severen Redwood <severen@shrike.me>";
|
||||
stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
|
||||
sternenseemann = "Lukas Epple <post@lukasepple.de>";
|
||||
stesie = "Stefan Siegl <stesie@brokenpipe.de>";
|
||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
||||
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
||||
@ -477,7 +495,7 @@
|
||||
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
||||
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
||||
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
||||
ttuegel = "Thomas Tuegel <ttuegel@gmail.com>";
|
||||
ttuegel = "Thomas Tuegel <ttuegel@mailbox.org>";
|
||||
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
||||
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
||||
tvorog = "Marsel Zaripov <marszaripov@gmail.com>";
|
||||
@ -492,6 +510,7 @@
|
||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
||||
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
||||
vifino = "Adrian Pistol <vifino@tty.sh>";
|
||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
||||
vklquevs = "vklquevs <vklquevs@gmail.com>";
|
||||
@ -511,8 +530,10 @@
|
||||
womfoo = "Kranium Gikos Mendoza <kranium@gikos.net>";
|
||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
||||
xwvvvvwx = "David Terry <davidterry@posteo.de>";
|
||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
||||
yochai = "Yochai <yochai@titat.info>";
|
||||
yorickvp = "Yorick van Pelt <yorickvanpelt@gmail.com>";
|
||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
||||
|
@ -326,7 +326,7 @@ rec {
|
||||
# Type-check the remaining definitions, and merge them.
|
||||
mergedValue = foldl' (res: def:
|
||||
if type.check def.value then res
|
||||
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${type.name}.")
|
||||
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${type.description}.")
|
||||
(type.merge loc defsFinal) defsFinal;
|
||||
|
||||
isDefined = defsFinal != [];
|
||||
|
@ -15,10 +15,10 @@ rec {
|
||||
freebsd = ["i686-freebsd" "x86_64-freebsd"];
|
||||
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
|
||||
illumos = ["x86_64-solaris"];
|
||||
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "mips64el-linux"];
|
||||
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mips64el-linux"];
|
||||
netbsd = ["i686-netbsd" "x86_64-netbsd"];
|
||||
openbsd = ["i686-openbsd" "x86_64-openbsd"];
|
||||
unix = linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos;
|
||||
|
||||
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux"];
|
||||
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux"];
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ rec {
|
||||
|
||||
cleanSource = builtins.filterSource cleanSourceFilter;
|
||||
|
||||
# Filter sources by a list of regular expressions.
|
||||
#
|
||||
# E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
|
||||
sourceByRegex = src: regexes: builtins.filterSource (path: type:
|
||||
let relPath = lib.removePrefix (toString src + "/") (toString path);
|
||||
in lib.any (re: builtins.match re relPath != null) regexes) src;
|
||||
|
||||
# Get all files ending with the specified suffices from the given
|
||||
# directory or its descendants. E.g. `sourceFilesBySuffices ./dir
|
||||
|
@ -115,6 +115,11 @@ set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-
|
||||
checkConfigError 'The option .* defined in .* does not exist.' "$@"
|
||||
checkConfigOutput "true" "$@" ./define-module-check.nix
|
||||
|
||||
# Check coerced value.
|
||||
checkConfigOutput "\"42\"" config.value ./declare-coerced-value.nix
|
||||
checkConfigOutput "\"24\"" config.value ./declare-coerced-value.nix ./define-value-string.nix
|
||||
checkConfigError 'The option value .* in .* is not a string or integer.' config.value ./declare-coerced-value.nix ./define-value-list.nix
|
||||
|
||||
cat <<EOF
|
||||
====== module tests ======
|
||||
$pass Pass
|
||||
|
10
lib/tests/modules/declare-coerced-value.nix
Normal file
10
lib/tests/modules/declare-coerced-value.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
options = {
|
||||
value = lib.mkOption {
|
||||
default = 42;
|
||||
type = lib.types.coercedTo lib.types.int builtins.toString lib.types.str;
|
||||
};
|
||||
};
|
||||
}
|
3
lib/tests/modules/define-value-list.nix
Normal file
3
lib/tests/modules/define-value-list.nix
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
value = [];
|
||||
}
|
3
lib/tests/modules/define-value-string.nix
Normal file
3
lib/tests/modules/define-value-string.nix
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
value = "24";
|
||||
}
|
@ -102,25 +102,7 @@ rec {
|
||||
min = x: y: if x < y then x else y;
|
||||
max = x: y: if x > y then x else y;
|
||||
|
||||
/* Reads a JSON file. It is useful to import pure data into other nix
|
||||
expressions.
|
||||
|
||||
Example:
|
||||
|
||||
mkDerivation {
|
||||
src = fetchgit (importJSON ./repo.json)
|
||||
#...
|
||||
}
|
||||
|
||||
where repo.json contains:
|
||||
|
||||
{
|
||||
"url": "git://some-domain/some/repo",
|
||||
"rev": "265de7283488964f44f0257a8b4a055ad8af984d",
|
||||
"sha256": "0sb3h3067pzf3a7mlxn1hikpcjrsvycjcnj9hl9b1c3ykcgvps7h"
|
||||
}
|
||||
|
||||
*/
|
||||
/* Reads a JSON file. */
|
||||
importJSON = path:
|
||||
builtins.fromJSON (builtins.readFile path);
|
||||
|
||||
|
@ -352,6 +352,28 @@ rec {
|
||||
functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; };
|
||||
};
|
||||
|
||||
coercedTo = coercedType: coerceFunc: finalType:
|
||||
assert coercedType.getSubModules == null;
|
||||
mkOptionType rec {
|
||||
name = "coercedTo";
|
||||
description = "${finalType.description} or ${coercedType.description}";
|
||||
check = x: finalType.check x || coercedType.check x;
|
||||
merge = loc: defs:
|
||||
let
|
||||
coerceVal = val:
|
||||
if finalType.check val then val
|
||||
else let
|
||||
coerced = coerceFunc val;
|
||||
in assert finalType.check coerced; coerced;
|
||||
|
||||
in finalType.merge loc (map (def: def // { value = coerceVal def.value; }) defs);
|
||||
getSubOptions = finalType.getSubOptions;
|
||||
getSubModules = finalType.getSubModules;
|
||||
substSubModules = m: coercedTo coercedType coerceFunc (finalType.substSubModules m);
|
||||
typeMerge = t1: t2: null;
|
||||
functor = (defaultFunctor name) // { wrapped = finalType; };
|
||||
};
|
||||
|
||||
# Obsolete alternative to configOf. It takes its option
|
||||
# declarations from the ‘options’ attribute of containing option
|
||||
# declaration.
|
||||
|
89
maintainers/scripts/hydra-eval-failures.py
Executable file
89
maintainers/scripts/hydra-eval-failures.py
Executable file
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python -p pythonFull pythonPackages.requests pythonPackages.pyquery pythonPackages.click
|
||||
|
||||
# To use, just execute this script with --help to display help.
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
import click
|
||||
import requests
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
|
||||
maintainers_json = subprocess.check_output([
|
||||
'nix-instantiate',
|
||||
'lib/maintainers.nix',
|
||||
'--eval',
|
||||
'--json'])
|
||||
maintainers = json.loads(maintainers_json)
|
||||
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
||||
|
||||
|
||||
def get_response_text(url):
|
||||
return pq(requests.get(url).text) # IO
|
||||
|
||||
EVAL_FILE = {
|
||||
'nixos': 'nixos/release.nix',
|
||||
'nixpkgs': 'pkgs/top-level/release.nix',
|
||||
}
|
||||
|
||||
|
||||
def get_maintainers(attr_name):
|
||||
nixname = attr_name.split('.')
|
||||
meta_json = subprocess.check_output([
|
||||
'nix-instantiate',
|
||||
'--eval',
|
||||
'--strict',
|
||||
'-A',
|
||||
'.'.join(nixname[1:]) + '.meta',
|
||||
EVAL_FILE[nixname[0]],
|
||||
'--json'])
|
||||
meta = json.loads(meta_json)
|
||||
if meta.get('maintainers'):
|
||||
return [MAINTAINERS[name] for name in meta['maintainers'] if MAINTAINERS.get(name)]
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option(
|
||||
'--jobset',
|
||||
default="nixos/release-16.09",
|
||||
help='Hydra project like nixos/release-16.09')
|
||||
def cli(jobset):
|
||||
"""
|
||||
Given a Hydra project, inspect latest evaluation
|
||||
and print a summary of failed builds
|
||||
"""
|
||||
|
||||
url = "http://hydra.nixos.org/jobset/{}".format(jobset)
|
||||
|
||||
# get the last evaluation
|
||||
click.echo(click.style(
|
||||
'Getting latest evaluation for {}'.format(url), fg='green'))
|
||||
d = get_response_text(url)
|
||||
evaluations = d('#tabs-evaluations').find('a[class="row-link"]')
|
||||
latest_eval_url = evaluations[0].get('href')
|
||||
|
||||
# parse last evaluation page
|
||||
click.echo(click.style(
|
||||
'Parsing evaluation {}'.format(latest_eval_url), fg='green'))
|
||||
d = get_response_text(latest_eval_url + '?full=1')
|
||||
|
||||
# TODO: aborted evaluations
|
||||
# TODO: dependency failed without propagated builds
|
||||
for tr in d('img[alt="Failed"]').parents('tr'):
|
||||
a = pq(tr)('a')[1]
|
||||
print "- [ ] [{}]({})".format(a.text, a.get('href'))
|
||||
|
||||
maintainers = get_maintainers(a.text)
|
||||
if maintainers:
|
||||
print " - maintainers: {}".format(", ".join(map(lambda u: '@' + u, maintainers)))
|
||||
# TODO: print last three persons that touched this file
|
||||
# TODO: pinpoint the diff that broke this build, or maybe it's transient or maybe it never worked?
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
cli()
|
||||
except:
|
||||
import pdb;pdb.post_mortem()
|
@ -21,6 +21,7 @@ effect after you run <command>nixos-rebuild</command>.</para>
|
||||
<xi:include href="user-mgmt.xml" />
|
||||
<xi:include href="file-systems.xml" />
|
||||
<xi:include href="x-windows.xml" />
|
||||
<xi:include href="xfce.xml" />
|
||||
<xi:include href="networking.xml" />
|
||||
<xi:include href="linux-kernel.xml" />
|
||||
|
||||
|
@ -22,5 +22,25 @@ boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>As with IPv4 networking interfaces are automatically configured via
|
||||
DHCPv6. You can configure an interface manually:
|
||||
|
||||
<programlisting>
|
||||
networking.interfaces.eth0.ip6 = [ { address = "fe00:aa:bb:cc::2"; prefixLength = 64; } ];
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>For configuring a gateway, optionally with explicitly specified interface:
|
||||
|
||||
<programlisting>
|
||||
networking.defaultGateway6 = {
|
||||
address = "fe00::1";
|
||||
interface = "enp0s3";
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>See <xref linkend='sec-ipv4' /> for similar examples and additional information.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
@ -37,6 +37,10 @@ boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-
|
||||
fileSystems."/".device = "/dev/mapper/crypted";
|
||||
</programlisting>
|
||||
|
||||
Should grub be used as bootloader, and <filename>/boot</filename> is located
|
||||
on an encrypted partition, it is necessary to add the following grub option:
|
||||
<programlisting>boot.loader.grub.enableCryptodisk = true;</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
@ -36,9 +36,8 @@ latter might look like this:
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{ services.xserver.enable = true;
|
||||
services.xserver.displayManager.kdm.enable = true;
|
||||
services.xserver.desktopManager.kde4.enable = true;
|
||||
environment.systemPackages = [ pkgs.kde4.kscreensaver ];
|
||||
services.xserver.displayManager.sddm.enable = true;
|
||||
services.xserver.desktopManager.kde5.enable = true;
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
|
@ -36,7 +36,10 @@ to set a password, which is retained across invocations of
|
||||
and /etc/group will be congruent to your NixOS configuration. For instance,
|
||||
if you remove a user from users.extraUsers and run nixos-rebuild, the user
|
||||
account will cease to exist. Also, imperative commands for managing users
|
||||
and groups, such as useradd, are no longer available.</para>
|
||||
and groups, such as useradd, are no longer available. Passwords may still be
|
||||
assigned by setting the user's <literal>hashedPassword</literal> option. A
|
||||
hashed password can be generated using <command>mkpasswd -m sha-512</command>
|
||||
after installing the <literal>mkpasswd</literal> package.</para>
|
||||
|
||||
<para>A user ID (uid) is assigned automatically. You can also specify
|
||||
a uid manually by adding
|
||||
|
@ -25,7 +25,7 @@ Otherwise, you can only log into a plain undecorated
|
||||
<command>xterm</command> window. Thus you should pick one or more of
|
||||
the following lines:
|
||||
<programlisting>
|
||||
services.xserver.desktopManager.kde4.enable = true;
|
||||
services.xserver.desktopManager.kde5.enable = true;
|
||||
services.xserver.desktopManager.xfce.enable = true;
|
||||
services.xserver.windowManager.xmonad.enable = true;
|
||||
services.xserver.windowManager.twm.enable = true;
|
||||
@ -35,9 +35,9 @@ services.xserver.windowManager.icewm.enable = true;
|
||||
|
||||
<para>NixOS’s default <emphasis>display manager</emphasis> (the
|
||||
program that provides a graphical login prompt and manages the X
|
||||
server) is SLiM. You can select KDE’s <command>kdm</command> instead:
|
||||
server) is SLiM. You can select KDE’s <command>sddm</command> instead:
|
||||
<programlisting>
|
||||
services.xserver.displayManager.kdm.enable = true;
|
||||
services.xserver.displayManager.sddm.enable = true;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
|
105
nixos/doc/manual/configuration/xfce.xml
Normal file
105
nixos/doc/manual/configuration/xfce.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<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-xfce">
|
||||
|
||||
<title>Xfce Desktop Environment</title>
|
||||
|
||||
<para>
|
||||
To enable the Xfce Desktop Environment, set
|
||||
<programlisting>
|
||||
services.xserver.desktopManager = {
|
||||
xfce.enable = true;
|
||||
default = "xfce";
|
||||
};
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Optionally, <emphasis>compton</emphasis>
|
||||
can be enabled for nice graphical effects, some example settings:
|
||||
<programlisting>
|
||||
services.compton = {
|
||||
enable = true;
|
||||
fade = true;
|
||||
inactiveOpacity = "0.9";
|
||||
shadow = true;
|
||||
fadeDelta = 4;
|
||||
};
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some Xfce programs are not installed automatically.
|
||||
To install them manually (system wide), put them into your
|
||||
<literal>environment.systemPackages</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NixOS’s default <emphasis>display manager</emphasis>is SLiM.
|
||||
(DM is the program that provides a graphical login prompt
|
||||
and manages the X server.)
|
||||
You can, for example, select KDE’s
|
||||
<command>sddm</command> instead:
|
||||
<programlisting>
|
||||
services.xserver.displayManager.sddm.enable = true;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<simplesect>
|
||||
<title>Thunar Volume Support</title>
|
||||
|
||||
<para>
|
||||
To enable
|
||||
<emphasis>Thunar</emphasis>
|
||||
volume support, put
|
||||
<programlisting>
|
||||
services.xserver.desktopManager.xfce.enable = true;
|
||||
</programlisting>
|
||||
into your <emphasis>configuration.nix</emphasis>.
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Polkit Authentication Agent</title>
|
||||
|
||||
<para>
|
||||
There is no authentication agent automatically installed alongside
|
||||
Xfce. To allow mounting of local (non-removable) filesystems, you
|
||||
will need to install one.
|
||||
|
||||
Installing <emphasis>polkit_gnome</emphasis>, a rebuild, logout and
|
||||
login did the trick.
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Troubleshooting</title>
|
||||
|
||||
<para>
|
||||
Even after enabling udisks2, volume management might not work.
|
||||
Thunar and/or the desktop takes time to show up.
|
||||
|
||||
Thunar will spit out this kind of message on start
|
||||
(look at journalctl --user -b).
|
||||
|
||||
<programlisting>
|
||||
Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported
|
||||
</programlisting>
|
||||
|
||||
This is caused by some needed GNOME services not running.
|
||||
This is all fixed by enabling "Launch GNOME services on startup" in
|
||||
the Advanced tab of the Session and Startup settings panel.
|
||||
Alternatively, you can run this command to do the same thing.
|
||||
<programlisting>
|
||||
$ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true
|
||||
</programlisting>
|
||||
A log-out and re-log will be needed for this to take effect.
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
</chapter>
|
@ -65,22 +65,22 @@ options = {
|
||||
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-option-declarations-eot"><title>Extensible Option
|
||||
<section xml:id="sec-option-declarations-eot"><title>Extensible Option
|
||||
Types</title>
|
||||
|
||||
<para>Extensible option types is a feature that allow to extend certain types
|
||||
<para>Extensible option types is a feature that allow to extend certain types
|
||||
declaration through multiple module files.
|
||||
This feature only work with a restricted set of types, namely
|
||||
This feature only work with a restricted set of types, namely
|
||||
<literal>enum</literal> and <literal>submodules</literal> and any composed
|
||||
forms of them.</para>
|
||||
|
||||
<para>Extensible option types can be used for <literal>enum</literal> options
|
||||
that affects multiple modules, or as an alternative to related
|
||||
<para>Extensible option types can be used for <literal>enum</literal> options
|
||||
that affects multiple modules, or as an alternative to related
|
||||
<literal>enable</literal> options.</para>
|
||||
|
||||
<para>As an example, we will take the case of display managers. There is a
|
||||
central display manager module for generic display manager options and a
|
||||
module file per display manager backend (slim, kdm, gdm ...).
|
||||
module file per display manager backend (slim, sddm, gdm ...).
|
||||
</para>
|
||||
|
||||
<para>There are two approach to this module structure:
|
||||
@ -96,7 +96,7 @@ options = {
|
||||
</para>
|
||||
|
||||
<para>Both approachs have problems.</para>
|
||||
|
||||
|
||||
<para>Making backends independent can quickly become hard to manage. For
|
||||
display managers, there can be only one enabled at a time, but the type
|
||||
system can not enforce this restriction as there is no relation between
|
||||
@ -108,18 +108,18 @@ options = {
|
||||
central module will require to change the central module option every time
|
||||
a new backend is added or removed.</para>
|
||||
|
||||
<para>By using extensible option types, it is possible to create a placeholder
|
||||
option in the central module (<xref linkend='ex-option-declaration-eot-service'
|
||||
/>), and to extend it in each backend module (<xref
|
||||
linkend='ex-option-declaration-eot-backend-slim' />, <xref
|
||||
linkend='ex-option-declaration-eot-backend-kdm' />).</para>
|
||||
|
||||
<para>By using extensible option types, it is possible to create a placeholder
|
||||
option in the central module (<xref linkend='ex-option-declaration-eot-service'
|
||||
/>), and to extend it in each backend module (<xref
|
||||
linkend='ex-option-declaration-eot-backend-slim' />, <xref
|
||||
linkend='ex-option-declaration-eot-backend-sddm' />).</para>
|
||||
|
||||
<para>As a result, <literal>displayManager.enable</literal> option values can
|
||||
be added without changing the main service module file and the type system
|
||||
automatically enforce that there can only be a single display manager
|
||||
enabled.</para>
|
||||
|
||||
<example xml:id='ex-option-declaration-eot-service'><title>Extensible type
|
||||
<example xml:id='ex-option-declaration-eot-service'><title>Extensible type
|
||||
placeholder in the service module</title>
|
||||
<screen>
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
@ -127,29 +127,29 @@ services.xserver.displayManager.enable = mkOption {
|
||||
type = with types; nullOr (enum [ ]);
|
||||
};</screen></example>
|
||||
|
||||
<example xml:id='ex-option-declaration-eot-backend-slim'><title>Extending
|
||||
<literal>services.xserver.displayManager.enable</literal> in the
|
||||
<example xml:id='ex-option-declaration-eot-backend-slim'><title>Extending
|
||||
<literal>services.xserver.displayManager.enable</literal> in the
|
||||
<literal>slim</literal> module</title>
|
||||
<screen>
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
type = with types; nullOr (enum [ "slim" ]);
|
||||
};</screen></example>
|
||||
|
||||
<example xml:id='ex-option-declaration-eot-backend-kdm'><title>Extending
|
||||
<literal>services.foo.backend</literal> in the <literal>kdm</literal>
|
||||
<example xml:id='ex-option-declaration-eot-backend-sddm'><title>Extending
|
||||
<literal>services.foo.backend</literal> in the <literal>sddm</literal>
|
||||
module</title>
|
||||
<screen>
|
||||
services.xserver.displayManager.enable = mkOption {
|
||||
type = with types; nullOr (enum [ "kdm" ]);
|
||||
type = with types; nullOr (enum [ "sddm" ]);
|
||||
};</screen></example>
|
||||
|
||||
<para>The placeholder declaration is a standard <literal>mkOption</literal>
|
||||
declaration, but it is important that extensible option declarations only use
|
||||
<para>The placeholder declaration is a standard <literal>mkOption</literal>
|
||||
declaration, but it is important that extensible option declarations only use
|
||||
the <literal>type</literal> argument.</para>
|
||||
|
||||
<para>Extensible option types work with any of the composed variants of
|
||||
<literal>enum</literal> such as
|
||||
<literal>with types; nullOr (enum [ "foo" "bar" ])</literal>
|
||||
<para>Extensible option types work with any of the composed variants of
|
||||
<literal>enum</literal> such as
|
||||
<literal>with types; nullOr (enum [ "foo" "bar" ])</literal>
|
||||
or <literal>with types; listOf (enum [ "foo" "bar" ])</literal>.</para>
|
||||
|
||||
</section>
|
||||
|
@ -37,6 +37,11 @@
|
||||
first disable network-manager with
|
||||
<command>systemctl stop network-manager</command>.</para></listitem>
|
||||
|
||||
<listitem><para>If you would like to continue the installation from a different
|
||||
machine you need to activate the SSH daemon via <literal>systemctl start sshd</literal>.
|
||||
In order to be able to login you also need to set a password for
|
||||
<literal>root</literal> using <literal>passwd</literal>.</para></listitem>
|
||||
|
||||
<listitem><para>The NixOS installer doesn’t do any partitioning or
|
||||
formatting yet, so you need to do that yourself. Use the following
|
||||
commands:
|
||||
|
@ -15,6 +15,21 @@ has the following highlights: </para>
|
||||
xlink:href="https://nixos.org/nixpkgs/manual/#sec-overlays-install">Nixpkgs
|
||||
manual</link> for more information.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The setuid wrapper functionality now supports setting
|
||||
capabilities.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>X.org server uses branch 1.19. Due to ABI incompatibilities,
|
||||
<literal>ati_unfree</literal> keeps forcing 1.17
|
||||
and <literal>amdgpu-pro</literal> starts forcing 1.18.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>PHP now defaults to PHP 7.1</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The following new services were added since the last release:</para>
|
||||
@ -30,6 +45,15 @@ has the following highlights: </para>
|
||||
following incompatible changes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Cross compilation has been rewritten. See the nixpkgs manual for
|
||||
details. The most obvious breaking change is that derivations absent a
|
||||
<literal>.nativeDrv</literal> or <literal>.crossDrv</literal> are now
|
||||
cross by default, not native.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>stdenv.overrides</literal> is now expected to take <literal>self</literal>
|
||||
@ -38,6 +62,15 @@ following incompatible changes:</para>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>ansible</literal> now defaults to ansible version 2 as version 1
|
||||
has been removed due to a serious <link
|
||||
xlink:href="https://www.computest.nl/advisories/CT-2017-0109_Ansible.txt">
|
||||
vulnerability</link> unpatched by upstream.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>gnome</literal> alias has been removed along with
|
||||
@ -79,6 +112,15 @@ following incompatible changes:</para>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Two lone top-level dict dbs moved into <literal>dictdDBs</literal>. This
|
||||
affects: <literal>dictdWordnet</literal> which is now at
|
||||
<literal>dictdDBs.wordnet</literal> and <literal>dictdWiktionary</literal>
|
||||
which is now at <literal>dictdDBs.wiktionary</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Parsoid service now uses YAML configuration format.
|
||||
@ -100,7 +142,36 @@ following incompatible changes:</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>service.nylon</literal> is now declared using named instances.
|
||||
As an example:
|
||||
|
||||
<programlisting>
|
||||
services.nylon = {
|
||||
enable = true;
|
||||
acceptInterface = "br0";
|
||||
bindInterface = "tun1";
|
||||
port = 5912;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
should be replaced with:
|
||||
|
||||
<programlisting>
|
||||
services.nylon.myvpn = {
|
||||
enable = true;
|
||||
acceptInterface = "br0";
|
||||
bindInterface = "tun1";
|
||||
port = 5912;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
this enables you to declare a SOCKS proxy for each uplink.
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>overridePackages</literal> function no longer exists.
|
||||
It is replaced by <link
|
||||
xlink:href="https://nixos.org/nixpkgs/manual/#sec-overlays-install">
|
||||
@ -124,18 +195,52 @@ following incompatible changes:</para>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Autoloading connection tracking helpers is now disabled by default.
|
||||
This default was also changed in the Linux kernel and is considered
|
||||
insecure if not configured properly in your firewall. If you need
|
||||
connection tracking helpers (i.e. for active FTP) please enable
|
||||
<literal>networking.firewall.autoLoadConntrackHelpers</literal> and
|
||||
tune <literal>networking.firewall.connectionTrackingModules</literal>
|
||||
to suit your needs.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>local_recipient_maps</literal> is not set to empty value by
|
||||
Postfix service. It's an insecure default as stated by Postfix
|
||||
documentation. Those who want to retain this setting need to set it via
|
||||
<literal>services.postfix.extraConfig</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<para>Other notable improvements:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>Module type system have a new extensible option types feature that
|
||||
allow to extend certain types, such as enum, through multiple option
|
||||
declarations of the same option across multiple modules.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>jre</literal> now defaults to GTK+ UI by default. This
|
||||
improves visual consistency and makes Java follow system font style,
|
||||
improving the situation on HighDPI displays. This has a cost of increased
|
||||
closure size; for server and other headless workloads it's recommended to
|
||||
use <literal>jre_headless</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
|
@ -508,7 +508,7 @@ sub screenshot {
|
||||
sub getTTYText {
|
||||
my ($self, $tty) = @_;
|
||||
|
||||
my ($status, $out) = $self->execute("fold -w 80 /dev/vcs${tty}");
|
||||
my ($status, $out) = $self->execute("fold -w\$(stty -F /dev/tty${tty} size | awk '{print \$2}') /dev/vcs${tty}");
|
||||
return $out;
|
||||
}
|
||||
|
||||
@ -607,7 +607,8 @@ sub waitForWindow {
|
||||
sub copyFileFromHost {
|
||||
my ($self, $from, $to) = @_;
|
||||
my $s = `cat $from` or die;
|
||||
$self->mustSucceed("echo '$s' > $to"); # !!! escaping
|
||||
$s =~ s/'/'\\''/g;
|
||||
$self->mustSucceed("echo '$s' > $to");
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,7 +108,7 @@ in {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to include the 32-bit pulseaudio libraries in the systemn or not.
|
||||
Whether to include the 32-bit pulseaudio libraries in the system or not.
|
||||
This is only useful on 64-bit systems and currently limited to x86_64-linux.
|
||||
'';
|
||||
};
|
||||
|
@ -168,7 +168,7 @@ in
|
||||
|
||||
${cfg.extraInit}
|
||||
|
||||
# The setuid wrappers override other bin directories.
|
||||
# The setuid/setcap wrappers override other bin directories.
|
||||
export PATH="${config.security.wrapperDir}:$PATH"
|
||||
|
||||
# ~/bin if it exists overrides other bin directories.
|
||||
|
@ -133,13 +133,10 @@ in
|
||||
'';
|
||||
|
||||
environment.sessionVariables.LD_LIBRARY_PATH =
|
||||
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
|
||||
[ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib";
|
||||
|
||||
environment.extraInit = ''
|
||||
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver/share
|
||||
'' + optionalString cfg.driSupport32Bit ''
|
||||
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver-32/share
|
||||
'';
|
||||
environment.variables.XDG_DATA_DIRS =
|
||||
[ "/run/opengl-driver/share" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/share";
|
||||
|
||||
hardware.opengl.package = mkDefault (makePackage pkgs);
|
||||
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
|
||||
|
@ -21,6 +21,8 @@ in
|
||||
|
||||
config = mkIf enabled {
|
||||
|
||||
nixpkgs.config.xorg.abiCompat = "1.18";
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "amdgpu"; modules = [ package ]; libPath = [ package ]; };
|
||||
|
||||
@ -44,9 +46,6 @@ in
|
||||
"amd/amdrc".source = package + "/etc/amd/amdrc";
|
||||
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
||||
"gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf";
|
||||
"OpenCL/vendors/amdocl64.icd".source = package + "/etc/OpenCL/vendors/amdocl64.icd";
|
||||
} // optionalAttrs opengl.driSupport32Bit {
|
||||
"OpenCL/vendors/amdocl32.icd".source = package32 + "/etc/OpenCL/vendors/amdocl32.icd";
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ in
|
||||
|
||||
config = mkIf enabled {
|
||||
|
||||
nixpkgs.config.xorg.fglrxCompat = true;
|
||||
nixpkgs.config.xorg.abiCompat = "1.17";
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; };
|
||||
|
@ -76,8 +76,8 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
boot.blacklistedKernelModules = [ "nvidia-drm" "nvidia" "nouveau" ];
|
||||
boot.kernelModules = optional useBbswitch [ "bbswitch" ];
|
||||
boot.extraModulePackages = optional useBbswitch kernel.bbswitch ++ optional useNvidia kernel.nvidia_x11;
|
||||
boot.kernelModules = optional useBbswitch "bbswitch";
|
||||
boot.extraModulePackages = optional useBbswitch kernel.bbswitch ++ optional useNvidia kernel.nvidia_x11.bin;
|
||||
|
||||
environment.systemPackages = [ bumblebee primus ];
|
||||
|
||||
|
61
nixos/modules/hardware/video/capture/mwprocapture.nix
Normal file
61
nixos/modules/hardware/video/capture/mwprocapture.nix
Normal file
@ -0,0 +1,61 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.hardware.mwProCapture;
|
||||
|
||||
kernelPackages = config.boot.kernelPackages;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options.hardware.mwProCapture.enable = mkEnableOption "Magewell Pro Capture family kernel module";
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = singleton {
|
||||
assertion = versionAtLeast kernelPackages.kernel.version "3.2";
|
||||
message = "Magewell Pro Capture family module is not supported for kernels older than 3.2";
|
||||
};
|
||||
|
||||
boot.kernelModules = [ "ProCapture" ];
|
||||
|
||||
environment.systemPackages = [ kernelPackages.mwprocapture ];
|
||||
|
||||
boot.extraModulePackages = [ kernelPackages.mwprocapture ];
|
||||
|
||||
boot.extraModprobeConfig = ''
|
||||
# Set the png picture to be displayed when no input signal is detected.
|
||||
options ProCapture nosignal_file=${kernelPackages.mwprocapture}/res/NoSignal.png
|
||||
|
||||
# Set the png picture to be displayed when an unsupported input signal is detected.
|
||||
options ProCapture unsupported_file=${kernelPackages.mwprocapture}/res/Unsupported.png
|
||||
|
||||
# Set the png picture to be displayed when an loking input signal is detected.
|
||||
options ProCapture locking_file=${kernelPackages.mwprocapture}/res/Locking.png
|
||||
|
||||
# Message signaled interrupts switch
|
||||
#options ProCapture disable_msi=0
|
||||
|
||||
# Set the debug level
|
||||
#options ProCapture debug_level=0
|
||||
|
||||
# Force init switch eeprom
|
||||
#options ProCapture init_switch_eeprom=0
|
||||
|
||||
# Min frame interval for VIDIOC_ENUM_FRAMEINTERVALS (default: 166666(100ns))
|
||||
#options ProCapture enum_frameinterval_min=166666
|
||||
|
||||
# VIDIOC_ENUM_FRAMESIZES type (1: DISCRETE; 2: STEPWISE; otherwise: CONTINUOUS )
|
||||
#options ProCapture enum_framesizes_type=0
|
||||
|
||||
# Parameters for internal usage
|
||||
#options ProCapture internal_params=""
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -27,6 +27,13 @@ let
|
||||
nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
|
||||
nvidia_libs32 = (nvidiaForKernel pkgs_i686.linuxPackages).override { libsOnly = true; kernel = null; };
|
||||
|
||||
nvidiaPackage = nvidia: pkgs:
|
||||
if !nvidia.useGLVND then nvidia
|
||||
else pkgs.buildEnv {
|
||||
name = "nvidia-libs";
|
||||
paths = [ pkgs.libglvnd nvidia.out ];
|
||||
};
|
||||
|
||||
enabled = nvidia_x11 != null;
|
||||
in
|
||||
|
||||
@ -35,19 +42,23 @@ in
|
||||
config = mkIf enabled {
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "nvidia"; modules = [ nvidia_x11 ]; libPath = [ nvidia_x11 ]; };
|
||||
{ name = "nvidia"; modules = [ nvidia_x11.bin ]; libPath = [ nvidia_x11 ]; };
|
||||
|
||||
services.xserver.screenSection =
|
||||
''
|
||||
Option "RandRRotation" "on"
|
||||
'';
|
||||
|
||||
hardware.opengl.package = nvidia_x11;
|
||||
hardware.opengl.package32 = nvidia_libs32;
|
||||
environment.etc."nvidia/nvidia-application-profiles-rc" = mkIf nvidia_x11.useProfiles {
|
||||
source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ nvidia_x11 ];
|
||||
hardware.opengl.package = nvidiaPackage nvidia_x11 pkgs;
|
||||
hardware.opengl.package32 = nvidiaPackage nvidia_libs32 pkgs_i686;
|
||||
|
||||
boot.extraModulePackages = [ nvidia_x11 ];
|
||||
environment.systemPackages = [ nvidia_x11.bin nvidia_x11.settings nvidia_x11.persistenced ];
|
||||
|
||||
boot.extraModulePackages = [ nvidia_x11.bin ];
|
||||
|
||||
# nvidia-uvm is required by CUDA applications.
|
||||
boot.kernelModules = [ "nvidia-uvm" ];
|
||||
@ -62,8 +73,6 @@ in
|
||||
|
||||
services.acpid.enable = true;
|
||||
|
||||
environment.etc."OpenCL/vendors/nvidia.icd".source = "${nvidia_x11}/lib/vendors/nvidia.icd";
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ in
|
||||
panel = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = literalExample "${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
|
||||
example = literalExample "''${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
|
||||
description = "Replace the IBus panel with another panel.";
|
||||
};
|
||||
};
|
||||
|
61
nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
Normal file
61
nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
Normal file
@ -0,0 +1,61 @@
|
||||
# To build, use:
|
||||
# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-aarch64.nix -A config.system.build.sdImage
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
extlinux-conf-builder =
|
||||
import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
|
||||
inherit pkgs;
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../../profiles/minimal.nix
|
||||
../../profiles/installation-device.nix
|
||||
./sd-image.nix
|
||||
];
|
||||
|
||||
assertions = lib.singleton {
|
||||
assertion = pkgs.stdenv.system == "aarch64-linux";
|
||||
message = "sd-image-aarch64.nix can be only built natively on Aarch64 / ARM64; " +
|
||||
"it cannot be cross compiled";
|
||||
};
|
||||
|
||||
# Needed by RPi firmware
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||
boot.kernelParams = ["console=ttyS0,115200n8" "console=tty0"];
|
||||
boot.consoleLogLevel = 7;
|
||||
|
||||
# FIXME: this probably should be in installation-device.nix
|
||||
users.extraUsers.root.initialHashedPassword = "";
|
||||
|
||||
sdImage = {
|
||||
populateBootCommands = let
|
||||
# Contains a couple of fixes for booting a Linux kernel, will hopefully appear upstream soon.
|
||||
patchedUboot = pkgs.ubootRaspberryPi3_64bit.overrideAttrs (oldAttrs: {
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "dezgeg";
|
||||
repo = "u-boot";
|
||||
rev = "baab53ec244fe44def01948a0f10e67342d401e6";
|
||||
sha256 = "0r5j2pc42ws3w3im0a9c6bh01czz5kapqrqp0ik9ra823cw73lxr";
|
||||
};
|
||||
});
|
||||
|
||||
configTxt = pkgs.writeText "config.txt" ''
|
||||
kernel=u-boot-rpi3.bin
|
||||
arm_control=0x200
|
||||
enable_uart=1
|
||||
'';
|
||||
in ''
|
||||
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/boot/)
|
||||
cp ${patchedUboot}/u-boot.bin boot/u-boot-rpi3.bin
|
||||
cp ${configTxt} boot/config.txt
|
||||
${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
|
||||
'';
|
||||
};
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
# To build, use:
|
||||
# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
@ -42,11 +44,9 @@ in
|
||||
enable_uart=1
|
||||
'';
|
||||
in ''
|
||||
for f in bootcode.bin fixup.dat start.elf; do
|
||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/$f boot/
|
||||
done
|
||||
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/boot/)
|
||||
cp ${pkgs.ubootRaspberryPi2}/u-boot.bin boot/u-boot-rpi2.bin
|
||||
cp ${pkgs.ubootRaspberryPi3}/u-boot.bin boot/u-boot-rpi3.bin
|
||||
cp ${pkgs.ubootRaspberryPi3_32bit}/u-boot.bin boot/u-boot-rpi3.bin
|
||||
cp ${configTxt} boot/config.txt
|
||||
${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
|
||||
'';
|
||||
|
@ -1,3 +1,5 @@
|
||||
# To build, use:
|
||||
# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix -A config.system.build.sdImage
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
@ -32,9 +34,7 @@ in
|
||||
|
||||
sdImage = {
|
||||
populateBootCommands = ''
|
||||
for f in bootcode.bin fixup.dat start.elf; do
|
||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/$f boot/
|
||||
done
|
||||
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/boot/)
|
||||
cp ${pkgs.ubootRaspberryPi}/u-boot.bin boot/u-boot-rpi.bin
|
||||
echo 'kernel u-boot-rpi.bin' > boot/config.txt
|
||||
${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
|
||||
|
@ -1,4 +1,4 @@
|
||||
# List all devices which are detected by nixos-hardware-scan.
|
||||
# List all devices which are detected by nixos-generate-config.
|
||||
# Common devices are enabled by default.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# List all devices which are _not_ detected by nixos-hardware-scan.
|
||||
# List all devices which are _not_ detected by nixos-generate-config.
|
||||
# Common devices are enabled by default.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
|
@ -208,9 +208,6 @@ foreach my $path (glob "/sys/bus/pci/devices/*") {
|
||||
pciCheck $path;
|
||||
}
|
||||
|
||||
push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];" if $videoDriver;
|
||||
|
||||
|
||||
# Idem for USB devices.
|
||||
|
||||
sub usbCheck {
|
||||
@ -277,6 +274,12 @@ if ($virt eq "qemu" || $virt eq "kvm" || $virt eq "bochs") {
|
||||
push @imports, "<nixpkgs/nixos/modules/profiles/qemu-guest.nix>";
|
||||
}
|
||||
|
||||
# Also for Hyper-V.
|
||||
if ($virt eq "microsoft") {
|
||||
push @initrdAvailableKernelModules, "hv_storvsc";
|
||||
$videoDriver = "fbdev";
|
||||
}
|
||||
|
||||
|
||||
# Pull in NixOS configuration for containers.
|
||||
if ($virt eq "systemd-nspawn") {
|
||||
@ -307,6 +310,7 @@ sub findStableDevPath {
|
||||
return $dev;
|
||||
}
|
||||
|
||||
push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];" if $videoDriver;
|
||||
|
||||
# Generate the swapDevices option from the currently activated swap
|
||||
# devices.
|
||||
@ -343,7 +347,6 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
||||
|
||||
# Skip special filesystems.
|
||||
next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs";
|
||||
next if $mountPoint eq "/var/setuid-wrappers";
|
||||
|
||||
# Skip the optional fields.
|
||||
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
|
||||
@ -588,6 +591,12 @@ $bootLoaderConfig
|
||||
# Enable the OpenSSH daemon.
|
||||
# services.openssh.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
# Enable CUPS to print documents.
|
||||
# services.printing.enable = true;
|
||||
|
||||
@ -597,8 +606,8 @@ $bootLoaderConfig
|
||||
# services.xserver.xkbOptions = "eurosign:e";
|
||||
|
||||
# Enable the KDE Desktop Environment.
|
||||
# services.xserver.displayManager.kdm.enable = true;
|
||||
# services.xserver.desktopManager.kde4.enable = true;
|
||||
# services.xserver.displayManager.sddm.enable = true;
|
||||
# services.xserver.desktopManager.kde5.enable = true;
|
||||
|
||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||
# users.extraUsers.guest = {
|
||||
|
@ -259,9 +259,9 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate
|
||||
|
||||
|
||||
# Ask the user to set a root password.
|
||||
if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /var/setuid-wrappers/passwd ] && [ -t 0 ]; then
|
||||
if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/bin/passwd ] && [ -t 0 ]; then
|
||||
echo "setting root password..."
|
||||
chroot $mountPoint /var/setuid-wrappers/passwd
|
||||
chroot $mountPoint /run/wrappers/bin/passwd
|
||||
fi
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@ origArgs=("$@")
|
||||
extraBuildFlags=()
|
||||
action=
|
||||
buildNix=1
|
||||
fast=
|
||||
rollback=
|
||||
upgrade=
|
||||
repair=
|
||||
@ -52,13 +53,13 @@ while [ "$#" -gt 0 ]; do
|
||||
repair=1
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q)
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--max-jobs|-j|--cores|-I)
|
||||
j="$1"; shift 1
|
||||
extraBuildFlags+=("$i" "$j")
|
||||
;;
|
||||
--show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
|
||||
extraBuildFlags+=("$i")
|
||||
;;
|
||||
--option)
|
||||
j="$1"; shift 1
|
||||
k="$1"; shift 1
|
||||
@ -66,6 +67,7 @@ while [ "$#" -gt 0 ]; do
|
||||
;;
|
||||
--fast)
|
||||
buildNix=
|
||||
fast=1
|
||||
extraBuildFlags+=(--show-trace)
|
||||
;;
|
||||
--profile-name|-p)
|
||||
@ -217,7 +219,7 @@ if [ -z "$_NIXOS_REBUILD_REEXEC" ]; then
|
||||
fi
|
||||
|
||||
# Re-execute nixos-rebuild from the Nixpkgs tree.
|
||||
if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" ]; then
|
||||
if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" -a -z "$fast" ]; then
|
||||
if p=$(nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
|
||||
export _NIXOS_REBUILD_REEXEC=1
|
||||
exec $p/bin/nixos-rebuild "${origArgs[@]}"
|
||||
|
@ -64,7 +64,7 @@
|
||||
cups = 36;
|
||||
foldingathome = 37;
|
||||
sabnzbd = 38;
|
||||
kdm = 39;
|
||||
#kdm = 39; # dropped in 17.03
|
||||
ghostone = 40;
|
||||
git = 41;
|
||||
fourstore = 42;
|
||||
@ -206,7 +206,7 @@
|
||||
ripple-data-api = 186;
|
||||
mediatomb = 187;
|
||||
rdnssd = 188;
|
||||
ihaskell = 189;
|
||||
# ihaskell = 189; # unused
|
||||
i2p = 190;
|
||||
lambdabot = 191;
|
||||
asterisk = 192;
|
||||
@ -284,6 +284,10 @@
|
||||
glance = 266;
|
||||
couchpotato = 267;
|
||||
gogs = 268;
|
||||
pdns-recursor = 269;
|
||||
kresd = 270;
|
||||
rpc = 271;
|
||||
geoip = 272;
|
||||
|
||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||
|
||||
@ -330,7 +334,7 @@
|
||||
#cups = 36; # unused
|
||||
#foldingathome = 37; # unused
|
||||
#sabnzd = 38; # unused
|
||||
#kdm = 39; # unused
|
||||
#kdm = 39; # unused, even before 17.03
|
||||
ghostone = 40;
|
||||
git = 41;
|
||||
fourstore = 42;
|
||||
@ -467,7 +471,7 @@
|
||||
#ripple-data-api = 186; #unused
|
||||
mediatomb = 187;
|
||||
#rdnssd = 188; # unused
|
||||
ihaskell = 189;
|
||||
# ihaskell = 189; # unused
|
||||
i2p = 190;
|
||||
lambdabot = 191;
|
||||
asterisk = 192;
|
||||
@ -538,6 +542,9 @@
|
||||
glance = 266;
|
||||
couchpotato = 267;
|
||||
gogs = 268;
|
||||
kresd = 270;
|
||||
#rpc = 271; # unused
|
||||
#geoip = 272; # unused
|
||||
|
||||
# When adding a gid, make sure it doesn't match an existing
|
||||
# uid. Users and groups with the same name should have equal
|
||||
|
@ -4,10 +4,12 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.locate;
|
||||
isMLocate = hasPrefix "mlocate" cfg.locate.name;
|
||||
isFindutils = hasPrefix "findutils" cfg.locate.name;
|
||||
in {
|
||||
options.services.locate = {
|
||||
options.services.locate = with types; {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled, NixOS will periodically update the database of
|
||||
@ -16,8 +18,9 @@ in {
|
||||
};
|
||||
|
||||
locate = mkOption {
|
||||
type = types.package;
|
||||
type = package;
|
||||
default = pkgs.findutils;
|
||||
defaultText = "pkgs.findutils";
|
||||
example = "pkgs.mlocate";
|
||||
description = ''
|
||||
The locate implementation to use
|
||||
@ -25,7 +28,7 @@ in {
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "02:15";
|
||||
example = "hourly";
|
||||
description = ''
|
||||
@ -38,11 +41,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
# This is no longer supported, but we keep it to give a better warning below
|
||||
period = mkOption { visible = false; };
|
||||
|
||||
extraFlags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Extra flags to pass to <command>updatedb</command>.
|
||||
@ -50,7 +50,7 @@ in {
|
||||
};
|
||||
|
||||
output = mkOption {
|
||||
type = types.path;
|
||||
type = path;
|
||||
default = "/var/cache/locatedb";
|
||||
description = ''
|
||||
The database file to build.
|
||||
@ -58,7 +58,7 @@ in {
|
||||
};
|
||||
|
||||
localuser = mkOption {
|
||||
type = types.str;
|
||||
type = nullOr str;
|
||||
default = "nobody";
|
||||
description = ''
|
||||
The user to search non-network directories as, using
|
||||
@ -66,31 +66,82 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
includeStore = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
pruneFS = mkOption {
|
||||
type = listOf str;
|
||||
default = ["afs" "anon_inodefs" "auto" "autofs" "bdev" "binfmt" "binfmt_misc" "cgroup" "cifs" "coda" "configfs" "cramfs" "cpuset" "debugfs" "devfs" "devpts" "devtmpfs" "ecryptfs" "eventpollfs" "exofs" "futexfs" "ftpfs" "fuse" "fusectl" "gfs" "gfs2" "hostfs" "hugetlbfs" "inotifyfs" "iso9660" "jffs2" "lustre" "misc" "mqueue" "ncpfs" "nnpfs" "ocfs" "ocfs2" "pipefs" "proc" "ramfs" "rpc_pipefs" "securityfs" "selinuxfs" "sfs" "shfs" "smbfs" "sockfs" "spufs" "nfs" "NFS" "nfs4" "nfsd" "sshfs" "subfs" "supermount" "sysfs" "tmpfs" "ubifs" "udf" "usbfs" "vboxsf" "vperfctrfs" ];
|
||||
description = ''
|
||||
Whether to include <filename>/nix/store</filename> in the locate database.
|
||||
Which filesystem types to exclude from indexing
|
||||
'';
|
||||
};
|
||||
|
||||
prunePaths = mkOption {
|
||||
type = listOf path;
|
||||
default = ["/tmp" "/var/tmp" "/var/cache" "/var/lock" "/var/run" "/var/spool" "/nix/store"];
|
||||
description = ''
|
||||
Which paths to exclude from indexing
|
||||
'';
|
||||
};
|
||||
|
||||
pruneNames = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
Directory components which should exclude paths containing them from indexing
|
||||
'';
|
||||
};
|
||||
|
||||
pruneBindMounts = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether not to index bind mounts
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
warnings =
|
||||
let opt = options.services.locate.period; in
|
||||
optional opt.isDefined "The ‘services.locate.period’ option in ${showFiles opt.files} has been removed; please replace it with ‘services.locate.interval’, using the systemd.time(7) calendar event format.";
|
||||
config = mkIf cfg.enable {
|
||||
users.extraGroups = mkIf isMLocate { mlocate = {}; };
|
||||
|
||||
security.wrappers = mkIf isMLocate {
|
||||
mlocate = {
|
||||
group = "mlocate";
|
||||
owner = "root";
|
||||
permissions = "u+rx,g+x,o+x";
|
||||
setgid = true;
|
||||
setuid = false;
|
||||
program = "locate";
|
||||
};
|
||||
};
|
||||
|
||||
nixpkgs.config = { locate.dbfile = cfg.output; };
|
||||
|
||||
environment.systemPackages = [ cfg.locate ];
|
||||
|
||||
environment.variables = mkIf (!isMLocate)
|
||||
{ LOCATE_PATH = cfg.output;
|
||||
};
|
||||
|
||||
warnings = optional (isMLocate && cfg.localuser != null) "mlocate does not support searching as user other than root"
|
||||
++ optional (isFindutils && cfg.pruneNames != []) "findutils locate does not support pruning by directory component"
|
||||
++ optional (isFindutils && cfg.pruneBindMounts) "findutils locate does not support skipping bind mounts";
|
||||
|
||||
systemd.services.update-locatedb =
|
||||
{ description = "Update Locate Database";
|
||||
path = [ pkgs.su ];
|
||||
path = mkIf (!isMLocate) [ pkgs.su ];
|
||||
script =
|
||||
''
|
||||
mkdir -m 0755 -p $(dirname ${toString cfg.output})
|
||||
install -m ${if isMLocate then "0750" else "0755"} -o root -g ${if isMLocate then "mlocate" else "root"} -d $(dirname ${cfg.output})
|
||||
exec ${cfg.locate}/bin/updatedb \
|
||||
--localuser=${cfg.localuser} \
|
||||
${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
|
||||
${optionalString (cfg.localuser != null) ''--localuser=${cfg.localuser}''} \
|
||||
--output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
environment = {
|
||||
PRUNEFS = concatStringsSep " " cfg.pruneFS;
|
||||
PRUNEPATHS = concatStringsSep " " cfg.prunePaths;
|
||||
PRUNENAMES = concatStringsSep " " cfg.pruneNames;
|
||||
PRUNE_BIND_MOUNTS = if cfg.pruneBindMounts then "yes" else "no";
|
||||
};
|
||||
serviceConfig.Nice = 19;
|
||||
serviceConfig.IOSchedulingClass = "idle";
|
||||
serviceConfig.PrivateTmp = "yes";
|
||||
@ -100,7 +151,7 @@ in {
|
||||
serviceConfig.ReadWriteDirectories = dirOf cfg.output;
|
||||
};
|
||||
|
||||
systemd.timers.update-locatedb = mkIf cfg.enable
|
||||
systemd.timers.update-locatedb =
|
||||
{ description = "Update timer for locate database";
|
||||
partOf = [ "update-locatedb.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
|
@ -45,9 +45,8 @@ let
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
nixpkgs.config = mkOption {
|
||||
options.nixpkgs = {
|
||||
config = mkOption {
|
||||
default = {};
|
||||
example = literalExample
|
||||
''
|
||||
@ -61,7 +60,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
nixpkgs.overlays = mkOption {
|
||||
overlays = mkOption {
|
||||
default = [];
|
||||
example = literalExample
|
||||
''
|
||||
@ -85,7 +84,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
nixpkgs.system = mkOption {
|
||||
system = mkOption {
|
||||
type = types.str;
|
||||
example = "i686-linux";
|
||||
description = ''
|
||||
@ -95,14 +94,9 @@ in
|
||||
multi-platform deployment, or when building virtual machines.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
_module.args.pkgs = import ../../.. {
|
||||
system = config.nixpkgs.system;
|
||||
|
||||
inherit (config.nixpkgs) config;
|
||||
};
|
||||
_module.args.pkgs = import ../../.. config.nixpkgs;
|
||||
};
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
./hardware/video/amdgpu.nix
|
||||
./hardware/video/amdgpu-pro.nix
|
||||
./hardware/video/ati.nix
|
||||
./hardware/video/capture/mwprocapture.nix
|
||||
./hardware/video/bumblebee.nix
|
||||
./hardware/video/displaylink.nix
|
||||
./hardware/video/nvidia.nix
|
||||
@ -80,6 +81,7 @@
|
||||
./programs/light.nix
|
||||
./programs/man.nix
|
||||
./programs/mosh.nix
|
||||
./programs/mtr.nix
|
||||
./programs/nano.nix
|
||||
./programs/oblogout.nix
|
||||
./programs/screen.nix
|
||||
@ -113,7 +115,7 @@
|
||||
./security/prey.nix
|
||||
./security/rngd.nix
|
||||
./security/rtkit.nix
|
||||
./security/setuid-wrappers.nix
|
||||
./security/wrappers/default.nix
|
||||
./security/sudo.nix
|
||||
./services/amqp/activemq/default.nix
|
||||
./services/amqp/rabbitmq.nix
|
||||
@ -141,6 +143,7 @@
|
||||
./services/computing/torque/mom.nix
|
||||
./services/computing/slurm/slurm.nix
|
||||
./services/continuous-integration/buildbot/master.nix
|
||||
./services/continuous-integration/buildbot/worker.nix
|
||||
./services/continuous-integration/buildkite-agent.nix
|
||||
./services/continuous-integration/hydra/default.nix
|
||||
./services/continuous-integration/gitlab-runner.nix
|
||||
@ -197,6 +200,7 @@
|
||||
./services/hardware/bluetooth.nix
|
||||
./services/hardware/brltty.nix
|
||||
./services/hardware/freefall.nix
|
||||
./services/hardware/illum.nix
|
||||
./services/hardware/irqbalance.nix
|
||||
./services/hardware/nvidia-optimus.nix
|
||||
./services/hardware/pcscd.nix
|
||||
@ -205,6 +209,7 @@
|
||||
./services/hardware/tcsd.nix
|
||||
./services/hardware/tlp.nix
|
||||
./services/hardware/thinkfan.nix
|
||||
./services/hardware/trezord.nix
|
||||
./services/hardware/udev.nix
|
||||
./services/hardware/udisks2.nix
|
||||
./services/hardware/upower.nix
|
||||
@ -212,6 +217,7 @@
|
||||
./services/logging/awstats.nix
|
||||
./services/logging/fluentd.nix
|
||||
./services/logging/graylog.nix
|
||||
./services/logging/journalbeat.nix
|
||||
./services/logging/klogd.nix
|
||||
./services/logging/logcheck.nix
|
||||
./services/logging/logrotate.nix
|
||||
@ -255,12 +261,13 @@
|
||||
./services/misc/felix.nix
|
||||
./services/misc/folding-at-home.nix
|
||||
./services/misc/gammu-smsd.nix
|
||||
./services/misc/geoip-updater.nix
|
||||
#./services/misc/gitit.nix
|
||||
./services/misc/gitlab.nix
|
||||
./services/misc/gitolite.nix
|
||||
./services/misc/gogs.nix
|
||||
./services/misc/gpsd.nix
|
||||
./services/misc/ihaskell.nix
|
||||
#./services/misc/ihaskell.nix
|
||||
./services/misc/leaps.nix
|
||||
./services/misc/mantisbt.nix
|
||||
./services/misc/mathics.nix
|
||||
@ -289,6 +296,7 @@
|
||||
./services/misc/siproxd.nix
|
||||
./services/misc/sonarr.nix
|
||||
./services/misc/spice-vdagentd.nix
|
||||
./services/misc/ssm-agent.nix
|
||||
./services/misc/sssd.nix
|
||||
./services/misc/subsonic.nix
|
||||
./services/misc/sundtek.nix
|
||||
@ -327,15 +335,18 @@
|
||||
./services/monitoring/scollector.nix
|
||||
./services/monitoring/smartd.nix
|
||||
./services/monitoring/statsd.nix
|
||||
./services/monitoring/sysstat.nix
|
||||
./services/monitoring/systemhealth.nix
|
||||
./services/monitoring/teamviewer.nix
|
||||
./services/monitoring/telegraf.nix
|
||||
./services/monitoring/ups.nix
|
||||
./services/monitoring/uptime.nix
|
||||
./services/monitoring/vnstat.nix
|
||||
./services/monitoring/zabbix-agent.nix
|
||||
./services/monitoring/zabbix-server.nix
|
||||
./services/network-filesystems/cachefilesd.nix
|
||||
./services/network-filesystems/drbd.nix
|
||||
./services/network-filesystems/glusterfs.nix
|
||||
./services/network-filesystems/ipfs.nix
|
||||
./services/network-filesystems/netatalk.nix
|
||||
./services/network-filesystems/nfsd.nix
|
||||
@ -370,6 +381,7 @@
|
||||
./services/networking/dhcpd.nix
|
||||
./services/networking/dnschain.nix
|
||||
./services/networking/dnscrypt-proxy.nix
|
||||
./services/networking/dnscrypt-wrapper.nix
|
||||
./services/networking/dnsmasq.nix
|
||||
./services/networking/ejabberd.nix
|
||||
./services/networking/fan.nix
|
||||
@ -396,6 +408,7 @@
|
||||
./services/networking/iodine.nix
|
||||
./services/networking/ircd-hybrid/default.nix
|
||||
./services/networking/kippo.nix
|
||||
./services/networking/kresd.nix
|
||||
./services/networking/lambdabot.nix
|
||||
./services/networking/libreswan.nix
|
||||
./services/networking/logmein-hamachi.nix
|
||||
@ -426,6 +439,7 @@
|
||||
./services/networking/pdnsd.nix
|
||||
./services/networking/polipo.nix
|
||||
./services/networking/powerdns.nix
|
||||
./services/networking/pdns-recursor.nix
|
||||
./services/networking/pptpd.nix
|
||||
./services/networking/prayer.nix
|
||||
./services/networking/privoxy.nix
|
||||
@ -436,6 +450,7 @@
|
||||
./services/networking/radicale.nix
|
||||
./services/networking/radvd.nix
|
||||
./services/networking/rdnssd.nix
|
||||
./services/networking/redsocks.nix
|
||||
./services/networking/rpcbind.nix
|
||||
./services/networking/sabnzbd.nix
|
||||
./services/networking/searx.nix
|
||||
@ -492,7 +507,8 @@
|
||||
./services/security/frandom.nix
|
||||
./services/security/haka.nix
|
||||
./services/security/haveged.nix
|
||||
./services/security/hologram.nix
|
||||
./services/security/hologram-server.nix
|
||||
./services/security/hologram-agent.nix
|
||||
./services/security/munge.nix
|
||||
./services/security/oauth2_proxy.nix
|
||||
./services/security/physlock.nix
|
||||
@ -516,6 +532,7 @@
|
||||
./services/web-apps/atlassian/confluence.nix
|
||||
./services/web-apps/atlassian/crowd.nix
|
||||
./services/web-apps/atlassian/jira.nix
|
||||
./services/web-apps/frab.nix
|
||||
./services/web-apps/mattermost.nix
|
||||
./services/web-apps/nixbot.nix
|
||||
./services/web-apps/pump.io.nix
|
||||
@ -546,7 +563,6 @@
|
||||
./services/x11/display-managers/auto.nix
|
||||
./services/x11/display-managers/default.nix
|
||||
./services/x11/display-managers/gdm.nix
|
||||
./services/x11/display-managers/kdm.nix
|
||||
./services/x11/display-managers/lightdm.nix
|
||||
./services/x11/display-managers/sddm.nix
|
||||
./services/x11/display-managers/slim.nix
|
||||
@ -632,6 +648,7 @@
|
||||
./virtualisation/container-config.nix
|
||||
./virtualisation/containers.nix
|
||||
./virtualisation/docker.nix
|
||||
./virtualisation/ecs-agent.nix
|
||||
./virtualisation/libvirtd.nix
|
||||
./virtualisation/lxc.nix
|
||||
./virtualisation/lxcfs.nix
|
||||
|
@ -42,6 +42,9 @@
|
||||
# Virtio (QEMU, KVM etc.) support.
|
||||
"virtio_net" "virtio_pci" "virtio_blk" "virtio_scsi" "virtio_balloon" "virtio_console"
|
||||
|
||||
# Hyper-V support.
|
||||
"hv_storvsc"
|
||||
|
||||
# Keyboards
|
||||
"usbhid" "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat"
|
||||
];
|
||||
|
@ -6,8 +6,8 @@
|
||||
{
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
displayManager.kdm.enable = true;
|
||||
desktopManager.kde4.enable = true;
|
||||
displayManager.sddm.enable = true;
|
||||
desktopManager.kde5.enable = true;
|
||||
synaptics.enable = true; # for touchpad support on many laptops
|
||||
};
|
||||
|
||||
|
@ -45,8 +45,13 @@ with lib;
|
||||
"Type `systemctl start display-manager' to\nstart the graphical user interface."}
|
||||
'';
|
||||
|
||||
# Allow sshd to be started manually through "start sshd".
|
||||
services.openssh.enable = true;
|
||||
# Allow sshd to be started manually through "systemctl start sshd".
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
# Allow password login to the installation, if the user sets a password via "passwd"
|
||||
# It is safe as root doesn't have a password by default and SSH is disabled by default
|
||||
permitRootLogin = "yes";
|
||||
};
|
||||
systemd.services.sshd.wantedBy = mkOverride 50 [];
|
||||
|
||||
# Enable wpa_supplicant, but don't start it by default.
|
||||
@ -66,9 +71,8 @@ with lib;
|
||||
boot.kernel.sysctl."vm.overcommit_memory" = "1";
|
||||
|
||||
# To speed up installation a little bit, include the complete
|
||||
# stdenv in the Nix store on the CD. Archive::Cpio is needed for
|
||||
# the initrd builder.
|
||||
system.extraDependencies = [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio ];
|
||||
# stdenv in the Nix store on the CD.
|
||||
system.extraDependencies = with pkgs; [ stdenv stdenvNoCC busybox ];
|
||||
|
||||
# Show all debug messages from the kernel but don't log refused packets
|
||||
# because we have the firewall enabled. This makes installs from the
|
||||
|
@ -17,8 +17,7 @@ in
|
||||
config = {
|
||||
|
||||
environment.variables =
|
||||
{ LOCATE_PATH = "/var/cache/locatedb";
|
||||
NIXPKGS_CONFIG = "/etc/nix/nixpkgs-config.nix";
|
||||
{ NIXPKGS_CONFIG = "/etc/nix/nixpkgs-config.nix";
|
||||
PAGER = mkDefault "less -R";
|
||||
EDITOR = mkDefault "nano";
|
||||
};
|
||||
|
@ -11,6 +11,6 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.kbdlight ];
|
||||
security.setuidPrograms = [ "kbdlight" ];
|
||||
security.wrappers.kbdlight.source = "${pkgs.kbdlight.out}/bin/kbdlight";
|
||||
};
|
||||
}
|
||||
|
@ -21,6 +21,6 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.light ];
|
||||
security.setuidPrograms = [ "light" ];
|
||||
security.wrappers.light.source = "${pkgs.light.out}/bin/light";
|
||||
};
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ with lib;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable manual pages and the <command>man</command> command.
|
||||
This also includes "man" outputs of all <literal>systemPackages</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
27
nixos/modules/programs/mtr.nix
Normal file
27
nixos/modules/programs/mtr.nix
Normal file
@ -0,0 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.mtr;
|
||||
in {
|
||||
options = {
|
||||
programs.mtr = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to add mtr to the global environment and configure a
|
||||
setcap wrapper for it.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
security.wrappers.mtr = {
|
||||
source = "${pkgs.mtr}/bin/mtr";
|
||||
capabilities = "cap_net_raw+p";
|
||||
};
|
||||
};
|
||||
}
|
@ -101,11 +101,15 @@ in
|
||||
chpasswd = { rootOK = true; };
|
||||
};
|
||||
|
||||
security.setuidPrograms = [ "su" "chfn" ]
|
||||
++ [ "newuidmap" "newgidmap" ] # new in shadow 4.2.x
|
||||
++ lib.optionals config.users.mutableUsers
|
||||
[ "passwd" "sg" "newgrp" ];
|
||||
|
||||
security.wrappers = {
|
||||
su.source = "${pkgs.shadow.su}/bin/su";
|
||||
chfn.source = "${pkgs.shadow.out}/bin/chfn";
|
||||
newuidmap.source = "${pkgs.shadow.out}/bin/newuidmap";
|
||||
newgidmap.source = "${pkgs.shadow.out}/bin/newgidmap";
|
||||
} // (if config.users.mutableUsers then {
|
||||
passwd.source = "${pkgs.shadow.out}/bin/passwd";
|
||||
sg.source = "${pkgs.shadow.out}/bin/sg";
|
||||
newgrp.source = "${pkgs.shadow.out}/bin/newgrp";
|
||||
} else {});
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ with lib;
|
||||
(mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ])
|
||||
(mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ])
|
||||
|
||||
(mkRenamedOptionModule [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ])
|
||||
(mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
|
||||
(mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
|
||||
|
||||
@ -18,6 +17,7 @@ with lib;
|
||||
(mkRenamedOptionModule [ "services" "elasticsearch" "host" ] [ "services" "elasticsearch" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "graphite" "api" "host" ] [ "services" "graphite" "api" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "graphite" "web" "host" ] [ "services" "graphite" "web" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "logstash" "address" ] [ "services" "logstash" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "kibana" "host" ] [ "services" "kibana" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "mpd" "network" "host" ] [ "services" "mpd" "network" "listenAddress" ])
|
||||
(mkRenamedOptionModule [ "services" "neo4j" "host" ] [ "services" "neo4j" "listenAddress" ])
|
||||
@ -32,6 +32,9 @@ with lib;
|
||||
|
||||
(mkRenamedOptionModule [ "services" "clamav" "updater" "config" ] [ "services" "clamav" "updater" "extraConfig" ])
|
||||
|
||||
(mkRemovedOptionModule [ "security" "setuidOwners" ] "Use security.wrappers instead")
|
||||
(mkRemovedOptionModule [ "security" "setuidPrograms" ] "Use security.wrappers instead")
|
||||
|
||||
# Old Grub-related options.
|
||||
(mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
|
||||
(mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ])
|
||||
@ -167,6 +170,14 @@ with lib;
|
||||
# dhcpd
|
||||
(mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ])
|
||||
|
||||
# locate
|
||||
(mkRenamedOptionModule [ "services" "locate" "period" ] [ "services" "locate" "interval" ])
|
||||
(mkRemovedOptionModule [ "services" "locate" "includeStore" ] "Use services.locate.prunePaths" )
|
||||
|
||||
# nfs
|
||||
(mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ])
|
||||
(mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ])
|
||||
|
||||
# Options that are obsolete and have no replacement.
|
||||
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
|
||||
(mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
|
||||
|
@ -129,7 +129,7 @@ in
|
||||
|
||||
certs = mkOption {
|
||||
default = { };
|
||||
type = with types; loaOf (submodule certOpts);
|
||||
type = with types; attrsOf (submodule certOpts);
|
||||
description = ''
|
||||
Attribute set of certificates to get signed and renewed.
|
||||
'';
|
||||
@ -284,6 +284,8 @@ in
|
||||
OnCalendar = cfg.renewInterval;
|
||||
Unit = "acme-${cert}.service";
|
||||
Persistent = "yes";
|
||||
AccuracySec = "5m";
|
||||
RandomizedDelaySec = "1h";
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ with lib;
|
||||
config = mkIf (cfg.confineSUIDApplications) {
|
||||
security.apparmor.profiles = [ (pkgs.writeText "ping" ''
|
||||
#include <tunables/global>
|
||||
/var/setuid-wrappers/ping {
|
||||
/run/wrappers/bin/ping {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/consoles>
|
||||
#include <abstractions/nameservice>
|
||||
@ -33,7 +33,6 @@ with lib;
|
||||
${pkgs.attr.out}/lib/libattr.so* mr,
|
||||
|
||||
${pkgs.iputils}/bin/ping mixr,
|
||||
/var/setuid-wrappers/ping.real r,
|
||||
|
||||
#/etc/modules.conf r,
|
||||
|
||||
|
@ -27,6 +27,6 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ sandbox ];
|
||||
security.setuidPrograms = [ sandbox.passthru.sandboxExecutableName ];
|
||||
security.wrappers."${sandbox.passthru.sandboxExecutableName}".source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}";
|
||||
};
|
||||
}
|
||||
|
@ -187,7 +187,8 @@ in
|
||||
];
|
||||
|
||||
environment.systemPackages = [ pkgs.duo-unix ];
|
||||
security.setuidPrograms = [ "login_duo" ];
|
||||
|
||||
security.wrappers.login_duo.source = "${pkgs.duo-unix.out}/bin/login_duo";
|
||||
environment.etc = loginCfgFile ++ pamCfgFile;
|
||||
|
||||
/* If PAM *and* SSH are enabled, then don't do anything special.
|
||||
|
@ -7,21 +7,20 @@
|
||||
<title>Grsecurity/PaX</title>
|
||||
|
||||
<para>
|
||||
Grsecurity/PaX is a set of patches against the Linux kernel that make it
|
||||
harder to exploit bugs. The patchset includes protections such as
|
||||
enforcement of non-executable memory, address space layout randomization,
|
||||
and chroot jail hardening. These and other
|
||||
Grsecurity/PaX is a set of patches against the Linux kernel that
|
||||
implements an extensive suite of
|
||||
<link xlink:href="https://grsecurity.net/features.php">features</link>
|
||||
render entire classes of exploits inert without additional efforts on the
|
||||
part of the adversary.
|
||||
designed to increase the difficulty of exploiting kernel and
|
||||
application bugs.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The NixOS grsecurity/PaX module is designed with casual users in mind and is
|
||||
intended to be compatible with normal desktop usage, without unnecessarily
|
||||
compromising security. The following sections describe the configuration
|
||||
and administration of a grsecurity/PaX enabled NixOS system. For
|
||||
more comprehensive coverage, please refer to the
|
||||
intended to be compatible with normal desktop usage, without
|
||||
<emphasis>unnecessarily</emphasis> compromising security. The
|
||||
following sections describe the configuration and administration of
|
||||
a grsecurity/PaX enabled NixOS system. For more comprehensive
|
||||
coverage, please refer to the
|
||||
<link xlink:href="https://en.wikibooks.org/wiki/Grsecurity">grsecurity wikibook</link>
|
||||
and the
|
||||
<link xlink:href="https://wiki.archlinux.org/index.php/Grsecurity">Arch
|
||||
@ -35,7 +34,7 @@
|
||||
and each configuration requires quite a bit of testing to ensure that the
|
||||
resulting packages work as advertised. Defining additional package sets
|
||||
would likely result in a large number of functionally broken packages, to
|
||||
nobody's benefit.</para></note>.
|
||||
nobody's benefit.</para></note>
|
||||
</para>
|
||||
|
||||
<sect1 xml:id="sec-grsec-enable"><title>Enabling grsecurity/PaX</title>
|
||||
@ -126,10 +125,10 @@
|
||||
The NixOS kernel is built using upstream's recommended settings for a
|
||||
desktop deployment that generally favours security over performance. This
|
||||
section details deviations from upstream's recommendations that may
|
||||
compromise operational security.
|
||||
compromise security.
|
||||
|
||||
<warning><para>There may be additional problems not covered here!</para>
|
||||
</warning>.
|
||||
</warning>
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
@ -159,8 +158,8 @@
|
||||
<listitem><para>
|
||||
The NixOS module conditionally weakens <command>chroot</command>
|
||||
restrictions to accommodate NixOS lightweight containers and sandboxed Nix
|
||||
builds. This is problematic if the deployment also runs a privileged
|
||||
network facing process that <emphasis>relies</emphasis> on
|
||||
builds. This can be problematic if the deployment also runs privileged
|
||||
network facing processes that <emphasis>rely</emphasis> on
|
||||
<command>chroot</command> for isolation.
|
||||
</para></listitem>
|
||||
|
||||
@ -221,15 +220,18 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The wikibook provides an exhaustive listing of
|
||||
The grsecurity/PaX wikibook provides an exhaustive listing of
|
||||
<link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options">kernel configuration options</link>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The NixOS module makes several assumptions about the kernel and so
|
||||
may be incompatible with your customised kernel. Currently, the only way
|
||||
to work around incompatibilities is to eschew the NixOS module.
|
||||
to work around these incompatibilities is to eschew the NixOS
|
||||
module.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If not using the NixOS module, a custom grsecurity package set can
|
||||
be specified inline instead, as in
|
||||
<programlisting>
|
||||
@ -290,7 +292,7 @@
|
||||
|
||||
<listitem><para>User initiated autoloading of modules (e.g., when
|
||||
using fuse or loop devices) is disallowed; either load requisite modules
|
||||
as root or add them to<option>boot.kernelModules</option>.</para></listitem>
|
||||
as root or add them to <option>boot.kernelModules</option>.</para></listitem>
|
||||
|
||||
<listitem><para>Virtualization: KVM is the preferred virtualization
|
||||
solution. Xen, Virtualbox, and VMWare are
|
||||
|
@ -212,6 +212,17 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
enableKwallet = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
If enabled, pam_wallet will attempt to automatically unlock the
|
||||
user's default KDE wallet upon login. If the user has no wallet named
|
||||
"kdewallet", or the login password does not match their wallet
|
||||
password, KDE will prompt separately after login.
|
||||
'';
|
||||
};
|
||||
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
description = "Contents of the PAM service file.";
|
||||
@ -253,6 +264,8 @@ let
|
||||
"auth sufficient ${pkgs.pam_u2f}/lib/security/pam_u2f.so"}
|
||||
${optionalString cfg.usbAuth
|
||||
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
|
||||
${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
|
||||
"auth requisite ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"}
|
||||
'' +
|
||||
# Modules in this block require having the password set in PAM_AUTHTOK.
|
||||
# pam_unix is marked as 'sufficient' on NixOS which means nothing will run
|
||||
@ -260,19 +273,20 @@ let
|
||||
# prompts the user for password so we run it once with 'required' at an
|
||||
# earlier point and it will run again with 'sufficient' further down.
|
||||
# We use try_first_pass the second time to avoid prompting password twice
|
||||
(optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount)) ''
|
||||
(optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount || cfg.enableKwallet)) ''
|
||||
auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth
|
||||
${optionalString config.security.pam.enableEcryptfs
|
||||
"auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
||||
${optionalString cfg.pamMount
|
||||
"auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
|
||||
${optionalString cfg.enableKwallet
|
||||
("auth optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||
" kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")}
|
||||
'') + ''
|
||||
${optionalString cfg.unixAuth
|
||||
"auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"}
|
||||
${optionalString cfg.otpwAuth
|
||||
"auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"}
|
||||
${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
|
||||
"auth sufficient ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"}
|
||||
${optionalString use_ldap
|
||||
"auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"}
|
||||
${optionalString config.services.sssd.enable
|
||||
@ -334,6 +348,9 @@ let
|
||||
"session optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
|
||||
${optionalString (cfg.enableAppArmor && config.security.apparmor.enable)
|
||||
"session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
|
||||
${optionalString (cfg.enableKwallet)
|
||||
("session optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||
" kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")}
|
||||
'');
|
||||
};
|
||||
|
||||
@ -472,19 +489,20 @@ in
|
||||
++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ]
|
||||
++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ];
|
||||
|
||||
security.setuidPrograms =
|
||||
optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ];
|
||||
security.wrappers = {
|
||||
unix_chkpwd = {
|
||||
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
|
||||
owner = "root";
|
||||
setuid = true;
|
||||
};
|
||||
} // (if config.security.pam.enableEcryptfs then {
|
||||
"mount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private";
|
||||
"umount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private";
|
||||
} else {});
|
||||
|
||||
environment.etc =
|
||||
mapAttrsToList (n: v: makePAMService v) config.security.pam.services;
|
||||
|
||||
security.setuidOwners = [ {
|
||||
program = "unix_chkpwd";
|
||||
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
|
||||
owner = "root";
|
||||
setuid = true;
|
||||
} ];
|
||||
|
||||
security.pam.services =
|
||||
{ other.text =
|
||||
''
|
||||
|
@ -32,10 +32,12 @@ in
|
||||
|
||||
config = mkIf (cfg.enable || anyUsbAuth) {
|
||||
|
||||
# pmount need to have a set-uid bit to make pam_usb works in user
|
||||
# environment. (like su, sudo)
|
||||
# Make sure pmount and pumount are setuid wrapped.
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount.out}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount.out}/bin/pumount";
|
||||
};
|
||||
|
||||
security.setuidPrograms = [ "pmount" "pumount" ];
|
||||
environment.systemPackages = [ pkgs.pmount ];
|
||||
|
||||
};
|
||||
|
@ -83,16 +83,10 @@ in
|
||||
|
||||
security.pam.services.polkit-1 = {};
|
||||
|
||||
security.setuidPrograms = [ "pkexec" ];
|
||||
|
||||
security.setuidOwners = [
|
||||
{ program = "polkit-agent-helper-1";
|
||||
owner = "root";
|
||||
group = "root";
|
||||
setuid = true;
|
||||
source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
|
||||
}
|
||||
];
|
||||
security.wrappers = {
|
||||
pkexec.source = "${pkgs.polkit.out}/bin/pkexec";
|
||||
"polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
|
||||
};
|
||||
|
||||
system.activationScripts.polkit =
|
||||
''
|
||||
|
@ -1,81 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Make sure assertions are not compiled out. */
|
||||
#undef NDEBUG
|
||||
|
||||
extern char **environ;
|
||||
|
||||
static char * wrapperDir = WRAPPER_DIR;
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
char self[PATH_MAX];
|
||||
|
||||
int len = readlink("/proc/self/exe", self, sizeof(self) - 1);
|
||||
assert (len > 0);
|
||||
self[len] = 0;
|
||||
|
||||
/* Make sure that we are being executed from the right location,
|
||||
i.e., `wrapperDir'. This is to prevent someone from
|
||||
creating hard link `X' from some other location, along with a
|
||||
false `X.real' file, to allow arbitrary programs from being
|
||||
executed setuid. */
|
||||
assert ((strncmp(self, wrapperDir, strlen(wrapperDir)) == 0) &&
|
||||
(self[strlen(wrapperDir)] == '/'));
|
||||
|
||||
/* Make *really* *really* sure that we were executed as `self',
|
||||
and not, say, as some other setuid program. That is, our
|
||||
effective uid/gid should match the uid/gid of `self'. */
|
||||
//printf("%d %d\n", geteuid(), getegid());
|
||||
|
||||
struct stat st;
|
||||
assert (lstat(self, &st) != -1);
|
||||
|
||||
//printf("%d %d\n", st.st_uid, st.st_gid);
|
||||
|
||||
assert ((st.st_mode & S_ISUID) == 0 ||
|
||||
(st.st_uid == geteuid()));
|
||||
|
||||
assert ((st.st_mode & S_ISGID) == 0 ||
|
||||
st.st_gid == getegid());
|
||||
|
||||
/* And, of course, we shouldn't be writable. */
|
||||
assert (!(st.st_mode & (S_IWGRP | S_IWOTH)));
|
||||
|
||||
|
||||
/* Read the path of the real (wrapped) program from <self>.real. */
|
||||
char realFN[PATH_MAX + 10];
|
||||
int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", self);
|
||||
assert (realFNSize < sizeof(realFN));
|
||||
|
||||
int fdSelf = open(realFN, O_RDONLY);
|
||||
assert (fdSelf != -1);
|
||||
|
||||
char real[PATH_MAX];
|
||||
len = read(fdSelf, real, PATH_MAX);
|
||||
assert (len != -1);
|
||||
assert (len < sizeof (real));
|
||||
assert (len > 0);
|
||||
real[len] = 0;
|
||||
|
||||
close(fdSelf);
|
||||
|
||||
//printf("real = %s, len = %d\n", real, len);
|
||||
|
||||
execve(real, argv, environ);
|
||||
|
||||
fprintf(stderr, "%s: cannot run `%s': %s\n",
|
||||
argv[0], real, strerror(errno));
|
||||
|
||||
exit(1);
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (config.security) wrapperDir;
|
||||
|
||||
setuidWrapper = pkgs.stdenv.mkDerivation {
|
||||
name = "setuid-wrapper";
|
||||
unpackPhase = "true";
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp ${./setuid-wrapper.c} setuid-wrapper.c
|
||||
gcc -Wall -O2 -DWRAPPER_DIR=\"/run/setuid-wrapper-dirs\" \
|
||||
setuid-wrapper.c -o $out/bin/setuid-wrapper
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
security.setuidPrograms = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = ["passwd"];
|
||||
description = ''
|
||||
The Nix store cannot contain setuid/setgid programs directly.
|
||||
For this reason, NixOS can automatically generate wrapper
|
||||
programs that have the necessary privileges. This option
|
||||
lists the names of programs in the system environment for
|
||||
which setuid root wrappers should be created.
|
||||
'';
|
||||
};
|
||||
|
||||
security.setuidOwners = mkOption {
|
||||
type = types.listOf types.attrs;
|
||||
default = [];
|
||||
example =
|
||||
[ { program = "sendmail";
|
||||
owner = "nobody";
|
||||
group = "postdrop";
|
||||
setuid = false;
|
||||
setgid = true;
|
||||
permissions = "u+rx,g+x,o+x";
|
||||
}
|
||||
];
|
||||
description = ''
|
||||
This option allows the ownership and permissions on the setuid
|
||||
wrappers for specific programs to be overridden from the
|
||||
default (setuid root, but not setgid root).
|
||||
'';
|
||||
};
|
||||
|
||||
security.wrapperDir = mkOption {
|
||||
internal = true;
|
||||
type = types.path;
|
||||
default = "/var/setuid-wrappers";
|
||||
description = ''
|
||||
This option defines the path to the setuid wrappers. It
|
||||
should generally not be overriden. Some packages in Nixpkgs
|
||||
expect that <option>wrapperDir</option> is
|
||||
<filename>/var/setuid-wrappers</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
|
||||
security.setuidPrograms = [ "fusermount" ];
|
||||
|
||||
system.activationScripts.setuid =
|
||||
let
|
||||
setuidPrograms =
|
||||
(map (x: { program = x; owner = "root"; group = "root"; setuid = true; })
|
||||
config.security.setuidPrograms)
|
||||
++ config.security.setuidOwners;
|
||||
|
||||
makeSetuidWrapper =
|
||||
{ program
|
||||
, source ? ""
|
||||
, owner ? "nobody"
|
||||
, group ? "nogroup"
|
||||
, setuid ? false
|
||||
, setgid ? false
|
||||
, permissions ? "u+rx,g+x,o+x"
|
||||
}:
|
||||
|
||||
''
|
||||
if ! source=${if source != "" then source else "$(readlink -f $(PATH=$SETUID_PATH type -tP ${program}))"}; then
|
||||
# If we can't find the program, fall back to the
|
||||
# system profile.
|
||||
source=/nix/var/nix/profiles/default/bin/${program}
|
||||
fi
|
||||
|
||||
cp ${setuidWrapper}/bin/setuid-wrapper $wrapperDir/${program}
|
||||
echo -n "$source" > $wrapperDir/${program}.real
|
||||
chmod 0000 $wrapperDir/${program} # to prevent races
|
||||
chown ${owner}.${group} $wrapperDir/${program}
|
||||
chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program}
|
||||
'';
|
||||
|
||||
in stringAfter [ "users" ]
|
||||
''
|
||||
# Look in the system path and in the default profile for
|
||||
# programs to be wrapped.
|
||||
SETUID_PATH=${config.system.path}/bin:${config.system.path}/sbin
|
||||
|
||||
mkdir -p /run/setuid-wrapper-dirs
|
||||
wrapperDir=$(mktemp --directory --tmpdir=/run/setuid-wrapper-dirs setuid-wrappers.XXXXXXXXXX)
|
||||
chmod a+rx $wrapperDir
|
||||
|
||||
${concatMapStrings makeSetuidWrapper setuidPrograms}
|
||||
|
||||
if [ -L ${wrapperDir} ]; then
|
||||
# Atomically replace the symlink
|
||||
# See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
|
||||
old=$(readlink ${wrapperDir})
|
||||
ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp
|
||||
mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir}
|
||||
rm --force --recursive $old
|
||||
elif [ -d ${wrapperDir} ]; then
|
||||
# Compatibility with old state, just remove the folder and symlink
|
||||
rm -f ${wrapperDir}/*
|
||||
# if it happens to be a tmpfs
|
||||
${pkgs.utillinux}/bin/umount ${wrapperDir} || true
|
||||
rm -d ${wrapperDir}
|
||||
ln -d --symbolic $wrapperDir ${wrapperDir}
|
||||
else
|
||||
# For initial setup
|
||||
ln --symbolic $wrapperDir ${wrapperDir}
|
||||
fi
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -81,7 +81,10 @@ in
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
security.setuidPrograms = [ "sudo" "sudoedit" ];
|
||||
security.wrappers = {
|
||||
sudo.source = "${pkgs.sudo.out}/bin/sudo";
|
||||
sudoedit.source = "${pkgs.sudo.out}/bin/sudoedit";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ sudo ];
|
||||
|
||||
|
222
nixos/modules/security/wrappers/default.nix
Normal file
222
nixos/modules/security/wrappers/default.nix
Normal file
@ -0,0 +1,222 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
|
||||
inherit (config.security) wrapperDir wrappers;
|
||||
|
||||
programs =
|
||||
(lib.mapAttrsToList
|
||||
(n: v: (if v ? "program" then v else v // {program=n;}))
|
||||
wrappers);
|
||||
|
||||
securityWrapper = pkgs.stdenv.mkDerivation {
|
||||
name = "security-wrapper";
|
||||
phases = [ "installPhase" "fixupPhase" ];
|
||||
buildInputs = [ pkgs.libcap pkgs.libcap_ng pkgs.linuxHeaders ];
|
||||
hardeningEnable = [ "pie" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
parentWrapperDir=$(dirname ${wrapperDir})
|
||||
gcc -Wall -O2 -DWRAPPER_DIR=\"$parentWrapperDir\" \
|
||||
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper
|
||||
'';
|
||||
};
|
||||
|
||||
###### Activation script for the setcap wrappers
|
||||
mkSetcapProgram =
|
||||
{ program
|
||||
, capabilities
|
||||
, source
|
||||
, owner ? "nobody"
|
||||
, group ? "nogroup"
|
||||
, ...
|
||||
}:
|
||||
assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
|
||||
''
|
||||
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
|
||||
echo -n "${source}" > $wrapperDir/${program}.real
|
||||
|
||||
# Prevent races
|
||||
chmod 0000 $wrapperDir/${program}
|
||||
chown ${owner}.${group} $wrapperDir/${program}
|
||||
|
||||
# Set desired capabilities on the file plus cap_setpcap so
|
||||
# the wrapper program can elevate the capabilities set on
|
||||
# its file into the Ambient set.
|
||||
${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program}
|
||||
|
||||
# Set the executable bit
|
||||
chmod u+rx,g+x,o+x $wrapperDir/${program}
|
||||
'';
|
||||
|
||||
###### Activation script for the setuid wrappers
|
||||
mkSetuidProgram =
|
||||
{ program
|
||||
, source
|
||||
, owner ? "nobody"
|
||||
, group ? "nogroup"
|
||||
, setuid ? false
|
||||
, setgid ? false
|
||||
, permissions ? "u+rx,g+x,o+x"
|
||||
, ...
|
||||
}:
|
||||
''
|
||||
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
|
||||
echo -n "${source}" > $wrapperDir/${program}.real
|
||||
|
||||
# Prevent races
|
||||
chmod 0000 $wrapperDir/${program}
|
||||
chown ${owner}.${group} $wrapperDir/${program}
|
||||
|
||||
chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program}
|
||||
'';
|
||||
|
||||
mkWrappedPrograms =
|
||||
builtins.map
|
||||
(s: if (s ? "capabilities")
|
||||
then mkSetcapProgram
|
||||
({ owner = "root";
|
||||
group = "root";
|
||||
} // s)
|
||||
else if
|
||||
(s ? "setuid" && s.setuid == true) ||
|
||||
(s ? "setguid" && s.setguid == true) ||
|
||||
(s ? "permissions")
|
||||
then mkSetuidProgram s
|
||||
else mkSetuidProgram
|
||||
({ owner = "root";
|
||||
group = "root";
|
||||
setuid = true;
|
||||
setgid = false;
|
||||
permissions = "u+rx,g+x,o+x";
|
||||
} // s)
|
||||
) programs;
|
||||
in
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
security.wrappers = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
example = lib.literalExample
|
||||
''
|
||||
{ sendmail.source = "/nix/store/.../bin/sendmail";
|
||||
ping = {
|
||||
source = "${pkgs.iputils.out}/bin/ping";
|
||||
owner = "nobody";
|
||||
group = "nogroup";
|
||||
capabilities = "cap_net_raw+ep";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
This option allows the ownership and permissions on the setuid
|
||||
wrappers for specific programs to be overridden from the
|
||||
default (setuid root, but not setgid root).
|
||||
|
||||
<note>
|
||||
<para>The sub-attribute <literal>source</literal> is mandatory,
|
||||
it must be the absolute path to the program to be wrapped.
|
||||
</para>
|
||||
|
||||
<para>The sub-attribute <literal>program</literal> is optional and
|
||||
can give the wrapper program a new name. The default name is the same
|
||||
as the attribute name itself.</para>
|
||||
|
||||
<para>Additionally, this option can set capabilities on a
|
||||
wrapper program that propagates those capabilities down to the
|
||||
wrapped, real program.</para>
|
||||
|
||||
<para>NOTE: cap_setpcap, which is required for the wrapper
|
||||
program to be able to raise caps into the Ambient set is NOT
|
||||
raised to the Ambient set so that the real program cannot
|
||||
modify its own capabilities!! This may be too restrictive for
|
||||
cases in which the real program needs cap_setpcap but it at
|
||||
least leans on the side security paranoid vs. too
|
||||
relaxed.</para>
|
||||
</note>
|
||||
'';
|
||||
};
|
||||
|
||||
security.wrapperDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/run/wrappers/bin";
|
||||
internal = true;
|
||||
description = ''
|
||||
This option defines the path to the wrapper programs. It
|
||||
should not be overriden.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = {
|
||||
|
||||
security.wrappers.fusermount.source = "${pkgs.fuse}/bin/fusermount";
|
||||
|
||||
# Make sure our wrapperDir exports to the PATH env variable when
|
||||
# initializing the shell
|
||||
environment.extraInit = ''
|
||||
# Wrappers override other bin directories.
|
||||
export PATH="${wrapperDir}:$PATH"
|
||||
'';
|
||||
|
||||
###### setcap activation script
|
||||
system.activationScripts.wrappers =
|
||||
lib.stringAfter [ "users" ]
|
||||
''
|
||||
# Look in the system path and in the default profile for
|
||||
# programs to be wrapped.
|
||||
WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin
|
||||
|
||||
# Remove the old /var/setuid-wrappers path from the system...
|
||||
#
|
||||
# TODO: this is only necessary for ugprades 16.09 => 17.x;
|
||||
# this conditional removal block needs to be removed after
|
||||
# the release.
|
||||
if [ -d /var/setuid-wrappers ]; then
|
||||
rm -rf /var/setuid-wrappers
|
||||
fi
|
||||
|
||||
# Remove the old /run/setuid-wrappers-dir path from the
|
||||
# system as well...
|
||||
#
|
||||
# TDOO: this is only necessary for ugprades 16.09 => 17.x;
|
||||
# this conditional removal block needs to be removed after
|
||||
# the release.
|
||||
if [ -d /run/setuid-wrapper-dirs ]; then
|
||||
rm -rf /run/setuid-wrapper-dirs
|
||||
fi
|
||||
|
||||
# Get the "/run/wrappers" path, we want to place the tmpdirs
|
||||
# for the wrappers there
|
||||
parentWrapperDir="$(dirname ${wrapperDir})"
|
||||
|
||||
mkdir -p "$parentWrapperDir"
|
||||
wrapperDir=$(mktemp --directory --tmpdir="$parentWrapperDir" wrappers.XXXXXXXXXX)
|
||||
chmod a+rx $wrapperDir
|
||||
|
||||
${lib.concatStringsSep "\n" mkWrappedPrograms}
|
||||
|
||||
if [ -L ${wrapperDir} ]; then
|
||||
# Atomically replace the symlink
|
||||
# See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
|
||||
old=$(readlink -f ${wrapperDir})
|
||||
ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp
|
||||
mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir}
|
||||
rm --force --recursive $old
|
||||
elif [ -d ${wrapperDir} ]; then
|
||||
# Compatibility with old state, just remove the folder and symlink
|
||||
rm -f ${wrapperDir}/*
|
||||
# if it happens to be a tmpfs
|
||||
${pkgs.utillinux}/bin/umount ${wrapperDir} || true
|
||||
rm -d ${wrapperDir}
|
||||
ln -d --symbolic $wrapperDir ${wrapperDir}
|
||||
else
|
||||
# For initial setup
|
||||
ln --symbolic $wrapperDir ${wrapperDir}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
239
nixos/modules/security/wrappers/wrapper.c
Normal file
239
nixos/modules/security/wrappers/wrapper.c
Normal file
@ -0,0 +1,239 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <linux/capability.h>
|
||||
#include <sys/capability.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <cap-ng.h>
|
||||
|
||||
// Make sure assertions are not compiled out, we use them to codify
|
||||
// invariants about this program and we want it to fail fast and
|
||||
// loudly if they are violated.
|
||||
#undef NDEBUG
|
||||
|
||||
extern char **environ;
|
||||
|
||||
// The WRAPPER_DIR macro is supplied at compile time so that it cannot
|
||||
// be changed at runtime
|
||||
static char * wrapperDir = WRAPPER_DIR;
|
||||
|
||||
// Wrapper debug variable name
|
||||
static char * wrapperDebug = "WRAPPER_DEBUG";
|
||||
|
||||
// Update the capabilities of the running process to include the given
|
||||
// capability in the Ambient set.
|
||||
static void set_ambient_cap(cap_value_t cap)
|
||||
{
|
||||
capng_get_caps_process();
|
||||
|
||||
if (capng_update(CAPNG_ADD, CAPNG_INHERITABLE, (unsigned long) cap))
|
||||
{
|
||||
perror("cannot raise the capability into the Inheritable set\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
capng_apply(CAPNG_SELECT_CAPS);
|
||||
|
||||
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long) cap, 0, 0))
|
||||
{
|
||||
perror("cannot raise the capability into the Ambient set\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Given the path to this program, fetch its configured capability set
|
||||
// (as set by `setcap ... /path/to/file`) and raise those capabilities
|
||||
// into the Ambient set.
|
||||
static int make_caps_ambient(const char *selfPath)
|
||||
{
|
||||
cap_t caps = cap_get_file(selfPath);
|
||||
|
||||
if(!caps)
|
||||
{
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything...");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We use `cap_to_text` and iteration over the tokenized result
|
||||
// string because, as of libcap's current release, there is no
|
||||
// facility for retrieving an array of `cap_value_t`'s that can be
|
||||
// given to `prctl` in order to lift that capability into the
|
||||
// Ambient set.
|
||||
//
|
||||
// Some discussion was had around shot-gunning all of the
|
||||
// capabilities we know about into the Ambient set but that has a
|
||||
// security smell and I deemed the risk of the current
|
||||
// implementation crashing the program to be lower than the risk
|
||||
// of a privilege escalation security hole being introduced by
|
||||
// raising all capabilities, even ones we didn't intend for the
|
||||
// program, into the Ambient set.
|
||||
//
|
||||
// `cap_t` which is returned by `cap_get_*` is an opaque type and
|
||||
// even if we could retrieve the bitmasks (which, as far as I can
|
||||
// tell we cannot) in order to get the `cap_value_t`
|
||||
// representation for each capability we would have to take the
|
||||
// total number of capabilities supported and iterate over the
|
||||
// sequence of integers up-to that maximum total, testing each one
|
||||
// against the bitmask ((bitmask >> n) & 1) to see if it's set and
|
||||
// aggregating each "capability integer n" that is set in the
|
||||
// bitmask.
|
||||
//
|
||||
// That, combined with the fact that we can't easily get the
|
||||
// bitmask anyway seemed much more brittle than fetching the
|
||||
// `cap_t`, transforming it into a textual representation,
|
||||
// tokenizing the string, and using `cap_from_name` on the token
|
||||
// to get the `cap_value_t` that we need for `prctl`. There is
|
||||
// indeed risk involved if the output string format of
|
||||
// `cap_to_text` ever changes but at this time the combination of
|
||||
// factors involving the below list have led me to the conclusion
|
||||
// that the best implementation at this time is reading then
|
||||
// parsing with *lots of documentation* about why we're doing it
|
||||
// this way.
|
||||
//
|
||||
// 1. No explicit API for fetching an array of `cap_value_t`'s or
|
||||
// for transforming a `cap_t` into such a representation
|
||||
// 2. The risk of a crash is lower than lifting all capabilities
|
||||
// into the Ambient set
|
||||
// 3. libcap is depended on heavily in the Linux ecosystem so
|
||||
// there is a high chance that the output representation of
|
||||
// `cap_to_text` will not change which reduces our risk that
|
||||
// this parsing step will cause a crash
|
||||
//
|
||||
// The preferred method, should it ever be available in the
|
||||
// future, would be to use libcap API's to transform the result
|
||||
// from a `cap_get_*` into an array of `cap_value_t`'s that can
|
||||
// then be given to prctl.
|
||||
//
|
||||
// - Parnell
|
||||
ssize_t capLen;
|
||||
char* capstr = cap_to_text(caps, &capLen);
|
||||
cap_free(caps);
|
||||
|
||||
// TODO: For now, we assume that cap_to_text always starts its
|
||||
// result string with " =" and that the first capability is listed
|
||||
// immediately after that. We should verify this.
|
||||
assert(capLen >= 2);
|
||||
capstr += 2;
|
||||
|
||||
char* saveptr = NULL;
|
||||
for(char* tok = strtok_r(capstr, ",", &saveptr); tok; tok = strtok_r(NULL, ",", &saveptr))
|
||||
{
|
||||
cap_value_t capnum;
|
||||
if (cap_from_name(tok, &capnum))
|
||||
{
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "cap_from_name failed, skipping: %s", tok);
|
||||
}
|
||||
else if (capnum == CAP_SETPCAP)
|
||||
{
|
||||
// Check for the cap_setpcap capability, we set this on the
|
||||
// wrapper so it can elevate the capabilities to the Ambient
|
||||
// set but we do not want to propagate it down into the
|
||||
// wrapped program.
|
||||
//
|
||||
// TODO: what happens if that's the behavior you want
|
||||
// though???? I'm preferring a strict vs. loose policy here.
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "cap_setpcap in set, skipping it\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
set_ambient_cap(capnum);
|
||||
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "raised %s into the Ambient capability set\n", tok);
|
||||
}
|
||||
}
|
||||
cap_free(capstr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
// I *think* it's safe to assume that a path from a symbolic link
|
||||
// should safely fit within the PATH_MAX system limit. Though I'm
|
||||
// not positive it's safe...
|
||||
char selfPath[PATH_MAX];
|
||||
int selfPathSize = readlink("/proc/self/exe", selfPath, sizeof(selfPath));
|
||||
|
||||
assert(selfPathSize > 0);
|
||||
|
||||
// Assert we have room for the zero byte, this ensures the path
|
||||
// isn't being truncated because it's too big for the buffer.
|
||||
//
|
||||
// A better way to handle this might be to use something like the
|
||||
// whereami library (https://github.com/gpakosz/whereami) or a
|
||||
// loop that resizes the buffer and re-reads the link if the
|
||||
// contents are being truncated.
|
||||
assert(selfPathSize < sizeof(selfPath));
|
||||
|
||||
// Set the zero byte since readlink doesn't do that for us.
|
||||
selfPath[selfPathSize] = '\0';
|
||||
|
||||
// Make sure that we are being executed from the right location,
|
||||
// i.e., `safeWrapperDir'. This is to prevent someone from creating
|
||||
// hard link `X' from some other location, along with a false
|
||||
// `X.real' file, to allow arbitrary programs from being executed
|
||||
// with elevated capabilities.
|
||||
int len = strlen(wrapperDir);
|
||||
if (len > 0 && '/' == wrapperDir[len - 1])
|
||||
--len;
|
||||
assert(!strncmp(selfPath, wrapperDir, len));
|
||||
assert('/' == wrapperDir[0]);
|
||||
assert('/' == selfPath[len]);
|
||||
|
||||
// Make *really* *really* sure that we were executed as
|
||||
// `selfPath', and not, say, as some other setuid program. That
|
||||
// is, our effective uid/gid should match the uid/gid of
|
||||
// `selfPath'.
|
||||
struct stat st;
|
||||
assert(lstat(selfPath, &st) != -1);
|
||||
|
||||
assert(!(st.st_mode & S_ISUID) || (st.st_uid == geteuid()));
|
||||
assert(!(st.st_mode & S_ISGID) || (st.st_gid == getegid()));
|
||||
|
||||
// And, of course, we shouldn't be writable.
|
||||
assert(!(st.st_mode & (S_IWGRP | S_IWOTH)));
|
||||
|
||||
// Read the path of the real (wrapped) program from <self>.real.
|
||||
char realFN[PATH_MAX + 10];
|
||||
int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", selfPath);
|
||||
assert (realFNSize < sizeof(realFN));
|
||||
|
||||
int fdSelf = open(realFN, O_RDONLY);
|
||||
assert (fdSelf != -1);
|
||||
|
||||
char sourceProg[PATH_MAX];
|
||||
len = read(fdSelf, sourceProg, PATH_MAX);
|
||||
assert (len != -1);
|
||||
assert (len < sizeof(sourceProg));
|
||||
assert (len > 0);
|
||||
sourceProg[len] = 0;
|
||||
|
||||
close(fdSelf);
|
||||
|
||||
// Read the capabilities set on the wrapper and raise them in to
|
||||
// the Ambient set so the program we're wrapping receives the
|
||||
// capabilities too!
|
||||
make_caps_ambient(selfPath);
|
||||
|
||||
execve(sourceProg, argv, environ);
|
||||
|
||||
fprintf(stderr, "%s: cannot run `%s': %s\n",
|
||||
argv[0], sourceProg, strerror(errno));
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ with lib;
|
||||
|
||||
let
|
||||
|
||||
name = "mpd";
|
||||
|
||||
uid = config.ids.uids.mpd;
|
||||
gid = config.ids.gids.mpd;
|
||||
cfg = config.services.mpd;
|
||||
@ -54,13 +56,14 @@ in {
|
||||
description = ''
|
||||
Extra directives added to to the end of MPD's configuration file,
|
||||
mpd.conf. Basic configuration like file location and uid/gid
|
||||
is added automatically to the beginning of the file.
|
||||
is added automatically to the beginning of the file. For available
|
||||
options see <literal>man 5 mpd.conf</literal>'.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/mpd";
|
||||
default = "/var/lib/${name}";
|
||||
description = ''
|
||||
The directory where MPD stores its state, tag cache,
|
||||
playlists etc.
|
||||
@ -69,13 +72,13 @@ in {
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "mpd";
|
||||
default = name;
|
||||
description = "User account under which MPD runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "mpd";
|
||||
default = name;
|
||||
description = "Group account under which MPD runs.";
|
||||
};
|
||||
|
||||
@ -131,17 +134,17 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
users.extraUsers = optionalAttrs (cfg.user == "mpd") (singleton {
|
||||
users.extraUsers = optionalAttrs (cfg.user == name) (singleton {
|
||||
inherit uid;
|
||||
name = "mpd";
|
||||
inherit name;
|
||||
group = cfg.group;
|
||||
extraGroups = [ "audio" ];
|
||||
description = "Music Player Daemon user";
|
||||
home = "${cfg.dataDir}";
|
||||
});
|
||||
|
||||
users.extraGroups = optionalAttrs (cfg.group == "mpd") (singleton {
|
||||
name = "mpd";
|
||||
users.extraGroups = optionalAttrs (cfg.group == name) (singleton {
|
||||
inherit name;
|
||||
gid = gid;
|
||||
});
|
||||
};
|
||||
|
@ -775,7 +775,7 @@ in {
|
||||
--bind-address=${cfg.proxy.address} \
|
||||
${optionalString cfg.verbose "--v=6"} \
|
||||
${optionalString cfg.verbose "--log-flush-frequency=1s"} \
|
||||
${cfg.controllerManager.extraOpts}
|
||||
${cfg.proxy.extraOpts}
|
||||
'';
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
};
|
||||
|
@ -7,7 +7,7 @@ with lib;
|
||||
let
|
||||
cfg = config.services.buildbot-master;
|
||||
escapeStr = s: escape ["'"] s;
|
||||
masterCfg = pkgs.writeText "master.cfg" ''
|
||||
masterCfg = if cfg.masterCfg == null then pkgs.writeText "master.cfg" ''
|
||||
from buildbot.plugins import *
|
||||
factory = util.BuildFactory()
|
||||
c = BuildmasterConfig = dict(
|
||||
@ -27,9 +27,8 @@ let
|
||||
factory.addStep(step)
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
configFile = if cfg.masterCfg == null then masterCfg else cfg.masterCfg;
|
||||
''
|
||||
else pkgs.writeText "master.cfg" cfg.masterCfg;
|
||||
|
||||
in {
|
||||
options = {
|
||||
@ -67,15 +66,13 @@ in {
|
||||
};
|
||||
|
||||
masterCfg = mkOption {
|
||||
type = with types; nullOr path;
|
||||
type = types.str;
|
||||
description = ''
|
||||
Optionally pass path to raw master.cfg file.
|
||||
Optionally pass raw master.cfg file as string.
|
||||
Other options in this configuration will be ignored.
|
||||
'';
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
pkgs.writeText "master.cfg" "BuildmasterConfig = c = {}"
|
||||
'';
|
||||
example = "BuildmasterConfig = c = {}";
|
||||
};
|
||||
|
||||
schedulers = mkOption {
|
||||
@ -99,9 +96,9 @@ in {
|
||||
type = types.listOf types.str;
|
||||
description = "List of Workers.";
|
||||
default = [
|
||||
"worker.Worker('default-worker', 'password')"
|
||||
"worker.Worker('example-worker', 'pass')"
|
||||
];
|
||||
example = [ "worker.LocalWorker('default-worker')" ];
|
||||
example = [ "worker.LocalWorker('example-worker')" ];
|
||||
};
|
||||
|
||||
status = mkOption {
|
||||
@ -209,7 +206,7 @@ in {
|
||||
|
||||
users.extraUsers = optional (cfg.user == "buildbot") {
|
||||
name = "buildbot";
|
||||
description = "buildbot user";
|
||||
description = "Buildbot User.";
|
||||
isNormalUser = true;
|
||||
createHome = true;
|
||||
home = cfg.home;
|
||||
@ -219,7 +216,7 @@ in {
|
||||
};
|
||||
|
||||
systemd.services.buildbot-master = {
|
||||
description = "Buildbot Continuous Integration Server";
|
||||
description = "Buildbot Continuous Integration Server.";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = cfg.packages;
|
||||
@ -233,9 +230,8 @@ in {
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
mkdir -vp ${cfg.buildbotDir}
|
||||
chown -c ${cfg.user}:${cfg.group} ${cfg.buildbotDir}
|
||||
ln -sf ${configFile} ${cfg.buildbotDir}/master.cfg
|
||||
${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir}
|
||||
${pkgs.coreutils}/bin/ln -sfv ${masterCfg} ${cfg.buildbotDir}/master.cfg
|
||||
${cfg.package}/bin/buildbot create-master ${cfg.buildbotDir}
|
||||
'';
|
||||
|
||||
@ -247,4 +243,6 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ nand0p Mic92 ];
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,128 @@
|
||||
# NixOS module for Buildbot Worker.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.buildbot-worker;
|
||||
|
||||
in {
|
||||
options = {
|
||||
services.buildbot-worker = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the Buildbot Worker.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "bbworker";
|
||||
type = types.str;
|
||||
description = "User the buildbot Worker should execute under.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
default = "bbworker";
|
||||
type = types.str;
|
||||
description = "Primary group of buildbot Worker user.";
|
||||
};
|
||||
|
||||
extraGroups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "nixbld" ];
|
||||
description = "List of extra groups that the Buildbot Worker user should be a part of.";
|
||||
};
|
||||
|
||||
home = mkOption {
|
||||
default = "/home/bbworker";
|
||||
type = types.path;
|
||||
description = "Buildbot home directory.";
|
||||
};
|
||||
|
||||
buildbotDir = mkOption {
|
||||
default = "${cfg.home}/worker";
|
||||
type = types.path;
|
||||
description = "Specifies the Buildbot directory.";
|
||||
};
|
||||
|
||||
workerUser = mkOption {
|
||||
default = "example-worker";
|
||||
type = types.str;
|
||||
description = "Specifies the Buildbot Worker user.";
|
||||
};
|
||||
|
||||
workerPass = mkOption {
|
||||
default = "pass";
|
||||
type = types.str;
|
||||
description = "Specifies the Buildbot Worker password.";
|
||||
};
|
||||
|
||||
masterUrl = mkOption {
|
||||
default = "localhost:9989";
|
||||
type = types.str;
|
||||
description = "Specifies the Buildbot Worker connection string.";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.buildbot-worker;
|
||||
description = "Package to use for buildbot worker.";
|
||||
example = pkgs.buildbot-worker;
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
default = [ ];
|
||||
example = [ pkgs.git ];
|
||||
type = types.listOf types.package;
|
||||
description = "Packages to add to PATH for the buildbot process.";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.extraGroups = optional (cfg.group == "bbworker") {
|
||||
name = "bbworker";
|
||||
};
|
||||
|
||||
users.extraUsers = optional (cfg.user == "bbworker") {
|
||||
name = "bbworker";
|
||||
description = "Buildbot Worker User.";
|
||||
isNormalUser = true;
|
||||
createHome = true;
|
||||
home = cfg.home;
|
||||
group = cfg.group;
|
||||
extraGroups = cfg.extraGroups;
|
||||
useDefaultShell = true;
|
||||
};
|
||||
|
||||
systemd.services.buildbot-worker = {
|
||||
description = "Buildbot Worker.";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "buildbot-master.service" ];
|
||||
path = cfg.packages;
|
||||
|
||||
preStart = ''
|
||||
# NOTE: ensure master has time to start in case running on localhost
|
||||
${pkgs.coreutils}/bin/sleep 4
|
||||
${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir}
|
||||
${cfg.package}/bin/buildbot-worker create-worker ${cfg.buildbotDir} ${cfg.masterUrl} ${cfg.workerUser} ${cfg.workerPass}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
WorkingDirectory = cfg.home;
|
||||
ExecStart = "${cfg.package}/bin/buildbot-worker start ${cfg.buildbotDir}";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ nand0p ];
|
||||
|
||||
}
|
@ -76,14 +76,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
stanchionSsl = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Tell stanchion to use SSL.
|
||||
'';
|
||||
};
|
||||
|
||||
distributedCookie = mkOption {
|
||||
type = types.str;
|
||||
default = "riak";
|
||||
@ -148,8 +140,6 @@ in
|
||||
|
||||
distributed_cookie = ${cfg.distributedCookie}
|
||||
|
||||
stanchion_ssl=${if cfg.stanchionSsl then "on" else "off"}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
|
@ -316,10 +316,10 @@ https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides
|
||||
<para>
|
||||
If you are not on NixOS or want to install this particular
|
||||
Emacs only for yourself, you can do so by adding it to your
|
||||
<filename>~/.nixpkgs/config.nix</filename>
|
||||
<filename>~/.config/nixpkgs/config.nix</filename>
|
||||
(see <link xlink:href="http://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides">Nixpkgs manual</link>):
|
||||
<example>
|
||||
<title>Custom Emacs in <filename>~/.nixpkgs/system.nix</filename></title>
|
||||
<title>Custom Emacs in <filename>~/.config/nixpkgs/config.nix</filename></title>
|
||||
<programlisting><![CDATA[
|
||||
{
|
||||
packageOverrides = super: let self = super.pkgs; in {
|
||||
|
@ -14,6 +14,31 @@ let
|
||||
read-data=${factorio}/share/factorio/data
|
||||
write-data=${stateDir}
|
||||
'';
|
||||
serverSettings = {
|
||||
name = cfg.game-name;
|
||||
description = cfg.description;
|
||||
visibility = {
|
||||
public = cfg.public;
|
||||
lan = cfg.lan;
|
||||
};
|
||||
username = cfg.username;
|
||||
password = cfg.password;
|
||||
token = cfg.token;
|
||||
game_password = cfg.game-password;
|
||||
require_user_verification = true;
|
||||
max_upload_in_kilobytes_per_second = 0;
|
||||
minimum_latency_in_ticks = 0;
|
||||
ignore_player_limit_for_returning_players = false;
|
||||
allow_commands = "admins-only";
|
||||
autosave_interval = cfg.autosave-interval;
|
||||
autosave_slots = 5;
|
||||
afk_autokick_interval = 0;
|
||||
auto_pause = true;
|
||||
only_admins_can_pause_the_game = true;
|
||||
autosave_only_on_server = true;
|
||||
admins = [];
|
||||
};
|
||||
serverSettingsFile = pkgs.writeText "server-settings.json" (builtins.toJSON (filterAttrsRecursive (n: v: v != null) serverSettings));
|
||||
modDir = pkgs.factorio-mkModDirDrv cfg.mods;
|
||||
in
|
||||
{
|
||||
@ -67,12 +92,68 @@ in
|
||||
derivations via nixos-channel. Until then, this is for experts only.
|
||||
'';
|
||||
};
|
||||
game-name = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = "Factorio Game";
|
||||
description = ''
|
||||
Name of the game as it will appear in the game listing.
|
||||
'';
|
||||
};
|
||||
description = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = "";
|
||||
description = ''
|
||||
Description of the game that will appear in the listing.
|
||||
'';
|
||||
};
|
||||
public = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Game will be published on the official Factorio matching server.
|
||||
'';
|
||||
};
|
||||
lan = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Game will be broadcast on LAN.
|
||||
'';
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
description = ''
|
||||
Your factorio.com login credentials. Required for games with visibility public.
|
||||
'';
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
description = ''
|
||||
Your factorio.com login credentials. Required for games with visibility public.
|
||||
'';
|
||||
};
|
||||
token = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
description = ''
|
||||
Authentication token. May be used instead of 'password' above.
|
||||
'';
|
||||
};
|
||||
game-password = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
description = ''
|
||||
Game password.
|
||||
'';
|
||||
};
|
||||
autosave-interval = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 2;
|
||||
example = 10;
|
||||
description = ''
|
||||
The time, in minutes, between autosaves.
|
||||
Autosave interval in minutes.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@ -120,8 +201,8 @@ in
|
||||
"--config=${cfg.configFile}"
|
||||
"--port=${toString cfg.port}"
|
||||
"--start-server=${mkSavePath cfg.saveName}"
|
||||
"--server-settings=${serverSettingsFile}"
|
||||
(optionalString (cfg.mods != []) "--mod-directory=${modDir}")
|
||||
(optionalString (cfg.autosave-interval != null) "--autosave-interval ${toString cfg.autosave-interval}")
|
||||
];
|
||||
};
|
||||
};
|
||||
|
@ -1,42 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
bluez-bluetooth = if config.services.xserver.desktopManager.kde4.enable then pkgs.bluez else pkgs.bluez5;
|
||||
bluez-bluetooth = pkgs.bluez;
|
||||
cfg = config.hardware.bluetooth;
|
||||
|
||||
configBluez = {
|
||||
description = "Bluetooth Service";
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
BusName = "org.bluez";
|
||||
ExecStart = "${getBin bluez-bluetooth}/bin/bluetoothd -n";
|
||||
};
|
||||
wantedBy = [ "bluetooth.target" ];
|
||||
};
|
||||
|
||||
configBluez5 = {
|
||||
description = "Bluetooth Service";
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
BusName = "org.bluez";
|
||||
ExecStart = "${getBin bluez-bluetooth}/bin/bluetoothd -n";
|
||||
NotifyAccess="main";
|
||||
CapabilityBoundingSet="CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
LimitNPROC=1;
|
||||
};
|
||||
wantedBy = [ "bluetooth.target" ];
|
||||
};
|
||||
|
||||
obexConfig = {
|
||||
description = "Bluetooth OBEX service";
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
BusName = "org.bluez.obex";
|
||||
ExecStart = "${getBin bluez-bluetooth}/bin/obexd";
|
||||
};
|
||||
};
|
||||
|
||||
bluezConfig = if config.services.xserver.desktopManager.kde4.enable then configBluez else configBluez5;
|
||||
in
|
||||
|
||||
{
|
||||
@ -45,23 +14,54 @@ in
|
||||
|
||||
options = {
|
||||
|
||||
hardware.bluetooth.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable support for Bluetooth.";
|
||||
hardware.bluetooth.enable = mkEnableOption "support for Bluetooth.";
|
||||
|
||||
hardware.bluetooth.powerOnBoot = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to power up the default Bluetooth controller on boot.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.hardware.bluetooth.enable {
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ];
|
||||
|
||||
services.udev.packages = [ bluez-bluetooth ];
|
||||
services.dbus.packages = [ bluez-bluetooth ];
|
||||
systemd.services."dbus-org.bluez" = bluezConfig;
|
||||
systemd.services."dbus-org.bluez.obex" = obexConfig;
|
||||
systemd.packages = [ bluez-bluetooth ];
|
||||
|
||||
services.udev.extraRules = optionalString cfg.powerOnBoot ''
|
||||
ACTION=="add", KERNEL=="hci[0-9]*", ENV{SYSTEMD_WANTS}="bluetooth-power@%k.service"
|
||||
'';
|
||||
|
||||
systemd.services = {
|
||||
bluetooth = {
|
||||
wantedBy = [ "bluetooth.target" ];
|
||||
aliases = [ "dbus-org.bluez.service" ];
|
||||
};
|
||||
|
||||
"bluetooth-power@" = mkIf cfg.powerOnBoot {
|
||||
description = "Power up bluetooth controller";
|
||||
after = [
|
||||
"bluetooth.service"
|
||||
"suspend.target"
|
||||
"sys-subsystem-bluetooth-devices-%i.device"
|
||||
];
|
||||
wantedBy = [ "suspend.target" ];
|
||||
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.ExecStart = "${pkgs.bluez.out}/bin/hciconfig %i up";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
systemd.user.services = {
|
||||
obex.aliases = [ "dbus-org.bluez.obex.service" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
35
nixos/modules/services/hardware/illum.nix
Normal file
35
nixos/modules/services/hardware/illum.nix
Normal file
@ -0,0 +1,35 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.illum;
|
||||
in {
|
||||
|
||||
options = {
|
||||
|
||||
services.illum = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enable illum, a daemon for controlling screen brightness with brightness buttons.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.services.illum = {
|
||||
description = "Backlight Adjustment Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.ExecStart = "${pkgs.illum}/bin/illum-d";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -51,7 +51,7 @@ in
|
||||
Enable support for SANE scanners.
|
||||
|
||||
<note><para>
|
||||
Users in the "scanner" group will gain access to the scanner.
|
||||
Users in the "scanner" group will gain access to the scanner, or the "lp" group if it's also a printer.
|
||||
</para></note>
|
||||
'';
|
||||
};
|
||||
|
54
nixos/modules/services/hardware/trezord.nix
Normal file
54
nixos/modules/services/hardware/trezord.nix
Normal file
@ -0,0 +1,54 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.trezord;
|
||||
in {
|
||||
|
||||
### interface
|
||||
|
||||
options = {
|
||||
services.trezord = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable Trezor bridge daemon, for use with Trezor hardware bitcoin wallets.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.udev.packages = lib.singleton (pkgs.writeTextFile {
|
||||
name = "trezord-udev-rules";
|
||||
destination = "/etc/udev/rules.d/51-trezor.rules";
|
||||
text = ''
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666", GROUP="dialout", SYMLINK+="trezor%n"
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666", GROUP="dialout"
|
||||
'';
|
||||
});
|
||||
|
||||
systemd.services.trezord = {
|
||||
description = "TREZOR Bridge";
|
||||
after = [ "systemd-udev-settle.service" "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.trezord}/bin/trezord -f";
|
||||
User = "trezord";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.trezord = {
|
||||
group = "trezord";
|
||||
description = "Trezor bridge daemon user";
|
||||
};
|
||||
|
||||
users.groups.trezord = {};
|
||||
};
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ in {
|
||||
default = "";
|
||||
description = "Fluentd config.";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
default = pkgs.fluentd;
|
||||
description = "The fluentd package to use.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -32,7 +38,7 @@ in {
|
||||
description = "Fluentd Daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.fluentd}/bin/fluentd -c ${pkgs.writeText "fluentd.conf" cfg.config}";
|
||||
ExecStart = "${cfg.package}/bin/fluentd -c ${pkgs.writeText "fluentd.conf" cfg.config}";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
};
|
||||
};
|
||||
|
76
nixos/modules/services/logging/journalbeat.nix
Normal file
76
nixos/modules/services/logging/journalbeat.nix
Normal file
@ -0,0 +1,76 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.journalbeat;
|
||||
|
||||
journalbeatYml = pkgs.writeText "journalbeat.yml" ''
|
||||
name: ${cfg.name}
|
||||
tags: ${builtins.toJSON cfg.tags}
|
||||
|
||||
journalbeat.cursor_state_file: ${cfg.stateDir}/cursor-state
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
|
||||
services.journalbeat = {
|
||||
|
||||
enable = mkEnableOption "journalbeat";
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "journalbeat";
|
||||
description = "Name of the beat";
|
||||
};
|
||||
|
||||
tags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Tags to place on the shipped log messages";
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/journalbeat";
|
||||
description = "The state directory. Journalbeat's own logs and other data are stored here.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''
|
||||
journalbeat:
|
||||
seek_position: cursor
|
||||
cursor_seek_fallback: tail
|
||||
write_cursor_state: true
|
||||
cursor_flush_period: 5s
|
||||
clean_field_names: true
|
||||
convert_to_numbers: false
|
||||
move_metadata_to_field: journal
|
||||
default_type: journal
|
||||
'';
|
||||
description = "Any other configuration options you want to add";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.services.journalbeat = with pkgs; {
|
||||
description = "Journalbeat log shipper";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
mkdir -p ${cfg.stateDir}/data
|
||||
mkdir -p ${cfg.stateDir}/logs
|
||||
'';
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.journalbeat}/bin/journalbeat -c ${journalbeatYml} -path.data ${cfg.stateDir}/data -path.logs ${cfg.stateDir}/logs";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -29,8 +29,8 @@ let
|
||||
};
|
||||
|
||||
cronJob = ''
|
||||
@reboot logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags}
|
||||
2 ${cfg.timeOfDay} * * * logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags}
|
||||
@reboot logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags}
|
||||
2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags}
|
||||
'';
|
||||
|
||||
writeIgnoreRule = name: {level, regex, ...}:
|
||||
@ -184,7 +184,7 @@ in
|
||||
description = ''
|
||||
This option defines extra ignore rules.
|
||||
'';
|
||||
type = with types; loaOf (submodule ignoreOptions);
|
||||
type = with types; attrsOf (submodule ignoreOptions);
|
||||
};
|
||||
|
||||
ignoreCron = mkOption {
|
||||
@ -192,7 +192,7 @@ in
|
||||
description = ''
|
||||
This option defines extra ignore rules for cronjobs.
|
||||
'';
|
||||
type = with types; loaOf (submodule ignoreCronOptions);
|
||||
type = with types; attrsOf (submodule ignoreCronOptions);
|
||||
};
|
||||
|
||||
extraGroups = mkOption {
|
||||
|
@ -63,7 +63,7 @@ in
|
||||
description = "Enable the logstash web interface.";
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
description = "Address on which to start webserver.";
|
||||
@ -77,7 +77,7 @@ in
|
||||
|
||||
inputConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''stdin { type => "example" }'';
|
||||
default = ''generator { }'';
|
||||
description = "Logstash input configuration.";
|
||||
example = ''
|
||||
# Read from journal
|
||||
@ -90,7 +90,7 @@ in
|
||||
|
||||
filterConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''noop {}'';
|
||||
default = "";
|
||||
description = "logstash filter configuration.";
|
||||
example = ''
|
||||
if [type] == "syslog" {
|
||||
@ -108,11 +108,11 @@ in
|
||||
|
||||
outputConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''stdout { debug => true debug_format => "json"}'';
|
||||
default = ''stdout { codec => rubydebug }'';
|
||||
description = "Logstash output configuration.";
|
||||
example = ''
|
||||
redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
|
||||
elasticsearch { embedded => true }
|
||||
redis { host => ["localhost"] data_type => "list" key => "logstash" codec => json }
|
||||
elasticsearch { }
|
||||
'';
|
||||
};
|
||||
|
||||
@ -147,7 +147,7 @@ in
|
||||
${cfg.outputConfig}
|
||||
}
|
||||
''} " +
|
||||
ops cfg.enableWeb "-- web -a ${cfg.address} -p ${cfg.port}";
|
||||
ops cfg.enableWeb "-- web -a ${cfg.listenAddress} -p ${cfg.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ let
|
||||
''
|
||||
base_dir = ${baseDir}
|
||||
protocols = ${concatStringsSep " " cfg.protocols}
|
||||
sendmail_path = /var/setuid-wrappers/sendmail
|
||||
sendmail_path = /run/wrappers/bin/sendmail
|
||||
''
|
||||
|
||||
(if isNull cfg.sslServerCert then ''
|
||||
|
@ -70,7 +70,7 @@ in
|
||||
etc."exim.conf".text = ''
|
||||
exim_user = ${cfg.user}
|
||||
exim_group = ${cfg.group}
|
||||
exim_path = /var/setuid-wrappers/exim
|
||||
exim_path = /run/wrappers/bin/exim
|
||||
spool_directory = ${cfg.spoolDir}
|
||||
${cfg.config}
|
||||
'';
|
||||
@ -89,7 +89,7 @@ in
|
||||
gid = config.ids.gids.exim;
|
||||
};
|
||||
|
||||
security.setuidPrograms = [ "exim" ];
|
||||
security.wrappers.exim.source = "${exim}/bin/exim";
|
||||
|
||||
systemd.services.exim = {
|
||||
description = "Exim Mail Daemon";
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user