Merge 'staging' into multiple-outputs
Conflicts: pkgs/applications/audio/flac/default.nix pkgs/build-support/gcc-wrapper/builder.sh pkgs/development/libraries/apr-util/default.nix pkgs/development/libraries/apr/default.nix pkgs/development/libraries/atk/default.nix pkgs/development/libraries/freetype/default.nix pkgs/development/libraries/gdk-pixbuf/default.nix pkgs/development/libraries/glib/default.nix pkgs/development/libraries/glibc/2.17/builder.sh pkgs/development/libraries/glibc/2.17/locales.nix pkgs/development/libraries/libjpeg/default.nix pkgs/development/libraries/libogg/default.nix pkgs/development/libraries/libsamplerate/default.nix pkgs/development/libraries/libtiff/default.nix pkgs/development/libraries/libvorbis/default.nix pkgs/development/libraries/mesa/default.nix pkgs/development/libraries/pango/default.nix pkgs/development/web/nodejs/default.nix pkgs/os-specific/linux/pam/default.nix pkgs/os-specific/linux/systemd/default.nix pkgs/stdenv/generic/setup.sh pkgs/stdenv/linux/default.nix pkgs/top-level/all-packages.nix pkgs/top-level/release-small.nix
This commit is contained in:
commit
96cec2a7bd
11
.gitignore
vendored
11
.gitignore
vendored
@ -3,8 +3,11 @@
|
|||||||
.*.swp
|
.*.swp
|
||||||
.*.swo
|
.*.swo
|
||||||
result
|
result
|
||||||
doc/NEWS.html
|
result-*
|
||||||
doc/NEWS.txt
|
/doc/NEWS.html
|
||||||
doc/manual.html
|
/doc/NEWS.txt
|
||||||
doc/manual.pdf
|
/doc/manual.html
|
||||||
|
/doc/manual.pdf
|
||||||
.version-suffix
|
.version-suffix
|
||||||
|
|
||||||
|
.DS_Store
|
10
README.md
Normal file
10
README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Nixpkgs is a collection of packages for [Nix](http://nixos.org/nix/) package
|
||||||
|
manager. Nixpkgs also includes [NixOS](http://nixos.org/nixos/) linux distribution source code.
|
||||||
|
|
||||||
|
* [NixOS installation instructions](http://nixos.org/nixos/manual/#ch-installation)
|
||||||
|
* [Manual (How to write packages for Nix)](http://nixos.org/nixpkgs/manual/)
|
||||||
|
* [Manual (NixOS)](http://nixos.org/nixos/manual/)
|
||||||
|
* [Continuous build](http://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||||
|
* [Tests](http://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||||
|
* [Mailing list](http://lists.science.uu.nl/mailman/listinfo/nix-dev)
|
||||||
|
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
|
@ -1 +1,7 @@
|
|||||||
import ./pkgs/top-level/all-packages.nix
|
if ! builtins ? nixVersion || builtins.compareVersions "1.6" builtins.nixVersion == 1 then
|
||||||
|
|
||||||
|
abort "This version of Nixpkgs requires Nix >= 1.6, please upgrade!"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
import ./pkgs/top-level/all-packages.nix
|
||||||
|
@ -21,18 +21,18 @@ all: NEWS.html NEWS.txt manual.html manual.pdf
|
|||||||
|
|
||||||
NEWS.html: release-notes.xml
|
NEWS.html: release-notes.xml
|
||||||
$(XSLTPROC) --nonet --xinclude --output $@ $(NEWS_OPTS) \
|
$(XSLTPROC) --nonet --xinclude --output $@ $(NEWS_OPTS) \
|
||||||
$(docbookxsl)/html/docbook.xsl release-notes.xml
|
$(docbookxsl)/xhtml/docbook.xsl release-notes.xml
|
||||||
|
|
||||||
NEWS.txt: release-notes.xml
|
NEWS.txt: release-notes.xml
|
||||||
$(XSLTPROC) --nonet --xinclude quote-literals.xsl release-notes.xml | \
|
$(XSLTPROC) --nonet --xinclude quote-literals.xsl release-notes.xml | \
|
||||||
$(XSLTPROC) --nonet --output $@.tmp.html $(NEWS_OPTS) \
|
$(XSLTPROC) --nonet --output $@.tmp.html $(NEWS_OPTS) \
|
||||||
$(docbookxsl)/html/docbook.xsl -
|
$(docbookxsl)/xhtml/docbook.xsl -
|
||||||
LANG=en_US w3m -dump $@.tmp.html > $@
|
LANG=en_US w3m -dump $@.tmp.html > $@
|
||||||
rm $@.tmp.html
|
rm $@.tmp.html
|
||||||
|
|
||||||
manual.html: *.xml
|
manual.html: *.xml
|
||||||
$(XSLTPROC) --nonet --xinclude --output manual.html \
|
$(XSLTPROC) --nonet --xinclude --output manual.html \
|
||||||
$(docbookxsl)/html/docbook.xsl manual.xml
|
$(docbookxsl)/xhtml/docbook.xsl manual.xml
|
||||||
|
|
||||||
manual.pdf: *.xml
|
manual.pdf: *.xml
|
||||||
$(dblatex) \
|
$(dblatex) \
|
||||||
|
@ -235,12 +235,7 @@ Most of the time, these are the same. For instance, the package
|
|||||||
bound to the variable name <varname>e2fsprogs</varname> in
|
bound to the variable name <varname>e2fsprogs</varname> in
|
||||||
<filename>all-packages.nix</filename>, and the Nix expression is in
|
<filename>all-packages.nix</filename>, and the Nix expression is in
|
||||||
<filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>.
|
<filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>.
|
||||||
However, identifiers in the Nix language don’t allow certain
|
</para>
|
||||||
characters (e.g. dashes), so sometimes a different variable name
|
|
||||||
should be used. For instance, the
|
|
||||||
<literal>module-init-tools</literal> package is bound to the
|
|
||||||
<literal>module_init_tools</literal> variable in
|
|
||||||
<filename>all-packages.nix</filename>.</para>
|
|
||||||
|
|
||||||
<para>There are a few naming guidelines:
|
<para>There are a few naming guidelines:
|
||||||
|
|
||||||
@ -261,17 +256,20 @@ should be used. For instance, the
|
|||||||
a package named <literal>hello-svn</literal> by
|
a package named <literal>hello-svn</literal> by
|
||||||
<command>nix-env</command>.</para></listitem>
|
<command>nix-env</command>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Dashes in the package name should be changed to
|
<listitem><para>Dashes in the package name should be preserved
|
||||||
underscores in variable names, rather than to camel case — e.g.,
|
in new variable names, rather than converted to underscores
|
||||||
<varname>module_init_tools</varname> instead of
|
(which was convention up to around 2013 and most names
|
||||||
<varname>moduleInitTools</varname>.</para></listitem>
|
still have underscores instead of dashes) — e.g.,
|
||||||
|
<varname>http-parser</varname> instead of
|
||||||
|
<varname>http_parser</varname>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>If there are multiple versions of a package, this
|
<listitem><para>If there are multiple versions of a package, this
|
||||||
should be reflected in the variable names in
|
should be reflected in the variable names in
|
||||||
<filename>all-packages.nix</filename>,
|
<filename>all-packages.nix</filename>,
|
||||||
e.g. <varname>hello_0_3</varname> and <varname>hello_0_4</varname>.
|
e.g. <varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>.
|
||||||
If there is an obvious “default” version, make an attribute like
|
If there is an obvious “default” version, make an attribute like
|
||||||
<literal>hello = hello_0_4;</literal>.</para></listitem>
|
<literal>json-c = json-c-0-9;</literal>.
|
||||||
|
See also <xref linkend="sec-versioning" /></para></listitem>
|
||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
@ -288,7 +286,7 @@ dashes between words — not in camel case. For instance, it should be
|
|||||||
<filename>allPackages.nix</filename> or
|
<filename>allPackages.nix</filename> or
|
||||||
<filename>AllPackages.nix</filename>.</para>
|
<filename>AllPackages.nix</filename>.</para>
|
||||||
|
|
||||||
<section><title>Hierachy</title>
|
<section><title>Hierarchy</title>
|
||||||
|
|
||||||
<para>Each package should be stored in its own directory somewhere in
|
<para>Each package should be stored in its own directory somewhere in
|
||||||
the <filename>pkgs/</filename> tree, i.e. in
|
the <filename>pkgs/</filename> tree, i.e. in
|
||||||
@ -567,7 +565,7 @@ splitting up an existing category.</para>
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section><title>Versioning</title>
|
<section xml:id="sec-versioning"><title>Versioning</title>
|
||||||
|
|
||||||
<para>Because every version of a package in Nixpkgs creates a
|
<para>Because every version of a package in Nixpkgs creates a
|
||||||
potential maintenance burden, old versions of a package should not be
|
potential maintenance burden, old versions of a package should not be
|
||||||
|
21
doc/contributing.xml
Normal file
21
doc/contributing.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="chap-contributing">
|
||||||
|
|
||||||
|
<title>Contributing</title>
|
||||||
|
|
||||||
|
<para>If you make modifications to the manual, it's important to build the manual before contributing:</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
|
||||||
|
<listitem><para><command>$ git clone git://github.com/NixOS/nixpkgs.git</command></para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><command>$ cd nixpkgs/pkgs/top-level</command></para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><command>$ nix-build -A tarball release.nix</command></para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Inside the built derivation you shall see <literal>manual/index.html</literal> file.</para></listitem>
|
||||||
|
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
</chapter>
|
@ -108,7 +108,7 @@ a <varname>preConfigure</varname> hook to generate a configuration
|
|||||||
file used by <filename>Makefile.PL</filename>:
|
file used by <filename>Makefile.PL</filename>:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{buildPerlPackage, fetchurl, db4}:
|
{buildPerlPackage, fetchurl, db}:
|
||||||
|
|
||||||
buildPerlPackage rec {
|
buildPerlPackage rec {
|
||||||
name = "BerkeleyDB-0.36";
|
name = "BerkeleyDB-0.36";
|
||||||
@ -119,8 +119,8 @@ buildPerlPackage rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
preConfigure = ''
|
preConfigure = ''
|
||||||
echo "LIB = ${db4}/lib" > config.in
|
echo "LIB = ${db}/lib" > config.in
|
||||||
echo "INCLUDE = ${db4}/include" >> config.in
|
echo "INCLUDE = ${db}/include" >> config.in
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@ -233,10 +233,83 @@ twisted = buildPythonPackage {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Java</title>
|
<section xml:id="ssec-language-java"><title>Java</title>
|
||||||
|
|
||||||
<para>Java packages should install JAR files in
|
<para>Ant-based Java packages are typically built from source as follows:
|
||||||
<filename>$out/lib/java</filename>.</para>
|
|
||||||
|
<programlisting>
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "...";
|
||||||
|
src = fetchurl { ... };
|
||||||
|
|
||||||
|
buildInputs = [ jdk ant ];
|
||||||
|
|
||||||
|
buildPhase = "ant";
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Note that <varname>jdk</varname> is an alias for the OpenJDK.</para>
|
||||||
|
|
||||||
|
<para>JAR files that are intended to be used by other packages should
|
||||||
|
be installed in <filename>$out/share/java</filename>. The OpenJDK has
|
||||||
|
a stdenv setup hook that adds any JARs in the
|
||||||
|
<filename>share/java</filename> directories of the build inputs to the
|
||||||
|
<envar>CLASSPATH</envar> environment variable. For instance, if the
|
||||||
|
package <literal>libfoo</literal> installs a JAR named
|
||||||
|
<filename>foo.jar</filename> in its <filename>share/java</filename>
|
||||||
|
directory, and another package declares the attribute
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
buildInputs = [ jdk libfoo ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
then <envar>CLASSPATH</envar> will be set to
|
||||||
|
<filename>/nix/store/...-libfoo/share/java/foo.jar</filename>.</para>
|
||||||
|
|
||||||
|
<para>Private JARs
|
||||||
|
should be installed in a location like
|
||||||
|
<filename>$out/share/<replaceable>package-name</replaceable></filename>.</para>
|
||||||
|
|
||||||
|
<para>If your Java package provides a program, you need to generate a
|
||||||
|
wrapper script to run it using the OpenJRE. You can use
|
||||||
|
<literal>makeWrapper</literal> for this:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
buildInputs = [ makeWrapper ];
|
||||||
|
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
makeWrapper ${jre}/bin/java $out/bin/foo \
|
||||||
|
--add-flags "-cp $out/share/java/foo.jar org.foo.Main"
|
||||||
|
'';
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Note the use of <literal>jre</literal>, which is the part of the
|
||||||
|
OpenJDK package that contains the Java Runtime Environment. By using
|
||||||
|
<literal>${jre}/bin/java</literal> instead of
|
||||||
|
<literal>${jdk}/bin/java</literal>, you prevent your package from
|
||||||
|
depending on the JDK at runtime.</para>
|
||||||
|
|
||||||
|
<para>It is possible to use a different Java compiler than
|
||||||
|
<command>javac</command> from the OpenJDK. For instance, to use the
|
||||||
|
Eclipse Java Compiler:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
buildInputs = [ jre ant ecj ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
(Note that here you don’t need the full JDK as an input, but just the
|
||||||
|
JRE.) The ECJ has a stdenv setup hook that sets some environment
|
||||||
|
variables to cause Ant to use ECJ, but this doesn’t work with all Ant
|
||||||
|
files. Similarly, you can use the GNU Java Compiler:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
buildInputs = [ gcj ant ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Here, Ant will automatically use <command>gij</command> (the GNU Java
|
||||||
|
Runtime) instead of the OpenJRE.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
<xi:include href="language-support.xml" />
|
<xi:include href="language-support.xml" />
|
||||||
<xi:include href="package-notes.xml" />
|
<xi:include href="package-notes.xml" />
|
||||||
<xi:include href="coding-conventions.xml" />
|
<xi:include href="coding-conventions.xml" />
|
||||||
|
<xi:include href="contributing.xml" />
|
||||||
|
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
188
doc/meta.xml
188
doc/meta.xml
@ -17,7 +17,9 @@ meta = {
|
|||||||
It is fully customizable.
|
It is fully customizable.
|
||||||
'';
|
'';
|
||||||
homepage = http://www.gnu.org/software/hello/manual/;
|
homepage = http://www.gnu.org/software/hello/manual/;
|
||||||
license = "GPLv3+";
|
license = stdenv.lib.licenses.gpl3Plus;
|
||||||
|
maintainers = [ stdenv.lib.maintainers.eelco ];
|
||||||
|
platforms = stdenv.lib.platforms.all;
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
@ -31,16 +33,42 @@ the package. The value of a meta-attribute must a string.</para>
|
|||||||
command-line using <command>nix-env</command>:
|
command-line using <command>nix-env</command>:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-env -qa hello --meta --xml
|
$ nix-env -qa hello --meta --json
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
{
|
||||||
<items>
|
"hello": {
|
||||||
<item attrPath="hello" name="hello-2.3" system="i686-linux">
|
"meta": {
|
||||||
<meta name="description" value="A program that produces a familiar, friendly greeting" />
|
"description": "A program that produces a familiar, friendly greeting",
|
||||||
<meta name="homepage" value="http://www.gnu.org/software/hello/manual/" />
|
"homepage": "http://www.gnu.org/software/hello/manual/",
|
||||||
<meta name="license" value="GPLv3+" />
|
"license": {
|
||||||
<meta name="longDescription" value="GNU Hello is a program that prints &quot;Hello, world!&quot; when you run it.&#xA;It is fully customizable.&#xA;" />
|
"fullName": "GNU General Public License version 3 or later",
|
||||||
</item>
|
"shortName": "GPLv3+",
|
||||||
</items>
|
"url": "http://www.fsf.org/licensing/licenses/gpl.html"
|
||||||
|
},
|
||||||
|
"longDescription": "GNU Hello is a program that prints \"Hello, world!\" when you run it.\nIt is fully customizable.\n",
|
||||||
|
"maintainers": [
|
||||||
|
"Ludovic Court\u00e8s <ludo@gnu.org>"
|
||||||
|
],
|
||||||
|
"platforms": [
|
||||||
|
"i686-linux",
|
||||||
|
"x86_64-linux",
|
||||||
|
"armv5tel-linux",
|
||||||
|
"armv7l-linux",
|
||||||
|
"mips64el-linux",
|
||||||
|
"x86_64-darwin",
|
||||||
|
"i686-cygwin",
|
||||||
|
"i686-freebsd",
|
||||||
|
"x86_64-freebsd",
|
||||||
|
"i686-openbsd",
|
||||||
|
"x86_64-openbsd"
|
||||||
|
],
|
||||||
|
"position": "/home/user/dev/nixpkgs/pkgs/applications/misc/hello/ex-2/default.nix:14"
|
||||||
|
},
|
||||||
|
"name": "hello-2.9",
|
||||||
|
"system": "x86_64-linux"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
<command>nix-env</command> knows about the
|
<command>nix-env</command> knows about the
|
||||||
@ -92,20 +120,23 @@ interpretation:</para>
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>license</varname></term>
|
<term><varname>license</varname></term>
|
||||||
<listitem><para>The license for the package. See below for the
|
<listitem><para>The license for the package. One from attribute set defined in
|
||||||
allowed values.</para></listitem>
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
|
||||||
|
<filename>nixpkgs/lib/licenses.nix</filename></link>.
|
||||||
|
Example:
|
||||||
|
<literal>stdenv.lib.licenses.gpl3</literal>.</para></listitem>
|
||||||
|
See details in <xref linkend='sec-meta-license'/>,
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>maintainers</varname></term>
|
<term><varname>maintainers</varname></term>
|
||||||
<listitem><para>A list of names and e-mail addresses of the
|
<listitem><para>A list of names and e-mail addresses of the
|
||||||
maintainers of this Nix expression, e.g. <literal>["Alice
|
maintainers of this Nix expression. If
|
||||||
<alice@example.org>" "Bob <bob@example.com>"]</literal>. If
|
you would like to be a maintainer of a package, you may want to add
|
||||||
you are the maintainer of multiple packages, you may want to add
|
|
||||||
yourself to <link
|
yourself to <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/lib/maintainers.nix"><filename>pkgs/lib/maintainers.nix</filename></link>
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/maintainers.nix"><filename>nixpkgs/lib/maintainers.nix</filename></link>
|
||||||
and write something like <literal>[stdenv.lib.maintainers.alice
|
and write something like <literal>[ stdenv.lib.maintainers.alice
|
||||||
stdenv.lib.maintainers.bob]</literal>.</para></listitem>
|
stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -118,6 +149,52 @@ interpretation:</para>
|
|||||||
package).</para></listitem>
|
package).</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>platforms</varname></term>
|
||||||
|
<listitem><para>The list of Nix platform types on which the
|
||||||
|
package is supported. Hydra builds packages according to the
|
||||||
|
platform specified. If no platform is specified, the package does
|
||||||
|
not have prebuilt binaries. An example is:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
meta.platforms = stdenv.lib.platforms.linux;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Attribute Set <varname>stdenv.lib.platforms</varname> in
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/platforms.nix">
|
||||||
|
<filename>nixpkgs/lib/platforms.nix</filename></link> defines various common
|
||||||
|
lists of platforms types.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>hydraPlatforms</varname></term>
|
||||||
|
<listitem><para>The list of Nix platform types for which the Hydra
|
||||||
|
instance at <literal>hydra.nixos.org</literal> will build the
|
||||||
|
package. (Hydra is the Nix-based continuous build system.) It
|
||||||
|
defaults to the value of <varname>meta.platforms</varname>. Thus,
|
||||||
|
the only reason to set <varname>meta.hydraPlatforms</varname> is
|
||||||
|
if you want <literal>hydra.nixos.org</literal> to build the
|
||||||
|
package on a subset of <varname>meta.platforms</varname>, or not
|
||||||
|
at all, e.g.
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
meta.platforms = stdenv.lib.platforms.linux;
|
||||||
|
meta.hydraPlatforms = [];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>broken</varname></term>
|
||||||
|
<listitem><para>If set to <literal>true</literal>, the package is
|
||||||
|
marked as “broken”, meaning that it won’t show up in
|
||||||
|
<literal>nix-env -qa</literal>, and cannot be built or installed.
|
||||||
|
Such packages should be removed from Nixpkgs eventually unless
|
||||||
|
they are fixed.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
|
||||||
@ -126,80 +203,23 @@ interpretation:</para>
|
|||||||
|
|
||||||
<section xml:id="sec-meta-license"><title>Licenses</title>
|
<section xml:id="sec-meta-license"><title>Licenses</title>
|
||||||
|
|
||||||
<note><para>This is just a first attempt at standardising the license
|
<para>The <varname>meta.license</varname> attribute should preferrably contain
|
||||||
attribute.</para></note>
|
a value from <varname>stdenv.lib.licenses</varname> defined in
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix">
|
||||||
<para>The <varname>meta.license</varname> attribute must be one of the
|
<filename>nixpkgs/lib/licenses.nix</filename></link>,
|
||||||
following:
|
or in-place license description of the same format if the license is
|
||||||
|
unlikely to be useful in another expression.
|
||||||
|
|
||||||
|
A few generic options are available, although it's typically better
|
||||||
|
to indicate the specific license:
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>GPL</varname></term>
|
|
||||||
<listitem><para>GNU General Public License; version not
|
|
||||||
specified.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>GPLv2</varname></term>
|
|
||||||
<listitem><para>GNU General Public License, version
|
|
||||||
2.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>GPLv2+</varname></term>
|
|
||||||
<listitem><para>GNU General Public License, version
|
|
||||||
2 or higher.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>GPLv3</varname></term>
|
|
||||||
<listitem><para>GNU General Public License, version
|
|
||||||
3.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>GPLv3+</varname></term>
|
|
||||||
<listitem><para>GNU General Public License, version
|
|
||||||
3 or higher.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>bsd</varname></term>
|
|
||||||
<listitem><para>Catch-all for licenses that are essentially
|
|
||||||
similar to <link
|
|
||||||
xlink:href="http://www.gnu.org/licenses/license-list.html#ModifiedBSD">the
|
|
||||||
original BSD license with the advertising clause removed</link>,
|
|
||||||
i.e. permissive non-copyleft free software licenses. This
|
|
||||||
includes the <link
|
|
||||||
xlink:href="http://www.gnu.org/licenses/license-list.html#X11License">X11
|
|
||||||
(“MIT”) License</link>.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>perl5</varname></term>
|
|
||||||
<listitem><para>The Perl 5 license (Artistic License, version 1
|
|
||||||
and GPL, version 1 or later).</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>free</varname></term>
|
<term><varname>free</varname></term>
|
||||||
<listitem><para>Catch-all for free software licenses not listed
|
<listitem><para>Catch-all for free software licenses not listed
|
||||||
above.</para></listitem>
|
above.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>free-copyleft</varname></term>
|
|
||||||
<listitem><para>Catch-all for free, copyleft software licenses not
|
|
||||||
listed above.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>free-non-copyleft</varname></term>
|
|
||||||
<listitem><para>Catch-all for free, non-copyleft software licenses
|
|
||||||
not listed above.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>unfree-redistributable</varname></term>
|
<term><varname>unfree-redistributable</varname></term>
|
||||||
<listitem><para>Unfree package that can be redistributed in binary
|
<listitem><para>Unfree package that can be redistributed in binary
|
||||||
|
158
doc/outline.txt
158
doc/outline.txt
@ -1,158 +0,0 @@
|
|||||||
- The standard environment
|
|
||||||
|
|
||||||
(Some of this can be moved from the Nix manual)
|
|
||||||
|
|
||||||
- Special attributes
|
|
||||||
|
|
||||||
- Generic builder
|
|
||||||
|
|
||||||
- Helper functions
|
|
||||||
|
|
||||||
- GCC / ld wrapper (+ env vars)
|
|
||||||
|
|
||||||
- Phases (+ how to add phases) and hooks
|
|
||||||
|
|
||||||
- Override functions for stdenv
|
|
||||||
|
|
||||||
- Overriding GCC
|
|
||||||
|
|
||||||
- Overriding the setup script
|
|
||||||
|
|
||||||
- Predefined override functions in all-packages.nix: static binary
|
|
||||||
stdenv, dietlibc stdenv
|
|
||||||
|
|
||||||
- Stdenv bootstrap; how to update the Linux bootstrap binaries
|
|
||||||
|
|
||||||
- Specific platform notes (Linux, Native, Cygwin, Mingw)
|
|
||||||
|
|
||||||
|
|
||||||
- Support for specific languages
|
|
||||||
|
|
||||||
- Perl
|
|
||||||
|
|
||||||
- Generic Perl builder
|
|
||||||
|
|
||||||
- Python
|
|
||||||
|
|
||||||
- Wrapper generation
|
|
||||||
|
|
||||||
- Haskell
|
|
||||||
|
|
||||||
- TODO
|
|
||||||
|
|
||||||
- Java
|
|
||||||
|
|
||||||
- TODO; Java needs lots of improvement
|
|
||||||
|
|
||||||
- TeX/LaTeX
|
|
||||||
|
|
||||||
- Special support for building TeX documents
|
|
||||||
|
|
||||||
|
|
||||||
- Special kinds of applications
|
|
||||||
|
|
||||||
- OpenGL apps
|
|
||||||
|
|
||||||
- Binary-only apps
|
|
||||||
|
|
||||||
- Linux kernel modules
|
|
||||||
|
|
||||||
- Mozilla plugins/extensions
|
|
||||||
|
|
||||||
- X apps
|
|
||||||
|
|
||||||
- KDE apps
|
|
||||||
|
|
||||||
- GConf-based apps
|
|
||||||
|
|
||||||
- Programs that need wrappers
|
|
||||||
|
|
||||||
- makeWrapper etc.
|
|
||||||
|
|
||||||
- Initial ramdisks
|
|
||||||
|
|
||||||
|
|
||||||
- Library functions
|
|
||||||
|
|
||||||
- i.e. in lib/default.nix
|
|
||||||
|
|
||||||
|
|
||||||
- Specific package notes
|
|
||||||
|
|
||||||
- Linux kernel; how to update; feature tests
|
|
||||||
|
|
||||||
- X.org; how to update
|
|
||||||
|
|
||||||
- Gnome; how to update
|
|
||||||
|
|
||||||
- GCC?
|
|
||||||
|
|
||||||
- GHC?
|
|
||||||
|
|
||||||
- ...
|
|
||||||
|
|
||||||
|
|
||||||
- Meta attributes
|
|
||||||
|
|
||||||
- License attr; possible values
|
|
||||||
|
|
||||||
|
|
||||||
- Virtual machine support (for the build farm)
|
|
||||||
|
|
||||||
- vmtools
|
|
||||||
|
|
||||||
- KVM notes
|
|
||||||
|
|
||||||
- Performing a build in a VM
|
|
||||||
|
|
||||||
- In the host FS
|
|
||||||
|
|
||||||
- In a disk image
|
|
||||||
|
|
||||||
- RPM builds
|
|
||||||
|
|
||||||
- RPM image creation
|
|
||||||
|
|
||||||
- Deb builds
|
|
||||||
|
|
||||||
- Deb image creation
|
|
||||||
|
|
||||||
- Debugging VM builds
|
|
||||||
|
|
||||||
|
|
||||||
- Guidelines for Nixpkgs contributions
|
|
||||||
|
|
||||||
- File naming conventions
|
|
||||||
|
|
||||||
- Versioning of packages
|
|
||||||
|
|
||||||
- Tree organisation
|
|
||||||
|
|
||||||
- Variable naming
|
|
||||||
|
|
||||||
- Layout / indentations style
|
|
||||||
|
|
||||||
- Output FS hierarchy (e.g. $out/share/man instead of $out/man)
|
|
||||||
|
|
||||||
|
|
||||||
- Misc
|
|
||||||
|
|
||||||
- Building outside of the Nixpkgs tree
|
|
||||||
|
|
||||||
- Config options
|
|
||||||
|
|
||||||
- Downloading stuff
|
|
||||||
|
|
||||||
- fetchurl
|
|
||||||
|
|
||||||
- mirror:// scheme
|
|
||||||
|
|
||||||
- fetchsvn
|
|
||||||
|
|
||||||
- fetchcvs
|
|
||||||
|
|
||||||
- fetchdarcs
|
|
||||||
|
|
||||||
|
|
||||||
- Appendix: Nixpkgs config options
|
|
||||||
|
|
@ -71,7 +71,7 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>GNU Multiple Precision arithmetic library (GMP): <link
|
<para>GNU Multiple Precision arithmetic library (GMP): <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/gmp/5.1.1.nix"><filename>pkgs/development/libraries/gmp/5.1.1.nix</filename></link>.
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/gmp/5.1.x.nix"><filename>pkgs/development/libraries/gmp/5.1.x.nix</filename></link>.
|
||||||
Also done by the generic builder, but has a dependency on
|
Also done by the generic builder, but has a dependency on
|
||||||
<varname>m4</varname>.</para>
|
<varname>m4</varname>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -155,9 +155,10 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
|
|||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>You can use <command>nix-prefetch-url</command>
|
<para>You can use <command>nix-prefetch-url</command> (or similar nix-prefetch-git, etc)
|
||||||
<replaceable>url</replaceable> to get the SHA-256 hash of
|
<replaceable>url</replaceable> to get the SHA-256 hash of
|
||||||
source distributions.</para>
|
source distributions. There are similar commands as <command>nix-prefetch-git</command> and
|
||||||
|
<command>nix-prefetch-hg</command> available in <literal>nix-prefetch-scripts</literal> package.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -196,7 +197,8 @@ $ emacs pkgs/top-level/all-packages.nix</screen>
|
|||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Test whether the package builds:
|
<para>To test whether the package builds, run the following command
|
||||||
|
from the root of the nixpkgs source tree:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build -A libfoo</screen>
|
$ nix-build -A libfoo</screen>
|
||||||
@ -220,17 +222,10 @@ $ nix-env -f . -iA libfoo</screen>
|
|||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Optionally commit the new package, or send a patch to
|
<para>Optionally commit the new package and open a pull request, or send a patch to
|
||||||
<literal>nix-dev@cs.uu.nl</literal>.</para>
|
<literal>nix-dev@cs.uu.nl</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>If you want the TU Delft build farm to build binaries of the
|
|
||||||
package and make them available in the <link
|
|
||||||
xlink:href="http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/"><literal>nixpkgs</literal>
|
|
||||||
channel</link>, add it to <link
|
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/release.nix"><filename>pkgs/top-level/release.nix</filename></link>.</para>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ xlink:href='http://nixos.org/releases/nix/nix-0.10/'>Nix
|
|||||||
<literal>stdenv</literal>; the formed changes the C compiler, and
|
<literal>stdenv</literal>; the formed changes the C compiler, and
|
||||||
the latter adds additional packages to the front of
|
the latter adds additional packages to the front of
|
||||||
<literal>stdenv</literal>’s initial <envar>PATH</envar>, allowing
|
<literal>stdenv</literal>’s initial <envar>PATH</envar>, allowing
|
||||||
tools to be overriden.</para>
|
tools to be overridden.</para>
|
||||||
|
|
||||||
<para>For instance, the package <varname>strategoxt</varname>
|
<para>For instance, the package <varname>strategoxt</varname>
|
||||||
doesn’t build with the GNU Make in <literal>stdenv</literal>
|
doesn’t build with the GNU Make in <literal>stdenv</literal>
|
||||||
|
@ -56,7 +56,7 @@ details.)</para>
|
|||||||
<para>Often it is necessary to override or modify some aspect of the
|
<para>Often it is necessary to override or modify some aspect of the
|
||||||
build. To make this easier, the standard environment breaks the
|
build. To make this easier, the standard environment breaks the
|
||||||
package build into a number of <emphasis>phases</emphasis>, all of
|
package build into a number of <emphasis>phases</emphasis>, all of
|
||||||
which can be overriden or modified individually: unpacking the
|
which can be overridden or modified individually: unpacking the
|
||||||
sources, applying patches, configuring, building, and installing.
|
sources, applying patches, configuring, building, and installing.
|
||||||
(There are some others; see <xref linkend="ssec-stdenv-phases"/>.)
|
(There are some others; see <xref linkend="ssec-stdenv-phases"/>.)
|
||||||
For instance, a package that doesn’t supply a makefile but instead has
|
For instance, a package that doesn’t supply a makefile but instead has
|
||||||
@ -233,7 +233,7 @@ specific parts of the build (e.g., unpacking the sources or installing
|
|||||||
the binaries). Furthermore, it allows a nicer presentation of build
|
the binaries). Furthermore, it allows a nicer presentation of build
|
||||||
logs in the Nix build farm.</para>
|
logs in the Nix build farm.</para>
|
||||||
|
|
||||||
<para>Each phase can be overriden in its entirety either by setting
|
<para>Each phase can be overridden in its entirety either by setting
|
||||||
the environment variable
|
the environment variable
|
||||||
<varname><replaceable>name</replaceable>Phase</varname> to a string
|
<varname><replaceable>name</replaceable>Phase</varname> to a string
|
||||||
containing some shell commands to be executed, or by redefining the
|
containing some shell commands to be executed, or by redefining the
|
||||||
@ -298,6 +298,13 @@ executed and in what order:
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>preFixupPhases</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Additional phases executed just before the fixup phase.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>preDistPhases</varname></term>
|
<term><varname>preDistPhases</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -1156,12 +1163,27 @@ echo @foo@
|
|||||||
to Qt’s path.</para></listitem>
|
to Qt’s path.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>gdk-pixbuf</term>
|
||||||
|
<listitem><para>Exports <envar>GDK_PIXBUF_MODULE_FILE</envar>
|
||||||
|
environment variable the the builder. Add librsvg package
|
||||||
|
to <varname>buildInputs</varname> to get svg support.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>GHC</term>
|
<term>GHC</term>
|
||||||
<listitem><para>Creates a temporary package database and registers
|
<listitem><para>Creates a temporary package database and registers
|
||||||
every Haskell build input in it (TODO: how?).</para></listitem>
|
every Haskell build input in it (TODO: how?).</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>GStreamer</term>
|
||||||
|
<listitem><para>Adds the
|
||||||
|
GStreamer plugins subdirectory of
|
||||||
|
each build input to the <envar>GST_PLUGIN_SYSTEM_PATH_1_0</envar> or
|
||||||
|
<envar>GST_PLUGIN_SYSTEM_PATH</envar> environment variable.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Operations on attribute sets.
|
# Operations on attribute sets.
|
||||||
|
|
||||||
with {
|
with {
|
||||||
inherit (builtins) head tail isString;
|
inherit (builtins) head tail;
|
||||||
inherit (import ./trivial.nix) or;
|
inherit (import ./trivial.nix) or;
|
||||||
inherit (import ./default.nix) fold;
|
inherit (import ./default.nix) fold;
|
||||||
inherit (import ./strings.nix) concatStringsSep;
|
inherit (import ./strings.nix) concatStringsSep;
|
||||||
@ -20,7 +20,7 @@ rec {
|
|||||||
let attr = head attrPath;
|
let attr = head attrPath;
|
||||||
in
|
in
|
||||||
if attrPath == [] then e
|
if attrPath == [] then e
|
||||||
else if builtins ? hasAttr && hasAttr attr e
|
else if hasAttr attr e
|
||||||
then attrByPath (tail attrPath) default (getAttr attr e)
|
then attrByPath (tail attrPath) default (getAttr attr e)
|
||||||
else default;
|
else default;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ rec {
|
|||||||
(AttrSet -> Bool) -> AttrSet -> AttrSet
|
(AttrSet -> Bool) -> AttrSet -> AttrSet
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
collect builtins.isList { a = { b = ["b"]; }; c = [1]; }
|
collect isList { a = { b = ["b"]; }; c = [1]; }
|
||||||
=> [["b"] [1]]
|
=> [["b"] [1]]
|
||||||
|
|
||||||
collect (x: x ? outPath)
|
collect (x: x ? outPath)
|
||||||
@ -110,7 +110,7 @@ rec {
|
|||||||
collect = pred: attrs:
|
collect = pred: attrs:
|
||||||
if pred attrs then
|
if pred attrs then
|
||||||
[ attrs ]
|
[ attrs ]
|
||||||
else if builtins.isAttrs attrs then
|
else if isAttrs attrs then
|
||||||
concatMap (collect pred) (attrValues attrs)
|
concatMap (collect pred) (attrValues attrs)
|
||||||
else
|
else
|
||||||
[];
|
[];
|
||||||
|
@ -1,15 +1,74 @@
|
|||||||
{lib, pkgs} :
|
{lib, pkgs} :
|
||||||
let inherit (lib) nv nvs; in
|
let inherit (lib) nv nvs; in
|
||||||
{
|
{
|
||||||
# see for example:
|
|
||||||
# - development/interpreters/php_configurable/default.nix
|
# composableDerivation basically mixes these features:
|
||||||
# - .. search composableDerivation in all-packages.nix ..
|
# - fix function
|
||||||
|
# - mergeAttrBy
|
||||||
|
# - provides shortcuts for "options" such as "--enable-foo" and adding
|
||||||
|
# buildInputs, see php example
|
||||||
#
|
#
|
||||||
# You should be able to override anything you like easily
|
# It predates styles which are common today, such as
|
||||||
# grep the mailinglist by title "python proposal" (dec 08)
|
# * the config attr
|
||||||
# -> http://mail.cs.uu.nl/pipermail/nix-dev/2008-December/001571.html
|
# * mkDerivation.override feature
|
||||||
# to see why this got complicated when using all its features
|
# * overrideDerivation (lib/customization.nix)
|
||||||
# TODO add newer example using new syntax (kernel derivation proposal -> mailinglist)
|
#
|
||||||
|
# Some of the most more important usage examples (which could be rewritten if it was important):
|
||||||
|
# * php
|
||||||
|
# * postgis
|
||||||
|
# * vim_configurable
|
||||||
|
#
|
||||||
|
# A minimal example illustrating most features would look like this:
|
||||||
|
# let base = composableDerivation { (fixed : let inherit (fixed.fixed) name in {
|
||||||
|
# src = fetchurl {
|
||||||
|
# }
|
||||||
|
# buildInputs = [A];
|
||||||
|
# preConfigre = "echo ${name}";
|
||||||
|
# # attention, "name" attr is missing, thus you cannot instantiate "base".
|
||||||
|
# }
|
||||||
|
# in {
|
||||||
|
# # These all add name attribute, thus you can instantiate those:
|
||||||
|
# v1 = base.merge ({ name = "foo-add-B"; buildInputs = [B]; }); // B gets merged into buildInputs
|
||||||
|
# v2 = base.merge ({ name = "mix-in-pre-configure-lines" preConfigre = ""; });
|
||||||
|
# v3 = base.replace ({ name = "foo-no-A-only-B;" buildInputs = [B]; });
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# So yes, you can think about it being something like nixos modules, and
|
||||||
|
# you'd be merging "features" in one at a time using .merge or .replace
|
||||||
|
# Thanks Shea for telling me that I rethink the documentation ..
|
||||||
|
#
|
||||||
|
# issues:
|
||||||
|
# * its complicated to understand
|
||||||
|
# * some "features" such as exact merge behaviour are burried in mergeAttrBy
|
||||||
|
# and defaultOverridableDelayableArgs assuming the default behaviour does
|
||||||
|
# the right thing in the common case
|
||||||
|
# * Eelco once said using such fix style functions are slow to evaluate
|
||||||
|
# * Too quick & dirty. Hard to understand for others. The benefit was that
|
||||||
|
# you were able to create a kernel builder like base derivation and replace
|
||||||
|
# / add patches the way you want without having to declare function arguments
|
||||||
|
#
|
||||||
|
# nice features:
|
||||||
|
# declaring "optional featuers" is modular. For instance:
|
||||||
|
# flags.curl = {
|
||||||
|
# configureFlags = ["--with-curl=${curl}" "--with-curlwrappers"];
|
||||||
|
# buildInputs = [curl openssl];
|
||||||
|
# };
|
||||||
|
# flags.other = { .. }
|
||||||
|
# (Example taken from PHP)
|
||||||
|
#
|
||||||
|
# alternative styles / related features:
|
||||||
|
# * Eg see function supporting building the kernel
|
||||||
|
# * versionedDerivation (discussion about this is still going on - or ended)
|
||||||
|
# * composedArgsAndFun
|
||||||
|
# * mkDerivation.override
|
||||||
|
# * overrideDerivation
|
||||||
|
# * using { .., *Support ? false }: like configurable options.
|
||||||
|
# To find those examples use grep
|
||||||
|
#
|
||||||
|
# To sum up: It exists for historical reasons - and for most commonly used
|
||||||
|
# tasks the alternatives should be used
|
||||||
|
#
|
||||||
|
# If you have questions about this code ping Marc Weber.
|
||||||
composableDerivation = {
|
composableDerivation = {
|
||||||
mkDerivation ? pkgs.stdenv.mkDerivation,
|
mkDerivation ? pkgs.stdenv.mkDerivation,
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ let
|
|||||||
in
|
in
|
||||||
{ inherit trivial lists strings stringsWithDeps attrsets sources options
|
{ inherit trivial lists strings stringsWithDeps attrsets sources options
|
||||||
modules types meta debug maintainers licenses platforms systems;
|
modules types meta debug maintainers licenses platforms systems;
|
||||||
# Pull in some builtins not included elsewhere.
|
|
||||||
inherit (builtins) pathExists readFile;
|
|
||||||
}
|
}
|
||||||
# !!! don't include everything at top-level; perhaps only the most
|
# !!! don't include everything at top-level; perhaps only the most
|
||||||
# commonly used functions.
|
# commonly used functions.
|
||||||
|
310
lib/licenses.nix
310
lib/licenses.nix
@ -1,137 +1,175 @@
|
|||||||
{
|
let
|
||||||
/* License identifiers loosely based on: http://fedoraproject.org/wiki/Licensing
|
spdx = lic: lic // {
|
||||||
|
url = "http://spdx.org/licenses/${lic.shortName}";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
/* License identifiers from spdx.org where possible.
|
||||||
* If you cannot find your license here, then look for a similar license or
|
* If you cannot find your license here, then look for a similar license or
|
||||||
* add it to this list. The URL mentioned above is a good source for inspiration.
|
* add it to this list. The URL mentioned above is a good source for inspiration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
artistic2 = {
|
agpl3 = spdx {
|
||||||
shortName = "Artistic 2.0";
|
shortName = "AGPL-3.0";
|
||||||
fullName = "Artistic 2.0";
|
fullName = "GNU Affero General Public License v3.0";
|
||||||
url = "http://opensource.org/licenses/artistic-license-2.0.php";
|
|
||||||
};
|
|
||||||
|
|
||||||
agpl3 = {
|
|
||||||
shortName = "AGPLv3";
|
|
||||||
fullName = "GNU Affero General Public License version 3 only";
|
|
||||||
url = https://www.gnu.org/licenses/agpl.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
agpl3Plus = {
|
agpl3Plus = {
|
||||||
shortName = "AGPLv3+";
|
shortName = "AGPL-3.0+";
|
||||||
fullName = "GNU Affero General Public License version 3 or later";
|
fullName = "GNU Affero General Public License v3.0 or later";
|
||||||
url = https://www.gnu.org/licenses/agpl.html;
|
inherit (agpl3) url;
|
||||||
};
|
};
|
||||||
|
|
||||||
amd = {
|
amd = {
|
||||||
shortName = "amd";
|
shortName = "amd";
|
||||||
fullName = "AMD License Agreement";
|
fullName = "AMD License Agreement";
|
||||||
url = "http://developer.amd.com/amd-license-agreement/";
|
url = http://developer.amd.com/amd-license-agreement/;
|
||||||
|
};#
|
||||||
|
|
||||||
|
apsl20 = spdx {
|
||||||
|
shortName = "APSL-2.0";
|
||||||
|
fullName = "Apple Public Source License 2.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
amdadl = {
|
artistic2 = spdx {
|
||||||
shortName = "amd-adl";
|
shortName = "Artistic-2.0";
|
||||||
fullName = "amd-adl license";
|
fullName = "Artistic License 2.0";
|
||||||
url = "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/licenses/AMD-ADL?revision=1.1";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Apple Public Source License 2.0;
|
asl20 = spdx {
|
||||||
# http://opensource.org/licenses/APSL-2.0
|
shortName = "Apache-2.0";
|
||||||
apsl20 = "APSL 2.0";
|
fullName = "Apache License 2.0";
|
||||||
|
|
||||||
asl20 = {
|
|
||||||
shortName = "ASL2.0";
|
|
||||||
fullName = "Apache Software License 2.0";
|
|
||||||
url = http://www.apache.org/licenses/LICENSE-2.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
boost = {
|
boost = spdx {
|
||||||
shortName = "boost";
|
shortName = "BSL-1.0";
|
||||||
fullName = "Boost Software License";
|
fullName = "Boost Software License 1.0";
|
||||||
url = http://www.boost.org/LICENSE_1_0.txt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bsd2 = {
|
bsd2 = spdx {
|
||||||
shortName = "BSD-2";
|
shortName = "BSD-2-Clause";
|
||||||
fullName = "BSD license (2 clause)";
|
fullName = ''BSD 2-clause "Simplified" License'';
|
||||||
url = http://opensource.org/licenses/BSD-2-Clause;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bsd3 = {
|
bsd3 = spdx {
|
||||||
shortName = "BSD-3";
|
shortName = "BSD-3-Clause";
|
||||||
fullName = "BSD license (3 clause)";
|
fullName = ''BSD 3-clause "New" or "Revised" License'';
|
||||||
url = http://opensource.org/licenses/BSD-3-Clause;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bsdOriginal = {
|
bsdOriginal = spdx {
|
||||||
shortName = "BSD-original";
|
shortName = "BSD-4-Clause";
|
||||||
fullName = "Original BSD license with advertising clause";
|
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
||||||
url = https://fedoraproject.org/wiki/Licensing/BSD;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cddl = {
|
cc-by-30 = spdx {
|
||||||
shortName = "CDDL";
|
shortName = "CC-BY-3.0";
|
||||||
fullName = "Common Development Distribution License ";
|
fullName = "Creative Commons Attribution 3.0";
|
||||||
url = http://www.opensolaris.org/os/licensing/cddllicense.txt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cpl10 = {
|
cddl = spdx {
|
||||||
shortName = "CPL 1.0";
|
shortName = "CDDL-1.0";
|
||||||
fullName = "Common Public License version 1.0";
|
fullName = "Common Development and Distribution License 1.0";
|
||||||
url = http://www.eclipse.org/legal/cpl-v10.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
epl10 = {
|
cecill-c = spdx {
|
||||||
shortName = "EPL 1.0";
|
shortName = "CECILL-C";
|
||||||
fullName = "Eclipse Public License version 1.0";
|
fullName = "CeCILL-C Free Software License Agreement";
|
||||||
url = http://www.eclipse.org/legal/epl-v10.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl2 = "GPLv2";
|
cpl10 = spdx {
|
||||||
|
shortName = "CPL-1.0";
|
||||||
|
fullName = "Common Public License 1.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
epl10 = spdx {
|
||||||
|
shortName = "EPL-1.0";
|
||||||
|
fullName = "Eclipse Public License 1.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
free = "free";
|
||||||
|
|
||||||
|
gpl2 = spdx {
|
||||||
|
shortName = "GPL-2.0";
|
||||||
|
fullName = "GNU General Public License v2.0 only";
|
||||||
|
};
|
||||||
|
|
||||||
gpl2Oss = {
|
gpl2Oss = {
|
||||||
shortName = "GPLv2+OSS";
|
shortName = "GPL-2.0-with-OSS";
|
||||||
fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
|
fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
|
||||||
url = http://www.mysql.com/about/legal/licensing/foss-exception;
|
url = http://www.mysql.com/about/legal/licensing/foss-exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
# GNU General Public License version 2 or later;
|
gpl2Plus = spdx {
|
||||||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
shortName = "GPL-2.0+";
|
||||||
gpl2Plus = "GPLv2+";
|
fullName = "GNU General Public License v2.0 or later";
|
||||||
|
|
||||||
gpl3 = {
|
|
||||||
shortName = "GPLv3";
|
|
||||||
fullName = "GNU General Public License version 3 only";
|
|
||||||
url = http://www.fsf.org/licensing/licenses/gpl.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl3Plus = {
|
gpl3 = spdx {
|
||||||
shortName = "GPLv3+";
|
shortName = "GPL-3.0";
|
||||||
fullName = "GNU General Public License version 3 or later";
|
fullName = "GNU General Public License v3.0 only";
|
||||||
url = http://www.fsf.org/licensing/licenses/gpl.html;
|
};
|
||||||
|
|
||||||
|
gpl3Plus = spdx {
|
||||||
|
shortName = "GPL-3.0+";
|
||||||
|
fullName = "GNU General Public License v3.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl3ClasspathPlus = {
|
gpl3ClasspathPlus = {
|
||||||
shortName = "GPLv3+classpath+";
|
shortName = "GPL-3.0+-with-classpath-exception";
|
||||||
fullName = "GNU General Public License version 3 or later (with Classpath exception)";
|
fullName = "GNU General Public License v3.0 or later (with Classpath exception)";
|
||||||
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
isc = {
|
inria = {
|
||||||
|
shortName = "INRIA-NCLA";
|
||||||
|
fullName = "INRIA Non-Commercial License Agreement";
|
||||||
|
url = "http://compcert.inria.fr/doc/LICENSE";
|
||||||
|
};
|
||||||
|
|
||||||
|
ipa = spdx {
|
||||||
|
shortName = "IPA";
|
||||||
|
fullName = "IPA Font License";
|
||||||
|
};
|
||||||
|
|
||||||
|
ipl10 = spdx {
|
||||||
|
shortName = "IPL-1.0";
|
||||||
|
fullName = "IBM Public License v1.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
isc = spdx {
|
||||||
shortName = "ISC";
|
shortName = "ISC";
|
||||||
fullName = "Internet Systems Consortium License";
|
fullName = "ISC License";
|
||||||
url = http://www.opensource.org/licenses/ISC;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ipl10 = {
|
lgpl2 = spdx {
|
||||||
shortName = "IPL 1.0";
|
shortName = "LGPL-2.0";
|
||||||
fullName = "IBM Public License Version 1.0";
|
fullName = "GNU Library General Public License v2 only";
|
||||||
url = http://www.ibm.com/developerworks/opensource/library/os-i18n2/os-ipl.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ijg = {
|
lgpl2Plus = spdx {
|
||||||
shortName = "IJG";
|
shortName = "LGPL-2.0+";
|
||||||
fullName = "Independent JPEG Group License";
|
fullName = "GNU Library General Public License v2 or later";
|
||||||
url = https://fedoraproject.org/wiki/Licensing/IJG;
|
};
|
||||||
|
|
||||||
|
lgpl21 = spdx {
|
||||||
|
shortName = "LGPL-2.1";
|
||||||
|
fullName = "GNU Library General Public License v2.1 only";
|
||||||
|
};
|
||||||
|
|
||||||
|
lgpl21Plus = spdx {
|
||||||
|
shortName = "LGPL-2.1+";
|
||||||
|
fullName = "GNU Library General Public License v2.1 or later";
|
||||||
|
};
|
||||||
|
|
||||||
|
lgpl3 = spdx {
|
||||||
|
shortName = "LGPL-3.0";
|
||||||
|
fullName = "GNU Lesser General Public License v3.0 only";
|
||||||
|
};
|
||||||
|
|
||||||
|
lgpl3Plus = spdx {
|
||||||
|
shortName = "LGPL-3.0+";
|
||||||
|
fullName = "GNU Lesser General Public License v3.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
libtiff = {
|
libtiff = {
|
||||||
@ -140,62 +178,52 @@
|
|||||||
url = https://fedoraproject.org/wiki/Licensing/libtiff;
|
url = https://fedoraproject.org/wiki/Licensing/libtiff;
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl2 = "LGPLv2";
|
|
||||||
|
|
||||||
lgpl2Plus = {
|
|
||||||
shortName = "LGPLv2+";
|
|
||||||
fullName = "GNU Library General Public License version 2 or later";
|
|
||||||
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html;
|
|
||||||
};
|
|
||||||
|
|
||||||
lgpl21 = "LGPLv2.1";
|
|
||||||
|
|
||||||
lgpl21Plus = {
|
|
||||||
shortName = "LGPLv2.1+";
|
|
||||||
fullName = "GNU Lesser General Public License version 2.1 or later";
|
|
||||||
url = http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html;
|
|
||||||
};
|
|
||||||
|
|
||||||
llgpl21 = {
|
llgpl21 = {
|
||||||
shortName = "LLGPLv2.1";
|
shortName = "LLGPL-2.1";
|
||||||
fullName = "Lisp LGPL; GNU Lesser General Public License version 2.1 with Franz Inc. preamble for clarification of LGPL terms in context of Lisp";
|
fullName = "Lisp LGPL; GNU Lesser General Public License version 2.1 with Franz Inc. preamble for clarification of LGPL terms in context of Lisp";
|
||||||
url = http://opensource.franz.com/preamble.html;
|
url = http://opensource.franz.com/preamble.html;
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl3 = {
|
lpl-102 = spdx {
|
||||||
shortName = "LGPLv3";
|
shortName = "LPL-1.02";
|
||||||
fullName = "GNU Lesser General Public License version 3 only";
|
fullName = "Lucent Public License v1.02";
|
||||||
url = http://www.fsf.org/licensing/licenses/lgpl.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl3Plus = {
|
mit = spdx {
|
||||||
shortName = "LGPLv3+";
|
|
||||||
fullName = "GNU Lesser General Public License version 3 or later";
|
|
||||||
url = http://www.fsf.org/licensing/licenses/lgpl.html;
|
|
||||||
};
|
|
||||||
|
|
||||||
mit = {
|
|
||||||
shortName = "MIT";
|
shortName = "MIT";
|
||||||
fullName = "MIT/X11 license";
|
fullName = "MIT License";
|
||||||
url = http://www.opensource.org/licenses/mit-license.php;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mpl11 = {
|
mpl11 = spdx {
|
||||||
shortName = "MPL1.1";
|
shortName = "MPL-1.1";
|
||||||
fullName = "Mozilla Public License version 1.1";
|
fullName = "Mozilla Public License 1.1";
|
||||||
url = http://www.mozilla.org/MPL/MPL-1.1.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mpl20 = {
|
mpl20 = spdx {
|
||||||
shortName = "MPL2.0";
|
shortName = "MPL-2.0";
|
||||||
fullName = "Mozilla Public License version 2.0";
|
fullName = "Mozilla Public License 2.0";
|
||||||
url = https://www.mozilla.org/MPL/2.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
openssl = {
|
msrla = {
|
||||||
shortName = "openssl";
|
shortName = "MSR-LA";
|
||||||
fullName = "OpenSSL license";
|
fullName = "Microsoft Research License Agreement";
|
||||||
url = http://www.openssl.org/source/license.html;
|
url = "http://research.microsoft.com/en-us/projects/pex/msr-la.txt";
|
||||||
|
};
|
||||||
|
|
||||||
|
ofl = spdx {
|
||||||
|
shortName = "OFL-1.1";
|
||||||
|
fullName = "SIL Open Font License 1.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
openssl = spdx {
|
||||||
|
shortName = "OpenSSL";
|
||||||
|
fullName = "OpenSSL License";
|
||||||
|
};
|
||||||
|
|
||||||
|
psfl = spdx {
|
||||||
|
shortName = "Python-2.0";
|
||||||
|
fullName = "Python Software Foundation License version 2";
|
||||||
|
#url = http://docs.python.org/license.html;
|
||||||
};
|
};
|
||||||
|
|
||||||
publicDomain = {
|
publicDomain = {
|
||||||
@ -203,10 +231,9 @@
|
|||||||
fullname = "Public Domain";
|
fullname = "Public Domain";
|
||||||
};
|
};
|
||||||
|
|
||||||
psfl = {
|
sleepycat = spdx {
|
||||||
shortName = "PSFL";
|
shortName = "Sleepycat";
|
||||||
fullName = "Python Software Foundation License";
|
fullName = "Sleepycat License";
|
||||||
url = http://docs.python.org/license.html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tcltk = {
|
tcltk = {
|
||||||
@ -221,21 +248,26 @@
|
|||||||
|
|
||||||
unfreeRedistributableFirmware = "unfree-redistributable-firmware";
|
unfreeRedistributableFirmware = "unfree-redistributable-firmware";
|
||||||
|
|
||||||
zlib = {
|
wadalab = {
|
||||||
shortName = "zlib";
|
shortName = "wadalab";
|
||||||
fullName = "zlib license";
|
fullName = "Wadalab Font License";
|
||||||
url = http://www.gzip.org/zlib/zlib_license.html;
|
url = https://fedoraproject.org/wiki/Licensing:Wadalab?rd=Licensing/Wadalab;
|
||||||
};
|
};
|
||||||
|
|
||||||
zpt20 = {
|
zlib = spdx {
|
||||||
shortName = "ZPT2.0";
|
shortName = "Zlib";
|
||||||
|
fullName = "zlib License";
|
||||||
|
};
|
||||||
|
|
||||||
|
zpt20 = spdx { # FIXME: why zpt* instead of zpl*
|
||||||
|
shortName = "ZPL-2.0";
|
||||||
fullName = "Zope Public License 2.0";
|
fullName = "Zope Public License 2.0";
|
||||||
url = "http://old.zope.org/Resources/License/ZPL-2.0";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
zpt21 = {
|
zpt21 = spdx {
|
||||||
shortName = "ZPT2.1";
|
shortName = "ZPL-2.1";
|
||||||
fullName = "Zope Public License 2.1";
|
fullName = "Zope Public License 2.1";
|
||||||
url = "http://old.zope.org/Resources/License/ZPL-2.1";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
# General list operations.
|
# General list operations.
|
||||||
let
|
|
||||||
|
|
||||||
inherit (import ./trivial.nix) deepSeq;
|
with import ./trivial.nix;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
inc = builtins.add 1;
|
inc = builtins.add 1;
|
||||||
|
|
||||||
dec = n: builtins.sub n 1;
|
dec = n: builtins.sub n 1;
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
inherit (builtins) head tail length isList add sub lessThan elemAt;
|
|
||||||
|
inherit (builtins) head tail length isList elemAt concatLists filter elem;
|
||||||
|
|
||||||
|
|
||||||
# Create a list consisting of a single element. `singleton x' is
|
# Create a list consisting of a single element. `singleton x' is
|
||||||
@ -56,10 +58,6 @@ in rec {
|
|||||||
in imap' 0;
|
in imap' 0;
|
||||||
|
|
||||||
|
|
||||||
# Concatenate a list of lists.
|
|
||||||
concatLists = builtins.concatLists or (fold (x: y: x ++ y) []);
|
|
||||||
|
|
||||||
|
|
||||||
# Map and concatenate the result.
|
# Map and concatenate the result.
|
||||||
concatMap = f: list: concatLists (map f list);
|
concatMap = f: list: concatLists (map f list);
|
||||||
|
|
||||||
@ -73,24 +71,10 @@ in rec {
|
|||||||
else [x];
|
else [x];
|
||||||
|
|
||||||
|
|
||||||
# Filter a list using a predicate; that is, return a list containing
|
|
||||||
# every element from `list' for which `pred' returns true.
|
|
||||||
filter =
|
|
||||||
builtins.filter or
|
|
||||||
(pred: list:
|
|
||||||
fold (x: y: if pred x then [x] ++ y else y) [] list);
|
|
||||||
|
|
||||||
|
|
||||||
# Remove elements equal to 'e' from a list. Useful for buildInputs.
|
# Remove elements equal to 'e' from a list. Useful for buildInputs.
|
||||||
remove = e: filter (x: x != e);
|
remove = e: filter (x: x != e);
|
||||||
|
|
||||||
|
|
||||||
# Return true if `list' has an element `x'.
|
|
||||||
elem =
|
|
||||||
builtins.elem or
|
|
||||||
(x: list: fold (a: bs: x == a || bs) false list);
|
|
||||||
|
|
||||||
|
|
||||||
# Find the sole element in the list matching the specified
|
# Find the sole element in the list matching the specified
|
||||||
# predicate, returns `default' if no such element exists, or
|
# predicate, returns `default' if no such element exists, or
|
||||||
# `multiple' if there are multiple matching elements.
|
# `multiple' if there are multiple matching elements.
|
||||||
@ -136,14 +120,14 @@ in rec {
|
|||||||
# If argument is a list, return it; else, wrap it in a singleton
|
# If argument is a list, return it; else, wrap it in a singleton
|
||||||
# list. If you're using this, you should almost certainly
|
# list. If you're using this, you should almost certainly
|
||||||
# reconsider if there isn't a more "well-typed" approach.
|
# reconsider if there isn't a more "well-typed" approach.
|
||||||
toList = x: if builtins.isList x then x else [x];
|
toList = x: if isList x then x else [x];
|
||||||
|
|
||||||
|
|
||||||
# Return a list of integers from `first' up to and including `last'.
|
# Return a list of integers from `first' up to and including `last'.
|
||||||
range = first: last:
|
range = first: last:
|
||||||
if builtins.lessThan last first
|
if lessThan last first
|
||||||
then []
|
then []
|
||||||
else [first] ++ range (builtins.add first 1) last;
|
else [first] ++ range (add first 1) last;
|
||||||
|
|
||||||
|
|
||||||
# Partition the elements of a list in two lists, `right' and
|
# Partition the elements of a list in two lists, `right' and
|
||||||
@ -160,7 +144,7 @@ in rec {
|
|||||||
let
|
let
|
||||||
len1 = length fst;
|
len1 = length fst;
|
||||||
len2 = length snd;
|
len2 = length snd;
|
||||||
len = if builtins.lessThan len1 len2 then len1 else len2;
|
len = if lessThan len1 len2 then len1 else len2;
|
||||||
zipListsWith' = n:
|
zipListsWith' = n:
|
||||||
if n != len then
|
if n != len then
|
||||||
[ (f (elemAt fst n) (elemAt snd n)) ]
|
[ (f (elemAt fst n) (elemAt snd n)) ]
|
||||||
@ -220,6 +204,7 @@ in rec {
|
|||||||
in drop' (dec len);
|
in drop' (dec len);
|
||||||
|
|
||||||
|
|
||||||
|
# Return the last element of a list.
|
||||||
last = list:
|
last = list:
|
||||||
assert list != []; elemAt list (dec (length list));
|
assert list != []; elemAt list (dec (length list));
|
||||||
|
|
||||||
@ -237,5 +222,9 @@ in rec {
|
|||||||
else [];
|
else [];
|
||||||
in zipTwoLists' 0;
|
in zipTwoLists' 0;
|
||||||
|
|
||||||
|
|
||||||
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
|
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
|
||||||
|
|
||||||
|
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,38 +4,72 @@
|
|||||||
/* Add your name and email address here. Keep the list
|
/* Add your name and email address here. Keep the list
|
||||||
alphabetically sorted. */
|
alphabetically sorted. */
|
||||||
|
|
||||||
|
_1126 = "Christian Lask <mail@elfsechsundzwanzig.de>";
|
||||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
||||||
|
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
||||||
|
akc = "Anders Claesson <akc@akc.is>";
|
||||||
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
||||||
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
||||||
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
||||||
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
||||||
|
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
|
||||||
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
||||||
antono = "Antono Vasiljev <self@antono.info>";
|
antono = "Antono Vasiljev <self@antono.info>";
|
||||||
|
arobyn = "Alexei Robyn <shados@shados.net>";
|
||||||
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
||||||
aszlig = "aszlig <aszlig@redmoonstudios.org>";
|
aszlig = "aszlig <aszlig@redmoonstudios.org>";
|
||||||
|
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
|
||||||
bbenoist = "Baptist BENOIST <return_0@live.com>";
|
bbenoist = "Baptist BENOIST <return_0@live.com>";
|
||||||
|
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
||||||
|
berdario = "Dario Bertini <berdario@gmail.com>";
|
||||||
bjg = "Brian Gough <bjg@gnu.org>";
|
bjg = "Brian Gough <bjg@gnu.org>";
|
||||||
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
||||||
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
||||||
bodil = "Bodil Stokke <nix@bodil.org>";
|
bodil = "Bodil Stokke <nix@bodil.org>";
|
||||||
|
bosu = "Boris Sukholitko <boriss@gmail.com>";
|
||||||
|
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
||||||
|
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
||||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
||||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
||||||
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
|
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
|
||||||
|
cstrahan = "Charles Strahan <charles.c.strahan@gmail.com>";
|
||||||
|
DamienCassou = "Damien Cassou <damien.cassou@gmail.com>";
|
||||||
|
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
||||||
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
||||||
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
|
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
|
||||||
ertes = "Ertugrul Söylemez <es@ertes.de>";
|
emery = "Emery Hemingway <emery@vfemail.net>";
|
||||||
|
ertes = "Ertugrul Söylemez <ertesx@gmx.de>";
|
||||||
|
falsifian = "James Cook <james.cook@utoronto.ca>";
|
||||||
|
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
||||||
|
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
|
||||||
garbas = "Rok Garbas <rok@garbas.si>";
|
garbas = "Rok Garbas <rok@garbas.si>";
|
||||||
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
||||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
guibert = "David Guibert <david.guibert@gmail.com>";
|
||||||
|
hinton = "Tom Hinton <t@larkery.com>";
|
||||||
|
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
||||||
|
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
||||||
iElectric = "Domen Kozar <domen@dev.si>";
|
iElectric = "Domen Kozar <domen@dev.si>";
|
||||||
iyzsong = "Song Wenwu <iyzsong@gmail.com>";
|
iyzsong = "Song Wenwu <iyzsong@gmail.com>";
|
||||||
jcumming = "Jack Cummings <jack@mudshark.org>";
|
jcumming = "Jack Cummings <jack@mudshark.org>";
|
||||||
|
jgeerds = "Jascha Geerds <jg@ekby.de>";
|
||||||
|
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
||||||
|
joelteon = "Joel Taylor <me@joelt.io>";
|
||||||
|
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
||||||
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
||||||
|
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
||||||
|
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
|
||||||
|
linquize = "Linquize <linquize@yahoo.com.hk>";
|
||||||
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
||||||
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
||||||
|
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
||||||
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
||||||
|
matejc = "Matej Cotman <cotman.matej@gmail.com>";
|
||||||
|
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
||||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
mornfall = "Petr Ročkai <me@mornfall.net>";
|
||||||
|
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
||||||
|
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
||||||
|
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
||||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
||||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
||||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
||||||
@ -43,24 +77,46 @@
|
|||||||
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
|
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
|
||||||
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
|
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
|
||||||
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
|
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
|
||||||
|
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
|
||||||
|
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
|
||||||
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
|
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
|
||||||
qknight = "Joachim Schiele <js@lastlog.de>";
|
qknight = "Joachim Schiele <js@lastlog.de>";
|
||||||
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
||||||
|
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
|
||||||
|
refnil = "Martin Lavoie <broemartino@gmail.com>";
|
||||||
|
relrod = "Ricky Elrod <ricky@elrod.me>";
|
||||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
||||||
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
||||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
||||||
|
roelof = "Roelof Wobben <rwobben@hotmail.com>";
|
||||||
|
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
||||||
|
rszibele = "Richard Szibele <richard_szibele@hotmail.com>";
|
||||||
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
||||||
shlevy = "Shea Levy <shea@shealevy.com>";
|
shlevy = "Shea Levy <shea@shealevy.com>";
|
||||||
simons = "Peter Simons <simons@cryp.to>";
|
simons = "Peter Simons <simons@cryp.to>";
|
||||||
|
skeidel = "Sven Keidel <svenkeidel@gmail.com>";
|
||||||
smironov = "Sergey Mironov <ierton@gmail.com>";
|
smironov = "Sergey Mironov <ierton@gmail.com>";
|
||||||
|
sprock = "Roger Mason <rmason@mun.ca>";
|
||||||
|
tailhook = "Paul Colomiets <paul@colomiets.name>";
|
||||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
||||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
||||||
|
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
||||||
|
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
||||||
|
ttuegel = "Thomas Tuegel <ttuegel@gmail.com>";
|
||||||
|
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
||||||
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
|
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
|
||||||
|
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
||||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
||||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
||||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
vizanto = "Danny Wilson <danny@prime.vc>";
|
||||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
||||||
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
||||||
|
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
|
||||||
|
wjlroe = "William Roe <willroe@gmail.com>";
|
||||||
|
wkennington = "William A. Kennington III <william@wkennington.com>";
|
||||||
|
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
|
||||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
||||||
zef = "Zef Hemel <zef@zef.me>";
|
zef = "Zef Hemel <zef@zef.me>";
|
||||||
|
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
||||||
|
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
||||||
}
|
}
|
||||||
|
28
lib/meta.nix
28
lib/meta.nix
@ -1,6 +1,9 @@
|
|||||||
/* Some functions for manipulating meta attributes, as well as the
|
/* Some functions for manipulating meta attributes, as well as the
|
||||||
name attribute. */
|
name attribute. */
|
||||||
|
|
||||||
|
let lib = import ./default.nix;
|
||||||
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
||||||
@ -11,7 +14,7 @@ rec {
|
|||||||
addMetaAttrs {description = "Bla blah";} somePkg
|
addMetaAttrs {description = "Bla blah";} somePkg
|
||||||
*/
|
*/
|
||||||
addMetaAttrs = newAttrs: drv:
|
addMetaAttrs = newAttrs: drv:
|
||||||
drv // { meta = (if drv ? meta then drv.meta else {}) // newAttrs; };
|
drv // { meta = (drv.meta or {}) // newAttrs; };
|
||||||
|
|
||||||
|
|
||||||
/* Change the symbolic name of a package for presentation purposes
|
/* Change the symbolic name of a package for presentation purposes
|
||||||
@ -28,11 +31,15 @@ rec {
|
|||||||
updateName = updater: drv: drv // {name = updater (drv.name);};
|
updateName = updater: drv: drv // {name = updater (drv.name);};
|
||||||
|
|
||||||
|
|
||||||
/* Append a suffix to the name of a package. !!! the suffix should
|
/* Append a suffix to the name of a package (before the version
|
||||||
really be appended *before* the version, at least most of the
|
part). */
|
||||||
time.
|
appendToName = suffix: updateName (name:
|
||||||
|
let x = builtins.parseDrvName name; in "${x.name}-${suffix}-${x.version}");
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply a function to each derivation and only to derivations in an attrset
|
||||||
*/
|
*/
|
||||||
appendToName = suffix: updateName (name: "${name}-${suffix}");
|
mapDerivationAttrset = f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set;
|
||||||
|
|
||||||
|
|
||||||
/* Decrease the nix-env priority of the package, i.e., other
|
/* Decrease the nix-env priority of the package, i.e., other
|
||||||
@ -40,9 +47,20 @@ rec {
|
|||||||
*/
|
*/
|
||||||
lowPrio = drv: addMetaAttrs { priority = "10"; } drv;
|
lowPrio = drv: addMetaAttrs { priority = "10"; } drv;
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply lowPrio to an attrset with derivations
|
||||||
|
*/
|
||||||
|
lowPrioSet = set: mapDerivationAttrset lowPrio set;
|
||||||
|
|
||||||
|
|
||||||
/* Increase the nix-env priority of the package, i.e., this
|
/* Increase the nix-env priority of the package, i.e., this
|
||||||
version/variant of the package will be preferred.
|
version/variant of the package will be preferred.
|
||||||
*/
|
*/
|
||||||
hiPrio = drv: addMetaAttrs { priority = "-10"; } drv;
|
hiPrio = drv: addMetaAttrs { priority = "-10"; } drv;
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply hiPrio to an attrset with derivations
|
||||||
|
*/
|
||||||
|
hiPrioSet = set: mapDerivationAttrset hiPrio set;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ rec {
|
|||||||
and ‘config’: the nested set of all option values. */
|
and ‘config’: the nested set of all option values. */
|
||||||
evalModules = { modules, prefix ? [], args ? {}, check ? true }:
|
evalModules = { modules, prefix ? [], args ? {}, check ? true }:
|
||||||
let
|
let
|
||||||
args' = args // result;
|
args' = args // { lib = import ./.; } // result;
|
||||||
closed = closeModules modules args';
|
closed = closeModules modules args';
|
||||||
# Note: the list of modules is reversed to maintain backward
|
# Note: the list of modules is reversed to maintain backward
|
||||||
# compatibility with the old module system. Not sure if this is
|
# compatibility with the old module system. Not sure if this is
|
||||||
@ -42,7 +42,7 @@ rec {
|
|||||||
closeModules = modules: args:
|
closeModules = modules: args:
|
||||||
let
|
let
|
||||||
toClosureList = file: parentKey: imap (n: x:
|
toClosureList = file: parentKey: imap (n: x:
|
||||||
if isAttrs x || builtins.isFunction x then
|
if isAttrs x || isFunction x then
|
||||||
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
|
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
|
||||||
else
|
else
|
||||||
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
|
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
|
||||||
@ -74,7 +74,7 @@ rec {
|
|||||||
config = removeAttrs m ["key" "_file" "require" "imports"];
|
config = removeAttrs m ["key" "_file" "require" "imports"];
|
||||||
};
|
};
|
||||||
|
|
||||||
applyIfFunction = f: arg: if builtins.isFunction f then f arg else f;
|
applyIfFunction = f: arg: if isFunction f then f arg else f;
|
||||||
|
|
||||||
/* Merge a list of modules. This will recurse over the option
|
/* Merge a list of modules. This will recurse over the option
|
||||||
declarations in all modules, combining them into a single set.
|
declarations in all modules, combining them into a single set.
|
||||||
@ -155,8 +155,14 @@ rec {
|
|||||||
let
|
let
|
||||||
# Process mkOverride properties, adding in the default
|
# Process mkOverride properties, adding in the default
|
||||||
# value specified in the option declaration (if any).
|
# value specified in the option declaration (if any).
|
||||||
defsFinal = filterOverrides
|
defsFinal' = filterOverrides
|
||||||
((if opt ? default then [{ file = head opt.declarations; value = mkOptionDefault opt.default; }] else []) ++ defs);
|
((if opt ? default then [{ file = head opt.declarations; value = mkOptionDefault opt.default; }] else []) ++ defs);
|
||||||
|
# Sort mkOrder properties.
|
||||||
|
defsFinal =
|
||||||
|
# Avoid sorting if we don't have to.
|
||||||
|
if any (def: def.value._type or "" == "order") defsFinal'
|
||||||
|
then sortProperties defsFinal'
|
||||||
|
else defsFinal';
|
||||||
files = map (def: def.file) defsFinal;
|
files = map (def: def.file) defsFinal;
|
||||||
# Type-check the remaining definitions, and merge them if
|
# Type-check the remaining definitions, and merge them if
|
||||||
# possible.
|
# possible.
|
||||||
@ -180,7 +186,7 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Given a config set, expand mkMerge properties, and push down the
|
/* Given a config set, expand mkMerge properties, and push down the
|
||||||
mkIf properties into the children. The result is a list of
|
other properties into the children. The result is a list of
|
||||||
config sets that do not have properties at top-level. For
|
config sets that do not have properties at top-level. For
|
||||||
example,
|
example,
|
||||||
|
|
||||||
@ -188,7 +194,7 @@ rec {
|
|||||||
|
|
||||||
is transformed into
|
is transformed into
|
||||||
|
|
||||||
[ { boot = set1; } { boot = mkIf cond set2; services mkIf cond set3; } ].
|
[ { boot = set1; } { boot = mkIf cond set2; services = mkIf cond set3; } ].
|
||||||
|
|
||||||
This transform is the critical step that allows mkIf conditions
|
This transform is the critical step that allows mkIf conditions
|
||||||
to refer to the full configuration without creating an infinite
|
to refer to the full configuration without creating an infinite
|
||||||
@ -201,7 +207,7 @@ rec {
|
|||||||
map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
|
map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
|
||||||
else if cfg._type or "" == "override" then
|
else if cfg._type or "" == "override" then
|
||||||
map (mapAttrs (n: v: mkOverride cfg.priority v)) (pushDownProperties cfg.content)
|
map (mapAttrs (n: v: mkOverride cfg.priority v)) (pushDownProperties cfg.content)
|
||||||
else
|
else # FIXME: handle mkOrder?
|
||||||
[ cfg ];
|
[ cfg ];
|
||||||
|
|
||||||
/* Given a config value, expand mkMerge properties, and discharge
|
/* Given a config value, expand mkMerge properties, and discharge
|
||||||
@ -253,6 +259,19 @@ rec {
|
|||||||
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
|
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
|
||||||
in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
|
in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
|
||||||
|
|
||||||
|
/* Sort a list of properties. The sort priority of a property is
|
||||||
|
1000 by default, but can be overriden by wrapping the property
|
||||||
|
using mkOrder. */
|
||||||
|
sortProperties = defs:
|
||||||
|
let
|
||||||
|
strip = def:
|
||||||
|
if def.value._type or "" == "order"
|
||||||
|
then def // { value = def.value.content; inherit (def.value) priority; }
|
||||||
|
else def;
|
||||||
|
defs' = map strip defs;
|
||||||
|
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
|
||||||
|
in sort compare defs';
|
||||||
|
|
||||||
/* Hack for backward compatibility: convert options of type
|
/* Hack for backward compatibility: convert options of type
|
||||||
optionSet to configOf. FIXME: remove eventually. */
|
optionSet to configOf. FIXME: remove eventually. */
|
||||||
fixupOptionType = loc: opt:
|
fixupOptionType = loc: opt:
|
||||||
@ -260,7 +279,7 @@ rec {
|
|||||||
options' = opt.options or
|
options' = opt.options or
|
||||||
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
|
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
|
||||||
coerce = x:
|
coerce = x:
|
||||||
if builtins.isFunction x then x
|
if isFunction x then x
|
||||||
else { config, ... }: { options = x; };
|
else { config, ... }: { options = x; };
|
||||||
options = map coerce (flatten options');
|
options = map coerce (flatten options');
|
||||||
f = tp:
|
f = tp:
|
||||||
@ -300,10 +319,17 @@ rec {
|
|||||||
mkForce = mkOverride 50;
|
mkForce = mkOverride 50;
|
||||||
mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’
|
mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’
|
||||||
|
|
||||||
|
mkStrict = builtins.trace "`mkStrict' is obsolete; use `mkOverride 0' instead." (mkOverride 0);
|
||||||
|
|
||||||
mkFixStrictness = id; # obsolete, no-op
|
mkFixStrictness = id; # obsolete, no-op
|
||||||
|
|
||||||
# FIXME: Add mkOrder back in. It's not currently used anywhere in
|
mkOrder = priority: content:
|
||||||
# NixOS, but it should be useful.
|
{ _type = "order";
|
||||||
|
inherit priority content;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkBefore = mkOrder 500;
|
||||||
|
mkAfter = mkOrder 1500;
|
||||||
|
|
||||||
|
|
||||||
/* Compatibility. */
|
/* Compatibility. */
|
||||||
|
@ -34,12 +34,12 @@ rec {
|
|||||||
mergeDefaultOption = loc: defs:
|
mergeDefaultOption = loc: defs:
|
||||||
let list = getValues defs; in
|
let list = getValues defs; in
|
||||||
if length list == 1 then head list
|
if length list == 1 then head list
|
||||||
else if all builtins.isFunction list then x: mergeDefaultOption loc (map (f: f x) list)
|
else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list)
|
||||||
else if all isList list then concatLists list
|
else if all isList list then concatLists list
|
||||||
else if all isAttrs list then fold lib.mergeAttrs {} list
|
else if all isAttrs list then fold lib.mergeAttrs {} list
|
||||||
else if all builtins.isBool list then fold lib.or false list
|
else if all isBool list then fold lib.or false list
|
||||||
else if all builtins.isString list then lib.concatStrings list
|
else if all isString list then lib.concatStrings list
|
||||||
else if all builtins.isInt list && all (x: x == head list) list then head list
|
else if all isInt list && all (x: x == head list) list then head list
|
||||||
else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}.";
|
else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}.";
|
||||||
|
|
||||||
/* Obsolete, will remove soon. Specify an option type or apply
|
/* Obsolete, will remove soon. Specify an option type or apply
|
||||||
@ -54,7 +54,7 @@ rec {
|
|||||||
|
|
||||||
mergeListOption = mergeTypedOption "list" isList concatLists;
|
mergeListOption = mergeTypedOption "list" isList concatLists;
|
||||||
|
|
||||||
mergeStringOption = mergeTypedOption "string" builtins.isString lib.concatStrings;
|
mergeStringOption = mergeTypedOption "string" isString lib.concatStrings;
|
||||||
|
|
||||||
mergeOneOption = loc: defs:
|
mergeOneOption = loc: defs:
|
||||||
if defs == [] then abort "This case should never happen."
|
if defs == [] then abort "This case should never happen."
|
||||||
|
@ -2,15 +2,15 @@ let lists = import ./lists.nix; in
|
|||||||
|
|
||||||
rec {
|
rec {
|
||||||
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
|
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
|
||||||
linux = ["i686-linux" "x86_64-linux" "powerpc-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"];
|
linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"];
|
||||||
darwin = ["x86_64-darwin"];
|
darwin = ["x86_64-darwin"];
|
||||||
freebsd = ["i686-freebsd" "x86_64-freebsd" "powerpc-freebsd"];
|
freebsd = ["i686-freebsd" "x86_64-freebsd"];
|
||||||
openbsd = ["i686-openbsd" "x86_64-openbsd"];
|
openbsd = ["i686-openbsd" "x86_64-openbsd"];
|
||||||
netbsd = ["i686-netbsd" "x86_64-netbsd"];
|
netbsd = ["i686-netbsd" "x86_64-netbsd"];
|
||||||
cygwin = ["i686-cygwin"];
|
cygwin = ["i686-cygwin" "x86_64-cygwin"];
|
||||||
unix = linux ++ darwin ++ freebsd ++ openbsd;
|
unix = linux ++ darwin ++ freebsd ++ openbsd;
|
||||||
all = linux ++ darwin ++ cygwin ++ freebsd ++ openbsd;
|
all = linux ++ darwin ++ cygwin ++ freebsd ++ openbsd;
|
||||||
none = [];
|
none = [];
|
||||||
allBut = platform: lists.filter (x: platform != x) all;
|
allBut = platforms: lists.filter (x: !(builtins.elem x platforms)) all;
|
||||||
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux"];
|
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux"];
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,12 @@ rec {
|
|||||||
cleanSource =
|
cleanSource =
|
||||||
let filter = name: type: let baseName = baseNameOf (toString name); in ! (
|
let filter = name: type: let baseName = baseNameOf (toString name); in ! (
|
||||||
# Filter out Subversion and CVS directories.
|
# Filter out Subversion and CVS directories.
|
||||||
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS")) ||
|
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
||||||
# Filter out backup files.
|
# Filter out backup files.
|
||||||
(lib.hasSuffix "~" baseName)
|
lib.hasSuffix "~" baseName ||
|
||||||
|
# Filter out generates files.
|
||||||
|
lib.hasSuffix ".o" baseName ||
|
||||||
|
lib.hasSuffix ".so" baseName
|
||||||
);
|
);
|
||||||
in src: builtins.filterSource filter src;
|
in src: builtins.filterSource filter src;
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ inherit (builtins) add sub lessThan length;
|
|||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
inherit (builtins) stringLength substring head tail;
|
|
||||||
|
inherit (builtins) stringLength substring head tail isString;
|
||||||
|
|
||||||
|
|
||||||
# Concatenate a list of strings.
|
# Concatenate a list of strings.
|
||||||
@ -55,12 +56,15 @@ rec {
|
|||||||
optionalString = cond: string: if cond then string else "";
|
optionalString = cond: string: if cond then string else "";
|
||||||
|
|
||||||
|
|
||||||
# Determine whether a filename ends in the given suffix.
|
# Determine whether a string has given prefix/suffix.
|
||||||
hasSuffix = ext: fileName:
|
hasPrefix = pref: str:
|
||||||
let lenFileName = stringLength fileName;
|
eqStrings (substring 0 (stringLength pref) str) pref;
|
||||||
lenExt = stringLength ext;
|
hasSuffix = suff: str:
|
||||||
in !(lessThan lenFileName lenExt) &&
|
let
|
||||||
substring (sub lenFileName lenExt) lenFileName fileName == ext;
|
lenStr = stringLength str;
|
||||||
|
lenSuff = stringLength suff;
|
||||||
|
in lenStr >= lenSuff &&
|
||||||
|
eqStrings (substring (lenStr - lenSuff) lenStr str) suff;
|
||||||
|
|
||||||
|
|
||||||
# Convert a string to a list of characters (i.e. singleton strings).
|
# Convert a string to a list of characters (i.e. singleton strings).
|
||||||
@ -115,17 +119,21 @@ rec {
|
|||||||
toLower = replaceChars upperChars lowerChars;
|
toLower = replaceChars upperChars lowerChars;
|
||||||
toUpper = replaceChars lowerChars upperChars;
|
toUpper = replaceChars lowerChars upperChars;
|
||||||
|
|
||||||
|
# Appends string context from another string
|
||||||
|
addContextFrom = a: b: (substring 0 0 a)+b;
|
||||||
|
|
||||||
# Compares strings not requiring context equality
|
# Compares strings not requiring context equality
|
||||||
# Obviously, a workaround but works on all Nix versions
|
# Obviously, a workaround but works on all Nix versions
|
||||||
eqStrings = a: b: (a+(substring 0 0 b)) == ((substring 0 0 a)+b);
|
eqStrings = a: b: addContextFrom b a == addContextFrom a b;
|
||||||
|
|
||||||
|
|
||||||
# Cut a string with a separator and produces a list of strings which were
|
# Cut a string with a separator and produces a list of strings which were
|
||||||
# separated by this separator. e.g.,
|
# separated by this separator. e.g.,
|
||||||
# `splitString "." "foo.bar.baz"' returns ["foo" "bar" "baz"].
|
# `splitString "." "foo.bar.baz"' returns ["foo" "bar" "baz"].
|
||||||
splitString = sep: s:
|
splitString = _sep: _s:
|
||||||
let
|
let
|
||||||
|
sep = addContextFrom _s _sep;
|
||||||
|
s = addContextFrom _sep _s;
|
||||||
sepLen = stringLength sep;
|
sepLen = stringLength sep;
|
||||||
sLen = stringLength s;
|
sLen = stringLength s;
|
||||||
lastSearch = sub sLen sepLen;
|
lastSearch = sub sLen sepLen;
|
||||||
@ -154,8 +162,18 @@ rec {
|
|||||||
preLen = stringLength pre;
|
preLen = stringLength pre;
|
||||||
sLen = stringLength s;
|
sLen = stringLength s;
|
||||||
in
|
in
|
||||||
if pre == substring 0 preLen s then
|
if hasPrefix pre s then
|
||||||
substring preLen (sub sLen preLen) s
|
substring preLen (sLen - preLen) s
|
||||||
|
else
|
||||||
|
s;
|
||||||
|
|
||||||
|
removeSuffix = suf: s:
|
||||||
|
let
|
||||||
|
sufLen = stringLength suf;
|
||||||
|
sLen = stringLength s;
|
||||||
|
in
|
||||||
|
if sufLen <= sLen && eqStrings suf (substring (sLen - sufLen) sufLen s) then
|
||||||
|
substring 0 (sLen - sufLen) s
|
||||||
else
|
else
|
||||||
s;
|
s;
|
||||||
|
|
||||||
|
@ -35,4 +35,19 @@ rec {
|
|||||||
else if builtins.isAttrs x
|
else if builtins.isAttrs x
|
||||||
then deepSeqAttrs x y
|
then deepSeqAttrs x y
|
||||||
else seq x y;
|
else seq x y;
|
||||||
|
|
||||||
|
# Pull in some builtins not included elsewhere.
|
||||||
|
inherit (builtins)
|
||||||
|
pathExists readFile isBool isFunction
|
||||||
|
isInt add sub lessThan;
|
||||||
|
|
||||||
|
# Return the Nixpkgs version number.
|
||||||
|
nixpkgsVersion =
|
||||||
|
let suffixFile = ../.version-suffix; in
|
||||||
|
readFile ../.version
|
||||||
|
+ (if pathExists suffixFile then readFile suffixFile else "pre-git");
|
||||||
|
|
||||||
|
# Whether we're being called by nix-shell. This is useful to
|
||||||
|
inNixShell = builtins.getEnv "IN_NIX_SHELL" == "1";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ with import ./strings.nix;
|
|||||||
rec {
|
rec {
|
||||||
|
|
||||||
isType = type: x: (x._type or "") == type;
|
isType = type: x: (x._type or "") == type;
|
||||||
typeOf = x: x._type or "";
|
|
||||||
|
|
||||||
setType = typeName: value: value // {
|
setType = typeName: value: value // {
|
||||||
_type = typeName;
|
_type = typeName;
|
||||||
@ -48,19 +47,19 @@ rec {
|
|||||||
|
|
||||||
bool = mkOptionType {
|
bool = mkOptionType {
|
||||||
name = "boolean";
|
name = "boolean";
|
||||||
check = builtins.isBool;
|
check = isBool;
|
||||||
merge = loc: fold (x: y: x.value || y) false;
|
merge = loc: fold (x: y: x.value || y) false;
|
||||||
};
|
};
|
||||||
|
|
||||||
int = mkOptionType {
|
int = mkOptionType {
|
||||||
name = "integer";
|
name = "integer";
|
||||||
check = builtins.isInt;
|
check = isInt;
|
||||||
merge = mergeOneOption;
|
merge = mergeOneOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
str = mkOptionType {
|
str = mkOptionType {
|
||||||
name = "string";
|
name = "string";
|
||||||
check = builtins.isString;
|
check = isString;
|
||||||
merge = mergeOneOption;
|
merge = mergeOneOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ rec {
|
|||||||
# separator between the values).
|
# separator between the values).
|
||||||
separatedString = sep: mkOptionType {
|
separatedString = sep: mkOptionType {
|
||||||
name = "string";
|
name = "string";
|
||||||
check = builtins.isString;
|
check = isString;
|
||||||
merge = loc: defs: concatStringsSep sep (getValues defs);
|
merge = loc: defs: concatStringsSep sep (getValues defs);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,7 +131,7 @@ rec {
|
|||||||
{ inherit (def) file;
|
{ inherit (def) file;
|
||||||
value = listToAttrs (
|
value = listToAttrs (
|
||||||
imap (elemIdx: elem:
|
imap (elemIdx: elem:
|
||||||
{ name = "unnamed-${toString defIdx}.${toString elemIdx}";
|
{ name = elem.name or "unnamed-${toString defIdx}.${toString elemIdx}";
|
||||||
value = elem;
|
value = elem;
|
||||||
}) def.value);
|
}) def.value);
|
||||||
}
|
}
|
||||||
@ -170,7 +169,7 @@ rec {
|
|||||||
|
|
||||||
functionTo = elemType: mkOptionType {
|
functionTo = elemType: mkOptionType {
|
||||||
name = "function that evaluates to a(n) ${elemType.name}";
|
name = "function that evaluates to a(n) ${elemType.name}";
|
||||||
check = builtins.isFunction;
|
check = isFunction;
|
||||||
merge = loc: defs:
|
merge = loc: defs:
|
||||||
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
|
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
|
||||||
getSubOptions = elemType.getSubOptions;
|
getSubOptions = elemType.getSubOptions;
|
||||||
@ -183,10 +182,10 @@ rec {
|
|||||||
in
|
in
|
||||||
mkOptionType rec {
|
mkOptionType rec {
|
||||||
name = "submodule";
|
name = "submodule";
|
||||||
check = x: isAttrs x || builtins.isFunction x;
|
check = x: isAttrs x || isFunction x;
|
||||||
merge = loc: defs:
|
merge = loc: defs:
|
||||||
let
|
let
|
||||||
coerce = def: if builtins.isFunction def then def else { config = def; };
|
coerce = def: if isFunction def then def else { config = def; };
|
||||||
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
|
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
|
||||||
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
|
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
|
||||||
getSubOptions = prefix: (evalModules
|
getSubOptions = prefix: (evalModules
|
||||||
@ -195,6 +194,18 @@ rec {
|
|||||||
args = { name = ""; }; }).options;
|
args = { name = ""; }; }).options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum = values: mkOptionType {
|
||||||
|
name = "one of ${concatStringsSep ", " values}";
|
||||||
|
check = flip elem values;
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
either = t1: t2: mkOptionType {
|
||||||
|
name = "${t1.name} or ${t2.name}";
|
||||||
|
check = x: t1.check x || t2.check x;
|
||||||
|
merge = mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
# Obsolete alternative to configOf. It takes its option
|
# Obsolete alternative to configOf. It takes its option
|
||||||
# declarations from the ‘options’ attribute of containing option
|
# declarations from the ‘options’ attribute of containing option
|
||||||
# declaration.
|
# declaration.
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
distDir=${NIX_TARBALLS_CACHE:-/tarballs}
|
|
||||||
|
|
||||||
url="$1"
|
|
||||||
file="$2"
|
|
||||||
if [ -z "$url" ]; then echo "syntax: $0 URL"; exit 0; fi
|
|
||||||
|
|
||||||
base="$(basename "$url")"
|
|
||||||
if [ -z "$base" ]; then echo "bad URL"; exit 1; fi
|
|
||||||
dstPath="$distDir/$base"
|
|
||||||
|
|
||||||
if [ -e "$dstPath" ]; then if [ -n "$VERBOSE" ]; then echo "$dstPath already exists"; fi; exit 0; fi
|
|
||||||
|
|
||||||
if [ -z "$file" ]; then
|
|
||||||
|
|
||||||
echo "downloading $url to $dstPath"
|
|
||||||
|
|
||||||
if [ -n "$DRY_RUN" ]; then exit 0; fi
|
|
||||||
|
|
||||||
declare -a res
|
|
||||||
if ! res=($(PRINT_PATH=1 nix-prefetch-url "$url")); then
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
storePath=${res[1]}
|
|
||||||
|
|
||||||
else
|
|
||||||
storePath="$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp $storePath "$dstPath.tmp.$$"
|
|
||||||
mv -f "$dstPath.tmp.$$" "$dstPath"
|
|
||||||
|
|
||||||
echo "hashing $dstPath"
|
|
||||||
|
|
||||||
md5=$(nix-hash --flat --type md5 "$dstPath")
|
|
||||||
ln -sfn "../$base" $distDir/md5/$md5
|
|
||||||
|
|
||||||
sha1=$(nix-hash --flat --type sha1 "$dstPath")
|
|
||||||
ln -sfn "../$base" $distDir/sha1/$sha1
|
|
||||||
|
|
||||||
sha256=$(nix-hash --flat --type sha256 "$dstPath")
|
|
||||||
ln -sfn "../$base" $distDir/sha256/$sha256
|
|
||||||
ln -sfn "../$base" $distDir/sha256/$(nix-hash --type sha256 --to-base32 "$sha256")
|
|
97
maintainers/scripts/copy-tarballs.pl
Executable file
97
maintainers/scripts/copy-tarballs.pl
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
#! /run/current-system/sw/bin/perl -w
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use XML::Simple;
|
||||||
|
use File::Basename;
|
||||||
|
use File::Path;
|
||||||
|
use File::Copy 'cp';
|
||||||
|
use IPC::Open2;
|
||||||
|
use Nix::Store;
|
||||||
|
|
||||||
|
my $myDir = dirname($0);
|
||||||
|
|
||||||
|
my $tarballsCache = $ENV{'NIX_TARBALLS_CACHE'} // "/tarballs";
|
||||||
|
|
||||||
|
my $xml = `nix-instantiate --eval-only --xml --strict '<nixpkgs/maintainers/scripts/find-tarballs.nix>'`;
|
||||||
|
die "$0: evaluation failed\n" if $? != 0;
|
||||||
|
|
||||||
|
my $data = XMLin($xml) or die;
|
||||||
|
|
||||||
|
mkpath($tarballsCache);
|
||||||
|
mkpath("$tarballsCache/md5");
|
||||||
|
mkpath("$tarballsCache/sha1");
|
||||||
|
mkpath("$tarballsCache/sha256");
|
||||||
|
|
||||||
|
foreach my $file (@{$data->{list}->{attrs}}) {
|
||||||
|
my $url = $file->{attr}->{url}->{string}->{value};
|
||||||
|
my $algo = $file->{attr}->{type}->{string}->{value};
|
||||||
|
my $hash = $file->{attr}->{hash}->{string}->{value};
|
||||||
|
|
||||||
|
if ($url !~ /^http:/ && $url !~ /^https:/ && $url !~ /^ftp:/ && $url !~ /^mirror:/) {
|
||||||
|
print STDERR "skipping $url (unsupported scheme)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url =~ /([^\/]+)$/;
|
||||||
|
my $fn = $1;
|
||||||
|
|
||||||
|
if (!defined $fn) {
|
||||||
|
print STDERR "skipping $url (no file name)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fn =~ /[&?=%]/ || $fn =~ /^\./) {
|
||||||
|
print STDERR "skipping $url (bad character in file name)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fn !~ /[a-zA-Z]/) {
|
||||||
|
print STDERR "skipping $url (no letter in file name)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fn !~ /[0-9]/) {
|
||||||
|
print STDERR "skipping $url (no digit in file name)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fn !~ /[-_\.]/) {
|
||||||
|
print STDERR "skipping $url (no dash/dot/underscore in file name)\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $dstPath = "$tarballsCache/$fn";
|
||||||
|
|
||||||
|
next if -e $dstPath;
|
||||||
|
|
||||||
|
print "downloading $url to $dstPath...\n";
|
||||||
|
|
||||||
|
next if $ENV{DRY_RUN};
|
||||||
|
|
||||||
|
$ENV{QUIET} = 1;
|
||||||
|
$ENV{PRINT_PATH} = 1;
|
||||||
|
my $fh;
|
||||||
|
my $pid = open($fh, "-|", "nix-prefetch-url", "--type", $algo, $url, $hash) or die;
|
||||||
|
waitpid($pid, 0) or die;
|
||||||
|
if ($? != 0) {
|
||||||
|
print STDERR "failed to fetch $url: $?\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
<$fh>; my $storePath = <$fh>; chomp $storePath;
|
||||||
|
|
||||||
|
die unless -e $storePath;
|
||||||
|
|
||||||
|
cp($storePath, $dstPath) or die;
|
||||||
|
|
||||||
|
my $md5 = hashFile("md5", 0, $storePath) or die;
|
||||||
|
symlink("../$fn", "$tarballsCache/md5/$md5");
|
||||||
|
|
||||||
|
my $sha1 = hashFile("sha1", 0, $storePath) or die;
|
||||||
|
symlink("../$fn", "$tarballsCache/sha1/$sha1");
|
||||||
|
|
||||||
|
my $sha256 = hashFile("sha256", 0, $storePath) or die;
|
||||||
|
symlink("../$fn", "$tarballsCache/sha256/$sha256");
|
||||||
|
|
||||||
|
$sha256 = hashFile("sha256", 1, $storePath) or die;
|
||||||
|
symlink("../$fn", "$tarballsCache/sha256/$sha256");
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
urls=$(nix-instantiate --eval-only --xml --strict '<nixpkgs/maintainers/scripts/eval-release.nix>' \
|
|
||||||
| grep -A2 'name="urls"' \
|
|
||||||
| grep '<string value=' \
|
|
||||||
| sed 's/.*"\(.*\)".*/\1/' \
|
|
||||||
| sort | uniq)
|
|
||||||
|
|
||||||
for url in $urls; do
|
|
||||||
if echo "$url" | grep -q -E "www.cs.uu.nl|nixos.org|.stratego-language.org|java.sun.com|ut2004|linuxq3a|RealPlayer|Adbe|belastingdienst|microsoft|armijn/.nix|sun.com|archive.eclipse.org"; then continue; fi
|
|
||||||
|
|
||||||
# Check the URL scheme.
|
|
||||||
if ! echo "$url" | grep -q -E "^[a-z]+://"; then echo "skipping $url (no URL scheme)"; continue; fi
|
|
||||||
|
|
||||||
# Check the basename. It should include something resembling a version.
|
|
||||||
base="$(basename "$url")"
|
|
||||||
#if ! echo "$base" | grep -q -E "[-_].*[0-9].*"; then echo "skipping $url (no version)"; continue; fi
|
|
||||||
if ! echo "$base" | grep -q -E "[a-zA-Z]"; then echo "skipping $url (no letter in name)"; continue; fi
|
|
||||||
if ! echo "$base" | grep -q -E "[0-9]"; then echo "skipping $url (no digit in name)"; continue; fi
|
|
||||||
if ! echo "$base" | grep -q -E "[-_\.]"; then echo "skipping $url (no dot/underscore in name)"; continue; fi
|
|
||||||
if echo "$base" | grep -q -E "[&?=%]"; then echo "skipping $url (bad character in name)"; continue; fi
|
|
||||||
if [ "${base:0:1}" = "." ]; then echo "skipping $url (starts with a dot)"; continue; fi
|
|
||||||
|
|
||||||
$(dirname $0)/copy-tarball.sh "$url"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo DONE
|
|
45
maintainers/scripts/find-tarballs.nix
Normal file
45
maintainers/scripts/find-tarballs.nix
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# This expression returns a list of all fetchurl calls used by all
|
||||||
|
# packages reachable from release.nix.
|
||||||
|
|
||||||
|
with import ../.. { };
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
root = removeAttrs (import ../../pkgs/top-level/release.nix { }) [ "tarball" "unstable" ];
|
||||||
|
|
||||||
|
uniqueUrls = map (x: x.file) (genericClosure {
|
||||||
|
startSet = map (file: { key = file.url; inherit file; }) urls;
|
||||||
|
operator = const [ ];
|
||||||
|
});
|
||||||
|
|
||||||
|
urls = map (drv: { url = head drv.urls; hash = drv.outputHash; type = drv.outputHashAlgo; }) fetchurlDependencies;
|
||||||
|
|
||||||
|
fetchurlDependencies = filter (drv: drv.outputHash or "" != "" && drv ? urls) dependencies;
|
||||||
|
|
||||||
|
dependencies = map (x: x.value) (genericClosure {
|
||||||
|
startSet = map keyDrv (derivationsIn' root);
|
||||||
|
operator = { key, value }: map keyDrv (immediateDependenciesOf value);
|
||||||
|
});
|
||||||
|
|
||||||
|
derivationsIn' = x:
|
||||||
|
if !canEval x then []
|
||||||
|
else if isDerivation x then optional (canEval x.drvPath) x
|
||||||
|
else if isList x then concatLists (map derivationsIn' x)
|
||||||
|
else if isAttrs x then concatLists (mapAttrsToList (n: v: derivationsIn' v) x)
|
||||||
|
else [ ];
|
||||||
|
|
||||||
|
keyDrv = drv: if canEval drv.drvPath then { key = drv.drvPath; value = drv; } else { };
|
||||||
|
|
||||||
|
immediateDependenciesOf = drv:
|
||||||
|
concatLists (mapAttrsToList (n: v: derivationsIn v) (removeAttrs drv ["meta" "passthru"]));
|
||||||
|
|
||||||
|
derivationsIn = x:
|
||||||
|
if !canEval x then []
|
||||||
|
else if isDerivation x then optional (canEval x.drvPath) x
|
||||||
|
else if isList x then concatLists (map derivationsIn x)
|
||||||
|
else [ ];
|
||||||
|
|
||||||
|
canEval = val: (builtins.tryEval val).success;
|
||||||
|
|
||||||
|
in uniqueUrls
|
@ -31,8 +31,7 @@ GetOptions("package|p=s" => \$filter,
|
|||||||
"maintainer|m=s" => \$maintainer,
|
"maintainer|m=s" => \$maintainer,
|
||||||
"file|f=s" => \$path,
|
"file|f=s" => \$path,
|
||||||
"help" => sub { showHelp() }
|
"help" => sub { showHelp() }
|
||||||
)
|
) or exit 1;
|
||||||
or die("syntax: $0 ...\n");
|
|
||||||
|
|
||||||
# Evaluate Nixpkgs into an XML representation.
|
# Evaluate Nixpkgs into an XML representation.
|
||||||
my $xml = `nix-env -f '$path' -qa '$filter' --xml --meta --drv-path`;
|
my $xml = `nix-env -f '$path' -qa '$filter' --xml --meta --drv-path`;
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
/* Tool to sort attribute sets. Primarily useful for keeping
|
|
||||||
all-packages.nix tidy.
|
|
||||||
|
|
||||||
To compile:
|
|
||||||
|
|
||||||
$ strc -i ../../maintainers/scripts/sort-attrs.str -la stratego-lib
|
|
||||||
|
|
||||||
Typical invocation:
|
|
||||||
|
|
||||||
$ sglr -m -p ~/Dev/nix/src/libexpr/nix.tbl -i all-packages.nix \
|
|
||||||
| implode-asfix --lex \
|
|
||||||
| ../../maintainers/scripts/sort-attrs \
|
|
||||||
| asfix-yield
|
|
||||||
*/
|
|
||||||
|
|
||||||
module sort-attrs
|
|
||||||
|
|
||||||
imports
|
|
||||||
libstratego-lib
|
|
||||||
libstratego-sglr
|
|
||||||
|
|
||||||
|
|
||||||
strategies
|
|
||||||
|
|
||||||
no-wsp = !appl(prod([], cf(opt(layout())), no-attrs()), [])
|
|
||||||
|
|
||||||
|
|
||||||
rules
|
|
||||||
|
|
||||||
list-sep(s): [] -> []
|
|
||||||
list-sep(s): [x | xs] -> [[x | before] | <list-sep(s)> [split | after]]
|
|
||||||
where
|
|
||||||
<split-fetch-keep(s)> xs => (before, split, after)
|
|
||||||
list-sep(s): [x | xs] -> [[x | xs]]
|
|
||||||
where
|
|
||||||
<not(split-fetch-keep(s))> xs
|
|
||||||
|
|
||||||
list-sep-end(s): xs -> [<conc> (before, [split]) | <list-sep-end(s)> after]
|
|
||||||
where
|
|
||||||
<split-fetch-keep(s)> xs => (before, split, after)
|
|
||||||
list-sep-end(s): xs -> [xs]
|
|
||||||
where
|
|
||||||
<not(split-fetch-keep(s))> xs
|
|
||||||
|
|
||||||
|
|
||||||
sort-attrs:
|
|
||||||
appl(p@prod(_, _, attrs([term(cons("Attrs"))])),
|
|
||||||
[ lit("{")
|
|
||||||
, ws1
|
|
||||||
, appl(p2@list(cf(iter-star(sort("Bind")))), attrs)
|
|
||||||
, ws2
|
|
||||||
, lit("}")
|
|
||||||
]
|
|
||||||
) ->
|
|
||||||
appl(p, [lit("{"), <no-wsp>, appl(p2, <concat> attrs'), ws2, lit("}")])
|
|
||||||
where
|
|
||||||
<debug> "found it";
|
|
||||||
<attach-wsp> [ws1 | attrs] => withWSP;
|
|
||||||
<list-sep(starts-section)> withWSP => groups;
|
|
||||||
<length; debug> groups;
|
|
||||||
<map({x', x'', x''', xs', starts, starts': \[x | xs] -> [x''' | xs']
|
|
||||||
where
|
|
||||||
<remove-section-start> x => (x', starts);
|
|
||||||
<map(regularise-empty-lines); if !starts; debug; sortable-section; debug then qsort(compare-attrs) else id end> [x' | xs] => [x'' | xs'];
|
|
||||||
<[] <+ \x -> ["\n\n\n" | x]\ > starts => starts';
|
|
||||||
<prepend-layout> (starts', x'') => x'''
|
|
||||||
\ })> groups => attrs';
|
|
||||||
<debug> "did it"
|
|
||||||
|
|
||||||
|
|
||||||
attach-wsp: [a, b | cs] -> [(a, b) | <attach-wsp> cs]
|
|
||||||
attach-wsp: [] -> []
|
|
||||||
|
|
||||||
|
|
||||||
strategies
|
|
||||||
|
|
||||||
starts-section =
|
|
||||||
?x@(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr);
|
|
||||||
<implode-string; is-substring(!"###")> cs;
|
|
||||||
!x
|
|
||||||
|
|
||||||
rules
|
|
||||||
|
|
||||||
|
|
||||||
sortable-section = ?[s]; !s; explode-string; not(fetch({x: ?x; !(x, 97); geq}))
|
|
||||||
|
|
||||||
|
|
||||||
remove-section-start:
|
|
||||||
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) ->
|
|
||||||
((appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs'), attr), starts)
|
|
||||||
where
|
|
||||||
!cs;
|
|
||||||
list-sep-end(?10); // separate into lines, keeping the \n
|
|
||||||
map(implode-string);
|
|
||||||
partition(where(is-substring(!"###"))) => (starts, rest);
|
|
||||||
<map(explode-string); concat> rest => cs'
|
|
||||||
|
|
||||||
|
|
||||||
regularise-empty-lines:
|
|
||||||
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) ->
|
|
||||||
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr)
|
|
||||||
where
|
|
||||||
// separate into lines, keeping the \n
|
|
||||||
// last whitespace is significant, keep
|
|
||||||
<list-sep-end(?10); split-init-last> cs => (init, last);
|
|
||||||
<regularise-empty-lines'> init => cs'; // remove whitespace-only lines
|
|
||||||
<concat> [<explode-string> "\n\n", <concat> cs', last] => cs'' // add one empty line
|
|
||||||
|
|
||||||
/* Dirty hack: *do* keep the first empty line following a non-empty line. !!! order matters */
|
|
||||||
regularise-empty-lines': [] -> []
|
|
||||||
|
|
||||||
regularise-empty-lines': [x, y | xs] -> [x, y | <regularise-empty-lines'> xs]
|
|
||||||
where
|
|
||||||
<fetch-elem(not(?10 <+ ?32))> x;
|
|
||||||
<not(fetch-elem(not(?10 <+ ?32)))> y
|
|
||||||
|
|
||||||
regularise-empty-lines': [x | xs] -> [x | <regularise-empty-lines'> xs]
|
|
||||||
where <fetch-elem(not(?10 <+ ?32))> x
|
|
||||||
|
|
||||||
regularise-empty-lines': [x | xs] -> <regularise-empty-lines'> xs
|
|
||||||
where <not(fetch-elem(not(?10 <+ ?32)))> x
|
|
||||||
|
|
||||||
|
|
||||||
prepend-layout:
|
|
||||||
(text, (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr)) ->
|
|
||||||
(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr)
|
|
||||||
where
|
|
||||||
<implode-string> cs => cs';
|
|
||||||
<conc-strings; explode-string> (<concat-strings> text, cs') => cs''
|
|
||||||
|
|
||||||
|
|
||||||
compare-attrs:
|
|
||||||
x@
|
|
||||||
( (_, appl(p1@prod(_, _, attrs([term(cons("Bind"))])), [id1 | xs1]))
|
|
||||||
, (_, appl(p2@prod(_, _, attrs([term(cons("Bind"))])), [id2 | xs2]))
|
|
||||||
)
|
|
||||||
-> x
|
|
||||||
where
|
|
||||||
<string-lt> (id1, id2)
|
|
||||||
|
|
||||||
|
|
||||||
strategies
|
|
||||||
|
|
||||||
main = io-wrap(
|
|
||||||
oncetd(sort-attrs)
|
|
||||||
)
|
|
@ -1 +0,0 @@
|
|||||||
improvements to vsftpd module
|
|
12
nixos/doc/manual/README
Normal file
12
nixos/doc/manual/README
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
To build the manual, you need Nix installed on your system (no need
|
||||||
|
for NixOS). To install Nix, follow the instructions at
|
||||||
|
|
||||||
|
https://nixos.org/nix/download.html
|
||||||
|
|
||||||
|
When you have Nix on your system, in the root directory of the project
|
||||||
|
(i.e., `nixpkgs`), run:
|
||||||
|
|
||||||
|
nix-build nixos/release.nix -A manual.x86_64-linux
|
||||||
|
|
||||||
|
When this command successfully finishes, it will tell you where the
|
||||||
|
manual got generated.
|
@ -237,7 +237,7 @@ postgresql.package = pkgs.postgresql90;
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Abstractions</title>
|
<section xml:id="sec-module-abstractions"><title>Abstractions</title>
|
||||||
|
|
||||||
<para>If you find yourself repeating yourself over and over, it’s time
|
<para>If you find yourself repeating yourself over and over, it’s time
|
||||||
to abstract. Take, for instance, this Apache HTTP Server configuration:
|
to abstract. Take, for instance, this Apache HTTP Server configuration:
|
||||||
@ -399,7 +399,7 @@ of an expression to be spliced into a string.</para>
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Modularity</title>
|
<section xml:id="sec-modularity"><title>Modularity</title>
|
||||||
|
|
||||||
<para>The NixOS configuration mechanism is modular. If your
|
<para>The NixOS configuration mechanism is modular. If your
|
||||||
<filename>configuration.nix</filename> becomes too big, you can split
|
<filename>configuration.nix</filename> becomes too big, you can split
|
||||||
@ -443,8 +443,20 @@ Note that both <filename>configuration.nix</filename> and
|
|||||||
define an option, NixOS will try to <emphasis>merge</emphasis> the
|
define an option, NixOS will try to <emphasis>merge</emphasis> the
|
||||||
definitions. In the case of
|
definitions. In the case of
|
||||||
<option>environment.systemPackages</option>, that’s easy: the lists of
|
<option>environment.systemPackages</option>, that’s easy: the lists of
|
||||||
packages can simply be concatenated. For other types of options, a
|
packages can simply be concatenated. The value in
|
||||||
merge may not be possible: for instance, if two modules define
|
<filename>configuration.nix</filename> is merged last, so for
|
||||||
|
list-type options, it will appear at the end of the merged list. If
|
||||||
|
you want it to appear first, you can use <varname>mkBefore</varname>:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
boot.kernelModules = mkBefore [ "kvm-intel" ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
This causes the <literal>kvm-intel</literal> kernel module to be
|
||||||
|
loaded before any other kernel modules.</para>
|
||||||
|
|
||||||
|
<para>For other types of options, a merge may not be possible. For
|
||||||
|
instance, if two modules define
|
||||||
<option>services.httpd.adminAddr</option>,
|
<option>services.httpd.adminAddr</option>,
|
||||||
<command>nixos-rebuild</command> will give an error:
|
<command>nixos-rebuild</command> will give an error:
|
||||||
|
|
||||||
@ -526,7 +538,7 @@ nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Syntax summary</title>
|
<section xml:id="sec-nix-syntax-summary"><title>Syntax summary</title>
|
||||||
|
|
||||||
<para>Below is a summary of the most important syntactic constructs in
|
<para>Below is a summary of the most important syntactic constructs in
|
||||||
the Nix expression language. It’s not complete. In particular, there
|
the Nix expression language. It’s not complete. In particular, there
|
||||||
@ -718,7 +730,7 @@ manual</link> for the rest.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Package management</title>
|
<section xml:id="sec-package-management"><title>Package management</title>
|
||||||
|
|
||||||
<para>This section describes how to add additional packages to your
|
<para>This section describes how to add additional packages to your
|
||||||
system. NixOS has two distinct styles of package management:
|
system. NixOS has two distinct styles of package management:
|
||||||
@ -861,7 +873,7 @@ Any package in Nixpkgs that depends on <literal>emacs</literal> will
|
|||||||
be passed your customised instance. (However, the value
|
be passed your customised instance. (However, the value
|
||||||
<literal>pkgs.emacs</literal> in
|
<literal>pkgs.emacs</literal> in
|
||||||
<varname>nixpkgs.config.packageOverrides</varname> refers to the
|
<varname>nixpkgs.config.packageOverrides</varname> refers to the
|
||||||
original rather than overriden instance, to prevent an infinite
|
original rather than overridden instance, to prevent an infinite
|
||||||
recursion.)</para>
|
recursion.)</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -923,7 +935,7 @@ environment.systemPackages = [ (import ./my-hello.nix) ];
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
where <filename>my-hello.nix</filename> contains:
|
where <filename>my-hello.nix</filename> contains:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
with <nixpkgs> {}; # bring all of Nixpkgs into scope
|
with import <nixpkgs> {}; # bring all of Nixpkgs into scope
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "hello-2.8";
|
name = "hello-2.8";
|
||||||
@ -1021,25 +1033,23 @@ states that a user account named <literal>alice</literal> shall exist:
|
|||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
users.extraUsers.alice =
|
users.extraUsers.alice =
|
||||||
{ createHome = true;
|
{ isNormalUser = true;
|
||||||
home = "/home/alice";
|
|
||||||
description = "Alice Foobar";
|
description = "Alice Foobar";
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" "networkmanager" ];
|
||||||
isSystemUser = false;
|
|
||||||
useDefaultShell = true;
|
|
||||||
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
Note that <literal>alice</literal> is a member of the
|
Note that <literal>alice</literal> is a member of the
|
||||||
<literal>wheel</literal> group, which allows her to use
|
<literal>wheel</literal> and <literal>networkmanager</literal> groups,
|
||||||
<command>sudo</command> to execute commands as
|
which allows her to use <command>sudo</command> to execute commands as
|
||||||
<literal>root</literal>. Also note the SSH public key that allows
|
<literal>root</literal> and to configure the network, respectively.
|
||||||
remote logins with the corresponding private key. Users created in
|
Also note the SSH public key that allows remote logins with the
|
||||||
this way do not have a password by default, so they cannot log in via
|
corresponding private key. Users created in this way do not have a
|
||||||
mechanisms that require a password. However, you can use the
|
password by default, so they cannot log in via mechanisms that require
|
||||||
<command>passwd</command> program to set a password, which is retained
|
a password. However, you can use the <command>passwd</command> program
|
||||||
across invocations of <command>nixos-rebuild</command>.</para>
|
to set a password, which is retained across invocations of
|
||||||
|
<command>nixos-rebuild</command>.</para>
|
||||||
|
|
||||||
<para>A user ID (uid) is assigned automatically. You can also specify
|
<para>A user ID (uid) is assigned automatically. You can also specify
|
||||||
a uid manually by adding
|
a uid manually by adding
|
||||||
@ -1060,11 +1070,6 @@ users.extraGroups.students.gid = 1000;
|
|||||||
As with users, the group ID (gid) is optional and will be assigned
|
As with users, the group ID (gid) is optional and will be assigned
|
||||||
automatically if it’s missing.</para>
|
automatically if it’s missing.</para>
|
||||||
|
|
||||||
<warning><para>Currently declarative user management is not perfect:
|
|
||||||
<command>nixos-rebuild</command> does not know how to realise certain
|
|
||||||
configuration changes. This includes removing a user or group, and
|
|
||||||
removing group membership from a user.</para></warning>
|
|
||||||
|
|
||||||
<para>In the imperative style, users and groups are managed by
|
<para>In the imperative style, users and groups are managed by
|
||||||
commands such as <command>useradd</command>,
|
commands such as <command>useradd</command>,
|
||||||
<command>groupmod</command> and so on. For instance, to create a user
|
<command>groupmod</command> and so on. For instance, to create a user
|
||||||
@ -1172,7 +1177,7 @@ fileSystems."/".device = "/dev/mapper/crypted";
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>X Window System</title>
|
<section xml:id="sec-x11"><title>X Window System</title>
|
||||||
|
|
||||||
<para>The X Window System (X11) provides the basis of NixOS’ graphical
|
<para>The X Window System (X11) provides the basis of NixOS’ graphical
|
||||||
user interface. It can be enabled as follows:
|
user interface. It can be enabled as follows:
|
||||||
@ -1235,7 +1240,7 @@ with other kernel modules.</para>
|
|||||||
<para>On 64-bit systems, if you want full acceleration for 32-bit
|
<para>On 64-bit systems, if you want full acceleration for 32-bit
|
||||||
programs such as Wine, you should also set the following:
|
programs such as Wine, you should also set the following:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
service.xserver.driSupport32Bit = true;
|
services.xserver.driSupport32Bit = true;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -1264,9 +1269,31 @@ services.xserver.synaptics.twoFingerScroll = true;
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Networking</title>
|
<section xml:id="sec-networking"><title>Networking</title>
|
||||||
|
|
||||||
<section><title>Secure shell access</title>
|
<section xml:id="sec-networkmanager"><title>NetworkManager</title>
|
||||||
|
|
||||||
|
<para>To facilitate network configuration, some desktop environments
|
||||||
|
use NetworkManager. You can enable NetworkManager by setting:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
services.networkmanager.enable = true;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Some desktop managers (e.g., GNOME) enable NetworkManager
|
||||||
|
automatically for you.</para>
|
||||||
|
|
||||||
|
<para>All users that should have permission to change network settings
|
||||||
|
must belong to the <code>networkmanager</code> group.</para>
|
||||||
|
|
||||||
|
<note><para><code>services.networkmanager</code> and
|
||||||
|
<code>services.wireless</code> can not be enabled at the same time:
|
||||||
|
you can still connect to the wireless networks using
|
||||||
|
NetworkManager.</para></note>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-ssh"><title>Secure shell access</title>
|
||||||
|
|
||||||
<para>Secure shell (SSH) access to your machine can be enabled by
|
<para>Secure shell (SSH) access to your machine can be enabled by
|
||||||
setting:
|
setting:
|
||||||
@ -1294,7 +1321,7 @@ users.extraUsers.alice.openssh.authorizedKeys.keys =
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>IPv4 configuration</title>
|
<section xml:id="sec-ipv4"><title>IPv4 configuration</title>
|
||||||
|
|
||||||
<para>By default, NixOS uses DHCP (specifically,
|
<para>By default, NixOS uses DHCP (specifically,
|
||||||
<command>dhcpcd</command>) to automatically configure network
|
<command>dhcpcd</command>) to automatically configure network
|
||||||
@ -1337,7 +1364,7 @@ provide the host name.</para>
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>IPv6 configuration</title>
|
<section xml:id="sec-ipv6"><title>IPv6 configuration</title>
|
||||||
|
|
||||||
<para>IPv6 is enabled by default. Stateless address autoconfiguration
|
<para>IPv6 is enabled by default. Stateless address autoconfiguration
|
||||||
is used to automatically assign IPv6 addresses to all interfaces. You
|
is used to automatically assign IPv6 addresses to all interfaces. You
|
||||||
@ -1352,17 +1379,19 @@ networking.enableIPv6 = false;
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Firewall</title>
|
<section xml:id="sec-firewall"><title>Firewall</title>
|
||||||
|
|
||||||
<para>NixOS has a simple stateful firewall that blocks incoming
|
<para>NixOS has a simple stateful firewall that blocks incoming
|
||||||
connections and other unexpected packets. The firewall applies to
|
connections and other unexpected packets. The firewall applies to
|
||||||
both IPv4 and IPv6 traffic. It can be enabled as follows:
|
both IPv4 and IPv6 traffic. It is enabled by default. It can be
|
||||||
|
disabled as follows:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
networking.firewall.enable = true;
|
networking.firewall.enable = false;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
You can open specific TCP ports to the outside world:
|
If the firewall is enabled, you can open specific TCP ports to the
|
||||||
|
outside world:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
@ -1384,7 +1413,12 @@ always allowed.)</para>
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section><title>Wireless networks</title>
|
<section xml:id="sec-wireless"><title>Wireless networks</title>
|
||||||
|
|
||||||
|
<para>For a desktop installation using NetworkManager (e.g., GNOME),
|
||||||
|
you just have to make sure the user is in the
|
||||||
|
<code>networkmanager</code> group and you can skip the rest of this
|
||||||
|
section on wireless networks.</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
NixOS will start wpa_supplicant for you if you enable this setting:
|
NixOS will start wpa_supplicant for you if you enable this setting:
|
||||||
@ -1445,7 +1479,7 @@ networking.localCommands =
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Linux kernel</title>
|
<section xml:id="sec-kernel-config"><title>Linux kernel</title>
|
||||||
|
|
||||||
<para>You can override the Linux kernel and associated packages using
|
<para>You can override the Linux kernel and associated packages using
|
||||||
the option <option>boot.kernelPackages</option>. For instance, this
|
the option <option>boot.kernelPackages</option>. For instance, this
|
||||||
@ -1458,10 +1492,11 @@ are specific to the kernel version, such as the NVIDIA video drivers.
|
|||||||
This ensures that driver packages are consistent with the
|
This ensures that driver packages are consistent with the
|
||||||
kernel.</para>
|
kernel.</para>
|
||||||
|
|
||||||
<para>The default Linux kernel configuration should be fine for most
|
<para>The default Linux kernel configuration should be fine for most users. You can see the configuration of your current kernel with the following command:
|
||||||
users. You can see the configuration of your current kernel in
|
<programlisting>
|
||||||
<filename>/run/booted-system/kernel-modules/config</filename>. If you
|
cat /proc/config.gz | gunzip
|
||||||
want to change the kernel configuration, you can use the
|
</programlisting>
|
||||||
|
If you want to change the kernel configuration, you can use the
|
||||||
<option>packageOverrides</option> feature (see <xref
|
<option>packageOverrides</option> feature (see <xref
|
||||||
linkend="sec-customising-packages" />). For instance, to enable
|
linkend="sec-customising-packages" />). For instance, to enable
|
||||||
support for the kernel debugger KGDB:
|
support for the kernel debugger KGDB:
|
||||||
|
242
nixos/doc/manual/containers.xml
Normal file
242
nixos/doc/manual/containers.xml
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="ch-containers">
|
||||||
|
|
||||||
|
<title>Containers</title>
|
||||||
|
|
||||||
|
<para>NixOS allows you to easily run other NixOS instances as
|
||||||
|
<emphasis>containers</emphasis>. Containers are a light-weight
|
||||||
|
approach to virtualisation that runs software in the container at the
|
||||||
|
same speed as in the host system. NixOS containers share the Nix store
|
||||||
|
of the host, making container creation very efficient.</para>
|
||||||
|
|
||||||
|
<warning><para>Currently, NixOS containers are not perfectly isolated
|
||||||
|
from the host system. This means that a user with root access to the
|
||||||
|
container can do things that affect the host. So you should not give
|
||||||
|
container root access to untrusted users.</para></warning>
|
||||||
|
|
||||||
|
<para>NixOS containers can be created in two ways: imperatively, using
|
||||||
|
the command <command>nixos-container</command>, and declaratively, by
|
||||||
|
specifying them in your <filename>configuration.nix</filename>. The
|
||||||
|
declarative approach implies that containers get upgraded along with
|
||||||
|
your host system when you run <command>nixos-rebuild</command>, which
|
||||||
|
is often not what you want. By contrast, in the imperative approach,
|
||||||
|
containers are configured and updated independently from the host
|
||||||
|
system.</para>
|
||||||
|
|
||||||
|
|
||||||
|
<section><title>Imperative container management</title>
|
||||||
|
|
||||||
|
<para>We’ll cover imperative container management using
|
||||||
|
<command>nixos-container</command> first. You create a container with
|
||||||
|
identifier <literal>foo</literal> as follows:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container create foo
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
This creates the container’s root directory in
|
||||||
|
<filename>/var/lib/containers/foo</filename> and a small configuration
|
||||||
|
file in <filename>/etc/containers/foo.conf</filename>. It also builds
|
||||||
|
the container’s initial system configuration and stores it in
|
||||||
|
<filename>/nix/var/nix/profiles/per-container/foo/system</filename>. You
|
||||||
|
can modify the initial configuration of the container on the command
|
||||||
|
line. For instance, to create a container that has
|
||||||
|
<command>sshd</command> running, with the given public key for
|
||||||
|
<literal>root</literal>:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container create foo --config 'services.openssh.enable = true; \
|
||||||
|
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Creating a container does not start it. To start the container,
|
||||||
|
run:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container start foo
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
This command will return as soon as the container has booted and has
|
||||||
|
reached <literal>multi-user.target</literal>. On the host, the
|
||||||
|
container runs within a systemd unit called
|
||||||
|
<literal>container@<replaceable>container-name</replaceable>.service</literal>.
|
||||||
|
Thus, if something went wrong, you can get status info using
|
||||||
|
<command>systemctl</command>:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ systemctl status container@foo
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>If the container has started succesfully, you can log in as
|
||||||
|
root using the <command>root-login</command> operation:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container root-login foo
|
||||||
|
[root@foo:~]#
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Note that only root on the host can do this (since there is no
|
||||||
|
authentication). You can also get a regular login prompt using the
|
||||||
|
<command>login</command> operation, which is available to all users on
|
||||||
|
the host:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container login foo
|
||||||
|
foo login: alice
|
||||||
|
Password: ***
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
With <command>nixos-container run</command>, you can execute arbitrary
|
||||||
|
commands in the container:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container run foo -- uname -a
|
||||||
|
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>There are several ways to change the configuration of the
|
||||||
|
container. First, on the host, you can edit
|
||||||
|
<literal>/var/lib/container/<replaceable>name</replaceable>/etc/nixos/configuration.nix</literal>,
|
||||||
|
and run
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container update foo
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
This will build and activate the new configuration. You can also
|
||||||
|
specify a new configuration on the command line:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container update foo --config 'services.httpd.enable = true; \
|
||||||
|
services.httpd.adminAddr = "foo@example.org";'
|
||||||
|
|
||||||
|
$ curl http://$(nixos-container show-ip foo)/
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
However, note that this will overwrite the container’s
|
||||||
|
<filename>/etc/nixos/configuration.nix</filename>.</para>
|
||||||
|
|
||||||
|
<para>Alternatively, you can change the configuration from within the
|
||||||
|
container itself by running <command>nixos-rebuild switch</command>
|
||||||
|
inside the container. Note that the container by default does not have
|
||||||
|
a copy of the NixOS channel, so you should run <command>nix-channel
|
||||||
|
--update</command> first.</para>
|
||||||
|
|
||||||
|
<para>Containers can be stopped and started using
|
||||||
|
<literal>nixos-container stop</literal> and <literal>nixos-container
|
||||||
|
start</literal>, respectively, or by using
|
||||||
|
<command>systemctl</command> on the container’s service unit. To
|
||||||
|
destroy a container, including its file system, do
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container destroy foo
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section><title>Declarative container specification</title>
|
||||||
|
|
||||||
|
<para>You can also specify containers and their configuration in the
|
||||||
|
host’s <filename>configuration.nix</filename>. For example, the
|
||||||
|
following specifies that there shall be a container named
|
||||||
|
<literal>database</literal> running PostgreSQL:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
containers.database =
|
||||||
|
{ config =
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
{ services.postgresql.enable = true;
|
||||||
|
services.postgresql.package = pkgs.postgresql92;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
If you run <literal>nixos-rebuild switch</literal>, the container will
|
||||||
|
be built and started. If the container was already running, it will be
|
||||||
|
updated in place, without rebooting.</para>
|
||||||
|
|
||||||
|
<para>By default, declarative containers share the network namespace
|
||||||
|
of the host, meaning that they can listen on (privileged)
|
||||||
|
ports. However, they cannot change the network configuration. You can
|
||||||
|
give a container its own network as follows:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
containers.database =
|
||||||
|
{ privateNetwork = true;
|
||||||
|
hostAddress = "192.168.100.10";
|
||||||
|
localAddress = "192.168.100.11";
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
This gives the container a private virtual Ethernet interface with IP
|
||||||
|
address <literal>192.168.100.11</literal>, which is hooked up to a
|
||||||
|
virtual Ethernet interface on the host with IP address
|
||||||
|
<literal>192.168.100.10</literal>. (See the next section for details
|
||||||
|
on container networking.)</para>
|
||||||
|
|
||||||
|
<para>To disable the container, just remove it from
|
||||||
|
<filename>configuration.nix</filename> and run <literal>nixos-rebuild
|
||||||
|
switch</literal>. Note that this will not delete the root directory of
|
||||||
|
the container in <literal>/var/lib/containers</literal>.</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section><title>Networking</title>
|
||||||
|
|
||||||
|
<para>When you create a container using <literal>nixos-container
|
||||||
|
create</literal>, it gets it own private IPv4 address in the range
|
||||||
|
<literal>10.233.0.0/16</literal>. You can get the container’s IPv4
|
||||||
|
address as follows:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-container show-ip foo
|
||||||
|
10.233.4.2
|
||||||
|
|
||||||
|
$ ping -c1 10.233.4.2
|
||||||
|
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Networking is implemented using a pair of virtual Ethernet
|
||||||
|
devices. The network interface in the container is called
|
||||||
|
<literal>eth0</literal>, while the matching interface in the host is
|
||||||
|
called <literal>ve-<replaceable>container-name</replaceable></literal>
|
||||||
|
(e.g., <literal>ve-foo</literal>). The container has its own network
|
||||||
|
namespace and the <literal>CAP_NET_ADMIN</literal> capability, so it
|
||||||
|
can perform arbitrary network configuration such as setting up
|
||||||
|
firewall rules, without affecting or having access to the host’s
|
||||||
|
network.</para>
|
||||||
|
|
||||||
|
<para>By default, containers cannot talk to the outside network. If
|
||||||
|
you want that, you should set up Network Address Translation (NAT)
|
||||||
|
rules on the host to rewrite container traffic to use your external
|
||||||
|
IP address. This can be accomplished using the following configuration
|
||||||
|
on the host:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
networking.nat.enable = true;
|
||||||
|
networking.nat.internalInterfaces = ["ve-+"];
|
||||||
|
networking.nat.externalInterface = "eth0";
|
||||||
|
</programlisting>
|
||||||
|
where <literal>eth0</literal> should be replaced with the desired
|
||||||
|
external interface. Note that <literal>ve-+</literal> is a wildcard
|
||||||
|
that matches all container interfaces.</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
</chapter>
|
||||||
|
|
@ -1,7 +1,6 @@
|
|||||||
{ pkgs, options
|
{ pkgs, options, version, revision }:
|
||||||
, revision ? "master"
|
|
||||||
}:
|
|
||||||
|
|
||||||
|
with pkgs;
|
||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
@ -14,17 +13,17 @@ let
|
|||||||
declarations = map (fn: stripPrefix fn) opt.declarations;
|
declarations = map (fn: stripPrefix fn) opt.declarations;
|
||||||
});
|
});
|
||||||
|
|
||||||
prefix = toString pkgs.path;
|
prefix = toString ../../..;
|
||||||
|
|
||||||
stripPrefix = fn:
|
stripPrefix = fn:
|
||||||
if substring 0 (stringLength prefix) fn == prefix then
|
if substring 0 (stringLength prefix) fn == prefix then
|
||||||
substring (add (stringLength prefix) 1) 1000 fn
|
substring (stringLength prefix + 1) 1000 fn
|
||||||
else
|
else
|
||||||
fn;
|
fn;
|
||||||
|
|
||||||
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML options''));
|
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML options''));
|
||||||
|
|
||||||
optionsDocBook = pkgs.runCommand "options-db.xml" {} ''
|
optionsDocBook = runCommand "options-db.xml" {} ''
|
||||||
if grep /nixpkgs/nixos/modules ${optionsXML}; then
|
if grep /nixpkgs/nixos/modules ${optionsXML}; then
|
||||||
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
|
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
|
||||||
echo "since this prevents sharing via the NixOS channel. This is typically"
|
echo "since this prevents sharing via the NixOS channel. This is typically"
|
||||||
@ -32,7 +31,7 @@ let
|
|||||||
echo "for hints about the offending path)."
|
echo "for hints about the offending path)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
${pkgs.libxslt}/bin/xsltproc \
|
${libxslt}/bin/xsltproc \
|
||||||
--stringparam revision '${revision}' \
|
--stringparam revision '${revision}' \
|
||||||
-o $out ${./options-to-docbook.xsl} ${optionsXML}
|
-o $out ${./options-to-docbook.xsl} ${optionsXML}
|
||||||
'';
|
'';
|
||||||
@ -40,12 +39,12 @@ let
|
|||||||
in rec {
|
in rec {
|
||||||
|
|
||||||
# Generate the NixOS manual.
|
# Generate the NixOS manual.
|
||||||
manual = pkgs.stdenv.mkDerivation {
|
manual = stdenv.mkDerivation {
|
||||||
name = "nixos-manual";
|
name = "nixos-manual";
|
||||||
|
|
||||||
sources = sourceFilesBySuffices ./. [".xml"];
|
sources = sourceFilesBySuffices ./. [".xml"];
|
||||||
|
|
||||||
buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
|
buildInputs = [ libxml2 libxslt ];
|
||||||
|
|
||||||
xsltFlags = ''
|
xsltFlags = ''
|
||||||
--param section.autolabel 1
|
--param section.autolabel 1
|
||||||
@ -60,22 +59,23 @@ in rec {
|
|||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
ln -s $sources/*.xml . # */
|
ln -s $sources/*.xml . # */
|
||||||
ln -s ${optionsDocBook} options-db.xml
|
ln -s ${optionsDocBook} options-db.xml
|
||||||
|
echo "${version}" > version
|
||||||
|
|
||||||
# Check the validity of the manual sources.
|
# Check the validity of the manual sources.
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
xmllint --noout --nonet --xinclude --noxincludenode \
|
||||||
--relaxng ${pkgs.docbook5}/xml/rng/docbook/docbook.rng \
|
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||||
manual.xml
|
manual.xml
|
||||||
|
|
||||||
# Generate the HTML manual.
|
# Generate the HTML manual.
|
||||||
dst=$out/share/doc/nixos
|
dst=$out/share/doc/nixos
|
||||||
ensureDir $dst
|
mkdir -p $dst
|
||||||
xsltproc $xsltFlags --nonet --xinclude \
|
xsltproc $xsltFlags --nonet --xinclude \
|
||||||
--output $dst/manual.html \
|
--output $dst/manual.html \
|
||||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
|
${docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
|
||||||
./manual.xml
|
./manual.xml
|
||||||
|
|
||||||
mkdir -p $dst/images/callouts
|
mkdir -p $dst/images/callouts
|
||||||
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
||||||
|
|
||||||
cp ${./style.css} $dst/style.css
|
cp ${./style.css} $dst/style.css
|
||||||
|
|
||||||
@ -87,13 +87,39 @@ in rec {
|
|||||||
meta.description = "The NixOS manual in HTML format";
|
meta.description = "The NixOS manual in HTML format";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
manualPDF = stdenv.mkDerivation {
|
||||||
|
name = "nixos-manual-pdf";
|
||||||
|
|
||||||
|
sources = sourceFilesBySuffices ./. [".xml"];
|
||||||
|
|
||||||
|
buildInputs = [ libxml2 libxslt dblatex tetex ];
|
||||||
|
|
||||||
|
buildCommand = ''
|
||||||
|
# TeX needs a writable font cache.
|
||||||
|
export VARTEXFONTS=$TMPDIR/texfonts
|
||||||
|
|
||||||
|
ln -s $sources/*.xml . # */
|
||||||
|
ln -s ${optionsDocBook} options-db.xml
|
||||||
|
echo "${version}" > version
|
||||||
|
|
||||||
|
dst=$out/share/doc/nixos
|
||||||
|
mkdir -p $dst
|
||||||
|
xmllint --xinclude manual.xml | dblatex -o $dst/manual.pdf - \
|
||||||
|
-P doc.collab.show=0 \
|
||||||
|
-P latex.output.revhistory=0
|
||||||
|
|
||||||
|
mkdir -p $out/nix-support
|
||||||
|
echo "doc-pdf manual $dst/manual.pdf" >> $out/nix-support/hydra-build-products
|
||||||
|
''; # */
|
||||||
|
};
|
||||||
|
|
||||||
# Generate the NixOS manpages.
|
# Generate the NixOS manpages.
|
||||||
manpages = pkgs.stdenv.mkDerivation {
|
manpages = stdenv.mkDerivation {
|
||||||
name = "nixos-manpages";
|
name = "nixos-manpages";
|
||||||
|
|
||||||
sources = sourceFilesBySuffices ./. [".xml"];
|
sources = sourceFilesBySuffices ./. [".xml"];
|
||||||
|
|
||||||
buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
|
buildInputs = [ libxml2 libxslt ];
|
||||||
|
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
ln -s $sources/*.xml . # */
|
ln -s $sources/*.xml . # */
|
||||||
@ -101,7 +127,7 @@ in rec {
|
|||||||
|
|
||||||
# Check the validity of the manual sources.
|
# Check the validity of the manual sources.
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
xmllint --noout --nonet --xinclude --noxincludenode \
|
||||||
--relaxng ${pkgs.docbook5}/xml/rng/docbook/docbook.rng \
|
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||||
./man-pages.xml
|
./man-pages.xml
|
||||||
|
|
||||||
# Generate manpages.
|
# Generate manpages.
|
||||||
@ -110,7 +136,7 @@ in rec {
|
|||||||
--param man.output.in.separate.dir 1 \
|
--param man.output.in.separate.dir 1 \
|
||||||
--param man.output.base.dir "'$out/share/man/'" \
|
--param man.output.base.dir "'$out/share/man/'" \
|
||||||
--param man.endnotes.are.numbered 0 \
|
--param man.endnotes.are.numbered 0 \
|
||||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||||
./man-pages.xml
|
./man-pages.xml
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="ch-development">
|
||||||
|
|
||||||
<title>Development</title>
|
<title>Development</title>
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ NixOS.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-getting-sources">
|
||||||
|
|
||||||
<title>Getting the sources</title>
|
<title>Getting the sources</title>
|
||||||
|
|
||||||
@ -38,7 +39,37 @@ This will check out the latest NixOS sources to
|
|||||||
and the Nixpkgs sources to
|
and the Nixpkgs sources to
|
||||||
<filename><replaceable>/my/sources</replaceable>/nixpkgs</filename>.
|
<filename><replaceable>/my/sources</replaceable>/nixpkgs</filename>.
|
||||||
(The NixOS source tree lives in a subdirectory of the Nixpkgs
|
(The NixOS source tree lives in a subdirectory of the Nixpkgs
|
||||||
repository.) If you want to rebuild your system using your (modified)
|
repository.)</para>
|
||||||
|
|
||||||
|
<para>It’s often inconvenient to develop directly on the master
|
||||||
|
branch, since if somebody has just committed (say) a change to GCC,
|
||||||
|
then the binary cache may not have caught up yet and you’ll have to
|
||||||
|
rebuild everything from source. So you may want to create a local
|
||||||
|
branch based on your current NixOS version:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nixos-version
|
||||||
|
14.04.273.ea1952b (Baboon)
|
||||||
|
|
||||||
|
$ git checkout -b local ea1952b
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Or, to base your local branch on the latest version available in the
|
||||||
|
NixOS channel:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ curl -sI http://nixos.org/channels/nixos-unstable/ | grep Location
|
||||||
|
Location: http://releases.nixos.org/nixos/unstable/nixos-14.10pre43986.acaf4a6/
|
||||||
|
|
||||||
|
$ git checkout -b local acaf4a6
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
You can then use <command>git rebase</command> to sync your local
|
||||||
|
branch with the upstream branch, and use <command>git
|
||||||
|
cherry-pick</command> to copy commits from your local branch to the
|
||||||
|
upstream branch.</para>
|
||||||
|
|
||||||
|
<para>If you want to rebuild your system using your (modified)
|
||||||
sources, you need to tell <command>nixos-rebuild</command> about them
|
sources, you need to tell <command>nixos-rebuild</command> about them
|
||||||
using the <option>-I</option> flag:
|
using the <option>-I</option> flag:
|
||||||
|
|
||||||
@ -74,7 +105,7 @@ in <filename>nixos/</filename> as packages.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-writing-modules">
|
||||||
|
|
||||||
<title>Writing NixOS modules</title>
|
<title>Writing NixOS modules</title>
|
||||||
|
|
||||||
@ -188,9 +219,9 @@ commands to be executed periodically by <command>cron</command>).</para>
|
|||||||
|
|
||||||
<example xml:id='locate-example'><title>NixOS module for the “locate” service</title>
|
<example xml:id='locate-example'><title>NixOS module for the “locate” service</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let locatedb = "/var/cache/locatedb"; in
|
let locatedb = "/var/cache/locatedb"; in
|
||||||
|
|
||||||
@ -494,7 +525,7 @@ module writers.</para>
|
|||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>etc.environment</option></term>
|
<term><option>environment.etc</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>This set defines files in <filename>/etc</filename>. A
|
<para>This set defines files in <filename>/etc</filename>. A
|
||||||
typical use is:
|
typical use is:
|
||||||
@ -579,7 +610,7 @@ systemd.services.dhcpcd =
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-building-parts">
|
||||||
|
|
||||||
<title>Building specific parts of NixOS</title>
|
<title>Building specific parts of NixOS</title>
|
||||||
|
|
||||||
@ -652,6 +683,37 @@ $ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>systemd.units.<replaceable>unit-name</replaceable>.unit</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>This builds the unit with the specified name. Note that
|
||||||
|
since unit names contain dots
|
||||||
|
(e.g. <literal>httpd.service</literal>), you need to put them
|
||||||
|
between quotes, like this:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-build -A 'config.systemd.units."httpd.service".unit'
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
You can also test individual units, without rebuilding the whole
|
||||||
|
system, by putting them in
|
||||||
|
<filename>/run/systemd/system</filename>:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
|
||||||
|
/run/systemd/system/tmp-httpd.service
|
||||||
|
$ systemctl daemon-reload
|
||||||
|
$ systemctl start tmp-httpd.service
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Note that the unit must not have the same name as any unit in
|
||||||
|
<filename>/etc/systemd/system</filename> since those take
|
||||||
|
precedence over <filename>/run/systemd/system</filename>.
|
||||||
|
That’s why the unit is installed as
|
||||||
|
<filename>tmp-httpd.service</filename> here.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
@ -661,7 +723,7 @@ $ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-building-cd">
|
||||||
|
|
||||||
<title>Building your own NixOS CD</title>
|
<title>Building your own NixOS CD</title>
|
||||||
|
|
||||||
@ -697,18 +759,22 @@ $ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
|
|||||||
|
|
||||||
<title>Testing the installer</title>
|
<title>Testing the installer</title>
|
||||||
|
|
||||||
<para>Building, burning, and
|
<para>Building, burning, and booting from an installation CD is rather
|
||||||
booting from an installation CD is rather
|
|
||||||
tedious, so here is a quick way to see if the installer works
|
tedious, so here is a quick way to see if the installer works
|
||||||
properly:
|
properly:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build -A config.system.build.nixos-install
|
$ nix-build -A config.system.build.nixos-install
|
||||||
$ dd if=/dev/zero of=diskimage seek=2G count=0 bs=1
|
$ mount -t tmpfs none /mnt
|
||||||
$ yes | mke2fs -j diskimage
|
|
||||||
$ mount -o loop diskimage /mnt
|
|
||||||
$ ./result/bin/nixos-install</screen>
|
$ ./result/bin/nixos-install</screen>
|
||||||
|
|
||||||
|
To start a login shell in the new NixOS installation in
|
||||||
|
<filename>/mnt</filename>:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ ./result/bin/nixos-install --chroot
|
||||||
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -717,57 +783,310 @@ $ ./result/bin/nixos-install</screen>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Whole-system testing using virtual machines</title>
|
<section xml:id="sec-nixos-tests">
|
||||||
|
|
||||||
<para>Complete NixOS GNU/Linux systems can be tested in virtual
|
<title>NixOS tests</title>
|
||||||
machines (VMs). This makes it possible to test a system upgrade or
|
|
||||||
configuration change before rebooting into it, using the
|
|
||||||
<command>nixos-rebuild build-vm</command> or <command>nixos-rebuild
|
|
||||||
build-vm-with-bootloader</command> command.</para>
|
|
||||||
|
|
||||||
<!-- The following is adapted from
|
<para>When you add some feature to NixOS, you should write a test for
|
||||||
http://wiki.nixos.org/wiki/NixOS_VM_tests, by Eelco Dolstra. -->
|
it. NixOS tests are kept in the directory <filename
|
||||||
<para>The <filename>tests/</filename> directory in the NixOS source
|
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/tests</filename>,
|
||||||
tree contains several <emphasis>whole-system unit tests</emphasis>.
|
and are executed (using Nix) by a testing framework that automatically
|
||||||
These tests can be run<footnote><para>NixOS tests can be run both from
|
starts one or more virtual machines containing the NixOS system(s)
|
||||||
NixOS and from a non-NixOS GNU/Linux distribution, provided the Nix
|
required for the test.</para>
|
||||||
package manager is installed.</para></footnote> from the NixOS source
|
|
||||||
tree as follows:
|
<simplesect><title>Writing tests</title>
|
||||||
|
|
||||||
|
<para>A NixOS test is a Nix expression that has the following structure:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
import ./make-test.nix {
|
||||||
|
|
||||||
|
# Either the configuration of a single machine:
|
||||||
|
machine =
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
{ <replaceable>configuration…</replaceable>
|
||||||
|
};
|
||||||
|
|
||||||
|
# Or a set of machines:
|
||||||
|
nodes =
|
||||||
|
{ <replaceable>machine1</replaceable> =
|
||||||
|
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
|
||||||
|
<replaceable>machine2</replaceable> =
|
||||||
|
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
|
||||||
|
…
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
''
|
||||||
|
<replaceable>Perl code…</replaceable>
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
The attribute <literal>testScript</literal> is a bit of Perl code that
|
||||||
|
executes the test (described below). During the test, it will start
|
||||||
|
one or more virtual machines, the configuration of which is described
|
||||||
|
by the attribute <literal>machine</literal> (if you need only one
|
||||||
|
machine in your test) or by the attribute <literal>nodes</literal> (if
|
||||||
|
you need multiple machines). For instance, <filename
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>
|
||||||
|
only needs a single machine to test whether users can log in on the
|
||||||
|
virtual console, whether device ownership is correctly maintained when
|
||||||
|
switching between consoles, and so on. On the other hand, <filename
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs.nix">nfs.nix</filename>,
|
||||||
|
which tests NFS client and server functionality in the Linux kernel
|
||||||
|
(including whether locks are maintained across server crashes),
|
||||||
|
requires three machines: a server and two clients.</para>
|
||||||
|
|
||||||
|
<para>There are a few special NixOS configuration options for test
|
||||||
|
VMs:
|
||||||
|
|
||||||
|
<!-- FIXME: would be nice to generate this automatically. -->
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>virtualisation.memorySize</option></term>
|
||||||
|
<listitem><para>The memory of the VM in
|
||||||
|
megabytes.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>virtualisation.vlans</option></term>
|
||||||
|
<listitem><para>The virtual networks to which the VM is
|
||||||
|
connected. See <filename
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nat.nix">nat.nix</filename>
|
||||||
|
for an example.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>virtualisation.writableStore</option></term>
|
||||||
|
<listitem><para>By default, the Nix store in the VM is not
|
||||||
|
writable. If you enable this option, a writable union file system
|
||||||
|
is mounted on top of the Nix store to make it appear
|
||||||
|
writable. This is necessary for tests that run Nix operations that
|
||||||
|
modify the store.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
For more options, see the module <filename
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/qemu-vm.nix">qemu-vm.nix</filename>.</para>
|
||||||
|
|
||||||
|
<para>The test script is a sequence of Perl statements that perform
|
||||||
|
various actions, such as starting VMs, executing commands in the VMs,
|
||||||
|
and so on. Each virtual machine is represented as an object stored in
|
||||||
|
the variable <literal>$<replaceable>name</replaceable></literal>,
|
||||||
|
where <replaceable>name</replaceable> is the identifier of the machine
|
||||||
|
(which is just <literal>machine</literal> if you didn’t specify
|
||||||
|
multiple machines using the <literal>nodes</literal> attribute). For
|
||||||
|
instance, the following starts the machine, waits until it has
|
||||||
|
finished booting, then executes a command and checks that the output
|
||||||
|
is more-or-less correct:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
$machine->start;
|
||||||
|
$machine->waitForUnit("default.target");
|
||||||
|
$machine->succeed("uname") =~ /Linux/;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
The first line is actually unnecessary; machines are implicitly
|
||||||
|
started when you first execute an action on them (such as
|
||||||
|
<literal>waitForUnit</literal> or <literal>succeed</literal>). If you
|
||||||
|
have multiple machines, you can speed up the test by starting them in
|
||||||
|
parallel:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
startAll;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The following methods are available on machine objects:
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>start</methodname></term>
|
||||||
|
<listitem><para>Start the virtual machine. This method is
|
||||||
|
asynchronous — it does not wait for the machine to finish
|
||||||
|
booting.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>shutdown</methodname></term>
|
||||||
|
<listitem><para>Shut down the machine, waiting for the VM to
|
||||||
|
exit.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>crash</methodname></term>
|
||||||
|
<listitem><para>Simulate a sudden power failure, by telling the VM
|
||||||
|
to exit immediately.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>block</methodname></term>
|
||||||
|
<listitem><para>Simulate unplugging the Ethernet cable that
|
||||||
|
connects the machine to the other machines.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>unblock</methodname></term>
|
||||||
|
<listitem><para>Undo the effect of
|
||||||
|
<methodname>block</methodname>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>screenshot</methodname></term>
|
||||||
|
<listitem><para>Take a picture of the display of the virtual
|
||||||
|
machine, in PNG format. The screenshot is linked from the HTML
|
||||||
|
log.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>sendMonitorCommand</methodname></term>
|
||||||
|
<listitem><para>Send a command to the QEMU monitor. This is rarely
|
||||||
|
used, but allows doing stuff such as attaching virtual USB disks
|
||||||
|
to a running machine.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>sendKeys</methodname></term>
|
||||||
|
<listitem><para>Simulate pressing keys on the virtual keyboard,
|
||||||
|
e.g., <literal>sendKeys("ctrl-alt-delete")</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>sendChars</methodname></term>
|
||||||
|
<listitem><para>Simulate typing a sequence of characters on the
|
||||||
|
virtual keyboard, e.g., <literal>sendKeys("foobar\n")</literal>
|
||||||
|
will type the string <literal>foobar</literal> followed by the
|
||||||
|
Enter key.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>execute</methodname></term>
|
||||||
|
<listitem><para>Execute a shell command, returning a list
|
||||||
|
<literal>(<replaceable>status</replaceable>,
|
||||||
|
<replaceable>stdout</replaceable>)</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>succeed</methodname></term>
|
||||||
|
<listitem><para>Execute a shell command, raising an exception if
|
||||||
|
the exit status is not zero, otherwise returning the standard
|
||||||
|
output.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>fail</methodname></term>
|
||||||
|
<listitem><para>Like <methodname>succeed</methodname>, but raising
|
||||||
|
an exception if the command returns a zero status.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitUntilSucceeds</methodname></term>
|
||||||
|
<listitem><para>Repeat a shell command with 1-second intervals
|
||||||
|
until it succeeds.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitUntilFails</methodname></term>
|
||||||
|
<listitem><para>Repeat a shell command with 1-second intervals
|
||||||
|
until it fails.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForUnit</methodname></term>
|
||||||
|
<listitem><para>Wait until the specified systemd unit has reached
|
||||||
|
the “active” state.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForFile</methodname></term>
|
||||||
|
<listitem><para>Wait until the specified file
|
||||||
|
exists.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForOpenPort</methodname></term>
|
||||||
|
<listitem><para>Wait until a process is listening on the given TCP
|
||||||
|
port (on <literal>localhost</literal>, at least).</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForClosedPort</methodname></term>
|
||||||
|
<listitem><para>Wait until nobody is listening on the given TCP
|
||||||
|
port.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForX</methodname></term>
|
||||||
|
<listitem><para>Wait until the X11 server is accepting
|
||||||
|
connections.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><methodname>waitForWindow</methodname></term>
|
||||||
|
<listitem><para>Wait until an X11 window has appeared whose name
|
||||||
|
matches the given regular expression, e.g.,
|
||||||
|
<literal>waitForWindow(qr/Terminal/)</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</simplesect>
|
||||||
|
|
||||||
|
|
||||||
|
<simplesect><title>Running tests</title>
|
||||||
|
|
||||||
|
<para>You can run tests using <command>nix-build</command>. For
|
||||||
|
example, to run the test <filename
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>,
|
||||||
|
you just do:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build tests/ -A nfs.test
|
$ nix-build '<nixpkgs/nixos/tests/login.nix>'
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
This performs an automated test of the NFS client and server
|
or, if you don’t want to rely on <envar>NIX_PATH</envar>:
|
||||||
functionality in the Linux kernel, including file locking semantics
|
|
||||||
(e.g., whether locks are maintained across server crashes). It will
|
<screen>
|
||||||
first build or download all the dependencies of the test (e.g., all
|
$ cd /my/nixpkgs/nixos/tests
|
||||||
packages needed to run a NixOS VM). The test is defined in <link
|
$ nix-build login.nix
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
…
|
||||||
<filename>tests/nfs.nix</filename></link>. If the test succeeds,
|
running the VM test script
|
||||||
<command>nix-build</command> will place a symlink
|
machine: QEMU running (pid 8841)
|
||||||
<filename>./result</filename> in the current directory pointing at the
|
…
|
||||||
location in the Nix store of the test results (e.g., screenshots, test
|
6 out of 6 tests succeeded
|
||||||
reports, and so on). In particular, a pretty-printed log of the test
|
</screen>
|
||||||
is written to <filename>log.html</filename>, which can be viewed using
|
|
||||||
a web browser like this:
|
After building/downloading all required dependencies, this will
|
||||||
|
perform a build that starts a QEMU/KVM virtual machine containing a
|
||||||
|
NixOS system. The virtual machine mounts the Nix store of the host;
|
||||||
|
this makes VM creation very fast, as no disk image needs to be
|
||||||
|
created. Afterwards, you can view a pretty-printed log of the test:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ firefox result/log.html
|
$ firefox result/log.html
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>It is also possible to run the test environment interactively,
|
<para>It is also possible to run the test environment interactively,
|
||||||
allowing you to experiment with the VMs. For example:
|
allowing you to experiment with the VMs. For example:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build tests/ -A nfs.driver
|
$ nix-build login.nix -A driver
|
||||||
$ ./result/bin/nixos-run-vms
|
$ ./result/bin/nixos-run-vms
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The script <command>nixos-run-vms</command> starts the three virtual
|
The script <command>nixos-run-vms</command> starts the virtual
|
||||||
machines defined in the NFS test using QEMU/KVM. The root file system
|
machines defined by test. The root file system of the VMs is created
|
||||||
of the VMs is created on the fly and kept across VM restarts in
|
on the fly and kept across VM restarts in
|
||||||
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
|
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
|
||||||
|
|
||||||
<para>Finally, the test itself can be run interactively. This is
|
<para>Finally, the test itself can be run interactively. This is
|
||||||
@ -780,17 +1099,11 @@ starting VDE switch for network 1
|
|||||||
>
|
>
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
Perl statements can now be typed in to start or manipulate the VMs:
|
You can then take any Perl statement, e.g.
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
> startAll;
|
> startAll
|
||||||
(the VMs start booting)
|
> $machine->succeed("touch /tmp/foo")
|
||||||
> $server->waitForJob("nfs-kernel-nfsd");
|
|
||||||
> $client1->succeed("flock -x /data/lock -c 'sleep 100000' &");
|
|
||||||
> $client2->fail("flock -n -s /data/lock true");
|
|
||||||
> $client1->shutdown;
|
|
||||||
(this releases client1's lock)
|
|
||||||
> $client2->succeed("flock -n -s /data/lock true");
|
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The function <command>testScript</command> executes the entire test
|
The function <command>testScript</command> executes the entire test
|
||||||
@ -798,54 +1111,7 @@ script and drops you back into the test driver command line upon its
|
|||||||
completion. This allows you to inspect the state of the VMs after the
|
completion. This allows you to inspect the state of the VMs after the
|
||||||
test (e.g. to debug the test script).</para>
|
test (e.g. to debug the test script).</para>
|
||||||
|
|
||||||
<para>This and other tests are continuously run on <link
|
</simplesect>
|
||||||
xlink:href="http://hydra.nixos.org/jobset/nixos/trunk">the Hydra
|
|
||||||
instance at <literal>nixos.org</literal></link>, which allows
|
|
||||||
developers to be notified of any regressions introduced by a NixOS or
|
|
||||||
Nixpkgs change.</para>
|
|
||||||
|
|
||||||
<para>The actual Nix programming interface to VM testing is in NixOS,
|
|
||||||
under <link
|
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/lib/testing.nix">
|
|
||||||
<filename>lib/testing.nix</filename></link>. This file defines a
|
|
||||||
function which takes an attribute set containing a
|
|
||||||
<literal>nixpkgs</literal> attribute (the path to a Nixpkgs checkout),
|
|
||||||
and a <literal>system</literal> attribute (the system type). It
|
|
||||||
returns an attribute set containing several utility functions, among
|
|
||||||
which the main entry point is <literal>makeTest</literal>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>The <literal>makeTest</literal> function takes a function
|
|
||||||
similar to that found in <link
|
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
|
||||||
<filename>tests/nfs.nix</filename></link> (discussed above). It
|
|
||||||
returns an attribute set containing (among others):
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>test</varname></term>
|
|
||||||
<listitem><para>A derivation containing the test log as an HTML
|
|
||||||
file, as seen above, suitable for presentation in the Hydra
|
|
||||||
continuous build system.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>report</varname></term>
|
|
||||||
<listitem><para>A derivation containing a code coverage report, with
|
|
||||||
meta-data suitable for Hydra.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>driver</varname></term>
|
|
||||||
<listitem><para>A derivation containing scripts to run the VM test or
|
|
||||||
interact with the VM network interactively, as seen above.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="ch-installation">
|
||||||
|
|
||||||
<title>Installing NixOS</title>
|
<title>Installing NixOS</title>
|
||||||
|
|
||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-obtaining">
|
||||||
|
|
||||||
<title>Obtaining NixOS</title>
|
<title>Obtaining NixOS</title>
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ running NixOS system through several other means:
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section xml:id="sec-installation">
|
||||||
|
|
||||||
<title>Installation</title>
|
<title>Installation</title>
|
||||||
|
|
||||||
@ -208,7 +209,20 @@ $ nixos-install</screen>
|
|||||||
a network issue while downloading binaries from the NixOS binary
|
a network issue while downloading binaries from the NixOS binary
|
||||||
cache), you can just re-run <command>nixos-install</command>.
|
cache), you can just re-run <command>nixos-install</command>.
|
||||||
Otherwise, fix your <filename>configuration.nix</filename> and
|
Otherwise, fix your <filename>configuration.nix</filename> and
|
||||||
then re-run <command>nixos-install</command>.</para></listitem>
|
then re-run <command>nixos-install</command>.</para>
|
||||||
|
|
||||||
|
<para>As the last step, <command>nixos-install</command> will ask
|
||||||
|
you to set the password for the <literal>root</literal> user, e.g.
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
setting root password...
|
||||||
|
Enter new UNIX password: ***
|
||||||
|
Retype new UNIX password: ***
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem><para>If everything went well:
|
<listitem><para>If everything went well:
|
||||||
|
|
||||||
@ -295,8 +309,81 @@ $ reboot</screen>
|
|||||||
}</screen>
|
}</screen>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
<section xml:id="sec-uefi-installation">
|
||||||
|
|
||||||
|
<title>UEFI Installation</title>
|
||||||
|
|
||||||
|
<para>NixOS can also be installed on UEFI systems. The procedure
|
||||||
|
is by and large the same as a BIOS installation, with the following
|
||||||
|
changes:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>You should boot the live CD in UEFI mode (consult your
|
||||||
|
specific hardware's documentation for instructions). You may find
|
||||||
|
the <link
|
||||||
|
xlink:href="http://www.rodsbooks.com/refind">rEFInd
|
||||||
|
boot manager</link> useful.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Instead of <command>fdisk</command>, you should use
|
||||||
|
<command>gdisk</command> to partition your disks. You will need to
|
||||||
|
have a separate partition for <filename>/boot</filename> with
|
||||||
|
partition code EF00, and it should be formatted as a
|
||||||
|
<literal>vfat</literal> filesystem.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>You must set <option>boot.loader.gummiboot.enable</option> to
|
||||||
|
<literal>true</literal>. <command>nixos-generate-config</command>
|
||||||
|
should do this automatically for new configurations when booted in
|
||||||
|
UEFI mode.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>After having mounted your installation partition to
|
||||||
|
<code>/mnt</code>, you must mount the <code>boot</code> partition
|
||||||
|
to <code>/mnt/boot</code>.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>You may want to look at the options starting with
|
||||||
|
<option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
|
||||||
|
as well.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>To see console messages during early boot, add <literal>"fbcon"</literal>
|
||||||
|
to your <option>boot.initrd.kernelModules</option>.</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<title xml:id="sec-booting-from-usb">Booting from a USB stick</title>
|
||||||
|
|
||||||
|
<para>For systems without CD drive, the NixOS livecd can be booted from
|
||||||
|
a usb stick. For non-UEFI installations,
|
||||||
|
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>
|
||||||
|
will work. For UEFI installations, you should mount the ISO, copy its contents
|
||||||
|
verbatim to your drive, then either:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Change the label of the disk partition to the label of the ISO
|
||||||
|
(visible with the blkid command), or</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
|
||||||
|
and change the <literal>root=</literal> field in the <literal>options</literal>
|
||||||
|
line to point to your drive (see the documentation on <literal>root=</literal>
|
||||||
|
in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
|
||||||
|
the kernel documentation</link> for more details).</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
@ -369,9 +456,23 @@ $ nixos-rebuild build-vm
|
|||||||
$ ./result/bin/run-*-vm
|
$ ./result/bin/run-*-vm
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The VM does not have use any data from your host system, so your
|
The VM does not have any data from your host system, so your existing
|
||||||
existing user accounts and home directories will not be
|
user accounts and home directories will not be available. You can
|
||||||
available.</para>
|
forward ports on the host to the guest. For instance, the following
|
||||||
|
will forward host port 2222 to guest port 22 (SSH):
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
allowing you to log in via SSH (assuming you have set the appropriate
|
||||||
|
passwords or SSH authorized keys):
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ ssh -p 2222 localhost
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -392,7 +493,7 @@ been built. These channels are:
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Stable channels, such as <literal
|
<para>Stable channels, such as <literal
|
||||||
xlink:href="http://nixos.org/channels/nixos-13.10">nixos-13.10</literal>.
|
xlink:href="http://nixos.org/channels/nixos-14.04">nixos-14.04</literal>.
|
||||||
These only get conservative bug fixes and package upgrades. For
|
These only get conservative bug fixes and package upgrades. For
|
||||||
instance, a channel update may cause the Linux kernel on your
|
instance, a channel update may cause the Linux kernel on your
|
||||||
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
|
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
|
||||||
@ -418,8 +519,8 @@ appliances.)</para>
|
|||||||
|
|
||||||
<para>When you first install NixOS, you’re automatically subscribed to
|
<para>When you first install NixOS, you’re automatically subscribed to
|
||||||
the NixOS channel that corresponds to your installation source. For
|
the NixOS channel that corresponds to your installation source. For
|
||||||
instance, if you installed from a 13.10 ISO, you will be subscribed to
|
instance, if you installed from a 14.04 ISO, you will be subscribed to
|
||||||
the <literal>nixos-13.10</literal> channel. To see which NixOS
|
the <literal>nixos-14.04</literal> channel. To see which NixOS
|
||||||
channel you’re subscribed to, run the following as root:
|
channel you’re subscribed to, run the following as root:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
@ -434,10 +535,10 @@ $ nix-channel --add http://nixos.org/channels/<replaceable>channel-name</replace
|
|||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
(Be sure to include the <literal>nixos</literal> parameter at the
|
(Be sure to include the <literal>nixos</literal> parameter at the
|
||||||
end.) For instance, to use the NixOS 13.10 stable channel:
|
end.) For instance, to use the NixOS 14.04 stable channel:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-channel --add http://nixos.org/channels/nixos-13.10 nixos
|
$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
But it you want to live on the bleeding edge:
|
But it you want to live on the bleeding edge:
|
||||||
|
@ -42,6 +42,9 @@ the following steps:
|
|||||||
and generates a GRUB configuration file that boots into the NixOS
|
and generates a GRUB configuration file that boots into the NixOS
|
||||||
configuration just installed.</para></listitem>
|
configuration just installed.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>It prompts you for a password for the root
|
||||||
|
account.</para></listitem>
|
||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
@ -5,25 +5,7 @@
|
|||||||
<info>
|
<info>
|
||||||
|
|
||||||
<title>NixOS Manual</title>
|
<title>NixOS Manual</title>
|
||||||
|
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
|
||||||
<author>
|
|
||||||
<personname>
|
|
||||||
<firstname>Eelco</firstname>
|
|
||||||
<surname>Dolstra</surname>
|
|
||||||
</personname>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
<author>
|
|
||||||
<personname>
|
|
||||||
<firstname>Nicolas</firstname>
|
|
||||||
<surname>Pierron</surname>
|
|
||||||
</personname>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2007-2013</year>
|
|
||||||
<holder>Eelco Dolstra</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
</info>
|
</info>
|
||||||
|
|
||||||
@ -53,10 +35,14 @@
|
|||||||
<xi:include href="running.xml" />
|
<xi:include href="running.xml" />
|
||||||
<!-- <xi:include href="userconfiguration.xml" /> -->
|
<!-- <xi:include href="userconfiguration.xml" /> -->
|
||||||
<xi:include href="troubleshooting.xml" />
|
<xi:include href="troubleshooting.xml" />
|
||||||
|
<xi:include href="containers.xml" />
|
||||||
<xi:include href="development.xml" />
|
<xi:include href="development.xml" />
|
||||||
<chapter xml:id="ch-options">
|
|
||||||
<title>List of options</title>
|
<xi:include href="release-notes.xml" />
|
||||||
|
|
||||||
|
<appendix xml:id="ch-options">
|
||||||
|
<title>Configuration options</title>
|
||||||
<xi:include href="options-db.xml" />
|
<xi:include href="options-db.xml" />
|
||||||
</chapter>
|
</appendix>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
@ -18,14 +18,12 @@
|
|||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<xsl:for-each select="attrs">
|
<xsl:for-each select="attrs">
|
||||||
|
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term xlink:href="#{$id}">
|
||||||
|
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
||||||
<option>
|
<option>
|
||||||
<xsl:for-each select="attr[@name = 'name']/string">
|
<xsl:value-of select="attr[@name = 'name']/string/@value" />
|
||||||
<xsl:value-of select="@value" />
|
|
||||||
<xsl:if test="position() != last()">.</xsl:if>
|
|
||||||
</xsl:for-each>
|
|
||||||
</option>
|
</option>
|
||||||
</term>
|
</term>
|
||||||
|
|
||||||
@ -204,4 +202,10 @@
|
|||||||
</simplelist>
|
</simplelist>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template match="function">
|
||||||
|
<xsl:text>λ</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
198
nixos/doc/manual/release-notes.xml
Normal file
198
nixos/doc/manual/release-notes.xml
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
<appendix xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="ch-release-notes">
|
||||||
|
|
||||||
|
<title>Release notes</title>
|
||||||
|
|
||||||
|
<!--==================================================================-->
|
||||||
|
|
||||||
|
<section xml:id="sec-release-14.10">
|
||||||
|
|
||||||
|
<title>Release 14.10 (“Caterpillar”, 2014/10/??)</title>
|
||||||
|
|
||||||
|
<para>When upgrading from a previous release, please be aware of the
|
||||||
|
following incompatible changes:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
|
||||||
|
<listitem><para>The host side of a container virtual Ethernet pair
|
||||||
|
is now called <literal>ve-<replaceable>container-name</replaceable></literal>
|
||||||
|
rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
|
||||||
|
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<!--==================================================================-->
|
||||||
|
|
||||||
|
<section xml:id="sec-release-14.04">
|
||||||
|
|
||||||
|
<title>Release 14.04 (“Baboon”, 2014/04/30)</title>
|
||||||
|
|
||||||
|
<para>This is the second stable release branch of NixOS. In addition
|
||||||
|
to numerous new and upgraded packages and modules, this release has
|
||||||
|
the following highlights:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
|
||||||
|
<listitem><para>Installation on UEFI systems is now supported. See
|
||||||
|
<xref linkend="sec-uefi-installation"/> for
|
||||||
|
details.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Systemd has been updated to version 212, which has
|
||||||
|
<link xlink:href="http://cgit.freedesktop.org/systemd/systemd/plain/NEWS?id=v212">numerous
|
||||||
|
improvements</link>. NixOS now automatically starts systemd user
|
||||||
|
instances when you log in. You can define global user units through
|
||||||
|
the <option>systemd.unit.*</option> options.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>NixOS is now based on Glibc 2.19 and GCC
|
||||||
|
4.8.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The default Linux kernel has been updated to
|
||||||
|
3.12.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>KDE has been updated to 4.12.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>GNOME 3.10 experimental support has been added.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Nix has been updated to 1.7 (<link
|
||||||
|
xlink:href="http://nixos.org/nix/manual/#ssec-relnotes-1.7">details</link>).</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>NixOS now supports fully declarative management of
|
||||||
|
users and groups. If you set <option>users.mutableUsers</option> to
|
||||||
|
<literal>false</literal>, then the contents of
|
||||||
|
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>
|
||||||
|
will be <link
|
||||||
|
xlink:href="https://www.usenix.org/legacy/event/lisa02/tech/full_papers/traugott/traugott_html/">congruent</link>
|
||||||
|
to your NixOS configuration. For instance, if you remove a user from
|
||||||
|
<option>users.extraUsers</option> and run
|
||||||
|
<command>nixos-rebuild</command>, the user account will cease to
|
||||||
|
exist. Also, imperative commands for managing users and groups, such
|
||||||
|
as <command>useradd</command>, are no longer available. If
|
||||||
|
<option>users.mutableUsers</option> is <literal>true</literal> (the
|
||||||
|
default), then behaviour is unchanged from NixOS
|
||||||
|
13.10.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>NixOS now has basic container support, meaning you
|
||||||
|
can easily run a NixOS instance as a container in a NixOS host
|
||||||
|
system. These containers are suitable for testing and
|
||||||
|
experimentation but not production use, since they’re not fully
|
||||||
|
isolated from the host. See <xref linkend="ch-containers"/> for
|
||||||
|
details.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Systemd units provided by packages can now be
|
||||||
|
overridden from the NixOS configuration. For instance, if a package
|
||||||
|
<literal>foo</literal> provides systemd units, you can say:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
systemd.packages = [ pkgs.foo ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
to enable those units. You can then set or override unit options in
|
||||||
|
the usual way, e.g.
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
systemd.services.foo.wantedBy = [ "multi-user.target" ];
|
||||||
|
systemd.services.foo.serviceConfig.MemoryLimit = "512M";
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>When upgrading from a previous release, please be aware of the
|
||||||
|
following incompatible changes:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
|
||||||
|
<listitem><para>Nixpkgs no longer exposes unfree packages by
|
||||||
|
default. If your NixOS configuration requires unfree packages from
|
||||||
|
Nixpkgs, you need to enable support for them explicitly by setting:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Otherwise, you get an error message such as:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
error: package ‘nvidia-x11-331.49-3.12.17’ in ‘…/nvidia-x11/default.nix:56’
|
||||||
|
has an unfree license, refusing to evaluate
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The Adobe Flash player is no longer enabled by
|
||||||
|
default in the Firefox and Chromium wrappers. To enable it, you must
|
||||||
|
set:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
nixpkgs.config.firefox.enableAdobeFlash = true; # for Firefox
|
||||||
|
nixpkgs.config.chromium.enableAdobeFlash = true; # for Chromium
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The firewall is now enabled by default. If you don’t
|
||||||
|
want this, you need to disable it explicitly:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The option
|
||||||
|
<option>boot.loader.grub.memtest86</option> has been renamed to
|
||||||
|
<option>boot.loader.grub.memtest86.enable</option>.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The <literal>mysql55</literal> service has been
|
||||||
|
merged into the <literal>mysql</literal> service, which no longer
|
||||||
|
sets a default for the option
|
||||||
|
<option>services.mysql.package</option>.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Package variants are now differentiated by suffixing
|
||||||
|
the name, rather than the version. For instance,
|
||||||
|
<filename>sqlite-3.8.4.3-interactive</filename> is now called
|
||||||
|
<filename>sqlite-interactive-3.8.4.3</filename>. This ensures that
|
||||||
|
<literal>nix-env -i sqlite</literal> is unambiguous, and that
|
||||||
|
<literal>nix-env -u</literal> won’t “upgrade”
|
||||||
|
<literal>sqlite</literal> to <literal>sqlite-interactive</literal>
|
||||||
|
or vice versa. Notably, this change affects the Firefox wrapper
|
||||||
|
(which provides plugins), as it is now called
|
||||||
|
<literal>firefox-wrapper</literal>. So when using
|
||||||
|
<command>nix-env</command>, you should do <literal>nix-env -e
|
||||||
|
firefox; nix-env -i firefox-wrapper</literal> if you want to keep
|
||||||
|
using the wrapper. This change does not affect declarative package
|
||||||
|
management, since attribute names like
|
||||||
|
<literal>pkgs.firefoxWrapper</literal> were already
|
||||||
|
unambiguous.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The symlink <filename>/etc/ca-bundle.crt</filename>
|
||||||
|
is gone. Programs should instead use the environment variable
|
||||||
|
<envar>OPENSSL_X509_CERT_FILE</envar> (which points to
|
||||||
|
<filename>/etc/ssl/certs/ca-bundle.crt</filename>).</para></listitem>
|
||||||
|
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!--==================================================================-->
|
||||||
|
|
||||||
|
<section xml:id="sec-release-13.10">
|
||||||
|
|
||||||
|
<title>Release 13.10 (“Aardvark”, 2013/10/31)</title>
|
||||||
|
|
||||||
|
<para>This is the first stable release branch of NixOS.</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</appendix>
|
@ -11,7 +11,7 @@ service manager.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Service management</title>
|
<section xml:id="sec-systemctl"><title>Service management</title>
|
||||||
|
|
||||||
<para>In NixOS, all system services are started and monitored using
|
<para>In NixOS, all system services are started and monitored using
|
||||||
the systemd program. Systemd is the “init” process of the system
|
the systemd program. Systemd is the “init” process of the system
|
||||||
@ -92,7 +92,7 @@ necessary).</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Rebooting and shutting down</title>
|
<section xml:id="sec-rebooting"><title>Rebooting and shutting down</title>
|
||||||
|
|
||||||
<para>The system can be shut down (and automatically powered off) by
|
<para>The system can be shut down (and automatically powered off) by
|
||||||
doing:
|
doing:
|
||||||
@ -134,7 +134,7 @@ authentication.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>User sessions</title>
|
<section xml:id="sec-user-sessions"><title>User sessions</title>
|
||||||
|
|
||||||
<para>Systemd keeps track of all users who are logged into the system
|
<para>Systemd keeps track of all users who are logged into the system
|
||||||
(e.g. on a virtual console or remotely via SSH). The command
|
(e.g. on a virtual console or remotely via SSH). The command
|
||||||
@ -185,7 +185,7 @@ $ loginctl terminate-session c3
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Control groups</title>
|
<section xml:id="sec-cgroups"><title>Control groups</title>
|
||||||
|
|
||||||
<para>To keep track of the processes in a running system, systemd uses
|
<para>To keep track of the processes in a running system, systemd uses
|
||||||
<emphasis>control groups</emphasis> (cgroups). A control group is a
|
<emphasis>control groups</emphasis> (cgroups). A control group is a
|
||||||
@ -258,7 +258,7 @@ usage.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Logging</title>
|
<section xml:id="sec-logging"><title>Logging</title>
|
||||||
|
|
||||||
<para>System-wide logging is provided by systemd’s
|
<para>System-wide logging is provided by systemd’s
|
||||||
<emphasis>journal</emphasis>, which subsumes traditional logging
|
<emphasis>journal</emphasis>, which subsumes traditional logging
|
||||||
@ -308,7 +308,7 @@ groups. All users have a private journal that can be read using
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Cleaning up the Nix store</title>
|
<section xml:id="sec-nix-gc"><title>Cleaning up the Nix store</title>
|
||||||
|
|
||||||
<para>Nix has a purely functional model, meaning that packages are
|
<para>Nix has a purely functional model, meaning that packages are
|
||||||
never upgraded in place. Instead new versions of packages end up in a
|
never upgraded in place. Instead new versions of packages end up in a
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xml:id="ch-troubleshooting">
|
||||||
|
|
||||||
<title>Troubleshooting</title>
|
<title>Troubleshooting</title>
|
||||||
|
|
||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Boot problems</title>
|
<section xml:id="sec-boot-problems"><title>Boot problems</title>
|
||||||
|
|
||||||
<para>If NixOS fails to boot, there are a number of kernel command
|
<para>If NixOS fails to boot, there are a number of kernel command
|
||||||
line parameters that may help you to identify or fix the issue. You
|
line parameters that may help you to identify or fix the issue. You
|
||||||
@ -69,7 +70,7 @@ unless something is very wrong.)</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Maintenance mode</title>
|
<section xml:id="sec-maintenance-mode"><title>Maintenance mode</title>
|
||||||
|
|
||||||
<para>You can enter rescue mode by running:
|
<para>You can enter rescue mode by running:
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ just exit from the rescue shell.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Rolling back configuration changes</title>
|
<section xml:id="sec-rollback"><title>Rolling back configuration changes</title>
|
||||||
|
|
||||||
<para>After running <command>nixos-rebuild</command> to switch to a
|
<para>After running <command>nixos-rebuild</command> to switch to a
|
||||||
new configuration, you may find that the new configuration doesn’t
|
new configuration, you may find that the new configuration doesn’t
|
||||||
@ -131,7 +132,7 @@ lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link ->
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Nix store corruption</title>
|
<section xml:id="sec-nix-store-corruption"><title>Nix store corruption</title>
|
||||||
|
|
||||||
<para>After a system crash, it’s possible for files in the Nix store
|
<para>After a system crash, it’s possible for files in the Nix store
|
||||||
to become corrupted. (For instance, the Ext4 file system has the
|
to become corrupted. (For instance, the Ext4 file system has the
|
||||||
@ -166,7 +167,7 @@ binary cache; otherwise, they cannot be repaired.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>Nix network issues</title>
|
<section xml:id="sec-nix-network-issues"><title>Nix network issues</title>
|
||||||
|
|
||||||
<para>Nix uses a so-called <emphasis>binary cache</emphasis> to
|
<para>Nix uses a so-called <emphasis>binary cache</emphasis> to
|
||||||
optimise building a package from source into downloading it as a
|
optimise building a package from source into downloading it as a
|
||||||
|
@ -68,8 +68,8 @@ rec {
|
|||||||
# the first interface (i.e. the first network in its
|
# the first interface (i.e. the first network in its
|
||||||
# virtualisation.vlans option).
|
# virtualisation.vlans option).
|
||||||
networking.extraHosts = flip concatMapStrings machines
|
networking.extraHosts = flip concatMapStrings machines
|
||||||
(m: let config = (getAttr m nodes).config; in
|
(m': let config = (getAttr m' nodes).config; in
|
||||||
optionalString (config.networking.primaryIPAddress != "")
|
optionalString (m.first != m' && config.networking.primaryIPAddress != "")
|
||||||
("${config.networking.primaryIPAddress} " +
|
("${config.networking.primaryIPAddress} " +
|
||||||
"${config.networking.hostName}\n"));
|
"${config.networking.hostName}\n"));
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
, extraArgs ? {}
|
, extraArgs ? {}
|
||||||
, modules
|
, modules
|
||||||
, check ? true
|
, check ? true
|
||||||
|
, prefix ? []
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
|
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
|
||||||
@ -17,6 +18,7 @@ rec {
|
|||||||
# Merge the option definitions in all modules, forming the full
|
# Merge the option definitions in all modules, forming the full
|
||||||
# system configuration.
|
# system configuration.
|
||||||
inherit (pkgs.lib.evalModules {
|
inherit (pkgs.lib.evalModules {
|
||||||
|
inherit prefix;
|
||||||
modules = modules ++ baseModules;
|
modules = modules ++ baseModules;
|
||||||
args = extraArgs;
|
args = extraArgs;
|
||||||
check = check && options.environment.checkConfigurationOptions.value;
|
check = check && options.environment.checkConfigurationOptions.value;
|
||||||
@ -24,10 +26,15 @@ rec {
|
|||||||
|
|
||||||
# These are the extra arguments passed to every module. In
|
# These are the extra arguments passed to every module. In
|
||||||
# particular, Nixpkgs is passed through the "pkgs" argument.
|
# particular, Nixpkgs is passed through the "pkgs" argument.
|
||||||
|
# FIXME: we enable config.allowUnfree to make packages like
|
||||||
|
# nvidia-x11 available. This isn't a problem because if the user has
|
||||||
|
# ‘nixpkgs.config.allowUnfree = false’, then evaluation will fail on
|
||||||
|
# the 64-bit package anyway. However, it would be cleaner to respect
|
||||||
|
# nixpkgs.config here.
|
||||||
extraArgs = extraArgs_ // {
|
extraArgs = extraArgs_ // {
|
||||||
inherit pkgs modules baseModules;
|
inherit pkgs modules baseModules;
|
||||||
modulesPath = ../modules;
|
modulesPath = ../modules;
|
||||||
pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; };
|
pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; config.allowUnfree = true; };
|
||||||
utils = import ./utils.nix pkgs;
|
utils = import ./utils.nix pkgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,10 +55,10 @@ rec {
|
|||||||
let
|
let
|
||||||
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
|
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
|
||||||
nixpkgsOptions = (import ./eval-config.nix {
|
nixpkgsOptions = (import ./eval-config.nix {
|
||||||
inherit system extraArgs modules;
|
inherit system extraArgs modules prefix;
|
||||||
# For efficiency, leave out most NixOS modules; they don't
|
# For efficiency, leave out most NixOS modules; they don't
|
||||||
# define nixpkgs.config, so it's pointless to evaluate them.
|
# define nixpkgs.config, so it's pointless to evaluate them.
|
||||||
baseModules = [ ../modules/misc/nixpkgs.nix ];
|
baseModules = [ ../modules/misc/nixpkgs.nix ../modules/config/no-x-libs.nix ];
|
||||||
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
|
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
|
||||||
check = false;
|
check = false;
|
||||||
}).config.nixpkgs;
|
}).config.nixpkgs;
|
||||||
|
@ -78,7 +78,7 @@ done
|
|||||||
cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
|
cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
|
||||||
|
|
||||||
|
|
||||||
ensureDir $out/iso
|
mkdir -p $out/iso
|
||||||
genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
|
genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
|
||||||
if test -z "$compressImage"; then
|
if test -z "$compressImage"; then
|
||||||
$genCommand -o $out/iso/$isoName
|
$genCommand -o $out/iso/$isoName
|
||||||
@ -87,5 +87,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
ensureDir $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
echo $system > $out/nix-support/system
|
echo $system > $out/nix-support/system
|
||||||
|
@ -48,11 +48,11 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
ensureDir $out/tarball
|
mkdir -p $out/tarball
|
||||||
|
|
||||||
tar cvJf $out/tarball/$fileName.tar.xz *
|
tar cvJf $out/tarball/$fileName.tar.xz *
|
||||||
|
|
||||||
ensureDir $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
echo $system > $out/nix-support/system
|
echo $system > $out/nix-support/system
|
||||||
echo "file system-tarball $out/tarball/$fileName.tar.xz" > $out/nix-support/hydra-build-products
|
echo "file system-tarball $out/tarball/$fileName.tar.xz" > $out/nix-support/hydra-build-products
|
||||||
|
|
||||||
|
@ -495,7 +495,9 @@ sub waitForX {
|
|||||||
my ($self, $regexp) = @_;
|
my ($self, $regexp) = @_;
|
||||||
$self->nest("waiting for the X11 server", sub {
|
$self->nest("waiting for the X11 server", sub {
|
||||||
retry sub {
|
retry sub {
|
||||||
my ($status, $out) = $self->execute("xwininfo -root > /dev/null 2>&1");
|
my ($status, $out) = $self->execute("journalctl -b SYSLOG_IDENTIFIER=systemd | grep 'session opened'");
|
||||||
|
return 0 if $status != 0;
|
||||||
|
($status, $out) = $self->execute("xwininfo -root > /dev/null 2>&1");
|
||||||
return 1 if $status == 0;
|
return 1 if $status == 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
<xsl:template match="logfile">
|
<xsl:template match="logfile">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
|
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||||
<script type="text/javascript" src="treebits.js" />
|
<script type="text/javascript" src="treebits.js" />
|
||||||
<link rel="stylesheet" href="logfile.css" type="text/css" />
|
<link rel="stylesheet" href="logfile.css" type="text/css" />
|
||||||
<title>Log File</title>
|
<title>Log File</title>
|
||||||
|
@ -52,12 +52,12 @@ sub createMachine {
|
|||||||
my ($args) = @_;
|
my ($args) = @_;
|
||||||
my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"});
|
my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"});
|
||||||
$vms{$vm->name} = $vm;
|
$vms{$vm->name} = $vm;
|
||||||
|
$context .= "my \$" . $vm->name . " = \$vms{'" . $vm->name . "'}; ";
|
||||||
return $vm;
|
return $vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $vmScript (@ARGV) {
|
foreach my $vmScript (@ARGV) {
|
||||||
my $vm = createMachine({startCommand => $vmScript});
|
my $vm = createMachine({startCommand => $vmScript});
|
||||||
$context .= "my \$" . $vm->name . " = \$vms{'" . $vm->name . "'}; ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -144,6 +144,13 @@ sub runTests {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$log->nest("syncing", sub {
|
||||||
|
foreach my $vm (values %vms) {
|
||||||
|
next unless $vm->isUp();
|
||||||
|
$vm->execute("sync");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if ($nrTests != 0) {
|
if ($nrTests != 0) {
|
||||||
$log->log("$nrSucceeded out of $nrTests tests succeeded",
|
$log->log("$nrSucceeded out of $nrTests tests succeeded",
|
||||||
($nrSucceeded < $nrTests ? { error => 1 } : { }));
|
($nrSucceeded < $nrTests ? { error => 1 } : { }));
|
||||||
|
@ -37,7 +37,7 @@ rec {
|
|||||||
# `driver' is the script that runs the network.
|
# `driver' is the script that runs the network.
|
||||||
runTests = driver:
|
runTests = driver:
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "vm-test-run";
|
name = "vm-test-run-${driver.testName}";
|
||||||
|
|
||||||
requiredSystemFeatures = [ "kvm" "nixos-test" ];
|
requiredSystemFeatures = [ "kvm" "nixos-test" ];
|
||||||
|
|
||||||
@ -67,68 +67,20 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Generate a coverage report from the coverage data produced by
|
makeTest =
|
||||||
# runTests.
|
{ testScript, makeCoverageReport ? false, name ? "unnamed", ... } @ t:
|
||||||
makeReport = x: runCommand "report" { buildInputs = [rsync]; }
|
|
||||||
''
|
|
||||||
mkdir -p $TMPDIR/gcov/
|
|
||||||
|
|
||||||
for d in ${x}/coverage-data/*; do
|
let
|
||||||
echo "doing $d"
|
testDriverName = "nixos-test-driver-${name}";
|
||||||
[ -n "$(ls -A "$d")" ] || continue
|
|
||||||
|
|
||||||
for i in $(cd $d/nix/store && ls); do
|
|
||||||
if ! test -e $TMPDIR/gcov/nix/store/$i; then
|
|
||||||
echo "copying $i"
|
|
||||||
mkdir -p $TMPDIR/gcov/$(echo $i | cut -c34-)
|
|
||||||
rsync -rv /nix/store/$i/.build/* $TMPDIR/gcov/
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
chmod -R u+w $TMPDIR/gcov
|
|
||||||
|
|
||||||
find $TMPDIR/gcov -name "*.gcda" -exec rm {} \;
|
|
||||||
|
|
||||||
for i in $(cd $d/nix/store && ls); do
|
|
||||||
rsync -rv $d/nix/store/$i/.build/* $TMPDIR/gcov/
|
|
||||||
done
|
|
||||||
|
|
||||||
find $TMPDIR/gcov -name "*.gcda" -exec chmod 644 {} \;
|
|
||||||
|
|
||||||
echo "producing info..."
|
|
||||||
${pkgs.lcov}/bin/geninfo --ignore-errors source,gcov $TMPDIR/gcov --output-file $TMPDIR/app.info
|
|
||||||
cat $TMPDIR/app.info >> $TMPDIR/full.info
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "making report..."
|
|
||||||
mkdir -p $out/coverage
|
|
||||||
${pkgs.lcov}/bin/genhtml --show-details $TMPDIR/full.info -o $out/coverage
|
|
||||||
cp $TMPDIR/full.info $out/coverage/
|
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
|
||||||
cat ${x}/nix-support/hydra-build-products >> $out/nix-support/hydra-build-products
|
|
||||||
echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products
|
|
||||||
[ ! -e ${x}/nix-support/failed ] || touch $out/nix-support/failed
|
|
||||||
''; # */
|
|
||||||
|
|
||||||
|
|
||||||
makeTest = testFun: complete (call testFun);
|
|
||||||
makeTests = testsFun: lib.mapAttrs (name: complete) (call testsFun);
|
|
||||||
|
|
||||||
apply = makeTest; # compatibility
|
|
||||||
call = f: f { inherit pkgs system; };
|
|
||||||
|
|
||||||
complete = t: t // rec {
|
|
||||||
nodes = buildVirtualNetwork (
|
nodes = buildVirtualNetwork (
|
||||||
if t ? nodes then t.nodes else
|
t.nodes or (if t ? machine then { machine = t.machine; } else { }));
|
||||||
if t ? machine then { machine = t.machine; }
|
|
||||||
else { } );
|
|
||||||
|
|
||||||
testScript =
|
testScript' =
|
||||||
# Call the test script with the computed nodes.
|
# Call the test script with the computed nodes.
|
||||||
if builtins.isFunction t.testScript
|
if builtins.isFunction testScript
|
||||||
then t.testScript { inherit nodes; }
|
then testScript { inherit nodes; }
|
||||||
else t.testScript;
|
else testScript;
|
||||||
|
|
||||||
vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
|
vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
|
||||||
|
|
||||||
@ -137,10 +89,11 @@ rec {
|
|||||||
# Generate onvenience wrappers for running the test driver
|
# Generate onvenience wrappers for running the test driver
|
||||||
# interactively with the specified network, and for starting the
|
# interactively with the specified network, and for starting the
|
||||||
# VMs from the command line.
|
# VMs from the command line.
|
||||||
driver = runCommand "nixos-test-driver"
|
driver = runCommand testDriverName
|
||||||
{ buildInputs = [ makeWrapper];
|
{ buildInputs = [ makeWrapper];
|
||||||
inherit testScript;
|
testScript = testScript';
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
|
testName = name;
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
@ -162,8 +115,9 @@ rec {
|
|||||||
|
|
||||||
test = runTests driver;
|
test = runTests driver;
|
||||||
|
|
||||||
report = makeReport test;
|
report = releaseTools.gcovReport { coverageRuns = [ test ]; };
|
||||||
};
|
|
||||||
|
in (if makeCoverageReport then report else test) // { inherit nodes driver test; };
|
||||||
|
|
||||||
|
|
||||||
runInMachine =
|
runInMachine =
|
||||||
@ -193,7 +147,7 @@ rec {
|
|||||||
exit $?
|
exit $?
|
||||||
'';
|
'';
|
||||||
|
|
||||||
testscript = ''
|
testScript = ''
|
||||||
startAll;
|
startAll;
|
||||||
$client->waitForUnit("multi-user.target");
|
$client->waitForUnit("multi-user.target");
|
||||||
${preBuild}
|
${preBuild}
|
||||||
@ -206,7 +160,7 @@ rec {
|
|||||||
${coreutils}/bin/mkdir $out
|
${coreutils}/bin/mkdir $out
|
||||||
${coreutils}/bin/mkdir -p vm-state-client/xchg
|
${coreutils}/bin/mkdir -p vm-state-client/xchg
|
||||||
export > vm-state-client/xchg/saved-env
|
export > vm-state-client/xchg/saved-env
|
||||||
export tests='${testscript}'
|
export tests='${testScript}'
|
||||||
${testDriver}/bin/nixos-test-driver ${vm.config.system.build.vm}/bin/run-*-vm
|
${testDriver}/bin/nixos-test-driver ${vm.config.system.build.vm}/bin/run-*-vm
|
||||||
''; # */
|
''; # */
|
||||||
|
|
||||||
@ -244,6 +198,6 @@ rec {
|
|||||||
} // args);
|
} // args);
|
||||||
|
|
||||||
|
|
||||||
simpleTest = as: (makeTest ({ ... }: as)).test;
|
simpleTest = as: (makeTest as).test;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
5
nixos/maintainers/scripts/ec2/amazon-base-config.nix
Normal file
5
nixos/maintainers/scripts/ec2/amazon-base-config.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{ modulesPath, ...}:
|
||||||
|
{
|
||||||
|
imports = [ "${modulesPath}/virtualisation/amazon-config.nix" ];
|
||||||
|
services.journald.rateLimitBurst = 0;
|
||||||
|
}
|
5
nixos/maintainers/scripts/ec2/amazon-hvm-config.nix
Normal file
5
nixos/maintainers/scripts/ec2/amazon-hvm-config.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{ config, pkgs, ...}:
|
||||||
|
{
|
||||||
|
imports = [ ./amazon-base-config.nix ];
|
||||||
|
ec2.hvm = true;
|
||||||
|
}
|
33
nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
Normal file
33
nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{ config, pkgs, lib, ...}:
|
||||||
|
let
|
||||||
|
cloudUtils = pkgs.fetchurl {
|
||||||
|
url = "https://launchpad.net/cloud-utils/trunk/0.27/+download/cloud-utils-0.27.tar.gz";
|
||||||
|
sha256 = "16shlmg36lidp614km41y6qk3xccil02f5n3r4wf6d1zr5n4v8vd";
|
||||||
|
};
|
||||||
|
growpart = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "growpart";
|
||||||
|
src = cloudUtils;
|
||||||
|
buildPhase = ''
|
||||||
|
cp bin/growpart $out
|
||||||
|
sed -i 's|awk|gawk|' $out
|
||||||
|
sed -i 's|sed|gnused|' $out
|
||||||
|
'';
|
||||||
|
dontInstall = true;
|
||||||
|
dontPatchShebangs = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./amazon-base-config.nix ];
|
||||||
|
ec2.hvm = true;
|
||||||
|
boot.loader.grub.device = lib.mkOverride 0 "nodev";
|
||||||
|
|
||||||
|
boot.initrd.extraUtilsCommands = ''
|
||||||
|
cp -v ${pkgs.gawk}/bin/gawk $out/bin/gawk
|
||||||
|
cp -v ${pkgs.gnused}/bin/sed $out/bin/gnused
|
||||||
|
cp -v ${pkgs.utillinux}/sbin/sfdisk $out/bin/sfdisk
|
||||||
|
cp -v ${growpart} $out/bin/growpart
|
||||||
|
'';
|
||||||
|
boot.initrd.postDeviceCommands = ''
|
||||||
|
[ -e /dev/xvda ] && [ -e /dev/xvda1 ] && TMPDIR=/run sh $(type -P growpart) /dev/xvda 1
|
||||||
|
'';
|
||||||
|
}
|
@ -8,15 +8,17 @@ import nixops.util
|
|||||||
from nixops import deployment
|
from nixops import deployment
|
||||||
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
|
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
|
||||||
import boto.ec2
|
import boto.ec2
|
||||||
|
from nixops.statefile import StateFile, get_default_state_file
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Create an EBS-backed NixOS AMI')
|
parser = argparse.ArgumentParser(description='Create an EBS-backed NixOS AMI')
|
||||||
parser.add_argument('--region', dest='region', required=True, help='EC2 region to create the image in')
|
parser.add_argument('--region', dest='region', required=True, help='EC2 region to create the image in')
|
||||||
|
parser.add_argument('--channel', dest='channel', default="13.10", help='Channel to use')
|
||||||
parser.add_argument('--keep', dest='keep', action='store_true', help='Keep NixOps machine after use')
|
parser.add_argument('--keep', dest='keep', action='store_true', help='Keep NixOps machine after use')
|
||||||
parser.add_argument('--hvm', dest='hvm', action='store_true', help='Create HVM image')
|
parser.add_argument('--hvm', dest='hvm', action='store_true', help='Create HVM image')
|
||||||
parser.add_argument('--key', dest='key_name', action='store_true', help='Keypair used for HVM instance creation', default="rob")
|
parser.add_argument('--key', dest='key_name', action='store_true', help='Keypair used for HVM instance creation', default="rob")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
instance_type = "cc1.4xlarge" if args.hvm else "m1.small"
|
instance_type = "m3.medium" if args.hvm else "m1.small"
|
||||||
ebs_size = 8 if args.hvm else 20
|
ebs_size = 8 if args.hvm else 20
|
||||||
|
|
||||||
|
|
||||||
@ -37,11 +39,11 @@ f.write('''{{
|
|||||||
'''.format(args.region, ebs_size))
|
'''.format(args.region, ebs_size))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
db = deployment.open_database(deployment.get_default_state_file())
|
db = StateFile(get_default_state_file())
|
||||||
try:
|
try:
|
||||||
depl = deployment.open_deployment(db, "ebs-creator")
|
depl = db.open_deployment("ebs-creator")
|
||||||
except Exception:
|
except Exception:
|
||||||
depl = deployment.create_deployment(db)
|
depl = db.create_deployment()
|
||||||
depl.name = "ebs-creator"
|
depl.name = "ebs-creator"
|
||||||
depl.auto_response = "y"
|
depl.auto_response = "y"
|
||||||
depl.nix_exprs = [os.path.abspath("./ebs-creator.nix"), os.path.abspath("./ebs-creator-config.nix")]
|
depl.nix_exprs = [os.path.abspath("./ebs-creator.nix"), os.path.abspath("./ebs-creator-config.nix")]
|
||||||
@ -50,7 +52,6 @@ depl.deploy(allow_reboot=True)
|
|||||||
|
|
||||||
m = depl.machines['machine']
|
m = depl.machines['machine']
|
||||||
|
|
||||||
|
|
||||||
# Do the installation.
|
# Do the installation.
|
||||||
device="/dev/xvdg"
|
device="/dev/xvdg"
|
||||||
if args.hvm:
|
if args.hvm:
|
||||||
@ -64,23 +65,27 @@ m.run_command("mkdir -p /mnt")
|
|||||||
m.run_command("mount {0} /mnt".format(device))
|
m.run_command("mount {0} /mnt".format(device))
|
||||||
m.run_command("touch /mnt/.ebs")
|
m.run_command("touch /mnt/.ebs")
|
||||||
m.run_command("mkdir -p /mnt/etc/nixos")
|
m.run_command("mkdir -p /mnt/etc/nixos")
|
||||||
m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable")
|
|
||||||
|
m.run_command("nix-channel --add http://nixos.org/channels/nixos-{} nixos".format(args.channel))
|
||||||
m.run_command("nix-channel --update")
|
m.run_command("nix-channel --update")
|
||||||
m.run_command("nixos-rebuild switch")
|
|
||||||
version = m.run_command("nixos-version", capture_stdout=True).replace('"', '').rstrip()
|
version = m.run_command("nix-instantiate --eval-only -A lib.nixpkgsVersion '<nixpkgs>'", capture_stdout=True).split(' ')[0].replace('"','').strip()
|
||||||
print >> sys.stderr, "NixOS version is {0}".format(version)
|
print >> sys.stderr, "NixOS version is {0}".format(version)
|
||||||
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix")
|
|
||||||
m.run_command("nixos-install")
|
|
||||||
if args.hvm:
|
if args.hvm:
|
||||||
m.run_command('cp /mnt/nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub')
|
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/amazon-base-config.nix")
|
||||||
m.run_command('sed -i "s|hd0|hd0,0|" /mnt/boot/grub/menu.lst')
|
m.upload_file("./amazon-hvm-config.nix", "/mnt/etc/nixos/configuration.nix")
|
||||||
|
m.upload_file("./amazon-hvm-install-config.nix", "/mnt/etc/nixos/amazon-hvm-install-config.nix")
|
||||||
|
m.run_command("NIXOS_CONFIG=/etc/nixos/amazon-hvm-install-config.nix nixos-install")
|
||||||
|
m.run_command('nix-env -iA nixos.pkgs.grub')
|
||||||
|
m.run_command('cp /nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub')
|
||||||
m.run_command('echo "(hd1) /dev/xvdg" > device.map')
|
m.run_command('echo "(hd1) /dev/xvdg" > device.map')
|
||||||
m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch')
|
m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch')
|
||||||
|
else:
|
||||||
|
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix")
|
||||||
|
m.run_command("nixos-install")
|
||||||
|
|
||||||
m.run_command("umount /mnt")
|
m.run_command("umount /mnt")
|
||||||
|
|
||||||
|
|
||||||
if args.hvm:
|
if args.hvm:
|
||||||
ami_name = "nixos-{0}-x86_64-ebs-hvm".format(version)
|
ami_name = "nixos-{0}-x86_64-ebs-hvm".format(version)
|
||||||
description = "NixOS {0} (x86_64; EBS root; hvm)".format(version)
|
description = "NixOS {0} (x86_64; EBS root; hvm)".format(version)
|
||||||
@ -98,7 +103,7 @@ def check():
|
|||||||
m.connect()
|
m.connect()
|
||||||
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
|
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
|
||||||
if args.hvm:
|
if args.hvm:
|
||||||
instance = m._conn.run_instances( image_id="ami-6a9e4503"
|
instance = m._conn.run_instances( image_id="ami-5f491f36"
|
||||||
, instance_type=instance_type
|
, instance_type=instance_type
|
||||||
, key_name=args.key_name
|
, key_name=args.key_name
|
||||||
, placement=m.zone
|
, placement=m.zone
|
||||||
@ -185,7 +190,7 @@ f.write(
|
|||||||
'''.format(args.region, ami_id, instance_type))
|
'''.format(args.region, ami_id, instance_type))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
test_depl = deployment.create_deployment(db)
|
test_depl = db.create_deployment()
|
||||||
test_depl.auto_response = "y"
|
test_depl.auto_response = "y"
|
||||||
test_depl.name = "ebs-creator-test"
|
test_depl.name = "ebs-creator-test"
|
||||||
test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]
|
test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]
|
||||||
@ -202,7 +207,7 @@ f = open("{0}.{1}.ami-id".format(args.region, image_type), "w")
|
|||||||
f.write("{0}".format(ami_id))
|
f.write("{0}".format(ami_id))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
for dest in [ 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1']:
|
for dest in [ 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1']:
|
||||||
if args.region != dest:
|
if args.region != dest:
|
||||||
print >> sys.stderr, "copying image from region {0} to {1}".format(args.region, dest)
|
print >> sys.stderr, "copying image from region {0} to {1}".format(args.region, dest)
|
||||||
conn = boto.ec2.connect_to_region(dest)
|
conn = boto.ec2.connect_to_region(dest)
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#! /bin/sh -e
|
#! /bin/sh -e
|
||||||
|
|
||||||
nixos=$(nix-instantiate --find-file nixos)
|
|
||||||
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/amazon-base-config.nix
|
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/amazon-base-config.nix
|
||||||
|
|
||||||
version=$(nix-instantiate --eval-only '<nixos>' -A config.system.nixosVersion | sed s/'"'//g)
|
version=$(nix-instantiate --eval-only '<nixpkgs/nixos>' -A config.system.nixosVersion | sed s/'"'//g)
|
||||||
echo "NixOS version is $version"
|
echo "NixOS version is $version"
|
||||||
|
|
||||||
buildAndUploadFor() {
|
buildAndUploadFor() {
|
||||||
@ -11,13 +10,13 @@ buildAndUploadFor() {
|
|||||||
arch="$2"
|
arch="$2"
|
||||||
|
|
||||||
echo "building $system image..."
|
echo "building $system image..."
|
||||||
nix-build '<nixos>' \
|
nix-build '<nixpkgs/nixos>' \
|
||||||
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
|
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
|
||||||
|
|
||||||
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
|
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
|
||||||
-c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
|
-c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
|
||||||
|
|
||||||
for region in eu-west-1 us-east-1 us-west-1 us-west-2; do
|
for region in eu-west-1; do
|
||||||
echo "uploading $system image for $region..."
|
echo "uploading $system image for $region..."
|
||||||
|
|
||||||
name=nixos-$version-$arch-s3
|
name=nixos-$version-$arch-s3
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
machine =
|
machine =
|
||||||
{ config, pkgs, resources, ... }:
|
{ config, pkgs, resources, ... }:
|
||||||
{ deployment.targetEnv = "ec2";
|
{ deployment.targetEnv = "ec2";
|
||||||
deployment.ec2.instanceType = "m1.large";
|
deployment.ec2.instanceType = "c3.large";
|
||||||
deployment.ec2.securityGroups = [ "admin" ];
|
deployment.ec2.securityGroups = [ "admin" ];
|
||||||
deployment.ec2.ebsBoot = false;
|
deployment.ec2.ebsBoot = false;
|
||||||
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
|
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
|
||||||
|
deployment.ec2.zone = "us-east-1e";
|
||||||
environment.systemPackages = [ pkgs.parted ];
|
environment.systemPackages = [ pkgs.parted ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
14
nixos/maintainers/scripts/gce/create-gce.sh
Executable file
14
nixos/maintainers/scripts/gce/create-gce.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#! /bin/sh -e
|
||||||
|
|
||||||
|
export NIX_PATH=nixpkgs=../../../..
|
||||||
|
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/google-compute-image.nix
|
||||||
|
export TIMESTAMP=$(date +%Y%m%d%H%M)
|
||||||
|
|
||||||
|
nix-build '<nixpkgs/nixos>' \
|
||||||
|
-A config.system.build.googleComputeImage --argstr system x86_64-linux -o gce --option extra-binary-caches http://hydra.nixos.org -j 10
|
||||||
|
|
||||||
|
img=$(echo gce/*.tar.gz)
|
||||||
|
if ! gsutil ls gs://nixos/$(basename $img); then
|
||||||
|
gsutil cp $img gs://nixos/$(basename $img)
|
||||||
|
fi
|
||||||
|
gcutil addimage $(basename $img .raw.tar.gz | sed 's|\.|-|' | sed 's|_|-|') gs://nixos/$(basename $img)
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ with pkgs.lib;
|
|||||||
|
|
||||||
config = mkIf config.fonts.enableCoreFonts {
|
config = mkIf config.fonts.enableCoreFonts {
|
||||||
|
|
||||||
fonts.extraFonts = [ pkgs.corefonts ];
|
fonts.fonts = [ pkgs.corefonts ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -10,20 +10,27 @@ with pkgs.lib;
|
|||||||
|
|
||||||
# TODO: find another name for it.
|
# TODO: find another name for it.
|
||||||
fonts = mkOption {
|
fonts = mkOption {
|
||||||
default = [
|
type = types.listOf types.path;
|
||||||
# - the user's .fonts directory
|
example = [ pkgs.dejavu_fonts ];
|
||||||
"~/.fonts"
|
description = "List of primary font paths.";
|
||||||
# - the user's current profile
|
apply = list: list ++
|
||||||
|
[ # - the user's current profile
|
||||||
"~/.nix-profile/lib/X11/fonts"
|
"~/.nix-profile/lib/X11/fonts"
|
||||||
"~/.nix-profile/share/fonts"
|
"~/.nix-profile/share/fonts"
|
||||||
# - the default profile
|
# - the default profile
|
||||||
"/nix/var/nix/profiles/default/lib/X11/fonts"
|
"/nix/var/nix/profiles/default/lib/X11/fonts"
|
||||||
"/nix/var/nix/profiles/default/share/fonts"
|
"/nix/var/nix/profiles/default/share/fonts"
|
||||||
];
|
];
|
||||||
description = "List of primary font paths.";
|
};
|
||||||
apply = list: list ++ [
|
|
||||||
# - a few statically built locations
|
};
|
||||||
pkgs.xorg.fontbhttf
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
fonts.fonts =
|
||||||
|
[ pkgs.xorg.fontbhttf
|
||||||
pkgs.xorg.fontbhlucidatypewriter100dpi
|
pkgs.xorg.fontbhlucidatypewriter100dpi
|
||||||
pkgs.xorg.fontbhlucidatypewriter75dpi
|
pkgs.xorg.fontbhlucidatypewriter75dpi
|
||||||
pkgs.ttf_bitstream_vera
|
pkgs.ttf_bitstream_vera
|
||||||
@ -32,17 +39,7 @@ with pkgs.lib;
|
|||||||
pkgs.xorg.fontbh100dpi
|
pkgs.xorg.fontbh100dpi
|
||||||
pkgs.xorg.fontmiscmisc
|
pkgs.xorg.fontmiscmisc
|
||||||
pkgs.xorg.fontcursormisc
|
pkgs.xorg.fontcursormisc
|
||||||
]
|
];
|
||||||
++ config.fonts.extraFonts;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFonts = mkOption {
|
|
||||||
default = [];
|
|
||||||
example = [ pkgs.dejavu_fonts ];
|
|
||||||
description = "List of packages with additional fonts.";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ with pkgs.lib;
|
|||||||
|
|
||||||
config = mkIf config.fonts.enableGhostscriptFonts {
|
config = mkIf config.fonts.enableGhostscriptFonts {
|
||||||
|
|
||||||
fonts.extraFonts = [ "${pkgs.ghostscript}/share/ghostscript/fonts" ];
|
fonts.fonts = [ "${pkgs.ghostscript}/share/ghostscript/fonts" ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
@ -36,7 +36,7 @@ with pkgs.lib;
|
|||||||
# GNU lsh.
|
# GNU lsh.
|
||||||
services.openssh.enable = false;
|
services.openssh.enable = false;
|
||||||
services.lshd.enable = true;
|
services.lshd.enable = true;
|
||||||
services.xserver.startOpenSSHAgent = false;
|
programs.ssh.startAgent = false;
|
||||||
services.xserver.startGnuPGAgent = true;
|
services.xserver.startGnuPGAgent = true;
|
||||||
|
|
||||||
# TODO: GNU dico.
|
# TODO: GNU dico.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -53,7 +53,11 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
consoleKeyMap = mkOption {
|
consoleKeyMap = mkOption {
|
||||||
type = types.str;
|
type = mkOptionType {
|
||||||
|
name = "string or path";
|
||||||
|
check = t: (isString t || types.path.check t);
|
||||||
|
};
|
||||||
|
|
||||||
default = "us";
|
default = "us";
|
||||||
example = "fr";
|
example = "fr";
|
||||||
description = ''
|
description = ''
|
||||||
@ -72,7 +76,12 @@ in
|
|||||||
|
|
||||||
environment.systemPackages = [ glibcLocales ];
|
environment.systemPackages = [ glibcLocales ];
|
||||||
|
|
||||||
environment.variables.LANG = config.i18n.defaultLocale;
|
environment.sessionVariables =
|
||||||
|
{ LANG = config.i18n.defaultLocale;
|
||||||
|
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.globalEnvironment.LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive";
|
||||||
|
|
||||||
# ‘/etc/locale.conf’ is used by systemd.
|
# ‘/etc/locale.conf’ is used by systemd.
|
||||||
environment.etc = singleton
|
environment.etc = singleton
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ in
|
|||||||
|
|
||||||
kdc = mkOption {
|
kdc = mkOption {
|
||||||
default = "kerberos.mit.edu";
|
default = "kerberos.mit.edu";
|
||||||
description = "Kerberos Domain Controller";
|
description = "Kerberos Domain Controller.";
|
||||||
};
|
};
|
||||||
|
|
||||||
kerberosAdminServer = mkOption {
|
kerberosAdminServer = mkOption {
|
||||||
default = "kerberos.mit.edu";
|
default = "kerberos.mit.edu";
|
||||||
description = "Kerberos Admin Server";
|
description = "Kerberos Admin Server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
|
||||||
with pkgs;
|
with pkgs;
|
||||||
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -217,9 +217,7 @@ in
|
|||||||
systemd.services = mkIf cfg.daemon.enable {
|
systemd.services = mkIf cfg.daemon.enable {
|
||||||
|
|
||||||
nslcd = {
|
nslcd = {
|
||||||
wantedBy = [ "nss-user-lookup.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "nss-user-lookup.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
|
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -p /run/nslcd
|
mkdir -p /run/nslcd
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# /etc files related to networking, such as /etc/services.
|
# /etc files related to networking, such as /etc/services.
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ in
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.extraHosts = pkgs.lib.mkOption {
|
networking.extraHosts = lib.mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
example = "192.168.0.1 lanlocalhost";
|
example = "192.168.0.1 lanlocalhost";
|
||||||
@ -23,7 +23,7 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.dnsSingleRequest = pkgs.lib.mkOption {
|
networking.dnsSingleRequest = lib.mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{ config, pkgs, ... }:
|
# This module gets rid of all dependencies on X11 client libraries
|
||||||
|
# (including fontconfig).
|
||||||
|
|
||||||
with pkgs.lib;
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
@ -8,18 +11,22 @@ with pkgs.lib;
|
|||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Switch off the options in the default configuration that require X libraries.
|
Switch off the options in the default configuration that
|
||||||
Currently this includes: ssh X11 forwarding, dbus, fonts.enableCoreFonts,
|
require X11 libraries. This includes client-side font
|
||||||
fonts.enableFontConfig
|
configuration and SSH forwarding of X11 authentication
|
||||||
|
in. Thus, you probably do not want to enable this option if
|
||||||
|
you want to run X11 programs on this machine via SSH.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.environment.noXlibs {
|
config = mkIf config.environment.noXlibs {
|
||||||
programs.ssh.setXAuthLocation = false;
|
programs.ssh.setXAuthLocation = false;
|
||||||
fonts = {
|
security.pam.services.su.forwardXAuth = lib.mkForce false;
|
||||||
enableCoreFonts = false;
|
|
||||||
enableFontConfig = false;
|
fonts.enableFontConfig = false;
|
||||||
};
|
|
||||||
|
nixpkgs.config.packageOverrides = pkgs:
|
||||||
|
{ dbus = pkgs.dbus.override { useX11 = false; }; };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# Configuration for the Name Service Switch (/etc/nsswitch.conf).
|
# Configuration for the Name Service Switch (/etc/nsswitch.conf).
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -65,14 +65,7 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
# Enable the ACPI daemon. Not sure whether this is essential.
|
# FIXME: Implement powersave governor for sandy bridge or later Intel CPUs
|
||||||
services.acpid.enable = true;
|
|
||||||
|
|
||||||
boot.kernelModules =
|
|
||||||
[ "acpi_cpufreq" "powernow-k8" "cpufreq_performance" "cpufreq_powersave" "cpufreq_ondemand"
|
|
||||||
"cpufreq_conservative"
|
|
||||||
];
|
|
||||||
|
|
||||||
powerManagement.cpuFreqGovernor = mkDefault "ondemand";
|
powerManagement.cpuFreqGovernor = mkDefault "ondemand";
|
||||||
powerManagement.scsiLinkPolicy = mkDefault "min_power";
|
powerManagement.scsiLinkPolicy = mkDefault "min_power";
|
||||||
|
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
|
||||||
with pkgs;
|
with pkgs;
|
||||||
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.hardware.pulseaudio;
|
cfg = config.hardware.pulseaudio;
|
||||||
|
|
||||||
|
systemWide = cfg.enable && cfg.systemWide;
|
||||||
|
nonSystemWide = cfg.enable && !cfg.systemWide;
|
||||||
|
|
||||||
uid = config.ids.uids.pulseaudio;
|
uid = config.ids.uids.pulseaudio;
|
||||||
gid = config.ids.gids.pulseaudio;
|
gid = config.ids.gids.pulseaudio;
|
||||||
|
|
||||||
pulseRuntimePath = "/var/run/pulse";
|
stateDir = "/run/pulse";
|
||||||
|
|
||||||
# Create pulse/client.conf even if PulseAudio is disabled so
|
# Create pulse/client.conf even if PulseAudio is disabled so
|
||||||
# that we can disable the autospawn feature in programs that
|
# that we can disable the autospawn feature in programs that
|
||||||
# are built with PulseAudio support (like KDE).
|
# are built with PulseAudio support (like KDE).
|
||||||
clientConf = writeText "client.conf" ''
|
clientConf = writeText "client.conf" ''
|
||||||
autospawn=${if (cfg.enable && !cfg.systemWide) then "yes" else "no"}
|
autospawn=${if nonSystemWide then "yes" else "no"}
|
||||||
${optionalString (cfg.enable && !cfg.systemWide)
|
${optionalString nonSystemWide "daemon-binary=${cfg.package}/bin/pulseaudio"}
|
||||||
"daemon-binary=${cfg.package}/bin/pulseaudio"}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Write an /etc/asound.conf that causes all ALSA applications to
|
# Write an /etc/asound.conf that causes all ALSA applications to
|
||||||
@ -68,7 +70,7 @@ in {
|
|||||||
|
|
||||||
configFile = mkOption {
|
configFile = mkOption {
|
||||||
type = types.uniq types.path;
|
type = types.uniq types.path;
|
||||||
default = "${pulseaudio}/etc/pulse/default.pa";
|
default = "${cfg.package}/etc/pulse/default.pa";
|
||||||
description = ''
|
description = ''
|
||||||
The path to the configuration the PulseAudio server
|
The path to the configuration the PulseAudio server
|
||||||
should use. By default, the "default.pa" configuration
|
should use. By default, the "default.pa" configuration
|
||||||
@ -77,15 +79,26 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.path;
|
type = types.package;
|
||||||
default = pulseaudio;
|
default = pulseaudioFull;
|
||||||
example = literalExample "pulseaudio.override { jackaudioSupport = true; }";
|
example = literalExample "pulseaudioFull";
|
||||||
description = ''
|
description = ''
|
||||||
The PulseAudio derivation to use. This can be used to enable
|
The PulseAudio derivation to use. This can be used to disable
|
||||||
features (such as JACK support) that are not enabled in the
|
features (such as JACK support, Bluetooth) that are enabled in the
|
||||||
default PulseAudio in Nixpkgs.
|
pulseaudioFull package in Nixpkgs.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
daemon = {
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "notice";
|
||||||
|
description = ''
|
||||||
|
The log level that the system-wide pulseaudio daemon should use,
|
||||||
|
if activated.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -111,38 +124,37 @@ in {
|
|||||||
security.rtkit.enable = true;
|
security.rtkit.enable = true;
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (cfg.enable && !cfg.systemWide) {
|
(mkIf nonSystemWide {
|
||||||
environment.etc = singleton {
|
environment.etc = singleton {
|
||||||
target = "pulse/default.pa";
|
target = "pulse/default.pa";
|
||||||
source = cfg.configFile;
|
source = cfg.configFile;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (cfg.enable && cfg.systemWide) {
|
(mkIf systemWide {
|
||||||
users.extraUsers.pulse = {
|
users.extraUsers.pulse = {
|
||||||
# For some reason, PulseAudio wants UID == GID.
|
# For some reason, PulseAudio wants UID == GID.
|
||||||
uid = assert uid == gid; uid;
|
uid = assert uid == gid; uid;
|
||||||
group = "pulse";
|
group = "pulse";
|
||||||
extraGroups = [ "audio" ];
|
extraGroups = [ "audio" ];
|
||||||
description = "PulseAudio system service user";
|
description = "PulseAudio system service user";
|
||||||
home = pulseRuntimePath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraGroups.pulse.gid = gid;
|
users.extraGroups.pulse.gid = gid;
|
||||||
|
|
||||||
systemd.services.pulseaudio = {
|
systemd.services.pulseaudio = {
|
||||||
description = "PulseAudio system-wide server";
|
description = "PulseAudio System-Wide Server";
|
||||||
wantedBy = [ "sound.target" ];
|
wantedBy = [ "sound.target" ];
|
||||||
before = [ "sound.target" ];
|
before = [ "sound.target" ];
|
||||||
path = [ cfg.package ];
|
environment.PULSE_RUNTIME_PATH = stateDir;
|
||||||
environment.PULSE_RUNTIME_PATH = pulseRuntimePath;
|
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -p --mode 755 ${pulseRuntimePath}
|
mkdir -p --mode 755 ${stateDir}
|
||||||
chown -R pulse:pulse ${pulseRuntimePath}
|
chown -R pulse:pulse ${stateDir}
|
||||||
'';
|
|
||||||
script = ''
|
|
||||||
exec pulseaudio --system -n --file="${cfg.configFile}"
|
|
||||||
'';
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/pulseaudio -D --log-level=${cfg.daemon.logLevel} --system --use-pid-file -n --file=${cfg.configFile}";
|
||||||
|
PIDFile = "${stateDir}/pid";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# This module defines a global environment configuration and
|
# This module defines a global environment configuration and
|
||||||
# a common configuration for all shells.
|
# a common configuration for all shells.
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -19,6 +19,7 @@ in
|
|||||||
default = {};
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
A set of environment variables used in the global environment.
|
A set of environment variables used in the global environment.
|
||||||
|
These variables will be set on shell initialisation.
|
||||||
The value of each variable can be either a string or a list of
|
The value of each variable can be either a string or a list of
|
||||||
strings. The latter is concatenated, interspersed with colon
|
strings. The latter is concatenated, interspersed with colon
|
||||||
characters.
|
characters.
|
||||||
@ -31,9 +32,9 @@ in
|
|||||||
res = (head defs').value;
|
res = (head defs').value;
|
||||||
in
|
in
|
||||||
if isList res then concatLists (getValues defs')
|
if isList res then concatLists (getValues defs')
|
||||||
else if builtins.lessThan 1 (length defs') then
|
else if lessThan 1 (length defs') then
|
||||||
throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
|
throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
|
||||||
else if !builtins.isString res then
|
else if !isString res then
|
||||||
throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
|
throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
|
||||||
else res;
|
else res;
|
||||||
});
|
});
|
||||||
@ -148,6 +149,12 @@ in
|
|||||||
|
|
||||||
system.build.binsh = pkgs.bashInteractive;
|
system.build.binsh = pkgs.bashInteractive;
|
||||||
|
|
||||||
|
# Set session variables in the shell as well. This is usually
|
||||||
|
# unnecessary, but it allows changes to session variables to take
|
||||||
|
# effect without restarting the session (e.g. by opening a new
|
||||||
|
# terminal instead of logging out of X11).
|
||||||
|
environment.variables = config.environment.sessionVariables;
|
||||||
|
|
||||||
environment.etc."shells".text =
|
environment.etc."shells".text =
|
||||||
''
|
''
|
||||||
${concatStringsSep "\n" cfg.shells}
|
${concatStringsSep "\n" cfg.shells}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{ config, pkgs, utils, ... }:
|
{ config, lib, pkgs, utils, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
|
||||||
with utils;
|
with utils;
|
||||||
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -106,6 +106,7 @@ with utils;
|
|||||||
if [ ! -e "${sw.device}" ]; then
|
if [ ! -e "${sw.device}" ]; then
|
||||||
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
||||||
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
||||||
|
chmod 0600 ${sw.device}
|
||||||
mkswap ${sw.device}
|
mkswap ${sw.device}
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
sysctlOption = mkOptionType {
|
sysctlOption = mkOptionType {
|
||||||
name = "sysctl option value";
|
name = "sysctl option value";
|
||||||
check = x: builtins.isBool x || builtins.isString x || builtins.isInt x;
|
check = val:
|
||||||
merge = args: defs: (last defs).value; # FIXME: hacky way to allow overriding in configuration.nix.
|
let
|
||||||
|
checkType = x: isBool x || isString x || isInt x || isNull x;
|
||||||
|
in
|
||||||
|
checkType val || (val._type or "" == "override" && checkType val.content);
|
||||||
|
merge = loc: defs: mergeOneOption loc (filterOverrides defs);
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -29,8 +33,9 @@ in
|
|||||||
<manvolnum>8</manvolnum></citerefentry>. Note that sysctl
|
<manvolnum>8</manvolnum></citerefentry>. Note that sysctl
|
||||||
parameters names must be enclosed in quotes
|
parameters names must be enclosed in quotes
|
||||||
(e.g. <literal>"vm.swappiness"</literal> instead of
|
(e.g. <literal>"vm.swappiness"</literal> instead of
|
||||||
<literal>vm.swappiness</literal>). The value of each parameter
|
<literal>vm.swappiness</literal>). The value of each
|
||||||
may be a string, integer or Boolean.
|
parameter may be a string, integer, boolean, or null
|
||||||
|
(signifying the option will not appear at all).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,19 +44,13 @@ in
|
|||||||
config = {
|
config = {
|
||||||
|
|
||||||
environment.etc."sysctl.d/nixos.conf".text =
|
environment.etc."sysctl.d/nixos.conf".text =
|
||||||
concatStrings (mapAttrsToList (n: v: "${n}=${if v == false then "0" else toString v}\n") config.boot.kernel.sysctl);
|
concatStrings (mapAttrsToList (n: v:
|
||||||
|
optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n"
|
||||||
|
) config.boot.kernel.sysctl);
|
||||||
|
|
||||||
systemd.services.systemd-sysctl =
|
systemd.services.systemd-sysctl =
|
||||||
{ description = "Apply Kernel Variables";
|
{ wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "sysinit.target" "shutdown.target" ];
|
|
||||||
wantedBy = [ "sysinit.target" "multi-user.target" ];
|
|
||||||
restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ];
|
restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ];
|
||||||
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStart = "${config.systemd.package}/lib/systemd/systemd-sysctl";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable hardlink and symlink restrictions. See
|
# Enable hardlink and symlink restrictions. See
|
||||||
@ -62,8 +61,9 @@ in
|
|||||||
|
|
||||||
# Hide kernel pointers (e.g. in /proc/modules) for unprivileged
|
# Hide kernel pointers (e.g. in /proc/modules) for unprivileged
|
||||||
# users as these make it easier to exploit kernel vulnerabilities.
|
# users as these make it easier to exploit kernel vulnerabilities.
|
||||||
boot.kernel.sysctl."kernel.kptr_restrict" = 1;
|
#
|
||||||
|
# Removed under grsecurity.
|
||||||
|
boot.kernel.sysctl."kernel.kptr_restrict" =
|
||||||
|
if config.security.grsecurity.enable then null else 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
56
nixos/modules/config/system-environment.nix
Normal file
56
nixos/modules/config/system-environment.nix
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# This module defines a system-wide environment that will be
|
||||||
|
# initialised by pam_env (that is, not only in shells).
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.environment;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
environment.sessionVariables = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
A set of environment variables used in the global environment.
|
||||||
|
These variables will be set by PAM.
|
||||||
|
The value of each variable can be either a string or a list of
|
||||||
|
strings. The latter is concatenated, interspersed with colon
|
||||||
|
characters.
|
||||||
|
'';
|
||||||
|
type = types.attrsOf (mkOptionType {
|
||||||
|
name = "a string or a list of strings";
|
||||||
|
merge = loc: defs:
|
||||||
|
let
|
||||||
|
defs' = filterOverrides defs;
|
||||||
|
res = (head defs').value;
|
||||||
|
in
|
||||||
|
if isList res then concatLists (getValues defs')
|
||||||
|
else if lessThan 1 (length defs') then
|
||||||
|
throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
|
||||||
|
else if !isString res then
|
||||||
|
throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
|
||||||
|
else res;
|
||||||
|
});
|
||||||
|
apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
system.build.pamEnvironment = pkgs.writeText "pam-environment"
|
||||||
|
''
|
||||||
|
${concatStringsSep "\n" (
|
||||||
|
(mapAttrsToList (n: v: ''${n}="${concatStringsSep ":" v}"'')
|
||||||
|
(zipAttrsWith (const concatLists) ([ (mapAttrs (n: v: [ v ]) cfg.sessionVariables) ]))))}
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
# This module defines the packages that appear in
|
# This module defines the packages that appear in
|
||||||
# /run/current-system/sw.
|
# /run/current-system/sw.
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -46,6 +46,7 @@ let
|
|||||||
pkgs.rsync
|
pkgs.rsync
|
||||||
pkgs.strace
|
pkgs.strace
|
||||||
pkgs.sysvtools
|
pkgs.sysvtools
|
||||||
|
pkgs.su
|
||||||
pkgs.time
|
pkgs.time
|
||||||
pkgs.usbutils
|
pkgs.usbutils
|
||||||
pkgs.utillinux
|
pkgs.utillinux
|
||||||
@ -109,6 +110,7 @@ in
|
|||||||
"/man"
|
"/man"
|
||||||
"/sbin"
|
"/sbin"
|
||||||
"/share/emacs"
|
"/share/emacs"
|
||||||
|
"/share/vim-plugins"
|
||||||
"/share/org"
|
"/share/org"
|
||||||
"/share/info"
|
"/share/info"
|
||||||
"/share/terminfo"
|
"/share/terminfo"
|
||||||
@ -134,6 +136,10 @@ in
|
|||||||
if [ -x $out/bin/glib-compile-schemas -a -w $out/share/glib-2.0/schemas ]; then
|
if [ -x $out/bin/glib-compile-schemas -a -w $out/share/glib-2.0/schemas ]; then
|
||||||
$out/bin/glib-compile-schemas $out/share/glib-2.0/schemas
|
$out/bin/glib-compile-schemas $out/share/glib-2.0/schemas
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -x $out/bin/update-desktop-database -a -w $out/share/applications ]; then
|
||||||
|
$out/bin/update-desktop-database $out/share/applications
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
tzdir = "${pkgs.tzdata}/share/zoneinfo";
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
@ -24,10 +30,14 @@ with pkgs.lib;
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
environment.variables.TZDIR = "/etc/zoneinfo";
|
environment.sessionVariables.TZDIR = "/etc/zoneinfo";
|
||||||
environment.variables.TZ = config.time.timeZone;
|
|
||||||
|
|
||||||
environment.etc.localtime.source = "${pkgs.tzdata}/share/zoneinfo/${config.time.timeZone}";
|
systemd.globalEnvironment.TZDIR = tzdir;
|
||||||
|
|
||||||
|
environment.etc.localtime =
|
||||||
|
{ source = "${tzdir}/${config.time.timeZone}";
|
||||||
|
mode = "direct-symlink";
|
||||||
|
};
|
||||||
|
|
||||||
environment.etc.zoneinfo.source = "${pkgs.tzdata}/share/zoneinfo";
|
environment.etc.zoneinfo.source = "${pkgs.tzdata}/share/zoneinfo";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
# unixODBC drivers (this solution is not perfect.. Because the user has to
|
# unixODBC drivers (this solution is not perfect.. Because the user has to
|
||||||
# ask the admin to add a driver.. but it's simple and works
|
# ask the admin to add a driver.. but it's simple and works
|
||||||
@ -27,7 +27,7 @@ with pkgs.lib;
|
|||||||
|
|
||||||
environment.etc."odbcinst.ini".text =
|
environment.etc."odbcinst.ini".text =
|
||||||
let inis = config.environment.unixODBCDrivers;
|
let inis = config.environment.unixODBCDrivers;
|
||||||
in pkgs.lib.concatStringsSep "\n" inis;
|
in lib.concatStringsSep "\n" inis;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
239
nixos/modules/config/update-users-groups.pl
Normal file
239
nixos/modules/config/update-users-groups.pl
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
use strict;
|
||||||
|
use File::Path qw(make_path);
|
||||||
|
use File::Slurp;
|
||||||
|
use JSON;
|
||||||
|
|
||||||
|
make_path("/var/lib/nixos", { mode => 0755 });
|
||||||
|
|
||||||
|
|
||||||
|
# Functions for allocating free GIDs/UIDs. FIXME: respect ID ranges in
|
||||||
|
# /etc/login.defs.
|
||||||
|
sub allocId {
|
||||||
|
my ($used, $idMin, $idMax, $up, $getid) = @_;
|
||||||
|
my $id = $up ? $idMin : $idMax;
|
||||||
|
while ($id >= $idMin && $id <= $idMax) {
|
||||||
|
if (!$used->{$id} && !defined &$getid($id)) {
|
||||||
|
$used->{$id} = 1;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
$used->{$id} = 1;
|
||||||
|
if ($up) { $id++; } else { $id--; }
|
||||||
|
}
|
||||||
|
die "$0: out of free UIDs or GIDs\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my (%gidsUsed, %uidsUsed);
|
||||||
|
|
||||||
|
sub allocGid {
|
||||||
|
return allocId(\%gidsUsed, 400, 499, 0, sub { my ($gid) = @_; getgrgid($gid) });
|
||||||
|
}
|
||||||
|
|
||||||
|
sub allocUid {
|
||||||
|
my ($isSystemUser) = @_;
|
||||||
|
my ($min, $max, $up) = $isSystemUser ? (400, 499, 0) : (1000, 29999, 1);
|
||||||
|
return allocId(\%uidsUsed, $min, $max, $up, sub { my ($uid) = @_; getpwuid($uid) });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Read the declared users/groups.
|
||||||
|
my $spec = decode_json(read_file($ARGV[0]));
|
||||||
|
|
||||||
|
# Don't allocate UIDs/GIDs that are already in use.
|
||||||
|
foreach my $g (@{$spec->{groups}}) {
|
||||||
|
$gidsUsed{$g->{gid}} = 1 if defined $g->{gid};
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $u (@{$spec->{groups}}) {
|
||||||
|
$uidsUsed{$u->{u}} = 1 if defined $u->{uid};
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read the current /etc/group.
|
||||||
|
sub parseGroup {
|
||||||
|
chomp;
|
||||||
|
my @f = split(':', $_, -4);
|
||||||
|
my $gid = $f[2] eq "" ? undef : int($f[2]);
|
||||||
|
$gidsUsed{$gid} = 1 if defined $gid;
|
||||||
|
return ($f[0], { name => $f[0], password => $f[1], gid => $gid, members => $f[3] });
|
||||||
|
}
|
||||||
|
|
||||||
|
my %groupsCur = -f "/etc/group" ? map { parseGroup } read_file("/etc/group") : ();
|
||||||
|
|
||||||
|
# Read the current /etc/passwd.
|
||||||
|
sub parseUser {
|
||||||
|
chomp;
|
||||||
|
my @f = split(':', $_, -7);
|
||||||
|
my $uid = $f[2] eq "" ? undef : int($f[2]);
|
||||||
|
$uidsUsed{$uid} = 1 if defined $uid;
|
||||||
|
return ($f[0], { name => $f[0], fakePassword => $f[1], uid => $uid,
|
||||||
|
gid => $f[3], description => $f[4], home => $f[5], shell => $f[6] });
|
||||||
|
}
|
||||||
|
|
||||||
|
my %usersCur = -f "/etc/passwd" ? map { parseUser } read_file("/etc/passwd") : ();
|
||||||
|
|
||||||
|
# Read the groups that were created declaratively (i.e. not by groups)
|
||||||
|
# in the past. These must be removed if they are no longer in the
|
||||||
|
# current spec.
|
||||||
|
my $declGroupsFile = "/var/lib/nixos/declarative-groups";
|
||||||
|
my %declGroups;
|
||||||
|
$declGroups{$_} = 1 foreach split / /, -e $declGroupsFile ? read_file($declGroupsFile) : "";
|
||||||
|
|
||||||
|
# Idem for the users.
|
||||||
|
my $declUsersFile = "/var/lib/nixos/declarative-users";
|
||||||
|
my %declUsers;
|
||||||
|
$declUsers{$_} = 1 foreach split / /, -e $declUsersFile ? read_file($declUsersFile) : "";
|
||||||
|
|
||||||
|
|
||||||
|
# Generate a new /etc/group containing the declared groups.
|
||||||
|
my %groupsOut;
|
||||||
|
foreach my $g (@{$spec->{groups}}) {
|
||||||
|
my $name = $g->{name};
|
||||||
|
my $existing = $groupsCur{$name};
|
||||||
|
|
||||||
|
my %members = map { ($_, 1) } @{$g->{members}};
|
||||||
|
|
||||||
|
if (defined $existing) {
|
||||||
|
$g->{gid} = $existing->{gid} if !defined $g->{gid};
|
||||||
|
if ($g->{gid} != $existing->{gid}) {
|
||||||
|
warn "warning: not applying GID change of group ‘$name’\n";
|
||||||
|
$g->{gid} = $existing->{gid};
|
||||||
|
}
|
||||||
|
$g->{password} = $existing->{password}; # do we want this?
|
||||||
|
if ($spec->{mutableUsers}) {
|
||||||
|
# Merge in non-declarative group members.
|
||||||
|
foreach my $uname (split /,/, $existing->{members} // "") {
|
||||||
|
$members{$uname} = 1 if !defined $declUsers{$uname};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$g->{gid} = allocGid if !defined $g->{gid};
|
||||||
|
$g->{password} = "x";
|
||||||
|
}
|
||||||
|
|
||||||
|
$g->{members} = join ",", sort(keys(%members));
|
||||||
|
$groupsOut{$name} = $g;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update the persistent list of declarative groups.
|
||||||
|
write_file($declGroupsFile, join(" ", sort(keys %groupsOut)));
|
||||||
|
|
||||||
|
# Merge in the existing /etc/group.
|
||||||
|
foreach my $name (keys %groupsCur) {
|
||||||
|
my $g = $groupsCur{$name};
|
||||||
|
next if defined $groupsOut{$name};
|
||||||
|
if (!$spec->{mutableUsers} || defined $declGroups{$name}) {
|
||||||
|
print STDERR "removing group ‘$name’\n";
|
||||||
|
} else {
|
||||||
|
$groupsOut{$name} = $g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Rewrite /etc/group. FIXME: acquire lock.
|
||||||
|
my @lines = map { join(":", $_->{name}, $_->{password}, $_->{gid}, $_->{members}) . "\n" }
|
||||||
|
(sort { $a->{gid} <=> $b->{gid} } values(%groupsOut));
|
||||||
|
write_file("/etc/group.tmp", @lines);
|
||||||
|
rename("/etc/group.tmp", "/etc/group") or die;
|
||||||
|
system("nscd --invalidate group");
|
||||||
|
|
||||||
|
# Generate a new /etc/passwd containing the declared users.
|
||||||
|
my %usersOut;
|
||||||
|
foreach my $u (@{$spec->{users}}) {
|
||||||
|
my $name = $u->{name};
|
||||||
|
|
||||||
|
# Resolve the gid of the user.
|
||||||
|
if ($u->{group} =~ /^[0-9]$/) {
|
||||||
|
$u->{gid} = $u->{group};
|
||||||
|
} elsif (defined $groupsOut{$u->{group}}) {
|
||||||
|
$u->{gid} = $groupsOut{$u->{group}}->{gid} // die;
|
||||||
|
} else {
|
||||||
|
warn "warning: user ‘$name’ has unknown group ‘$u->{group}’\n";
|
||||||
|
$u->{gid} = 65534;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $existing = $usersCur{$name};
|
||||||
|
if (defined $existing) {
|
||||||
|
$u->{uid} = $existing->{uid} if !defined $u->{uid};
|
||||||
|
if ($u->{uid} != $existing->{uid}) {
|
||||||
|
warn "warning: not applying UID change of user ‘$name’\n";
|
||||||
|
$u->{uid} = $existing->{uid};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$u->{uid} = allocUid($u->{isSystemUser}) if !defined $u->{uid};
|
||||||
|
|
||||||
|
# Create a home directory.
|
||||||
|
if ($u->{createHome}) {
|
||||||
|
make_path($u->{home}, { mode => 0700 }) if ! -e $u->{home};
|
||||||
|
chown $u->{uid}, $u->{gid}, $u->{home};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $u->{passwordFile}) {
|
||||||
|
if (-e $u->{passwordFile}) {
|
||||||
|
$u->{hashedPassword} = read_file($u->{passwordFile});
|
||||||
|
chomp $u->{hashedPassword};
|
||||||
|
} else {
|
||||||
|
warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$u->{fakePassword} = $existing->{fakePassword} // "x";
|
||||||
|
$usersOut{$name} = $u;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update the persistent list of declarative users.
|
||||||
|
write_file($declUsersFile, join(" ", sort(keys %usersOut)));
|
||||||
|
|
||||||
|
# Merge in the existing /etc/passwd.
|
||||||
|
foreach my $name (keys %usersCur) {
|
||||||
|
my $u = $usersCur{$name};
|
||||||
|
next if defined $usersOut{$name};
|
||||||
|
if (!$spec->{mutableUsers} || defined $declUsers{$name}) {
|
||||||
|
print STDERR "removing user ‘$name’\n";
|
||||||
|
} else {
|
||||||
|
$usersOut{$name} = $u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rewrite /etc/passwd. FIXME: acquire lock.
|
||||||
|
@lines = map { join(":", $_->{name}, $_->{fakePassword}, $_->{uid}, $_->{gid}, $_->{description}, $_->{home}, $_->{shell}) . "\n" }
|
||||||
|
(sort { $a->{uid} <=> $b->{uid} } (values %usersOut));
|
||||||
|
write_file("/etc/passwd.tmp", @lines);
|
||||||
|
rename("/etc/passwd.tmp", "/etc/passwd") or die;
|
||||||
|
system("nscd --invalidate passwd");
|
||||||
|
|
||||||
|
|
||||||
|
# Rewrite /etc/shadow to add new accounts or remove dead ones.
|
||||||
|
my @shadowNew;
|
||||||
|
my %shadowSeen;
|
||||||
|
|
||||||
|
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
|
||||||
|
chomp $line;
|
||||||
|
my ($name, $password, @rest) = split(':', $line, -9);
|
||||||
|
my $u = $usersOut{$name};;
|
||||||
|
next if !defined $u;
|
||||||
|
$password = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
|
||||||
|
push @shadowNew, join(":", $name, $password, @rest) . "\n";
|
||||||
|
$shadowSeen{$name} = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $u (values %usersOut) {
|
||||||
|
next if defined $shadowSeen{$u->{name}};
|
||||||
|
my $password = "!";
|
||||||
|
$password = $u->{hashedPassword} if defined $u->{hashedPassword};
|
||||||
|
# FIXME: set correct value for sp_lstchg.
|
||||||
|
push @shadowNew, join(":", $u->{name}, $password, "1::::::") . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
write_file("/etc/shadow.tmp", { perms => 0600 }, @shadowNew);
|
||||||
|
rename("/etc/shadow.tmp", "/etc/shadow") or die;
|
||||||
|
|
||||||
|
|
||||||
|
# Call chpasswd to apply password. FIXME: generate the hashes directly
|
||||||
|
# and merge into the /etc/shadow updating above.
|
||||||
|
foreach my $u (@{$spec->{users}}) {
|
||||||
|
if (defined $u->{password}) {
|
||||||
|
my $pid = open(PW, "| chpasswd") or die;
|
||||||
|
print PW "$u->{name}:$u->{password}\n";
|
||||||
|
close PW or die "unable to change password of user ‘$u->{name}’: $?\n";
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,29 @@
|
|||||||
{pkgs, config, ...}:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
ids = config.ids;
|
ids = config.ids;
|
||||||
users = config.users;
|
cfg = config.users;
|
||||||
|
|
||||||
|
passwordDescription = ''
|
||||||
|
The options <literal>hashedPassword</literal>,
|
||||||
|
<literal>password</literal> and <literal>passwordFile</literal>
|
||||||
|
controls what password is set for the user.
|
||||||
|
<literal>hashedPassword</literal> overrides both
|
||||||
|
<literal>password</literal> and <literal>passwordFile</literal>.
|
||||||
|
<literal>password</literal> overrides <literal>passwordFile</literal>.
|
||||||
|
If none of these three options are set, no password is assigned to
|
||||||
|
the user, and the user will not be able to do password logins.
|
||||||
|
If the option <literal>users.mutableUsers</literal> is true, the
|
||||||
|
password defined in one of the three options will only be set when
|
||||||
|
the user is created for the first time. After that, you are free to
|
||||||
|
change the password with the ordinary user management commands. If
|
||||||
|
<literal>users.mutableUsers</literal> is false, you cannot change
|
||||||
|
user passwords, they will always be set according to the password
|
||||||
|
options.
|
||||||
|
'';
|
||||||
|
|
||||||
userOpts = { name, config, ... }: {
|
userOpts = { name, config, ... }: {
|
||||||
|
|
||||||
@ -13,7 +31,10 @@ let
|
|||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The name of the user account. If undefined, the name of the attribute set will be used.";
|
description = ''
|
||||||
|
The name of the user account. If undefined, the name of the
|
||||||
|
attribute set will be used.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
@ -28,9 +49,40 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
uid = mkOption {
|
uid = mkOption {
|
||||||
type = with types; uniq (nullOr int);
|
type = with types; nullOr int;
|
||||||
default = null;
|
default = null;
|
||||||
description = "The account UID. If undefined, NixOS will select a free UID.";
|
description = ''
|
||||||
|
The account UID. If the UID is null, a free UID is picked on
|
||||||
|
activation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
isSystemUser = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Indicates if the user is a system user or not. This option
|
||||||
|
only has an effect if <option>uid</option> is
|
||||||
|
<option>null</option>, in which case it determines whether
|
||||||
|
the user's UID is allocated in the range for system users
|
||||||
|
(below 500) or in the range for normal users (starting at
|
||||||
|
1000).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
isNormalUser = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Indicates whether this is an account for a “real” user. This
|
||||||
|
automatically sets <option>group</option> to
|
||||||
|
<literal>users</literal>, <option>createHome</option> to
|
||||||
|
<literal>true</literal>, <option>home</option> to
|
||||||
|
<filename>/home/<replaceable>username</replaceable></filename>,
|
||||||
|
<option>useDefaultShell</option> to <literal>true</literal>,
|
||||||
|
and <option>isSystemUser</option> to
|
||||||
|
<literal>false</literal>.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
group = mkOption {
|
group = mkOption {
|
||||||
@ -60,56 +112,69 @@ let
|
|||||||
createHome = mkOption {
|
createHome = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "If true, the home directory will be created automatically.";
|
description = ''
|
||||||
|
If true, the home directory will be created automatically. If this
|
||||||
|
option is true and the home directory already exists but is not
|
||||||
|
owned by the user, directory owner and group will be changed to
|
||||||
|
match the user.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
useDefaultShell = mkOption {
|
useDefaultShell = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "If true, the user's shell will be set to <literal>users.defaultUserShell</literal>.";
|
description = ''
|
||||||
|
If true, the user's shell will be set to
|
||||||
|
<literal>cfg.defaultUserShell</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hashedPassword = mkOption {
|
||||||
|
type = with types; uniq (nullOr str);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Specifies the (hashed) password for the user.
|
||||||
|
${passwordDescription}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
password = mkOption {
|
password = mkOption {
|
||||||
type = with types; uniq (nullOr str);
|
type = with types; uniq (nullOr str);
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
The user's password. If undefined, no password is set for
|
Specifies the (clear text) password for the user.
|
||||||
the user. Warning: do not set confidential information here
|
Warning: do not set confidential information here
|
||||||
because it is world-readable in the Nix store. This option
|
because it is world-readable in the Nix store. This option
|
||||||
should only be used for public accounts such as
|
should only be used for public accounts.
|
||||||
<literal>guest</literal>.
|
${passwordDescription}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
isSystemUser = mkOption {
|
passwordFile = mkOption {
|
||||||
type = types.bool;
|
type = with types; uniq (nullOr string);
|
||||||
default = true;
|
default = null;
|
||||||
description = "Indicates if the user is a system user or not.";
|
|
||||||
};
|
|
||||||
|
|
||||||
createUser = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
description = ''
|
||||||
Indicates if the user should be created automatically as a local user.
|
The path to a file that contains the user's password. The password
|
||||||
Set this to false if the user for instance is an LDAP user. NixOS will
|
file is read on each system activation. The file should contain
|
||||||
then not modify any of the basic properties for the user account.
|
exactly one line, which should be the password in an encrypted form
|
||||||
|
that is suitable for the <literal>chpasswd -e</literal> command.
|
||||||
|
${passwordDescription}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
isAlias = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "If true, the UID of this user is not required to be unique and can thus alias another user.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
config = mkMerge
|
||||||
|
[ { name = mkDefault name;
|
||||||
config = {
|
shell = mkIf config.useDefaultShell (mkDefault cfg.defaultUserShell);
|
||||||
name = mkDefault name;
|
}
|
||||||
uid = mkDefault (attrByPath [name] null ids.uids);
|
(mkIf config.isNormalUser {
|
||||||
shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell);
|
group = mkDefault "users";
|
||||||
};
|
createHome = mkDefault true;
|
||||||
|
home = mkDefault "/home/${name}";
|
||||||
|
useDefaultShell = mkDefault true;
|
||||||
|
isSystemUser = mkDefault false;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,41 +184,102 @@ let
|
|||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The name of the group. If undefined, the name of the attribute set will be used.";
|
description = ''
|
||||||
|
The name of the group. If undefined, the name of the attribute set
|
||||||
|
will be used.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
gid = mkOption {
|
gid = mkOption {
|
||||||
type = with types; uniq (nullOr int);
|
type = with types; nullOr int;
|
||||||
default = null;
|
default = null;
|
||||||
description = "The GID of the group. If undefined, NixOS will select a free GID.";
|
description = ''
|
||||||
|
The group GID. If the GID is null, a free GID is picked on
|
||||||
|
activation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
members = mkOption {
|
||||||
|
type = with types; listOf string;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
The user names of the group members, added to the
|
||||||
|
<literal>/etc/group</literal> file.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
name = mkDefault name;
|
name = mkDefault name;
|
||||||
gid = mkDefault (attrByPath [name] null ids.gids);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Note: the 'X' in front of the password is to distinguish between
|
idsAreUnique = set: idAttr: !(fold (name: args@{ dup, acc }:
|
||||||
# having an empty password, and not having a password.
|
|
||||||
serializedUser = u: "${u.name}\n${u.description}\n${if u.uid != null then toString u.uid else ""}\n${u.group}\n${toString (concatStringsSep "," u.extraGroups)}\n${u.home}\n${u.shell}\n${toString u.createHome}\n${if u.password != null then "X" + u.password else ""}\n${toString u.isSystemUser}\n${toString u.createUser}\n${toString u.isAlias}\n";
|
|
||||||
|
|
||||||
usersFile = pkgs.writeText "users" (
|
|
||||||
let
|
let
|
||||||
p = partition (u: u.isAlias) (attrValues config.users.extraUsers);
|
id = builtins.toString (builtins.getAttr idAttr (builtins.getAttr name set));
|
||||||
in concatStrings (map serializedUser p.wrong ++ map serializedUser p.right));
|
exists = builtins.hasAttr id acc;
|
||||||
|
newAcc = acc // (builtins.listToAttrs [ { name = id; value = true; } ]);
|
||||||
|
in if dup then args else if exists
|
||||||
|
then builtins.trace "Duplicate ${idAttr} ${id}" { dup = true; acc = null; }
|
||||||
|
else { dup = false; acc = newAcc; }
|
||||||
|
) { dup = false; acc = {}; } (builtins.attrNames set)).dup;
|
||||||
|
|
||||||
in
|
uidsAreUnique = idsAreUnique (filterAttrs (n: u: u.uid != null) cfg.extraUsers) "uid";
|
||||||
|
gidsAreUnique = idsAreUnique (filterAttrs (n: g: g.gid != null) cfg.extraGroups) "gid";
|
||||||
|
|
||||||
{
|
spec = builtins.toFile "users-groups.json" (builtins.toJSON {
|
||||||
|
inherit (cfg) mutableUsers;
|
||||||
|
users = mapAttrsToList (n: u:
|
||||||
|
{ inherit (u)
|
||||||
|
name uid group description home shell createHome isSystemUser
|
||||||
|
password passwordFile hashedPassword;
|
||||||
|
}) cfg.extraUsers;
|
||||||
|
groups = mapAttrsToList (n: g:
|
||||||
|
{ inherit (g) name gid;
|
||||||
|
members = mapAttrsToList (n: u: u.name) (
|
||||||
|
filterAttrs (n: u: elem g.name u.extraGroups) cfg.extraUsers
|
||||||
|
);
|
||||||
|
}) cfg.extraGroups;
|
||||||
|
});
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
|
users.mutableUsers = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
If true, you are free to add new users and groups to the system
|
||||||
|
with the ordinary <literal>useradd</literal> and
|
||||||
|
<literal>groupadd</literal> commands. On system activation, the
|
||||||
|
existing contents of the <literal>/etc/passwd</literal> and
|
||||||
|
<literal>/etc/group</literal> files will be merged with the
|
||||||
|
contents generated from the <literal>users.extraUsers</literal> and
|
||||||
|
<literal>users.extraGroups</literal> options. If
|
||||||
|
<literal>mutableUsers</literal> is false, the contents of the user and
|
||||||
|
group files will simply be replaced on system activation. This also
|
||||||
|
holds for the user passwords; if this option is false, all changed
|
||||||
|
passwords will be reset according to the
|
||||||
|
<literal>users.extraUsers</literal> configuration on activation. If
|
||||||
|
this option is true, the initial password for a user will be set
|
||||||
|
according to <literal>users.extraUsers</literal>, but existing passwords
|
||||||
|
will not be changed.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
users.enforceIdUniqueness = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to require that no two users/groups share the same uid/gid.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
users.extraUsers = mkOption {
|
users.extraUsers = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = types.loaOf types.optionSet;
|
type = types.loaOf types.optionSet;
|
||||||
@ -188,6 +314,26 @@ in
|
|||||||
options = [ groupOpts ];
|
options = [ groupOpts ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
security.initialRootPassword = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "!";
|
||||||
|
example = "";
|
||||||
|
description = ''
|
||||||
|
The (hashed) password for the root account set on initial
|
||||||
|
installation. The empty string denotes that root can login
|
||||||
|
locally without a password (but not via remote services such
|
||||||
|
as SSH, or indirectly via <command>su</command> or
|
||||||
|
<command>sudo</command>). The string <literal>!</literal>
|
||||||
|
prevents root from logging in using a password.
|
||||||
|
Note that setting this option sets
|
||||||
|
<literal>users.extraUsers.root.hashedPassword</literal>.
|
||||||
|
Also, if <literal>users.mutableUsers</literal> is false
|
||||||
|
you cannot change the root password manually, so in that case
|
||||||
|
the name of this option is a bit misleading, since it will define
|
||||||
|
the root password beyond the user initialisation phase.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -197,128 +343,59 @@ in
|
|||||||
|
|
||||||
users.extraUsers = {
|
users.extraUsers = {
|
||||||
root = {
|
root = {
|
||||||
|
uid = ids.uids.root;
|
||||||
description = "System administrator";
|
description = "System administrator";
|
||||||
home = "/root";
|
home = "/root";
|
||||||
shell = config.users.defaultUserShell;
|
shell = mkDefault cfg.defaultUserShell;
|
||||||
group = "root";
|
group = "root";
|
||||||
|
extraGroups = [ "grsecurity" ];
|
||||||
|
hashedPassword = mkDefault config.security.initialRootPassword;
|
||||||
};
|
};
|
||||||
nobody = {
|
nobody = {
|
||||||
|
uid = ids.uids.nobody;
|
||||||
description = "Unprivileged account (don't use!)";
|
description = "Unprivileged account (don't use!)";
|
||||||
|
group = "nogroup";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraGroups = {
|
users.extraGroups = {
|
||||||
root = { };
|
root.gid = ids.gids.root;
|
||||||
wheel = { };
|
wheel.gid = ids.gids.wheel;
|
||||||
disk = { };
|
disk.gid = ids.gids.disk;
|
||||||
kmem = { };
|
kmem.gid = ids.gids.kmem;
|
||||||
tty = { };
|
tty.gid = ids.gids.tty;
|
||||||
floppy = { };
|
floppy.gid = ids.gids.floppy;
|
||||||
uucp = { };
|
uucp.gid = ids.gids.uucp;
|
||||||
lp = { };
|
lp.gid = ids.gids.lp;
|
||||||
cdrom = { };
|
cdrom.gid = ids.gids.cdrom;
|
||||||
tape = { };
|
tape.gid = ids.gids.tape;
|
||||||
audio = { };
|
audio.gid = ids.gids.audio;
|
||||||
video = { };
|
video.gid = ids.gids.video;
|
||||||
dialout = { };
|
dialout.gid = ids.gids.dialout;
|
||||||
nogroup = { };
|
nogroup.gid = ids.gids.nogroup;
|
||||||
users = { };
|
users.gid = ids.gids.users;
|
||||||
nixbld = { };
|
nixbld.gid = ids.gids.nixbld;
|
||||||
utmp = { };
|
utmp.gid = ids.gids.utmp;
|
||||||
adm = { }; # expected by journald
|
adm.gid = ids.gids.adm;
|
||||||
|
grsecurity.gid = ids.gids.grsecurity;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.activationScripts.rootPasswd = stringAfter [ "etc" ]
|
system.activationScripts.users = stringAfter [ "etc" ]
|
||||||
''
|
''
|
||||||
# If there is no password file yet, create a root account with an
|
${pkgs.perl}/bin/perl -w \
|
||||||
# empty password.
|
-I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl \
|
||||||
if ! test -e /etc/passwd; then
|
-I${pkgs.perlPackages.JSON}/lib/perl5/site_perl \
|
||||||
rootHome=/root
|
${./update-users-groups.pl} ${spec}
|
||||||
touch /etc/passwd; chmod 0644 /etc/passwd
|
|
||||||
touch /etc/group; chmod 0644 /etc/group
|
|
||||||
touch /etc/shadow; chmod 0600 /etc/shadow
|
|
||||||
# Can't use useradd, since it complains that it doesn't know us
|
|
||||||
# (bootstrap problem!).
|
|
||||||
echo "root:x:0:0:System administrator:$rootHome:${config.users.defaultUserShell}" >> /etc/passwd
|
|
||||||
echo "root::::::::" >> /etc/shadow
|
|
||||||
fi
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
system.activationScripts.users = stringAfter [ "groups" ]
|
# for backwards compatibility
|
||||||
''
|
system.activationScripts.groups = stringAfter [ "users" ] "";
|
||||||
echo "updating users..."
|
|
||||||
|
|
||||||
cat ${usersFile} | while true; do
|
assertions = [
|
||||||
read name || break
|
{ assertion = !cfg.enforceIdUniqueness || (uidsAreUnique && gidsAreUnique);
|
||||||
read description
|
message = "UIDs and GIDs must be unique!";
|
||||||
read uid
|
|
||||||
read group
|
|
||||||
read extraGroups
|
|
||||||
read home
|
|
||||||
read shell
|
|
||||||
read createHome
|
|
||||||
read password
|
|
||||||
read isSystemUser
|
|
||||||
read createUser
|
|
||||||
read isAlias
|
|
||||||
|
|
||||||
if [ -z "$createUser" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! curEnt=$(getent passwd "$name"); then
|
|
||||||
useradd ''${isSystemUser:+--system} \
|
|
||||||
--comment "$description" \
|
|
||||||
''${uid:+--uid $uid} \
|
|
||||||
--gid "$group" \
|
|
||||||
--groups "$extraGroups" \
|
|
||||||
--home "$home" \
|
|
||||||
--shell "$shell" \
|
|
||||||
''${createHome:+--create-home} \
|
|
||||||
''${isAlias:+--non-unique} \
|
|
||||||
"$name"
|
|
||||||
if test "''${password:0:1}" = 'X'; then
|
|
||||||
(echo "''${password:1}"; echo "''${password:1}") | ${pkgs.shadow}/bin/passwd "$name"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
#echo "updating user $name..."
|
|
||||||
oldIFS="$IFS"; IFS=:; set -- $curEnt; IFS="$oldIFS"
|
|
||||||
prevUid=$3
|
|
||||||
prevHome=$6
|
|
||||||
# Don't change the home directory if it's the same to prevent
|
|
||||||
# unnecessary warnings about logged in users.
|
|
||||||
if test "$prevHome" = "$home"; then unset home; fi
|
|
||||||
usermod \
|
|
||||||
--comment "$description" \
|
|
||||||
--gid "$group" \
|
|
||||||
--groups "$extraGroups" \
|
|
||||||
''${home:+--home "$home"} \
|
|
||||||
--shell "$shell" \
|
|
||||||
"$name"
|
|
||||||
fi
|
|
||||||
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
|
|
||||||
system.activationScripts.groups = stringAfter [ "rootPasswd" "binsh" "etc" "var" ]
|
|
||||||
''
|
|
||||||
echo "updating groups..."
|
|
||||||
|
|
||||||
createGroup() {
|
|
||||||
name="$1"
|
|
||||||
gid="$2"
|
|
||||||
|
|
||||||
if ! curEnt=$(getent group "$name"); then
|
|
||||||
groupadd --system \
|
|
||||||
''${gid:+--gid $gid} \
|
|
||||||
"$name"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
];
|
||||||
${flip concatMapStrings (attrValues config.users.extraGroups) (g: ''
|
|
||||||
createGroup '${g.name}' '${toString g.gid}'
|
|
||||||
'')}
|
|
||||||
'';
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
138
nixos/modules/config/zram.nix
Normal file
138
nixos/modules/config/zram.nix
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.zramSwap;
|
||||||
|
|
||||||
|
devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
|
||||||
|
|
||||||
|
modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
zramSwap = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Enable in-memory compressed swap space provided by the zram kernel
|
||||||
|
module. It is recommended to enable only for kernel 3.14 or higher.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
numDevices = mkOption {
|
||||||
|
default = 4;
|
||||||
|
type = types.int;
|
||||||
|
description = ''
|
||||||
|
Number of zram swap devices to create. It should be equal to the
|
||||||
|
number of CPU cores your system has.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
memoryPercent = mkOption {
|
||||||
|
default = 50;
|
||||||
|
type = types.int;
|
||||||
|
description = ''
|
||||||
|
Maximum amount of memory that can be used by the zram swap devices
|
||||||
|
(as a percentage of your total memory). Defaults to 1/2 of your total
|
||||||
|
RAM.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
priority = mkOption {
|
||||||
|
default = 5;
|
||||||
|
type = types.int;
|
||||||
|
description = ''
|
||||||
|
Priority of the zram swap devices. It should be a number higher than
|
||||||
|
the priority of your disk-based swap devices (so that the system will
|
||||||
|
fill the zram swap devices before falling back to disk swap).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||||
|
(isModule "ZRAM")
|
||||||
|
];
|
||||||
|
|
||||||
|
# Disabling this for the moment, as it would create and mkswap devices twice,
|
||||||
|
# once in stage 2 boot, and again when the zram-reloader service starts.
|
||||||
|
# boot.kernelModules = [ "zram" ];
|
||||||
|
|
||||||
|
boot.extraModprobeConfig = ''
|
||||||
|
options zram num_devices=${toString cfg.numDevices}
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
KERNEL=="zram[0-9]*", ENV{SYSTEMD_WANTS}="zram-init-%k.service", TAG+="systemd"
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.services =
|
||||||
|
let
|
||||||
|
createZramInitService = dev:
|
||||||
|
nameValuePair "zram-init-${dev}" {
|
||||||
|
description = "Init swap on zram-based device ${dev}";
|
||||||
|
bindsTo = [ "dev-${dev}.swap" ];
|
||||||
|
after = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||||
|
requires = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||||
|
before = [ "dev-${dev}.swap" ];
|
||||||
|
requiredBy = [ "dev-${dev}.swap" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
set -u
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
PATH=${pkgs.procps}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin
|
||||||
|
|
||||||
|
# Calculate memory to use for zram
|
||||||
|
totalmem=$(free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//')
|
||||||
|
mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
|
||||||
|
|
||||||
|
echo $mem > /sys/class/block/${dev}/disksize
|
||||||
|
${pkgs.utillinux}/sbin/mkswap /dev/${dev}
|
||||||
|
'';
|
||||||
|
restartIfChanged = false;
|
||||||
|
};
|
||||||
|
in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
|
||||||
|
{
|
||||||
|
description = "Reload zram kernel module when number of devices changes";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStartPre = "${modprobe} -r zram";
|
||||||
|
ExecStart = "${modprobe} zram";
|
||||||
|
ExecStop = "${modprobe} -r zram";
|
||||||
|
};
|
||||||
|
restartTriggers = [ cfg.numDevices ];
|
||||||
|
restartIfChanged = true;
|
||||||
|
})]);
|
||||||
|
|
||||||
|
swapDevices =
|
||||||
|
let
|
||||||
|
useZramSwap = dev:
|
||||||
|
{
|
||||||
|
device = "/dev/${dev}";
|
||||||
|
priority = cfg.priority;
|
||||||
|
};
|
||||||
|
in map useZramSwap devices;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{pkgs, config, ...}:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
||||||
|
|
||||||
@ -8,9 +10,9 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableB43Firmware = pkgs.lib.mkOption {
|
networking.enableB43Firmware = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Turn on this option if you want firmware for the NICs supported by the b43 module.
|
Turn on this option if you want firmware for the NICs supported by the b43 module.
|
||||||
'';
|
'';
|
||||||
@ -21,11 +23,11 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableB43Firmware {
|
config = mkIf config.networking.enableB43Firmware {
|
||||||
assertions = [ {
|
assertions = singleton
|
||||||
assertion = builtins.lessThan 0 (builtins.compareVersions kernelVersion "3.2");
|
{ assertion = lessThan 0 (builtins.compareVersions kernelVersion "3.2");
|
||||||
message = "b43 firmware for kernels older than 3.2 not packaged yet!";
|
message = "b43 firmware for kernels older than 3.2 not packaged yet!";
|
||||||
} ];
|
};
|
||||||
hardware.firmware = [ pkgs.b43Firmware_5_1_138 ];
|
hardware.firmware = [ pkgs.b43Firmware_5_1_138 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableIntel2100BGFirmware = pkgs.lib.mkOption {
|
networking.enableIntel2100BGFirmware = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = lib.types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Turn on this option if you want firmware for the Intel
|
Turn on this option if you want firmware for the Intel
|
||||||
PRO/Wireless 2100BG to be loaded automatically. This is
|
PRO/Wireless 2100BG to be loaded automatically. This is
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableIntel2100BGFirmware {
|
config = lib.mkIf config.networking.enableIntel2100BGFirmware {
|
||||||
|
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableIntel2200BGFirmware = pkgs.lib.mkOption {
|
networking.enableIntel2200BGFirmware = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = lib.types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Turn on this option if you want firmware for the Intel
|
Turn on this option if you want firmware for the Intel
|
||||||
PRO/Wireless 2200BG to be loaded automatically. This is
|
PRO/Wireless 2200BG to be loaded automatically. This is
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableIntel2200BGFirmware {
|
config = lib.mkIf config.networking.enableIntel2200BGFirmware {
|
||||||
|
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableIntel3945ABGFirmware = pkgs.lib.mkOption {
|
networking.enableIntel3945ABGFirmware = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = lib.types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
This option enables automatic loading of the firmware for the Intel
|
This option enables automatic loading of the firmware for the Intel
|
||||||
PRO/Wireless 3945ABG.
|
PRO/Wireless 3945ABG.
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableIntel3945ABGFirmware {
|
config = lib.mkIf config.networking.enableIntel3945ABGFirmware {
|
||||||
|
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{pkgs, config, ...}:
|
{pkgs, config, lib, ...}:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableRalinkFirmware = pkgs.lib.mkOption {
|
networking.enableRalinkFirmware = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = lib.types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Turn on this option if you want firmware for the RT73 NIC.
|
Turn on this option if you want firmware for the RT73 NIC.
|
||||||
'';
|
'';
|
||||||
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableRalinkFirmware {
|
config = lib.mkIf config.networking.enableRalinkFirmware {
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{pkgs, config, ...}:
|
{pkgs, config, lib, ...}:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
networking.enableRTL8192cFirmware = pkgs.lib.mkOption {
|
networking.enableRTL8192cFirmware = lib.mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = pkgs.lib.types.bool;
|
type = lib.types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Turn on this option if you want firmware for the RTL8192c (and related) NICs.
|
Turn on this option if you want firmware for the RTL8192c (and related) NICs.
|
||||||
'';
|
'';
|
||||||
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = pkgs.lib.mkIf config.networking.enableRTL8192cFirmware {
|
config = lib.mkIf config.networking.enableRTL8192cFirmware {
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{pkgs, config, ...}:
|
{lib, config, ...}:
|
||||||
|
|
||||||
{
|
{
|
||||||
hardware = {
|
hardware = {
|
||||||
pcmcia = {
|
pcmcia = {
|
||||||
firmware = [ (pkgs.lib.cleanSource ./firmware) ];
|
firmware = [ (lib.cleanSource ./firmware) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
125
nixos/modules/hardware/opengl.nix
Normal file
125
nixos/modules/hardware/opengl.nix
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
{ config, lib, pkgs, pkgs_i686, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.hardware.opengl;
|
||||||
|
|
||||||
|
kernelPackages = config.boot.kernelPackages;
|
||||||
|
|
||||||
|
videoDrivers = config.services.xserver.videoDrivers;
|
||||||
|
|
||||||
|
makePackage = p: p.buildEnv {
|
||||||
|
name = "mesa-drivers+txc-${p.mesa_drivers.version}";
|
||||||
|
paths =
|
||||||
|
[ p.mesa_drivers
|
||||||
|
p.mesa_noglu # mainly for libGL
|
||||||
|
(if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
|
||||||
|
p.udev
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
hardware.opengl.enable = mkOption {
|
||||||
|
description = "Whether this configuration requires OpenGL.";
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.driSupport = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to enable accelerated OpenGL rendering through the
|
||||||
|
Direct Rendering Interface (DRI).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.driSupport32Bit = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
On 64-bit systems, whether to support Direct Rendering for
|
||||||
|
32-bit applications (such as Wine). This is currently only
|
||||||
|
supported for the <literal>nvidia</literal> driver and for
|
||||||
|
<literal>Mesa</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.s3tcSupport = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Make S3TC(S3 Texture Compression) via libtxc_dxtn available
|
||||||
|
to OpenGL drivers instead of the patent-free S2TC replacement.
|
||||||
|
|
||||||
|
Using this library may require a patent license depending on your location.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
The package that provides the OpenGL implementation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.package32 = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
The package that provides the 32-bit OpenGL implementation on
|
||||||
|
64-bit systems. Used when <option>driSupport32Bit</option> is
|
||||||
|
set.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions = lib.singleton {
|
||||||
|
assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
|
||||||
|
message = "Option driSupport32Bit only makes sense on a 64-bit system.";
|
||||||
|
};
|
||||||
|
|
||||||
|
system.activationScripts.setup-opengl =
|
||||||
|
''
|
||||||
|
ln -sfn ${cfg.package} /run/opengl-driver
|
||||||
|
${if pkgs.stdenv.isi686 then ''
|
||||||
|
ln -sfn opengl-driver /run/opengl-driver-32
|
||||||
|
'' else if cfg.driSupport32Bit then ''
|
||||||
|
ln -sfn ${cfg.package32} /run/opengl-driver-32
|
||||||
|
'' else ''
|
||||||
|
rm -f /run/opengl-driver-32
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.sessionVariables.LD_LIBRARY_PATH =
|
||||||
|
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
|
||||||
|
|
||||||
|
# FIXME: move this into card-specific modules.
|
||||||
|
hardware.opengl.package = mkDefault
|
||||||
|
(if elem "ati_unfree" videoDrivers then
|
||||||
|
kernelPackages.ati_drivers_x11
|
||||||
|
else
|
||||||
|
makePackage pkgs);
|
||||||
|
|
||||||
|
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
|
||||||
|
|
||||||
|
boot.extraModulePackages =
|
||||||
|
optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions ++
|
||||||
|
optional (elem "ati_unfree" videoDrivers) kernelPackages.ati_drivers_x11;
|
||||||
|
|
||||||
|
environment.etc =
|
||||||
|
optionalAttrs (elem "ati_unfree" videoDrivers) {
|
||||||
|
"ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
49
nixos/modules/hardware/video/bumblebee.nix
Normal file
49
nixos/modules/hardware/video/bumblebee.nix
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let kernel = config.boot.kernelPackages; in
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
options = {
|
||||||
|
hardware.bumblebee.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Enable the bumblebee daemon to manage Optimus hybrid video cards.
|
||||||
|
This should power off secondary GPU until its use is requested
|
||||||
|
by running an application with optirun.
|
||||||
|
|
||||||
|
Only nvidia driver is supported so far.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
hardware.bumblebee.group = mkOption {
|
||||||
|
default = "wheel";
|
||||||
|
example = "video";
|
||||||
|
type = types.uniq types.str;
|
||||||
|
description = ''Group for bumblebee socket'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.hardware.bumblebee.enable {
|
||||||
|
boot.blacklistedKernelModules = [ "nouveau" "nvidia" ];
|
||||||
|
boot.kernelModules = [ "bbswitch" ];
|
||||||
|
boot.extraModulePackages = [ kernel.bbswitch kernel.nvidia_x11 ];
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.bumblebee ];
|
||||||
|
|
||||||
|
systemd.services.bumblebeed = {
|
||||||
|
description = "Bumblebee Hybrid Graphics Switcher";
|
||||||
|
wantedBy = [ "display-manager.service" ];
|
||||||
|
script = "bumblebeed --use-syslog -g ${config.hardware.bumblebee.group}";
|
||||||
|
path = [ kernel.bbswitch pkgs.bumblebee ];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 60;
|
||||||
|
CPUSchedulingPolicy = "idle";
|
||||||
|
};
|
||||||
|
environment.LD_LIBRARY_PATH="/run/opengl-driver/lib/";
|
||||||
|
environment.MODULE_DIR="/run/current-system/kernel-modules/lib/modules/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
54
nixos/modules/hardware/video/nvidia.nix
Normal file
54
nixos/modules/hardware/video/nvidia.nix
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# This module provides the proprietary NVIDIA X11 / OpenGL drivers.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, pkgs_i686, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
drivers = config.services.xserver.videoDrivers;
|
||||||
|
|
||||||
|
# FIXME: should introduce an option like
|
||||||
|
# ‘hardware.video.nvidia.package’ for overriding the default NVIDIA
|
||||||
|
# driver.
|
||||||
|
enabled = elem "nvidia" drivers || elem "nvidiaLegacy173" drivers || elem "nvidiaLegacy304" drivers;
|
||||||
|
|
||||||
|
nvidia_x11 =
|
||||||
|
if elem "nvidia" drivers then
|
||||||
|
config.boot.kernelPackages.nvidia_x11
|
||||||
|
else if elem "nvidiaLegacy173" drivers then
|
||||||
|
config.boot.kernelPackages.nvidia_x11_legacy173
|
||||||
|
else if elem "nvidiaLegacy304" drivers then
|
||||||
|
config.boot.kernelPackages.nvidia_x11_legacy304
|
||||||
|
else throw "impossible";
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
config = mkIf enabled {
|
||||||
|
|
||||||
|
services.xserver.drivers = singleton
|
||||||
|
{ name = "nvidia"; modules = [ nvidia_x11 ]; libPath = [ nvidia_x11 ]; };
|
||||||
|
|
||||||
|
services.xserver.screenSection =
|
||||||
|
''
|
||||||
|
Option "RandRRotation" "on"
|
||||||
|
'';
|
||||||
|
|
||||||
|
hardware.opengl.package = nvidia_x11;
|
||||||
|
hardware.opengl.package32 = pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; };
|
||||||
|
|
||||||
|
environment.systemPackages = [ nvidia_x11 ];
|
||||||
|
|
||||||
|
boot.extraModulePackages = [ nvidia_x11 ];
|
||||||
|
|
||||||
|
boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ];
|
||||||
|
|
||||||
|
services.acpid.enable = true;
|
||||||
|
|
||||||
|
environment.etc."OpenCL/vendors/nvidia.icd".source = "${nvidia_x11}/lib/vendors/nvidia.icd";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user